From 7f67a4596e53553bd78eae3361d5dfe43ce7b527 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 18 Jun 2018 20:59:53 -0600 Subject: [PATCH] changes to get mom6 working correctly in nuopc mode and addition of debug output --- config_src/mct_driver/ocn_cap_methods.F90 | 50 ++++- config_src/mct_driver/ocn_comp_mct.F90 | 9 +- config_src/nuopc_driver/mom_cap.F90 | 196 +++++++++++++++----- config_src/nuopc_driver/mom_cap_methods.F90 | 62 +++++-- 4 files changed, 244 insertions(+), 73 deletions(-) diff --git a/config_src/mct_driver/ocn_cap_methods.F90 b/config_src/mct_driver/ocn_cap_methods.F90 index 337607e578..712738bb4d 100644 --- a/config_src/mct_driver/ocn_cap_methods.F90 +++ b/config_src/mct_driver/ocn_cap_methods.F90 @@ -1,9 +1,11 @@ module ocn_cap_methods + use ESMF use MOM_ocean_model, only: ocean_public_type, ocean_state_type use MOM_surface_forcing, only: ice_ocean_boundary_type use MOM_grid, only: ocean_grid_type use MOM_domains, only: pass_var + use MOM_error_handler, only: is_root_pe use mpp_domains_mod, only: mpp_get_compute_domain use ocn_cpl_indices, only: cpl_indices_type @@ -13,22 +15,28 @@ module ocn_cap_methods public :: ocn_import public :: ocn_export - logical, parameter :: debug=.true. + logical, parameter :: debug=.false. !======================================================================= contains !======================================================================= - subroutine ocn_import(x2o, ind, grid, ice_ocean_boundary, c1, c2, c3, c4) - real(kind=8) , intent(in) :: x2o(:,:) !< incoming data - type(cpl_indices_type) , intent(in) :: ind !< Structure with MCT attribute vectors and indices - type(ocean_grid_type) , intent(in) :: grid !< Ocean model grid - type(ice_ocean_boundary_type) , intent(inout) :: ice_ocean_boundary !< Ocean boundary forcing - real(kind=8), optional , intent(in) :: c1, c2, c3, c4 !< Coeffs. used in the shortwave decomposition + subroutine ocn_import(x2o, ind, grid, ice_ocean_boundary, ocean_public, logunit, Eclock, c1, c2, c3, c4) + real(kind=8) , intent(in) :: x2o(:,:) ! incoming data + type(cpl_indices_type) , intent(in) :: ind ! Structure with MCT attribute vects and indices + type(ocean_grid_type) , intent(in) :: grid ! Ocean model grid + type(ice_ocean_boundary_type) , intent(inout) :: ice_ocean_boundary ! Ocean boundary forcing + type(ocean_public_type) , intent(in) :: ocean_public ! Ocean surface state + integer , intent(in) :: logunit ! Unit for stdout output + type(ESMF_Clock) , intent(in) :: EClock ! Time and time step ? \todo Why must this + real(kind=8), optional , intent(in) :: c1, c2, c3, c4 ! Coeffs. used in the shortwave decomposition ! Local variables - integer :: i, j, i1, j1, ig, jg, isc, iec, jsc, jec !< Grid indices - integer :: k !< temporary + integer :: i, j, ig, jg, isc, iec, jsc, jec ! Grid indices + integer :: k + integer :: day, secs, rc + type(ESMF_time) :: currTime + character(*), parameter :: F01 = "('(ocn_import) ',a,4(i6,2x),d21.14)" !----------------------------------------------------------------------- isc = GRID%isc; iec = GRID%iec ; jsc = GRID%jsc; jec = GRID%jec @@ -95,6 +103,30 @@ subroutine ocn_import(x2o, ind, grid, ice_ocean_boundary, c1, c2, c3, c4) end do end do + if (debug .and. is_root_pe()) then + call ESMF_ClockGet(EClock, CurrTime=CurrTime, rc=rc) + call ESMF_TimeGet(CurrTime, d=day, s=secs, rc=rc) + + do j = GRID%jsc, GRID%jec + do i = GRID%isc, GRID%iec + write(logunit,F01)'import: day, secs, j, i, u_flux = ',day,secs,j,i,ice_ocean_boundary%u_flux(i,j) + write(logunit,F01)'import: day, secs, j, i, v_flux = ',day,secs,j,i,ice_ocean_boundary%v_flux(i,j) + write(logunit,F01)'import: day, secs, j, i, lprec = ',day,secs,j,i,ice_ocean_boundary%lprec(i,j) + write(logunit,F01)'import: day, secs, j, i, lwrad = ',day,secs,j,i,ice_ocean_boundary%lw_flux(i,j) + write(logunit,F01)'import: day, secs, j, i, q_flux = ',day,secs,j,i,ice_ocean_boundary%q_flux(i,j) + write(logunit,F01)'import: day, secs, j, i, t_flux = ',day,secs,j,i,ice_ocean_boundary%t_flux(i,j) + write(logunit,F01)'import: day, secs, j, i, latent_flux = ',day,secs,j,i,ice_ocean_boundary%latent_flux(i,j) + write(logunit,F01)'import: day, secs, j, i, runoff = ',day,secs,j,i,ice_ocean_boundary%rofl_flux(i,j) + ice_ocean_boundary%rofi_flux(i,j) + write(logunit,F01)'import: day, secs, j, i, psurf = ',day,secs,j,i,ice_ocean_boundary%p(i,j) + write(logunit,F01)'import: day, secs, j, i, salt_flux = ',day,secs,j,i,ice_ocean_boundary%salt_flux(i,j) + write(logunit,F01)'import: day, secs, j, i, sw_flux_vis_dir = ',day,secs,j,i,ice_ocean_boundary%sw_flux_vis_dir(i,j) + write(logunit,F01)'import: day, secs, j, i, sw_flux_vis_dif = ',day,secs,j,i,ice_ocean_boundary%sw_flux_vis_dif(i,j) + write(logunit,F01)'import: day, secs, j, i, sw_flux_nir_dir = ',day,secs,j,i,ice_ocean_boundary%sw_flux_nir_dir(i,j) + write(logunit,F01)'import: day, secs, j, i, sw_flux_nir_dif = ',day,secs,j,i,ice_ocean_boundary%sw_flux_nir_dir(i,j) + end do + end do + end if + end subroutine ocn_import !======================================================================= diff --git a/config_src/mct_driver/ocn_comp_mct.F90 b/config_src/mct_driver/ocn_comp_mct.F90 index 19fa362db1..6f207e963b 100644 --- a/config_src/mct_driver/ocn_comp_mct.F90 +++ b/config_src/mct_driver/ocn_comp_mct.F90 @@ -311,6 +311,7 @@ subroutine ocn_init_mct( EClock, cdata_o, x2o_o, o2x_o, NLFilename ) glb%grid => glb%ocn_state%grid ! Allocate IOB data type (needs to be called after glb%grid is set) + write(6,*)'DEBUG: isc,iec,jsc,jec= ',glb%grid%isc, glb%grid%iec, glb%grid%jsc, glb%grid%jec call IOB_allocate(ice_ocean_boundary, glb%grid%isc, glb%grid%iec, glb%grid%jsc, glb%grid%jec) call t_stopf('MOM_init') @@ -488,12 +489,14 @@ subroutine ocn_run_mct( EClock, cdata_o, x2o_o, o2x_o) call seq_cdata_setptrs(cdata_o, infodata=glb%infodata) ! Translate import fields to ice_ocean_boundary - ! TODO: make this an input variable + !TODO: make this an input variable glb%sw_decomp = .false. + !END TODO: if (glb%sw_decomp) then - call ocn_import(x2o_o%rattr, glb%ind, glb%grid, Ice_ocean_boundary, c1=glb%c1, c2=glb%c2, c3=glb%c3, c4=glb%c4) + call ocn_import(x2o_o%rattr, glb%ind, glb%grid, Ice_ocean_boundary, glb%ocn_public, glb%stdout, Eclock, & + c1=glb%c1, c2=glb%c2, c3=glb%c3, c4=glb%c4) else - call ocn_import(x2o_o%rattr, glb%ind, glb%grid, Ice_ocean_boundary) + call ocn_import(x2o_o%rattr, glb%ind, glb%grid, Ice_ocean_boundary, glb%ocn_public, glb%stdout, Eclock ) end if ! Update internal ocean diff --git a/config_src/nuopc_driver/mom_cap.F90 b/config_src/nuopc_driver/mom_cap.F90 index b9496b8e4a..62e6a121bf 100644 --- a/config_src/nuopc_driver/mom_cap.F90 +++ b/config_src/nuopc_driver/mom_cap.F90 @@ -400,6 +400,9 @@ module mom_cap_mod use shr_nuopc_methods_mod, only: shr_nuopc_methods_State_SetScalar use shr_nuopc_methods_mod, only: shr_nuopc_methods_State_GetScalar use shr_nuopc_methods_mod, only: shr_nuopc_methods_State_Diagnose + use shr_file_mod, only: shr_file_getUnit, shr_file_freeUnit, shr_file_setIO + use shr_file_mod, only: shr_file_getLogUnit, shr_file_getLogLevel + use shr_file_mod, only: shr_file_setLogUnit, shr_file_setLogLevel #endif use MOM_ocean_model, only: ocean_model_restart, ocean_public_type, ocean_state_type use MOM_ocean_model, only: ocean_model_data_get, ocean_model_init_sfc @@ -456,6 +459,7 @@ module mom_cap_mod type(ESMF_Grid) :: mom_grid_i #ifdef CESMCOUPLED + integer :: logunit ! logging unit number logical :: write_diagnostics = .false. #else logical :: write_diagnostics = .true. @@ -475,6 +479,8 @@ module mom_cap_mod !------------------- Solo Ocean code starts here ----------------------- !----------------------------------------------------------------------- + !=============================================================================== + !> NUOPC SetService method is the only public entry point. !! SetServices registers all of the user-provided subroutines !! in the module with the NUOPC layer. @@ -545,7 +551,7 @@ subroutine SetServices(gcomp, rc) end subroutine SetServices - !----------------------------------------------------------------------------- + !=============================================================================== !> First initialize subroutine called by NUOPC. The purpose !! is to set which version of the Initialize Phase Definition (IPD) @@ -582,7 +588,7 @@ subroutine InitializeP0(gcomp, importState, exportState, clock, rc) line=__LINE__, & file=__FILE__)) & return ! bail out -! write_diagnostics=(trim(value)=="true") + ! write_diagnostics=(trim(value)=="true") call ESMF_LogWrite('MOM_CAP:DumpFields = '//trim(value), ESMF_LOGMSG_INFO, rc=dbrc) call ESMF_AttributeGet(gcomp, name="ProfileMemory", value=value, defaultValue="true", & @@ -637,7 +643,7 @@ subroutine InitializeP0(gcomp, importState, exportState, clock, rc) end subroutine - !----------------------------------------------------------------------------- + !=============================================================================== !> Called by NUOPC to advertise import and export fields. "Advertise" !! simply means that the standard names of all import and export @@ -754,6 +760,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) !tcx call data_override_init(ocean_domain_in = ocean_public%domain) call mpp_get_compute_domain(ocean_public%domain, isc, iec, jsc, jec) + write(6,*)'DEBUG: isc,iec,jsc,jec= ',isc,iec,jsc,jec call IOB_allocate(ice_ocean_boundary, isc, iec, jsc, jec) call external_coupler_sbc_init(ocean_public%domain, dt_cpld, Run_len) @@ -827,7 +834,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) end subroutine InitializeAdvertise - !----------------------------------------------------------------------------- + !=============================================================================== !> Called by NUOPC to realize import and export fields. "Realizing" a field !! means that its grid has been defined and an ESMF_Field object has been @@ -859,9 +866,10 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) integer :: nxg, nyg, cnt integer :: isc,iec,jsc,jec integer, allocatable :: xb(:),xe(:),yb(:),ye(:),pe(:) - integer, allocatable :: deBlockList(:,:,:), & - petMap(:),deLabelList(:), & - indexList(:) + integer, allocatable :: deBlockList(:,:,:) + integer, allocatable :: petMap(:) + integer, allocatable :: deLabelList(:) + integer, allocatable :: indexList(:) integer :: ioff, joff integer :: i, j, n, i1, j1, n1, icount integer :: lbnd1,ubnd1,lbnd2,ubnd2 @@ -878,10 +886,27 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) real(ESMF_KIND_R8), pointer :: dataPtr_ycor(:,:) type(ESMF_Field) :: field_t_surf integer :: mpicom + integer :: localPet +#ifdef CESMCOUPLED + integer :: shrlogunit ! original log unit + integer :: shrloglev ! original log level + integer :: inst_index ! number of current instance (ie. 1) + character(len=16) :: inst_name ! fullname of current instance (ie. "lnd_0001") + character(len=16) :: inst_suffix = "" ! char string associated with instance (ie. "_0001" or "") + character(len=64) :: cvalue + character(len=512) :: diro + character(len=512) :: logfile + logical :: isPresent +#endif character(len=*),parameter :: subname='(mom_cap:InitializeRealize)' + !-------------------------------- rc = ESMF_SUCCESS + !---------------------------------------------------------------------------- + ! Get pointers to ocean internal state + !---------------------------------------------------------------------------- + call ESMF_GridCompGetInternalState(gcomp, ocean_internalstate, rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & line=__LINE__, & @@ -889,20 +914,78 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) return ! bail out Ice_ocean_boundary => ocean_internalstate%ptr%ice_ocean_boundary_type_ptr - ocean_public => ocean_internalstate%ptr%ocean_public_type_ptr + ocean_public => ocean_internalstate%ptr%ocean_public_type_ptr ocean_state => ocean_internalstate%ptr%ocean_state_type_ptr + !---------------------------------------------------------------------------- + ! Get mpi information + !---------------------------------------------------------------------------- + call ESMF_VMGetCurrent(vm, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & line=__LINE__, & file=__FILE__)) & return ! bail out - call ESMF_VMGet(vm, petCount=npet, mpiCommunicator=mpicom, rc=rc) + call ESMF_VMGet(vm, petCount=npet, mpiCommunicator=mpicom, localPet=localPet, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + +#ifdef CESMCOUPLED + ! determine instance information + call NUOPC_CompAttributeGet(gcomp, name="inst_name", value=inst_name, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + call NUOPC_CompAttributeGet(gcomp, name="inst_index", value=cvalue, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & line=__LINE__, & file=__FILE__)) & return ! bail out + read(cvalue,*) inst_index + + call ESMF_AttributeGet(gcomp, name="inst_suffix", isPresent=isPresent, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + if (isPresent) then + call NUOPC_CompAttributeGet(gcomp, name="inst_suffix", value=inst_suffix, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + else + inst_suffix = '' + end if + + ! reset shr logging to my log file + if (localPet == 0) then + call NUOPC_CompAttributeGet(gcomp, name="diro", value=diro, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call NUOPC_CompAttributeGet(gcomp, name="logfile", value=logfile, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + logunit = shr_file_getUnit() + open(logunit,file=trim(diro)//"/"//trim(logfile)) + else + logunit = 6 + endif + + call shr_file_getLogUnit (shrlogunit) + call shr_file_getLogLevel(shrloglev) + call shr_file_setLogLevel(max(shrloglev,1)) + call shr_file_setLogUnit (logunit) +#endif !--------------------------------- ! global mom grid size @@ -1389,9 +1472,15 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) write(*,*) '----- MOM initialization phase Realize completed' +#ifdef CESMCOUPLED + ! Reset shr logging to original values + call shr_file_setLogUnit (shrlogunit) + call shr_file_setLogLevel(shrloglev) +#endif + end subroutine InitializeRealize - !----------------------------------------------------------------------------- + !=============================================================================== subroutine DataInitialize(gcomp, rc) type(ESMF_GridComp) :: gcomp @@ -1400,14 +1489,18 @@ subroutine DataInitialize(gcomp, rc) ! local variables type(ESMF_Clock) :: clock type(ESMF_State) :: importState, exportState - type (ocean_public_type), pointer :: ocean_public => NULL() + type (ocean_public_type), pointer :: ocean_public => NULL() type (ocean_state_type), pointer :: ocean_state => NULL() type(ice_ocean_boundary_type), pointer :: Ice_ocean_boundary => NULL() type(ocean_internalstate_wrapper) :: ocean_internalstate - type(ocean_grid_type), pointer :: ocean_grid - character(240) :: msgString - integer :: fieldCount, n - type(ESMF_Field) :: field + type(ocean_grid_type), pointer :: ocean_grid + character(240) :: msgString + integer :: fieldCount, n + type(ESMF_Field) :: field +#ifdef CESMCOUPLED + integer :: shrlogunit ! original log unit + integer :: shrloglev ! original log level +#endif character(len=64),allocatable :: fieldNameList(:) character(len=*),parameter :: subname='(mom_cap:DataInitialize)' @@ -1485,7 +1578,8 @@ subroutine DataInitialize(gcomp, rc) end subroutine DataInitialize - !----------------------------------------------------------------------------- + !=============================================================================== + !> Called by NUOPC to advance the model a single timestep. !! !! @param gcomp an ESMF_GridComp object @@ -1503,38 +1597,35 @@ subroutine ModelAdvance(gcomp, rc) type(ESMF_TimeInterval) :: time_elapsed integer(ESMF_KIND_I8) :: n_interval, time_elapsed_sec character(len=64) :: timestamp - - type (ocean_public_type), pointer :: ocean_public => NULL() + type (ocean_public_type), pointer :: ocean_public => NULL() type (ocean_state_type), pointer :: ocean_state => NULL() type(ice_ocean_boundary_type), pointer :: Ice_ocean_boundary => NULL() type(ocean_internalstate_wrapper) :: ocean_internalstate - - ! define some time types type(time_type) :: Time type(time_type) :: Time_step_coupled type(time_type) :: Time_restart_current - - integer :: dth, dtm, dts, dt_cpld = 86400 - integer :: isc,iec,jsc,jec,lbnd1,ubnd1,lbnd2,ubnd2 - integer :: i,j,i1,j1 - integer :: nc + integer :: dth, dtm, dts, dt_cpld = 86400 + integer :: isc,iec,jsc,jec,lbnd1,ubnd1,lbnd2,ubnd2 + integer :: i,j,i1,j1 + integer :: nc #ifdef CESMCOUPLED - ! in ocn_import, ocn_export + integer :: shrlogunit ! original log unit + integer :: shrloglev ! original log level #else real(ESMF_KIND_R8), allocatable :: ofld(:,:), ocz(:,:), ocm(:,:) real(ESMF_KIND_R8), allocatable :: mmmf(:,:), mzmf(:,:) - real(ESMF_KIND_R8), pointer :: dataPtr_mask(:,:) - real(ESMF_KIND_R8), pointer :: dataPtr_mmmf(:,:) - real(ESMF_KIND_R8), pointer :: dataPtr_mzmf(:,:) - real(ESMF_KIND_R8), pointer :: dataPtr_ocz(:,:) - real(ESMF_KIND_R8), pointer :: dataPtr_ocm(:,:) - real(ESMF_KIND_R8), pointer :: dataPtr_frazil(:,:) - real(ESMF_KIND_R8), pointer :: dataPtr_evap(:,:) - real(ESMF_KIND_R8), pointer :: dataPtr_sensi(:,:) + real(ESMF_KIND_R8), pointer :: dataPtr_mask(:,:) + real(ESMF_KIND_R8), pointer :: dataPtr_mmmf(:,:) + real(ESMF_KIND_R8), pointer :: dataPtr_mzmf(:,:) + real(ESMF_KIND_R8), pointer :: dataPtr_ocz(:,:) + real(ESMF_KIND_R8), pointer :: dataPtr_ocm(:,:) + real(ESMF_KIND_R8), pointer :: dataPtr_frazil(:,:) + real(ESMF_KIND_R8), pointer :: dataPtr_evap(:,:) + real(ESMF_KIND_R8), pointer :: dataPtr_sensi(:,:) #endif - type(ocean_grid_type), pointer :: ocean_grid - character(240) :: msgString - character(len=*),parameter :: subname='(mom_cap:ModelAdvance)' + type(ocean_grid_type), pointer :: ocean_grid + character(240) :: msgString + character(len=*),parameter :: subname='(mom_cap:ModelAdvance)' rc = ESMF_SUCCESS if(profile_memory) call ESMF_VMLogMemInfo("Entering MOM Model_ADVANCE: ") @@ -1554,9 +1645,17 @@ subroutine ModelAdvance(gcomp, rc) return ! bail out Ice_ocean_boundary => ocean_internalstate%ptr%ice_ocean_boundary_type_ptr - ocean_public => ocean_internalstate%ptr%ocean_public_type_ptr + ocean_public => ocean_internalstate%ptr%ocean_public_type_ptr ocean_state => ocean_internalstate%ptr%ocean_state_type_ptr +#ifdef CESMCOUPLED + ! Reset shr logging to my log file + call shr_file_getLogUnit (shrlogunit) + call shr_file_getLogLevel(shrloglev) + call shr_file_setLogLevel(max(shrloglev,1)) + call shr_file_setLogUnit (logunit) +#endif + ! HERE THE MODEL ADVANCES: currTime -> currTime + timeStep call ESMF_ClockPrint(clock, options="currTime", & @@ -1642,12 +1741,7 @@ subroutine ModelAdvance(gcomp, rc) !#endif #ifdef CESMCOUPLED - call ESMF_LogWrite(subname//' tcx call ocn_import', ESMF_LOGMSG_INFO, rc=rc) - if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & - line=__LINE__, & - file=__FILE__)) & - return ! bail out - call ocn_import(ocean_public, ocean_grid, importState, ice_ocean_boundary, rc=rc) + call ocn_import(ocean_public, ocean_grid, importState, ice_ocean_boundary, logunit, clock, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & line=__LINE__, & file=__FILE__)) & @@ -1892,8 +1986,16 @@ subroutine ModelAdvance(gcomp, rc) if(profile_memory) call ESMF_VMLogMemInfo("Leaving MOM Model_ADVANCE: ") +#ifdef CESMCOUPLED + ! reset shr logging to my original values + call shr_file_setLogUnit (shrlogunit) + call shr_file_setLogLevel(shrloglev) +#endif + end subroutine ModelAdvance + !=============================================================================== + !> Called by NUOPC at the end of the run to clean up. !! !! @param gcomp an ESMF_GridComp object @@ -1950,8 +2052,9 @@ subroutine ocean_model_finalize(gcomp, rc) end subroutine ocean_model_finalize -!==================================================================== -! get forcing data from data_overide + !==================================================================== + + ! get forcing data from data_overide subroutine ice_ocn_bnd_from_data(x, Time, Time_step_coupled) type (ice_ocean_boundary_type) :: x @@ -1980,7 +2083,6 @@ subroutine ice_ocn_bnd_from_data(x, Time, Time_step_coupled) end subroutine ice_ocn_bnd_from_data - !----------------------------------------------------------------------------------------- ! ! Subroutines for enabling coupling to external programs through a third party coupler diff --git a/config_src/nuopc_driver/mom_cap_methods.F90 b/config_src/nuopc_driver/mom_cap_methods.F90 index 6061e0c7fd..e16a580ad1 100644 --- a/config_src/nuopc_driver/mom_cap_methods.F90 +++ b/config_src/nuopc_driver/mom_cap_methods.F90 @@ -10,10 +10,12 @@ module mom_cap_methods use MOM_surface_forcing, only: ice_ocean_boundary_type use MOM_grid, only: ocean_grid_type use MOM_domains, only: pass_var + use MOM_error_handler, only: is_root_pe use mpp_domains_mod, only: mpp_get_compute_domain ! By default make data private - implicit none; private + implicit none + private ! Public member functions public :: ocn_export @@ -23,6 +25,8 @@ module mom_cap_methods integer :: import_cnt = 0 character(len=1024) :: tmpstr + logical, parameter :: debug=.false. + !----------------------------------------------------------------------- contains !----------------------------------------------------------------------- @@ -279,17 +283,21 @@ end subroutine ocn_export !! See \ref section_ocn_import for a summary of the surface fluxes that are !! passed from MCT to MOM6, including fluxes that need to be included in !! the future. - subroutine ocn_import(ocean_public, grid, importState, ice_ocean_boundary, rc) + subroutine ocn_import(ocean_public, grid, importState, ice_ocean_boundary, logunit, clock, rc) type(ocean_public_type) , intent(in) :: ocean_public !< Ocean surface state type(ocean_grid_type) , intent(in) :: grid !< Ocean model grid type(ESMF_State) , intent(inout) :: importState !< incoming data type(ice_ocean_boundary_type) , intent(inout) :: ice_ocean_boundary !< Ocean boundary forcing + type(ESMF_Clock) , intent(in) :: clock + integer , intent(in) :: logunit integer , intent(inout) :: rc - integer :: i, j, i1, j1, ig, jg, isc, iec, jsc, jec !< Grid indices - real(ESMF_KIND_R8) :: c1,c2,c3,c4 - integer :: lbnd1, lbnd2, ubnd1, ubnd2 - + ! Local Variables + integer :: i, j, i1, j1, ig, jg ! Grid indices + integer :: isc, iec, jsc, jec ! Grid indices + integer :: isc_bnd, jsc_bnd, ise_bnd, jse_bnd + integer :: lbnd1, lbnd2, ubnd1, ubnd2 + integer :: i0, j0, is, js, ie, je real(ESMF_KIND_R8), pointer :: dataPtr_p(:,:) real(ESMF_KIND_R8), pointer :: dataPtr_ifrac(:,:) real(ESMF_KIND_R8), pointer :: dataPtr_duu10n(:,:) @@ -319,6 +327,9 @@ subroutine ocn_import(ocean_public, grid, importState, ice_ocean_boundary, rc) real(ESMF_KIND_R8), pointer :: dataPtr_prec(:,:) real(ESMF_KIND_R8), pointer :: dataPtr_rain(:,:) real(ESMF_KIND_R8), pointer :: dataPtr_snow(:,:) + integer :: day, secs + type(ESMF_time) :: currTime + character(len=*), parameter :: F01 = "('(ocn_import) ',a,4(i6,2x),d21.14)" character(len=*), parameter :: subname = '(ocn_import)' !----------------------------------------------------------------------- @@ -537,22 +548,45 @@ subroutine ocn_import(ocean_public, grid, importState, ice_ocean_boundary, rc) ice_ocean_boundary%lw_flux(i,j) = (dataPtr_lwup(i1,j1) + dataPtr_lwdn(i1,j1)) * GRID%mask2dT(ig,jg) ice_ocean_boundary%sw_flux_vis_dir(i,j) = dataPtr_swvdr(i1,j1) * GRID%mask2dT(ig,jg) ice_ocean_boundary%sw_flux_vis_dif(i,j) = dataPtr_swvdf(i1,j1) * GRID%mask2dT(ig,jg) - ice_ocean_boundary%sw_flux_nir_dir(i,j) = dataPtr_swndf(i1,j1) * GRID%mask2dT(ig,jg) + ice_ocean_boundary%sw_flux_nir_dir(i,j) = dataPtr_swndr(i1,j1) * GRID%mask2dT(ig,jg) ice_ocean_boundary%sw_flux_nir_dif(i,j) = dataPtr_swndf(i1,j1) * GRID%mask2dT(ig,jg) ice_ocean_boundary%salt_flux(i,j) = dataPtr_iosalt(i1,j1) * GRID%mask2dT(ig,jg) + ice_ocean_boundary%runoff(i,j) = (dataPtr_rofl(i1,j1) + dataPtr_rofi(i1,j1)) * GRID%mask2dT(ig,jg) !ice_ocean_boundary%salt_flux(i,j) = (dataPtr_osalt(i1,j1) + ice_ocean_boundary%salt_flux(i,j)) * GRID%mask2dT(ig,jg) !ice_ocean_boundary%latent_flux(i,j) = dataPtr_lat(i1,j1) * GRID%mask2dT(ig,jg) - !ice_ocean_boundary%runoff(i,j) = (dataPtr_rofl(i1,j1)+dataPtr_rofi(i1,j1)) * GRID%mask2dT(ig,jg) - !ice_ocean_boundary%u_flux(i,j) = (GRID%cos_rot(ig,jg)*dataPtr_taux(i1,j1) + & - ! GRID%sin_rot(ig,jg)*dataPtr_tauy(i1,j1)) - !ice_ocean_boundary%v_flux(i,j) = (GRID%cos_rot(ig,jg)*dataPtr_tauy(i1,j1) + & - ! GRID%sin_rot(ig,jg)*dataPtr_taux(i1,j1)) - + !ice_ocean_boundary%u_flux(i,j) = (GRID%cos_rot(ig,jg)*dataPtr_taux(i1,j1) + GRID%sin_rot(ig,jg)*dataPtr_tauy(i1,j1)) + !ice_ocean_boundary%v_flux(i,j) = (GRID%cos_rot(ig,jg)*dataPtr_tauy(i1,j1) + GRID%sin_rot(ig,jg)*dataPtr_taux(i1,j1)) endif - enddo enddo + ! debug output + if (import_cnt > 2 .and. debug .and. is_root_pe()) then + call ESMF_ClockGet(clock, CurrTime=CurrTime, rc=rc) + call ESMF_TimeGet(CurrTime, d=day, s=secs, rc=rc) + + i0 = GRID%isc - isc + j0 = GRID%jsc - jsc + do j = GRID%jsc, GRID%jec + do i = GRID%isc, GRID%iec + write(logunit,F01)'import: day, secs, j, i, u_flux = ',day,secs,j,i,ice_ocean_boundary%u_flux(i-i0,j-j0) + write(logunit,F01)'import: day, secs, j, i, v_flux = ',day,secs,j,i,ice_ocean_boundary%v_flux(i-i0,j-j0) + write(logunit,F01)'import: day, secs, j, i, lprec = ',day,secs,j,i,ice_ocean_boundary%lprec(i-i0,j-j0) + write(logunit,F01)'import: day, secs, j, i, lwrad = ',day,secs,j,i,ice_ocean_boundary%lw_flux(i-i0,j-j0) + write(logunit,F01)'import: day, secs, j, i, q_flux = ',day,secs,j,i,ice_ocean_boundary%q_flux(i-i0,j-j0) + write(logunit,F01)'import: day, secs, j, i, t_flux = ',day,secs,j,i,ice_ocean_boundary%t_flux(i-i0,j-j0) + !write(logunit,F01)'import: day, secs, j, i, latent_flux = ',day,secs,j,i,ice_ocean_boundary%latent_flux(i-i0,j-j0) + write(logunit,F01)'import: day, secs, j, i, runoff = ',day,secs,j,i,ice_ocean_boundary%runoff(i-i0,j-j0) + write(logunit,F01)'import: day, secs, j, i, psurf = ',day,secs,j,i,ice_ocean_boundary%p(i-i0,j-j0) + write(logunit,F01)'import: day, secs, j, i, salt_flux = ',day,secs,j,i,ice_ocean_boundary%salt_flux(i-i0,j-j0) + write(logunit,F01)'import: day, secs, j, i, sw_flux_vis_dir = ',day,secs,j,i,ice_ocean_boundary%sw_flux_vis_dir(i-i0,j-j0) + write(logunit,F01)'import: day, secs, j, i, sw_flux_vis_dif = ',day,secs,j,i,ice_ocean_boundary%sw_flux_vis_dif(i-i0,j-j0) + write(logunit,F01)'import: day, secs, j, i, sw_flux_nir_dir = ',day,secs,j,i,ice_ocean_boundary%sw_flux_nir_dir(i-i0,j-j0) + write(logunit,F01)'import: day, secs, j, i, sw_flux_nir_dif = ',day,secs,j,i,ice_ocean_boundary%sw_flux_nir_dir(i-i0,j-j0) + end do + end do + end if + end subroutine ocn_import !-----------------------------------------------------------------------------