From e10a3fd1f16dc2186e90cdd2b0235fc8ec5d46e6 Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Mon, 31 Jul 2023 11:28:12 -0600 Subject: [PATCH 1/5] make building ww3 tools optional --- CMakeLists.txt | 1 + model/src/CMakeLists.txt | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9dff6c12f..e4f424606 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,7 @@ set(UFS_CAP "" CACHE STRING "Valid options are ${valid_caps}") set(NETCDF ON CACHE BOOL "Build NetCDF programs (requires NetCDF)") set(ENDIAN "BIG" CACHE STRING "Endianness of unformatted output files. Valid values are 'BIG', 'LITTLE', 'NATIVE'.") set(EXCLUDE_FIND "" CACHE STRING "Don't try and search for these libraries (assumd to be handled by the compiler/wrapper)") +set(BUILD_TOOLS OFF CACHE BOOL "Build WW3 tools") # make sure all "exclude_find" entries are lower case list(TRANSFORM EXCLUDE_FIND TOLOWER) diff --git a/model/src/CMakeLists.txt b/model/src/CMakeLists.txt index 9dbc16073..db91eb519 100644 --- a/model/src/CMakeLists.txt +++ b/model/src/CMakeLists.txt @@ -141,7 +141,9 @@ if(UFS_CAP) target_sources(ww3_lib PRIVATE ${cap_src}) target_link_libraries(ww3_lib PUBLIC esmf) # Don't build executables when building WW3 ESMF library - set(programs "") + if (NOT BUILD_TOOLS) + set(programs "") + endif() endif() set_property(SOURCE w3initmd.F90 From 2e8510e005580403a42a80396faf4ab467f9afe8 Mon Sep 17 00:00:00 2001 From: Ufuk Turuncoglu Date: Mon, 30 Oct 2023 12:19:23 -0500 Subject: [PATCH 2/5] add radiation stress components to nuopc cap --- model/src/wav_import_export.F90 | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/model/src/wav_import_export.F90 b/model/src/wav_import_export.F90 index e6caa1a2d..4a9af31d7 100644 --- a/model/src/wav_import_export.F90 +++ b/model/src/wav_import_export.F90 @@ -145,6 +145,9 @@ subroutine advertise_fields(importState, ExportState, flds_scalar_name, rc) call fldlist_add(fldsFrWav_num, fldsFrWav, 'Sw_vstokes') else call fldlist_add(fldsFrWav_num, fldsFrWav, 'Sw_z0') + call fldlist_add(fldsFrWav_num, fldsFrWav, 'Sw_wavsuu') + call fldlist_add(fldsFrWav_num, fldsFrWav, 'Sw_wavsuv') + call fldlist_add(fldsFrWav_num, fldsFrWav, 'Sw_wavsvv') end if call fldlist_add(fldsFrWav_num, fldsFrWav, 'Sw_pstokes_x', ungridded_lbound=1, ungridded_ubound=3) call fldlist_add(fldsFrWav_num, fldsFrWav, 'Sw_pstokes_y', ungridded_lbound=1, ungridded_ubound=3) @@ -753,14 +756,14 @@ subroutine export_fields (gcomp, rc) call CalcBotcur( va, wbcuru, wbcurv, wbcurp) end if - if ( state_fldchk(exportState, 'wavsuu') .and. & - state_fldchk(exportState, 'wavsuv') .and. & - state_fldchk(exportState, 'wavsvv')) then - call state_getfldptr(exportState, 'sxxn', sxxn, rc=rc) + if ( state_fldchk(exportState, 'Sw_wavsuu') .and. & + state_fldchk(exportState, 'Sw_wavsuv') .and. & + state_fldchk(exportState, 'Sw_wavsvv')) then + call state_getfldptr(exportState, 'Sw_wavsuu', sxxn, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call state_getfldptr(exportState, 'sxyn', sxyn, rc=rc) + call state_getfldptr(exportState, 'Sw_wavsuv', sxyn, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call state_getfldptr(exportState, 'syyn', syyn, rc=rc) + call state_getfldptr(exportState, 'Sw_wavsvv', syyn, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call CalcRadstr2D( va, sxxn, sxyn, syyn) end if From 8c75b2dbf2b138fadaa05ff534e6d0f51fdfe1cd Mon Sep 17 00:00:00 2001 From: Ufuk Turuncoglu Date: Thu, 25 Jan 2024 09:48:28 -0600 Subject: [PATCH 3/5] add scrip to meshcap switch --- model/bin/switch_meshcap_pdlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/bin/switch_meshcap_pdlib b/model/bin/switch_meshcap_pdlib index 3b43c7146..5eccc27a1 100644 --- a/model/bin/switch_meshcap_pdlib +++ b/model/bin/switch_meshcap_pdlib @@ -1 +1 @@ -NCO PDLIB SCOTCH NOGRB DIST MPI PR3 UQ FLX0 SEED ST4 STAB0 NL1 BT1 DB1 MLIM FLD2 TR0 BS0 RWND WNX1 WNT1 CRX1 CRT1 O0 O1 O2 O3 O4 O5 O6 O7 O14 O15 IC0 IS0 REF0 +NCO PDLIB SCOTCH SCRIP SCRIPNC NOGRB DIST MPI PR3 UQ FLX0 SEED ST4 STAB0 NL1 BT1 DB1 MLIM FLD2 TR0 BS0 RWND WNX1 WNT1 CRX1 CRT1 O0 O1 O2 O3 O4 O5 O6 O7 O14 O15 IC0 IS0 REF0 From f2b10a59733ff46e6487afa5b80eeadddd944289 Mon Sep 17 00:00:00 2001 From: Ufuk Turuncoglu Date: Thu, 8 Feb 2024 14:19:10 -0600 Subject: [PATCH 4/5] enable standalone ww3 run --- model/src/wav_comp_nuopc.F90 | 16 ++++++++++++++-- model/src/wav_import_export.F90 | 27 ++++++++++++++++++++++----- model/src/wav_shr_mod.F90 | 2 ++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/model/src/wav_comp_nuopc.F90 b/model/src/wav_comp_nuopc.F90 index c7bb14ef2..14bc4cb9b 100644 --- a/model/src/wav_comp_nuopc.F90 +++ b/model/src/wav_comp_nuopc.F90 @@ -47,7 +47,7 @@ module wav_comp_nuopc use w3odatmd , only : runtype, use_user_histname, user_histfname, use_user_restname, user_restfname use w3odatmd , only : user_netcdf_grdout use w3odatmd , only : time_origin, calendar_name, elapsed_secs - use wav_shr_mod , only : casename, multigrid, inst_suffix, inst_index, unstr_mesh + use wav_shr_mod , only : casename, multigrid, inst_suffix, inst_index, unstr_mesh, standalone use wav_wrapper_mod , only : ufs_settimer, ufs_logtimer, ufs_file_setlogunit, wtime #ifndef W3_CESMCOUPLED use wmwavemd , only : wmwave @@ -379,10 +379,22 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (isPresent .and. isSet) runtimelog=(trim(cvalue)=="true") write(logmsg,*) runtimelog - call ESMF_LogWrite('WW3_cap:RunTimeLog = '//trim(logmsg), ESMF_LOGMSG_INFO) + call ESMF_LogWrite(trim(subname)//': RunTimeLog = '//trim(logmsg), ESMF_LOGMSG_INFO) if (runtimelog) then call ufs_file_setLogUnit('./log.ww3.timer',nu_timer,runtimelog) end if + + ! Determine if this is standalone run + call NUOPC_CompAttributeGet(gcomp, name="standalone", value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (isPresent .and. isSet) then + if (trim(cvalue) == '.true.' .or. trim(cvalue) == 'true') then + standalone = .true. + end if + end if + write(logmsg,'(A,l)') trim(subname)//': Standalone setting is ', standalone + call ESMF_LogWrite(trim(logmsg), ESMF_LOGMSG_INFO) + call advertise_fields(importState, exportState, flds_scalar_name, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return diff --git a/model/src/wav_import_export.F90 b/model/src/wav_import_export.F90 index 4a9af31d7..8b8f4b4b2 100644 --- a/model/src/wav_import_export.F90 +++ b/model/src/wav_import_export.F90 @@ -20,6 +20,7 @@ module wav_import_export use wav_shr_mod , only : chkerr use wav_shr_mod , only : state_diagnose, state_reset, state_getfldptr, state_fldchk use wav_shr_mod , only : wav_coupling_to_cice, nwav_elev_spectrum, merge_import, dbug_flag, multigrid, unstr_mesh + use wav_shr_mod , only : standalone use constants , only : grav, tpi, dwat, dair use w3parall , only : init_get_isea @@ -381,12 +382,14 @@ subroutine import_fields( gcomp, time0, timen, rc ) TW0 = time0 ! times for atm wind/temp fields. TWN = timen - if (merge_import) then + if (merge_import .or. standalone) then ! set mask using u-wind field if merge_import; assume all import fields ! will have same missing overlap region ! import_mask memory will be allocate in set_importmask - call set_importmask(importState, clock, trim(uwnd), vm, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (merge_import) then + call set_importmask(importState, clock, trim(uwnd), vm, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if allocate(wxdata(nsea)) allocate(wydata(nsea)) call readfromfile('WND', wxdata, wydata, time0, timen, rc) @@ -396,8 +399,10 @@ subroutine import_fields( gcomp, time0, timen, rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) return call check_globaldata(gcomp, 'wydata', wydata, nsea, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call check_globaldata(gcomp, 'import_mask', import_mask, nsea, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (merge_import) then + call check_globaldata(gcomp, 'import_mask', import_mask, nsea, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if end if end if @@ -418,6 +423,12 @@ subroutine import_fields( gcomp, time0, timen, rc ) call FillGlobalInput(global_data, WX0) call FillGlobalInput(global_data, WXN) end if + else + if (standalone) then + call ESMF_LogWrite(trim(subname)//' no connected uwnd field. reading data from wind.ww3.', ESMF_LOGMSG_INFO) + call FillGlobalInput(wxdata, WX0) + call FillGlobalInput(wxdata, WXN) + end if end if ! atm v wind @@ -438,6 +449,12 @@ subroutine import_fields( gcomp, time0, timen, rc ) call FillGlobalInput(global_data, WY0) call FillGlobalInput(global_data, WYN) end if + else + if (standalone) then + call ESMF_LogWrite(trim(subname)//' no connected vwnd field. reading data from wind.ww3.', ESMF_LOGMSG_INFO) + call FillGlobalInput(wydata, WY0) + call FillGlobalInput(wydata, WYN) + end if end if ! air temp - ocn temp diff --git a/model/src/wav_shr_mod.F90 b/model/src/wav_shr_mod.F90 index 9bddd503e..0780852b3 100644 --- a/model/src/wav_shr_mod.F90 +++ b/model/src/wav_shr_mod.F90 @@ -75,6 +75,8 @@ module wav_shr_mod !! be merged with a field provided from a file logical , public :: multigrid = .false. !< @public logical to control whether wave model is run !! as multigrid + logical , public :: standalone = .false. !< @public logical to control whether wave model is run + !! in standalone mode - read fields from file interface ymd2date module procedure ymd2date_int From 80a5ad544d8997931dde7fa7c8ebad56612ed299 Mon Sep 17 00:00:00 2001 From: Ufuk Turuncoglu Date: Fri, 19 Apr 2024 14:28:34 -0500 Subject: [PATCH 5/5] minor fix for standalone build --- model/src/wav_shr_mod.F90 | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/model/src/wav_shr_mod.F90 b/model/src/wav_shr_mod.F90 index 0780852b3..2d4c1149f 100644 --- a/model/src/wav_shr_mod.F90 +++ b/model/src/wav_shr_mod.F90 @@ -26,6 +26,7 @@ module wav_shr_mod use ESMF , only : ESMF_Time, ESMF_TimeGet, ESMF_TimeSet use ESMF , only : ESMF_TimeInterval, ESMF_TimeIntervalSet, ESMF_TimeIntervalGet use ESMF , only : ESMF_VM, ESMF_VMGet, ESMF_VMBroadcast, ESMF_VMGetCurrent + use ESMF , only : ESMF_FieldStatus_Flag, ESMF_FIELDSTATUS_COMPLETE use NUOPC , only : NUOPC_CompAttributeGet use NUOPC_Model , only : NUOPC_ModelGet use wav_kind_mod , only : r8 => shr_kind_r8, i8 => shr_kind_i8, cl=>shr_kind_cl, cs=>shr_kind_cs @@ -486,6 +487,7 @@ subroutine state_reset(State, reset_value, rc) ! local variables integer :: i,j,n type(ESMF_Field) :: lfield + type(ESMF_FieldStatus_Flag) :: lstatus integer :: fieldCount integer :: lrank character(ESMF_MAXSTR), allocatable :: lfieldnamelist(:) @@ -507,19 +509,24 @@ subroutine state_reset(State, reset_value, rc) call ESMF_StateGet(State, itemName=trim(lfieldnamelist(n)), field=lfield, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call field_getfldptr(lfield, fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) + call ESMF_FieldGet(lfield, status=lstatus, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (lrank == 0) then - ! no local data - elseif (lrank == 1) then - fldptr1 = reset_value - elseif (lrank == 2) then - fldptr2 = reset_value - else - call ESMF_LogWrite(trim(subname)//": ERROR in rank "//trim(lfieldnamelist(n)), ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return + if (lstatus == ESMF_FIELDSTATUS_COMPLETE) then + call field_getfldptr(lfield, fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (lrank == 0) then + ! no local data + elseif (lrank == 1) then + fldptr1 = reset_value + elseif (lrank == 2) then + fldptr2 = reset_value + else + call ESMF_LogWrite(trim(subname)//": ERROR in rank "//trim(lfieldnamelist(n)), ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + endif endif enddo