diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 438a2f450..f3d2d933a 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -11,39 +11,6 @@ Are changes expected to change answers? (specify if bfb, different at roundoff,
Any User Interface Changes (namelist or namelist defaults changes)?
### Testing performed
+Please describe the tests along with the target model and machine(s)
+If possible, please also added hashes that were used in the testing
-Testing performed if application target is CESM:
-- [ ] (recommended) CIME_DRIVER=nuopc scripts_regression_tests.py
- - machines:
- - details (e.g. failed tests):
-- [ ] (recommended) CESM testlist_drv.xml
- - machines and compilers:
- - details (e.g. failed tests):
-- [ ] (optional) CESM prealpha test
- - machines and compilers
- - details (e.g. failed tests):
-- [ ] (other) please described in detail
- - machines and compilers
- - details (e.g. failed tests):
-
-Testing performed if application target is UFS-coupled:
-- [ ] (recommended) UFS-coupled testing
- - description:
- - details (e.g. failed tests):
-
-Testing performed if application target is UFS-HAFS:
-- [ ] (recommended) UFS-HAFS testing
- - description:
- - details (e.g. failed tests):
-
-### Hashes used for testing:
-
-- [ ] CESM:
- - repository to check out: https://github.com/ESCOMP/CESM.git
- - branch/hash:
-- [ ] UFS-coupled, then umbrella repostiory to check out and associated hash:
- - repository to check out:
- - branch/hash:
-- [ ] UFS-HAFS, then umbrella repostiory to check out and associated hash:
- - repository to check out:
- - branch/hash:
diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml
index fafc46f46..6e26b40a5 100644
--- a/.github/workflows/extbuild.yml
+++ b/.github/workflows/extbuild.yml
@@ -18,11 +18,13 @@ jobs:
FC: mpifort
CXX: mpicxx
CPPFLAGS: "-I/usr/include -I/usr/local/include"
+
# Versions of all dependencies can be updated here
- ESMF_VERSION: v8.4.0
+ ESMF_VERSION: v8.4.2
PNETCDF_VERSION: checkpoint.1.12.3
NETCDF_FORTRAN_VERSION: v4.6.0
- PIO_VERSION: pio2_5_10
+ PIO_VERSION: pio2_6_0
+ CDEPS_VERSION: cdeps1.0.15
steps:
- uses: actions/checkout@v3
# Build the ESMF library, if the cache contains a previous build
@@ -50,14 +52,14 @@ jobs:
key: ${{ runner.os }}-${{ env.PIO_VERSION }}.pio
- name: Build ParallelIO
if: steps.cache-ParallelIO.outputs.cache-hit != 'true'
- uses: NCAR/ParallelIO/.github/actions/parallelio_cmake@9390e30e29d4ebbfbef0fc72162cacd9e8f25e4e
+ uses: NCAR/ParallelIO/.github/actions/parallelio_cmake@pio2_6_0
with:
parallelio_version: ${{ env.ParallelIO_VERSION }}
enable_fortran: True
install_prefix: $HOME/pio
- name: Build ESMF
if: steps.cache-esmf.outputs.cache-hit != 'true'
- uses: ESCOMP/CDEPS/.github/actions/buildesmf@e06246b560d3132170bb1a5443fa3d65dfbd2040
+ uses: ESCOMP/CDEPS/.github/actions/buildesmf@cdeps1.0.15
with:
esmf_version: ${{ env.ESMF_VERSION }}
esmf_bopt: g
@@ -67,12 +69,39 @@ jobs:
netcdf_fortran_path: /usr
pnetcdf_path: /usr
parallelio_path: $HOME/pio
+ - name: Cache CDEPS
+ id: cache-cdeps
+ uses: actions/cache@v3
+ with:
+ path: $HOME/cdeps
+ key: ${{ runner.os }}-${{ env.CDEPS_VERSION }}.cdeps
+
+ - name: checkout CDEPS
+ uses: actions/checkout@v3
+ with:
+ repository: ESCOMP/CDEPS
+ path: cdeps-src
+ ref: ${{ env.CDEPS_VERSION }}
+ - name: Build CDEPS
+ if: steps.cache-cdeps.outputs.cache-hit != 'true'
+ uses: ESCOMP/CDEPS/.github/actions/buildcdeps@cdeps1.0.15
+ with:
+ esmfmkfile: $HOME/ESMF/lib/libg/Linux.gfortran.64.openmpi.default/esmf.mk
+ pio_path: $HOME/pio
+ src_root: ${GITHUB_WORKSPACE}/cdeps-src
+ cmake_flags: " -Wno-dev -DCMAKE_BUILD_TYPE=DEBUG -DWERROR=ON -DCMAKE_Fortran_FLAGS=\"-DCPRGNU -g -Wall \
+ -ffree-form -ffree-line-length-none -fallow-argument-mismatch \""
+
- name: Build CMEPS
run: |
export ESMFMKFILE=$HOME/ESMF/lib/libg/Linux.gfortran.64.openmpi.default/esmf.mk
export PIO=$HOME/pio
mkdir build-cmeps
pushd build-cmeps
- cmake -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_Fortran_FLAGS="-g -Wall -Werror -ffree-form -ffree-line-length-none -Wno-unused-dummy-argument" ../
+ cmake -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_Fortran_FLAGS="-g -Wall -Werror -ffree-form -ffree-line-length-none -Wno-unused-dummy-argument -I /home/runner/work/CMEPS/CMEPS/build-cdeps/share" ../
make VERBOSE=1
popd
+
+ - name: Setup tmate session
+ if: ${{ failure() }}
+ uses: mxschmitt/action-tmate@v3
diff --git a/cesm/driver/ensemble_driver.F90 b/cesm/driver/ensemble_driver.F90
index 58b9d58a1..2656f10fc 100644
--- a/cesm/driver/ensemble_driver.F90
+++ b/cesm/driver/ensemble_driver.F90
@@ -7,7 +7,7 @@ module Ensemble_driver
! esm driver and its components layed out concurently across mpi tasks.
!-----------------------------------------------------------------------------
- use shr_kind_mod , only : cl=>shr_kind_cl, cs=>shr_kind_cs
+ use shr_kind_mod , only : cl=>shr_kind_cl, cs=>shr_kind_cs, cx=>shr_kind_cx
use shr_log_mod , only : shr_log_setLogUnit
use esm_utils_mod , only : maintask, logunit, chkerr
@@ -16,7 +16,13 @@ module Ensemble_driver
public :: SetServices
private :: SetModelServices
+ private :: ensemble_finalize
+ integer, allocatable :: asyncio_petlist(:)
+ logical :: asyncio_task=.false.
+ logical :: asyncIO_available=.false.
+ integer :: number_of_members
+ integer :: inst ! ensemble instance containing this task
character(*),parameter :: u_FILE_u = &
__FILE__
@@ -26,9 +32,12 @@ module Ensemble_driver
subroutine SetServices(ensemble_driver, rc)
- use NUOPC , only : NUOPC_CompDerive, NUOPC_CompSpecialize
+ use NUOPC , only : NUOPC_CompDerive, NUOPC_CompSpecialize, NUOPC_CompAttributeSet
+ use NUOPC , only : NUOPC_CompAttributeGet
use NUOPC_Driver , only : driver_routine_SS => SetServices
use NUOPC_Driver , only : ensemble_label_SetModelServices => label_SetModelServices
+ use NUOPC_Driver , only : ensemble_label_PostChildrenAdvertise => label_PostChildrenAdvertise
+ use NUOPC_Driver , only : label_Finalize
use ESMF , only : ESMF_GridComp, ESMF_GridCompSet
use ESMF , only : ESMF_Config, ESMF_ConfigCreate, ESMF_ConfigLoadFile
use ESMF , only : ESMF_SUCCESS, ESMF_LogWrite, ESMF_LOGMSG_INFO
@@ -38,6 +47,7 @@ subroutine SetServices(ensemble_driver, rc)
! local variables
type(ESMF_Config) :: config
+ logical :: isPresent
character(len=*), parameter :: subname = "(ensemble_driver.F90:SetServices)"
!---------------------------------------
@@ -53,6 +63,14 @@ subroutine SetServices(ensemble_driver, rc)
specRoutine=SetModelServices, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
+ ! PostChildrenAdvertise is a NUOPC specialization which happens after Advertize but before Realize
+ ! We have overloaded this specialization location to initilize IO.
+ ! So after all components have called Advertise but before any component calls Realize
+ ! IO will be initialized and any async IO tasks will be split off to the PIO async IO driver.
+ call NUOPC_CompSpecialize(ensemble_driver, specLabel=ensemble_label_PostChildrenAdvertise, &
+ specRoutine=InitializeIO, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+
! Create, open and set the config
config = ESMF_ConfigCreate(rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
@@ -63,6 +81,26 @@ subroutine SetServices(ensemble_driver, rc)
call ESMF_GridCompSet(ensemble_driver, config=config, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
+ ! NUOPC component drivers end the initialization process with an internal call to InitializeDataResolution.
+ ! The ensemble_driver does not need to InitializeDataResolution and doing so will cause a hang
+ ! if asyncronous IO is used. This attribute is available after ESMF8.4.0b03 to toggle that control.
+ ! Cannot use asyncIO with older ESMF versions.
+ call NUOPC_CompAttributeGet(ensemble_driver, name="InitializeDataResolution", &
+ isPresent=isPresent, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+
+ if(isPresent) then
+ call ESMF_LogWrite(trim(subname)//": setting InitializeDataResolution false", ESMF_LOGMSG_INFO)
+ call NUOPC_CompAttributeSet(ensemble_driver, name="InitializeDataResolution", value="false", rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ asyncIO_available = .true.
+ call ESMF_LogWrite(trim(subname)//": asyncio is available", ESMF_LOGMSG_INFO)
+ endif
+ ! Set a finalize method, it calls pio_finalize
+ call NUOPC_CompSpecialize(ensemble_driver, specLabel=label_Finalize, &
+ specRoutine=ensemble_finalize, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+
call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO)
end subroutine SetServices
@@ -99,14 +137,18 @@ subroutine SetModelServices(ensemble_driver, rc)
character(len=512) :: logfile
logical :: read_restart
character(len=CS) :: read_restart_string
- integer :: inst
- integer :: number_of_members
integer :: ntasks_per_member
+ integer :: iopetcnt
+ integer :: petcnt
+ logical :: comp_task
+ integer :: pio_asyncio_ntasks
+ integer :: pio_asyncio_stride
+ integer :: pio_asyncio_rootpe
integer :: Global_Comm
- character(CL) :: start_type ! Type of startup
+ character(len=CL) :: start_type ! Type of startup
character(len=7) :: drvrinst
character(len=5) :: inst_suffix
- character(len=CL) :: msgstr
+ character(len=CX) :: msgstr
character(len=CL) :: cvalue
character(len=CL) :: calendar
character(len=*) , parameter :: start_type_start = "startup"
@@ -196,13 +238,25 @@ subroutine SetModelServices(ensemble_driver, rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) number_of_members
+ call NUOPC_CompAttributeGet(ensemble_driver, name="pio_asyncio_ntasks", value=cvalue, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ read(cvalue,*) pio_asyncio_ntasks
+
+ call NUOPC_CompAttributeGet(ensemble_driver, name="pio_asyncio_stride", value=cvalue, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ read(cvalue,*) pio_asyncio_stride
+
+ call NUOPC_CompAttributeGet(ensemble_driver, name="pio_asyncio_rootpe", value=cvalue, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ read(cvalue,*) pio_asyncio_rootpe
+
call ESMF_VMGet(vm, localPet=localPet, PetCount=PetCount, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
- ntasks_per_member = PetCount/number_of_members
- if(ntasks_per_member*number_of_members .ne. PetCount) then
+ ntasks_per_member = PetCount/number_of_members - pio_asyncio_ntasks
+ if(modulo(PetCount-pio_asyncio_ntasks*number_of_members, number_of_members) .ne. 0) then
write (msgstr,'(a,i5,a,i3,a,i3,a)') &
- "PetCount (",PetCount,") must be evenly divisable by number of members (",number_of_members,")"
+ "PetCount (",PetCount,") - Async IOtasks (",pio_asyncio_ntasks*number_of_members,") must be evenly divisable by number of members (",number_of_members,")"
call ESMF_LogSetError(ESMF_RC_ARG_BAD, msg=msgstr, line=__LINE__, file=__FILE__, rcToReturn=rc)
return
endif
@@ -212,77 +266,123 @@ subroutine SetModelServices(ensemble_driver, rc)
!-------------------------------------------
allocate(petList(ntasks_per_member))
- ! We need to loop over instances
- call t_startf('compute_drivers')
- do inst = 1, number_of_members
-
+ allocate(asyncio_petlist(pio_asyncio_ntasks))
+ !
+ ! Logic for asyncio variables is handled in cmeps buildnml.
+ ! here we assume that pio_asyncio_stride and pio_asyncio_ntasks are only set
+ ! if asyncio is enabled.
+ !
+ logunit = 6
+ do inst=1,number_of_members
+ petcnt=1
+ iopetcnt = 1
+ comp_task = .false.
+ asyncio_task = .false.
! Determine pet list for driver instance
- petList(1) = (inst-1) * ntasks_per_member
- do n=2,ntasks_per_member
- petList(n) = petList(n-1) + 1
+ if(pio_asyncio_ntasks > 0) then
+ do n=pio_asyncio_rootpe,pio_asyncio_rootpe+pio_asyncio_stride*(pio_asyncio_ntasks-1),pio_asyncio_stride
+ asyncio_petlist(iopetcnt) = (inst-1)*(ntasks_per_member+pio_asyncio_ntasks) + n
+ if(asyncio_petlist(iopetcnt) == localPet) asyncio_task = .true.
+ iopetcnt = iopetcnt+1
+ enddo
+ iopetcnt = 1
+ endif
+ do n=0,ntasks_per_member+pio_asyncio_ntasks-1
+ if(pio_asyncio_ntasks > 0) then
+ if( asyncio_petlist(iopetcnt)==(inst-1)*(ntasks_per_member+pio_asyncio_ntasks) + n) then
+ ! Here if asyncio is true and this is an io task
+ iopetcnt = iopetcnt+1
+ else if(petcnt <= ntasks_per_member) then
+ ! Here if this is a compute task
+ petList(petcnt) = n + (inst-1)*(ntasks_per_member + pio_asyncio_ntasks)
+ if (petList(petcnt) == localPet) then
+ comp_task=.true.
+ endif
+ petcnt = petcnt+1
+ else
+ msgstr = "ERROR task cannot be neither a compute task nor an asyncio task"
+ call ESMF_LogSetError(ESMF_RC_NOT_VALID, msg=msgstr, line=__LINE__, file=__FILE__, rcToReturn=rc)
+ return ! bail out
+ endif
+ else
+ ! Here if asyncio is false
+ petList(petcnt) = (inst-1)*ntasks_per_member + n
+ if (petList(petcnt) == localPet) comp_task=.true.
+ petcnt = petcnt+1
+ endif
enddo
-
+ if(inst == localPet/(ntasks_per_member+pio_asyncio_ntasks) + 1) then
+ if(comp_task .and. asyncio_task) then
+ write(msgstr,*) "ERROR task cannot be both a compute task and an asyncio task", inst, petlist
+ call ESMF_LogSetError(ESMF_RC_NOT_VALID, msg=msgstr, line=__LINE__, file=__FILE__, rcToReturn=rc)
+ return ! bail out
+ elseif (.not. comp_task .and. .not. asyncio_task) then
+ write(msgstr,*) "ERROR task is nether a compute task nor an asyncio task", inst, petlist
+ call ESMF_LogSetError(ESMF_RC_NOT_VALID, msg=msgstr, line=__LINE__, file=__FILE__, rcToReturn=rc)
+ return ! bail out
+ endif
+ endif
! Add driver instance to ensemble driver
write(drvrinst,'(a,i4.4)') "ESM",inst
- call NUOPC_DriverAddComp(ensemble_driver, drvrinst, ESMSetServices, petList=petList, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- enddo
- call t_stopf('compute_drivers')
-
- inst = localPet/ntasks_per_member + 1
- petList(1) = (inst-1) * ntasks_per_member
- do n=2,ntasks_per_member
- petList(n) = petList(n-1) + 1
- enddo
- if (localpet >= petlist(1) .and. localpet <= petlist(ntasks_per_member)) then
- write(drvrinst,'(a,i4.4)') "ESM",inst
- call NUOPC_DriverGetComp(ensemble_driver, drvrinst, comp=driver, rc=rc)
+
+ call NUOPC_DriverAddComp(ensemble_driver, drvrinst, ESMSetServices, petList=petList, comp=driver, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- if(number_of_members > 1) then
- call NUOPC_CompAttributeAdd(driver, attrList=(/'inst_suffix'/), rc=rc)
+ write(msgstr, *) ": driver added on PETS ",petlist(1),' to ',petlist(petcnt-1), comp_task, asyncio_task
+ call ESMF_LogWrite(trim(subname)//msgstr)
+ ! Set the driver log to the driver task 0
+ if (comp_task) then
+ if(number_of_members > 1) then
+ call NUOPC_CompAttributeAdd(driver, attrList=(/'inst_suffix'/), rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ write(inst_suffix,'(a,i4.4)') '_',inst
+ call NUOPC_CompAttributeSet(driver, name='inst_suffix', value=inst_suffix, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ else
+ inst_suffix = ''
+ endif
+ ! CESM does not use this ESMF feature and at large processor counts it can be expensive to have it on.
+ call NUOPC_CompAttributeSet(driver, name="HierarchyProtocol", value="off", rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
- write(inst_suffix,'(a,i4.4)') '_',inst
- call NUOPC_CompAttributeSet(driver, name='inst_suffix', value=inst_suffix, rc=rc)
+
+ ! Set the driver instance attributes
+ call NUOPC_CompAttributeAdd(driver, attrList=(/'read_restart'/), rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
- else
- inst_suffix = ''
- endif
-
- ! Set the driver instance attributes
- call NUOPC_CompAttributeAdd(driver, attrList=(/'read_restart'/), rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- call NUOPC_CompAttributeSet(driver, name='read_restart', value=trim(read_restart_string), rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- call ReadAttributes(driver, config, "CLOCK_attributes::", rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- call ReadAttributes(driver, config, "DRIVER_attributes::", rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- call ReadAttributes(driver, config, "DRV_modelio::", rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- ! Set the driver log to the driver task 0
- if (mod(localPet, ntasks_per_member) == 0) then
- call NUOPC_CompAttributeGet(driver, name="diro", value=diro, rc=rc)
+ call NUOPC_CompAttributeSet(driver, name='read_restart', value=trim(read_restart_string), rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+
+ call ReadAttributes(driver, config, "CLOCK_attributes::", rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
- call NUOPC_CompAttributeGet(driver, name="logfile", value=logfile, rc=rc)
+
+ call ReadAttributes(driver, config, "DRIVER_attributes::", rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
- open (newunit=logunit,file=trim(diro)//"/"//trim(logfile))
- maintask = .true.
- else
- logUnit = 6
- maintask = .false.
+
+ call ReadAttributes(driver, config, "DRV_modelio::", rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ write(msgStr, *) trim(subname), ' instance = ',inst, 'attributes read'
+ call ESMF_LogWrite(msgStr)
+ if (localPet == petList(1)) then
+ call NUOPC_CompAttributeGet(driver, name="diro", value=diro, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call NUOPC_CompAttributeGet(driver, name="logfile", value=logfile, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ ! Multiinstance logfile name needs a correction
+ if(len_trim(inst_suffix) > 0) then
+ n = index(logfile, '.')
+ logfile = logfile(1:n-1)//trim(inst_suffix)//logfile(n:)
+ endif
+ open (newunit=logunit,file=trim(diro)//"/"//trim(logfile))
+ maintask = .true.
+ endif
+
endif
call shr_log_setLogUnit (logunit)
-
! Create a clock for each driver instance
- call esm_time_clockInit(ensemble_driver, driver, logunit, maintask, rc)
+
+ call esm_time_clockInit(ensemble_driver, driver, logunit, localpet==petList(1), rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
- endif
+ enddo
+ inst = localPet/(ntasks_per_member+pio_asyncio_ntasks) + 1
deallocate(petList)
call t_stopf(subname)
@@ -291,4 +391,75 @@ subroutine SetModelServices(ensemble_driver, rc)
end subroutine SetModelServices
+ subroutine InitializeIO(ensemble_driver, rc)
+ use ESMF, only: ESMF_GridComp, ESMF_LOGMSG_INFO, ESMF_LogWrite
+ use ESMF, only: ESMF_SUCCESS, ESMF_VM, ESMF_GridCompGet, ESMF_VMGet
+ use ESMF, only: ESMF_CONFIG, ESMF_GridCompIsPetLocal, ESMF_State, ESMF_Clock
+ use NUOPC, only: NUOPC_CompAttributeGet, NUOPC_CompGet
+ use NUOPC_DRIVER, only: NUOPC_DriverGetComp
+ use driver_pio_mod , only: driver_pio_init, driver_pio_component_init
+#ifndef NO_MPI2
+ use MPI, only : MPI_Comm_split, MPI_UNDEFINED
+#endif
+ type(ESMF_GridComp) :: ensemble_driver
+ type(ESMF_VM) :: ensemble_vm
+ integer, intent(out) :: rc
+ character(len=*), parameter :: subname = '('//__FILE__//':InitializeIO)'
+ type(ESMF_GridComp), pointer :: dcomp(:)
+ integer :: iam
+ integer :: Global_Comm, Instance_Comm
+ integer :: drv
+ integer :: PetCount
+ integer :: key, color, i
+ type(ESMF_GridComp) :: driver
+ character(len=7) :: drvrinst
+ character(len=8) :: compname
+
+ rc = ESMF_SUCCESS
+ call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO)
+ call shr_log_setLogUnit (logunit)
+
+ call ESMF_GridCompGet(ensemble_driver, vm=ensemble_vm, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call ESMF_VMGet(ensemble_vm, localpet=iam, mpiCommunicator=Global_Comm, PetCount=PetCount, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ if(number_of_members > 1) then
+ color = inst
+ key = modulo(iam, PetCount/number_of_members)
+#ifndef NO_MPI2
+ call MPI_Comm_split(Global_Comm, color, key, Instance_Comm, rc)
+#endif
+ do i=1,size(asyncio_petlist)
+ asyncio_petList(i) = modulo(asyncio_petList(i), PetCount/number_of_members)
+ enddo
+ else
+ Instance_Comm = Global_Comm
+ endif
+ write(drvrinst,'(a,i4.4)') "ESM",inst
+ call NUOPC_DriverGetComp(ensemble_driver, drvrinst, comp=driver, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+
+ call ESMF_LogWrite(trim(subname)//": call driver_pio_init "//compname, ESMF_LOGMSG_INFO)
+ call driver_pio_init(driver, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+
+ call ESMF_LogWrite(trim(subname)//": call driver_pio_component_init "//compname, ESMF_LOGMSG_INFO)
+ call driver_pio_component_init(driver, Instance_Comm, asyncio_petlist, rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call ESMF_LogWrite(trim(subname)//": driver_pio_component_init done "//compname, ESMF_LOGMSG_INFO)
+
+ deallocate(asyncio_petlist)
+ call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO)
+ end subroutine InitializeIO
+
+ subroutine ensemble_finalize(ensemble_driver, rc)
+ use ESMF, only : ESMF_GridComp, ESMF_SUCCESS
+ use driver_pio_mod, only: driver_pio_finalize
+ type(ESMF_GridComp) :: Ensemble_driver
+ integer, intent(out) :: rc
+ rc = ESMF_SUCCESS
+ call shr_log_setLogUnit (logunit)
+ call driver_pio_finalize()
+
+ end subroutine ensemble_finalize
end module Ensemble_driver
diff --git a/cesm/driver/esm.F90 b/cesm/driver/esm.F90
index da2f6f6d3..b5207955a 100644
--- a/cesm/driver/esm.F90
+++ b/cesm/driver/esm.F90
@@ -237,6 +237,7 @@ subroutine SetRunSequence(driver, rc)
rc = ESMF_SUCCESS
call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO)
+ call shr_log_setLogunit(logunit)
!--------
! Run Sequence and Connectors
@@ -335,6 +336,7 @@ recursive subroutine ModifyCplLists(driver, importState, exportState, clock, rc)
rc = ESMF_SUCCESS
call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO)
+ call shr_log_setLogunit(logunit)
call ESMF_LogWrite("Driver is in ModifyCplLists()", ESMF_LOGMSG_INFO, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
@@ -430,6 +432,7 @@ subroutine InitAttributes(driver, rc)
rc = ESMF_SUCCESS
call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO)
+ call shr_log_setLogunit(logunit)
!----------------------------------------------------------
! Initialize options for reproducible sums
@@ -607,16 +610,17 @@ subroutine AddAttributes(gcomp, driver, config, compid, compname, inst_suffix, n
character(len=*) , intent(in) :: inst_suffix
integer , intent(in) :: nthrds
integer , intent(inout) :: rc
-
! local variables
integer :: inst_index
+ logical :: computetask
character(len=CL) :: cvalue
character(len=CS) :: attribute
character(len=*), parameter :: subname = "(esm.F90:AddAttributes)"
!-------------------------------------------
-
+ computetask = .false.
rc = ESMF_Success
call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO)
+ call shr_log_setLogunit(logunit)
!------
! Add compid to gcomp attributes
@@ -631,6 +635,10 @@ subroutine AddAttributes(gcomp, driver, config, compid, compname, inst_suffix, n
! Add driver restart flag to gcomp attributes
!------
attribute = 'read_restart'
+ call NUOPC_CompAttributeGet(driver, name=trim(attribute), isPresent=computetask, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ if(.not. computetask) return
+
call NUOPC_CompAttributeGet(driver, name=trim(attribute), value=cvalue, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call NUOPC_CompAttributeAdd(gcomp, (/trim(attribute)/), rc=rc)
@@ -645,6 +653,9 @@ subroutine AddAttributes(gcomp, driver, config, compid, compname, inst_suffix, n
if (chkerr(rc,__LINE__,u_FILE_u)) return
call ReadAttributes(gcomp, config, "ALLCOMP_attributes::", rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
+
+ call ESMF_LogWrite(trim(subname)//": call Readattributes for"//trim(compname), ESMF_LOGMSG_INFO)
+
call ReadAttributes(gcomp, config, trim(compname)//"_modelio::", rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) then
print *,__FILE__,__LINE__,"ERROR reading ",trim(compname)," modelio from runconfig"
@@ -718,6 +729,7 @@ subroutine ReadAttributes(gcomp, config, label, relaxedflag, formatprint, rc)
!-------------------------------------------
rc = ESMF_SUCCESS
+ call shr_log_setLogunit(logunit)
if (present(relaxedflag)) then
attrFF = NUOPC_FreeFormatCreate(config, label=trim(label), relaxedflag=.true., rc=rc)
@@ -784,8 +796,7 @@ subroutine esm_init_pelayout(driver, maxthreads, rc)
#ifndef NO_MPI2
use mpi , only : MPI_COMM_NULL, mpi_comm_size
#endif
- use mct_mod , only : mct_world_init
- use driver_pio_mod , only : driver_pio_init, driver_pio_component_init
+ use m_MCTWorld , only : mct_world_init => init
#ifdef MED_PRESENT
use med_internalstate_mod , only : med_id
@@ -870,6 +881,7 @@ subroutine esm_init_pelayout(driver, maxthreads, rc)
integer :: rank, nprocs, ierr
character(len=*), parameter :: subname = "(esm_pelayout.F90:esm_init_pelayout)"
!---------------------------------------
+ call shr_log_setLogunit(logunit)
rc = ESMF_SUCCESS
call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO)
@@ -908,11 +920,6 @@ subroutine esm_init_pelayout(driver, maxthreads, rc)
inst_suffix = ""
endif
- ! Initialize PIO
- ! This reads in the pio parameters that are independent of component
- call driver_pio_init(driver, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
allocate(comms(componentCount+1), comps(componentCount+1))
comps(1) = 1
comms = MPI_COMM_NULL
@@ -937,7 +944,7 @@ subroutine esm_init_pelayout(driver, maxthreads, rc)
read(cvalue,*) ntasks
if (ntasks < 0 .or. ntasks > PetCount) then
- write (msgstr, *) "Invalid NTASKS value specified for component: ",namestr, ' ntasks: ',ntasks
+ write (msgstr, *) "Invalid NTASKS value specified for component: ",namestr, ' ntasks: ',ntasks, petcount
call ESMF_LogSetError(ESMF_RC_NOT_VALID, msg=msgstr, line=__LINE__, file=__FILE__, rcToReturn=rc)
return
endif
@@ -1156,12 +1163,7 @@ subroutine esm_init_pelayout(driver, maxthreads, rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
enddo
- ! Read in component dependent PIO parameters and initialize
- ! IO systems
- call driver_pio_component_init(driver, size(comps), rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- ! Initialize MCT (this is needed for data models and cice prescribed capability)
call mct_world_init(componentCount+1, GLOBAL_COMM, comms, comps)
@@ -1232,7 +1234,9 @@ subroutine esm_set_single_column_attributes(compname, gcomp, rc)
!-------------------------------------------------------------------------------
rc = ESMF_SUCCESS
+ call shr_log_setLogunit(logunit)
scol_mesh_n = 0
+
! obtain the single column lon and lat
call NUOPC_CompAttributeGet(gcomp, name='scol_lon', value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
@@ -1392,11 +1396,12 @@ subroutine esm_set_single_column_attributes(compname, gcomp, rc)
allocate(lonMesh(lsize), latMesh(lsize))
call ESMF_MeshGet(mesh, ownedElemCoords=ownedElemCoords)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
+
+ scol_mesh_n = 0
do n = 1,lsize
lonMesh(n) = ownedElemCoords(2*n-1)
latMesh(n) = ownedElemCoords(2*n)
if (abs(lonMesh(n) - scol_lon) < 1.e-4 .and. abs(latMesh(n) - scol_lat) < 1.e-4) then
- scol_mesh_n = n
scol_mesh_n = n
exit
end if
@@ -1493,7 +1498,7 @@ end subroutine esm_set_single_column_attributes
subroutine esm_finalize(driver, rc)
use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_VM, ESMF_VMGet
- use ESMF , only : ESMF_SUCCESS
+ use ESMF , only : ESMF_SUCCESS, ESMF_LOGMSG_INFO, ESMF_LOGWRITE
use NUOPC , only : NUOPC_CompAttributeGet
use perf_mod , only : t_prf, t_finalizef
@@ -1507,14 +1512,12 @@ subroutine esm_finalize(driver, rc)
logical :: isPresent
type(ESMF_VM) :: vm
integer :: mpicomm
+ character(len=*), parameter :: subname = '(esm_finalize) '
!---------------------------------------
+ call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO)
rc = ESMF_SUCCESS
-
- if (maintask) then
- write(logunit,*)' SUCCESSFUL TERMINATION OF CESM'
- end if
-
+ call shr_log_setLogunit(logunit)
call ESMF_GridCompGet(driver, vm=vm, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call ESMF_VMGet(vm, mpiCommunicator=mpicomm, rc=rc)
@@ -1533,6 +1536,11 @@ subroutine esm_finalize(driver, rc)
endif
call t_prf(trim(timing_dir)//'/model_timing'//trim(inst_suffix), mpicom=mpicomm)
+ if (maintask) then
+ write(logunit,*)' SUCCESSFUL TERMINATION OF CESM'
+ end if
+ call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO)
+
call t_finalizef()
end subroutine esm_finalize
diff --git a/cesm/driver/esm_time_mod.F90 b/cesm/driver/esm_time_mod.F90
index 0c8a6e86c..fc57eaf11 100644
--- a/cesm/driver/esm_time_mod.F90
+++ b/cesm/driver/esm_time_mod.F90
@@ -11,7 +11,8 @@ module esm_time_mod
use ESMF , only : ESMF_TimeInterval, ESMF_TimeIntervalSet, ESMF_TimeIntervalGet
use ESMF , only : ESMF_SUCCESS, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_FAILURE, ESMF_LOGMSG_ERROR
use ESMF , only : ESMF_VM, ESMF_VMGet, ESMF_VMBroadcast
- use ESMF , only : ESMF_LOGMSG_INFO, ESMF_FAILURE
+ use ESMF , only : ESMF_VMAllReduce, ESMF_REDUCE_MAX
+ use ESMF , only : ESMF_LOGMSG_INFO, ESMF_FAILURE, ESMF_GridCompIsPetLocal
use ESMF , only : operator(<), operator(/=), operator(+)
use ESMF , only : operator(-), operator(*) , operator(>=)
use ESMF , only : operator(<=), operator(>), operator(==)
@@ -62,7 +63,7 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas
! local variables
type(ESMF_Clock) :: clock
- type(ESMF_VM) :: vm
+ type(ESMF_VM) :: vm, envm
type(ESMF_Time) :: StartTime ! Start time
type(ESMF_Time) :: RefTime ! Reference time
type(ESMF_Time) :: CurrTime ! Current time
@@ -100,99 +101,151 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas
character(CL) :: tmpstr ! temporary
character(CS) :: inst_suffix
integer :: tmp(4) ! Array for Broadcast
+ integer :: myid, bcastID(2)
logical :: isPresent
- character(len=*), parameter :: subname = '(esm_time_clockInit): '
+ logical :: inDriver
+ logical, save :: firsttime=.true.
+ character(len=*), parameter :: subname = '('//__FILE__//':esm_time_clockInit) '
!-------------------------------------------------------------------------------
rc = ESMF_SUCCESS
-
- call ESMF_GridCompGet(instance_driver, vm=vm, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO)
!---------------------------------------------------------------------------
! Determine start time, reference time and current time
!---------------------------------------------------------------------------
- call NUOPC_CompAttributeGet(instance_driver, name="start_ymd", value=cvalue, rc=rc)
+ call NUOPC_CompAttributeGet(ensemble_driver, name="start_ymd", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) start_ymd
- call NUOPC_CompAttributeGet(instance_driver, name="start_tod", value=cvalue, rc=rc)
+ call NUOPC_CompAttributeGet(ensemble_driver, name="start_tod", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) start_tod
- call NUOPC_CompAttributeGet(instance_driver, name='read_restart', value=cvalue, rc=rc)
+ !---------------------------------------------------------------------------
+ ! Determine driver clock timestep
+ !---------------------------------------------------------------------------
+
+ call NUOPC_CompAttributeGet(ensemble_driver, name="atm_cpl_dt", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) read_restart
+ read(cvalue,*) atm_cpl_dt
- if (read_restart) then
+ call NUOPC_CompAttributeGet(ensemble_driver, name="lnd_cpl_dt", value=cvalue, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ read(cvalue,*) lnd_cpl_dt
- call NUOPC_CompAttributeGet(instance_driver, name='drv_restart_pointer', value=restart_file, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ call NUOPC_CompAttributeGet(ensemble_driver, name="ice_cpl_dt", value=cvalue, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ read(cvalue,*) ice_cpl_dt
- if (trim(restart_file) /= 'none') then
+ call NUOPC_CompAttributeGet(ensemble_driver, name="ocn_cpl_dt", value=cvalue, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ read(cvalue,*) ocn_cpl_dt
- call NUOPC_CompAttributeGet(instance_driver, name="inst_suffix", isPresent=isPresent, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- if(isPresent) then
- call NUOPC_CompAttributeGet(instance_driver, name="inst_suffix", value=inst_suffix, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- else
- inst_suffix = ""
- endif
+ call NUOPC_CompAttributeGet(ensemble_driver, name="glc_cpl_dt", value=cvalue, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ read(cvalue,*) glc_cpl_dt
- restart_pfile = trim(restart_file)//inst_suffix
-
- if (maintask) then
- call ESMF_LogWrite(trim(subname)//" read rpointer file = "//trim(restart_pfile), &
- ESMF_LOGMSG_INFO)
- open(newunit=unitn, file=restart_pfile, form='FORMATTED', status='old',iostat=ierr)
- if (ierr < 0) then
- rc = ESMF_FAILURE
- call ESMF_LogWrite(trim(subname)//' ERROR rpointer file open returns error', &
- ESMF_LOGMSG_ERROR, line=__LINE__, file=__FILE__)
- return
- end if
- read(unitn,'(a)', iostat=ierr) restart_file
- if (ierr < 0) then
- rc = ESMF_FAILURE
- call ESMF_LogWrite(trim(subname)//' ERROR rpointer file read returns error', &
- ESMF_LOGMSG_INFO, line=__LINE__, file=__FILE__)
- return
- end if
- close(unitn)
- if (maintask) then
- write(logunit,'(a)') trim(subname)//" reading driver restart from file = "//trim(restart_file)
- end if
- call esm_time_read_restart(restart_file, start_ymd, start_tod, curr_ymd, curr_tod, rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ call NUOPC_CompAttributeGet(ensemble_driver, name="rof_cpl_dt", value=cvalue, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ read(cvalue,*) rof_cpl_dt
- tmp(1) = start_ymd ; tmp(2) = start_tod
- tmp(3) = curr_ymd ; tmp(4) = curr_tod
- endif
+ call NUOPC_CompAttributeGet(ensemble_driver, name="wav_cpl_dt", value=cvalue, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ read(cvalue,*) wav_cpl_dt
- call ESMF_VMBroadcast(vm, tmp, 4, 0, rc=rc)
+ dtime_drv = minval((/atm_cpl_dt, lnd_cpl_dt, ocn_cpl_dt, ice_cpl_dt, glc_cpl_dt, rof_cpl_dt, wav_cpl_dt/))
+ if(maintask) then
+ write(tmpstr,'(i10)') dtime_drv
+ call ESMF_LogWrite(trim(subname)//': driver time interval is : '// trim(tmpstr), ESMF_LOGMSG_INFO, rc=rc)
+ write(logunit,*) trim(subname)//': driver time interval is : '// trim(tmpstr)
+ endif
+ call ESMF_GridCompGet(ensemble_driver, vm=envm, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+
+ call ESMF_VMGet(envm, localPet=myid, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ indriver = ESMF_GridCompIsPetLocal(instance_driver, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+
+ if(indriver) then
+ call ESMF_GridCompGet(instance_driver, vm=vm, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ call NUOPC_CompAttributeGet(instance_driver, name='read_restart', value=cvalue, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ read(cvalue,*) read_restart
+
+ if (read_restart) then
+
+ call NUOPC_CompAttributeGet(instance_driver, name='drv_restart_pointer', value=restart_file, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- start_ymd = tmp(1) ; start_tod = tmp(2)
- curr_ymd = tmp(3) ; curr_tod = tmp(4)
- else
+ if (trim(restart_file) /= 'none') then
- if (maintask) then
- write(logunit,*) ' NOTE: the current compset has no mediator - which provides the clock restart information'
- write(logunit,*) ' In this case the restarts are handled solely by the component being used and'
- write(logunit,*) ' and the driver clock will always be starting from the initial date on restart'
- end if
- curr_ymd = start_ymd
- curr_tod = start_tod
+ call NUOPC_CompAttributeGet(instance_driver, name="inst_suffix", isPresent=isPresent, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ if(isPresent) then
+ call NUOPC_CompAttributeGet(instance_driver, name="inst_suffix", value=inst_suffix, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ else
+ inst_suffix = ""
+ endif
- end if
+ restart_pfile = trim(restart_file)//inst_suffix
+ if (maintask) then
+ call ESMF_LogWrite(trim(subname)//" read rpointer file = "//trim(restart_pfile), &
+ ESMF_LOGMSG_INFO)
+ open(newunit=unitn, file=restart_pfile, form='FORMATTED', status='old',iostat=ierr)
+ if (ierr < 0) then
+ rc = ESMF_FAILURE
+ call ESMF_LogWrite(trim(subname)//' ERROR rpointer file open returns error', &
+ ESMF_LOGMSG_ERROR, line=__LINE__, file=__FILE__)
+ return
+ end if
+ read(unitn,'(a)', iostat=ierr) restart_file
+ if (ierr < 0) then
+ rc = ESMF_FAILURE
+ call ESMF_LogWrite(trim(subname)//' ERROR rpointer file read returns error', &
+ ESMF_LOGMSG_INFO, line=__LINE__, file=__FILE__)
+ return
+ end if
+ close(unitn)
+ if (maintask) then
+ write(logunit,'(a)') trim(subname)//" reading driver restart from file = "//trim(restart_file)
+ end if
+ call esm_time_read_restart(restart_file, start_ymd, start_tod, curr_ymd, curr_tod, rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ endif
+ else
+ if(maintask) then
+ write(logunit,*) ' NOTE: the current compset has no mediator - which provides the clock restart information'
+ write(logunit,*) ' In this case the restarts are handled solely by the component being used and'
+ write(logunit,*) ' and the driver clock will always be starting from the initial date on restart'
+ end if
+ curr_ymd = start_ymd
+ curr_tod = start_tod
+ endif
+ else
+ curr_ymd = start_ymd
+ curr_tod = start_tod
+ end if ! end if read_restart
+ endif
+ if(maintask) then
+ bcastID(1) = myid
+ tmp(1) = start_ymd ; tmp(2) = start_tod
+ tmp(3) = curr_ymd ; tmp(4) = curr_tod
else
+ bcastID(1) = 0
+ tmp = 0
+ endif
+ call ESMF_VMAllReduce(envm, bcastID(1:1), bcastID(2:2), 1, ESMF_REDUCE_MAX,rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
- curr_ymd = start_ymd
- curr_tod = start_tod
-
- end if ! end if read_restart
+ call ESMF_VMBroadcast(envm, tmp, 4, bcastID(2), rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ start_ymd = tmp(1) ; start_tod = tmp(2)
+ curr_ymd = tmp(3) ; curr_tod = tmp(4)
! Determine start time (THE FOLLOWING ASSUMES THAT THE DEFAULT CALENDAR IS SET in the driver)
@@ -222,7 +275,6 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas
call ESMF_LogWrite(trim(subname)//': driver curr_tod: '// trim(tmpstr), ESMF_LOGMSG_INFO)
write(logunit,*) trim(subname)//': driver curr_tod: '// trim(tmpstr)
endif
-
! Set reference time - HARD-CODED TO START TIME
ref_ymd = start_ymd
ref_tod = start_tod
@@ -230,48 +282,7 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas
call ESMF_TimeSet( RefTime, yy=yr, mm=mon, dd=day, s=ref_tod, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- !---------------------------------------------------------------------------
- ! Determine driver clock timestep
- !---------------------------------------------------------------------------
-
- call NUOPC_CompAttributeGet(instance_driver, name="atm_cpl_dt", value=cvalue, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) atm_cpl_dt
-
- call NUOPC_CompAttributeGet(instance_driver, name="lnd_cpl_dt", value=cvalue, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) lnd_cpl_dt
-
- call NUOPC_CompAttributeGet(instance_driver, name="ice_cpl_dt", value=cvalue, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) ice_cpl_dt
-
- call NUOPC_CompAttributeGet(instance_driver, name="ocn_cpl_dt", value=cvalue, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) ocn_cpl_dt
-
- call NUOPC_CompAttributeGet(instance_driver, name="glc_cpl_dt", value=cvalue, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) glc_cpl_dt
-
- call NUOPC_CompAttributeGet(instance_driver, name="rof_cpl_dt", value=cvalue, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) rof_cpl_dt
-
- call NUOPC_CompAttributeGet(instance_driver, name="wav_cpl_dt", value=cvalue, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) wav_cpl_dt
- call NUOPC_CompAttributeGet(instance_driver, name="glc_avg_period", value=glc_avg_period, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) glc_avg_period
-
- dtime_drv = minval((/atm_cpl_dt, lnd_cpl_dt, ocn_cpl_dt, ice_cpl_dt, glc_cpl_dt, rof_cpl_dt, wav_cpl_dt/))
- if(maintask) then
- write(tmpstr,'(i10)') dtime_drv
- call ESMF_LogWrite(trim(subname)//': driver time interval is : '// trim(tmpstr), ESMF_LOGMSG_INFO, rc=rc)
- write(logunit,*) trim(subname)//': driver time interval is : '// trim(tmpstr)
- endif
call ESMF_TimeIntervalSet( TimeStep, s=dtime_drv, rc=rc )
if (ChkErr(rc,__LINE__,u_FILE_u)) return
@@ -293,20 +304,22 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end do
- ! Set the ensemble driver gridded component clock to the created clock
- call ESMF_GridCompSet(instance_driver, clock=clock, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ ! Set the driver gridded component clock to the created clock
+ if (indriver) then
+ call ESMF_GridCompSet(instance_driver, clock=clock, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ endif
! Set driver clock stop time
- call NUOPC_CompAttributeGet(instance_driver, name="stop_option", value=stop_option, rc=rc)
+ call NUOPC_CompAttributeGet(ensemble_driver, name="stop_option", value=stop_option, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call NUOPC_CompAttributeGet(instance_driver, name="stop_n", value=cvalue, rc=rc)
+ call NUOPC_CompAttributeGet(ensemble_driver, name="stop_n", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) stop_n
- call NUOPC_CompAttributeGet(instance_driver, name="stop_ymd", value=cvalue, rc=rc)
+ call NUOPC_CompAttributeGet(ensemble_driver, name="stop_ymd", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) stop_ymd
- call NUOPC_CompAttributeGet(instance_driver, name="stop_tod", value=cvalue, rc=rc)
+ call NUOPC_CompAttributeGet(ensemble_driver, name="stop_tod", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) stop_tod
if ( stop_ymd < 0) then
@@ -341,17 +354,17 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas
!---------------------------------------------------------------------------
! Create the ensemble driver clock
- ! TODO: this is done repeatedly - but only needs to be done the first time this is called
!---------------------------------------------------------------------------
+ if(firsttime) then
+ TimeStep = StopTime - ClockTime
+ clock = ESMF_ClockCreate(TimeStep, ClockTime, StopTime=StopTime, &
+ refTime=RefTime, name='ESMF ensemble Driver Clock', rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
- TimeStep = StopTime - ClockTime
- clock = ESMF_ClockCreate(TimeStep, ClockTime, StopTime=StopTime, &
- refTime=RefTime, name='ESMF ensemble Driver Clock', rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
-
- call ESMF_GridCompSet(ensemble_driver, clock=clock, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
-
+ call ESMF_GridCompSet(ensemble_driver, clock=clock, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ firsttime = .false.
+ endif
end subroutine esm_time_clockInit
!===============================================================================
diff --git a/cesm/nuopc_cap_share/driver_pio_mod.F90 b/cesm/nuopc_cap_share/driver_pio_mod.F90
index 43d913c6d..710373ed9 100644
--- a/cesm/nuopc_cap_share/driver_pio_mod.F90
+++ b/cesm/nuopc_cap_share/driver_pio_mod.F90
@@ -1,9 +1,12 @@
module driver_pio_mod
- use pio
+ use pio , only : pio_offset_kind, pio_rearr_opt_t, PIO_REARR_COMM_UNLIMITED_PEND_REQ
+ use pio , only : pio_iotype_netcdf, pio_iotype_pnetcdf, pio_iotype_netcdf4c, pio_iotype_netcdf4p
+ use pio , only : iosystem_desc_t, PIO_64BIT_DATA, PIO_64BIT_OFFSET, PIO_REARR_COMM_COLL
+ use pio , only : PIO_REARR_COMM_P2P, pio_init, pio_set_log_level
+ use pio , only : pio_set_blocksize, pio_set_buffer_size_limit, pio_finalize
use shr_pio_mod, only : io_compname, pio_comp_settings, iosystems, io_compid, shr_pio_getindex
use shr_kind_mod, only : CS=>shr_kind_CS, shr_kind_cl, shr_kind_in
- use shr_log_mod, only : shr_log_unit
- use shr_mpi_mod, only : shr_mpi_bcast, shr_mpi_chkerr
+ use shr_log_mod, only : shr_log_getLogUnit
use shr_sys_mod, only : shr_sys_abort
#ifndef NO_MPI2
use mpi, only : mpi_comm_null, mpi_comm_world, mpi_finalize
@@ -17,14 +20,14 @@ module driver_pio_mod
public :: driver_pio_init
public :: driver_pio_component_init
public :: driver_pio_finalize
- public :: driver_pio_log_comp_settings
+ private :: driver_pio_log_comp_settings
integer :: io_comm
integer :: pio_debug_level=0, pio_blocksize=0
integer(kind=pio_offset_kind) :: pio_buffer_size_limit=-1
type(pio_rearr_opt_t) :: pio_rearr_opts
- logical, allocatable :: pio_async_interface(:)
+ logical :: pio_async_interface
integer :: total_comps
logical :: maintask
@@ -62,11 +65,13 @@ subroutine driver_pio_init(driver, rc)
character(len=shr_kind_cl) :: nlfilename, cname
integer :: ret
integer :: localPet
+ integer :: logunit
character(len=CS) :: pio_rearr_comm_type, pio_rearr_comm_fcd
character(CS) :: msgstr
character(*), parameter :: subName = '(driver_pio_init) '
-
+
+ call shr_log_getLogUnit(logunit)
call ESMF_GridCompGet(driver, vm=vm, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
@@ -80,7 +85,7 @@ subroutine driver_pio_init(driver, rc)
! 0 is a valid value of pio_buffer_size_limit
if(pio_buffer_size_limit>=0) then
- if(maintask) write(shr_log_unit,*) 'Setting pio_buffer_size_limit : ',pio_buffer_size_limit
+ if(maintask) write(logunit,*) 'Setting pio_buffer_size_limit : ',pio_buffer_size_limit
call pio_set_buffer_size_limit(pio_buffer_size_limit)
endif
@@ -89,7 +94,7 @@ subroutine driver_pio_init(driver, rc)
read(cname, *) pio_blocksize
if(pio_blocksize>0) then
- if(maintask) write(shr_log_unit,*) 'Setting pio_blocksize : ',pio_blocksize
+ if(maintask) write(logunit,*) 'Setting pio_blocksize : ',pio_blocksize
call pio_set_blocksize(pio_blocksize)
endif
@@ -98,7 +103,7 @@ subroutine driver_pio_init(driver, rc)
read(cname, *) pio_debug_level
if(pio_debug_level > 0) then
- if(maintask) write(shr_log_unit,*) 'Setting pio_debug_level : ',pio_debug_level
+ if(maintask) write(logunit,*) 'Setting pio_debug_level : ',pio_debug_level
ret = pio_set_log_level(pio_debug_level)
endif
@@ -120,22 +125,22 @@ subroutine driver_pio_init(driver, rc)
call NUOPC_CompAttributeGet(driver, name="pio_rearr_comm_enable_hs_comp2io", value=cname, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
- pio_rearr_opts%comm_fc_opts_comp2io%enable_hs = (trim(cname) .eq. '.true.')
+ pio_rearr_opts%comm_fc_opts_comp2io%enable_hs = logical((trim(cname) .eq. '.true.'), kind=1)
call NUOPC_CompAttributeGet(driver, name="pio_rearr_comm_enable_hs_io2comp", value=cname, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
- pio_rearr_opts%comm_fc_opts_io2comp%enable_hs = (trim(cname) .eq. '.true.')
+ pio_rearr_opts%comm_fc_opts_io2comp%enable_hs = logical((trim(cname) .eq. '.true.'), kind=1)
call NUOPC_CompAttributeGet(driver, name="pio_rearr_comm_enable_isend_comp2io", value=cname, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
- pio_rearr_opts%comm_fc_opts_comp2io%enable_isend = (trim(cname) .eq. '.true.')
+ pio_rearr_opts%comm_fc_opts_comp2io%enable_isend = logical((trim(cname) .eq. '.true.'), kind=1)
call NUOPC_CompAttributeGet(driver, name="pio_rearr_comm_enable_isend_io2comp", value=cname, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
- pio_rearr_opts%comm_fc_opts_io2comp%enable_isend = (trim(cname) .eq. '.true.')
+ pio_rearr_opts%comm_fc_opts_io2comp%enable_isend = logical((trim(cname) .eq. '.true.'), kind=1)
call NUOPC_CompAttributeGet(driver, name="pio_rearr_comm_max_pend_req_comp2io", value=cname, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
@@ -147,98 +152,169 @@ subroutine driver_pio_init(driver, rc)
if(maintask) then
! Log the rearranger options
- write(shr_log_unit, *) "PIO rearranger options:"
- write(shr_log_unit, *) " comm type = ", pio_rearr_opts%comm_type, " (",trim(pio_rearr_comm_type),")"
- write(shr_log_unit, *) " comm fcd = ", pio_rearr_opts%fcd, " (",trim(pio_rearr_comm_fcd),")"
+ write(logunit, *) "PIO rearranger options:"
+ write(logunit, *) " comm type = ", pio_rearr_opts%comm_type, " (",trim(pio_rearr_comm_type),")"
+ write(logunit, *) " comm fcd = ", pio_rearr_opts%fcd, " (",trim(pio_rearr_comm_fcd),")"
if(pio_rearr_opts%comm_fc_opts_comp2io%max_pend_req == PIO_REARR_COMM_UNLIMITED_PEND_REQ) then
- write(shr_log_unit, *) " max pend req (comp2io) = PIO_REARR_COMM_UNLIMITED_PEND_REQ (-1)"
+ write(logunit, *) " max pend req (comp2io) = PIO_REARR_COMM_UNLIMITED_PEND_REQ (-1)"
else
- write(shr_log_unit, *) " max pend req (comp2io) = ", pio_rearr_opts%comm_fc_opts_comp2io%max_pend_req
+ write(logunit, *) " max pend req (comp2io) = ", pio_rearr_opts%comm_fc_opts_comp2io%max_pend_req
end if
- write(shr_log_unit, *) " enable_hs (comp2io) = ", pio_rearr_opts%comm_fc_opts_comp2io%enable_hs
- write(shr_log_unit, *) " enable_isend (comp2io) = ", pio_rearr_opts%comm_fc_opts_comp2io%enable_isend
+ write(logunit, *) " enable_hs (comp2io) = ", pio_rearr_opts%comm_fc_opts_comp2io%enable_hs
+ write(logunit, *) " enable_isend (comp2io) = ", pio_rearr_opts%comm_fc_opts_comp2io%enable_isend
if(pio_rearr_opts%comm_fc_opts_io2comp%max_pend_req == PIO_REARR_COMM_UNLIMITED_PEND_REQ) then
- write(shr_log_unit, *) " max pend req (io2comp) = PIO_REARR_COMM_UNLIMITED_PEND_REQ (-1)"
+ write(logunit, *) " max pend req (io2comp) = PIO_REARR_COMM_UNLIMITED_PEND_REQ (-1)"
else
- write(shr_log_unit, *) " max pend req (io2comp) = ", pio_rearr_opts%comm_fc_opts_io2comp%max_pend_req
+ write(logunit, *) " max pend req (io2comp) = ", pio_rearr_opts%comm_fc_opts_io2comp%max_pend_req
end if
- write(shr_log_unit, *) " enable_hs (io2comp) = ", pio_rearr_opts%comm_fc_opts_io2comp%enable_hs
- write(shr_log_unit, *) " enable_isend (io2comp) = ", pio_rearr_opts%comm_fc_opts_io2comp%enable_isend
+ write(logunit, *) " enable_hs (io2comp) = ", pio_rearr_opts%comm_fc_opts_io2comp%enable_hs
+ write(logunit, *) " enable_isend (io2comp) = ", pio_rearr_opts%comm_fc_opts_io2comp%enable_isend
end if
end subroutine driver_pio_init
- subroutine driver_pio_component_init(driver, ncomps, rc)
+ subroutine driver_pio_component_init(driver, inst_comm, asyncio_petlist, rc)
use ESMF, only : ESMF_GridComp, ESMF_LogSetError, ESMF_RC_NOT_VALID, ESMF_GridCompIsCreated, ESMF_VM, ESMF_VMGet
- use ESMF, only : ESMF_GridCompGet, ESMF_GridCompIsPetLocal, ESMF_VMIsCreated
+ use ESMF, only : ESMF_GridCompGet, ESMF_GridCompIsPetLocal, ESMF_VMIsCreated, ESMF_Finalize, ESMF_PtrInt1D
+ use ESMF, only : ESMF_LOGMSG_INFO, ESMF_LOGWRITE
use NUOPC, only : NUOPC_CompAttributeGet, NUOPC_CompAttributeSet, NUOPC_CompAttributeAdd
use NUOPC_Driver, only : NUOPC_DriverGetComp
+ use mpi, only : MPI_INTEGER, MPI_MAX, MPI_IN_PLACE, MPI_LOR, MPI_LOGICAL
type(ESMF_GridComp) :: driver
- type(ESMF_VM) :: vm
- integer, intent(in) :: ncomps
+ integer, intent(in) :: asyncio_petlist(:)
+ integer, intent(in) :: Inst_comm ! The communicator associated with the driver
integer, intent(out) :: rc
+ type(ESMF_VM) :: vm
integer :: i, npets, default_stride
- integer :: j
+ integer :: j, myid
+ integer :: k
integer :: comp_comm, comp_rank
+ integer, allocatable :: procs_per_comp(:), async_procs_per_comp(:)
+ integer, allocatable :: io_proc_list(:), asyncio_tasks(:), comp_proc_list(:,:)
+
type(ESMF_GridComp), pointer :: gcomp(:)
+
character(CS) :: cval
character(CS) :: msgstr
integer :: do_async_init
+ integer :: totalpes
+ integer :: asyncio_ntasks
+ integer :: asyncio_stride
+ integer :: pecnt
+ integer :: ierr
+ integer :: iocomm
+ integer :: pp
+ integer :: async_rearr
+ integer :: maxprocspercomp, driver_myid
+ integer, allocatable :: driverpetlist(:)
+ integer, allocatable :: asyncio_comp_comm(:)
+ integer :: logunit
+ integer :: ioproc
+ integer :: n
+ logical :: asyncio_task
+ logical, allocatable :: petlocal(:)
+ type(ESMF_PtrInt1D), pointer :: petLists(:)
type(iosystem_desc_t), allocatable :: async_iosystems(:)
+ character(len=*), parameter :: subname = '('//__FILE__//':shr_pio_component_init)'
+
+ asyncio_ntasks = size(asyncio_petlist)
- allocate(pio_comp_settings(ncomps))
- allocate(gcomp(ncomps))
+ call shr_log_getLogUnit(logunit)
+ call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
- allocate(io_compid(ncomps))
- allocate(io_compname(ncomps))
- allocate(iosystems(ncomps))
+ call MPI_Comm_rank(Inst_comm, myid, rc)
+ call MPI_Comm_size(Inst_comm, totalpes, rc)
- allocate(pio_async_interface(ncomps))
+ asyncio_task=.false.
+ do i=1,asyncio_ntasks
+ ! asyncio_petlist is in
+ if(asyncio_petlist(i) == myid) then
+ asyncio_task = .true.
+ exit
+ endif
+ enddo
+ write(msgstr,*) 'asyncio_task = ', asyncio_task, myid, asyncio_petlist
+ call ESMF_LogWrite(trim(subname)//msgstr, ESMF_LOGMSG_INFO, rc=rc)
nullify(gcomp)
- do_async_init = 0
+ nullify(petLists)
+ if (.not. asyncio_task) then
+ call ESMF_GridCompGet(gridcomp=driver, vm=vm, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call ESMF_VMGet(vm, localPet=driver_myid, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call NUOPC_DriverGetComp(driver, compList=gcomp, petLists=petLists, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ endif
+ if(associated(gcomp)) then
+ total_comps = size(gcomp)
+ else
+ total_comps = 0
+ endif
- call NUOPC_DriverGetComp(driver, compList=gcomp, rc=rc)
+ call ESMF_LogWrite(trim(subname)//": share total_comps and driverpecount", ESMF_LOGMSG_INFO)
if (chkerr(rc,__LINE__,u_FILE_u)) return
+ if(totalpes > 1) then
+ call MPI_AllReduce(MPI_IN_PLACE, total_comps, 1, MPI_INTEGER, &
+ MPI_MAX, Inst_comm, rc)
+ endif
+
+ allocate(pio_comp_settings(total_comps))
+ allocate(procs_per_comp(total_comps))
+ allocate(io_compid(total_comps))
+ allocate(io_compname(total_comps))
+ allocate(iosystems(total_comps))
+ allocate(petlocal(total_comps))
+ do_async_init = 0
+ procs_per_comp = 0
- total_comps = size(gcomp)
-
do i=1,total_comps
- io_compid(i) = i+1
+ if(associated(gcomp)) then
+ petlocal(i) = ESMF_GridCompIsPetLocal(gcomp(i), rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
- if (ESMF_GridCompIsPetLocal(gcomp(i), rc=rc)) then
- call ESMF_GridCompGet(gcomp(i), vm=vm, name=cval, rc=rc)
+ call NUOPC_CompAttributeGet(gcomp(i), name="pio_async_interface", value=cval, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
+ pio_comp_settings(i)%pio_async_interface = (trim(cval) == '.true.')
- io_compname(i) = trim(cval)
-
+ call NUOPC_CompAttributeGet(gcomp(i), name="pio_rearranger", value=cval, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ read(cval, *) pio_comp_settings(i)%pio_rearranger
+ else
+ petlocal(i) = .false.
+ endif
+ pio_comp_settings(i)%pio_async_interface = .false.
+ io_compid(i) = i+1
+
+ if (petlocal(i)) then
call NUOPC_CompAttributeAdd(gcomp(i), attrList=(/'MCTID'/), rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
-
write(cval, *) io_compid(i)
call NUOPC_CompAttributeSet(gcomp(i), name="MCTID", value=trim(cval), rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- call ESMF_VMGet(vm, mpiCommunicator=comp_comm, rc=rc)
+
+ call ESMF_GridCompGet(gcomp(i), vm=vm, name=cval, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call ESMF_LogWrite(trim(subname)//": initialize component: "//trim(cval), ESMF_LOGMSG_INFO)
+ io_compname(i) = trim(cval)
- if(comp_comm .ne. MPI_COMM_NULL) then
- call ESMF_VMGet(vm, petCount=npets, localPet=comp_rank, ssiLocalPetCount=default_stride, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call ESMF_VMGet(vm, mpiCommunicator=comp_comm, localPet=comp_rank, petCount=npets, &
+ ssiLocalPetCount=default_stride, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ procs_per_comp(i) = npets
+
+ if(.not. pio_comp_settings(i)%pio_async_interface) then
call NUOPC_CompAttributeGet(gcomp(i), name="pio_stride", value=cval, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
read(cval, *) pio_comp_settings(i)%pio_stride
if(pio_comp_settings(i)%pio_stride <= 0 .or. pio_comp_settings(i)%pio_stride > npets) then
pio_comp_settings(i)%pio_stride = min(npets, default_stride)
endif
-
- call NUOPC_CompAttributeGet(gcomp(i), name="pio_rearranger", value=cval, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- read(cval, *) pio_comp_settings(i)%pio_rearranger
-
+
call NUOPC_CompAttributeGet(gcomp(i), name="pio_numiotasks", value=cval, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
read(cval, *) pio_comp_settings(i)%pio_numiotasks
@@ -247,84 +323,167 @@ subroutine driver_pio_component_init(driver, ncomps, rc)
pio_comp_settings(i)%pio_numiotasks = max(1,npets/pio_comp_settings(i)%pio_stride)
endif
+
call NUOPC_CompAttributeGet(gcomp(i), name="pio_root", value=cval, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
read(cval, *) pio_comp_settings(i)%pio_root
-
+
if(pio_comp_settings(i)%pio_root < 0 .or. pio_comp_settings(i)%pio_root > npets) then
pio_comp_settings(i)%pio_root = 0
endif
+ endif
+
+ call NUOPC_CompAttributeGet(gcomp(i), name="pio_typename", value=cval, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
- call NUOPC_CompAttributeGet(gcomp(i), name="pio_typename", value=cval, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- select case (trim(cval))
- case ('pnetcdf')
- pio_comp_settings(i)%pio_iotype = PIO_IOTYPE_PNETCDF
- case ('netcdf')
- pio_comp_settings(i)%pio_iotype = PIO_IOTYPE_NETCDF
- case ('netcdf4p')
- pio_comp_settings(i)%pio_iotype = PIO_IOTYPE_NETCDF4P
- case ('netcdf4c')
- pio_comp_settings(i)%pio_iotype = PIO_IOTYPE_NETCDF4C
- case DEFAULT
- write (msgstr, *) "Invalid PIO_TYPENAME Setting for component ", trim(cval)
- call ESMF_LogSetError(ESMF_RC_NOT_VALID, msg=msgstr, line=__LINE__, file=__FILE__, rcToReturn=rc)
- return
- end select
-
- call NUOPC_CompAttributeGet(gcomp(i), name="pio_async_interface", value=cval, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- pio_async_interface(i) = (trim(cval) == '.true.')
-
- call NUOPC_CompAttributeGet(gcomp(i), name="pio_netcdf_format", value=cval, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- call driver_pio_getioformatfromname(cval, pio_comp_settings(i)%pio_netcdf_ioformat, PIO_64BIT_DATA)
-
- if (pio_async_interface(i)) then
- do_async_init = do_async_init + 1
- else
- if(pio_rearr_opts%comm_fc_opts_io2comp%max_pend_req < PIO_REARR_COMM_UNLIMITED_PEND_REQ) then
- pio_rearr_opts%comm_fc_opts_io2comp%max_pend_req = pio_comp_settings(i)%pio_numiotasks
- endif
- if(pio_rearr_opts%comm_fc_opts_comp2io%max_pend_req < PIO_REARR_COMM_UNLIMITED_PEND_REQ) then
- pio_rearr_opts%comm_fc_opts_comp2io%max_pend_req = pio_comp_settings(i)%pio_numiotasks
- endif
- call pio_init(comp_rank ,comp_comm ,pio_comp_settings(i)%pio_numiotasks, 0, pio_comp_settings(i)%pio_stride, &
- pio_comp_settings(i)%pio_rearranger, iosystems(i), pio_comp_settings(i)%pio_root, &
- pio_rearr_opts)
+ select case (trim(cval))
+ case ('pnetcdf')
+ pio_comp_settings(i)%pio_iotype = PIO_IOTYPE_PNETCDF
+ case ('netcdf')
+ pio_comp_settings(i)%pio_iotype = PIO_IOTYPE_NETCDF
+ case ('netcdf4p')
+ pio_comp_settings(i)%pio_iotype = PIO_IOTYPE_NETCDF4P
+ case ('netcdf4c')
+ pio_comp_settings(i)%pio_iotype = PIO_IOTYPE_NETCDF4C
+ case DEFAULT
+ write (msgstr, *) "Invalid PIO_TYPENAME Setting for component ", trim(cval)
+ call ESMF_LogSetError(ESMF_RC_NOT_VALID, msg=msgstr, line=__LINE__, file=__FILE__, rcToReturn=rc)
+ return
+ end select
+
+ call NUOPC_CompAttributeGet(gcomp(i), name="pio_netcdf_format", value=cval, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call driver_pio_getioformatfromname(cval, pio_comp_settings(i)%pio_netcdf_ioformat, PIO_64BIT_DATA)
+
+ if (.not. pio_comp_settings(i)%pio_async_interface) then
+ if(pio_rearr_opts%comm_fc_opts_io2comp%max_pend_req < PIO_REARR_COMM_UNLIMITED_PEND_REQ) then
+ pio_rearr_opts%comm_fc_opts_io2comp%max_pend_req = pio_comp_settings(i)%pio_numiotasks
+ endif
+ if(pio_rearr_opts%comm_fc_opts_comp2io%max_pend_req < PIO_REARR_COMM_UNLIMITED_PEND_REQ) then
+ pio_rearr_opts%comm_fc_opts_comp2io%max_pend_req = pio_comp_settings(i)%pio_numiotasks
endif
+
+ call pio_init(comp_rank ,comp_comm ,pio_comp_settings(i)%pio_numiotasks, 0, pio_comp_settings(i)%pio_stride, &
+ pio_comp_settings(i)%pio_rearranger, iosystems(i), pio_comp_settings(i)%pio_root, &
+ pio_rearr_opts)
endif
+ ! Write the PIO settings to the beggining of each component log
+ if(comp_rank == 0) call driver_pio_log_comp_settings(gcomp(i), rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+
endif
enddo
+
+ call ESMF_LogWrite(trim(subname)//": check for async", ESMF_LOGMSG_INFO)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ do i=1,total_comps
+ call MPI_AllReduce(MPI_IN_PLACE, pio_comp_settings(i)%pio_async_interface, 1, MPI_LOGICAL, &
+ MPI_LOR, Inst_comm, rc)
+ if(pio_comp_settings(i)%pio_async_interface) then
+ do_async_init = do_async_init + 1
+ endif
+ enddo
+
+!
+! Get the PET list for each component using async IO
+!
+
+ call MPI_Allreduce(MPI_IN_PLACE, do_async_init, 1, MPI_INTEGER, MPI_MAX, Inst_comm, ierr)
+ call MPI_Allreduce(MPI_IN_PLACE, procs_per_comp, total_comps, MPI_INTEGER, MPI_MAX, Inst_comm, ierr)
if (do_async_init > 0) then
+ maxprocspercomp = 0
+ do i=1,total_comps
+ if(procs_per_comp(i) > maxprocspercomp) maxprocspercomp = procs_per_comp(i)
+ enddo
+ call MPI_AllReduce(MPI_IN_PLACE, maxprocspercomp, 1, MPI_INTEGER, &
+ MPI_MAX, Inst_comm, rc)
+
+ allocate(asyncio_comp_comm(do_async_init))
+ allocate(comp_proc_list(maxprocspercomp, do_async_init))
+ j = 1
+ k = 1
+ comp_proc_list = -1
+ if(.not. asyncio_task) then
+ do i=1,total_comps
+ if(pio_comp_settings(i)%pio_async_interface) then
+ comp_proc_list(1:procs_per_comp(i), j) = petLists(i)%ptr
+ ! IO tasks are not in the driver comp so we need to correct the comp_proc_list
+ do k=1,size(asyncio_petlist)
+ ioproc = asyncio_petlist(k)
+ do n=1,procs_per_comp(i)
+ if(petLists(i)%ptr(n) >= (ioproc-k+1)) comp_proc_list(n,j) = comp_proc_list(n,j) + 1
+ enddo
+ enddo
+ j = j+1
+ endif
+! deallocate(petLists(i)%ptr)
+ enddo
+ endif
+ ! Copy comp_proc_list to io tasks
+ do i=1,do_async_init
+ call MPI_AllReduce(MPI_IN_PLACE, comp_proc_list(:,i), maxprocspercomp, MPI_INTEGER, MPI_MAX, Inst_comm, ierr)
+ enddo
+ if(asyncio_ntasks == 0) then
+ call shr_sys_abort(subname//' ERROR: ASYNC IO Requested but no IO PES assigned')
+ endif
+
allocate(async_iosystems(do_async_init))
+ allocate(async_procs_per_comp(do_async_init))
j=1
+ async_rearr = 0
do i=1,total_comps
- if(pio_async_interface(i)) then
- iosystems(i) = async_iosystems(j)
+ if(pio_comp_settings(i)%pio_async_interface) then
+ async_procs_per_comp(j) = procs_per_comp(i)
j = j+1
+ if(.not.asyncio_task) then
+ if(async_rearr == 0) then
+ async_rearr = pio_comp_settings(i)%pio_rearranger
+ elseif(async_rearr .ne. pio_comp_settings(i)%pio_rearranger .and. pio_comp_settings(i)%pio_rearranger > 0) then
+ write(msgstr,*) i,async_rearr,pio_comp_settings(i)%pio_rearranger
+ call shr_sys_abort(subname//' ERROR: all async component rearrangers must match '//msgstr)
+ endif
+ endif
endif
enddo
+ ! IO tasks should not return until the run is completed
+ !ierr = pio_set_log_level(1)
+ call ESMF_LogWrite(trim(subname)//": call async pio_init", ESMF_LOGMSG_INFO)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call MPI_AllReduce(MPI_IN_PLACE, async_rearr, 1, MPI_INTEGER, &
+ MPI_MAX, Inst_comm, rc)
+ call pio_init(async_iosystems, Inst_comm, async_procs_per_comp, &
+ comp_proc_list, asyncio_petlist, &
+ async_rearr, asyncio_comp_comm, io_comm)
+ if(.not. asyncio_task) then
+ j=1
+ do i=1,total_comps
+ if(pio_comp_settings(i)%pio_async_interface) then
+ iosystems(i) = async_iosystems(j)
+ j = j+1
+ endif
+ enddo
+ endif
endif
-
- deallocate(gcomp)
+ call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO)
+ if(associated(petLists)) deallocate(petLists)
+ if(associated(gcomp)) deallocate(gcomp)
end subroutine driver_pio_component_init
- subroutine driver_pio_log_comp_settings(gcomp, logunit)
- use ESMF, only : ESMF_GridComp, ESMF_GridCompGet
+ subroutine driver_pio_log_comp_settings(gcomp, rc)
+ use ESMF, only : ESMF_GridComp, ESMF_GridCompGet, ESMF_SUCCESS
use NUOPC, only: NUOPC_CompAttributeGet
-
+ use, intrinsic :: iso_fortran_env, only: output_unit
+
type(ESMF_GridComp) :: gcomp
- integer, intent(in) :: logunit
-
+ integer, intent(out) :: rc
integer :: compid
character(len=CS) :: name, cval
integer :: i
- integer :: rc
+ integer :: logunit
logical :: isPresent
+ rc = ESMF_SUCCESS
call ESMF_GridCompGet(gcomp, name=name, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
@@ -335,21 +494,29 @@ subroutine driver_pio_log_comp_settings(gcomp, logunit)
read(cval, *) compid
i = shr_pio_getindex(compid)
endif
- write(logunit,*) trim(name),': PIO numiotasks=', pio_comp_settings(i)%pio_numiotasks
-
- write(logunit, *) trim(name), ': PIO stride=',pio_comp_settings(i)%pio_stride
-
- write(logunit, *) trim(name),': PIO rearranger=',pio_comp_settings(i)%pio_rearranger
- write(logunit, *) trim(name),': PIO root=',pio_comp_settings(i)%pio_root
-
+ logunit = 6
+ call NUOPC_CompAttributeGet(gcomp, name="logunit", value=logunit, isPresent=ispresent, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ if(.not. isPresent) then
+ logunit = output_unit
+ if(maintask) write(logunit,*) 'Attribute logunit not set for ',trim(name)
+ endif
+ if(pio_comp_settings(i)%pio_async_interface) then
+ write(logunit,*) trim(name),': using ASYNC IO interface'
+ else
+ write(logunit,*) trim(name),': PIO numiotasks=', pio_comp_settings(i)%pio_numiotasks
+ write(logunit, *) trim(name), ': PIO stride=',pio_comp_settings(i)%pio_stride
+ write(logunit, *) trim(name),': PIO rearranger=',pio_comp_settings(i)%pio_rearranger
+ write(logunit, *) trim(name),': PIO root=',pio_comp_settings(i)%pio_root
+ endif
end subroutine driver_pio_log_comp_settings
!===============================================================================
subroutine driver_pio_finalize( )
integer :: ierr
integer :: i
- do i=1,total_comps
+ do i=1,size(iosystems)
call pio_finalize(iosystems(i), ierr)
end do
@@ -383,6 +550,10 @@ subroutine driver_pio_getiotypefromname(typename, iotype, defaulttype)
integer, intent(out) :: iotype
integer, intent(in) :: defaulttype
+ integer :: logunit
+
+ call shr_log_getLogUnit(logunit)
+
typename = shr_string_toupper(typename)
if ( typename .eq. 'NETCDF' ) then
iotype = pio_iotype_netcdf
@@ -397,7 +568,7 @@ subroutine driver_pio_getiotypefromname(typename, iotype, defaulttype)
else if ( typename .eq. 'DEFAULT') then
iotype = defaulttype
else
- write(shr_log_unit,*) 'driver_pio_mod: WARNING Bad io_type argument - using iotype_netcdf'
+ write(logunit,*) 'driver_pio_mod: WARNING Bad io_type argument - using iotype_netcdf'
iotype=pio_iotype_netcdf
end if
diff --git a/cesm/nuopc_cap_share/nuopc_shr_methods.F90 b/cesm/nuopc_cap_share/nuopc_shr_methods.F90
index 3d50906d7..9062b27f1 100644
--- a/cesm/nuopc_cap_share/nuopc_shr_methods.F90
+++ b/cesm/nuopc_cap_share/nuopc_shr_methods.F90
@@ -130,9 +130,8 @@ subroutine get_component_instance(gcomp, inst_suffix, inst_index, rc)
end subroutine get_component_instance
!===============================================================================
-
subroutine set_component_logging(gcomp, maintask, logunit, shrlogunit, rc)
- use driver_pio_mod, only : driver_pio_log_comp_settings
+ use NUOPC, only: NUOPC_CompAttributeSet, NUOPC_CompAttributeAdd
! input/output variables
type(ESMF_GridComp) :: gcomp
logical, intent(in) :: maintask
@@ -144,8 +143,10 @@ subroutine set_component_logging(gcomp, maintask, logunit, shrlogunit, rc)
character(len=CL) :: diro
character(len=CL) :: logfile
character(len=CL) :: inst_suffix
- integer :: inst_index ! not used here
+ integer :: inst_index ! Not used here
integer :: n
+ character(len=CL) :: name
+ character(len=*), parameter :: subname = "("//__FILE__//": set_component_logging)"
!-----------------------------------------------------------------------
rc = ESMF_SUCCESS
@@ -164,16 +165,23 @@ subroutine set_component_logging(gcomp, maintask, logunit, shrlogunit, rc)
endif
open(newunit=logunit,file=trim(diro)//"/"//trim(logfile))
- ! Write the PIO settings to the beggining of each component log
- call driver_pio_log_comp_settings(gcomp, logunit)
else
logUnit = 6
endif
- shrlogunit = logunit
+
+ call ESMF_GridCompGet(gcomp, name=name, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call ESMF_LogWrite(trim(subname)//": setting logunit for component: "//trim(name), ESMF_LOGMSG_INFO)
+ call NUOPC_CompAttributeAdd(gcomp, (/"logunit"/), rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call NUOPC_CompAttributeSet(gcomp, "logunit", logunit, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
call shr_log_setLogUnit (logunit)
-
+ ! Still need to set this return value
+ shrlogunit = logunit
+ call ESMF_LogWrite(trim(subname)//": done for component "//trim(name), ESMF_LOGMSG_INFO)
end subroutine set_component_logging
!===============================================================================
diff --git a/cesm/nuopc_cap_share/shr_expr_parser_mod.F90 b/cesm/nuopc_cap_share/shr_expr_parser_mod.F90
index f37a4ac3c..4cf748a35 100644
--- a/cesm/nuopc_cap_share/shr_expr_parser_mod.F90
+++ b/cesm/nuopc_cap_share/shr_expr_parser_mod.F90
@@ -1,12 +1,12 @@
!=============================================================================
! expression parser utility --
! for parsing simple linear mathematical expressions of the form
-! X = a*Y + b*Z + ...
+! X = a*R + b*S + c*(X + Y + Z) ...
!
!=============================================================================
module shr_expr_parser_mod
use shr_kind_mod,only : r8 => shr_kind_r8
- use shr_kind_mod,only : cx => shr_kind_cx
+ use shr_kind_mod,only : CXX => shr_kind_cxx
implicit none
private
@@ -35,82 +35,122 @@ function shr_exp_parse( exp_array, nitems ) result(exp_items_list)
integer, optional, intent(out) :: nitems ! number of expressions parsed
type(shr_exp_item_t), pointer :: exp_items_list ! linked list of items returned
- integer :: i,j, jj, nmax, nterms, n_exp_items
- character(len=cx) :: tmp_str
+ integer :: i,j, n_exp_items
type(shr_exp_item_t), pointer :: exp_item, list_item
+ integer :: ndxs(512)
+ integer :: nelem, j1,j2,k
+ character(len=CXX) :: tmp_str, tmp_name
+ character(len=8) :: xchr ! multipler
+ real(r8) :: xdbl
+ real(r8) :: coeff0
+ logical :: more_to_come
+ character(len=CXX), allocatable :: sums_grps(:)
+ character(len=CXX) :: sum_string
+
+ allocate(sums_grps(size(exp_array)))
nullify( exp_items_list )
nullify( exp_item )
nullify( list_item )
- n_exp_items = 0
- nmax = size( exp_array )
+ sums_grps(:) = ' '
- do i = 1,nmax
- if (len_trim(exp_array(i))>0) then
+ ! combine lines that have a trailing "+" with the next line
+ i=1
+ j=1
+ loop1: do while( len_trim(exp_array(i)) > 0 )
- j = scan( exp_array(i), '=' )
+ k = scan(exp_array(i), '+', back=.true. )
+ more_to_come = k == len_trim(exp_array(i)) ! line ends with "+"
- if ( j>0 ) then
+ if ( more_to_come ) then
+ sums_grps(j) = trim(sums_grps(j)) // trim(adjustl(exp_array(i)))
+ else
+ sums_grps(j) = trim(sums_grps(j)) // trim(adjustl(exp_array(i)))
+ j = j+1
+ endif
+
+ i = i+1
+ if ( i > size(exp_array) ) exit loop1
- n_exp_items = n_exp_items + 1
+ end do loop1
- allocate( exp_item )
- exp_item%n_terms = 0
- exp_item%name = trim(adjustl(exp_array(i)(:j-1)))
+ n_exp_items = j-1
- tmp_str = trim(adjustl(exp_array(i)(j+1:)))
+ ! a group is a summation of terms
- nterms = 1
- jj = scan( tmp_str, '+' )
- do while(jj>0)
- nterms = nterms + 1
- tmp_str = tmp_str(jj+1:)
- jj = scan( tmp_str, '+' )
- enddo
+ ! parse the individual sum strings... and form the groupings
+ has_grps: if (n_exp_items>0) then
- allocate( exp_item%vars(nterms) )
- allocate( exp_item%coeffs(nterms) )
+ ! from shr_megan_mod ... should be generalized and shared...
+ grploop: do i = 1,n_exp_items
- tmp_str = trim(adjustl(exp_array(i)(j+1:)))
+ ! parse out the term names
+ ! from first parsing out the terms in the summation equation ("+" separates the terms)
+ sum_string = sums_grps(i)
+ j = scan( sum_string, '=' )
+ nelem = 1
+ ndxs(nelem) = j ! ndxs stores the index of each term of the equation
+
+ ! find indices of all the terms in the equation
+ tmp_str = trim( sum_string(j+1:) )
+ j = scan( tmp_str, '+' )
+ do while(j>0)
+ nelem = nelem+1
+ ndxs(nelem) = ndxs(nelem-1) + j
+ tmp_str = tmp_str(j+1:)
j = scan( tmp_str, '+' )
+ enddo
+ ndxs(nelem+1) = len(sum_string)+1
- if (j>0) then
- call set_coefvar( tmp_str(:j-1), exp_item )
- tmp_str = tmp_str(j-1:)
- else
- call set_coefvar( tmp_str, exp_item )
- endif
+ allocate( exp_item )
- else
+ exp_item%n_terms = nelem ! number of terms
- tmp_str = trim(adjustl(exp_array(i))) ! assumed to begin with '+'
+ exp_item%name = trim(adjustl( sum_string(:ndxs(1)-1))) ! thing to the left of the "=" is used as the name of the group
- endif
+ ! now that we have the number of terms in the summation allocate memory for the terms
+ allocate( exp_item%vars(nelem) )
+ allocate( exp_item%coeffs(nelem) )
- ! at this point tmp_str begins with '+'
- j = scan( tmp_str, '+' )
+ coeff0 = 1._r8 ! default multiplier
- if (j>0) then
+ ! now parse out the multiplier from the terms
+ elmloop: do k = 1,nelem
- ! remove the leading + ...
- tmp_str = tmp_str(j+1:)
- j = scan( tmp_str, '+' )
+ exp_item%coeffs(k) = coeff0
- do while(j>0)
+ ! get the term name which follows the '*' operator if the is one
+ tmp_name = adjustl(sum_string(ndxs(k)+1:ndxs(k+1)-1))
- call set_coefvar( tmp_str(:j-1), exp_item )
+ j = scan( tmp_name, '*' )
+ if (j>0) then
- tmp_str = tmp_str(j+1:)
- j = scan( tmp_str, '+' )
+ xchr = tmp_name(1:j-1) ! get the multipler (left of the '*')
+ read( xchr, * ) xdbl ! convert the string to a real
+ exp_item%coeffs(k) = xdbl ! store the multiplier
- enddo
+ j1 = scan( tmp_name, '(' )
+ if (j1>0) then
+ coeff0 = xdbl
+ tmp_name = trim(adjustl(tmp_name(j1+1:))) ! get the term name (right of the '*')
+ else
+ coeff0 = 1._r8
+ tmp_name = trim(adjustl(tmp_name(j+1:))) ! get the term name (right of the '*')
+ endif
- call set_coefvar( tmp_str, exp_item )
+ endif
- endif
+ j2 = scan( tmp_name, ')' )
+ if (j2>0) then
+ coeff0 = 1._r8
+ tmp_name = tmp_name(1:j2-1)
+ endif
+ exp_item%vars(k) = trim(tmp_name)
+
+ enddo elmloop
if (associated(exp_item)) then
if (associated(exp_items_list)) then
@@ -124,13 +164,16 @@ function shr_exp_parse( exp_array, nitems ) result(exp_items_list)
endif
endif
- endif
- enddo
+
+ enddo grploop
+ endif has_grps
if ( present(nitems) ) then
nitems = n_exp_items
endif
+ deallocate(sums_grps)
+
end function shr_exp_parse
! -----------------------------------------------------------------
@@ -157,29 +200,4 @@ subroutine shr_exp_list_destroy( list )
end subroutine shr_exp_list_destroy
- !==========================
- ! Private Methods
-
- ! -----------------------------------------------------------------
- ! -----------------------------------------------------------------
- subroutine set_coefvar( term, item )
- character(len=*), intent(in) :: term
- type(shr_exp_item_t) , intent(inout) :: item
-
- integer :: k, n
-
- item%n_terms = item%n_terms + 1
- n = item%n_terms
-
- k = scan( term, '*' )
- if (k>0) then
- item%vars(n) = trim(adjustl(term(k+1:)))
- read( term(:k-1), *) item%coeffs(n)
- else
- item%vars(n) = trim(adjustl(term))
- item%coeffs(n) = 1.0_r8
- endif
-
- end subroutine set_coefvar
-
end module shr_expr_parser_mod
diff --git a/cesm/nuopc_cap_share/shr_lightning_coupling_mod.F90 b/cesm/nuopc_cap_share/shr_lightning_coupling_mod.F90
new file mode 100644
index 000000000..3b4e260d8
--- /dev/null
+++ b/cesm/nuopc_cap_share/shr_lightning_coupling_mod.F90
@@ -0,0 +1,112 @@
+module shr_lightning_coupling_mod
+
+ !========================================================================
+ ! Module for handling namelist variables related to lightning coupling
+ !========================================================================
+
+ use ESMF , only : ESMF_VMGetCurrent, ESMF_VM, ESMF_VMGet
+ use ESMF , only : ESMF_LOGERR_PASSTHRU, ESMF_SUCCESS
+ use ESMF , only : ESMF_VMBroadCast, ESMF_Logical, assignment(=)
+ use shr_sys_mod , only : shr_sys_abort
+ use shr_log_mod , only : shr_log_getLogUnit
+ use shr_nl_mod , only : shr_nl_find_group_name
+ use nuopc_shr_methods, only : chkerr
+
+ implicit none
+ private
+
+ ! !PUBLIC MEMBER FUNCTIONS
+ public shr_lightning_coupling_readnl ! Read namelist
+
+ character(len=*), parameter :: &
+ u_FILE_u=__FILE__
+
+ !====================================================================================
+CONTAINS
+ !====================================================================================
+
+ subroutine shr_lightning_coupling_readnl(NLFilename, atm_provides_lightning_out)
+
+ !========================================================================
+ ! reads lightning_coupling_nl namelist and returns a variable specifying
+ ! if atmosphere model provides lightning flash frequency field to mediator
+ !========================================================================
+
+ ! input/output variables
+ character(len=*), intent(in) :: NLFilename ! Namelist filename
+ logical, intent(out) :: atm_provides_lightning_out ! if TRUE atm will provide lightning flash frequency
+
+ !----- local -----
+ logical :: atm_provides_lightning
+ type(ESMF_VM) :: vm
+ integer :: unitn ! namelist unit number
+ integer :: ierr ! error code
+ logical :: exists ! if file exists or not
+ type(ESMF_Logical):: ltmp(1)
+ integer :: rc
+ integer :: localpet
+ integer :: mpicom
+ integer :: s_logunit
+ character(len=*), parameter :: atm_ozone_frequency_not_present = 'NOT_PRESENT'
+ character(len=*), parameter :: subname = '(shr_lightning_coupling_readnl) '
+ ! ------------------------------------------------------------------
+
+ namelist /lightning_coupling_nl/ atm_provides_lightning
+
+ rc = ESMF_SUCCESS
+
+ atm_provides_lightning_out = .false.
+ ltmp(1) = .false.
+
+ !--- Open and read namelist ---
+ if ( len_trim(NLFilename) == 0 ) then
+ call shr_sys_abort( subname//'ERROR: nlfilename not set' )
+ end if
+ call shr_log_getLogUnit(s_logunit)
+ call ESMF_VMGetCurrent(vm, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+
+ call ESMF_VMGet(vm, localPet=localpet, mpiCommunicator=mpicom, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+
+ if (localpet==0) then
+ ! ------------------------------------------------------------------------
+ ! Set default values in case namelist file doesn't exist, lightning_coupling_nl group
+ ! doesn't exist within the file, or a given variable isn't present in the namelist
+ ! group in the file.
+ ! ------------------------------------------------------------------------
+ atm_provides_lightning = .false.
+
+ ! ------------------------------------------------------------------------
+ ! Read namelist file
+ ! ------------------------------------------------------------------------
+ inquire( file=trim(NLFileName), exist=exists)
+ if ( exists ) then
+ open(newunit=unitn, file=trim(NLFilename), status='old' )
+ write(s_logunit,'(a)') subname,'Read in lightning_coupling_nl namelist from: ', trim(NLFilename)
+ call shr_nl_find_group_name(unitn, 'lightning_coupling_nl', ierr)
+ if (ierr == 0) then
+ ! Note that ierr /= 0 means no namelist is present.
+ read(unitn, lightning_coupling_nl, iostat=ierr)
+ if (ierr > 0) then
+ call shr_sys_abort(subname//'problem reading lightning_coupling_nl')
+ end if
+ end if
+ close( unitn )
+ end if
+
+ ltmp(1) = atm_provides_lightning
+
+ end if
+
+ ! ------------------------------------------------------------------------
+ ! Broadcast values to all tasks
+ ! ------------------------------------------------------------------------
+ call ESMF_VMBroadcast(vm, ltmp, count=1, rootPet=0, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+
+ atm_provides_lightning_out = ltmp(1)
+
+ end subroutine shr_lightning_coupling_readnl
+
+end module shr_lightning_coupling_mod
diff --git a/cesm/nuopc_cap_share/shr_megan_mod.F90 b/cesm/nuopc_cap_share/shr_megan_mod.F90
index d49411e84..57a218dd7 100644
--- a/cesm/nuopc_cap_share/shr_megan_mod.F90
+++ b/cesm/nuopc_cap_share/shr_megan_mod.F90
@@ -5,22 +5,22 @@ module shr_megan_mod
! MEGAN = Model of Emissions of Gases and Aerosols from Nature
!
! This reads the megan_emis_nl namelist in drv_flds_in and makes the relavent
- ! information available to CAM, CLM, and driver.
- ! - The driver sets up CLM to CAM communication for the VOC flux fields.
- ! - CLM needs to know what specific VOC fluxes need to be passed to the coupler
+ ! information available to CAM, CLM, and driver.
+ ! - The driver sets up CLM to CAM communication for the VOC flux fields.
+ ! - CLM needs to know what specific VOC fluxes need to be passed to the coupler
! and how to assemble the fluxes.
! - CAM needs to know what specific VOC fluxes to expect from CLM.
!================================================================================
use ESMF , only : ESMF_VMGetCurrent, ESMF_VM, ESMF_VMGet
- use ESMF , only : ESMF_LogFoundError, ESMF_LOGERR_PASSTHRU, ESMF_SUCCESS
- use shr_kind_mod , only : r8 => shr_kind_r8, cl=>shr_kind_cl, cx=>shr_kind_cx, cs=>shr_kind_cs
+ use ESMF , only : ESMF_LogFoundError, ESMF_LOGERR_PASSTHRU
+ use shr_kind_mod , only : r8 => shr_kind_r8, cl=>shr_kind_cl, cx=>shr_kind_cx
use shr_sys_mod , only : shr_sys_abort
use shr_log_mod , only : shr_log_getLogUnit
use shr_mpi_mod , only : shr_mpi_bcast
use shr_nl_mod , only : shr_nl_find_group_name
use shr_expr_parser_mod , only : shr_exp_parse, shr_exp_item_t, shr_exp_list_destroy
-
+
implicit none
private
@@ -68,6 +68,9 @@ module shr_megan_mod
! switch to use mapped emission factors
logical :: shr_megan_mapped_emisfctrs = .false.
+ integer :: localPet = -huge(1)
+ integer :: logunit = -huge(1)
+
!--------------------------------------------------------
contains
!--------------------------------------------------------
@@ -100,7 +103,8 @@ subroutine shr_megan_readnl( NLFileName, megan_nflds)
! Example:
! &megan_emis_nl
! megan_specifier = 'ISOP = isoprene',
- ! 'C10H16 = myrcene + sabinene + limonene + carene_3 + ocimene_t_b + pinene_b + ...',
+ ! 'C10H16 = myrcene + sabinene + limonene + carene_3 + ocimene_t_b + pinene_b + ',
+ ! ' thujene_a + bornene + 0.5*(terpineol_4 + terpineol_a + terpinyl_ACT_a + myrtenal) + ...',
! 'CH3OH = methanol',
! 'C2H5OH = ethanol',
! 'CH2O = formaldehyde',
@@ -109,25 +113,22 @@ subroutine shr_megan_readnl( NLFileName, megan_nflds)
! megan_factors_file = '$datapath/megan_emis_factors.nc'
! /
!-------------------------------------------------------------------------
-
+
! input/output variables
character(len=*), intent(in) :: NLFileName
integer, intent(out) :: megan_nflds
! local variables
type(ESMF_VM) :: vm
- integer :: localPet
integer :: mpicom
integer :: unitn ! namelist unit number
integer :: ierr ! error code
logical :: exists ! if file exists or not
- integer, parameter :: maxspc = 100
- character(len=2*CX) :: megan_specifier(maxspc) = ' '
+ integer, parameter :: maxspc = 200
+ character(len=CX) :: megan_specifier(maxspc) = ' '
logical :: megan_mapped_emisfctrs = .false.
character(len=CL) :: megan_factors_file = ' '
integer :: rc
- integer :: logunit
- integer :: i, tmp(1)
character(*), parameter :: F00 = "('(shr_megan_readnl) ',2a)"
character(len=*), parameter :: subname='(shr_megan_readnl)'
!--------------------------------------------------------------
@@ -140,12 +141,12 @@ subroutine shr_megan_readnl( NLFileName, megan_nflds)
end if
call ESMF_VMGetCurrent(vm, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
call ESMF_VMGet(vm, localPet=localPet, mpiCommunicator=mpicom, rc=rc)
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
call shr_log_getLogUnit(logunit)
- ! Note the following still needs to be called on all processors since the mpi_bcast is a collective
+ ! Note the following still needs to be called on all processors since the mpi_bcast is a collective
! call on all the pes of mpicom
if (localPet==0) then
inquire( file=trim(NLFileName), exist=exists)
@@ -204,6 +205,8 @@ subroutine shr_megan_init( specifier)
allocate(shr_megan_mechcomps(n_entries))
shr_megan_mechcomps(:)%n_megan_comps = 0
+ if (localPet==0) write(logunit,*) 'MEGAN entries:'
+
item => items_list
i = 1
do while(associated(item))
@@ -221,7 +224,9 @@ subroutine shr_megan_init( specifier)
shr_megan_mechcomps(i)%n_megan_comps = item%n_terms
allocate(shr_megan_mechcomps(i)%megan_comps(item%n_terms))
+ if (localPet==0) write(logunit,*) ' species : ', item%name
do j = 1,item%n_terms
+ if (localPet==0) write(logunit,'(f12.4,a,a)') item%coeffs(j),' * ', item%vars(j)
shr_megan_mechcomps(i)%megan_comps(j)%ptr => add_megan_comp( item%vars(j), item%coeffs(j) )
enddo
shr_megan_mechcomps_n = shr_megan_mechcomps_n+1
diff --git a/cime_config/buildexe b/cime_config/buildexe
index 406f660a3..1d7366718 100755
--- a/cime_config/buildexe
+++ b/cime_config/buildexe
@@ -38,6 +38,7 @@ def _main_func():
num_esp = case.get_value("NUM_COMP_INST_ESP")
ocn_model = case.get_value("COMP_OCN")
gmake_args = get_standard_makefile_args(case)
+ link_libs = case.get_value("CAM_LINKED_LIBS", subgroup="build_component_cam")
esmf_aware_threading = case.get_value("ESMF_AWARE_THREADING")
# Determine valid components
@@ -65,6 +66,9 @@ def _main_func():
if ocn_model == 'mom':
gmake_args += "USE_FMS=TRUE"
+ if link_libs is not None:
+ gmake_args += 'USER_SLIBS="{}"'.format(link_libs)
+
comp_classes = case.get_values("COMP_CLASSES")
for comp in comp_classes:
model = case.get_value("COMP_{}".format(comp))
diff --git a/cime_config/buildnml b/cime_config/buildnml
index 32d6df1c0..32be8ead4 100755
--- a/cime_config/buildnml
+++ b/cime_config/buildnml
@@ -125,17 +125,13 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files):
elif case.get_value("RUN_TYPE") == "branch":
config["run_type"] = "branch"
+ config['wav_ice_coupling'] = config['COMP_WAV'] == 'ww3dev' and config['COMP_ICE'] == 'cice'
+
# ----------------------------------------------------
# Initialize namelist defaults
# ----------------------------------------------------
nmlgen.init_defaults(infile, config, skip_default_for_groups=["modelio"])
- # --------------------------------
- # Set default wav-ice coupling (assumes cice6 as the ice component
- # --------------------------------
- if case.get_value("COMP_WAV") == "ww3dev" and case.get_value("COMP_ICE") == "cice":
- nmlgen.add_default("wavice_coupling", value=".true.")
-
# --------------------------------
# Overwrite: set brnch_retain_casename
# --------------------------------
@@ -298,8 +294,13 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files):
# --------------------------------
# Determine valid components
valid_comps = []
+ asyncio = False
+
for item in case.get_values("COMP_CLASSES"):
comp = case.get_value("COMP_" + item)
+ if case.get_value(f"PIO_ASYNC_INTERFACE", {"compclass":item}):
+ asyncio = True
+
valid = True
if comp == "s" + item.lower():
# stub comps
@@ -322,6 +323,20 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files):
valid = False
if valid:
valid_comps.append(item)
+ asyncio_ntasks = case.get_value("PIO_ASYNCIO_NTASKS")
+ asyncio_stride = case.get_value("PIO_ASYNCIO_STRIDE")
+ # If asyncio is enabled make sure that the aysncio values are set
+ # if not enabled then do not pass xml settings to namelists.
+ if asyncio:
+ expect(asyncio_ntasks > 0 and asyncio_stride > 0,
+ "ASYNCIO is enabled but PIO_ASYNCIO_NTASKS={} and PIO_ASYNCIO_STRIDE = {}".
+ format(asyncio_ntasks, asyncio_stride))
+ else:
+ if asyncio_ntasks > 0 or asyncio_stride > 0:
+ logger.warning("ASYNCIO is disabled, ignoring settings for PIO_ASYNCIO_NTASKS={} and PIO_ASYNCIO_STRIDE = {}".
+ format(asyncio_ntasks, asyncio_stride))
+ nmlgen.set_value("pio_asyncio_ntasks", 0)
+ nmlgen.set_value("pio_asyncio_stride", 0)
# Determine if there are any data components in the compset
datamodel_in_compset = False
@@ -601,14 +616,7 @@ def buildnml(case, caseroot, component):
major = line[-2] if "MAJOR" in line else major
minor = line[-2] if "MINOR" in line else minor
logger.debug("ESMF version major {} minor {}".format(major, minor))
- expect(int(major) >= 8, "ESMF version should be 8.1 or newer")
- if esmf_aware_threading:
- expect(
- int(minor) >= 2,
- "ESMF version should be 8.2.0 or newer when using ESMF_AWARE_THREADING",
- )
- else:
- expect(int(minor) >= 1, "ESMF version should be 8.1.0 or newer")
+ expect(int(major) >= 8 and int(minor) >=4, "ESMF version should be 8.4.1 or newer")
confdir = os.path.join(case.get_value("CASEBUILD"), "cplconf")
if not os.path.isdir(confdir):
diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml
index c06f7a7f3..f986cfad2 100644
--- a/cime_config/config_component.xml
+++ b/cime_config/config_component.xml
@@ -1361,87 +1361,6 @@
-
-
-
- char
- idmap
- run_domain
- env_run.xml
- atm2ocn flux mapping file
-
-
-
- char
- idmap
- run_domain
- env_run.xml
- atm2ocn state mapping file
-
-
-
- char
- idmap
- run_domain
- env_run.xml
- atm2ocn vector mapping file
-
-
-
- char
- idmap
- run_domain
- env_run.xml
- atm2lnd flux mapping file
-
-
-
- char
- idmap
- run_domain
- env_run.xml
- atm2lnd state mapping file
-
-
-
- char
- idmap
- run_domain
- env_run.xml
- atm2wav state mapping file
-
-
-
- char
- idmap
- run_domain
- env_run.xml
- ocn2atm flux mapping file
-
-
-
- char
- idmap
- run_domain
- env_run.xml
- ocn2atm state mapping file
-
-
-
- char
- idmap
- run_domain
- env_run.xml
- lnd2atm flux mapping file
-
-
-
- char
- idmap
- run_domain
- env_run.xml
- lnd2atm state mapping file
-
char
@@ -2023,6 +1942,30 @@
pio blocksize for box decompositions
+
+ integer
+ 0
+ run_pio
+ env_mach_pes.xml
+ Task count for asyncronous IO, only valid if PIO_ASYNC_INTERFACE is True
+
+
+
+ integer
+ 0
+ run_pio
+ env_mach_pes.xml
+ Stride of tasks for asyncronous IO, only valid if PIO_ASYNC_INTERFACE is True
+
+
+
+ integer
+ 1
+ run_pio
+ env_mach_pes.xml
+ RootPE of tasks for asyncronous IO, only valid if PIO_ASYNC_INTERFACE is True
+
+
integer
-1
diff --git a/cime_config/config_component_cesm.xml b/cime_config/config_component_cesm.xml
index e2e6b44e1..dbf3b11e3 100644
--- a/cime_config/config_component_cesm.xml
+++ b/cime_config/config_component_cesm.xml
@@ -108,12 +108,15 @@
CO2A
none
CO2A
+ CO2A
CO2A
CO2A
CO2A
CO2A
CO2C
CO2C
+ CO2A
+ CO2A
run_coupling
env_run.xml
@@ -232,6 +235,11 @@
1
+
+
+
+ 24
+ 48
run_coupling
env_run.xml
@@ -466,37 +474,6 @@
-
- char
- none,never,nsteps,nseconds,nminutes,nhours,ndays,nmonths,nyears,date,end
- never
-
- nmonths
-
- med_history
- env_run.xml
- Sets mediator average history file frequency (like REST_OPTION)
-
-
- char
-
- -999
-
- 1
-
- med_history
- env_run.xml
- Sets mediator average history file frequency (like REST_N)
-
-
- integer
-
- -999
- med_history
- env_run.xml
- yyyymmdd format, sets mediator average history date (like REST_DATE)
-
-
logical
TRUE,FALSE
diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml
index ce1ae92ff..d9001cfb7 100644
--- a/cime_config/namelist_definition_drv.xml
+++ b/cime_config/namelist_definition_drv.xml
@@ -36,6 +36,42 @@
+
+ integer
+ pio
+ PELAYOUT_attributes
+
+ IO tasks FOR ASYNC IO, only valid if ASYNCIO is true.
+
+
+ $PIO_ASYNCIO_NTASKS
+
+
+
+
+ integer
+ pio
+ PELAYOUT_attributes
+
+ IO task stride FOR ASYNC IO, only valid if ASYNCIO is true.
+
+
+ $PIO_ASYNCIO_STRIDE
+
+
+
+
+ integer
+ pio
+ PELAYOUT_attributes
+
+ IO rootpe task FOR ASYNC IO, only valid if ASYNCIO is true.
+
+
+ $PIO_ASYNCIO_ROOTPE
+
+
+
char
expdef
@@ -680,6 +716,17 @@
$ESMF_VERBOSITY_LEVEL
+
+ logical
+ performance
+ MED_attributes
+
+ Check for NaN values in fields returned from mediator to components. This has a small performance impact.
+
+
+ .true.
+
+
integer
control
@@ -888,10 +935,10 @@
ogrid,agrid,xgrid
Grid for atm ocn flux calc
- default: xgrid
+ default: ogrid
- ogrid
+ xgrid
@@ -1199,7 +1246,7 @@
-
+
logical
aux_hist
@@ -1228,10 +1275,10 @@
- char
+ integer
aux_hist
MED_attributes
- history option type
+ history option span
1
@@ -1258,13 +1305,13 @@
integer
aux_hist
MED_attributes
- Number of time sames per file.
+ Number of time samples per file.
24
-
+
logical
aux_hist
@@ -1293,10 +1340,10 @@
- char
+ integer
aux_hist
MED_attributes
- history option type
+ history option span
1
@@ -1311,10 +1358,10 @@
- char
+ integer
aux_hist
MED_attributes
- Number of time sames per file.
+ Number of time samples per file.
24
@@ -1329,7 +1376,7 @@
-
+
logical
aux_hist
@@ -1345,7 +1392,7 @@
char
aux_hist
MED_attributes
- Auxiliary mediator atm2med precipitation history output every 3 hours
+ Auxiliary mediator atm2med precipitation fields history output every 3 hours
Faxa_rainc:Faxa_rainl:Faxa_snowc:Faxa_snowl
@@ -1360,10 +1407,10 @@
- char
+ integer
aux_hist
MED_attributes
- history option type
+ history option span
3
@@ -1378,10 +1425,10 @@
- char
+ integer
aux_hist
MED_attributes
- Number of time sames per file.
+ Number of time samples per file.
8
@@ -1396,13 +1443,13 @@
-
+
logical
aux_hist
MED_attributes
- Auxiliary mediator a2x precipitation history output every 3 hours
+ Auxiliary mediator a2x dynamic, radiation, and precipitation history output every 3 hours
.false.
@@ -1413,7 +1460,7 @@
aux_hist
MED_attributes
- Auxiliary mediator a2x precipitation history output every 3 hours
+ Auxiliary mediator a2x dynamic, radiation, and precipitation fields history output every 3 hours
Sa_z:Sa_topo:Sa_u:Sa_v:Sa_tbot:Sa_ptem:Sa_shum:Sa_dens:Sa_pbot:Sa_pslv:Faxa_lwdn:Faxa_rainc:Faxa_rainl:Faxa_snowc:Faxa_snowl:Faxa_swndr:Faxa_swvdr:Faxa_swndf:Faxa_swvdf:Sa_co2diag:Sa_co2prog
@@ -1429,10 +1476,10 @@
- char
+ integer
aux_hist
MED_attributes
- history option type
+ history option span
3
@@ -1447,10 +1494,10 @@
- char
+ integer
aux_hist
MED_attributes
- Number of time sames per file.
+ Number of time samples per file.
8
@@ -1465,12 +1512,12 @@
-
+
logical
aux_hist
MED_attributes
- Auxiliary mediator a2x precipitation history output every 3 hours
+ Auxiliary mediator a2x aerosol and ghg history output daily or endofrun
.false.
@@ -1479,7 +1526,7 @@
char
aux_hist
MED_attributes
- Auxiliary mediator a2x precipitation history output every 3 hours
+ Auxiliary mediator a2x aerosol and ghg history output daily or endofrun
Faxa_bcph:Faxa_ocph:Faxa_dstwet:Faxa_dstdry:Sa_co2prog:Sa_co2diag
@@ -1490,16 +1537,16 @@
MED_attributes
history option type
- ndays
+ nhours
- char
+ integer
aux_hist
MED_attributes
- history option type
+ history option span
- 1
+ 3
@@ -1512,12 +1559,12 @@
- char
+ integer
aux_hist
MED_attributes
- Number of time sames per file.
+ Number of time samples per file.
- 1
+ 2
@@ -1712,7 +1759,7 @@
- char
+ integer
aux_hist
MED_attributes
history option type
@@ -1730,10 +1777,10 @@
- char
+ integer
aux_hist
MED_attributes
- Number of time sames per file.
+ Number of time samples per file.
1
@@ -1765,6 +1812,71 @@
+
+
+ logical
+ aux_hist
+ MED_attributes
+ Auxiliary mediator ocn2med average history output every day.
+
+ .false.
+
+
+
+ char
+ aux_hist
+ MED_attributes
+ Auxiliary mediator ocn2med average history output every day.
+
+ So_bldepth:So_t:So_u:So_v
+
+
+
+ char
+ aux_hist
+ MED_attributes
+ history option type
+
+ ndays
+
+
+
+ integer
+ aux_hist
+ MED_attributes
+ history option type
+
+ 1
+
+
+
+ logical
+ aux_hist
+ MED_attributes
+ If true, use time average for aux file output.
+
+ .true.
+
+
+
+ char
+ aux_hist
+ MED_attributes
+ Auxiliary name identifier in history name
+
+ ocn.24h.avg
+
+
+
+ integer
+ aux_hist
+ MED_attributes
+ Number of time samples per file.
+
+ 30
+
+
+
char
time
@@ -1877,7 +1989,7 @@
char
aux_hist
MED_attributes
- Auxiliary mediator rof2med precipitation history output.
+ Auxiliary mediator rof2med precipitation fields history output.
all
@@ -1888,16 +2000,16 @@
MED_attributes
history option type
- ndays
+ nhours
- char
+ integer
aux_hist
MED_attributes
- history option type
+ history option span
- 1
+ 3
@@ -1910,12 +2022,12 @@
- char
+ integer
aux_hist
MED_attributes
- Number of time sames per file.
+ Number of time samples per file.
- 1
+ 2
@@ -2055,25 +2167,25 @@
idmap
-
+
char
mapping
abs
MED_attributes
- lnd to rof mapping, 'unset' or 'idmap' are normal possible values
+ lnd to rof mapping, 'unset' or 'idmap' are normal possible values (mapping file given for mizuRoute grids)
- unset
+ $LND2ROF_FMAPNAME
idmap
-
+
char
mapping
abs
MED_attributes
- rof to lnd mapping, 'unset' or 'idmap' are normal possible values
+ rof to lnd mapping, 'unset' or 'idmap' are normal possible values (mapping file given for mizuRoute grids)
- unset
+ $ROF2LND_FMAPNAME
idmap
@@ -2270,6 +2382,7 @@
4
+ 4
0
@@ -3798,7 +3911,7 @@
-
+
logical
expdef
ALLCOMP_attributes
@@ -3807,6 +3920,8 @@
.false.
+
+
diff --git a/cime_config/namelist_definition_drv_flds.xml b/cime_config/namelist_definition_drv_flds.xml
index b8d96bcd6..03b6b7c6d 100644
--- a/cime_config/namelist_definition_drv_flds.xml
+++ b/cime_config/namelist_definition_drv_flds.xml
@@ -142,7 +142,7 @@
-
+
@@ -157,4 +157,17 @@
+
+
+
+
+
+ logical
+ lightning_coupling
+ lightning_coupling_nl
+
+ If TRUE atmosphere model will provide prognosed lightning flash frequency (flashes per minute).
+
+
+
diff --git a/cime_config/runseq/driver_config.py b/cime_config/runseq/driver_config.py
index e5fe2715d..9694c7503 100644
--- a/cime_config/runseq/driver_config.py
+++ b/cime_config/runseq/driver_config.py
@@ -132,7 +132,8 @@ def __compute_ocn(self, case, coupling_times):
# TODO: check of data model prognostic flag is on - this is a new xml variable
# If the prognostic flag is on, then should set med_to_wav to True
docn_mode = case.get_value("DOCN_MODE")
- med_to_ocn = ('som' in docn_mode or 'interannual' in docn_mode)
+ docn_import_fields = case.get_value("DOCN_IMPORT_FIELDS")
+ med_to_ocn = ('som' in docn_mode or 'interannual' in docn_mode or docn_import_fields != 'none')
return (run_ocn, med_to_ocn, coupling_times["ocn_cpl_dt"])
diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py
index 2b7f0cc0a..ddbfca598 100644
--- a/cime_config/runseq/runseq_general.py
+++ b/cime_config/runseq/runseq_general.py
@@ -94,7 +94,7 @@ def gen_runseq(case, coupling_times):
runseq.add_action("MED med_phases_aofluxes_run" , run_ocn and run_atm and (med_to_ocn or med_to_atm))
runseq.add_action("MED med_phases_prep_ocn_accum" , med_to_ocn)
runseq.add_action("MED med_phases_ocnalb_run" , (run_ocn and run_atm and (med_to_ocn or med_to_atm)) and not xcompset)
- runseq.add_action("MED med_phases_diag_ocn" , run_ocn and diag_mode)
+ runseq.add_action("MED med_phases_diag_ocn" , run_ocn and diag_mode)
if (cpl_seq_option == 'OPTION1'):
if ocn_cpl_time != atm_cpl_time:
@@ -104,11 +104,17 @@ def gen_runseq(case, coupling_times):
if ocn_cpl_time != atm_cpl_time:
runseq.leave_time_loop(inner_loop, addextra_atsign=True)
+ if (cpl_seq_option == 'TIGHT'):
+ runseq.add_action("MED med_phases_aofluxes_run" , med_to_ocn)
+ runseq.add_action("MED med_phases_prep_ocn_accum" , med_to_ocn)
+ runseq.add_action("MED med_phases_prep_ocn_avg" , med_to_ocn and ocn_outer_loop)
+ runseq.add_action("MED -> OCN :remapMethod=redist", med_to_ocn and ocn_outer_loop)
+
runseq.add_action("MED med_phases_prep_lnd" , med_to_lnd)
runseq.add_action("MED -> LND :remapMethod=redist" , med_to_lnd)
- runseq.add_action("MED med_phases_prep_ice" , med_to_ice)
- runseq.add_action("MED -> ICE :remapMethod=redist" , med_to_ice)
+ runseq.add_action("MED med_phases_prep_ice" , med_to_ice)
+ runseq.add_action("MED -> ICE :remapMethod=redist" , med_to_ice)
runseq.add_action("MED med_phases_prep_wav_accum" , med_to_wav)
runseq.add_action("MED med_phases_prep_wav_avg" , med_to_wav)
diff --git a/cime_config/testdefs/testlist_drv.xml b/cime_config/testdefs/testlist_drv.xml
index 7368a1fd2..985bd6ce9 100644
--- a/cime_config/testdefs/testlist_drv.xml
+++ b/cime_config/testdefs/testlist_drv.xml
@@ -189,7 +189,7 @@
-
+
@@ -260,4 +260,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cime_config/testdefs/testmods_dirs/drv/asyncio1node/shell_commands b/cime_config/testdefs/testmods_dirs/drv/asyncio1node/shell_commands
new file mode 100644
index 000000000..70ec80d0e
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/drv/asyncio1node/shell_commands
@@ -0,0 +1,17 @@
+# This will add 4 asyncio tasks on the first node
+./xmlchange PIO_ASYNCIO_ROOTPE=0
+./xmlchange PIO_ASYNCIO_STRIDE=1
+./xmlchange PIO_ASYNCIO_NTASKS=4
+./xmlchange PIO_REARRANGER=2
+./xmlchange PIO_ASYNC_INTERFACE=TRUE
+for comp in ATM OCN LND ICE CPL GLC ROF
+do
+ rootpe=`./xmlquery --value ROOTPE_$comp`
+ let newrootpe=rootpe+4
+ ./xmlchange ROOTPE_$comp=$newrootpe
+done
+comp_ocn=`./xmlquery --value COMP_OCN`
+# MOM ocn has no pio interface
+if [[ "$comp_ocn" == "mom" ]]; then
+ ./xmlchange PIO_ASYNC_INTERFACE_OCN=FALSE;
+fi
diff --git a/cime_config/testdefs/testmods_dirs/drv/asyncio1pernode/shell_commands b/cime_config/testdefs/testmods_dirs/drv/asyncio1pernode/shell_commands
new file mode 100644
index 000000000..05077453c
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/drv/asyncio1pernode/shell_commands
@@ -0,0 +1,22 @@
+# This will add one async pio task per node to a test
+# does not work for all cases
+max2() { printf '%d' $(( $1 > $2 ? $1 : $2 )); }
+let totaltasks=0
+./xmlchange --force --force PIO_ASYNC_INTERFACE=TRUE
+for comp in ATM OCN LND ICE CPL GLC ROF
+do
+ ntasks=`./xmlquery --value NTASKS_$comp`
+ rootpe=`./xmlquery --value ROOTPE_$comp`
+ let maxpe=ntasks+rootpe
+ totaltasks=$(( $totaltasks > $maxpe ? $totaltasks : $maxpe ))
+done
+echo "totaltasks is $totaltasks"
+tpn=`./xmlquery --value MAX_MPITASKS_PER_NODE`
+./xmlchange --force --force PIO_ASYNCIO_STRIDE=$tpn
+let piontasks=totaltasks/tpn
+echo "piontasks=$piontasks"
+./xmlchange --force --force PIO_ASYNCIO_NTASKS=$piontasks
+let newntasks=totaltasks-piontasks
+echo "newntasks=$newntasks"
+./xmlchange --force --force NTASKS=$newntasks
+./xmlchange --force --force PIO_REARRANGER=2
diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90
index 6ebd49e0f..13811aec9 100644
--- a/mediator/esmFldsExchange_cesm_mod.F90
+++ b/mediator/esmFldsExchange_cesm_mod.F90
@@ -96,16 +96,16 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc)
type(InternalState) :: is_local
integer :: n, ns
character(len=CL) :: cvalue
- logical :: wavice_coupling
+ logical :: wav_coupling_to_cice
logical :: ocn2glc_coupling
character(len=*) , parameter :: subname=' (esmFldsExchange_cesm) '
!--------------------------------------
rc = ESMF_SUCCESS
- call NUOPC_CompAttributeGet(gcomp, name='wavice_coupling', value=cvalue, rc=rc)
+ call NUOPC_CompAttributeGet(gcomp, name='wav_coupling_to_cice', value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) wavice_coupling
+ read(cvalue,*) wav_coupling_to_cice
call NUOPC_CompAttributeGet(gcomp, name='ocn2glc_coupling', value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
@@ -399,6 +399,19 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc)
end if
end if
! ---------------------------------------------------------------------
+ ! to lnd: cld to grnd lightning flash freq
+ ! ---------------------------------------------------------------------
+ if (phase == 'advertise') then
+ call addfld_from(compatm, 'Sa_lightning')
+ call addfld_to(complnd, 'Sa_lightning')
+ else
+ if ( fldchk(is_local%wrap%FBexp(complnd) , 'Sa_lightning', rc=rc) .and. &
+ fldchk(is_local%wrap%FBImp(compatm,compatm ), 'Sa_lightning', rc=rc)) then
+ call addmap_from(compatm, 'Sa_lightning', complnd, mapbilnr, 'one', atm2lnd_map)
+ call addmrg_to(complnd, 'Sa_lightning', mrg_from=compatm, mrg_fld='Sa_lightning', mrg_type='copy')
+ end if
+ end if
+ ! ---------------------------------------------------------------------
! to lnd: temperature at the lowest model level from atm
! ---------------------------------------------------------------------
if (phase == 'advertise') then
@@ -1960,6 +1973,17 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc)
mrg_from=compatm, mrg_fld='Faxa_dstdry', mrg_type='copy_with_weights', mrg_fracname='ofrac')
end if
end if
+ if (phase == 'advertise') then
+ call addfld_to(compocn, 'Faxa_ndep')
+ call addfld_from(compatm, 'Faxa_ndep')
+ else
+ if ( fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_ndep', rc=rc) .and. &
+ fldchk(is_local%wrap%FBExp(compocn) , 'Faxa_ndep', rc=rc)) then
+ call addmap_from(compatm, 'Faxa_ndep', compocn, mapconsf, 'one', atm2ocn_map)
+ call addmrg_to(compocn, 'Faxa_ndep', &
+ mrg_from=compatm, mrg_fld='Faxa_ndep', mrg_type='copy')
+ end if
+ end if
! ---------------------------------------------------------------------
! to ocn: enthalpy from atm rain, snow, evaporation
@@ -2807,7 +2831,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc)
! ---------------------------------------------------------------------
! to ice: wave elevation spectrum (field with ungridded dimensions)
! ---------------------------------------------------------------------
- if (wavice_coupling) then
+ if (wav_coupling_to_cice) then
if (phase == 'advertise') then
call addfld_from(compwav, 'Sw_elevation_spectrum')
call addfld_to(compice, 'Sw_elevation_spectrum')
@@ -2842,7 +2866,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc)
!----------------------------------------------------------
! to wav: ice thickness from ice
!----------------------------------------------------------
- if (wavice_coupling) then
+ if (wav_coupling_to_cice) then
if (phase == 'advertise') then
call addfld_from(compice, 'Si_thick')
call addfld_to(compwav, 'Si_thick')
@@ -2857,7 +2881,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc)
!----------------------------------------------------------
! to wav: ice floe diameter from ice
!----------------------------------------------------------
- if (wavice_coupling) then
+ if (wav_coupling_to_cice) then
if (phase == 'advertise') then
call addfld_from(compice, 'Si_floediam')
call addfld_to(compwav, 'Si_floediam')
@@ -2962,6 +2986,14 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc)
end if
end if
+ ! ---------------------------------------------------------------------
+ ! to wav: zonal and meridional wind stress
+ ! ---------------------------------------------------------------------
+ if (phase == 'advertise') then
+ call addfld_to(compwav , 'Fwxx_taux')
+ call addfld_to(compwav , 'Fwxx_tauy')
+ end if
+
!=====================================================================
! FIELDS TO RIVER (comprof)
!=====================================================================
diff --git a/mediator/fd_cesm.yaml b/mediator/fd_cesm.yaml
index 648a4fed2..c09a63c58 100644
--- a/mediator/fd_cesm.yaml
+++ b/mediator/fd_cesm.yaml
@@ -325,6 +325,10 @@
canonical_units: mol/mol
description: atmosphere export - O3 in the lowest model layer (prognosed or prescribed)
#
+ - standard_name: Sa_lightning
+ canonical_units: /min
+ description: atmosphere export - lightning flash freqency
+ #
- standard_name: Sa_topo
alias: inst_surface_height
canonical_units: m
@@ -745,7 +749,7 @@
description: sea-ice export - ice thickness
#
- standard_name: Si_floediam
- canonical_units: m
+ canonical_units: m
description: sea-ice export - ice floe diameter
#
#-----------------------------------
@@ -1172,6 +1176,21 @@
canonical_units: m2/s
description: wave elevation spectrum
+ #
+ #-----------------------------------
+ # section: wave import
+ #-----------------------------------
+ #
+ - standard_name: Fwxx_taux
+ alias: mean_zonal_moment_flx
+ canonical_units: N m-2
+ description: wave import - zonal surface stress
+ #
+ - standard_name: Fwxx_tauy
+ alias: mean_merid_moment_flx
+ canonical_units: N m-2
+ description: wave import - meridional surface stress
+
#-----------------------------------
# mediator fields
#-----------------------------------
diff --git a/mediator/med.F90 b/mediator/med.F90
index 79a43a4c9..56fcb7621 100644
--- a/mediator/med.F90
+++ b/mediator/med.F90
@@ -59,10 +59,10 @@ module MED
public SetServices
public SetVM
private InitializeP0
- private InitializeIPDv03p1 ! advertise fields
- private InitializeIPDv03p3 ! realize connected Fields with transfer action "provide"
- private InitializeIPDv03p4 ! optionally modify the decomp/distr of transferred Grid/Mesh
- private InitializeIPDv03p5 ! realize all Fields with transfer action "accept"
+ private AdvertiseFields ! advertise fields
+ private RealizeFieldsWithTransferProvided ! realize connected Fields with transfer action "provide"
+ private ModifyDecompofMesh ! optionally modify the decomp/distr of transferred Grid/Mesh
+ private RealizeFieldsWithTransferAccept ! realize all Fields with transfer action "accept"
private DataInitialize ! finish initialization and resolve data dependencies
private SetRunClock
private med_meshinfo_create
@@ -129,7 +129,7 @@ subroutine SetServices(gcomp, rc)
integer, intent(out) :: rc
! local variables
- character(len=*),parameter :: subname=' (SetServices) '
+ character(len=*), parameter :: subname = '('//__FILE__//':SetServices)'
!-----------------------------------------------------------
rc = ESMF_SUCCESS
@@ -161,7 +161,7 @@ subroutine SetServices(gcomp, rc)
! The valid values are: [will provide, can provide, cannot provide]
call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_INITIALIZE, &
- phaseLabelList=(/"IPDv03p1"/), userRoutine=InitializeIPDv03p1, rc=rc)
+ phaseLabelList=(/"IPDv03p1"/), userRoutine=AdvertiseFields, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
!------------------
@@ -169,7 +169,7 @@ subroutine SetServices(gcomp, rc)
!------------------
call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_INITIALIZE, &
- phaseLabelList=(/"IPDv03p3"/), userRoutine=InitializeIPDv03p3, rc=rc)
+ phaseLabelList=(/"IPDv03p3"/), userRoutine=RealizeFieldsWithTransferProvided, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
!------------------
@@ -177,7 +177,7 @@ subroutine SetServices(gcomp, rc)
!------------------
call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_INITIALIZE, &
- phaseLabelList=(/"IPDv03p4"/), userRoutine=InitializeIPDv03p4, rc=rc)
+ phaseLabelList=(/"IPDv03p4"/), userRoutine=ModifyDecompofMesh, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
!------------------
@@ -185,7 +185,7 @@ subroutine SetServices(gcomp, rc)
!------------------
call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_INITIALIZE, &
- phaseLabelList=(/"IPDv03p5"/), userRoutine=InitializeIPDv03p5, rc=rc)
+ phaseLabelList=(/"IPDv03p5"/), userRoutine=RealizeFieldsWithTransferAccept, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
!------------------
@@ -567,10 +567,12 @@ subroutine InitializeP0(gcomp, importState, exportState, clock, rc)
character(len=CX) :: diro
character(len=CX) :: logfile
character(len=CX) :: diagfile
- character(len=*),parameter :: subname=' (InitializeP0) '
+ character(len=*), parameter :: subname = '('//__FILE__//':InitializeP0)'
!-----------------------------------------------------------
rc = ESMF_SUCCESS
+ call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO)
+
if (profile_memory) call ESMF_VMLogMemInfo("Entering "//trim(subname))
call ESMF_GridCompGet(gcomp, vm=vm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
@@ -646,7 +648,7 @@ end subroutine InitializeP0
!-----------------------------------------------------------------------
- subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc)
+ subroutine AdvertiseFields(gcomp, importState, exportState, clock, rc)
! Mediator advertises its import and export Fields and sets the
! TransferOfferGeomObject Attribute.
@@ -659,6 +661,7 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc)
use NUOPC , only : NUOPC_CompAttributeGet, NUOPC_CompAttributeSet, NUOPC_CompAttributeAdd
use esmFlds, only : med_fldlist_init1, med_fld_GetFldInfo, med_fldList_entry_type
use med_phases_history_mod, only : med_phases_history_init
+ use med_methods_mod , only : mediator_checkfornans
! input/output variables
type(ESMF_GridComp) :: gcomp
@@ -677,7 +680,7 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc)
type(med_fldlist_type), pointer :: fldListFr, fldListTo
type(med_fldList_entry_type), pointer :: fld
integer :: stat
- character(len=*),parameter :: subname=' (Advertise Fields) '
+ character(len=*), parameter :: subname = '('//__FILE__//':AdvertiseFields)'
!-----------------------------------------------------------
call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO)
@@ -914,14 +917,32 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc)
end if
end do ! end of ncomps loop
+ ! Should mediator check for NaNs?
+ call NUOPC_CompAttributeGet(gcomp, name="check_for_nans", value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ if(isPresent .and. isSet) then
+ read(cvalue, *) mediator_checkfornans
+ else
+ mediator_checkfornans = .false.
+ endif
+ if(maintask) then
+ write(logunit,*) ' check_for_nans is ',mediator_checkfornans
+ if(mediator_checkfornans) then
+ write(logunit,*) ' Fields will be checked for NaN values when passed from mediator to component'
+ else
+ write(logunit,*) ' Fields will NOT be checked for NaN values when passed from mediator to component'
+ endif
+ endif
+
+
if (profile_memory) call ESMF_VMLogMemInfo("Leaving "//trim(subname))
call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO)
- end subroutine InitializeIPDv03p1
+ end subroutine AdvertiseFields
!-----------------------------------------------------------------------------
- subroutine InitializeIPDv03p3(gcomp, importState, exportState, clock, rc)
+ subroutine RealizeFieldsWithTransferProvided(gcomp, importState, exportState, clock, rc)
! Realize connected Fields with transfer action "provide"
@@ -941,7 +962,7 @@ subroutine InitializeIPDv03p3(gcomp, importState, exportState, clock, rc)
type(InternalState) :: is_local
type(ESMF_VM) :: vm
integer :: n
- character(len=*),parameter :: subname=' (Realize Fields with Transfer Provide) '
+ character(len=*), parameter :: subname = '('//__FILE__//':RealizeFieldsWithTransferProvided)'
!-----------------------------------------------------------
call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO)
@@ -981,11 +1002,11 @@ subroutine InitializeIPDv03p3(gcomp, importState, exportState, clock, rc)
if (profile_memory) call ESMF_VMLogMemInfo("Leaving "//trim(subname))
call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO)
- end subroutine InitializeIPDv03p3
+ end subroutine RealizeFieldsWithTransferProvided
!-----------------------------------------------------------------------------
- subroutine InitializeIPDv03p4(gcomp, importState, exportState, clock, rc)
+ subroutine ModifyDecompofMesh(gcomp, importState, exportState, clock, rc)
! Optionally modify the decomp/distr of transferred Grid/Mesh
@@ -1002,7 +1023,8 @@ subroutine InitializeIPDv03p4(gcomp, importState, exportState, clock, rc)
! local variables
type(InternalState) :: is_local
integer :: n1
- character(len=*),parameter :: subname=' (Modify Decomp of Mesh/Grid) '
+ character(len=*), parameter :: subname = '('//__FILE__//':ModifyDecompofMesh)'
+
!-----------------------------------------------------------
call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO)
@@ -1301,11 +1323,11 @@ subroutine realizeConnectedGrid(State,string,rc)
end subroutine realizeConnectedGrid
- end subroutine InitializeIPDv03p4
+ end subroutine ModifyDecompofMesh
!-----------------------------------------------------------------------------
- subroutine InitializeIPDv03p5(gcomp, importState, exportState, clock, rc)
+ subroutine RealizeFieldsWithTransferAccept(gcomp, importState, exportState, clock, rc)
use ESMF , only : ESMF_GridComp, ESMF_State, ESMF_Clock, ESMF_LogWrite
use ESMF , only : ESMF_SUCCESS, ESMF_LOGMSG_INFO, ESMF_StateIsCreated
@@ -1330,7 +1352,8 @@ subroutine InitializeIPDv03p5(gcomp, importState, exportState, clock, rc)
! local variables
type(InternalState) :: is_local
integer :: n1
- character(len=*),parameter :: subname=' (Realize Fields with Transfer Accept) '
+ character(len=*), parameter :: subname = '('//__FILE__//':RealizeFieldsWithTransferAccept)'
+
!-----------------------------------------------------------
call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO)
@@ -1402,7 +1425,7 @@ subroutine completeFieldInitialization(State,rc)
integer, allocatable :: ungriddedLBound(:), ungriddedUBound(:)
logical :: isPresent
logical :: meshcreated
- character(len=*),parameter :: subname=' (Complete Field Initialization) '
+ character(len=*), parameter :: subname = '('//__FILE__//':completeFieldInitialization)'
!-----------------------------------------------------------
call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO)
@@ -1512,7 +1535,7 @@ subroutine completeFieldInitialization(State,rc)
end subroutine completeFieldInitialization
- end subroutine InitializeIPDv03p5
+ end subroutine RealizeFieldsWithTransferAccept
!-----------------------------------------------------------------------------
@@ -1594,7 +1617,7 @@ subroutine DataInitialize(gcomp, rc)
logical,save :: first_call = .true.
real(r8) :: real_nx, real_ny
character(len=CX) :: msgString
- character(len=*), parameter :: subname=' (Data Initialization) '
+ character(len=*), parameter :: subname = '('//__FILE__//':DataInitialize)'
!-----------------------------------------------------------
call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO)
@@ -2200,8 +2223,8 @@ subroutine SetRunClock(gcomp, rc)
character(len=CL) :: stop_option
integer :: stop_n, stop_ymd
logical, save :: stopalarmcreated=.false.
+ character(len=*), parameter :: subname = '('//__FILE__//':SetRunClock)'
- character(len=*),parameter :: subname=' (Set Run Clock) '
!-----------------------------------------------------------
rc = ESMF_SUCCESS
@@ -2286,7 +2309,7 @@ subroutine med_meshinfo_create(FB, mesh_info, FBArea, rc)
real(r8), allocatable :: ownedElemCoords(:)
real(r8), pointer :: dataptr(:)
integer :: n, dimcount, fieldcount
- character(len=*),parameter :: subname=' (module_MED:med_meshinfo_create) '
+ character(len=*), parameter :: subname = '('//__FILE__//':med_meshinfo_create)'
!-------------------------------------------------------------------------------
rc= ESMF_SUCCESS
@@ -2359,7 +2382,7 @@ subroutine med_grid_write(grid, fileName, rc)
type(ESMF_ArrayBundle) :: arrayBundle
integer :: tileCount
logical :: isPresent
- character(len=*), parameter :: subname=' (Grid Write) '
+ character(len=*), parameter :: subname = '('//__FILE__//':med_grid_write)'
!-------------------------------------------------------------------------------
rc = ESMF_SUCCESS
diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90
index 802334f6f..8ea6651ea 100644
--- a/mediator/med_diag_mod.F90
+++ b/mediator/med_diag_mod.F90
@@ -95,6 +95,8 @@ module med_diag_mod
character(*), parameter :: FA1 = "(' ',a12,6f15.8)"
character(*), parameter :: FA0r = "(' ',12x,8(6x,a8,1x))"
character(*), parameter :: FA1r = "(' ',a12,8f15.8)"
+ character(*), parameter :: FA0s = "(' ',12x,8(7x,a8,2x))"
+ character(*), parameter :: FA1s = "(' ',a12,8g18.8)"
! ---------------------------------
! C for component
@@ -2683,7 +2685,7 @@ subroutine med_diag_print_summary(data, ip, date, tod)
write(diagunit,*) ' '
write(diagunit,FAH) subname,'NET SALT BUDGET (kg/m2s): period = ',&
trim(budget_diags%periods(ip)%name), ': date = ',date,tod
- write(diagunit,FA0r) ' atm',' lnd',' rof',' ocn',' ice nh',' ice sh',' glc',' *SUM* '
+ write(diagunit,FA0s) ' atm',' lnd',' rof',' ocn',' ice nh',' ice sh',' glc',' *SUM* '
do nf = f_salt_beg, f_salt_end
net_salt_atm = data(nf, c_atm_recv, ip) + data(nf, c_atm_send, ip)
net_salt_lnd = data(nf, c_lnd_recv, ip) + data(nf, c_lnd_send, ip)
@@ -2695,7 +2697,7 @@ subroutine med_diag_print_summary(data, ip, date, tod)
net_salt_tot = net_salt_atm + net_salt_lnd + net_salt_rof + net_salt_ocn + &
net_salt_ice_nh + net_salt_ice_sh + net_salt_glc
- write(diagunit,FA1r) budget_diags%fields(nf)%name,&
+ write(diagunit,FA1s) budget_diags%fields(nf)%name,&
net_salt_atm, net_salt_lnd, net_salt_rof, net_salt_ocn, &
net_salt_ice_nh, net_salt_ice_sh, net_salt_glc, net_salt_tot
enddo
@@ -2718,7 +2720,7 @@ subroutine med_diag_print_summary(data, ip, date, tod)
sum_net_salt_tot = sum_net_salt_atm + sum_net_salt_lnd + sum_net_salt_rof + sum_net_salt_ocn + &
sum_net_salt_ice_nh + sum_net_salt_ice_sh + sum_net_salt_glc
- write(diagunit,FA1r)' *SUM*',&
+ write(diagunit,FA1s)' *SUM*',&
sum_net_salt_atm, sum_net_salt_lnd, sum_net_salt_rof, sum_net_salt_ocn, &
sum_net_salt_ice_nh, sum_net_salt_ice_sh, sum_net_salt_glc, sum_net_salt_tot
end if
diff --git a/mediator/med_io_mod.F90 b/mediator/med_io_mod.F90
index 13ae0d3ec..82e0b04d0 100644
--- a/mediator/med_io_mod.F90
+++ b/mediator/med_io_mod.F90
@@ -7,7 +7,7 @@ module med_io_mod
use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, I8=>SHR_KIND_I8, R8=>SHR_KIND_R8
use med_kind_mod , only : R4=>SHR_KIND_R4
use med_constants_mod , only : fillvalue => SHR_CONST_SPVAL
- use ESMF , only : ESMF_VM, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LogFoundError
+ use ESMF , only : ESMF_VM, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LogFoundError, ESMF_LOGMSG_ERROR
use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_END_ABORT, ESMF_LOGERR_PASSTHRU
use ESMF , only : ESMF_VMGetCurrent, ESMF_VMGet, ESMF_VMBroadCast, ESMF_Finalize
use NUOPC , only : NUOPC_FieldDictionaryGetEntry
@@ -75,10 +75,7 @@ module med_io_mod
character(*),parameter :: prefix = "med_io_"
character(*),parameter :: modName = "(med_io_mod) "
character(*),parameter :: version = "cmeps0"
- integer , parameter :: number_strlen = 8
- integer , parameter :: file_desc_t_cnt = 20 ! Note - this is hard-wired for now
- character(CL) :: wfilename(0:file_desc_t_cnt) = ''
- type(file_desc_t) :: io_file(0:file_desc_t_cnt)
+
integer :: pio_iotype
integer :: pio_ioformat
type(iosystem_desc_t), pointer :: io_subsystem
@@ -198,7 +195,7 @@ subroutine med_io_init(gcomp, rc)
else if (trim(cvalue) .eq. '64BIT_DATA') then
pio_ioformat = PIO_64BIT_DATA
else
- call ESMF_LogWrite(trim(subname)//': need to provide valid option for pio_ioformat (CLASSIC|64BIT_OFFSET|64BIT_DATA)', ESMF_LOGMSG_INFO)
+ call ESMF_LogWrite(trim(subname)//': need to provide valid option for pio_ioformat (CLASSIC|64BIT_OFFSET|64BIT_DATA)', ESMF_LOGMSG_ERROR)
rc = ESMF_FAILURE
return
end if
@@ -223,7 +220,7 @@ subroutine med_io_init(gcomp, rc)
else if (trim(cvalue) .eq. 'NETCDF4P') then
pio_iotype = PIO_IOTYPE_NETCDF4P
else
- call ESMF_LogWrite(trim(subname)//': need to provide valid option for pio_typename (NETCDF|PNETCDF|NETCDF4C|NETCDF4P)', ESMF_LOGMSG_INFO)
+ call ESMF_LogWrite(trim(subname)//': need to provide valid option for pio_typename (NETCDF|PNETCDF|NETCDF4C|NETCDF4P)', ESMF_LOGMSG_ERROR)
rc = ESMF_FAILURE
return
end if
@@ -334,13 +331,13 @@ subroutine med_io_init(gcomp, rc)
else if (trim(cvalue) .eq. 'SUBSET') then
pio_rearranger = PIO_REARR_SUBSET
else
- call ESMF_LogWrite(trim(subname)//': need to provide valid option for pio_rearranger (BOX|SUBSET)', ESMF_LOGMSG_INFO)
+ call ESMF_LogWrite(trim(subname)//': need to provide valid option for pio_rearranger (BOX|SUBSET)', ESMF_LOGMSG_ERROR)
rc = ESMF_FAILURE
return
end if
else
- cvalue = 'BOX'
- pio_rearranger = PIO_REARR_BOX
+ cvalue = 'SUBSET'
+ pio_rearranger = PIO_REARR_SUBSET
end if
if (localPet == 0) write(logunit,*) trim(subname), ' : pio_rearranger = ', trim(cvalue), pio_rearranger
@@ -357,7 +354,7 @@ subroutine med_io_init(gcomp, rc)
if (isPresent .and. isSet) then
read(cvalue,*) pio_debug_level
if (pio_debug_level < 0 .or. pio_debug_level > 6) then
- call ESMF_LogWrite(trim(subname)//': need to provide valid option for pio_debug_level (0-6)', ESMF_LOGMSG_INFO)
+ call ESMF_LogWrite(trim(subname)//': need to provide valid option for pio_debug_level (0-6)', ESMF_LOGMSG_ERROR)
rc = ESMF_FAILURE
return
end if
@@ -381,7 +378,7 @@ subroutine med_io_init(gcomp, rc)
else if (trim(cvalue) .eq. 'COLL') then
pio_rearr_comm_type = PIO_REARR_COMM_COLL
else
- call ESMF_LogWrite(trim(subname)//': need to provide valid option for pio_rearr_comm_type (P2P|COLL)', ESMF_LOGMSG_INFO)
+ call ESMF_LogWrite(trim(subname)//': need to provide valid option for pio_rearr_comm_type (P2P|COLL)', ESMF_LOGMSG_ERROR)
rc = ESMF_FAILURE
return
end if
@@ -406,7 +403,7 @@ subroutine med_io_init(gcomp, rc)
else if (trim(cvalue) .eq. '2DDISABLE') then
pio_rearr_comm_fcd = PIO_REARR_COMM_FC_2D_DISABLE
else
- call ESMF_LogWrite(trim(subname)//': need to provide valid option for pio_rearr_comm_fcd (2DENABLE|IO2COMP|COMP2IO|2DDISABLE)', ESMF_LOGMSG_INFO)
+ call ESMF_LogWrite(trim(subname)//': need to provide valid option for pio_rearr_comm_fcd (2DENABLE|IO2COMP|COMP2IO|2DDISABLE)', ESMF_LOGMSG_ERROR)
rc = ESMF_FAILURE
return
end if
@@ -498,7 +495,7 @@ subroutine med_io_init(gcomp, rc)
end subroutine med_io_init
!===============================================================================
- subroutine med_io_wopen(filename, vm, clobber, file_ind, model_doi_url)
+ subroutine med_io_wopen(filename, io_file, vm, rc, clobber, file_ind, model_doi_url)
!---------------
! open netcdf file
@@ -511,17 +508,17 @@ subroutine med_io_wopen(filename, vm, clobber, file_ind, model_doi_url)
! input/output arguments
character(*), intent(in) :: filename
+ type(file_desc_t), intent(inout) :: io_file
type(ESMF_VM) :: vm
+ integer, intent(out) :: rc
logical, optional, intent(in) :: clobber
integer, optional, intent(in) :: file_ind
character(CL), optional, intent(in) :: model_doi_url
-
! local variables
logical :: lclobber
integer :: rcode
integer :: nmode
integer :: lfile_ind
- integer :: rc
integer :: iam
character(CL) :: lversion
character(CL) :: lmodel_doi_url
@@ -539,13 +536,11 @@ subroutine med_io_wopen(filename, vm, clobber, file_ind, model_doi_url)
lfile_ind = 0
if (present(file_ind)) lfile_ind=file_ind
- if (.not. pio_file_is_open(io_file(lfile_ind))) then
+ call ESMF_VMGet(vm, localPet=iam, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call ESMF_VMGet(vm, localPet=iam, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- ! filename not open
- wfilename(lfile_ind) = trim(filename)
+ if (.not. pio_file_is_open(io_file)) then
if (med_io_file_exists(vm, filename)) then
if (lclobber) then
@@ -554,20 +549,20 @@ subroutine med_io_wopen(filename, vm, clobber, file_ind, model_doi_url)
if(pio_iotype == PIO_IOTYPE_NETCDF .or. pio_iotype == PIO_IOTYPE_PNETCDF) then
nmode = ior(nmode,pio_ioformat)
endif
- rcode = pio_createfile(io_subsystem, io_file(lfile_ind), pio_iotype, trim(filename), nmode)
+ rcode = pio_createfile(io_subsystem, io_file, pio_iotype, trim(filename), nmode)
if(iam==0) write(logunit,'(a)') trim(subname)//' creating file '//trim(filename)
- rcode = pio_put_att(io_file(lfile_ind),pio_global,"file_version",version)
- rcode = pio_put_att(io_file(lfile_ind),pio_global,"model_doi_url",lmodel_doi_url)
+ rcode = pio_put_att(io_file,pio_global,"file_version",version)
+ rcode = pio_put_att(io_file,pio_global,"model_doi_url",lmodel_doi_url)
else
- rcode = pio_openfile(io_subsystem, io_file(lfile_ind), pio_iotype, trim(filename), pio_write)
+ rcode = pio_openfile(io_subsystem, io_file, pio_iotype, trim(filename), pio_write)
if (iam==0) write(logunit,'(a)') trim(subname)//' opening file '//trim(filename)
- call pio_seterrorhandling(io_file(lfile_ind),PIO_BCAST_ERROR)
- rcode = pio_get_att(io_file(lfile_ind),pio_global,"file_version",lversion)
- call pio_seterrorhandling(io_file(lfile_ind),PIO_INTERNAL_ERROR)
+ call pio_seterrorhandling(io_file,PIO_BCAST_ERROR)
+ rcode = pio_get_att(io_file,pio_global,"file_version",lversion)
+ call pio_seterrorhandling(io_file,PIO_INTERNAL_ERROR)
if (trim(lversion) /= trim(version)) then
- rcode = pio_redef(io_file(lfile_ind))
- rcode = pio_put_att(io_file(lfile_ind),pio_global,"file_version",version)
- rcode = pio_enddef(io_file(lfile_ind))
+ rcode = pio_redef(io_file)
+ rcode = pio_put_att(io_file,pio_global,"file_version",version)
+ rcode = pio_enddef(io_file)
endif
endif
else
@@ -577,22 +572,12 @@ subroutine med_io_wopen(filename, vm, clobber, file_ind, model_doi_url)
nmode = ior(nmode,pio_ioformat)
endif
- rcode = pio_createfile(io_subsystem, io_file(lfile_ind), pio_iotype, trim(filename), nmode)
+ rcode = pio_createfile(io_subsystem, io_file, pio_iotype, trim(filename), nmode)
if (iam==0) write(logunit,'(a)') trim(subname) //' creating file '// trim(filename)
- rcode = pio_put_att(io_file(lfile_ind),pio_global,"file_version",version)
- rcode = pio_put_att(io_file(lfile_ind),pio_global,"model_doi_url",lmodel_doi_url)
+ rcode = pio_put_att(io_file,pio_global,"file_version",version)
+ rcode = pio_put_att(io_file,pio_global,"model_doi_url",lmodel_doi_url)
endif
- elseif (trim(wfilename(lfile_ind)) /= trim(filename)) then
- ! filename is open, better match open filename
- if (iam==0) then
- write(logunit,'(a)') trim(subname)//' different filename currently open '//trim(filename)
- write(logunit,'(a)') trim(subname)//' different wfilename currently open '//trim(wfilename(lfile_ind))
- end if
- call ESMF_LogWrite(trim(subname)//'different file currently open '//trim(filename), ESMF_LOGMSG_INFO)
- rc = ESMF_FAILURE
- return
-
else
! filename is already open, just return
endif
@@ -600,7 +585,7 @@ subroutine med_io_wopen(filename, vm, clobber, file_ind, model_doi_url)
end subroutine med_io_wopen
!===============================================================================
- subroutine med_io_close(filename, vm, file_ind, rc)
+ subroutine med_io_close(io_file, rc)
!---------------
! close netcdf file
@@ -609,85 +594,51 @@ subroutine med_io_close(filename, vm, file_ind, rc)
use pio, only: pio_file_is_open, pio_closefile
! input/output variables
- character(*) , intent(in) :: filename
- type(ESMF_VM) , intent(in) :: vm
- integer,optional , intent(in) :: file_ind
+ type(file_desc_t) :: io_file
integer , intent(out) :: rc
! local variables
- integer :: lfile_ind
- integer :: iam
+
character(*),parameter :: subName = '(med_io_close) '
!-------------------------------------------------------------------------------
rc = ESMF_SUCCESS
- lfile_ind = 0
- if (present(file_ind)) lfile_ind=file_ind
-
- if (.not. pio_file_is_open(io_file(lfile_ind))) then
- ! filename not open, just return
- elseif (trim(wfilename(lfile_ind)) == trim(filename)) then
- ! filename matches, close it
- call pio_closefile(io_file(lfile_ind))
- !wfilename(lfile_ind) = ''
- else
- call ESMF_VMGet(vm, localPet=iam, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
-
- ! different filename is open, abort
- if (iam==0) then
- write(logunit,*) subname,' different wfilename and filename currently open, aborting '
- write(logunit,'(a)') 'filename = ',trim(filename)
- write(logunit,'(a)') 'wfilename = ',trim(wfilename(lfile_ind))
- write(logunit,'(i6)')'lfile_ind = ',lfile_ind
- end if
- call ESMF_LogWrite(subname//'different file currently open, aborting '//trim(filename), ESMF_LOGMSG_INFO)
- rc = ESMF_FAILURE
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) then
- call ESMF_Finalize(endflag=ESMF_END_ABORT)
- end if
+ if (pio_file_is_open(io_file)) then
+ call pio_closefile(io_file)
endif
end subroutine med_io_close
!===============================================================================
- subroutine med_io_redef(filename,file_ind)
+ subroutine med_io_redef(io_file)
use pio, only : pio_redef
! input/output variables
- character(len=*), intent(in) :: filename
- integer,optional,intent(in):: file_ind
-
+ type(file_desc_t) :: io_file
! local variables
- integer :: lfile_ind
integer :: rcode
!-------------------------------------------------------------------------------
- lfile_ind = 0
- if (present(file_ind)) lfile_ind=file_ind
- rcode = pio_redef(io_file(lfile_ind))
+ rcode = pio_redef(io_file)
end subroutine med_io_redef
!===============================================================================
- subroutine med_io_enddef(filename,file_ind)
+ subroutine med_io_enddef(io_file)
use pio, only : pio_enddef
! input/output variables
- character(len=*) , intent(in) :: filename
- integer,optional , intent(in) :: file_ind
+ type(file_desc_t) :: io_file
! local variables
- integer :: lfile_ind
+
integer :: rcode
!-------------------------------------------------------------------------------
- lfile_ind = 0
- if (present(file_ind)) lfile_ind=file_ind
- rcode = pio_enddef(io_file(lfile_ind))
+ rcode = pio_enddef(io_file)
end subroutine med_io_enddef
@@ -746,8 +697,8 @@ character(len=8) function med_io_sec2hms (seconds, rc)
end function med_io_sec2hms
!===============================================================================
- subroutine med_io_write_FB(filename, FB, whead, wdata, nx, ny, nt, &
- fillval, pre, flds, tavg, use_float, file_ind, tilesize, rc)
+ subroutine med_io_write_FB(io_file, FB, whead, wdata, nx, ny, nt, &
+ fillval, pre, flds, tavg, use_float, tilesize, rc)
!---------------
! Write FB to netcdf file
@@ -765,7 +716,7 @@ subroutine med_io_write_FB(filename, FB, whead, wdata, nx, ny, nt, &
use pio , only : pio_syncfile
! input/output variables
- character(len=*) , intent(in) :: filename ! file
+ type(file_desc_t) :: io_file
type(ESMF_FieldBundle) , intent(in) :: FB ! data to be written
logical , intent(in) :: whead ! write header
logical , intent(in) :: wdata ! write data
@@ -777,7 +728,6 @@ subroutine med_io_write_FB(filename, FB, whead, wdata, nx, ny, nt, &
character(len=*), optional , intent(in) :: flds(:) ! specific fields to write out
logical, optional , intent(in) :: tavg ! is this a tavg
logical, optional , intent(in) :: use_float ! write output as float rather than double
- integer, optional , intent(in) :: file_ind
integer, optional , intent(in) :: tilesize ! if non-zero, write atm component on tiles
integer , intent(out):: rc
@@ -811,7 +761,6 @@ subroutine med_io_write_FB(filename, FB, whead, wdata, nx, ny, nt, &
integer, pointer :: maxIndexPTile(:,:)
integer :: dimCount, tileCount
integer, pointer :: Dof(:)
- integer :: lfile_ind
real(r8), pointer :: fldptr1(:)
real(r8), pointer :: fldptr2(:,:)
real(r8), allocatable :: ownedElemCoords(:), ownedElemCoords_x(:), ownedElemCoords_y(:)
@@ -835,8 +784,7 @@ subroutine med_io_write_FB(filename, FB, whead, wdata, nx, ny, nt, &
if (present(pre)) lpre = trim(pre)
luse_float = .false.
if (present(use_float)) luse_float = use_float
- lfile_ind = 0
- if (present(file_ind)) lfile_ind=file_ind
+
atmtiles = .false.
if (present(tilesize)) then
if (tilesize > 0) atmtiles = .true.
@@ -848,7 +796,6 @@ subroutine med_io_write_FB(filename, FB, whead, wdata, nx, ny, nt, &
if (dbug_flag > 5) then
call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO)
endif
- rc = ESMF_Success
return
endif
@@ -954,22 +901,22 @@ subroutine med_io_write_FB(filename, FB, whead, wdata, nx, ny, nt, &
! Write header
if (whead) then
if (atmtiles) then
- rcode = pio_def_dim(io_file(lfile_ind), trim(lpre)//'_nx', lnx, dimid3(1))
- rcode = pio_def_dim(io_file(lfile_ind), trim(lpre)//'_ny', lny, dimid3(2))
- rcode = pio_def_dim(io_file(lfile_ind), trim(lpre)//'_ntiles', ntiles, dimid3(3))
+ rcode = pio_def_dim(io_file, trim(lpre)//'_nx', lnx, dimid3(1))
+ rcode = pio_def_dim(io_file, trim(lpre)//'_ny', lny, dimid3(2))
+ rcode = pio_def_dim(io_file, trim(lpre)//'_ntiles', ntiles, dimid3(3))
if (present(nt)) then
dimid4(1:3) = dimid3
- rcode = pio_inq_dimid(io_file(lfile_ind), 'time', dimid4(4))
+ rcode = pio_inq_dimid(io_file, 'time', dimid4(4))
dimid => dimid4
else
dimid => dimid3
endif
else
- rcode = pio_def_dim(io_file(lfile_ind), trim(lpre)//'_nx', lnx, dimid2(1))
- rcode = pio_def_dim(io_file(lfile_ind), trim(lpre)//'_ny', lny, dimid2(2))
+ rcode = pio_def_dim(io_file, trim(lpre)//'_nx', lnx, dimid2(1))
+ rcode = pio_def_dim(io_file, trim(lpre)//'_ny', lny, dimid2(2))
if (present(nt)) then
dimid3(1:2) = dimid2
- rcode = pio_inq_dimid(io_file(lfile_ind), 'time', dimid3(3))
+ rcode = pio_inq_dimid(io_file, 'time', dimid3(3))
dimid => dimid3
else
dimid => dimid2
@@ -1008,21 +955,21 @@ subroutine med_io_write_FB(filename, FB, whead, wdata, nx, ny, nt, &
name1 = trim(lpre)//'_'//trim(itemc)//trim(cnumber)
call ESMF_LogWrite(trim(subname)//': defining '//trim(name1), ESMF_LOGMSG_INFO)
if (luse_float) then
- rcode = pio_def_var(io_file(lfile_ind), trim(name1), PIO_REAL, dimid, varid)
- rcode = pio_put_att(io_file(lfile_ind), varid,"_FillValue",real(lfillvalue,r4))
+ rcode = pio_def_var(io_file, trim(name1), PIO_REAL, dimid, varid)
+ rcode = pio_put_att(io_file, varid,"_FillValue",real(lfillvalue,r4))
else
- rcode = pio_def_var(io_file(lfile_ind), trim(name1), PIO_DOUBLE, dimid, varid)
- rcode = pio_put_att(io_file(lfile_ind),varid,"_FillValue",lfillvalue)
+ rcode = pio_def_var(io_file, trim(name1), PIO_DOUBLE, dimid, varid)
+ rcode = pio_put_att(io_file,varid,"_FillValue",lfillvalue)
end if
if (NUOPC_FieldDictionaryHasEntry(trim(itemc))) then
call NUOPC_FieldDictionaryGetEntry(itemc, canonicalUnits=cunit, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
- rcode = pio_put_att(io_file(lfile_ind), varid, "units" , trim(cunit))
+ rcode = pio_put_att(io_file, varid, "units" , trim(cunit))
end if
- rcode = pio_put_att(io_file(lfile_ind), varid, "standard_name", trim(name1))
+ rcode = pio_put_att(io_file, varid, "standard_name", trim(name1))
if (present(tavg)) then
if (tavg) then
- rcode = pio_put_att(io_file(lfile_ind), varid, "cell_methods", "time: mean")
+ rcode = pio_put_att(io_file, varid, "cell_methods", "time: mean")
endif
endif
end if
@@ -1031,21 +978,21 @@ subroutine med_io_write_FB(filename, FB, whead, wdata, nx, ny, nt, &
name1 = trim(lpre)//'_'//trim(itemc)
call ESMF_LogWrite(trim(subname)//':'//trim(itemc)//':'//trim(name1),ESMF_LOGMSG_INFO)
if (luse_float) then
- rcode = pio_def_var(io_file(lfile_ind), trim(name1), PIO_REAL, dimid, varid)
- rcode = pio_put_att(io_file(lfile_ind), varid, "_FillValue", real(lfillvalue, r4))
+ rcode = pio_def_var(io_file, trim(name1), PIO_REAL, dimid, varid)
+ rcode = pio_put_att(io_file, varid, "_FillValue", real(lfillvalue, r4))
else
- rcode = pio_def_var(io_file(lfile_ind), trim(name1), PIO_DOUBLE, dimid, varid)
- rcode = pio_put_att(io_file(lfile_ind), varid, "_FillValue", lfillvalue)
+ rcode = pio_def_var(io_file, trim(name1), PIO_DOUBLE, dimid, varid)
+ rcode = pio_put_att(io_file, varid, "_FillValue", lfillvalue)
end if
if (NUOPC_FieldDictionaryHasEntry(trim(itemc))) then
call NUOPC_FieldDictionaryGetEntry(itemc, canonicalUnits=cunit, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
- rcode = pio_put_att(io_file(lfile_ind), varid, "units", trim(cunit))
+ rcode = pio_put_att(io_file, varid, "units", trim(cunit))
end if
- rcode = pio_put_att(io_file(lfile_ind), varid, "standard_name", trim(name1))
+ rcode = pio_put_att(io_file, varid, "standard_name", trim(name1))
if (present(tavg)) then
if (tavg) then
- rcode = pio_put_att(io_file(lfile_ind), varid, "cell_methods", "time: mean")
+ rcode = pio_put_att(io_file, varid, "cell_methods", "time: mean")
endif
end if
end if
@@ -1055,13 +1002,13 @@ subroutine med_io_write_FB(filename, FB, whead, wdata, nx, ny, nt, &
! Add coordinate information to file
do n = 1,ndims
if (luse_float) then
- rcode = pio_def_var(io_file(lfile_ind), trim(coordvarnames(n)), PIO_REAL, dimid, varid)
+ rcode = pio_def_var(io_file, trim(coordvarnames(n)), PIO_REAL, dimid, varid)
else
- rcode = pio_def_var(io_file(lfile_ind), trim(coordvarnames(n)), PIO_DOUBLE, dimid, varid)
+ rcode = pio_def_var(io_file, trim(coordvarnames(n)), PIO_DOUBLE, dimid, varid)
end if
- rcode = pio_put_att(io_file(lfile_ind), varid, "long_name", trim(coordnames(n)))
- rcode = pio_put_att(io_file(lfile_ind), varid, "units", trim(coordunits(n)))
- rcode = pio_put_att(io_file(lfile_ind), varid, "standard_name", trim(coordnames(n)))
+ rcode = pio_put_att(io_file, varid, "long_name", trim(coordnames(n)))
+ rcode = pio_put_att(io_file, varid, "units", trim(coordunits(n)))
+ rcode = pio_put_att(io_file, varid, "standard_name", trim(coordnames(n)))
end do
end if
@@ -1107,40 +1054,39 @@ subroutine med_io_write_FB(filename, FB, whead, wdata, nx, ny, nt, &
do n = 1,ungriddedUBound(1)
write(cnumber,'(i0)') n
name1 = trim(lpre)//'_'//trim(itemc)//trim(cnumber)
- rcode = pio_inq_varid(io_file(lfile_ind), trim(name1), varid)
- call pio_setframe(io_file(lfile_ind),varid,frame)
+ rcode = pio_inq_varid(io_file, trim(name1), varid)
+ call pio_setframe(io_file,varid,frame)
if (gridToFieldMap(1) == 1) then
- call pio_write_darray(io_file(lfile_ind), varid, iodesc, fldptr2(:,n), rcode, fillval=lfillvalue)
+ call pio_write_darray(io_file, varid, iodesc, fldptr2(:,n), rcode, fillval=lfillvalue)
else if (gridToFieldMap(1) == 2) then
- call pio_write_darray(io_file(lfile_ind), varid, iodesc, fldptr2(n,:), rcode, fillval=lfillvalue)
+ call pio_write_darray(io_file, varid, iodesc, fldptr2(n,:), rcode, fillval=lfillvalue)
end if
end do
else if (rank == 1 .or. rank == 0) then
name1 = trim(lpre)//'_'//trim(itemc)
- rcode = pio_inq_varid(io_file(lfile_ind), trim(name1), varid)
- call pio_setframe(io_file(lfile_ind),varid,frame)
+ rcode = pio_inq_varid(io_file, trim(name1), varid)
+ call pio_setframe(io_file,varid,frame)
! fix for writing data on exchange grid, which has no data in some PETs
if (rank == 0) nullify(fldptr1)
- call pio_write_darray(io_file(lfile_ind), varid, iodesc, fldptr1, rcode, fillval=lfillvalue)
+ call pio_write_darray(io_file, varid, iodesc, fldptr1, rcode, fillval=lfillvalue)
end if ! end if rank is 2 or 1 or 0
end if ! end if not "hgt"
end do ! end loop over fields in FB
! Fill coordinate variables - why is this being done each time?
- rcode = pio_inq_varid(io_file(lfile_ind), trim(coordvarnames(1)), varid)
- call pio_setframe(io_file(lfile_ind),varid,frame)
- call pio_write_darray(io_file(lfile_ind), varid, iodesc, ownedElemCoords_x, rcode, fillval=lfillvalue)
+ rcode = pio_inq_varid(io_file, trim(coordvarnames(1)), varid)
+ call pio_setframe(io_file,varid,frame)
+ call pio_write_darray(io_file, varid, iodesc, ownedElemCoords_x, rcode, fillval=lfillvalue)
- rcode = pio_inq_varid(io_file(lfile_ind), trim(coordvarnames(2)), varid)
- call pio_setframe(io_file(lfile_ind),varid,frame)
- call pio_write_darray(io_file(lfile_ind), varid, iodesc, ownedElemCoords_y, rcode, fillval=lfillvalue)
+ rcode = pio_inq_varid(io_file, trim(coordvarnames(2)), varid)
+ call pio_setframe(io_file,varid,frame)
+ call pio_write_darray(io_file, varid, iodesc, ownedElemCoords_y, rcode, fillval=lfillvalue)
- call pio_syncfile(io_file(lfile_ind))
- call pio_freedecomp(io_file(lfile_ind), iodesc)
+ call pio_syncfile(io_file)
+ call pio_freedecomp(io_file, iodesc)
endif
- deallocate(fieldNameList)
deallocate(ownedElemCoords, ownedElemCoords_x, ownedElemCoords_y)
if (dbug_flag > 5) then
@@ -1150,7 +1096,7 @@ subroutine med_io_write_FB(filename, FB, whead, wdata, nx, ny, nt, &
end subroutine med_io_write_FB
!===============================================================================
- subroutine med_io_write_int(filename, idata, dname, whead, wdata, file_ind, rc)
+ subroutine med_io_write_int(io_file, idata, dname, whead, wdata, rc)
use pio, only : var_desc_t, pio_def_var, pio_put_att, pio_int, pio_inq_varid, pio_put_var
@@ -1159,45 +1105,40 @@ subroutine med_io_write_int(filename, idata, dname, whead, wdata, file_ind, rc)
!---------------
! intput/output variables
- character(len=*) ,intent(in) :: filename ! file
+ type(file_desc_t) :: io_file
integer ,intent(in) :: idata ! data to be written
character(len=*) ,intent(in) :: dname ! name of data
logical ,intent(in) :: whead ! write header
logical ,intent(in) :: wdata ! write data
- integer,optional ,intent(in) :: file_ind
integer ,intent(out):: rc
! local variables
integer :: rcode
type(var_desc_t) :: varid
character(CL) :: cunit ! var units
- integer :: lfile_ind
character(*),parameter :: subName = '(med_io_write_int) '
!-------------------------------------------------------------------------------
rc = ESMF_SUCCESS
- lfile_ind = 0
- if (present(file_ind)) lfile_ind=file_ind
-
if (whead) then
if (NUOPC_FieldDictionaryHasEntry(trim(dname))) then
call NUOPC_FieldDictionaryGetEntry(dname, canonicalUnits=cunit, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
- rcode = pio_put_att(io_file(lfile_ind),varid,"units",trim(cunit))
+ rcode = pio_put_att(io_file,varid,"units",trim(cunit))
end if
- rcode = pio_def_var(io_file(lfile_ind),trim(dname),PIO_INT,varid)
- rcode = pio_put_att(io_file(lfile_ind),varid,"standard_name",trim(dname))
+ rcode = pio_def_var(io_file,trim(dname),PIO_INT,varid)
+ rcode = pio_put_att(io_file,varid,"standard_name",trim(dname))
endif
if (wdata) then
- rcode = pio_inq_varid(io_file(lfile_ind),trim(dname),varid)
- rcode = pio_put_var(io_file(lfile_ind),varid,idata)
+ rcode = pio_inq_varid(io_file,trim(dname),varid)
+ rcode = pio_put_var(io_file,varid,idata)
endif
end subroutine med_io_write_int
!===============================================================================
- subroutine med_io_write_int1d(filename, idata, dname, whead, wdata, file_ind, rc)
+ subroutine med_io_write_int1d(io_file, idata, dname, whead, wdata, file_ind, rc)
!---------------
! Write 1d integer array to netcdf file
@@ -1208,7 +1149,7 @@ subroutine med_io_write_int1d(filename, idata, dname, whead, wdata, file_ind, rc
use pio , only : pio_int, pio_def_var
! input/output arguments
- character(len=*) ,intent(in) :: filename ! file
+ type(file_desc_t) :: io_file
integer ,intent(in) :: idata(:) ! data to be written
character(len=*) ,intent(in) :: dname ! name of data
logical ,intent(in) :: whead ! write header
@@ -1235,21 +1176,21 @@ subroutine med_io_write_int1d(filename, idata, dname, whead, wdata, file_ind, rc
if (NUOPC_FieldDictionaryHasEntry(trim(dname))) then
call NUOPC_FieldDictionaryGetEntry(dname, canonicalUnits=cunit, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
- rcode = pio_put_att(io_file(lfile_ind),varid,"units",trim(cunit))
+ rcode = pio_put_att(io_file,varid,"units",trim(cunit))
end if
lnx = size(idata)
- rcode = pio_def_dim(io_file(lfile_ind),trim(dname),lnx,dimid(1))
- rcode = pio_def_var(io_file(lfile_ind),trim(dname),PIO_INT,dimid,varid)
- rcode = pio_put_att(io_file(lfile_ind),varid,"standard_name",trim(dname))
+ rcode = pio_def_dim(io_file,trim(dname),lnx,dimid(1))
+ rcode = pio_def_var(io_file,trim(dname),PIO_INT,dimid,varid)
+ rcode = pio_put_att(io_file,varid,"standard_name",trim(dname))
else if (wdata) then
- rcode = pio_inq_varid(io_file(lfile_ind),trim(dname),varid)
- rcode = pio_put_var(io_file(lfile_ind),varid,idata)
+ rcode = pio_inq_varid(io_file,trim(dname),varid)
+ rcode = pio_put_var(io_file,varid,idata)
endif
end subroutine med_io_write_int1d
!===============================================================================
- subroutine med_io_write_r8(filename, rdata, dname, whead, wdata, file_ind, rc)
+ subroutine med_io_write_r8(io_file, rdata, dname, whead, wdata, rc)
!---------------
! Write scalar double to netcdf file
@@ -1259,48 +1200,41 @@ subroutine med_io_write_r8(filename, rdata, dname, whead, wdata, file_ind, rc)
use pio , only : pio_double, pio_noerr, pio_inq_varid, pio_put_var
! input/output arguments
- character(len=*) ,intent(in) :: filename ! file
+ type(file_desc_T) :: io_file
real(r8) ,intent(in) :: rdata ! data to be written
character(len=*) ,intent(in) :: dname ! name of data
logical ,intent(in) :: whead ! write header
logical ,intent(in) :: wdata ! write data
- integer,optional ,intent(in) :: file_ind
integer ,intent(out):: rc
! local variables
integer :: rcode
type(var_desc_t) :: varid
character(CL) :: cunit ! var units
- integer :: lfile_ind
character(*),parameter :: subName = '(med_io_write_r8) '
!-------------------------------------------------------------------------------
rc = ESMF_SUCCESS
- if(present(file_ind)) then
- lfile_ind = file_ind
- else
- lfile_ind = 1
- endif
if (whead) then
- rcode = pio_def_var(io_file(lfile_ind),trim(dname),PIO_DOUBLE,varid)
+ rcode = pio_def_var(io_file,trim(dname),PIO_DOUBLE,varid)
if (rcode==PIO_NOERR) then
if (NUOPC_FieldDictionaryHasEntry(trim(dname))) then
call NUOPC_FieldDictionaryGetEntry(dname, canonicalUnits=cunit, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
- rcode = pio_put_att(io_file(lfile_ind),varid,"units",trim(cunit))
+ rcode = pio_put_att(io_file,varid,"units",trim(cunit))
end if
- rcode = pio_put_att(io_file(lfile_ind),varid,"standard_name",trim(dname))
+ rcode = pio_put_att(io_file,varid,"standard_name",trim(dname))
end if
else if (wdata) then
- rcode = pio_inq_varid(io_file(lfile_ind),trim(dname),varid)
- rcode = pio_put_var(io_file(lfile_ind),varid,rdata)
+ rcode = pio_inq_varid(io_file,trim(dname),varid)
+ rcode = pio_put_var(io_file,varid,rdata)
endif
end subroutine med_io_write_r8
!===============================================================================
- subroutine med_io_write_r81d(filename, rdata, dname, whead, wdata, file_ind, rc)
+ subroutine med_io_write_r81d(io_file, rdata, dname, whead, wdata, rc)
!---------------
! Write 1d double array to netcdf file
@@ -1310,12 +1244,11 @@ subroutine med_io_write_r81d(filename, rdata, dname, whead, wdata, file_ind, rc)
use pio , only : pio_inq_varid, pio_put_var, pio_double, pio_put_att
! !INPUT/OUTPUT PARAMETERS:
- character(len=*) ,intent(in) :: filename ! file
+ type(file_desc_t) :: io_file
real(r8) ,intent(in) :: rdata(:) ! data to be written
character(len=*) ,intent(in) :: dname ! name of data
logical ,intent(in) :: whead ! write header
logical ,intent(in) :: wdata ! write data
- integer,optional ,intent(in) :: file_ind
integer ,intent(out):: rc
! local variables
@@ -1324,38 +1257,32 @@ subroutine med_io_write_r81d(filename, rdata, dname, whead, wdata, file_ind, rc)
type(var_desc_t) :: varid
character(CL) :: cunit ! var units
integer :: lnx
- integer :: lfile_ind
character(*),parameter :: subName = '(med_io_write_r81d) '
!-------------------------------------------------------------------------------
rc = ESMF_SUCCESS
- if(present(file_ind)) then
- lfile_ind = file_ind
- else
- lfile_ind = 1
- endif
if (whead) then
lnx = size(rdata)
- rcode = pio_def_dim(io_file(lfile_ind),trim(dname)//'_nx',lnx,dimid(1))
- rcode = pio_def_var(io_file(lfile_ind),trim(dname),PIO_DOUBLE,dimid,varid)
+ rcode = pio_def_dim(io_file,trim(dname)//'_nx',lnx,dimid(1))
+ rcode = pio_def_var(io_file,trim(dname),PIO_DOUBLE,dimid,varid)
if (NUOPC_FieldDictionaryHasEntry(trim(dname))) then
call NUOPC_FieldDictionaryGetEntry(dname, canonicalUnits=cunit, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
- rcode = pio_put_att(io_file(lfile_ind),varid,"units",trim(cunit))
+ rcode = pio_put_att(io_file,varid,"units",trim(cunit))
end if
- rcode = pio_put_att(io_file(lfile_ind),varid,"standard_name",trim(dname))
+ rcode = pio_put_att(io_file,varid,"standard_name",trim(dname))
endif
if (wdata) then
- rcode = pio_inq_varid(io_file(lfile_ind),trim(dname),varid)
- rcode = pio_put_var(io_file(lfile_ind),varid,rdata)
+ rcode = pio_inq_varid(io_file,trim(dname),varid)
+ rcode = pio_put_var(io_file,varid,rdata)
endif
end subroutine med_io_write_r81d
!===============================================================================
- subroutine med_io_write_char(filename, rdata, dname, whead, wdata, file_ind, rc)
+ subroutine med_io_write_char(io_file, rdata, dname, whead, wdata, rc)
!---------------
! Write char string to netcdf file
@@ -1365,12 +1292,11 @@ subroutine med_io_write_char(filename, rdata, dname, whead, wdata, file_ind, rc)
use pio , only : pio_char, pio_put_var
! input/output arguments
- character(len=*) ,intent(in) :: filename ! file
+ type(file_desc_t) :: io_file
character(len=*) ,intent(in) :: rdata ! data to be written
character(len=*) ,intent(in) :: dname ! name of data
logical ,intent(in) :: whead ! write header
logical ,intent(in) :: wdata ! write data
- integer,optional ,intent(in) :: file_ind
integer ,intent(out):: rc
! local variables
@@ -1379,37 +1305,32 @@ subroutine med_io_write_char(filename, rdata, dname, whead, wdata, file_ind, rc)
type(var_desc_t) :: varid
character(CL) :: cunit ! var units
integer :: lnx
- integer :: lfile_ind
character(CL) :: charvar ! buffer for string read/write
character(*),parameter :: subName = '(med_io_write_char) '
!-------------------------------------------------------------------------------
rc = ESMF_SUCCESS
- if(present(file_ind)) then
- lfile_ind = file_ind
- else
- lfile_ind = 1
- endif
+
if (whead) then
lnx = len(charvar)
- rcode = pio_def_dim(io_file(lfile_ind),trim(dname)//'_len',lnx,dimid(1))
- rcode = pio_def_var(io_file(lfile_ind),trim(dname),PIO_CHAR,dimid,varid)
+ rcode = pio_def_dim(io_file,trim(dname)//'_len',lnx,dimid(1))
+ rcode = pio_def_var(io_file,trim(dname),PIO_CHAR,dimid,varid)
if (NUOPC_FieldDictionaryHasEntry(trim(dname))) then
call NUOPC_FieldDictionaryGetEntry(dname, canonicalUnits=cunit, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
end if
- rcode = pio_put_att(io_file(lfile_ind),varid,"standard_name",trim(dname))
+ rcode = pio_put_att(io_file,varid,"standard_name",trim(dname))
else if (wdata) then
charvar = ''
charvar = trim(rdata)
- rcode = pio_inq_varid(io_file(lfile_ind),trim(dname),varid)
- rcode = pio_put_var(io_file(lfile_ind),varid,charvar)
+ rcode = pio_inq_varid(io_file,trim(dname),varid)
+ rcode = pio_put_var(io_file,varid,charvar)
endif
end subroutine med_io_write_char
!===============================================================================
- subroutine med_io_define_time(time_units, calendar, file_ind, rc)
+ subroutine med_io_define_time(io_file, time_units, calendar, rc)
use ESMF, only : operator(==), operator(/=)
use ESMF, only : ESMF_Calendar, ESMF_CalendarIsCreated
@@ -1422,9 +1343,9 @@ subroutine med_io_define_time(time_units, calendar, file_ind, rc)
use pio , only : pio_inq_varid, pio_put_var
! input/output variables
+ type(file_desc_t) :: io_file
character(len=*) , intent(in) :: time_units ! units of time
type(ESMF_Calendar) , intent(in) :: calendar ! calendar
- integer, optional , intent(in) :: file_ind
integer , intent(out):: rc
! local variables
@@ -1432,16 +1353,12 @@ subroutine med_io_define_time(time_units, calendar, file_ind, rc)
integer :: dimid(1)
integer :: dimid2(2)
type(var_desc_t) :: varid
- integer :: lfile_ind
character(CL) :: calname ! calendar name
character(*),parameter :: subName = '(med_io_define_time) '
!-------------------------------------------------------------------------------
rc = ESMF_SUCCESS
- lfile_ind = 0
- if (present(file_ind)) lfile_ind=file_ind
-
if (.not. ESMF_CalendarIsCreated(calendar)) then
call ESMF_LogWrite(trim(subname)//' ERROR: calendar is not created ', &
ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u)
@@ -1450,9 +1367,9 @@ subroutine med_io_define_time(time_units, calendar, file_ind, rc)
end if
! define time and add calendar attribute
- rcode = pio_def_dim(io_file(lfile_ind), 'time', PIO_UNLIMITED, dimid(1))
- rcode = pio_def_var(io_file(lfile_ind), 'time', PIO_DOUBLE, dimid, varid)
- rcode = pio_put_att(io_file(lfile_ind), varid, 'units', trim(time_units))
+ rcode = pio_def_dim(io_file, 'time', PIO_UNLIMITED, dimid(1))
+ rcode = pio_def_var(io_file, 'time', PIO_DOUBLE, dimid, varid)
+ rcode = pio_put_att(io_file, varid, 'units', trim(time_units))
if (calendar == ESMF_CALKIND_360DAY) then
calname = '360_day'
else if (calendar == ESMF_CALKIND_GREGORIAN) then
@@ -1468,18 +1385,18 @@ subroutine med_io_define_time(time_units, calendar, file_ind, rc)
else if (calendar == ESMF_CALKIND_NOLEAP) then
calname = 'noleap'
end if
- rcode = pio_put_att(io_file(lfile_ind), varid, 'calendar', trim(calname))
+ rcode = pio_put_att(io_file, varid, 'calendar', trim(calname))
! define time bounds
dimid2(2) = dimid(1)
- rcode = pio_def_dim(io_file(lfile_ind), 'ntb', 2, dimid2(1))
- rcode = pio_def_var(io_file(lfile_ind), 'time_bnds', PIO_DOUBLE, dimid2, varid)
- rcode = pio_put_att(io_file(lfile_ind), varid, 'bounds', 'time_bnds')
+ rcode = pio_def_dim(io_file, 'ntb', 2, dimid2(1))
+ rcode = pio_def_var(io_file, 'time_bnds', PIO_DOUBLE, dimid2, varid)
+ rcode = pio_put_att(io_file, varid, 'bounds', 'time_bnds')
end subroutine med_io_define_time
!===============================================================================
- subroutine med_io_write_time(time_val, tbnds, nt, file_ind, rc)
+ subroutine med_io_write_time(io_file, time_val, tbnds, nt, rc)
!---------------
! Write time variable to netcdf file
@@ -1488,15 +1405,14 @@ subroutine med_io_write_time(time_val, tbnds, nt, file_ind, rc)
use pio, only : pio_put_att, pio_inq_varid, pio_put_var
! input/output variables
+ type(file_desc_t) :: io_file
real(r8) , intent(in) :: time_val ! data to be written
real(r8) , intent(in) :: tbnds(2) ! time bounds
integer , intent(in) :: nt
- integer , optional, intent(in) :: file_ind
integer , intent(out):: rc
! local variables
integer :: rcode
- integer :: lfile_ind
integer :: varid
integer :: start(2),count(2)
character(*),parameter :: subName = '(med_io_write_time) '
@@ -1504,19 +1420,16 @@ subroutine med_io_write_time(time_val, tbnds, nt, file_ind, rc)
rc = ESMF_SUCCESS
- lfile_ind = 0
- if (present(file_ind)) lfile_ind=file_ind
-
! write time
count = 1; start = nt
- rcode = pio_inq_varid(io_file(lfile_ind), 'time', varid)
- rcode = pio_put_var(io_file(lfile_ind), varid, start(1:1), count(1:1), (/time_val/))
+ rcode = pio_inq_varid(io_file, 'time', varid)
+ rcode = pio_put_var(io_file, varid, start(1:1), count(1:1), (/time_val/))
! write time bounds
- rcode = pio_inq_varid(io_file(lfile_ind), 'time_bnds', varid)
+ rcode = pio_inq_varid(io_file, 'time_bnds', varid)
start(1) = 1; start(2) = nt
count(1) = 2; count(2) = 1
- rcode = pio_put_var(io_file(lfile_ind), varid, start(1:2), count(1:2), tbnds)
+ rcode = pio_put_var(io_file, varid, start(1:2), count(1:2), tbnds)
end subroutine med_io_write_time
@@ -1539,7 +1452,7 @@ subroutine med_io_read_FB(filename, vm, FB, pre, frame, rc)
use pio , only : pio_read_darray, pio_offset_kind, pio_setframe
! input/output arguments
- character(len=*) ,intent(in) :: filename ! file
+ character(len=*) ,intent(in) :: filename
type(ESMF_VM) ,intent(in) :: vm
type(ESMF_FieldBundle) ,intent(in) :: FB ! data to be read
character(len=*) ,optional ,intent(in) :: pre ! prefix to variable name
diff --git a/mediator/med_methods_mod.F90 b/mediator/med_methods_mod.F90
index bd5b60793..54fe20ec1 100644
--- a/mediator/med_methods_mod.F90
+++ b/mediator/med_methods_mod.F90
@@ -24,8 +24,13 @@ module med_methods_mod
med_methods_FieldPtr_compare2
end interface
- ! used/reused in module
+ interface med_methods_check_for_nans
+ module procedure med_methods_check_for_nans_1d
+ module procedure med_methods_check_for_nans_2d
+ end interface med_methods_check_for_nans
+ ! used/reused in module
+ logical, public :: mediator_checkfornans ! set in med.F90 AdvertiseFields
logical :: isPresent
character(len=1024) :: msgString
type(ESMF_FieldStatus_Flag) :: status
@@ -49,6 +54,7 @@ module med_methods_mod
public med_methods_FB_getdata2d
public med_methods_FB_getdata1d
public med_methods_FB_getmesh
+ public med_methods_FB_check_for_nans
public med_methods_State_reset
public med_methods_State_diagnose
@@ -71,6 +77,8 @@ module med_methods_mod
#ifdef DIAGNOSE
private med_methods_Array_diagnose
#endif
+ private med_methods_check_for_nans
+
!-----------------------------------------------------------------------------
contains
!-----------------------------------------------------------------------------
@@ -2497,4 +2505,101 @@ subroutine med_methods_FB_getmesh(FB, mesh, rc)
end subroutine med_methods_FB_getmesh
+ !-----------------------------------------------------------------------------
+ subroutine med_methods_FB_check_for_nans(FB, maintask, logunit, rc)
+ use ESMF, only : ESMF_FieldBundle, ESMF_Field, ESMF_FieldBundleGet, ESMF_FieldGet
+ ! input/output variables
+ type(ESMF_FieldBundle) , intent(in) :: FB
+ logical , intent(in) :: maintask
+ integer , intent(in) :: logunit
+ integer , intent(inout) :: rc
+
+ ! local variables
+ type(ESMF_Field) :: field
+ integer :: index
+ integer :: fieldcount
+ integer :: fieldrank
+ character(len=CL) :: fieldname
+ real(r8) , pointer :: dataptr1d(:)
+ real(r8) , pointer :: dataptr2d(:,:)
+ integer :: nancount
+ character(len=CS) :: nancount_char
+ character(len=CL) :: msg_error
+ logical :: nanfound
+ character(len=*), parameter :: subname='(med_methods_FB_check_for_nans)'
+ ! ----------------------------------------------
+ rc = ESMF_SUCCESS
+
+ if(.not. mediator_checkfornans) return
+
+ call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+
+ nanfound = .false.
+ do index=1,fieldCount
+ call med_methods_FB_getNameN(FB, index, fieldname, rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call ESMF_FieldBundleGet(FB, fieldName=fieldname, field=field, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call ESMF_FieldGet(field, rank=fieldrank, name=fieldname, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ if (fieldrank == 1) then
+ call ESMF_FieldGet(field, farrayPtr=dataptr1d, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call med_methods_check_for_nans(dataptr1d, nancount)
+ else
+ call ESMF_FieldGet(field, farrayPtr=dataptr2d, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call med_methods_check_for_nans(dataptr2d, nancount)
+ end if
+ if (nancount > 0) then
+ write(nancount_char, '(i0)') nancount
+ msg_error = "ERROR: " // trim(nancount_char) //" nans found in "//trim(fieldname)
+ call ESMF_LogWrite(trim(msg_error), ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u)
+ nanfound = .true.
+ end if
+ end do
+ if (nanfound) then
+ call ESMF_LogWrite('ABORTING JOB', ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u)
+ rc = ESMF_FAILURE
+ return
+ end if
+
+ end subroutine med_methods_FB_check_for_nans
+
+ !-----------------------------------------------------------------------------
+ subroutine med_methods_check_for_nans_1d(dataptr, nancount)
+ use shr_infnan_mod, only: shr_infnan_isnan
+ ! input/output variables
+ real(r8) , intent(in) :: dataptr(:)
+ integer , intent(out) :: nancount
+ ! local variables
+ integer :: n
+
+ nancount = 0
+ do n = 1,size(dataptr)
+ if (shr_infnan_isnan(dataptr(n))) then
+ nancount = nancount + 1
+ end if
+ end do
+ end subroutine med_methods_check_for_nans_1d
+
+ subroutine med_methods_check_for_nans_2d(dataptr, nancount)
+ use shr_infnan_mod, only: shr_infnan_isnan
+ ! input/output variables
+ real(r8) , intent(in) :: dataptr(:,:)
+ integer , intent(out) :: nancount
+ ! local variables
+ integer :: n,k
+
+ nancount = 0
+ do k = 1,size(dataptr, dim=1)
+ do n = 1,size(dataptr, dim=2)
+ if (shr_infnan_isnan(dataptr(k,n))) then
+ nancount = nancount + 1
+ end if
+ end do
+ end do
+ end subroutine med_methods_check_for_nans_2d
+
end module med_methods_mod
diff --git a/mediator/med_phases_aofluxes_mod.F90 b/mediator/med_phases_aofluxes_mod.F90
index 0b3d10901..48055e92e 100644
--- a/mediator/med_phases_aofluxes_mod.F90
+++ b/mediator/med_phases_aofluxes_mod.F90
@@ -27,7 +27,7 @@ module med_phases_aofluxes_mod
use ESMF , only : ESMF_XGridGet, ESMF_MeshCreate, ESMF_MeshWrite, ESMF_KIND_R8
use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8
use med_internalstate_mod , only : InternalState, maintask, logunit
- use med_internalstate_mod , only : compatm, compocn, coupling_mode, aoflux_code, mapconsd, mapconsf, mapfcopy
+ use med_internalstate_mod , only : compatm, compocn, compwav, coupling_mode, aoflux_code, mapconsd, mapconsf, mapfcopy
use med_constants_mod , only : dbug_flag => med_constants_dbug_flag
use med_utils_mod , only : memcheck => med_memcheck
use med_utils_mod , only : chkerr => med_utils_chkerr
@@ -487,6 +487,7 @@ subroutine med_aofluxes_init_ogrid(gcomp, aoflux_in, aoflux_out, rc)
use esmFlds , only : med_fldlist_GetaofluxfldList
use esmFlds , only : med_fldList_type
use med_map_mod , only : med_map_packed_field_create
+ use med_methods_mod , only : FB_fldchk => med_methods_FB_FldChk
! Arguments
type(ESMF_GridComp) , intent(inout) :: gcomp
@@ -565,7 +566,6 @@ subroutine med_aofluxes_init_ogrid(gcomp, aoflux_in, aoflux_out, rc)
if (is_local%wrap%aoflux_grid == 'ogrid') then
if ( ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_o) .and. &
ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_a)) then
-
call med_map_packed_field_create(destcomp=compatm, &
flds_scalar_name=is_local%wrap%flds_scalar_name, &
fieldsSrc=fldListMed_aoflux, &
@@ -573,7 +573,6 @@ subroutine med_aofluxes_init_ogrid(gcomp, aoflux_in, aoflux_out, rc)
FBDst=is_local%wrap%FBMed_aoflux_a, &
packed_data=is_local%wrap%packed_data_aoflux_o2a(:), rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
-
end if
end if
@@ -768,6 +767,7 @@ subroutine med_aofluxes_init_xgrid(gcomp, aoflux_in, aoflux_out, rc)
type(ESMF_Mesh) :: xch_mesh
real(r8), pointer :: dataptr(:)
integer :: fieldcount
+ integer :: stp ! srcTermProcessing is declared inout and must have variable not constant
type(ESMF_CoordSys_Flag) :: coordSys
real(ESMF_KIND_R8) ,allocatable :: garea(:)
character(len=*),parameter :: subname=' (med_aofluxes_init_xgrid) '
@@ -870,11 +870,12 @@ subroutine med_aofluxes_init_xgrid(gcomp, aoflux_in, aoflux_out, rc)
regridmethod=ESMF_REGRIDMETHOD_CONSERVE_2ND, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
if (trim(coupling_mode) == 'cesm') then
+ stp = 1
call ESMF_FieldRegridStore(field_a, field_x, routehandle=rh_agrid2xgrid_bilinr, &
- regridmethod=ESMF_REGRIDMETHOD_BILINEAR, dstMaskValues=(/0/), rc=rc)
+ regridmethod=ESMF_REGRIDMETHOD_BILINEAR, dstMaskValues=(/0/), srcTermProcessing=stp, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call ESMF_FieldRegridStore(field_a, field_x, routehandle=rh_agrid2xgrid_patch, &
- regridmethod=ESMF_REGRIDMETHOD_PATCH, dstMaskValues=(/0/), rc=rc)
+ regridmethod=ESMF_REGRIDMETHOD_PATCH, dstMaskValues=(/0/), srcTermProcessing=stp, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
end if
@@ -948,6 +949,9 @@ subroutine med_aofluxes_update(gcomp, aoflux_in, aoflux_out, rc)
use ESMF , only : ESMF_GridComp
use ESMF , only : ESMF_LogWrite, ESMF_LogMsg_Info, ESMF_SUCCESS
use med_map_mod , only : med_map_field_packed, med_map_rh_is_created
+ use med_map_mod , only : med_map_routehandles_init
+ use med_methods_mod, only : FB_fldchk => med_methods_FB_fldchk
+ use med_methods_mod, only : FB_diagnose => med_methods_FB_diagnose
#ifdef CESMCOUPLED
use shr_flux_mod , only : flux_atmocn
#else
@@ -970,6 +974,9 @@ subroutine med_aofluxes_update(gcomp, aoflux_in, aoflux_out, rc)
real(r8), parameter :: p0 = 100000.0_r8 ! reference pressure in Pa
real(r8), parameter :: rcp = 0.286_r8 ! gas constant of air / specific heat capacity at a constant pressure
real(r8), parameter :: rdair = 287.058_r8 ! dry air gas constant in J/K/kg
+ integer :: maptype
+ type(ESMF_Field) :: field_src
+ type(ESMF_Field) :: field_dst
character(*),parameter :: subName = '(med_aofluxes_update) '
!-----------------------------------------------------------------------
@@ -1115,6 +1122,35 @@ subroutine med_aofluxes_update(gcomp, aoflux_in, aoflux_out, rc)
end if
+ ! map taux and tauy from ocean to wave grid if stresses are needed on the wave grid
+ if ( FB_fldchk(is_local%wrap%FBExp(compwav), 'Fwxx_taux', rc=rc) .and. &
+ FB_fldchk(is_local%wrap%FBExp(compwav), 'Fwxx_tauy', rc=rc)) then
+ maptype = mapconsf
+ if (.not. med_map_RH_is_created(is_local%wrap%RH(compocn,compwav,:), maptype, rc=rc)) then
+ call med_map_routehandles_init( compocn, compwav, &
+ FBSrc=is_local%wrap%FBImp(compocn,compocn), &
+ FBDst=is_local%wrap%FBImp(compwav,compwav), &
+ mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ end if
+ call ESMF_FieldBundleGet(is_local%wrap%FBMed_aoflux_o, 'Faox_taux', field=field_src, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call ESMF_FieldBundleGet(is_local%wrap%FBExp(compwav), 'Fwxx_taux', field=field_dst, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call ESMF_FieldRegrid(field_src, field_dst, &
+ routehandle=is_local%wrap%RH(compocn, compwav, maptype), &
+ termorderflag=ESMF_TERMORDER_SRCSEQ, zeroregion=ESMF_REGION_TOTAL, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call ESMF_FieldBundleGet(is_local%wrap%FBMed_aoflux_o, 'Faox_tauy', field=field_src, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call ESMF_FieldBundleGet(is_local%wrap%FBExp(compwav), 'Fwxx_tauy', field=field_dst, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call ESMF_FieldRegrid(field_src, field_dst, &
+ routehandle=is_local%wrap%RH(compocn, compwav, maptype), &
+ termorderflag=ESMF_TERMORDER_SRCSEQ, zeroregion=ESMF_REGION_TOTAL, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
+ end if
+
call t_stopf('MED:'//subname)
end subroutine med_aofluxes_update
diff --git a/mediator/med_phases_history_mod.F90 b/mediator/med_phases_history_mod.F90
index 2f7c9f062..5f150a4b7 100644
--- a/mediator/med_phases_history_mod.F90
+++ b/mediator/med_phases_history_mod.F90
@@ -24,7 +24,8 @@ module med_phases_history_mod
use med_time_mod , only : med_time_alarmInit
use med_io_mod , only : med_io_write, med_io_wopen, med_io_enddef, med_io_close
use perf_mod , only : t_startf, t_stopf
-
+ use pio , only : file_desc_t
+
implicit none
private
@@ -59,6 +60,7 @@ module med_phases_history_mod
! Instantaneous history files datatypes/variables per component
! ----------------------------
type, public :: instfile_type
+ type(file_desc_t):: io_file
logical :: write_inst
character(CS) :: hist_option
integer :: hist_n
@@ -74,6 +76,7 @@ module med_phases_history_mod
! Time averaging history files
! ----------------------------
type, public :: avgfile_type
+ type(file_desc_t) :: io_file
logical :: write_avg
type(ESMF_FieldBundle) :: FBaccum_import ! field bundle for time averaging
integer :: accumcnt_import ! field bundle accumulation counter
@@ -93,6 +96,7 @@ module med_phases_history_mod
! Auxiliary history files
! ----------------------------
type, public :: auxfile_type
+ type(file_desc_t) :: io_file
character(CS), allocatable :: flds(:) ! array of aux field names
character(CS) :: auxname ! name for history file creation
character(CL) :: histfile = '' ! current history file name
@@ -155,6 +159,7 @@ subroutine med_phases_history_write(gcomp, rc)
integer, intent(out) :: rc
! local variables
+ type(file_desc_t) :: io_file
type(InternalState) :: is_local
type(ESMF_Clock) :: mclock
type(ESMF_Alarm) :: alarm
@@ -292,22 +297,23 @@ subroutine med_phases_history_write(gcomp, rc)
! Create history file
call ESMF_GridCompGet(gcomp, vm=vm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_wopen(hist_file, vm, clobber=.true.)
+ call med_io_wopen(hist_file, io_file, vm, rc, clobber=.true.)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
! Loop over whead/wdata phases
do m = 1,2
if (m == 2) then
- call med_io_enddef(hist_file)
+ call med_io_enddef(io_file)
end if
! Write time values
if (whead(m)) then
call ESMF_ClockGet(mclock, calendar=calendar, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_define_time(time_units, calendar, rc=rc)
+ call med_io_define_time(io_file, time_units, calendar, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
else
- call med_io_write_time(time_val, time_bnds, nt=1, rc=rc)
+ call med_io_write_time(io_file, time_val, time_bnds, nt=1, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
@@ -315,49 +321,49 @@ subroutine med_phases_history_write(gcomp, rc)
! Write import and export field bundles
if (is_local%wrap%comp_present(n)) then
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBimp(n,n),rc=rc)) then
- call med_io_write(hist_file, is_local%wrap%FBimp(n,n), whead(m), wdata(m), &
+ call med_io_write(io_file, is_local%wrap%FBimp(n,n), whead(m), wdata(m), &
is_local%wrap%nx(n), is_local%wrap%ny(n), nt=1, pre=trim(compname(n))//'Imp', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
endif
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBexp(n),rc=rc)) then
- call med_io_write(hist_file, is_local%wrap%FBexp(n), whead(m), wdata(m), &
+ call med_io_write(io_file, is_local%wrap%FBexp(n), whead(m), wdata(m), &
is_local%wrap%nx(n), is_local%wrap%ny(n), nt=1, pre=trim(compname(n))//'Exp', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
endif
end if
! Write mediator fraction field bundles
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBFrac(n),rc=rc)) then
- call med_io_write(hist_file, is_local%wrap%FBFrac(n), whead(m), wdata(m), &
+ call med_io_write(io_file, is_local%wrap%FBFrac(n), whead(m), wdata(m), &
is_local%wrap%nx(n), is_local%wrap%ny(n), nt=1, pre='Med_frac_'//trim(compname(n)), rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
! Write component mediator area field bundles
- call med_io_write(hist_file, is_local%wrap%FBArea(n), whead(m), wdata(m), &
+ call med_io_write(io_file, is_local%wrap%FBArea(n), whead(m), wdata(m), &
is_local%wrap%nx(n), is_local%wrap%ny(n), nt=1, pre='MED_'//trim(compname(n)), rc=rc)
end do
! Write atm/ocn fluxes and ocean albedoes if field bundles are created
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_ocnalb_o,rc=rc)) then
- call med_io_write(hist_file, is_local%wrap%FBMed_ocnalb_o, whead(m), wdata(m), &
+ call med_io_write(io_file, is_local%wrap%FBMed_ocnalb_o, whead(m), wdata(m), &
is_local%wrap%nx(compocn), is_local%wrap%ny(compocn), nt=1, pre='Med_alb_ocn', rc=rc)
end if
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_o,rc=rc)) then
- call med_io_write(hist_file, is_local%wrap%FBMed_aoflux_o, whead(m), wdata(m), &
+ call med_io_write(io_file, is_local%wrap%FBMed_aoflux_o, whead(m), wdata(m), &
is_local%wrap%nx(compocn), is_local%wrap%ny(compocn), nt=1, pre='Med_aoflux_ocn', rc=rc)
end if
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_ocnalb_a,rc=rc)) then
- call med_io_write(hist_file, is_local%wrap%FBMed_ocnalb_a, whead(m), wdata(m), &
+ call med_io_write(io_file, is_local%wrap%FBMed_ocnalb_a, whead(m), wdata(m), &
is_local%wrap%nx(compatm), is_local%wrap%ny(compatm), nt=1, pre='Med_alb_atm', rc=rc)
end if
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_a,rc=rc)) then
- call med_io_write(hist_file, is_local%wrap%FBMed_aoflux_a, whead(m), wdata(m), &
+ call med_io_write(io_file, is_local%wrap%FBMed_aoflux_a, whead(m), wdata(m), &
is_local%wrap%nx(compatm), is_local%wrap%ny(compatm), nt=1, pre='Med_aoflux_atm', rc=rc)
end if
end do ! end of loop over whead/wdata m index phases
! Close file
- call med_io_close(hist_file, vm, rc=rc)
+ call med_io_close(io_file, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if ! end of write_now if-block
@@ -463,43 +469,44 @@ subroutine med_phases_history_write_med(gcomp, rc)
! Create history file
call ESMF_GridCompGet(gcomp, vm=vm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_wopen(hist_file, vm, clobber=.true.)
+ call med_io_wopen(hist_file, instfiles(compmed)%io_file, vm, rc, clobber=.true.)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
do m = 1,2
! Write time values
if (whead(m)) then
call ESMF_ClockGet(instfiles(compmed)%clock, calendar=calendar, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_define_time(time_units, calendar, rc=rc)
+ call med_io_define_time(instfiles(compmed)%io_file, time_units, calendar, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
else
- call med_io_enddef(hist_file)
- call med_io_write_time(time_val, time_bnds, nt=1, rc=rc)
+ call med_io_enddef(instfiles(compmed)%io_file)
+ call med_io_write_time(instfiles(compmed)%io_file, time_val, time_bnds, nt=1, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
! Write aoflux fields computed in mediator
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_o,rc=rc)) then
- call med_io_write(hist_file, is_local%wrap%FBMed_aoflux_o, whead(m), wdata(m), &
+ call med_io_write(instfiles(compmed)%io_file, is_local%wrap%FBMed_aoflux_o, whead(m), wdata(m), &
is_local%wrap%nx(compocn), is_local%wrap%ny(compocn), nt=1, pre='Med_aoflux_ocn', rc=rc)
end if
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_a,rc=rc)) then
- call med_io_write(hist_file, is_local%wrap%FBMed_aoflux_a, whead(m), wdata(m), &
+ call med_io_write(instfiles(compmed)%io_file, is_local%wrap%FBMed_aoflux_a, whead(m), wdata(m), &
is_local%wrap%nx(compatm), is_local%wrap%ny(compatm), nt=1, pre='Med_aoflux_atm', rc=rc)
end if
! If appropriate - write ocn albedos computed in mediator
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_ocnalb_o,rc=rc)) then
- call med_io_write(hist_file, is_local%wrap%FBMed_ocnalb_o, whead(m), wdata(m), &
+ call med_io_write(instfiles(compmed)%io_file, is_local%wrap%FBMed_ocnalb_o, whead(m), wdata(m), &
is_local%wrap%nx(compocn), is_local%wrap%ny(compocn), nt=1, pre='Med_alb_ocn', rc=rc)
end if
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_ocnalb_a,rc=rc)) then
- call med_io_write(hist_file, is_local%wrap%FBMed_ocnalb_a, whead(m), wdata(m), &
+ call med_io_write(instfiles(compmed)%io_file, is_local%wrap%FBMed_ocnalb_a, whead(m), wdata(m), &
is_local%wrap%nx(compatm), is_local%wrap%ny(compatm), nt=1, pre='Med_alb_atm', rc=rc)
end if
end do ! end of loop over m
! Close file
- call med_io_close(hist_file, vm, rc=rc)
+ call med_io_close(instfiles(compmed)%io_file, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if ! end of if-write_now block
@@ -523,6 +530,7 @@ subroutine med_phases_history_write_lnd2glc(gcomp, fldbun, rc)
integer , intent(out) :: rc
! local variables
+ type(file_desc_t) :: io_file
type(InternalState) :: is_local
type(ESMF_VM) :: vm
type(ESMF_Clock) :: clock
@@ -596,27 +604,28 @@ subroutine med_phases_history_write_lnd2glc(gcomp, fldbun, rc)
! Create history file
call ESMF_GridCompGet(gcomp, vm=vm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_wopen(hist_file, vm, clobber=.true.)
+ call med_io_wopen(hist_file, io_file, vm, rc, clobber=.true.)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
! Write data to history file
do m = 1,2
if (whead(m)) then
call ESMF_ClockGet(clock, calendar=calendar, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_define_time(time_units, calendar, rc=rc)
+ call med_io_define_time(io_file, time_units, calendar, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
else
- call med_io_enddef(hist_file)
- call med_io_write_time(time_val, time_bnds, nt=1, rc=rc)
+ call med_io_enddef(io_file)
+ call med_io_write_time(io_file, time_val, time_bnds, nt=1, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
- call med_io_write(hist_file, fldbun, whead(m), wdata(m), is_local%wrap%nx(complnd), is_local%wrap%ny(complnd), &
+ call med_io_write(io_file, fldbun, whead(m), wdata(m), is_local%wrap%nx(complnd), is_local%wrap%ny(complnd), &
nt=1, pre=trim(compname(complnd))//'Imp', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end do ! end of loop over m
! Close history file
- call med_io_close(hist_file, vm, rc=rc)
+ call med_io_close(io_file, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end subroutine med_phases_history_write_lnd2glc
@@ -749,17 +758,18 @@ subroutine med_phases_history_write_comp_inst(gcomp, compid, instfile, rc)
! Create history file
call ESMF_GridCompGet(gcomp, vm=vm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_wopen(hist_file, vm, clobber=.true.)
+ call med_io_wopen(hist_file, instfile%io_file, vm, rc, clobber=.true.)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
do m = 1,2
! Write time values
if (whead(m)) then
call ESMF_ClockGet(instfile%clock, calendar=calendar, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_define_time(time_units, calendar, rc=rc)
+ call med_io_define_time(instfile%io_file, time_units, calendar, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
else
- call med_io_enddef(hist_file)
- call med_io_write_time(time_val, time_bnds, nt=1, rc=rc)
+ call med_io_enddef(instfile%io_file)
+ call med_io_write_time(instfile%io_file, time_val, time_bnds, nt=1, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
@@ -767,19 +777,19 @@ subroutine med_phases_history_write_comp_inst(gcomp, compid, instfile, rc)
ny = is_local%wrap%ny(compid)
! Define/write import field bundle
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBimp(compid,compid),rc=rc)) then
- call med_io_write(hist_file, is_local%wrap%FBimp(compid,compid), whead(m), wdata(m), nx, ny, &
+ call med_io_write(instfile%io_file, is_local%wrap%FBimp(compid,compid), whead(m), wdata(m), nx, ny, &
nt=1, pre=trim(compname(compid))//'Imp', tilesize=hist_tilesize, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
endif
! Define/write import export bundle
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBexp(compid),rc=rc)) then
- call med_io_write(hist_file, is_local%wrap%FBexp(compid), whead(m), wdata(m), nx, ny, &
+ call med_io_write(instfile%io_file, is_local%wrap%FBexp(compid), whead(m), wdata(m), nx, ny, &
nt=1, pre=trim(compname(compid))//'Exp', tilesize=hist_tilesize, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
endif
! Define/Write mediator fractions
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBFrac(compid),rc=rc)) then
- call med_io_write(hist_file, is_local%wrap%FBFrac(compid), whead(m), wdata(m), nx, ny, &
+ call med_io_write(instfile%io_file, is_local%wrap%FBFrac(compid), whead(m), wdata(m), nx, ny, &
nt=1, pre='Med_frac_'//trim(compname(compid)), tilesize=hist_tilesize, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
@@ -787,7 +797,7 @@ subroutine med_phases_history_write_comp_inst(gcomp, compid, instfile, rc)
end do ! end of loop over m
! Close file
- call med_io_close(hist_file, vm, rc=rc)
+ call med_io_close(instfile%io_file, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
@@ -953,17 +963,18 @@ subroutine med_phases_history_write_comp_avg(gcomp, compid, avgfile, rc)
! Create history file
call ESMF_GridCompGet(gcomp, vm=vm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_wopen(hist_file, vm, clobber=.true.)
+ call med_io_wopen(hist_file, avgfile%io_file, vm, rc, clobber=.true.)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
do m = 1,2
! Write time values
if (whead(m)) then
call ESMF_ClockGet(avgfile%clock, calendar=calendar, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_define_time(time_units, calendar, rc=rc)
+ call med_io_define_time(avgfile%io_file, time_units, calendar, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
else
- call med_io_enddef(hist_file)
- call med_io_write_time(time_val, time_bnds, nt=1, rc=rc)
+ call med_io_enddef(avgfile%io_file)
+ call med_io_write_time(avgfile%io_file, time_val, time_bnds, nt=1, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
@@ -972,7 +983,7 @@ subroutine med_phases_history_write_comp_avg(gcomp, compid, avgfile, rc)
nx = is_local%wrap%nx(compid)
ny = is_local%wrap%ny(compid)
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBimp(compid,compid),rc=rc)) then
- call med_io_write(hist_file, avgfile%FBaccum_import, whead(m), wdata(m), nx, ny, &
+ call med_io_write(avgfile%io_file, avgfile%FBaccum_import, whead(m), wdata(m), nx, ny, &
nt=1, pre=trim(compname(compid))//'Imp', tilesize=hist_tilesize, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (wdata(m)) then
@@ -981,7 +992,7 @@ subroutine med_phases_history_write_comp_avg(gcomp, compid, avgfile, rc)
end if
endif
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBexp(compid),rc=rc)) then
- call med_io_write(hist_file, avgfile%FBaccum_export, whead(m), wdata(m), nx, ny, &
+ call med_io_write(avgfile%io_file, avgfile%FBaccum_export, whead(m), wdata(m), nx, ny, &
nt=1, pre=trim(compname(compid))//'Exp', tilesize=hist_tilesize, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (wdata(m)) then
@@ -993,7 +1004,7 @@ subroutine med_phases_history_write_comp_avg(gcomp, compid, avgfile, rc)
end do ! end of loop over m
! Close file
- call med_io_close(hist_file, vm, rc=rc)
+ call med_io_close(avgfile%io_file, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if ! end of write_now if-block
@@ -1276,39 +1287,40 @@ subroutine med_phases_history_write_comp_aux(gcomp, compid, auxcomp, rc)
! open file
call ESMF_GridCompGet(gcomp, vm=vm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_wopen(auxcomp%files(nf)%histfile, vm, file_ind=nf, clobber=.true.)
+ call med_io_wopen(auxcomp%files(nf)%histfile, auxcomp%files(nf)%io_file, vm, rc, file_ind=nf, clobber=.true.)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
! define time variables
call ESMF_ClockGet(auxcomp%files(nf)%clock, calendar=calendar, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_define_time(time_units, calendar, file_ind=nf, rc=rc)
+ call med_io_define_time(auxcomp%files(nf)%io_file, time_units, calendar, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
! define data variables with a time dimension (include the nt argument below)
- call med_io_write(auxcomp%files(nf)%histfile, is_local%wrap%FBimp(compid,compid), &
+ call med_io_write(auxcomp%files(nf)%io_file, is_local%wrap%FBimp(compid,compid), &
whead(1), wdata(1), nx, ny, nt=auxcomp%files(nf)%nt, &
pre=trim(compname(compid))//'Imp', flds=auxcomp%files(nf)%flds, &
- file_ind=nf, use_float=.true., rc=rc)
+ use_float=.true., rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
! end definition phase
- call med_io_enddef(auxcomp%files(nf)%histfile, file_ind=nf)
+ call med_io_enddef(auxcomp%files(nf)%io_file)
end if
! Write time variables for time nt
- call med_io_write_time(time_val, time_bnds, nt=auxcomp%files(nf)%nt, file_ind=nf, rc=rc)
+ call med_io_write_time(auxcomp%files(nf)%io_file, time_val, time_bnds, nt=auxcomp%files(nf)%nt, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
! Write data variables for time nt
if (auxcomp%files(nf)%doavg) then
- call med_io_write(auxcomp%files(nf)%histfile, auxcomp%files(nf)%FBaccum, whead(2), wdata(2), nx, ny, &
- nt=auxcomp%files(nf)%nt, pre=trim(compname(compid))//'Imp', flds=auxcomp%files(nf)%flds, file_ind=nf, rc=rc)
+ call med_io_write(auxcomp%files(nf)%io_file, auxcomp%files(nf)%FBaccum, whead(2), wdata(2), nx, ny, &
+ nt=auxcomp%files(nf)%nt, pre=trim(compname(compid))//'Imp', flds=auxcomp%files(nf)%flds, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call med_methods_FB_reset(auxcomp%files(nf)%FBaccum, value=czero, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
else
- call med_io_write(auxcomp%files(nf)%histfile, is_local%wrap%FBimp(compid,compid), whead(2), wdata(2), nx, ny, &
- nt=auxcomp%files(nf)%nt, pre=trim(compname(compid))//'Imp', flds=auxcomp%files(nf)%flds, file_ind=nf, rc=rc)
+ call med_io_write(auxcomp%files(nf)%io_file, is_local%wrap%FBimp(compid,compid), whead(2), wdata(2), nx, ny, &
+ nt=auxcomp%files(nf)%nt, pre=trim(compname(compid))//'Imp', flds=auxcomp%files(nf)%flds, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
@@ -1316,7 +1328,7 @@ subroutine med_phases_history_write_comp_aux(gcomp, compid, auxcomp, rc)
if (auxcomp%files(nf)%nt == auxcomp%files(nf)%ntperfile) then
call ESMF_GridCompGet(gcomp, vm=vm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_close(auxcomp%files(nf)%histfile, vm, file_ind=nf, rc=rc)
+ call med_io_close(auxcomp%files(nf)%io_file, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
auxcomp%files(nf)%nt = 0
end if
diff --git a/mediator/med_phases_prep_atm_mod.F90 b/mediator/med_phases_prep_atm_mod.F90
index 9bb2b059f..98728a8a6 100644
--- a/mediator/med_phases_prep_atm_mod.F90
+++ b/mediator/med_phases_prep_atm_mod.F90
@@ -14,9 +14,10 @@ module med_phases_prep_atm_mod
use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose
use med_methods_mod , only : FB_fldchk => med_methods_FB_FldChk
use med_methods_mod , only : FB_getfldptr=> med_methods_FB_GetFldPtr
+ use med_methods_mod , only : FB_check_for_nans => med_methods_FB_check_for_nans
use med_merge_mod , only : med_merge_auto
use med_map_mod , only : med_map_field_packed
- use med_internalstate_mod , only : InternalState, maintask
+ use med_internalstate_mod , only : InternalState, maintask, logunit
use med_internalstate_mod , only : compatm, compocn, compice, compname, coupling_mode
use esmFlds , only : med_fldlist_GetfldListTo, med_fldlist_type
use perf_mod , only : t_startf, t_stopf
@@ -243,6 +244,10 @@ subroutine med_phases_prep_atm(gcomp, rc)
end do
end if
+ ! Check for nans in fields export to atm
+ call FB_check_for_nans(is_local%wrap%FBExp(compatm), maintask, logunit, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+
if (dbug_flag > 5) then
call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO)
end if
diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90
index 311d91c8a..920fb415e 100644
--- a/mediator/med_phases_prep_glc_mod.F90
+++ b/mediator/med_phases_prep_glc_mod.F90
@@ -34,6 +34,7 @@ module med_phases_prep_glc_mod
use med_methods_mod , only : fldbun_diagnose => med_methods_FB_diagnose
use med_methods_mod , only : fldbun_reset => med_methods_FB_reset
use med_methods_mod , only : fldbun_init => med_methods_FB_init
+ use med_methods_mod , only : FB_check_for_nans => med_methods_FB_check_for_nans
use med_methods_mod , only : field_getdata2d => med_methods_Field_getdata2d
use med_methods_mod , only : field_getdata1d => med_methods_Field_getdata1d
use med_utils_mod , only : chkerr => med_utils_ChkErr
@@ -706,6 +707,12 @@ subroutine med_phases_prep_glc_avg(gcomp, rc)
endif
end if
+ ! Check for nans in fields export to glc
+ do ns = 1,is_local%wrap%num_icesheets
+ call FB_check_for_nans(is_local%wrap%FBExp(compglc(ns)), maintask, logunit, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ end do
+
if (dbug_flag > 5) then
call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO)
endif
diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90
index 428f3afef..524313622 100644
--- a/mediator/med_phases_prep_ice_mod.F90
+++ b/mediator/med_phases_prep_ice_mod.F90
@@ -34,6 +34,7 @@ subroutine med_phases_prep_ice(gcomp, rc)
use med_methods_mod , only : FB_fldchk => med_methods_FB_FldChk
use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose
use med_methods_mod , only : FB_GetFldPtr => med_methods_FB_GetFldPtr
+ use med_methods_mod , only : FB_check_for_nans => med_methods_FB_check_for_nans
use med_constants_mod , only : dbug_flag => med_constants_dbug_flag
use med_merge_mod , only : med_merge_auto
use med_internalstate_mod , only : InternalState, logunit, maintask
@@ -149,6 +150,10 @@ subroutine med_phases_prep_ice(gcomp, rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
end if
+ ! Check for nans in fields export to ice
+ call FB_check_for_nans(is_local%wrap%FBExp(compice), maintask, logunit, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+
if (dbug_flag > 5) then
call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO)
endif
diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90
index 0c0bad212..4be8bb402 100644
--- a/mediator/med_phases_prep_lnd_mod.F90
+++ b/mediator/med_phases_prep_lnd_mod.F90
@@ -29,10 +29,11 @@ subroutine med_phases_prep_lnd(gcomp, rc)
use ESMF , only : ESMF_StateGet, ESMF_StateItem_Flag, ESMF_STATEITEM_NOTFOUND
use esmFlds , only : med_fldList_GetFldListTo, med_fldList_type
use med_methods_mod , only : fldbun_diagnose => med_methods_FB_diagnose
+ use med_methods_mod , only : FB_check_for_nans => med_methods_FB_check_for_nans
use med_utils_mod , only : chkerr => med_utils_ChkErr
use med_constants_mod , only : dbug_flag => med_constants_dbug_flag
use med_internalstate_mod , only : complnd, compatm
- use med_internalstate_mod , only : InternalState, maintask
+ use med_internalstate_mod , only : InternalState, maintask, logunit
use med_merge_mod , only : med_merge_auto
use perf_mod , only : t_startf, t_stopf
@@ -127,6 +128,10 @@ subroutine med_phases_prep_lnd(gcomp, rc)
! Set first call logical to false
first_call = .false.
+ ! Check for nans in fields export to lnd
+ call FB_check_for_nans(is_local%wrap%FBExp(complnd), maintask, logunit, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+
if (dbug_flag > 5) then
call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO)
end if
diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90
index 58c9ebc8b..373d92469 100644
--- a/mediator/med_phases_prep_ocn_mod.F90
+++ b/mediator/med_phases_prep_ocn_mod.F90
@@ -19,6 +19,7 @@ module med_phases_prep_ocn_mod
use med_methods_mod , only : FB_average => med_methods_FB_average
use med_methods_mod , only : FB_copy => med_methods_FB_copy
use med_methods_mod , only : FB_reset => med_methods_FB_reset
+ use med_methods_mod , only : FB_check_for_nans => med_methods_FB_check_for_nans
use esmFlds , only : med_fldList_GetfldListTo, med_fldlist_type
use med_internalstate_mod , only : compocn, compatm, compice, coupling_mode
use perf_mod , only : t_startf, t_stopf
@@ -295,6 +296,10 @@ subroutine med_phases_prep_ocn_avg(gcomp, rc)
call FB_copy(is_local%wrap%FBExp(compocn), is_local%wrap%FBExpAccumOcn, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ ! Check for nans in fields export to ocn
+ call FB_check_for_nans(is_local%wrap%FBExp(compocn), maintask, logunit, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+
! zero accumulator
is_local%wrap%ExpAccumOcnCnt = 0
call FB_reset(is_local%wrap%FBExpAccumOcn, value=czero, rc=rc)
@@ -372,7 +377,6 @@ subroutine med_phases_prep_ocn_custom_cesm(gcomp, rc)
rc = ESMF_SUCCESS
- call t_startf('MED:'//subname)
if (dbug_flag > 20) then
call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO)
end if
@@ -383,6 +387,17 @@ subroutine med_phases_prep_ocn_custom_cesm(gcomp, rc)
call ESMF_GridCompGetInternalState(gcomp, is_local, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ ! Check that the necessary export field is present
+ if ( .not. FB_fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet', rc=rc) .and. &
+ .not. (FB_fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdr', rc=rc) .and. &
+ FB_fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdf', rc=rc) .and. &
+ FB_fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idr', rc=rc) .and. &
+ FB_fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idf', rc=rc))) then
+ return
+ end if
+
+ call t_startf('MED:'//subname)
+
!---------------------------------------
! Compute netsw for ocean
!---------------------------------------
diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90
index 5d603a141..55b2dae82 100644
--- a/mediator/med_phases_prep_rof_mod.F90
+++ b/mediator/med_phases_prep_rof_mod.F90
@@ -23,6 +23,7 @@ module med_phases_prep_rof_mod
use med_methods_mod , only : fldbun_reset => med_methods_FB_reset
use med_methods_mod , only : fldbun_average => med_methods_FB_average
use med_methods_mod , only : field_getdata1d => med_methods_Field_getdata1d
+ use med_methods_mod , only : FB_check_for_nans => med_methods_FB_check_for_nans
use perf_mod , only : t_startf, t_stopf
implicit none
@@ -376,6 +377,10 @@ subroutine med_phases_prep_rof(gcomp, rc)
FBfrac=is_local%wrap%FBFrac(comprof), FBin=FBlndAccum2rof_r, fldListTo=fldList, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
+ ! Check for nans in fields export to rof
+ call FB_check_for_nans(is_local%wrap%FBExp(comprof), maintask, logunit, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+
if (dbug_flag > 1) then
call fldbun_diagnose(is_local%wrap%FBExp(comprof), &
string=trim(subname)//' FBexp(comprof) ', rc=rc)
diff --git a/mediator/med_phases_prep_wav_mod.F90 b/mediator/med_phases_prep_wav_mod.F90
index 5fcb9ba7e..c690aa522 100644
--- a/mediator/med_phases_prep_wav_mod.F90
+++ b/mediator/med_phases_prep_wav_mod.F90
@@ -17,6 +17,7 @@ module med_phases_prep_wav_mod
use med_methods_mod , only : FB_average => med_methods_FB_average
use med_methods_mod , only : FB_copy => med_methods_FB_copy
use med_methods_mod , only : FB_reset => med_methods_FB_reset
+ use med_methods_mod , only : FB_check_for_nans => med_methods_FB_check_for_nans
use esmFlds , only : med_fldList_GetfldListTo
use med_internalstate_mod , only : compwav
use perf_mod , only : t_startf, t_stopf
@@ -176,6 +177,10 @@ subroutine med_phases_prep_wav_avg(gcomp, rc)
call FB_copy(is_local%wrap%FBExp(compwav), is_local%wrap%FBExpAccumWav, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ ! Check for nans in fields export to wav
+ call FB_check_for_nans(is_local%wrap%FBExp(compwav), maintask, logunit, rc=rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+
! zero accumulator
is_local%wrap%ExpAccumWavCnt = 0
call FB_reset(is_local%wrap%FBExpAccumWav, value=czero, rc=rc)
diff --git a/mediator/med_phases_restart_mod.F90 b/mediator/med_phases_restart_mod.F90
index 6bf5f3466..a225ff97c 100644
--- a/mediator/med_phases_restart_mod.F90
+++ b/mediator/med_phases_restart_mod.F90
@@ -13,7 +13,7 @@ module med_phases_restart_mod
use med_phases_prep_glc_mod , only : FBlndAccum2glc_l, lndAccum2glc_cnt
use med_phases_prep_glc_mod , only : FBocnAccum2glc_o, ocnAccum2glc_cnt
use med_phases_prep_rof_mod , only : FBlndAccum2rof_l, lndAccum2rof_cnt
-
+ use pio , only : file_desc_t
implicit none
private
@@ -143,6 +143,7 @@ subroutine med_phases_restart_write(gcomp, rc)
integer, intent(out) :: rc
! local variables
+ type(file_desc_t) :: io_file
type(ESMF_VM) :: vm
type(ESMF_Clock) :: clock
type(ESMF_Time) :: starttime
@@ -309,11 +310,12 @@ subroutine med_phases_restart_write(gcomp, rc)
call ESMF_LogWrite(trim(subname)//": write "//trim(restart_file), ESMF_LOGMSG_INFO)
call ESMF_GridCompGet(gcomp, vm=vm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_wopen(restart_file, vm, clobber=.true.)
+ call med_io_wopen(restart_file, io_file, vm, rc, clobber=.true.)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
do m = 1,2
if (m == 2) then
- call med_io_enddef(restart_file)
+ call med_io_enddef(io_file)
end if
tbnds = days_since
@@ -321,23 +323,23 @@ subroutine med_phases_restart_write(gcomp, rc)
if (whead(m)) then
call ESMF_ClockGet(clock, calendar=calendar, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_define_time(time_units, calendar, rc=rc)
+ call med_io_define_time(io_file, time_units, calendar, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
else
- call med_io_write_time(days_since, tbnds=(/days_since,days_since/), nt=1, rc=rc)
+ call med_io_write_time(io_file, days_since, tbnds=(/days_since,days_since/), nt=1, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
! Write out next ymd/tod in place of curr ymd/tod because the
! restart represents the time at end of the current timestep
! and that is where we want to start the next run.
- call med_io_write(restart_file, start_ymd, 'start_ymd', whead(m), wdata(m), rc=rc)
+ call med_io_write(io_file, start_ymd, 'start_ymd', whead(m), wdata(m), rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_write(restart_file, start_tod, 'start_tod', whead(m), wdata(m), rc=rc)
+ call med_io_write(io_file, start_tod, 'start_tod', whead(m), wdata(m), rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_write(restart_file, next_ymd , 'curr_ymd' , whead(m), wdata(m), rc=rc)
+ call med_io_write(io_file, next_ymd , 'curr_ymd' , whead(m), wdata(m), rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_write(restart_file, next_tod , 'curr_tod' , whead(m), wdata(m), rc=rc)
+ call med_io_write(io_file, next_tod , 'curr_tod' , whead(m), wdata(m), rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
do n = 1,ncomps
@@ -346,19 +348,19 @@ subroutine med_phases_restart_write(gcomp, rc)
ny = is_local%wrap%ny(n)
! Write import field bundles
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBimp(n,n),rc=rc)) then
- call med_io_write(restart_file, is_local%wrap%FBimp(n,n), whead(m), wdata(m), nx, ny, &
+ call med_io_write(io_file, is_local%wrap%FBimp(n,n), whead(m), wdata(m), nx, ny, &
nt=1, pre=trim(compname(n))//'Imp', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
endif
! Write export field bundles
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBexp(n),rc=rc)) then
- call med_io_write(restart_file, is_local%wrap%FBexp(n), whead(m), wdata(m), nx, ny, &
+ call med_io_write(io_file, is_local%wrap%FBexp(n), whead(m), wdata(m), nx, ny, &
nt=1, pre=trim(compname(n))//'Exp', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
endif
! Write fraction field bundles
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBfrac(n),rc=rc)) then
- call med_io_write(restart_file, is_local%wrap%FBfrac(n), whead(m), wdata(m), nx, ny, &
+ call med_io_write(io_file, is_local%wrap%FBfrac(n), whead(m), wdata(m), nx, ny, &
nt=1, pre=trim(compname(n))//'Frac', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
endif
@@ -369,10 +371,10 @@ subroutine med_phases_restart_write(gcomp, rc)
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBExpAccumOcn)) then
nx = is_local%wrap%nx(compocn)
ny = is_local%wrap%ny(compocn)
- call med_io_write(restart_file, is_local%wrap%FBExpAccumOcn, whead(m), wdata(m), nx, ny, &
+ call med_io_write(io_file, is_local%wrap%FBExpAccumOcn, whead(m), wdata(m), nx, ny, &
nt=1, pre='ocnExpAccum', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_write(restart_file, is_local%wrap%ExpAccumOcnCnt, 'ocnExpAccum_cnt', whead(m), wdata(m), rc=rc)
+ call med_io_write(io_file, is_local%wrap%ExpAccumOcnCnt, 'ocnExpAccum_cnt', whead(m), wdata(m), rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
endif
@@ -380,10 +382,10 @@ subroutine med_phases_restart_write(gcomp, rc)
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBExpAccumWav)) then
nx = is_local%wrap%nx(compwav)
ny = is_local%wrap%ny(compwav)
- call med_io_write(restart_file, is_local%wrap%FBExpAccumWav, whead(m), wdata(m), nx, ny, &
+ call med_io_write(io_file, is_local%wrap%FBExpAccumWav, whead(m), wdata(m), nx, ny, &
nt=1, pre='wavExpAccum', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_write(restart_file, is_local%wrap%ExpAccumWavCnt, 'wavExpAccum_cnt', whead(m), wdata(m), rc=rc)
+ call med_io_write(io_file, is_local%wrap%ExpAccumWavCnt, 'wavExpAccum_cnt', whead(m), wdata(m), rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
endif
@@ -391,10 +393,10 @@ subroutine med_phases_restart_write(gcomp, rc)
if (ESMF_FieldBundleIsCreated(FBlndAccum2rof_l)) then
nx = is_local%wrap%nx(complnd)
ny = is_local%wrap%ny(complnd)
- call med_io_write(restart_file, FBlndAccum2rof_l, whead(m), wdata(m), nx, ny, &
+ call med_io_write(io_file, FBlndAccum2rof_l, whead(m), wdata(m), nx, ny, &
nt=1, pre='lndImpAccum2rof', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_write(restart_file, lndAccum2rof_cnt, 'lndImpAccum2rof_cnt', whead(m), wdata(m), rc=rc)
+ call med_io_write(io_file, lndAccum2rof_cnt, 'lndImpAccum2rof_cnt', whead(m), wdata(m), rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
@@ -402,10 +404,10 @@ subroutine med_phases_restart_write(gcomp, rc)
if (ESMF_FieldBundleIsCreated(FBlndAccum2glc_l)) then
nx = is_local%wrap%nx(complnd)
ny = is_local%wrap%ny(complnd)
- call med_io_write(restart_file, FBlndAccum2glc_l, whead(m), wdata(m), nx, ny, &
+ call med_io_write(io_file, FBlndAccum2glc_l, whead(m), wdata(m), nx, ny, &
nt=1, pre='lndImpAccum2glc', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_write(restart_file, lndAccum2glc_cnt, 'lndImpAccum2glc_cnt', whead(m), wdata(m), rc=rc)
+ call med_io_write(io_file, lndAccum2glc_cnt, 'lndImpAccum2glc_cnt', whead(m), wdata(m), rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
@@ -413,10 +415,10 @@ subroutine med_phases_restart_write(gcomp, rc)
if (ESMF_FieldBundleIsCreated(FBocnAccum2glc_o)) then
nx = is_local%wrap%nx(compocn)
ny = is_local%wrap%ny(compocn)
- call med_io_write(restart_file, FBocnAccum2glc_o, whead(m), wdata(m), nx, ny, &
+ call med_io_write(io_file, FBocnAccum2glc_o, whead(m), wdata(m), nx, ny, &
nt=1, pre='ocnImpAccum2glc_o', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_write(restart_file, ocnAccum2glc_cnt, 'ocnImpAccum2glc_cnt', whead(m), wdata(m), rc=rc)
+ call med_io_write(io_file, ocnAccum2glc_cnt, 'ocnImpAccum2glc_cnt', whead(m), wdata(m), rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
@@ -424,7 +426,7 @@ subroutine med_phases_restart_write(gcomp, rc)
if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_ocnalb_o,rc=rc)) then
nx = is_local%wrap%nx(compocn)
ny = is_local%wrap%ny(compocn)
- call med_io_write(restart_file, is_local%wrap%FBMed_ocnalb_o, whead(m), wdata(m), nx, ny, &
+ call med_io_write(io_file, is_local%wrap%FBMed_ocnalb_o, whead(m), wdata(m), nx, ny, &
nt=1, pre='MedOcnAlb_o', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
@@ -437,11 +439,11 @@ subroutine med_phases_restart_write(gcomp, rc)
if (auxcomp(nc)%files(nf)%doavg .and. auxcomp(nc)%files(nf)%accumcnt > 0) then
nx = is_local%wrap%nx(nc)
ny = is_local%wrap%ny(nc)
- call med_io_write(restart_file, auxcomp(nc)%files(nf)%FBaccum, &
+ call med_io_write(io_file, auxcomp(nc)%files(nf)%FBaccum, &
whead(m), wdata(m), nx, ny, &
nt=1, pre=trim(compname(nc))//trim(auxcomp(nc)%files(nf)%auxname), rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_io_write(restart_file, auxcomp(nc)%files(nf)%accumcnt, &
+ call med_io_write(io_file, auxcomp(nc)%files(nf)%accumcnt, &
trim(compname(nc))//trim(auxcomp(nc)%files(nf)%auxname)//'_accumcnt', &
whead(m), wdata(m), rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
@@ -452,7 +454,7 @@ subroutine med_phases_restart_write(gcomp, rc)
enddo ! end of whead/wdata loop
! Close file
- call med_io_close(restart_file, vm, rc=rc)
+ call med_io_close(io_file, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
endif