diff --git a/atmos_model.F90 b/atmos_model.F90 index 04ecae56b..0a3872631 100644 --- a/atmos_model.F90 +++ b/atmos_model.F90 @@ -2620,6 +2620,20 @@ subroutine setup_exportdata (rc) enddo enddo endif + + ! oceanfrac used by atm to calculate fluxes + idx = queryfieldlist(exportFieldsList,'openwater_frac_in_atm') + if (idx > 0 ) then +!$omp parallel do default(shared) private(i,j,nb,ix) + do j=jsc,jec + do i=isc,iec + nb = Atm_block%blkno(i,j) + ix = Atm_block%ixp(i,j) + exportData(i,j,idx) = (one - GFS_Data(nb)%Sfcprop%fice(ix))*GFS_Data(nb)%Sfcprop%oceanfrac(ix) + enddo + enddo + endif + endif !cplflx !--- diff --git a/cpl/module_cap_cpl.F90 b/cpl/module_cap_cpl.F90 index f5427c791..128e72716 100644 --- a/cpl/module_cap_cpl.F90 +++ b/cpl/module_cap_cpl.F90 @@ -139,50 +139,45 @@ subroutine realizeConnectedCplFields(state, grid, isConnected = NUOPC_IsConnected(state, fieldName=trim(fieldNames(item)), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return if (isConnected) then + call ESMF_StateGet(state, field=field, itemName=trim(fieldNames(item)), rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return + call ESMF_FieldEmptySet(field, grid=grid, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return select case (fieldTypes(item)) case ('l','layer') - field = ESMF_FieldCreate(grid, typekind=ESMF_TYPEKIND_R8, & - name=trim(fieldNames(item)), & + call ESMF_FieldEmptyComplete(field, typekind=ESMF_TYPEKIND_R8, & ungriddedLBound=(/1/), ungriddedUBound=(/numLevels/), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return case ('i','interface') - field = ESMF_FieldCreate(grid, typekind=ESMF_TYPEKIND_R8, & - name=trim(fieldNames(item)), & + call ESMF_FieldEmptyComplete(field, typekind=ESMF_TYPEKIND_R8, & ungriddedLBound=(/1/), ungriddedUBound=(/numLevels+1/), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return case ('t','tracer') - field = ESMF_FieldCreate(grid, typekind=ESMF_TYPEKIND_R8, & - name=trim(fieldNames(item)), & + call ESMF_FieldEmptyComplete(field, typekind=ESMF_TYPEKIND_R8, & ungriddedLBound=(/1, 1/), ungriddedUBound=(/numLevels, numTracers/), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return case ('u','tracer_up_flux') - field = ESMF_FieldCreate(grid, typekind=ESMF_TYPEKIND_R8, & - name=trim(fieldNames(item)), & + call ESMF_FieldEmptyComplete(field, typekind=ESMF_TYPEKIND_R8, & ungriddedLBound=(/1/), ungriddedUBound=(/num_diag_sfc_emis_flux/), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return case ('d','tracer_down_flx') - field = ESMF_FieldCreate(grid, typekind=ESMF_TYPEKIND_R8, & - name=trim(fieldNames(item)), & + call ESMF_FieldEmptyComplete(field, typekind=ESMF_TYPEKIND_R8, & ungriddedLBound=(/1, 1/), & ungriddedUBound=(/num_diag_down_flux, num_diag_type_down_flux/), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return case ('b','tracer_anth_biom_emission') - field = ESMF_FieldCreate(grid, typekind=ESMF_TYPEKIND_R8, & - name=trim(fieldNames(item)), & + call ESMF_FieldEmptyComplete(field, typekind=ESMF_TYPEKIND_R8, & ungriddedLBound=(/1/), ungriddedUBound=(/num_diag_burn_emis_flux/), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return case ('c','tracer_column_mass_density') - field = ESMF_FieldCreate(grid, typekind=ESMF_TYPEKIND_R8, & - name=trim(fieldNames(item)), & + call ESMF_FieldEmptyComplete(field, typekind=ESMF_TYPEKIND_R8, & ungriddedLBound=(/1/), ungriddedUBound=(/num_diag_cmass/), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return case ('s','surface') - field = ESMF_FieldCreate(grid, typekind=ESMF_TYPEKIND_R8, & - name=trim(fieldNames(item)), rc=rc) + call ESMF_FieldEmptyComplete(field, typekind=ESMF_TYPEKIND_R8, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return case ('g','soil') - field = ESMF_FieldCreate(grid, typekind=ESMF_TYPEKIND_R8, & - name=trim(fieldNames(item)), & + call ESMF_FieldEmptyComplete(field, typekind=ESMF_TYPEKIND_R8, & ungriddedLBound=(/1/), ungriddedUBound=(/numSoilLayers/), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return case default @@ -194,7 +189,7 @@ subroutine realizeConnectedCplFields(state, grid, call NUOPC_Realize(state, field=field, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return - ! -- zero out field + ! -- zero out field call ESMF_FieldFill(field, dataFillScheme="const", const1=0._ESMF_KIND_R8, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return @@ -216,16 +211,17 @@ end subroutine realizeConnectedCplFields !----------------------------------------------------------------------------- subroutine diagnose_cplFields(gcomp, importState, exportstate, clock_fv3, & - statewrite_flag, stdiagnose_flag, state_tag, timestr) + fcstpe, statewrite_flag, stdiagnose_flag, state_tag, timestr) type(ESMF_GridComp), intent(in) :: gcomp type(ESMF_State) :: importState, exportstate type(ESMF_Clock),intent(in) :: clock_fv3 + logical, intent(in) :: fcstpe logical, intent(in) :: statewrite_flag integer, intent(in) :: stdiagnose_flag character(len=*), intent(in) :: state_tag !< Import or export. character(len=*), intent(in) :: timestr !< Import or export. - integer :: timeslice = 1 + integer :: timeslice = 1 ! character(len=160) :: nuopcMsg character(len=160) :: filename @@ -244,11 +240,11 @@ subroutine diagnose_cplFields(gcomp, importState, exportstate, clock_fv3, & unit=nuopcMsg) ! call ESMF_LogWrite(nuopcMsg, ESMF_LOGMSG_INFO) - if(trim(state_tag) .eq. 'import')then + if(trim(state_tag) .eq. 'import')then call ESMF_GridCompGet(gcomp, importState=importState, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return - if(stdiagnose_flag > 0)then + if(stdiagnose_flag > 0 .and. fcstpe)then call state_diagnose(importState, ':IS', rc=rc) end if @@ -264,7 +260,7 @@ subroutine diagnose_cplFields(gcomp, importState, exportstate, clock_fv3, & call ESMF_GridCompGet(gcomp, exportState=exportState, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return - if(stdiagnose_flag > 0)then + if(stdiagnose_flag > 0 .and. fcstpe)then call state_diagnose(exportState, ':ES', rc=rc) end if diff --git a/cpl/module_cplfields.F90 b/cpl/module_cplfields.F90 index 3690731ea..cb941bf0b 100644 --- a/cpl/module_cplfields.F90 +++ b/cpl/module_cplfields.F90 @@ -13,7 +13,7 @@ module module_cplfields private ! Export Fields ---------------------------------------- - integer, public, parameter :: NexportFields = 71 + integer, public, parameter :: NexportFields = 72 type(ESMF_Field), target, public :: exportFields(NexportFields) character(len=*), public, parameter :: exportFieldsList(NexportFields) = (/ & "inst_pres_interface ", & @@ -86,7 +86,8 @@ module module_cplfields "inst_merid_wind_height_lowest ", & "inst_pres_height_lowest ", & "inst_height_lowest ", & - "mean_fprec_rate " & + "mean_fprec_rate ", & + "openwater_frac_in_atm " & ! "northward_wind_neutral ", & ! "eastward_wind_neutral ", & ! "upward_wind_neutral ", & @@ -112,7 +113,7 @@ module module_cplfields "s","s","s","s","s","s","s","s", & "s","s","s","s","s","s","s","s", & "s","s","s","s","s","s","s","s", & - "s","s","s","s","s" & + "s","s","s","s","s","s" & ! "l","l","l","l","l","l","l","s", & /) ! Set exportFieldShare to .true. if field is provided as memory reference @@ -132,7 +133,7 @@ module module_cplfields .false.,.false.,.false.,.false.,.false., & .false.,.false.,.false.,.true. ,.false., & .false.,.false.,.false.,.false.,.false., & - .false. & + .false.,.false. & ! .false.,.false.,.false.,.false.,.false., & ! .false.,.false.,.false. & /) @@ -212,7 +213,7 @@ subroutine fillExportFields(data_a2oi, rc) isCreated = ESMF_FieldIsCreated(exportFields(n), rc=localrc) if (ESMF_LogFoundError(rcToCheck=localrc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__, rcToReturn=rc)) return if (isCreated) then -! set data +! set data call ESMF_FieldGet(exportFields(n), name=fieldname, dimCount=dimCount, typekind=datatype, rc=localrc) if (ESMF_LogFoundError(rcToCheck=localrc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__, rcToReturn=rc)) return !print *,'in fillExportFields, field created n=',n,size(exportFields),'name=', trim(fieldname) diff --git a/fv3_cap.F90 b/fv3_cap.F90 index 29b7c361a..185f5cfea 100644 --- a/fv3_cap.F90 +++ b/fv3_cap.F90 @@ -30,7 +30,7 @@ module fv3gfs_cap_mod calendar, calendar_type, cpl, & force_date_from_configure, & cplprint_flag,output_1st_tstep_rst, & - first_kdt,num_restart_interval + first_kdt,num_restart_interval use module_fv3_io_def, only: num_pes_fcst,write_groups,app_domain, & num_files, filename_base, & @@ -63,7 +63,7 @@ module fv3gfs_cap_mod queryFieldList, fillExportFields, & exportData use module_cap_cpl, only: realizeConnectedCplFields, & - clock_cplIntval, diagnose_cplFields + clock_cplIntval, diagnose_cplFields implicit none @@ -235,7 +235,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) ! ! local variables - type(ESMF_VM) :: vm + type(ESMF_VM) :: vm, fcstVM type(ESMF_Time) :: CurrTime, starttime, StopTime type(ESMF_Time) :: alarm_output_hf_ring, alarm_output_ring type(ESMF_Time) :: alarm_output_hf_stop, alarm_output_stop @@ -250,7 +250,6 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) integer :: i, j, k, io_unit, urc, ierr integer :: petcount, mype integer :: num_output_file - logical :: isPetLocal logical :: OPENED character(ESMF_MAXSTR) :: name logical :: fcstpe @@ -589,6 +588,9 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return if (ESMF_LogFoundError(rcToCheck=urc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__, rcToReturn=rc)) return +! obtain fcst VM + call ESMF_GridCompGet(fcstComp, vm=fcstVM, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! create fcst state fcstState = ESMF_StateCreate(rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return @@ -601,7 +603,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (ESMF_LogFoundError(rcToCheck=urc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__, rcToReturn=rc)) return ! ! reconcile the fcstComp's import state - call ESMF_StateReconcile(fcstState, attreconflag= ESMF_ATTRECONCILE_ON, rc=rc) + call ESMF_StateReconcile(fcstState, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! ! determine number elements in fcstState @@ -649,7 +651,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) allocate(petList(wrttasks_per_group)) if(mype == 0) print *,'af allco wrtComp,write_groups=',write_groups -! set up ESMF time interval at center of iau window +! set up ESMF time interval at center of iau window call ESMF_TimeIntervalSet(IAU_offsetTI, h=iau_offset, rc=rc) ! allocate(originPetList(num_pes_fcst+wrttasks_per_group)) @@ -813,7 +815,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) call ESMF_TimeIntervalSet(output_interval_hf, h=nfhout_hf, m=nfmout_hf, & s=nfsout_hf, rc=rc) call ESMF_TimeIntervalSet(output_hfmax, h=nfhmax_hf, m=0, s=0, rc=rc) - alarm_output_hf_stop = starttime + output_hfmax + output_interval_hf + alarm_output_hf_stop = starttime + output_hfmax + output_interval_hf if (currtime <= starttime+output_hfmax) then nhf = (currtime-starttime)/output_interval_hf alarm_output_hf_ring = startTime + (nhf+1_ESMF_KIND_I4)*output_interval_hf @@ -871,21 +873,16 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if( cpl ) then - isPetLocal = ESMF_GridCompIsPetLocal(fcstComp, rc=rc) - if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return - - if (isPetLocal) then - ! importable fields: do i = 1, size(ImportFieldsList) if (importFieldShare(i)) then call NUOPC_Advertise(importState, & StandardName=trim(ImportFieldsList(i)), & - SharePolicyField="share", rc=rc) + SharePolicyField="share", vm=fcstVM, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return else call NUOPC_Advertise(importState, & - StandardName=trim(ImportFieldsList(i)), rc=rc) + StandardName=trim(ImportFieldsList(i)), vm=fcstVM, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return end if end do @@ -895,16 +892,15 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (exportFieldShare(i)) then call NUOPC_Advertise(exportState, & StandardName=trim(exportFieldsList(i)), & - SharePolicyField="share", rc=rc) + SharePolicyField="share", vm=fcstVM, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return else call NUOPC_Advertise(exportState, & - StandardName=trim(exportFieldsList(i)), rc=rc) + StandardName=trim(exportFieldsList(i)), vm=fcstVM, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return end if end do - endif if(mype==0) print *,'in fv3_cap, aft import, export fields in atmos' endif @@ -975,6 +971,7 @@ subroutine ModelAdvance(gcomp, rc) integer(ESMF_KIND_I8) :: n_interval, time_elapsed_sec ! integer :: na, i, urc + logical :: fcstpe logical :: isAlarmEnabled, isAlarmRinging, lalarm, reconcileFlag character(len=*),parameter :: subname='(fv3_cap:ModelAdvance)' character(240) :: msgString @@ -995,13 +992,16 @@ subroutine ModelAdvance(gcomp, rc) if (profile_memory) call ESMF_VMLogMemInfo("Entering FV3 Model_ADVANCE: ") timeri = mpi_wtime() -! +! call ESMF_GridCompGet(gcomp, name=name, localpet=mype, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return + fcstpe = .false. + if( mype < num_pes_fcst ) fcstpe = .true. + ! Because of the way that the internal Clock was set in SetClock(), ! its timeStep is likely smaller than the parent timeStep. As a consequence - ! the time interval covered by a single parent timeStep will result in + ! the time interval covered by a single parent timeStep will result in ! multiple calls to the ModelAdvance() routine. Every time the currTime ! will come in by one internal timeStep advanced. This goes until the ! stopTime of the internal Clock has been reached. @@ -1086,10 +1086,8 @@ subroutine ModelAdvance(gcomp, rc) if ( cpl ) then ! assign import_data called during phase=1 if( dbug > 0 .or. cplprint_flag ) then - if( mype < num_pes_fcst ) then call diagnose_cplFields(gcomp, importState, exportstate, clock_fv3, & - cplprint_flag, dbug, 'import', import_timestr) - endif + fcstpe, cplprint_flag, dbug, 'import', import_timestr) endif endif @@ -1215,10 +1213,8 @@ subroutine ModelAdvance(gcomp, rc) !jw for coupled, check clock and dump import and export state if ( cpl ) then if( dbug > 0 .or. cplprint_flag ) then - if( mype < num_pes_fcst ) then call diagnose_cplFields(gcomp, importState, exportstate, clock_fv3, & - cplprint_flag, dbug, 'export', export_timestr) - endif + fcstpe, cplprint_flag, dbug, 'export', export_timestr) end if endif @@ -1260,13 +1256,13 @@ subroutine ModelAdvance_phase1(gcomp, rc) rc = ESMF_SUCCESS if(profile_memory) call ESMF_VMLogMemInfo("Entering FV3 Model_ADVANCE phase1: ") -! +! call ESMF_GridCompGet(gcomp, name=name, localpet=mype, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! Expecting to be called by NUOPC run method exactly once for every coupling ! step. - ! Also expecting the coupling step to be identical to the timeStep for + ! Also expecting the coupling step to be identical to the timeStep for ! clock_fv3. call ESMF_ClockPrint(clock_fv3, options="currTime", &