From 117a47e4e8cd9f084134ede54c7d853268e9cf1f Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Fri, 22 Nov 2024 21:23:38 +0000 Subject: [PATCH 01/10] make sure point is defined with the same -180 to 180 or 0 to 360 etc coordinates --- model/src/w3triamd.F90 | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/model/src/w3triamd.F90 b/model/src/w3triamd.F90 index 9fac503b6..b7fb6aaec 100644 --- a/model/src/w3triamd.F90 +++ b/model/src/w3triamd.F90 @@ -1716,7 +1716,7 @@ SUBROUTINE IS_IN_UNGRID(IMOD, XTIN, YTIN, ITOUT, IS, JS, RW) !/ ------------------------------------------------------------------- / !local parameters - DOUBLE PRECISION :: x1, x2, x3 + DOUBLE PRECISION :: x1, x2, x3, XTINmod, xavg DOUBLE PRECISION :: y1, y2, y3 DOUBLE PRECISION :: s1, s2, s3, sg1, sg2, sg3 REAL*8 :: PT(3,2) @@ -1748,19 +1748,26 @@ SUBROUTINE IS_IN_UNGRID(IMOD, XTIN, YTIN, ITOUT, IS, JS, RW) !coordinates of the 3rd vertex C x3 = PT(3,1) y3 = PT(3,2) - !with M = (XTIN,YTIN) the target point ... + !ensure XTIN is defined with same coordinates as element + xavg=(x1+x2+x3)/3 + IF (ABS(XTIN-xavg).GT.180) THEN + XTINmod=XTIN-SIGN(360.0d0,(XTIN-xavg)) + ELSE + XTINmod=XTIN + END IF + !with M = (XTINmod,YTIN) the target point ... !vector product of AB and AC sg3=(y3-y1)*(x2-x1)-(x3-x1)*(y2-y1) !vector product of AB and AM - s3=(YTIN-y1)*(x2-x1)-(XTIN-x1)*(y2-y1) + s3=(YTIN-y1)*(x2-x1)-(XTINmod-x1)*(y2-y1) !vector product of BC and BA sg1=(y1-y2)*(x3-x2)-(x1-x2)*(y3-y2) !vector product of BC and BM - s1=(YTIN-y2)*(x3-x2)-(XTIN-x2)*(y3-y2) + s1=(YTIN-y2)*(x3-x2)-(XTINmod-x2)*(y3-y2) !vector product of CA and CB sg2=(y2-y3)*(x1-x3)-(x2-x3)*(y1-y3) !vector product of CA and CM - s2=(YTIN-y3)*(x1-x3)-(XTIN-x3)*(y1-y3) + s2=(YTIN-y3)*(x1-x3)-(XTINmod-x3)*(y1-y3) IF ((s1*sg1.GE.0).AND.(s2*sg2.GE.0).AND.(s3*sg3.GE.0)) THEN itout=ITRI nbFound=nbFound+1 From cf16dd620d184c0dd77f522038909d05b61ef094 Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Mon, 2 Dec 2024 18:03:42 +0000 Subject: [PATCH 02/10] add only to is_in_unst routine --- model/src/w3triamd.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/src/w3triamd.F90 b/model/src/w3triamd.F90 index b7fb6aaec..f2118ec24 100644 --- a/model/src/w3triamd.F90 +++ b/model/src/w3triamd.F90 @@ -1697,7 +1697,7 @@ SUBROUTINE IS_IN_UNGRID(IMOD, XTIN, YTIN, ITOUT, IS, JS, RW) ! 10. Source code : ! !/ ------------------------------------------------------------------- / - USE W3GDATMD + USE W3GDATMD, ONLY: GRIDS USE W3SERVMD, ONLY: EXTCDE #ifdef W3_S USE W3SERVMD, ONLY: STRACE From 040df5bfd1fa96956be97f75280752151e620e17 Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Mon, 2 Dec 2024 22:13:14 +0000 Subject: [PATCH 03/10] have added writing/reading of netcdf file with weights for points --- model/src/w3iopomd.F90 | 152 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 147 insertions(+), 5 deletions(-) diff --git a/model/src/w3iopomd.F90 b/model/src/w3iopomd.F90 index bbdfda34c..420991ddd 100644 --- a/model/src/w3iopomd.F90 +++ b/model/src/w3iopomd.F90 @@ -146,6 +146,10 @@ MODULE W3IOPOMD !> Dimension name for the netCDF point output file, for WW3TIME character(*), parameter, private :: DNAME_WW3TIME = 'WW3TIME' + !> Dimension name for the netCDF point weight file, WGHTLEN + !> This is 4 the dimension of weights + character(*), parameter, private :: DNAME_WGHTLEN = 'WGHTLEN' + !> Variable name for the netCDF point output file, for NK. character(*), parameter, private :: VNAME_NK = 'NK' @@ -158,6 +162,12 @@ MODULE W3IOPOMD !> Variable name for the netCDF point output file, for PTNME. character(*), parameter, private :: VNAME_PTNME = 'PTNME' + !> Variable name for the netCDF point weight file, for IPTINT + character(*), parameter, private :: VNAME_IPTINT = 'IPTINT' + + !> Variable name for the netCDF point weight file, for PTIFAC + character(*), parameter, private :: VNAME_PTIFAC = 'PTIFAC' + !> Variable name for the netCDF point output file, for TIME. character(*), parameter, private :: VNAME_TIME = 'TIME' @@ -329,7 +339,8 @@ SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD ) ! 10. Source code : ! !/ ------------------------------------------------------------------- / - USE W3GSRUMD + USE NETCDF + USE W3GSRUMD, ONLY: W3GRMP USE W3GDATMD, ONLY: NTH, NK, NSPEC, NX, NY, X0, Y0, SX, GSU,& RLGTYPE, CLGTYPE, UNGTYPE, GTYPE, FLAGLL, & ICLOSE,ICLOSE_NONE,ICLOSE_SMPL,ICLOSE_TRPL, & @@ -340,14 +351,15 @@ SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD ) USE W3GDATMD, ONLY: PoLat, PoLon, FLAGUNR USE W3SERVMD, ONLY: W3LLTOEQ #endif - USE W3ODATMD, ONLY: W3DMO2 + USE W3ODATMD, ONLY: W3DMO2, FNMPRE USE W3ODATMD, ONLY: NDSE, NDST, IAPROC, NAPERR, NAPOUT, SCREEN, & NOPTS, PTLOC, PTNME, GRDID, IPTINT, PTIFAC USE W3SERVMD, ONLY: EXTCDE #ifdef W3_S USE W3SERVMD, ONLY: STRACE #endif - USE W3TRIAMD + USE W3TRIAMD, ONLY: IS_IN_UNGRID + USE W3GDATMD, ONLY: FILEXT ! IMPLICIT NONE !/ @@ -389,6 +401,14 @@ SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD ) !! Declare a few temporary variables for rotated grid. JGLi12Jun2012 REAL, ALLOCATABLE :: EquLon(:),EquLat(:),StdLon(:),StdLat(:),AnglPT(:) #endif + ! Variables for NetCDF weights file for points + character(len = 124) :: filename + logical :: pnt_wght_exists, pnt_wght_write + integer :: ncerr, fh + integer :: d_nopts, d_namelen, d_vsize, d_wghtlen + integer :: d_nopts_len, d_vsize_len,d_namelen_len,d_wghtlen_len + integer :: v_ptloc, v_ptnme, v_iptint, v_ptifac + !/ !/ ------------------------------------------------------------------- / !/ @@ -423,10 +443,22 @@ SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD ) #endif ! - ! Removed by F.A. 2011/04/04 /T CALL W3GSUP( GSU, NDST ) + !If unstructured grid, check to see if a netcdf point weight file exists: + filename = 'pnt_wght.'//FILEXT(:LEN_TRIM(FILEXT))//'.nc' + IF (GTYPE .NE. UNGTYPE) THEN + !skipping weights file for non-unstructured grids. + !likely could be used after proper testing if initialization time is long + pnt_wght_exists = .FALSE. + pnt_wght_write = .FALSE. + ELSE + !for unstructured grid, use saved weights file if exists: + INQUIRE(FILE=filename, EXIST=pnt_wght_exists) + pnt_wght_write = .NOT. pnt_wght_exists + ENDIF ! - ! Loop over output points + ! Loop over output points if saved weights do not exist ! + IF (.NOT. pnt_wght_exists) THEN DO IPT=1, NPT ! #ifdef W3_T @@ -503,6 +535,116 @@ SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD ) PTNME(NOPTS) = PNAMES(IPT) ! END DO ! End loop over output points (IPT). + ELSE + !READ from file + !open file + ! read NOPTS + ! READ PTLOC + ! READ IPTINT(2, 4, NOPTS) + ! READ PTIFAC(4, NOPOTS) + ! READ PTNME(NOPTS) + + ! Open the netCDF file. + ncerr = nf90_open(filename, NF90_NOWRITE, fh) + if (nf90_err(ncerr) .ne. 0) return + + ! Read the dimension information for NOPTS. + ncerr = nf90_inq_dimid(fh, DNAME_NOPTS, d_nopts) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_inquire_dimension(fh, d_nopts, len = d_nopts_len) + if (nf90_err(ncerr) .ne. 0) return + NOPTS=d_nopts_len + + ! Read the dimension information for VSIZE. + ncerr = nf90_inq_dimid(fh, DNAME_VSIZE, d_vsize) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_inquire_dimension(fh, d_vsize, len = d_vsize_len) + if (nf90_err(ncerr) .ne. 0) return + + ! Read the dimension information for NAMELEN. + ncerr = nf90_inq_dimid(fh, DNAME_NAMELEN, d_namelen) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_inquire_dimension(fh, d_namelen, len = d_namelen_len) + if (nf90_err(ncerr) .ne. 0) return + + ! Read the dimension information for WGHTLEN. + ncerr = nf90_inq_dimid(fh, DNAME_WGHTLEN, d_wghtlen) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_inquire_dimension(fh, d_wghtlen, len = d_wghtlen_len) + if (nf90_err(ncerr) .ne. 0) return + + ! Read vars + ncerr = nf90_inq_varid(fh, VNAME_PTLOC, v_ptloc) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_get_var(fh, v_ptloc, PTLOC, start = (/ 1, 1/), & + count = (/ d_vsize_len, d_nopts_len /)) + if (nf90_err(ncerr) .ne. 0) return + + ncerr = nf90_inq_varid(fh, VNAME_PTNME, v_ptnme) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_get_var(fh, v_ptnme, PTNME, start = (/ 1, 1/), & + count = (/ d_namelen_len, d_nopts_len /)) + if (nf90_err(ncerr) .ne. 0) return + + ncerr = nf90_inq_varid(fh, VNAME_IPTINT, v_iptint) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_get_var(fh, v_iptint, IPTINT, start = (/ 1, 1/), & + count = (/ d_vsize_len, d_wghtlen_len, d_nopts_len /)) + if (nf90_err(ncerr) .ne. 0) return + + ncerr = nf90_inq_varid(fh, VNAME_PTIFAC, v_ptifac) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_get_var(fh, v_ptifac, PTIFAC, start = (/ 1, 1/), & + count = (/ d_wghtlen_len, d_nopts_len /)) + if (nf90_err(ncerr) .ne. 0) return + + ENDIF + IF ( pnt_wght_write .AND. (NOPTS > 0) ) THEN + + ! Create the netCDF file. + ncerr = nf90_create(filename, NF90_NETCDF4, fh) + if (nf90_err(ncerr) .ne. 0) return + + ! Define dimensions. + ncerr = nf90_def_dim(fh, DNAME_NOPTS, NOPTS, d_nopts) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_def_dim(fh, DNAME_NAMELEN, 40, d_namelen) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_def_dim(fh, DNAME_VSIZE, 2, d_vsize) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_def_dim(fh, DNAME_WGHTLEN, 4, d_wghtlen) + if (nf90_err(ncerr) .ne. 0) return + + ! Define vars with nopts as a dimension. Point location and name + ncerr = nf90_def_var(fh, VNAME_PTLOC, NF90_FLOAT, (/d_vsize, d_nopts/), v_ptloc) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_PTNME, NF90_CHAR, (/d_namelen, d_nopts/), v_ptnme) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_IPTINT, NF90_FLOAT, (/d_vsize, d_wghtlen, d_nopts/), v_iptint) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_PTIFAC, NF90_FLOAT, (/d_wghtlen, d_nopts/), v_ptifac) + if (nf90_err(ncerr) .ne. 0) return + + ! End of all variable definitions + ncerr = nf90_enddef(fh) + if (nf90_err(ncerr) .ne. 0) return + + !write variables to file + ncerr = nf90_put_var(fh, v_ptloc, PTLOC(:,1:NOPTS)) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_put_var(fh, v_ptnme, PTNME(1:NOPTS)) + if (nf90_err(ncerr) .ne. 0) return + + ncerr = nf90_put_var(fh, v_iptint, IPTINT(:,:,1:NOPTS)) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_put_var(fh, v_ptifac, PTIFAC(:,1:NOPTS)) + if (nf90_err(ncerr) .ne. 0) return + + ! Close the file. + ncerr = nf90_close(fh) + if (nf90_err(ncerr) .ne. 0) return + + ENDIF ! #ifdef W3_RTD DEALLOCATE( EquLon, EquLat, StdLon, StdLat, AnglPT ) From 4e3446027afd7a4f9bef437a5b0852a6f0999197 Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Wed, 4 Dec 2024 14:06:26 +0000 Subject: [PATCH 04/10] update for netcdf error function to be outside of bin2nc and only write the file if it's processor 1 --- model/src/w3iopomd.F90 | 84 ++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 45 deletions(-) diff --git a/model/src/w3iopomd.F90 b/model/src/w3iopomd.F90 index 420991ddd..671e6e31a 100644 --- a/model/src/w3iopomd.F90 +++ b/model/src/w3iopomd.F90 @@ -536,13 +536,6 @@ SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD ) ! END DO ! End loop over output points (IPT). ELSE - !READ from file - !open file - ! read NOPTS - ! READ PTLOC - ! READ IPTINT(2, 4, NOPTS) - ! READ PTIFAC(4, NOPOTS) - ! READ PTNME(NOPTS) ! Open the netCDF file. ncerr = nf90_open(filename, NF90_NOWRITE, fh) @@ -600,50 +593,51 @@ SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD ) ENDIF IF ( pnt_wght_write .AND. (NOPTS > 0) ) THEN + IF ( IAPROC .EQ. 1 ) THEN + ! Create the netCDF file. + ncerr = nf90_create(filename, NF90_NETCDF4, fh) + if (nf90_err(ncerr) .ne. 0) return - ! Create the netCDF file. - ncerr = nf90_create(filename, NF90_NETCDF4, fh) - if (nf90_err(ncerr) .ne. 0) return - - ! Define dimensions. - ncerr = nf90_def_dim(fh, DNAME_NOPTS, NOPTS, d_nopts) - if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_def_dim(fh, DNAME_NAMELEN, 40, d_namelen) - if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_def_dim(fh, DNAME_VSIZE, 2, d_vsize) - if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_def_dim(fh, DNAME_WGHTLEN, 4, d_wghtlen) - if (nf90_err(ncerr) .ne. 0) return + ! Define dimensions. + ncerr = nf90_def_dim(fh, DNAME_NOPTS, NOPTS, d_nopts) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_def_dim(fh, DNAME_NAMELEN, 40, d_namelen) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_def_dim(fh, DNAME_VSIZE, 2, d_vsize) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_def_dim(fh, DNAME_WGHTLEN, 4, d_wghtlen) + if (nf90_err(ncerr) .ne. 0) return - ! Define vars with nopts as a dimension. Point location and name - ncerr = nf90_def_var(fh, VNAME_PTLOC, NF90_FLOAT, (/d_vsize, d_nopts/), v_ptloc) - if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_def_var(fh, VNAME_PTNME, NF90_CHAR, (/d_namelen, d_nopts/), v_ptnme) - if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_def_var(fh, VNAME_IPTINT, NF90_FLOAT, (/d_vsize, d_wghtlen, d_nopts/), v_iptint) - if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_def_var(fh, VNAME_PTIFAC, NF90_FLOAT, (/d_wghtlen, d_nopts/), v_ptifac) - if (nf90_err(ncerr) .ne. 0) return + ! Define vars with nopts as a dimension. Point location and name + ncerr = nf90_def_var(fh, VNAME_PTLOC, NF90_FLOAT, (/d_vsize, d_nopts/), v_ptloc) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_PTNME, NF90_CHAR, (/d_namelen, d_nopts/), v_ptnme) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_IPTINT, NF90_FLOAT, (/d_vsize, d_wghtlen, d_nopts/), v_iptint) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_PTIFAC, NF90_FLOAT, (/d_wghtlen, d_nopts/), v_ptifac) + if (nf90_err(ncerr) .ne. 0) return - ! End of all variable definitions - ncerr = nf90_enddef(fh) - if (nf90_err(ncerr) .ne. 0) return + ! End of all variable definitions + ncerr = nf90_enddef(fh) + if (nf90_err(ncerr) .ne. 0) return - !write variables to file - ncerr = nf90_put_var(fh, v_ptloc, PTLOC(:,1:NOPTS)) - if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_put_var(fh, v_ptnme, PTNME(1:NOPTS)) - if (nf90_err(ncerr) .ne. 0) return + !write variables to file + ncerr = nf90_put_var(fh, v_ptloc, PTLOC(:,1:NOPTS)) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_put_var(fh, v_ptnme, PTNME(1:NOPTS)) + if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_put_var(fh, v_iptint, IPTINT(:,:,1:NOPTS)) - if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_put_var(fh, v_ptifac, PTIFAC(:,1:NOPTS)) - if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_put_var(fh, v_iptint, IPTINT(:,:,1:NOPTS)) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_put_var(fh, v_ptifac, PTIFAC(:,1:NOPTS)) + if (nf90_err(ncerr) .ne. 0) return - ! Close the file. - ncerr = nf90_close(fh) - if (nf90_err(ncerr) .ne. 0) return + ! Close the file. + ncerr = nf90_close(fh) + if (nf90_err(ncerr) .ne. 0) return + END IF ENDIF ! #ifdef W3_RTD @@ -1257,7 +1251,6 @@ SUBROUTINE W3IOPE ( A ) !/ END SUBROUTINE W3IOPE -#ifdef W3_BIN2NC !> Handle netCDF return code. !> !> @param errcode NetCDF error code. 0 for no error. @@ -1279,6 +1272,7 @@ integer function nf90_err_check(errcode, ILINE) return endif end function nf90_err_check +#ifdef W3_BIN2NC !> Read point output in netCDF format. !> From 1289334ceeee4aebc87a1fb35d66aa3f5934b496 Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Wed, 4 Dec 2024 14:23:12 +0000 Subject: [PATCH 05/10] code clean up --- model/src/w3iopomd.F90 | 128 +++++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 63 deletions(-) diff --git a/model/src/w3iopomd.F90 b/model/src/w3iopomd.F90 index 671e6e31a..9fc644e1a 100644 --- a/model/src/w3iopomd.F90 +++ b/model/src/w3iopomd.F90 @@ -459,83 +459,84 @@ SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD ) ! Loop over output points if saved weights do not exist ! IF (.NOT. pnt_wght_exists) THEN - DO IPT=1, NPT - ! + DO IPT=1, NPT + ! #ifdef W3_T - WRITE (NDST,9010) IPT, XPT(IPT), YPT(IPT), PNAMES(IPT) + WRITE (NDST,9010) IPT, XPT(IPT), YPT(IPT), PNAMES(IPT) #endif - ! + ! #ifdef W3_RTD - !! Need to wrap rotated Elon values greater than X0. JGLi12Jun2012 - XPT(IPT) = MOD( EquLon(IPT)+360.0, 360.0 ) - IF( XPT(IPT) .LT. X0 ) XPT(IPT) = XPT(IPT) + 360.0 + !! Need to wrap rotated Elon values greater than X0. JGLi12Jun2012 + XPT(IPT) = MOD( EquLon(IPT)+360.0, 360.0 ) + IF( XPT(IPT) .LT. X0 ) XPT(IPT) = XPT(IPT) + 360.0 #endif - ! - ! Check if point within grid and compute interpolation weights - ! - IF (GTYPE .NE. UNGTYPE) THEN - INGRID = W3GRMP( GSU, XPT(IPT), YPT(IPT), IX, IY, RD ) - ELSE - CALL IS_IN_UNGRID(IMOD, DBLE(XPT(IPT)), DBLE(YPT(IPT)), itout, IX, IY, RD) - INGRID = (ITOUT.GT.0) - END IF - ! - IF ( .NOT.INGRID ) THEN - IF ( IAPROC .EQ. NAPERR ) THEN - IF ( FLAGLL ) THEN - WRITE (NDSE,1000) XPT(IPT), YPT(IPT), PNAMES(IPT) - ELSE - WRITE (NDSE,1001) XPT(IPT), YPT(IPT), PNAMES(IPT) + ! + ! Check if point within grid and compute interpolation weights + ! + IF (GTYPE .NE. UNGTYPE) THEN + INGRID = W3GRMP( GSU, XPT(IPT), YPT(IPT), IX, IY, RD ) + ELSE + CALL IS_IN_UNGRID(IMOD, DBLE(XPT(IPT)), DBLE(YPT(IPT)), itout, IX, IY, RD) + INGRID = (ITOUT.GT.0) + END IF + ! + IF ( .NOT.INGRID ) THEN + IF ( IAPROC .EQ. NAPERR ) THEN + IF ( FLAGLL ) THEN + WRITE (NDSE,1000) XPT(IPT), YPT(IPT), PNAMES(IPT) + ELSE + WRITE (NDSE,1001) XPT(IPT), YPT(IPT), PNAMES(IPT) + END IF END IF + CYCLE END IF - CYCLE - END IF - ! + ! #ifdef W3_T - DO K = 1,4 - WRITE (NDST,9012) IX(K), IY(K), RD(K) - END DO + DO K = 1,4 + WRITE (NDST,9012) IX(K), IY(K), RD(K) + END DO #endif - ! - ! Check if point not on land - ! - IF ( MAPSTA(IY(1),IX(1)) .EQ. 0 .AND. & - MAPSTA(IY(2),IX(2)) .EQ. 0 .AND. & - MAPSTA(IY(3),IX(3)) .EQ. 0 .AND. & - MAPSTA(IY(4),IX(4)) .EQ. 0 ) THEN - IF ( IAPROC .EQ. NAPERR ) THEN - IF ( FLAGLL ) THEN - WRITE (NDSE,1002) XPT(IPT), YPT(IPT), PNAMES(IPT) - ELSE - WRITE (NDSE,1003) XPT(IPT), YPT(IPT), PNAMES(IPT) + ! + ! Check if point not on land + ! + IF ( MAPSTA(IY(1),IX(1)) .EQ. 0 .AND. & + MAPSTA(IY(2),IX(2)) .EQ. 0 .AND. & + MAPSTA(IY(3),IX(3)) .EQ. 0 .AND. & + MAPSTA(IY(4),IX(4)) .EQ. 0 ) THEN + IF ( IAPROC .EQ. NAPERR ) THEN + IF ( FLAGLL ) THEN + WRITE (NDSE,1002) XPT(IPT), YPT(IPT), PNAMES(IPT) + ELSE + WRITE (NDSE,1003) XPT(IPT), YPT(IPT), PNAMES(IPT) + END IF END IF + CYCLE END IF - CYCLE - END IF - ! - ! Store interpolation data - ! - NOPTS = NOPTS + 1 - ! - PTLOC (1,NOPTS) = XPT(IPT) - PTLOC (2,NOPTS) = YPT(IPT) + ! + ! Store interpolation data + ! + NOPTS = NOPTS + 1 + ! + PTLOC (1,NOPTS) = XPT(IPT) + PTLOC (2,NOPTS) = YPT(IPT) #ifdef W3_RTD - !! Store the standard lon/lat in PTLOC for output purpose, assuming - !! they are not used for any inside calculation. JGLi12Jun2012 - PTLOC (1,NOPTS) = StdLon(IPT) - PTLOC (2,NOPTS) = StdLat(IPT) + !! Store the standard lon/lat in PTLOC for output purpose, assuming + !! they are not used for any inside calculation. JGLi12Jun2012 + PTLOC (1,NOPTS) = StdLon(IPT) + PTLOC (2,NOPTS) = StdLat(IPT) #endif - ! - DO K = 1,4 - IPTINT(1,K,NOPTS) = IX(K) - IPTINT(2,K,NOPTS) = IY(K) - PTIFAC(K,NOPTS) = RD(K) - END DO + ! + DO K = 1,4 + IPTINT(1,K,NOPTS) = IX(K) + IPTINT(2,K,NOPTS) = IY(K) + PTIFAC(K,NOPTS) = RD(K) + END DO - PTNME(NOPTS) = PNAMES(IPT) - ! - END DO ! End loop over output points (IPT). + PTNME(NOPTS) = PNAMES(IPT) + ! + END DO ! End loop over output points (IPT). ELSE + ! Saved weight file exists, read weights from file ! Open the netCDF file. ncerr = nf90_open(filename, NF90_NOWRITE, fh) @@ -593,6 +594,7 @@ SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD ) ENDIF IF ( pnt_wght_write .AND. (NOPTS > 0) ) THEN + !Create a weights file if there are output points IF ( IAPROC .EQ. 1 ) THEN ! Create the netCDF file. ncerr = nf90_create(filename, NF90_NETCDF4, fh) From a837fc034d02f869d33a80c8b19990b82cca431d Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Wed, 4 Dec 2024 22:09:56 +0000 Subject: [PATCH 06/10] add MPI so that not all ranks are reading in weights --- model/src/w3initmd.F90 | 6 ++- model/src/w3iopomd.F90 | 116 +++++++++++++++++++++++------------------ model/src/wmiopomd.F90 | 4 +- 3 files changed, 73 insertions(+), 53 deletions(-) diff --git a/model/src/w3initmd.F90 b/model/src/w3initmd.F90 index 4badbcb1a..c8a74d3ab 100644 --- a/model/src/w3initmd.F90 +++ b/model/src/w3initmd.F90 @@ -1240,7 +1240,11 @@ SUBROUTINE W3INIT ( IMOD, IsMulti, FEXT, MDS, MTRACE, ODAT, FLGRD, FLGR2, FLGD, ! ! 4.d Preprocessing for point output. ! - IF ( FLOUT(2) ) CALL W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD ) +#ifdef W3_MPI + IF ( FLOUT(2) ) CALL W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD, MPI_COMM_WAVE ) +#else + IF ( FLOUT(2) ) CALL W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD, 1 ) +#endif #ifdef W3_PDLIB CALL DEALLOCATE_PDLIB_GLOBAL(IMOD) #endif diff --git a/model/src/w3iopomd.F90 b/model/src/w3iopomd.F90 index 9fc644e1a..669b2bd63 100644 --- a/model/src/w3iopomd.F90 +++ b/model/src/w3iopomd.F90 @@ -236,7 +236,7 @@ MODULE W3IOPOMD !> !> @author H. L. Tolman @date 02-Sep-2012 !> - SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD ) + SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD, MPI_COMM_IOPP ) !/ !/ +-----------------------------------+ !/ | WAVEWATCH III NOAA/NCEP | @@ -362,11 +362,14 @@ SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD ) USE W3GDATMD, ONLY: FILEXT ! IMPLICIT NONE +#ifdef W3_MPI + INCLUDE "mpif.h" +#endif !/ !/ ------------------------------------------------------------------- / !/ Parameter list !/ - INTEGER, INTENT(IN) :: NPT, IMOD + INTEGER, INTENT(IN) :: NPT, IMOD, MPI_COMM_IOPP REAL, INTENT(INOUT) :: XPT(NPT), YPT(NPT) CHARACTER(LEN=40),INTENT(IN) :: PNAMES(NPT) !/ @@ -408,7 +411,9 @@ SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD ) integer :: d_nopts, d_namelen, d_vsize, d_wghtlen integer :: d_nopts_len, d_vsize_len,d_namelen_len,d_wghtlen_len integer :: v_ptloc, v_ptnme, v_iptint, v_ptifac - +#ifdef W3_MPI + integer :: IERR_MPI +#endif !/ !/ ------------------------------------------------------------------- / !/ @@ -537,64 +542,75 @@ SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD ) END DO ! End loop over output points (IPT). ELSE ! Saved weight file exists, read weights from file + IF ( IAPROC .EQ. 1 ) THEN + ! Open the netCDF file. + ncerr = nf90_open(filename, NF90_NOWRITE, fh) + if (nf90_err(ncerr) .ne. 0) return - ! Open the netCDF file. - ncerr = nf90_open(filename, NF90_NOWRITE, fh) - if (nf90_err(ncerr) .ne. 0) return + ! Read the dimension information for NOPTS. + ncerr = nf90_inq_dimid(fh, DNAME_NOPTS, d_nopts) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_inquire_dimension(fh, d_nopts, len = d_nopts_len) + if (nf90_err(ncerr) .ne. 0) return + NOPTS=d_nopts_len - ! Read the dimension information for NOPTS. - ncerr = nf90_inq_dimid(fh, DNAME_NOPTS, d_nopts) - if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_inquire_dimension(fh, d_nopts, len = d_nopts_len) - if (nf90_err(ncerr) .ne. 0) return - NOPTS=d_nopts_len + ! Read the dimension information for VSIZE. + ncerr = nf90_inq_dimid(fh, DNAME_VSIZE, d_vsize) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_inquire_dimension(fh, d_vsize, len = d_vsize_len) + if (nf90_err(ncerr) .ne. 0) return - ! Read the dimension information for VSIZE. - ncerr = nf90_inq_dimid(fh, DNAME_VSIZE, d_vsize) - if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_inquire_dimension(fh, d_vsize, len = d_vsize_len) - if (nf90_err(ncerr) .ne. 0) return + ! Read the dimension information for NAMELEN. + ncerr = nf90_inq_dimid(fh, DNAME_NAMELEN, d_namelen) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_inquire_dimension(fh, d_namelen, len = d_namelen_len) + if (nf90_err(ncerr) .ne. 0) return - ! Read the dimension information for NAMELEN. - ncerr = nf90_inq_dimid(fh, DNAME_NAMELEN, d_namelen) - if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_inquire_dimension(fh, d_namelen, len = d_namelen_len) - if (nf90_err(ncerr) .ne. 0) return + ! Read the dimension information for WGHTLEN. + ncerr = nf90_inq_dimid(fh, DNAME_WGHTLEN, d_wghtlen) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_inquire_dimension(fh, d_wghtlen, len = d_wghtlen_len) + if (nf90_err(ncerr) .ne. 0) return - ! Read the dimension information for WGHTLEN. - ncerr = nf90_inq_dimid(fh, DNAME_WGHTLEN, d_wghtlen) - if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_inquire_dimension(fh, d_wghtlen, len = d_wghtlen_len) - if (nf90_err(ncerr) .ne. 0) return + ! Read vars + ncerr = nf90_inq_varid(fh, VNAME_PTLOC, v_ptloc) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_get_var(fh, v_ptloc, PTLOC, start = (/ 1, 1/), & + count = (/ d_vsize_len, d_nopts_len /)) + if (nf90_err(ncerr) .ne. 0) return - ! Read vars - ncerr = nf90_inq_varid(fh, VNAME_PTLOC, v_ptloc) - if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_get_var(fh, v_ptloc, PTLOC, start = (/ 1, 1/), & - count = (/ d_vsize_len, d_nopts_len /)) - if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_PTNME, v_ptnme) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_get_var(fh, v_ptnme, PTNME, start = (/ 1, 1/), & + count = (/ d_namelen_len, d_nopts_len /)) + if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_inq_varid(fh, VNAME_PTNME, v_ptnme) - if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_get_var(fh, v_ptnme, PTNME, start = (/ 1, 1/), & - count = (/ d_namelen_len, d_nopts_len /)) - if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_IPTINT, v_iptint) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_get_var(fh, v_iptint, IPTINT, start = (/ 1, 1/), & + count = (/ d_vsize_len, d_wghtlen_len, d_nopts_len /)) + if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_inq_varid(fh, VNAME_IPTINT, v_iptint) - if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_get_var(fh, v_iptint, IPTINT, start = (/ 1, 1/), & - count = (/ d_vsize_len, d_wghtlen_len, d_nopts_len /)) - if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_PTIFAC, v_ptifac) + if (nf90_err(ncerr) .ne. 0) return + ncerr = nf90_get_var(fh, v_ptifac, PTIFAC, start = (/ 1, 1/), & + count = (/ d_wghtlen_len, d_nopts_len /)) + if (nf90_err(ncerr) .ne. 0) return + END IF - ncerr = nf90_inq_varid(fh, VNAME_PTIFAC, v_ptifac) - if (nf90_err(ncerr) .ne. 0) return - ncerr = nf90_get_var(fh, v_ptifac, PTIFAC, start = (/ 1, 1/), & - count = (/ d_wghtlen_len, d_nopts_len /)) - if (nf90_err(ncerr) .ne. 0) return +#ifdef W3_MPI + ! Broadcast weight info to all MPI tasks: + CALL MPI_BCAST(NOPTS,1,MPI_INTEGER,IAPROC-1,MPI_COMM_IOPP,IERR_MPI) + CALL MPI_BCAST(PTNME,80,MPI_CHARACTER,IAPROC-1,MPI_COMM_IOPP,IERR_MPI) + CALL MPI_BCAST(PTLOC,40*NPT,MPI_REAL,0,MPI_COMM_IOPP,IERR_MPI) + CALL MPI_BCAST(IPTINT,2*4*NPT,MPI_REAL,0,MPI_COMM_IOPP,IERR_MPI) + CALL MPI_BCAST(PTIFAC,4*NPT,MPI_REAL,0,MPI_COMM_IOPP,IERR_MPI) + CALL MPI_Barrier(MPI_COMM_IOPP,IERR_MPI) +#endif + ENDIF !end if point weight file exists - ENDIF + !Create a weights file if there are output points: IF ( pnt_wght_write .AND. (NOPTS > 0) ) THEN - !Create a weights file if there are output points IF ( IAPROC .EQ. 1 ) THEN ! Create the netCDF file. ncerr = nf90_create(filename, NF90_NETCDF4, fh) diff --git a/model/src/wmiopomd.F90 b/model/src/wmiopomd.F90 index bce460483..1737e04bb 100644 --- a/model/src/wmiopomd.F90 +++ b/model/src/wmiopomd.F90 @@ -500,7 +500,7 @@ SUBROUTINE WMIOPP ( NPT, XPT, YPT, PNAMES ) #endif ! #ifdef W3_SHRD - CALL W3IOPP ( MDATAS(J)%NRUPTS, XP, YP, PN, J ) + CALL W3IOPP ( MDATAS(J)%NRUPTS, XP, YP, PN, J, 1) #endif ! ! 3.d.2 Distributed memory version @@ -535,7 +535,7 @@ SUBROUTINE WMIOPP ( NPT, XPT, YPT, PNAMES ) #endif ! #ifdef W3_MPI - CALL W3IOPP ( MDATAS(J)%NRUPTS, XP, YP, PN, J ) + CALL W3IOPP ( MDATAS(J)%NRUPTS, XP, YP, PN, J, MPI_COMM_MWAVE) #endif ! #ifdef W3_MPI From 45edee9e0ee3fff8012137cb59d03100243ca89b Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Fri, 6 Dec 2024 01:06:23 +0000 Subject: [PATCH 07/10] fix MPI issue --- model/src/w3iopomd.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/model/src/w3iopomd.F90 b/model/src/w3iopomd.F90 index 669b2bd63..c64183a86 100644 --- a/model/src/w3iopomd.F90 +++ b/model/src/w3iopomd.F90 @@ -541,6 +541,7 @@ SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD, MPI_COMM_IOPP ) ! END DO ! End loop over output points (IPT). ELSE + write(*,*) 'read points weight JDM' ! Saved weight file exists, read weights from file IF ( IAPROC .EQ. 1 ) THEN ! Open the netCDF file. @@ -597,12 +598,11 @@ SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD, MPI_COMM_IOPP ) count = (/ d_wghtlen_len, d_nopts_len /)) if (nf90_err(ncerr) .ne. 0) return END IF - #ifdef W3_MPI ! Broadcast weight info to all MPI tasks: CALL MPI_BCAST(NOPTS,1,MPI_INTEGER,IAPROC-1,MPI_COMM_IOPP,IERR_MPI) - CALL MPI_BCAST(PTNME,80,MPI_CHARACTER,IAPROC-1,MPI_COMM_IOPP,IERR_MPI) - CALL MPI_BCAST(PTLOC,40*NPT,MPI_REAL,0,MPI_COMM_IOPP,IERR_MPI) + CALL MPI_BCAST(PTNME,40*NPT,MPI_CHARACTER,IAPROC-1,MPI_COMM_IOPP,IERR_MPI) + CALL MPI_BCAST(PTLOC,2*NPT,MPI_REAL,0,MPI_COMM_IOPP,IERR_MPI) CALL MPI_BCAST(IPTINT,2*4*NPT,MPI_REAL,0,MPI_COMM_IOPP,IERR_MPI) CALL MPI_BCAST(PTIFAC,4*NPT,MPI_REAL,0,MPI_COMM_IOPP,IERR_MPI) CALL MPI_Barrier(MPI_COMM_IOPP,IERR_MPI) From 5435c9847ef6a884bfc52a01cd96f50df44f42ec Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Fri, 13 Dec 2024 13:54:30 +0000 Subject: [PATCH 08/10] minor white space changes to make merged develop->dev/ufs-weather-model easier --- model/src/w3gridmd.F90 | 2 +- model/src/w3initmd.F90 | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/model/src/w3gridmd.F90 b/model/src/w3gridmd.F90 index ecf2726a0..8bfc6521a 100644 --- a/model/src/w3gridmd.F90 +++ b/model/src/w3gridmd.F90 @@ -845,7 +845,7 @@ MODULE W3GRIDMD #ifdef W3_ST4 INTEGER :: SWELLFPAR, SDSISO, SDSBRFDF, SINTABLE,& TAUWBUG - REAL :: SDSBCHOICE + REAL :: SDSBCHOICE REAL :: ZWND, ALPHA0, Z0MAX, BETAMAX, SINTHP,& ZALP, Z0RAT, TAUWSHELTER, SWELLF, & SWELLF2,SWELLF3,SWELLF4, SWELLF5, & diff --git a/model/src/w3initmd.F90 b/model/src/w3initmd.F90 index c8a74d3ab..fbefffc84 100644 --- a/model/src/w3initmd.F90 +++ b/model/src/w3initmd.F90 @@ -658,7 +658,6 @@ SUBROUTINE W3INIT ( IMOD, IsMulti, FEXT, MDS, MTRACE, ODAT, FLGRD, FLGR2, FLGD, STOP ENDIF #endif - ! ! 1.c Open files without unpacking MDS ,,, ! From 1a8753a2359266f8d36db6ca86a4f249f58776a3 Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Fri, 13 Dec 2024 14:00:40 +0000 Subject: [PATCH 09/10] update to read pnt wght file in regtests --- regtests/bin/run_cmake_test | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/regtests/bin/run_cmake_test b/regtests/bin/run_cmake_test index 07ade5a8b..d7e05497b 100755 --- a/regtests/bin/run_cmake_test +++ b/regtests/bin/run_cmake_test @@ -1358,6 +1358,16 @@ fi done fi +# copy pnt weight files from input to work directory + pntwghtfile=`\ls $path_i/pnt_wght.*.nc 2>/dev/null` + if [ ! -z "$pntwghtfile" ]; then + for pntwghtnc in $pntwghtfile + do + cp $pntwghtnc . + echo "copying $pntwghtnc to $path_w" + done + fi + if [ $multi -ge 1 ] then prog=ww3_multi From 72d1d23f8150d5c2545a36bbf98d34db999a52ae Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Fri, 13 Dec 2024 17:25:07 +0000 Subject: [PATCH 10/10] remove debug comment --- model/src/w3iopomd.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/model/src/w3iopomd.F90 b/model/src/w3iopomd.F90 index c64183a86..fec758638 100644 --- a/model/src/w3iopomd.F90 +++ b/model/src/w3iopomd.F90 @@ -541,7 +541,6 @@ SUBROUTINE W3IOPP ( NPT, XPT, YPT, PNAMES, IMOD, MPI_COMM_IOPP ) ! END DO ! End loop over output points (IPT). ELSE - write(*,*) 'read points weight JDM' ! Saved weight file exists, read weights from file IF ( IAPROC .EQ. 1 ) THEN ! Open the netCDF file.