123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- PROGRAM cdfmaxmoc
- !!---------------------------------------------------------------------------------------------------
- !! *** PROGRAM cdfmaxmoc ***
- !!
- !! ** Purpose : Compute the maximum of the overturning fonction from a file calculated by cdfmoc
- !!
- !! ** Method : maxovt 'ovtfile' latmin latmax depmin depmax
- !! return ovtmaximum and ovt minimum in the defined range.
- !! Also give location of those extrema
- !! works for Atlantic and Global MOC
- !!
- !! * history:
- !! July 2005 : original : J.M. Molines
- !! November : modified and adapted to cdf output R. Dussin.
- !!---------------------------------------------------------------------------------------------------
- !! $Rev: 319 $
- !! $Date: 2010-05-19 12:19:07 +0200 (Wed, 19 May 2010) $
- !! $Id: cdfmaxmoc.f90 319 2010-05-19 10:19:07Z dussin $
- !!--------------------------------------------------------------
- USE netcdf
- USE cdfio
- USE io_ezcdf
- IMPLICIT NONE
- !!
- INTEGER :: jj, jk, jt, jt_pos ! dummy loop index !LB
- INTEGER :: id_moc, id_lat_max, id_depthw_max, idd_t, idv_time, idf_out
- LOGICAL :: lfncout
- INTEGER :: npjglo, npk, nt ! size of the overturning !LB
- INTEGER :: narg, iargc, istatus ! line command stuff
- INTEGER :: jmin, jmax, kmin, kmax ! (latitude, depth) window where to look at extrema
- INTEGER :: imaxloc(3) ! temporary array to use with minloc/maxloc
- ! added to write in netcdf
- INTEGER :: kx=1, ky=1, kz=1 ! dims of netcdf output file
- INTEGER :: nboutput=6 ! number of values to write in cdf output
- INTEGER :: ncout, ierr ! for netcdf output
- INTEGER, DIMENSION(:), ALLOCATABLE :: ipk, id_varout
- !
- REAL(KIND=4), DIMENSION(:,:,:), ALLOCATABLE :: zomoc ! zonal MOC (1,npjglo,jpk)
- REAL(KIND=4), DIMENSION(:,:), ALLOCATABLE :: rlat ! latitude (1, npjglo)
- REAL(KIND=4), DIMENSION(:), ALLOCATABLE :: gdepw ! depth read in the header
- REAL(KIND=4), DIMENSION(:), ALLOCATABLE :: ovtmax
- INTEGER, DIMENSION(:), ALLOCATABLE :: jlatmax, kdmax
- CHARACTER(len=4) :: clatmin, clatmax
- REAL(KIND=4) :: rlatmin, rlatmax, depmin , depmax
- ! added to write in netcdf
- REAL(KIND=4), DIMENSION(:,:), ALLOCATABLE :: dumlon, dumlat
- REAL(KIND=4), DIMENSION (1) :: tim ! time counter
- TYPE(variable), DIMENSION(:), ALLOCATABLE :: typvar ! structure of output
- !
- CHARACTER(LEN=256) :: cdum, cfile, comment, cbasin, cvar, cdep, ctim, cv_dum
- CHARACTER(LEN=512) :: cd_out='.', cf_out
- REAL(4) :: ryear, rmon, rdt
- INTEGER :: idf_moc=0 , idv_moc=0
- ! * main program
- narg=iargc()
- IF (narg == 8) THEN
- CALL getarg(1,cfile)
- CALL getarg(2,cbasin)
- CALL getarg(3,cdum)
- READ(cdum,*) rlatmin
- CALL getarg(4,cdum)
- READ(cdum,*) rlatmax
- CALL getarg(5,cdum)
- READ(cdum,*) depmin
- CALL getarg(6,cdum)
- READ(cdum,*) depmax
- CALL getarg(7,cdum)
- READ(cdum,*) ryear
- CALL getarg(8,cd_out)
- ELSE
- PRINT *,' USAGE: cdfmaxmoc ''ovt_file.nc'' cbasin latmin latmax depmin depmax <year> <DIROUT>'
- PRINT *,' cbasin is one of atl glo inp ind or pac '
- PRINT *,' Output on standard output by default and maxmoc.nc '
- STOP
- ENDIF
- npjglo = getdim(cfile,'y')
- cdep='none'
- npk = getdim(cfile,'olevel',cdtrue=cdep,kstatus=istatus) !LB
- ctim='none'
- nt = getdim(cfile,'time', cdtrue=ctim,kstatus=istatus) !LB
- ALLOCATE ( zomoc (1,npjglo,npk) ,gdepw(npk), rlat(1,npjglo), ovtmax(nt), jlatmax(nt), kdmax(nt) )
- gdepw(:) = -getvar1d(cfile,'olevel',npk)
- rlat(:,:) = getvar(cfile,'nav_lat',1,1,npjglo)
- SELECT CASE (cbasin)
- CASE ('atl')
- cvar='zomsfatl'
- CASE ('glo')
- cvar='zomsfglo'
- CASE ('pac')
- cvar='zomsfpac'
- CASE ('inp')
- cvar='zomsfinp'
- CASE ('ind')
- cvar='zomsfind'
- CASE DEFAULT
- STOP 'basin not found'
- END SELECT
- ! look for jmin-jmax :
- DO jj=1, npjglo
- IF ( rlat(1,jj) <= rlatmin ) jmin = jj
- IF ( rlat(1,jj) <= rlatmax ) jmax = jj
- END DO
- ! look for kmin kmax
- DO jk=1,npk
- IF ( gdepw(jk) <= depmin ) kmin = jk
- IF ( gdepw(jk) <= depmax ) kmax = jk
- END DO
- DO jt = 1, nt !LB
- !PRINT *, ' * [cdfmaxmoc] jt = ', jt
- CALL GETVAR_3D(idf_moc, idv_moc, cfile, cvar, nt, jt, zomoc)
- ! look for max/min overturning
- ovtmax(jt) = MAXVAL(zomoc(1,jmin:jmax,kmin:kmax))
- ! find location of min/max
- !iminloc =MINLOC(zomoc(:,jmin:jmax,kmin:kmax))
- imaxloc =MAXLOC(zomoc(:,jmin:jmax,kmin:kmax))
- ! results from minloc/maxloc is relative to the sub -array given as arguments
- jlatmax(jt) = imaxloc(2)+jmin -1
- kdmax(jt) = imaxloc(3)+kmin -1
- END DO !LB nt
- WRITE( clatmin, '(i2.2)') INT(ABS(rlatmin))
- WRITE( clatmax, '(i2.2)') INT(ABS(rlatmax))
- IF ( rlatmin >= 0. ) THEN
- clatmin = '+'//trim(clatmin)//'N'
- ELSE
- clatmin = '-'//trim(clatmin)//'N'
- END IF
- IF ( rlatmax >= 0. ) THEN
- clatmax = '+'//trim(clatmax)//'N'
- ELSE
- clatmax = '-'//trim(clatmax)//'N'
- END IF
- WRITE( cf_out , '(a,"/max_moc_",a,"_",2a,".nc")' ) trim(cd_out), trim(cbasin), clatmin, clatmax
-
- id_moc = 0 ; id_lat_max = 0 ; id_depthw_max = 0
- INQUIRE( FILE=cf_out, EXIST=lfncout )
-
- IF ( .NOT. lfncout ) THEN
- !! Creating file
- PRINT *, ' Creating file '//trim(cf_out)//' !!!'
- ierr = NF90_CREATE(cf_out, NF90_CLOBBER, idf_out)
- ierr = NF90_DEF_DIM(idf_out, 'time', NF90_UNLIMITED, idd_t)
- ierr = NF90_DEF_VAR(idf_out, 'time', NF90_DOUBLE, idd_t, idv_time)
- ierr = NF90_DEF_VAR(idf_out, 'moc_'//trim(cbasin), NF90_FLOAT, (/idd_t/), id_moc)
- ierr = NF90_PUT_ATT(idf_out, id_moc, 'long_name', 'Meridional Overturning Circulation')
- ierr = NF90_PUT_ATT(idf_out, id_moc, 'units', 'Sv')
- ierr = NF90_DEF_VAR(idf_out, 'lat_max_'//trim(cbasin), NF90_FLOAT, (/idd_t/), id_lat_max)
- ierr = NF90_PUT_ATT(idf_out, id_lat_max, 'long_name', 'Latitude for maximum of MOC')
- ierr = NF90_PUT_ATT(idf_out, id_lat_max, 'units', 'deg.N')
- ierr = NF90_DEF_VAR(idf_out, 'depthw_max_'//trim(cbasin), NF90_FLOAT, (/idd_t/), id_depthw_max)
- ierr = NF90_PUT_ATT(idf_out, id_depthw_max, 'long_name', 'W-depth for maximum of MOC')
- ierr = NF90_PUT_ATT(idf_out, id_depthw_max, 'units', 'm')
- ierr = NF90_PUT_ATT(idf_out, NF90_GLOBAL, 'About', &
- & 'Created by BaraKuda (cdfmaxmoc.f90) => https://github.com/brodeau/barakuda')
- ierr = NF90_ENDDEF(idf_out)
- jt_pos = 0
- ELSE
- !! Opening already existing file
- ierr = NF90_OPEN (cf_out, NF90_WRITE, idf_out)
- !! Need IDs of variables to append... NF90_INQ_VARID
- ierr = NF90_INQ_VARID(idf_out, 'moc_'//trim(cbasin), id_moc)
- !! Need IDs of variables to append... NF90_INQ_VARID
- ierr = NF90_INQ_VARID(idf_out, 'lat_max_'//trim(cbasin), id_lat_max)
- !! Need IDs of variables to append... NF90_INQ_VARID
- ierr = NF90_INQ_VARID(idf_out, 'depthw_max_'//trim(cbasin), id_depthw_max)
- ! Get ID of unlimited dimension
- ierr = NF90_INQUIRE(idf_out, unlimitedDimId = idv_time)
- ! Need to know jt_pos, record number of the last time record writen in the file
- ierr = NF90_INQUIRE_DIMENSION(idf_out, idv_time, name=cv_dum, len=jt_pos)
- END IF
- WRITE(*,'("Going to write record ",i4.4," to ",i4.4," into ",a)') jt_pos+1, jt_pos+1+nt, trim(cf_out)
- DO jt = 1, nt
- ! Writing record jt for time vector and 1d fields:
- ierr = NF90_PUT_VAR( idf_out, idv_time, (/ryear+1./12.*(REAL(jt)-1.+0.5)/), start=(/jt_pos+jt/), count=(/1/) )
- !! Default variable is the only one present (index = 1) :
- ierr = NF90_PUT_VAR(idf_out, id_moc, (/ ovtmax(jt) /), start=(/jt_pos+jt/), count=(/1/))
- ierr = NF90_PUT_VAR(idf_out, id_lat_max, (/ rlat(1,jlatmax(jt)) /), start=(/jt_pos+jt/), count=(/1/))
- ierr = NF90_PUT_VAR(idf_out, id_depthw_max, (/ gdepw(kdmax(jt)) /), start=(/jt_pos+jt/), count=(/1/))
-
- END DO
- ierr = NF90_CLOSE(idf_out)
- PRINT *, ''
- END PROGRAM cdfmaxmoc
|