!/ ------------------------------------------------------------------- / PROGRAM WW3_SYSTRK !/ !/ +-----------------------------------+ !/ | WAVEWATCH III NOAA/NCEP | !/ | A. J. van der Westhuysen | !/ | Jeff Hanson | !/ | Eve-Marie Devaliere | !/ | FORTRAN 95 | !/ | Last update : 16-Jan-2017 | !/ +-----------------------------------+ !/ !/ 03-Feb-2012 : Origination, based on Matlab code ( version 4.05 ) !/ by Jeff Hanson & Eve-Marie Devaliere !/ 04-Jan-2013 : Inclusion in trunk ( version 4.08 ) !/ 29-Nov-2013 : Remove DOC control characters, !/ update MPI! to MPI/! (H.L. Tolman). ( version 4.15 ) !/ 11-Feb-2014 : Add NetCDF output option. Both NetCDF-3 and !/ NetCDF-4 are available. (B. Li). ( version 4.18 ) !/ 26-Sep-2016 : Optimization updates (A. van der Westhuysen) !/ ( version 5.15 ) !/ 20-Sep-2016 : Add support for unformatted partition file. !/ (S.Zieger BoM, Australia) ( version 5.16 ) !/ 20-Dec-2016 : Optimized search algorithms and !/ set functions. (S.Zieger) ( version 5.16 ) !/ !/ Copyright 2009-2013 National Weather Service (NWS), !/ National Oceanic and Atmospheric Administration. All rights !/ reserved. WAVEWATCH III is a trademark of the NWS. !/ No unauthorized use without permission. !/ USE W3STRKMD !/F90 USE W3TIMEMD, ONLY: TDIFF IMPLICIT NONE !/MPI !/MPI INCLUDE "mpif.h" ! ! 1. Purpose : ! ! Perform spatial and temporal tracking of wave systems, based ! on spectral partition (bulletin) output. ! ! 2. Method : ! ! This is a controller program. It reads the input parameter file ! ww3_systrk.inp and calls subroutine waveTracking_NWS_V2 to ! perform the actual tracking procedure. Write output (fields and ! point output). ! ! 3. Parameters : ! LOGICAL :: testout PARAMETER (testout = .FALSE.) CHARACTER :: filename*80, paramFile*32 REAL :: dirKnob, perKnob, hsKnob, wetPts, seedLat, & seedLon, dirTimeKnob, tpTimeKnob, tint REAL :: lonout(100), latout(100) !Increase dimension? INTEGER :: maxGroup, ntint, noutp !/F90 INTEGER :: CLKDT0(8),CLKDT1(8) !/F90 REAL :: CLKFEL TYPE(dat2d), POINTER :: wsdat(:) TYPE(timsys), POINTER :: sysA(:) INTEGER, POINTER :: maxSys(:) ! ! Local parameters. ! ---------------------------------------------------------------- ! intype Int input Type of input (0 = from memory; 1 = from file) ! tmax Int input Value of maxTs to apply (1 or 2, used for model coupling) ! tcur Int input Index of current time step (1 or 2, used for model coupling) ! ulimGroup Int input Upper limit of number of wave systems to output ! LOGICAL :: file_exists CHARACTER :: inpstr*72 INTEGER :: intype, tmax, tcur, maxI, maxJ INTEGER :: it, igrp, sysmatch, ind, ip INTEGER :: i, j, leng, ulimGroup REAL, ALLOCATABLE :: dum(:,:) !/TRKNC REAL, ALLOCATABLE :: dum2nc(:,:,:,:) !/TRKNC REAL, ALLOCATABLE :: hsprt_nc(:,:,:) !/TRKNC REAL, ALLOCATABLE :: tpprt_nc(:,:,:) !/TRKNC REAL, ALLOCATABLE :: dirprt_nc(:,:,:) !/TRKNC REAL, ALLOCATABLE :: longitude_nc(:),latitude_nc(:) !/TRKNC REAL, ALLOCATABLE :: lonprt_nc(:),latprt_nc(:) INTEGER NTIME_NC INTEGER :: outputType LOGICAL :: outputCheck1,outputCheck2 DOUBLE PRECISION :: date1, date2, tstart, tend REAL :: dlon, dlat, lonprt, latprt REAL :: dt REAL :: minlon, maxlon, minlat, maxlat INTEGER :: mxcwt, mycwt !/MPI INTEGER :: rank, nproc, ierr !/MPI CHARACTER :: rankstr*4 ! For point output (bilinear interpolation) REAL :: hsprt(10),tpprt(10),dirprt(10) REAL :: BL_hsprt(10),BR_hsprt(10),TR_hsprt(10),TL_hsprt(10), & BL_tpprt(10),BR_tpprt(10),TR_tpprt(10),TL_tpprt(10), & BL_dirprt(10),BR_dirprt(10),TR_dirprt(10),TL_dirprt(10) REAL :: BL_dirx,BR_dirx,TR_dirx,TL_dirx, & BL_diry,BR_diry,TR_diry,TL_diry REAL :: BL_lonprt,BR_lonprt,TR_lonprt,TL_lonprt, & BL_latprt,BR_latprt,TR_latprt,TL_latprt REAL :: t, u, BL_W, BR_W, TR_W, TL_W REAL :: PI PARAMETER (PI = 3.1416) ! ! 4. Subroutines used : ! ! waveTracking_NWS_V2 ! ! 5. Called by : ! ! None, stand-alone program. ! ! 6. Error messages : ! ! 7. Remarks : ! ! 8. Structure : ! ! Calls subroutine waveTracking_NWS_V2 in trackmd.95 - see that ! file for structure. ! ! 9. Switches : ! ! !/SHRD Switch for shared / distributed memory architecture. ! !/MPI Id. ! ! 10. Source code : ! !/ ------------------------------------------------------------------- / ! !/MPI/! Start of parallel region !/MPI CALL MPI_INIT(ierr) !/MPI !/MPI CALL MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) !/MPI CALL MPI_COMM_SIZE(MPI_COMM_WORLD, nproc, ierr) !/MPI ! Open log file !/MPI WRITE(rankstr,'(i4.4)') rank !/MPI OPEN(unit=20,file='sys_log'//rankstr//'.ww3',status='unknown') !/SHRD OPEN(unit=20,file='sys_log.ww3',status='unknown') ! Print code version !/MPI IF (rank.EQ.0) THEN WRITE(6,900) !/MPI END IF WRITE(20,900) 900 FORMAT (/15X,' *** WAVEWATCH III Wave system tracking *** '/ & 15X,'==============================================='/) ! Since this program reads the raw partitioning input from file, ! we set intype=1 or 2, and tmax and tcur to dummy values (not used). intype = 2 ! intype = 1 IF (intype.EQ.1) WRITE(6,*) & '*** WARNING: partRes format input used!' tmax = 0 tcur = 0 ! Read input parameter file !/MPI IF (rank.EQ.0) THEN INQUIRE(FILE='ww3_systrk.inp', EXIST=file_exists) IF (.NOT.file_exists) THEN WRITE(20,2000) WRITE(6,2000) CALL ABORT END IF OPEN(unit=10,file='ww3_systrk.inp',status='old') READ(10,'(A72)') inpstr DO WHILE (inpstr(1:1).EQ.'$') READ(10,'(A72)') inpstr END DO BACKSPACE(10) READ(10,*) filename READ(10,'(A72)') inpstr DO WHILE (inpstr(1:1).EQ.'$') READ(10,'(A72)') inpstr END DO BACKSPACE(10) READ(10,*) date1, date2, dt, ntint tstart = date1 + date2/1000000 READ(10,'(A72)') inpstr DO WHILE (inpstr(1:1).EQ.'$') READ(10,'(A72)') inpstr END DO BACKSPACE(10) READ(10,*) outputType !Check for correct outputType option: IF (outputType.EQ.1) THEN !ASCII output ELSEIF (outputType.EQ.3) THEN !NetCDF 3 - requrires !/TRKNC switch outputCheck1 = .TRUE. !/TRKNC outputCheck1 = .FALSE. IF(outputCheck1) THEN WRITE(6,993) STOP END IF ELSEIF (outputType.EQ.4) THEN !NetCDF 4 - requrires !/TRKNC and !/NC4 switch outputCheck1 = .TRUE. outputCheck2 = .TRUE. !/TRKNC outputCheck1 = .FALSE. !/NC4 outputCheck2 = .FALSE. IF(outputCheck1.OR.outputCheck2) THEN WRITE(6,994) STOP END IF ELSE !Not a valid outputType WRITE(6,995) outputType STOP ENDIF READ(10,'(A72)') inpstr DO WHILE (inpstr(1:1).EQ.'$') READ(10,'(A72)') inpstr END DO BACKSPACE(10) READ(10,*) minlon, maxlon, mxcwt READ(10,'(A72)') inpstr DO WHILE (inpstr(1:1).EQ.'$') READ(10,'(A72)') inpstr END DO BACKSPACE(10) READ(10,*) minlat, maxlat, mycwt READ(10,'(A72)') inpstr DO WHILE (inpstr(1:1).EQ.'$') READ(10,'(A72)') inpstr END DO BACKSPACE(10) READ(10,*) dirKnob, perKnob, hsKnob, wetPts, & dirTimeKnob, tpTimeKnob READ(10,'(A72)') inpstr DO WHILE (inpstr(1:1).EQ.'$') READ(10,'(A72)') inpstr END DO BACKSPACE(10) READ(10,*) seedLat, seedLon READ(10,'(A72)') inpstr DO WHILE (inpstr(1:1).EQ.'$') READ(10,'(A72)') inpstr END DO BACKSPACE(10) noutp = 1 lonout(:) = 9999. latout(:) = 9999. DO WHILE (.TRUE.) READ(10,*) lonout(noutp),latout(noutp) IF ((lonout(noutp).EQ.0.).AND.(latout(noutp).EQ.0.)) EXIT noutp = noutp + 1 END DO noutp = noutp - 1 CLOSE(10) WRITE(20,*) 'Raw partition file = ',filename WRITE(20,'(A,F15.6)') 'Start time = ',tstart WRITE(20,*) 'dt = ',dt WRITE(20,*) 'No. time levels = ',ntint WRITE(20,'(A,2F7.2)') 'Domain limits: Longitude =',minlon, maxlon WRITE(20,'(A,2F7.2)') ' Latitude =',minlat, maxlat WRITE(20,*) 'No. increments: Long, Lat =',mxcwt, mycwt WRITE(20,*) 'dirKnob, perKnob, hsKnob, wetPts, & dirTimeKnob, tpTimeKnob, seedLat, seedLon =' WRITE(20,'(8F6.2)') dirKnob, perKnob, hsKnob, wetPts, & dirTimeKnob, tpTimeKnob, seedLat, seedLon WRITE(20,*) 'No. output points =',noutp DO i = 1,noutp WRITE(20,*) lonout(i), latout(i) END DO INQUIRE(FILE=filename, EXIST=file_exists) IF (.NOT.file_exists) THEN WRITE(20,2200) filename WRITE(6,2200) filename CALL EXIT(1) END IF !/F90 CALL DATE_AND_TIME ( VALUES=CLKDT0 ) !/MPI END IF !/MPI/! MPI communication block !/MPI CALL MPI_BCAST(filename,80,MPI_CHARACTER,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(tstart,1,MPI_DOUBLE_PRECISION,0, & !/MPI MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(tend,1,MPI_DOUBLE_PRECISION,0, & !/MPI MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(dt,1,MPI_REAL,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(ntint,1,MPI_INTEGER,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(minlon,1,MPI_REAL,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(maxlon,1,MPI_REAL,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(minlat,1,MPI_REAL,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(maxlat,1,MPI_REAL,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(mxcwt,1,MPI_INTEGER,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(mycwt,1,MPI_INTEGER,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(dirKnob,1,MPI_REAL,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(perKnob,1,MPI_REAL,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(hsKnob,1,MPI_REAL,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(wetPts,1,MPI_REAL,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(dirTimeKnob,1,MPI_REAL,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(tpTimeKnob,1,MPI_REAL,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(seedLon,1,MPI_REAL,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(seedLat,1,MPI_REAL,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(noutp,1,MPI_INTEGER,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(lonout,100,MPI_REAL,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_BCAST(latout,100,MPI_REAL,0,MPI_COMM_WORLD,IERR) !/MPI CALL MPI_Barrier(MPI_COMM_WORLD,IERR) CALL waveTracking_NWS_V2 (intype ,tmax , & tcur ,filename , & tstart ,tend , & dt ,ntint , & minlon ,maxlon , & minlat ,maxlat , & mxcwt ,mycwt , & dirKnob , & perKnob ,hsKnob , & wetPts ,seedLat , & seedLon ,dirTimeKnob, & tpTimeKnob ,paramFile , & sysA ,wsdat , & maxSys ,maxGroup ) !/MPI IF (rank.EQ.0) THEN !/F90 CALL DATE_AND_TIME ( VALUES=CLKDT1 ) !/F90 CLKFEL = TDIFF ( CLKDT0,CLKDT1 ) !/F90 WRITE (6,998) CLKFEL WRITE (6,*) 'Final system output...' ! Set upper limit for wave systems to output (limited by AWIPS display) ulimGroup = 9 !-----Output systems as plain text---------------------------------------- maxI = SIZE(wsdat(1)%lon,1) maxJ = SIZE(wsdat(1)%lon,2) dlon = wsdat(1)%lon(2,2)-wsdat(1)%lon(1,1) dlat = wsdat(1)%lat(2,2)-wsdat(1)%lat(1,1) WRITE(20,*) 'dlon, dlat =',dlon,dlat !-----Final SYSTEM output: Coordinates OPEN(unit=21,file='sys_coord.ww3', status='unknown') WRITE(21,'(I6,69X,A)') maxJ,'Number of rows' WRITE(21,'(I6,69X,A)') maxI,'Number of cols' !/TRKNC ALLOCATE( longitude_nc(maxI) ) !/TRKNC ALLOCATE( latitude_nc(maxJ) ) WRITE(21,*) 'Longitude =' DO j = maxJ,1,-1 DO i = 1,maxI WRITE(21,'(F7.2)',ADVANCE='NO') wsdat(1)%lon(i,j) !/TRKNC longitude_nc(i)=wsdat(1)%lon(i,1) END DO WRITE(21,'(A)',ADVANCE='YES') '' END DO WRITE(21,*) 'Latitude = ' DO j = maxJ,1,-1 DO i = 1,maxI WRITE(21,'(F7.2)',ADVANCE='NO') wsdat(1)%lat(i,j) !/TRKNC latitude_nc(j)=wsdat(1)%lat(1,j) END DO WRITE(21,'(A)',ADVANCE='YES') '' END DO CLOSE(21) !-----Final SYSTEM output: hs IF(outputType == 1) THEN OPEN(unit=22,file='sys_hs.ww3', status='unknown') WRITE(22,'(I6,69X,A)') maxJ,'Number of rows' WRITE(22,'(I6,69X,A)') maxI,'Number of cols' ENDIF NTIME_NC=SIZE(sysA) ALLOCATE( dum(maxI,maxJ) ) !/TRKNC IF(outputType == 3 .OR. outputType == 4) THEN !/TRKNC ALLOCATE( dum2nc(maxI,maxJ,maxGroup,NTIME_NC) ) !/TRKNC ENDIF DO it = 1,SIZE(sysA) ! Loop through identified groups, limiting the output in file to ulimGroup IF(outputType == 1) THEN WRITE(22,'(F15.6,60x,A)') wsdat(it)%date,'Time' WRITE(22,'(I6,69x,A)') MIN(ulimGroup,maxGroup), & 'Tot number of systems' ENDIF DO igrp = 1,MIN(ulimGroup,maxGroup) dum(1:maxI,1:maxJ) = 9999.00 ! Find system with this group tag sysmatch = 1 DO WHILE (sysmatch.LE.maxSys(it)) IF (sysA(it)%sys(sysmatch)%grp.EQ.igrp) EXIT sysmatch = sysmatch+1 END DO IF (sysmatch.LE.maxSys(it)) THEN ! Match found: fill the output matrix with this data leng = sysA(it)%sys(sysmatch)%nPoints DO ind = 1, leng dum(sysA(it)%sys(sysmatch)%i(ind), & sysA(it)%sys(sysmatch)%j(ind)) = & sysA(it)%sys(sysmatch)%hs(ind) END DO ELSE leng = 0 END IF IF(outputType == 1) THEN WRITE(22,'(I6,69x,A)') igrp,'System number' WRITE(22,'(I6,69x,A)') leng,'Number of points in system' DO J = maxJ,1,-1 DO i = 1,maxI WRITE(22,'(F8.2)',ADVANCE='NO') dum(i,j) END DO WRITE(22,'(A)',ADVANCE='YES') '' END DO ELSE !/TRKNC DO J = maxJ,1,-1 !/TRKNC DO i = 1,maxI !/TRKNC dum2nc(i,j,igrp,it)=dum(i,j) !/TRKNC END DO !/TRKNC END DO ENDIF END DO END DO !/TRKNC IF(outputType == 3 .OR. outputType == 4 ) THEN !/TRKNC call t2netcdf(longitude_nc,latitude_nc,dum2nc,maxI,maxJ,& !/TRKNC maxGroup,date1,date2,dt,NTIME_NC,1,outputType) !/TRKNC ENDIF IF(outputType.EQ.1) CLOSE(22) !-----Final SYSTEM output: tp IF(outputType == 1) THEN OPEN(unit=23,file='sys_tp.ww3',status='unknown') WRITE(23,'(I6,69X,A)') maxJ,'Number of rows' WRITE(23,'(I6,69X,A)') maxI,'Number of cols' ENDIF DO it = 1,SIZE(sysA) ! Loop through identified groups, limiting the output in file to ulimGroup IF(outputType == 1) THEN WRITE(23,'(F15.6,60x,A)') wsdat(it)%date,'Time' WRITE(23,'(I6,69X,A)') MIN(ulimGroup,maxGroup), & 'Tot number of systems' ENDIF DO igrp = 1,MIN(ulimGroup,maxGroup) dum(1:maxI,1:maxJ) = 9999.00 ! Find system with this group tag sysmatch = 1 DO WHILE (sysmatch.LE.maxSys(it)) IF (sysA(it)%sys(sysmatch)%grp.EQ.igrp) EXIT sysmatch = sysmatch+1 END DO IF (sysmatch.LE.maxSys(it)) THEN ! Match found: fill the output matrix with this data leng = sysA(it)%sys(sysmatch)%nPoints DO ind = 1, leng dum(sysA(it)%sys(sysmatch)%i(ind), & sysA(it)%sys(sysmatch)%j(ind)) = & sysA(it)%sys(sysmatch)%tp(ind) END DO ELSE leng = 0 END IF IF(outputType == 1) THEN WRITE(23,'(I6,69X,A)') igrp,'System number' WRITE(23,'(I6,69X,A)') leng,'Number of points in system' DO J = maxJ,1,-1 DO i = 1,maxI WRITE(23,'(F8.2)',ADVANCE='NO') dum(i,j) END DO WRITE(23,'(A)',ADVANCE='YES') '' END DO ELSE !/TRKNC DO J = maxJ,1,-1 !/TRKNC DO i = 1,maxI !/TRKNC dum2nc(i,j,igrp,it)=dum(i,j) !/TRKNC END DO !/TRKNC END DO ENDIF END DO END DO !/TRKNC IF(outputType.EQ.3 .OR. outputType.EQ. 4 ) THEN !/TRKNC call t2netcdf(longitude_nc,latitude_nc,dum2nc,maxI,maxJ,& !/TRKNC maxGroup,date1,date2,dt,NTIME_NC,2,outputType) !/TRKNC ENDIF IF(outputType.EQ.1) CLOSE(23) !-----Final SYSTEM output: dir IF(outputType == 1) THEN OPEN(unit=24,file='sys_dir.ww3',status='unknown') WRITE(24,'(I6,69X,A)') maxJ,'Number of rows' WRITE(24,'(I6,69X,A)') maxI,'Number of cols' ENDIF DO it = 1,SIZE(sysA) ! Loop through identified groups, limiting the output in file to ! ulimGroup IF(outputType == 1) THEN WRITE(24,'(F15.6,60x,A)') wsdat(it)%date,'Time' WRITE(24,'(I6,69X,A)') MIN(ulimGroup,maxGroup), & 'Tot number of systems' ENDIF DO igrp = 1,MIN(ulimGroup,maxGroup) dum(1:maxI,1:maxJ) = 9999.00 ! Find system with this group tag sysmatch = 1 DO WHILE (sysmatch.LE.maxSys(it)) IF (sysA(it)%sys(sysmatch)%grp.EQ.igrp) EXIT sysmatch = sysmatch+1 END DO IF (sysmatch.LE.maxSys(it)) THEN ! Match found: fill the output matrix with this data leng = sysA(it)%sys(sysmatch)%nPoints DO ind = 1, leng dum(sysA(it)%sys(sysmatch)%i(ind), & sysA(it)%sys(sysmatch)%j(ind)) = & sysA(it)%sys(sysmatch)%dir(ind) END DO ELSE leng = 0 END IF IF(outputType == 1) THEN WRITE(24,'(I6,69X,A)') igrp,'System number' WRITE(24,'(I6,69X,A)') leng,'Number of points in system' DO J = maxJ,1,-1 DO i = 1,maxI WRITE(24,'(F8.2)',ADVANCE='NO') dum(i,j) END DO WRITE(24,'(A)',ADVANCE='YES') '' END DO ELSE !/TRKNC DO J = maxJ,1,-1 !/TRKNC DO i = 1,maxI !/TRKNC dum2nc(i,j,igrp,it)=dum(i,j) !/TRKNC END DO !/TRKNC END DO END IF END DO END DO !/TRKNC IF(outputType.EQ.3 .OR. outputType.EQ.4 ) THEN !/TRKNC call t2netcdf(longitude_nc,latitude_nc,dum2nc,maxI,maxJ,& !/TRKNC maxGroup,date1,date2,dt,NTIME_NC,3,outputType) !/TRKNC ENDIF IF(outputType.EQ.1) CLOSE(24) !-----Final SYSTEM output: dspr IF(outputType == 1) THEN OPEN(unit=25,file='sys_dspr.ww3',status='unknown') WRITE(25,'(I6,69X,A)') maxJ,'Number of rows' WRITE(25,'(I6,69X,A)') maxI,'Number of cols' ENDIF DO it = 1,SIZE(sysA) ! Loop through identified groups, limiting the output in file to ulimGroup IF(outputType == 1) THEN WRITE(25,'(F15.6,60x,A)') wsdat(it)%date,'Time' WRITE(25,'(I6,69X,A)') MIN(ulimGroup,maxGroup), & 'Tot number of systems' ENDIF DO igrp = 1,MIN(ulimGroup,maxGroup) dum(1:maxI,1:maxJ) = 9999.00 ! Find system with this group tag sysmatch = 1 DO WHILE (sysmatch.LE.maxSys(it)) IF (sysA(it)%sys(sysmatch)%grp.EQ.igrp) EXIT sysmatch = sysmatch+1 END DO IF (sysmatch.LE.maxSys(it)) THEN ! Match found: fill the output matrix with this data leng = sysA(it)%sys(sysmatch)%nPoints DO ind = 1, leng dum(sysA(it)%sys(sysmatch)%i(ind), & sysA(it)%sys(sysmatch)%j(ind)) = & sysA(it)%sys(sysmatch)%dspr(ind) END DO ELSE leng = 0 END IF IF(outputType == 1) THEN WRITE(25,'(I6,69X,A)') igrp,'System number' WRITE(25,'(I6,69X,A)') leng,'Number of points in system' DO J = maxJ,1,-1 DO i = 1,maxI WRITE(25,'(F8.2)',ADVANCE='NO') dum(i,j) END DO WRITE(25,'(A)',ADVANCE='YES') '' END DO ELSE !/TRKNC DO J = maxJ,1,-1 !/TRKNC DO i = 1,maxI !/TRKNC dum2nc(i,j,igrp,it)=dum(i,j) !/TRKNC END DO !/TRKNC END DO ENDIF END DO END DO !/TRKNC IF(outputType.EQ.3 .OR. outputType.EQ.4 ) THEN !/TRKNC call t2netcdf(longitude_nc,latitude_nc,dum2nc,maxI,maxJ,& !/TRKNC maxGroup,date1,date2,dt,NTIME_NC,4,outputType) !/TRKNC ENDIF IF(outputType.EQ.1) CLOSE(25) IF (ALLOCATED(DUM)) DEALLOCATE(dum) !/TRKNC IF (ALLOCATED(dum2nc)) DEALLOCATE(dum2nc) !/TRKNC IF(outputType.EQ.3.OR.outputType.EQ.4) THEN !/TRKNC ALLOCATE( hsprt_nc(10,noutp,NTIME_NC) ) !/TRKNC ALLOCATE( tpprt_nc(10,noutp,NTIME_NC) ) !/TRKNC ALLOCATE( dirprt_nc(10,noutp,NTIME_NC) ) !/TRKNC ALLOCATE( lonprt_nc(noutp) ) !/TRKNC ALLOCATE( latprt_nc(noutp) ) !/TRKNC ENDIF !-----Final SYSTEM output: point output IF(outputType == 1) THEN OPEN(unit=26,file='sys_pnt.ww3',status='unknown') WRITE(26,'(A)') '%' WRITE(26,'(A)') '%' WRITE(26,'(A)') '% WW3 Wave tracking point output' WRITE(26,'(A)') '%' WRITE(26,'(10A)') '% Xp Yp ', & 'HsSY01 HsSY02 HsSY03 HsSY04 ', & 'HsSY05 HsSY06 HsSY07 HsSY08 ', & 'HsSY09 HsSY10 ', & 'TpSY01 TpSY02 TpSY03 TpSY04 ', & 'TpSY05 TpSY06 TpSY07 TpSY08 ', & 'TpSY09 TpSY10 ', & 'DrSY01 DrSY02 DrSY03 DrSY04 ', & 'DrSY05 DrSY06 DrSY07 DrSY08 ', & 'DrSY09 DrSY10' WRITE(26,'(10A)') '% [degr] [degr] ', & '[m] [m] [m] [m] ', & '[m] [m] [m] [m] ', & '[m] [m] ', & '[sec] [sec] [sec] [sec] ', & '[sec] [sec] [sec] [sec] ', & '[sec] [sec] ', & '[degr] [degr] [degr] [degr] ', & '[degr] [degr] [degr] [degr] ', & '[degr] [degr]' WRITE(26,'(A)') '%' ENDIF DO it = 1,SIZE(sysA) IF(outputType == 1) THEN WRITE(26,'(A,F15.6)') 'Time : ',wsdat(it)%date ENDIF DO ip = 1,noutp hsprt(1:10) = 999.9999 tpprt(1:10) = 999.9999 dirprt(1:10) = 999.9999 lonprt = 999.9999 latprt = 999.9999 BL_hsprt(1:10) = 999.9999 BL_tpprt(1:10) = 999.9999 BL_dirprt(1:10) = 999.9999 BR_hsprt(1:10) = 999.9999 BR_tpprt(1:10) = 999.9999 BR_dirprt(1:10) = 999.9999 TL_hsprt(1:10) = 999.9999 TL_tpprt(1:10) = 999.9999 TL_dirprt(1:10) = 999.9999 TR_hsprt(1:10) = 999.9999 TR_tpprt(1:10) = 999.9999 TR_dirprt(1:10) = 999.9999 BL_lonprt = 999.9999 BL_latprt = 999.9999 BR_lonprt = 999.9999 BR_latprt = 999.9999 TL_lonprt = 999.9999 TL_latprt = 999.9999 TR_lonprt = 999.9999 TR_latprt = 999.9999 BL_W = 999 BR_W = 999 TR_W = 999 TL_W = 999 DO j = 1, (maxJ-1) DO i = 1, (maxI-1) IF ( ( ((lonout(ip).GE. & wsdat(1)%lon(i,j)).AND. & (lonout(ip).LT. & wsdat(1)%lon(i+1,j))).OR. & ((lonout(ip).GT. & wsdat(1)%lon(i,j)).AND. & (lonout(ip).LE. & wsdat(1)%lon(i+1,j))) ).AND. & ( ((latout(ip).GE. & wsdat(1)%lat(i,j)).AND. & (latout(ip).LT. & wsdat(1)%lat(i,j+1))).OR. & ((latout(ip).GT. & wsdat(1)%lat(i,j)).AND. & (latout(ip).LE. & wsdat(1)%lat(i,j+1))) ) ) & THEN BL_lonprt = wsdat(1)%lon(i,j) BL_latprt = wsdat(1)%lat(i,j) BR_lonprt = wsdat(1)%lon(i+1,j) BR_latprt = wsdat(1)%lat(i+1,j) TL_lonprt = wsdat(1)%lon(i,j+1) TL_latprt = wsdat(1)%lat(i,j+1) TR_lonprt = wsdat(1)%lon(i+1,j+1) TR_latprt = wsdat(1)%lat(i+1,j+1) ! Compute weights for this point t = (lonout(ip)-BL_lonprt)/(BR_lonprt-BL_lonprt) u = (latout(ip)-BL_latprt)/(TL_latprt-BL_latprt) BL_W = (1-t)*(1-u) BR_W = t*(1-u) TR_W = t*u TL_W = (1-t)*u ! Compute output values using weights lonprt = BL_W*BL_lonprt + BR_W*BR_lonprt + & TL_W*TL_lonprt + TR_W*TR_lonprt latprt = BL_W*BL_latprt + BR_W*BR_latprt + & TL_W*TL_latprt + TR_W*TR_latprt END IF END DO END DO ! Loop through identified groups, limiting the output in file to 10 DO igrp = 1,MIN(10,maxGroup) ! Find system with this group tag sysmatch = 1 DO WHILE (sysmatch.LE.maxSys(it)) IF (sysA(it)%sys(sysmatch)%grp.EQ.igrp) EXIT sysmatch = sysmatch+1 END DO IF (sysmatch.LE.maxSys(it)) THEN ! Match found: fill the output matrix with this data leng = sysA(it)%sys(sysmatch)%nPoints DO ind = 1, leng ! Write output point data with bilinear interpolation IF ( (sysA(it)%sys(sysmatch)%lon(ind).EQ.& BL_lonprt).AND.& (sysA(it)%sys(sysmatch)%lat(ind).EQ.& BL_latprt) ) THEN BL_hsprt(igrp) = sysA(it)%sys(sysmatch)%hs(ind) BL_tpprt(igrp) = sysA(it)%sys(sysmatch)%tp(ind) BL_dirprt(igrp) = sysA(it)%sys(sysmatch)%dir(ind) ELSE IF ( (sysA(it)%sys(sysmatch)%lon(ind).EQ.& BR_lonprt).AND.& (sysA(it)%sys(sysmatch)%lat(ind).EQ.& BR_latprt)) THEN BR_hsprt(igrp) = sysA(it)%sys(sysmatch)%hs(ind) BR_tpprt(igrp) = sysA(it)%sys(sysmatch)%tp(ind) BR_dirprt(igrp) = sysA(it)%sys(sysmatch)%dir(ind) ELSE IF ( (sysA(it)%sys(sysmatch)%lon(ind).EQ.& TL_lonprt).AND.& (sysA(it)%sys(sysmatch)%lat(ind).EQ.& TL_latprt)) THEN TL_hsprt(igrp) = sysA(it)%sys(sysmatch)%hs(ind) TL_tpprt(igrp) = sysA(it)%sys(sysmatch)%tp(ind) TL_dirprt(igrp) = sysA(it)%sys(sysmatch)%dir(ind) ELSE IF ( (sysA(it)%sys(sysmatch)%lon(ind).EQ.& TR_lonprt).AND.& (sysA(it)%sys(sysmatch)%lat(ind).EQ.& TR_latprt)) THEN TR_hsprt(igrp) = sysA(it)%sys(sysmatch)%hs(ind) TR_tpprt(igrp) = sysA(it)%sys(sysmatch)%tp(ind) TR_dirprt(igrp) = sysA(it)%sys(sysmatch)%dir(ind) END IF END DO ! Compute output value using weights ! (only if output point is surrounded by valid points) IF ( (BL_hsprt(igrp).NE.999.9999).AND. & (BR_hsprt(igrp).NE.999.9999).AND. & (TL_hsprt(igrp).NE.999.9999).AND. & (TR_hsprt(igrp).NE.999.9999) ) THEN hsprt(igrp) = BL_W * BL_hsprt(igrp) + & BR_W * BR_hsprt(igrp) + & TL_W * TL_hsprt(igrp) + & TR_W * TR_hsprt(igrp) tpprt(igrp) = BL_W * BL_tpprt(igrp) + & BR_W * BR_tpprt(igrp) + & TL_W * TL_tpprt(igrp) + & TR_W * TR_tpprt(igrp) BL_dirx = COS((270-BL_dirprt(igrp))*PI/180.) BR_dirx = COS((270-BR_dirprt(igrp))*PI/180.) TR_dirx = COS((270-TR_dirprt(igrp))*PI/180.) TL_dirx = COS((270-TL_dirprt(igrp))*PI/180.) BL_diry = SIN((270-BL_dirprt(igrp))*PI/180.) BR_diry = SIN((270-BR_dirprt(igrp))*PI/180.) TR_diry = SIN((270-TR_dirprt(igrp))*PI/180.) TL_diry = SIN((270-TL_dirprt(igrp))*PI/180.) dirprt(igrp)=270 - 180./PI* & ATAN2(BL_W*BL_diry+BR_W*BR_diry+ & TL_W*TL_diry+TR_W*TR_diry, & BL_W*BL_dirx+BR_W*BR_dirx+ & TL_W*TL_dirx+TR_W*TR_dirx) IF (dirprt(igrp).GT.360.) THEN dirprt(igrp) = dirprt(igrp) - 360. END IF ELSE hsprt(igrp) = 999.9999 tpprt(igrp) = 999.9999 dirprt(igrp) = 999.9999 END IF END IF END DO IF(outputType == 1) THEN WRITE(26,'(32F14.4)') lonprt,latprt, & hsprt(1:10),tpprt(1:10),dirprt(1:10) ENDIF !/TRKNC IF(outputType.EQ.3.OR.outputType.EQ.4) THEN !/TRKNC lonprt_nc(ip)=lonprt !/TRKNC latprt_nc(ip)=latprt !/TRKNC do igrp=1,10 !/TRKNC hsprt_nc(igrp,ip,it)=hsprt(igrp) !/TRKNC tpprt_nc(igrp,ip,it)=tpprt(igrp) !/TRKNC dirprt_nc(igrp,ip,it)=dirprt(igrp) !/TRKNC enddo !/TRKNC ENDIF END DO END DO !/TRKNC IF(outputType.EQ.3.OR.outputType.EQ.4) THEN !/TRKNC call pt2netcdf(lonprt_nc,latprt_nc,hsprt_nc,tpprt_nc, & !/TRKNC dirprt_nc,noutp,date1,date2,dt,NTIME_NC,outputType) !/TRKNC ENDIF IF(outputType.EQ.1) CLOSE(26) !-----Final SYSTEM output: point output (Nearest neighbor, as a double check) IF (testout) THEN OPEN(unit=28,file='sys_pnt_nn.ww3',status='unknown') WRITE(28,'(A)') '%' WRITE(28,'(A)') '%' WRITE(28,'(A)') '% WW3 Wave tracking point output' WRITE(28,'(A)') '%' WRITE(28,'(10A)') '% Xp Yp ', & 'HsSY01 HsSY02 HsSY03 HsSY04 ', & 'HsSY05 HsSY06 HsSY07 HsSY08 ', & 'HsSY09 HsSY10 ', & 'TpSY01 TpSY02 TpSY03 TpSY04 ', & 'TpSY05 TpSY06 TpSY07 TpSY08 ', & 'TpSY09 TpSY10 ', & 'DrSY01 DrSY02 DrSY03 DrSY04 ', & 'DrSY05 DrSY06 DrSY07 DrSY08 ', & 'DrSY09 DrSY10' WRITE(28,'(10A)') '% [degr] [degr] ', & '[m] [m] [m] [m] ', & '[m] [m] [m] [m] ', & '[m] [m] ', & '[sec] [sec] [sec] [sec] ', & '[sec] [sec] [sec] [sec] ', & '[sec] [sec] ', & '[degr] [degr] [degr] [degr] ', & '[degr] [degr] [degr] [degr] ', & '[degr] [degr]' WRITE(28,'(A)') '%' DO it = 1,SIZE(sysA) WRITE(28,'(A,F15.6)') 'Time : ',wsdat(it)%date DO ip = 1,noutp hsprt(1:10) = 999.9999 tpprt(1:10) = 999.9999 dirprt(1:10) = 999.9999 lonprt = 999.9999 latprt = 999.9999 DO j = 1, maxJ DO i = 1, maxI ! Write nearest nearbor output (no bilinear interpolation) IF ( (lonout(ip).GE. & (wsdat(1)%lon(i,j)-dlon/2)).AND. & (lonout(ip).LT. & (wsdat(1)%lon(i,j)+dlon/2)).AND. & (latout(ip).GE. & (wsdat(1)%lat(i,j)-dlat/2)).AND. & (latout(ip).LT. & (wsdat(1)%lat(i,j)+dlat/2)) ) & THEN lonprt = wsdat(1)%lon(i,j) latprt = wsdat(1)%lat(i,j) END IF END DO END DO ! Loop through identified groups, limiting the output in file to 10 DO igrp = 1,MIN(10,maxGroup) ! Find system with this group tag sysmatch = 1 DO WHILE (sysmatch.LE.maxSys(it)) IF (sysA(it)%sys(sysmatch)%grp.EQ.igrp) EXIT sysmatch = sysmatch+1 END DO IF (sysmatch.LE.maxSys(it)) THEN ! Match found: fill the output matrix with this data leng = sysA(it)%sys(sysmatch)%nPoints DO ind = 1, leng ! Write nearest nearbor output (no bilinear interpolation) IF ( (lonout(ip).GE. & (sysA(it)%sys(sysmatch)%lon(ind)-dlon/2)).AND. & (lonout(ip).LT. & (sysA(it)%sys(sysmatch)%lon(ind)+dlon/2)).AND. & (latout(ip).GE. & (sysA(it)%sys(sysmatch)%lat(ind)-dlat/2)).AND. & (latout(ip).LT. & (sysA(it)%sys(sysmatch)%lat(ind)+dlat/2)) ) & THEN hsprt(igrp) = sysA(it)%sys(sysmatch)%hs(ind) tpprt(igrp) = sysA(it)%sys(sysmatch)%tp(ind) dirprt(igrp) = sysA(it)%sys(sysmatch)%dir(ind) END IF END DO END IF END DO WRITE(28,'(32F14.4)') lonprt,latprt, & hsprt(1:10),tpprt(1:10),dirprt(1:10) END DO END DO CLOSE(28) END IF !------------------------------------------------------------------------- WRITE(20,*) 'In ww3_systrk: Deallocating wsdat ...' DO it=1,size(wsdat) IF (ASSOCIATED(wsdat(it)%lat)) DEALLOCATE(wsdat(it)%lat) IF (ASSOCIATED(wsdat(it)%lon)) DEALLOCATE(wsdat(it)%lon) IF (ASSOCIATED(wsdat(it)%par)) DEALLOCATE(wsdat(it)%par) IF (ASSOCIATED(wsdat(it)%wnd)) DEALLOCATE(wsdat(it)%wnd) END DO IF (ASSOCIATED(wsdat)) DEALLOCATE(wsdat) WRITE(20,*) ' Deallocating sysA ...' DO i=1,size(sysA) DO j=1,size(sysA(i)%sys) IF (ASSOCIATED(sysA(i)%sys(j)%i)) DEALLOCATE(sysA(i)%sys(j)%i) IF (ASSOCIATED(sysA(i)%sys(j)%j)) DEALLOCATE(sysA(i)%sys(j)%j) IF (ASSOCIATED(sysA(i)%sys(j)%lon)) & DEALLOCATE(sysA(i)%sys(j)%lon) IF (ASSOCIATED(sysA(i)%sys(j)%lat)) & DEALLOCATE(sysA(i)%sys(j)%lat) IF (ASSOCIATED(sysA(i)%sys(j)%hs)) & DEALLOCATE(sysA(i)%sys(j)%hs) IF (ASSOCIATED(sysA(i)%sys(j)%tp)) & DEALLOCATE(sysA(i)%sys(j)%tp) IF (ASSOCIATED(sysA(i)%sys(j)%dir)) & DEALLOCATE(sysA(i)%sys(j)%dir) IF (ASSOCIATED(sysA(i)%sys(j)%dspr)) & DEALLOCATE(sysA(i)%sys(j)%dspr) END DO END DO IF (ASSOCIATED(sysA)) DEALLOCATE(sysA) WRITE(20,*) ' Deallocating maxSys ...' IF (ASSOCIATED(maxSys)) DEALLOCATE(maxSys) CLOSE(20) WRITE(6,*) '... ww3_systrk completed successfully.' WRITE(6,999) !/MPI END IF !/IF (rank.EQ.0) !/MPI CALL MPI_FINALIZE(IERR) !/MPI/! End of parallel region !/F90 998 FORMAT ( ' ... finished. Elapsed time : ',F10.2,' s') 993 FORMAT (/' *** WAVEWATCH III ERROR IN WW3_SYSTRK : '/ & ' OutputType=3 needs TRKNC switch ') 994 FORMAT (/' *** WAVEWATCH III ERROR IN WW3_SYSTRK : '/ & ' OutputType=4 needs TRKNC and NC4 switch ') 995 FORMAT (/' *** WAVEWATCH III ERROR IN WW3_SYSTRK : '/ & ' OutputType,',I3,'not valid. Options: 1,3,4') 999 FORMAT (/15X,'End of program '/ & 15X,'==============================================='/ & 15X,' *** WAVEWATCH III Wave system tracking *** ') 2000 FORMAT (/' *** WAVEWATCH III ERROR IN W3SYSTRK : '/ & ' ERROR IN OPENING INPUT FILE') 2200 FORMAT (/' *** WAVEWATCH III ERROR IN W3SYSTRK : '/ & ' ERROR IN OPENING PARTITION FILE : ',A) END PROGRAM WW3_SYSTRK ! !/TRKNC subroutine t2netcdf(lons,lats,data_in,nlons,nlats,nsys,date1,date2,& !/TRKNC dt,ntime,ivar, outputType) !/TRKNC USE W3TIMEMD !/TRKNC use netcdf !/TRKNC implicit none !/TRKNC character (len = 15) :: file_name !/TRKNC integer, parameter :: ndims = 4 !/TRKNC integer, parameter :: deflate = 1 !/TRKNC integer :: outputType, ncid, oldMode !/TRKNC integer :: nlons,nlats,nsys,rec,ntime,ivar !/TRKNC double precision :: date1,date2,timenc !/TRKNC real :: data_in(nlons, nlats, nsys,ntime) !/TRKNC real :: lats(nlats), lons(nlons),dt !/TRKNC double precision :: times(ntime) !/TRKNC integer :: iyc,imc,idc,ihc,iminc,isc,Jday,Jday0 !/TRKNC integer :: iret ! !/TRKNC integer :: lon_varid, lat_varid, rec_varid !/TRKNC character (len = *), parameter :: lsys_name = "system_index" !/TRKNC character (len = *), parameter :: lat_name = "latitude" !/TRKNC character (len = *), parameter :: lon_name = "longitude" !/TRKNC character (len = *), parameter :: time_name = "time" !/TRKNC integer :: sys_dimid, lon_dimid, lat_dimid, rec_dimid !/TRKNC integer :: start(ndims), count(ndims) ! !/TRKNC character (len = *), parameter :: var1_name="hs" !/TRKNC character (len = *), parameter :: var2_name="tp" !/TRKNC character (len = *), parameter :: var3_name="dir" !/TRKNC character (len = *), parameter :: var4_name="dspr" !/TRKNC integer :: var1_varid, var2_varid, var3_varid,var4_varid !/TRKNC integer :: dimids(ndims) ! !/TRKNC character (len = *), parameter :: units = "units" !/TRKNC character (len = *), parameter :: var1_units = "m" !/TRKNC character (len = *), parameter :: var2_units = "s" !/TRKNC character (len = *), parameter :: var3_units = "degrees" !/TRKNC character (len = *), parameter :: var4_units = "degrees" !/TRKNC character (len = *), parameter :: lat_units = "degrees_north" !/TRKNC character (len = *), parameter :: lon_units = "degrees_east" !/TRKNC iyc=date1/10000 !/TRKNC imc=(date1-iyc*10000)/100 !/TRKNC idc=int(date1-DBLE(iyc*10000)-DBLE(imc*100)) !/TRKNC ihc=date2/10000 !/TRKNC iminc=(date2-ihc*10000)/100 !/TRKNC isc=date2-ihc*10000-100*iminc !/TRKNC timenc=DBLE(julday(idc,imc,iyc))+(DBLE(ihc)+(DBLE(iminc)+ & !/TRKNC (DBLE(isc)/60.0D0))/60.0D0)/24.0D0 !/TRKNC Jday0=julday(1,1,1990) !/TRKNC timenc=timenc-Jday0 !/TRKNC do rec=1,ntime !/TRKNC times(rec)=timenc+DBLE( (rec-1)*dt)/3600.0D0/24.0D0 !/TRKNC enddo !/TRKNC if( ivar == 1) then !/TRKNC file_name = "sys_hs.ww3.nc" !/TRKNC else if( ivar == 2) then !/TRKNC file_name = "sys_tp.ww3.nc" !/TRKNC else if( ivar == 3) then !/TRKNC file_name = "sys_dir.ww3.nc" !/TRKNC else !/TRKNC file_name = "sys_dspr.ww3.nc" !/TRKNC endif ! !/TRKNC! create the netcdf file. !/TRKNC if (outputType.EQ.3) then !/TRKNC call check( nf90_create(file_name, NF90_CLOBBER, ncid) ) !/TRKNC endif !/NC4 if(outputType.EQ.4) call check( nf90_create(file_name,NF90_NETCDF4,ncid)) !/TRKNC call check ( nf90_set_fill(ncid,nf90_nofill,oldMode) ) !/TRKNC call check( nf90_def_dim(ncid, lsys_name, nsys, sys_dimid) ) !/TRKNC call check( nf90_def_dim(ncid, lat_name, nlats, lat_dimid) ) !/TRKNC call check( nf90_def_dim(ncid, lon_name, nlons, lon_dimid) ) !/TRKNC call check( nf90_def_dim(ncid, time_name, ntime, rec_dimid) ) !/TRKNC call check( nf90_def_var(ncid, lat_name, NF90_REAL, lat_dimid,lat_varid)) !/NC4 call check( nf90_def_var_deflate(ncid,lat_varid,1,1,deflate) ) !/TRKNC call check( nf90_def_var(ncid, lon_name, NF90_REAL, lon_dimid,lon_varid)) !/NC4 call check( nf90_def_var_deflate(ncid,lon_varid,1,1,deflate) ) !/TRKNC call check( nf90_def_var(ncid,time_name,NF90_DOUBLE,rec_dimid,rec_varid)) !/NC4 call check( nf90_def_var_deflate(ncid,rec_varid,1,1,deflate) ) ! !/TRKNC call check( nf90_put_att(ncid, lat_varid, units, lat_units) ) !/TRKNC call check( nf90_put_att(ncid, lat_varid, 'long_name', 'latitude') ) !/TRKNC call check( nf90_put_att(ncid, lat_varid, 'standard_name', 'latitude') ) !/TRKNC call check( nf90_put_att(ncid, lat_varid, 'axis','Y')) !/TRKNC call check( nf90_put_att(ncid, lon_varid, units, lon_units) ) !/TRKNC call check( nf90_put_att(ncid, lon_varid, 'long_name', 'longitude') ) !/TRKNC call check( nf90_put_att(ncid, lon_varid, 'standard_name', 'longitude') ) !/TRKNC call check( nf90_put_att(ncid, lon_varid, 'axis','X')) !/TRKNC call check(nf90_put_att(ncid,rec_varid,units,& !/TRKNC 'days since 1990-01-01 00:00:00')) !/TRKNC call check(nf90_put_att(ncid,rec_varid,'long_name','julian day (UT)')) !/TRKNC call check( nf90_put_att(ncid, rec_varid,'standard_name', 'time') ) !/TRKNC call check( nf90_put_att(ncid, rec_varid, 'conventions',& !/TRKNC 'relative julian day with decimal part (as part of the day)' ) ) !/TRKNC call check( nf90_put_att(ncid, rec_varid, 'axis','T')) ! !/TRKNC dimids = (/ lon_dimid, lat_dimid, sys_dimid, rec_dimid /) !/TRKNC if( ivar == 1) then !/TRKNC call check( nf90_def_var(ncid, var1_name, NF90_REAL, dimids,var1_varid) ) !/NC4 call check( nf90_def_var_deflate(ncid,var1_varid,1,1,deflate) ) !/TRKNC call check( nf90_put_att(ncid, var1_varid, units, var1_units) ) !/TRKNC call check( nf90_put_att(ncid, var1_varid,'long_name','significant_wave_height') ) !/TRKNC call check( nf90_put_att(ncid, var1_varid,'missing_value','9999.00')) !/TRKNC else if( ivar == 2) then !/TRKNC call check( nf90_def_var(ncid, var2_name, NF90_REAL, dimids, var2_varid) ) !/NC4 call check( nf90_def_var_deflate(ncid,var2_varid,1,1,deflate) ) !/TRKNC call check( nf90_put_att(ncid, var2_varid, units, var2_units) ) !/TRKNC call check( nf90_put_att(ncid, var2_varid,'long_name','peak_period') ) !/TRKNC call check( nf90_put_att(ncid, var2_varid,'missing_value','9999.00') ) !/TRKNC else if ( ivar ==3 ) then !/TRKNC call check( nf90_def_var(ncid, var3_name, NF90_REAL, dimids, var3_varid) ) !/NC4 call check( nf90_def_var_deflate(ncid,var3_varid,1,1,deflate) ) !/TRKNC call check( nf90_put_att(ncid, var3_varid, units, var3_units) ) !/TRKNC call check( nf90_put_att(ncid, var3_varid,'long_name','peak_direction') ) !/TRKNC call check( nf90_put_att(ncid, var3_varid,'missing_value','9999.00') ) !/TRKNC else !/TRKNC call check( nf90_def_var(ncid, var4_name, NF90_REAL, dimids, var4_varid) ) !/NC4 call check( nf90_def_var_deflate(ncid,var4_varid,1,1,deflate) ) !/TRKNC call check( nf90_put_att(ncid, var4_varid, units, var4_units) ) !/TRKNC call check( nf90_put_att(ncid,var4_varid,'long_name','directional_spread') ) !/TRKNC call check( nf90_put_att(ncid, var4_varid,'missing_value','9999.00') ) !/TRKNC endif !/TRKNC call check( nf90_enddef(ncid) ) ! !/TRKNC call check( nf90_put_var(ncid, lat_varid, lats) ) !/TRKNC call check( nf90_put_var(ncid, lon_varid, lons) ) !/TRKNC call check( nf90_put_var(ncid, rec_varid, times) ) ! !/TRKNC count = (/ nlons, nlats, nsys, ntime /) !/TRKNC start = (/ 1, 1, 1, 1 /) !/TRKNC if( ivar == 1) then !/TRKNC call check( nf90_put_var(ncid, var1_varid, data_in, start = start, & !/TRKNC count = count) ) !/TRKNC else if( ivar == 2) then !/TRKNC call check( nf90_put_var(ncid, var2_varid, data_in, start = start, & !/TRKNC count = count) ) !/TRKNC else if( ivar == 3) then !/TRKNC call check( nf90_put_var(ncid, var3_varid, data_in, start = start, & !/TRKNC count = count) ) !/TRKNC else !/TRKNC call check( nf90_put_var(ncid, var4_varid, data_in, start = start, & !/TRKNC count = count) ) !/TRKNC endif !/TRKNC call check( nf90_close(ncid) ) !/TRKNC end subroutine t2netcdf ! !/TRKNC subroutine check(status) !/TRKNC use netcdf !/TRKNC integer, intent ( in) :: status !/TRKNC if(status /= nf90_noerr) then !/TRKNC write(6,996) !/TRKNC 996 FORMAT (/' *** WAVEWATCH III ERROR IN WW3_SYSTRK:'/ & !/TRKNC 'netCDF error:') !/TRKNC print *, trim(nf90_strerror(status)) !/TRKNC stop "Stopped in netcdf output part" !/TRKNC endif !/TRKNC end subroutine check ! !/TRKNC subroutine pt2netcdf(longitude,latitude,hs,tp,& !/TRKNC dir,npoints,date1,date2,dt,ntime,outputType) !/TRKNC USE W3TIMEMD !/TRKNC use netcdf !/TRKNC implicit none !/TRKNC integer :: ntime,npoints,outputType !/TRKNC integer, parameter :: deflate = 1 !/TRKNC integer :: iret, oldMode !/TRKNC integer :: ncid !/TRKNC integer :: system_index_dim !/TRKNC integer :: point_dim,rec_dim !/TRKNC integer :: nsys !/TRKNC integer :: start(3), count(3) !/TRKNC parameter (nsys = 10) !/TRKNC integer :: latitude_id !/TRKNC integer :: longitude_id !/TRKNC integer :: time_id !/TRKNC integer :: hs_id !/TRKNC integer :: tp_id !/TRKNC integer :: dir_id !/TRKNC integer :: time_rank !/TRKNC integer :: hs_rank !/TRKNC integer :: tp_rank !/TRKNC integer :: dir_rank !/TRKNC parameter (time_rank = 1) !/TRKNC parameter (hs_rank = 3) !/TRKNC parameter (tp_rank = 3) !/TRKNC parameter (dir_rank = 3) ! !/TRKNC integer :: hs_dims(hs_rank) !/TRKNC integer :: tp_dims(tp_rank) !/TRKNC integer :: dir_dims(dir_rank) !/TRKNC real :: latitude(npoints),dt !/TRKNC real :: longitude(npoints) !/TRKNC real :: hs(nsys, npoints, ntime) !/TRKNC real :: tp(nsys, npoints, ntime) !/TRKNC real :: dir(nsys, npoints, ntime) !/TRKNC integer :: iyc,imc,idc,ihc,iminc,isc,Jday,Jday0,rec !/TRKNC double precision date1,date2,timenc !/TRKNC double precision times(ntime) ! !/TRKNC iyc=date1/10000 !/TRKNC imc=(date1-iyc*10000)/100 !/TRKNC idc=int(date1-DBLE(iyc*10000)-DBLE(imc*100)) !/TRKNC ihc=date2/10000 !/TRKNC iminc=(date2-ihc*10000)/100 !/TRKNC isc=date2-ihc*10000-100*iminc !/TRKNC timenc=DBLE(julday(idc,imc,iyc))+(DBLE(ihc)+(DBLE(iminc)+ & !/TRKNC (DBLE(isc)/60.0D0))/60.0D0)/24.0D0 !/TRKNC Jday0=julday(1,1,1990) !/TRKNC timenc=timenc-Jday0 !/TRKNC do rec=1,ntime !/TRKNC times(rec)=timenc+DBLE( (rec-1)*dt)/3600.0D0/24.0D0 !/TRKNC enddo ! !/TRKNC if(outputType.EQ.3) then !/TRKNC iret = nf90_create('sys_pnt.ww3.nc', NF90_CLOBBER, ncid) !/TRKNC endif !/TRKNC if (outputType.EQ.4) iret = nf90_create('sys_pnt.ww3.nc',NF90_NETCDF4, ncid) !/TRKNC call check(iret) !/TRKNC iret = nf90_set_fill(ncid,nf90_nofill,oldMode) !/TRKNC call check(iret) !/TRKNC! define dimensions !/TRKNC iret = nf90_def_dim(ncid, 'system_index', nsys, system_index_dim) !/TRKNC call check(iret) !/TRKNC iret = nf90_def_dim(ncid, 'point', npoints, point_dim) !/TRKNC call check(iret) !/TRKNC iret = nf90_def_dim(ncid, 'time', ntime, rec_dim) !/TRKNC call check(iret) !/TRKNC! define variables !/TRKNC iret = nf90_def_var(ncid, 'latitude', NF90_REAL, point_dim, & !/TRKNC latitude_id) !/TRKNC call check(iret) !/NC4 call check( nf90_def_var_deflate(ncid,latitude_id,1,1,deflate)) !/TRKNC iret = nf90_def_var(ncid, 'longitude', NF90_REAL, point_dim, & !/TRKNC longitude_id) !/TRKNC call check(iret) !/NC4 call check( nf90_def_var_deflate(ncid,longitude_id,1,1,deflate)) !/TRKNC iret = nf90_def_var(ncid, 'time', NF90_DOUBLE, rec_dim, & !/TRKNC time_id) !/TRKNC call check(iret) !/NC4 call check( nf90_def_var_deflate(ncid,time_id,1,1,deflate) ) !/TRKNC hs_dims(3) = rec_dim !/TRKNC hs_dims(2) = point_dim !/TRKNC hs_dims(1) = system_index_dim !/TRKNC iret = nf90_def_var(ncid, 'hs', NF90_REAL, & !/TRKNC hs_dims, hs_id) !/TRKNC call check(iret) !/NC4 call check( nf90_def_var_deflate(ncid,hs_id,1,1,deflate)) !/TRKNC tp_dims(3) = rec_dim !/TRKNC tp_dims(2) = point_dim !/TRKNC tp_dims(1) = system_index_dim !/TRKNC iret = nf90_def_var(ncid, 'tp', NF90_REAL, & !/TRKNC tp_dims, tp_id) !/TRKNC call check(iret) !/NC4 call check( nf90_def_var_deflate(ncid,tp_id,1,1,deflate)) !/TRKNC dir_dims(3) = rec_dim !/TRKNC dir_dims(2) = point_dim !/TRKNC dir_dims(1) = system_index_dim !/TRKNC iret = nf90_def_var(ncid, 'dir', NF90_REAL, & !/TRKNC dir_dims, dir_id) !/TRKNC call check(iret) !/NC4 call check( nf90_def_var_deflate(ncid,dir_id,1,1,deflate)) !/TRKNC! assign attributes !/TRKNC iret = nf90_put_att(ncid, latitude_id, 'units', 'degrees_north') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, latitude_id, 'long_name', 'latitude') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, latitude_id, 'standard_name', 'latitude') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, latitude_id, 'axis', 'Y') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, longitude_id, 'units', 'degrees_east') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, longitude_id,'long_name','longitude') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, longitude_id,'standard_name','longitude') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, longitude_id, 'axis', 'X') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, time_id, 'units', & !/TRKNC 'days since 1990-01-01 00:00:00') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, time_id, 'long_name','julian day(UT)') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, time_id, 'standard_name','time') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, time_id, 'conventions', & !/TRKNC 'relative julian day with decimal part (as part of the day)') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, time_id, 'axis', 'T') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, hs_id, 'units', 'm') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, hs_id,'long_name','significant_wave_height') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, hs_id, 'missing_value', & !/TRKNC '999.9999') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, tp_id, 'units', 's') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, tp_id,'long_name','peak_period') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, tp_id, 'missing_value', & !/TRKNC '999.9999') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, dir_id, 'units', 'degrees') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, dir_id,'long_name','peak_direction') !/TRKNC call check(iret) !/TRKNC iret = nf90_put_att(ncid, dir_id, 'missing_value',& !/TRKNC '999.9999') !/TRKNC call check(iret) !/TRKNC! leave define mode !/TRKNC iret = nf90_enddef(ncid) !/TRKNC call check(iret) !/TRKNC iret = nf90_put_var(ncid, latitude_id, latitude) !/TRKNC call check(iret) ! !/TRKNC iret = nf90_put_var(ncid, longitude_id, longitude) !/TRKNC call check(iret) ! !/TRKNC iret = nf90_put_var(ncid, time_id, times) !/TRKNC call check(iret) ! !/TRKNC start = (/ 1, 1, 1 /) !/TRKNC count = (/ nsys,npoints,ntime /) ! !/TRKNC iret = nf90_put_var(ncid, hs_id, hs,& !/TRKNC start = start, count = count ) !/TRKNC call check(iret) !/TRKNC iret = nf90_put_var(ncid, tp_id, tp, & !/TRKNC start = start, count = count ) !/TRKNC call check(iret) !/TRKNC iret = nf90_put_var(ncid, dir_id, dir,& !/TRKNC start = start, count = count ) !/TRKNC call check(iret) !/TRKNC iret = nf90_close(ncid) !/TRKNC call check(iret) !/TRKNC return !/TRKNC end subroutine pt2netcdf