XBeach
C:/repositories/XBeach/trunk/src/xbeachlibrary/ncoutput.F90
Go to the documentation of this file.
00001 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00002 !!!!!!!!!!!!!!!!!!!!!!!   MODULE OUTPUT    !!!!!!!!!!!!!!!!!!!!!!!!!!!
00003 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00004 ! this module will provide for netcdf output in the way varoutput provides for binary output.
00005 ! It should be called optionally through one of the params.txt settings
00006 ! It will also be compiled conditionally like mpi. Only if it proves usefull will it be added by default.
00007 ! it will add dependencies on the netcdf fortran library (http://www.unidata.ucar.edu/software/netcdf/)
00008 !
00009 ! With contributions from Uwe Rosebrock (CSIRO).
00010 !
00011 ! if NCSINGLE is defined, output of all real variables in single precision
00012 !                         else double precision
00013 !
00014 ! P+R: tijdelijk uit voor testbed
00015 !#define NCSINGLE
00016 !#ifdef NCSINGLE
00017 !#define NCREAL NF90_REAL
00018 !#define CONVREAL sngl
00019 !#define CONVREALTYPE real*4
00020 !#else
00021 !#define NCREAL NF90_DOUBLE
00022 #define CONVREAL
00023 #define CONVREALTYPE real*8
00024 !#endif
00025 
00026 ! NF90: macro to call nf90 function: if return value .ne. nf90_noerr,
00027 !   an error message is produced, including file and lineno of the error,
00028 !     and the program is halted
00029 ! example:
00030 !  replace these two lines:
00031 !     status = nf90_create(path = par%ncfilename, cmode=ior(NF90_CLOBBER,NF90_64BIT_OFFSET), ncid = ncid)
00032 !     if (status /= nf90_noerr) call handle_err(status,__FILE__,__LINE__)
00033 !  with this one line:
00034 !  NF90(nf90_create(path = par%ncfilename, cmode=ior(NF90_CLOBBER,NF90_64BIT_OFFSET), ncid = ncid))
00035 !
00036 !  NOTE: the NF90 call must be on one line because of preprocessor restrictions
00037 !
00038 #ifdef USENETCDF
00039 #define NF90(nf90call) call handle_err(nf90call,__FILE__,__LINE__)
00040 #endif
00041 
00042 module ncoutput_module
00043 
00044 #ifdef HAVE_CONFIG_H
00045 #include "config.h"
00046 #endif
00047    use xmpi_module
00048 #ifdef USENETCDF
00049    use netcdf
00050 #endif
00051    use mnemmodule,    only: mnemonics, numvars
00052    use typesandkinds, only: slen
00053    implicit none
00054    save
00055    private
00056    public ncoutput, fortoutput_init, points_output_init
00057 #ifdef USENETCDF
00058    public ncoutput_init
00059 #endif
00060 
00061    ! wwvv todo why the save's?
00062    !        see http://stackoverflow.com/questions/2893097/fortran-save-statement
00063    !        so, we should use save everywhere in modules, or use them in main program
00064    !        we could also add a line
00065    !        save
00066    !        after 'implicit none'
00067 
00068    integer :: ncid
00069 
00070    ! parameters
00071    integer :: parvarid
00072 
00073    ! grid
00074    integer :: xdimid, ydimid
00075    integer :: xvarid, yvarid
00076 
00077    ! Wave angle
00078    integer :: thetadimid
00079    ! Sediment
00080    integer :: sedimentclassesdimid, bedlayersdimid
00081 
00082    ! Drifters
00083    integer              :: driftersdimid, driftersdimid2, drifterstimedimid, drifterstimevarid
00084    integer, allocatable :: driftersvarids(:)
00085    real*8               :: drift(3)
00086 
00087    ! Ships
00088    integer :: shipdimid
00089 
00090    ! Vegetation
00091    integer :: vegdimid
00092 
00093    ! Q3D
00094    integer :: Q3Ddimid
00095 
00096    ! global
00097    integer, dimension(:), allocatable :: globalvarids
00098    ! default output (fixed length)
00099 
00100    ! points
00101    integer :: pointsdimid, pointnamelengthdimid
00102    integer :: xpointsvarid, ypointsvarid, pointtypesvarid, xpointindexvarid, ypointindexvarid, stationidvarid
00103    integer, dimension(:), allocatable :: pointsvarids
00104    integer, dimension(:),allocatable  :: xpoints     ! model x-coordinate of output points
00105    integer, dimension(:),allocatable  :: ypoints     ! model y-coordinate of output points
00106 
00107    ! mean
00108    ! number of variables by number of parameters per variable (mean, sigma^2, min, max)
00109    integer, dimension(:,:), allocatable       :: meanvarids
00110    character(slen), dimension(:), allocatable :: meanvartypes
00111    integer*4                                  :: nmeanvartypes  = 4   ! number of time-average variable types
00112    integer*4,dimension(:),allocatable         :: rugrowindex ! Array with row index where runup gauge can be found
00113 
00114 
00115    ! time
00116    integer :: globaltimedimid, pointtimedimid, meantimedimid
00117    integer :: globaltimevarid, pointtimevarid, meantimevarid
00118 
00119 
00120    ! TODO: check out why these are sometimes used....
00121    integer :: tidetimedimid, windtimedimid
00122    integer :: inoutdimid, tidecornersdimid
00123 
00124    ! local variables
00125    integer :: npointstotal
00126    integer :: itg,itp,itc,itm,itd
00127    ! Only alive at xmaster
00128    integer :: stpm        ! size of tpm
00129    integer :: wordsize    ! size of word in bytes
00130 
00131    integer                     :: noutnumbers = 0  ! the number of outnumbers
00132    integer, dimension(numvars) :: outnumbers  ! numbers, corrsponding to mnemonics, which are to be output
00133 
00134    ! Output type
00135    integer                     :: NCREAL ! can be NF90_double or NF90_float
00136 
00137    ! Fill numbers
00138    integer,parameter                     :: iFill = -huge(0)
00139    real,parameter                        :: sFill = -huge(0.0)
00140    real*8,parameter                      :: dFill = -dble(huge(0.0))  ! Robert: easier this way than to catch dFill<sFill later on
00141 contains
00142 
00143 #ifdef USENETCDF
00144    ! Error handling of netcdf errors
00145    subroutine handle_err(status,file,line)
00146       use netcdf
00147       implicit none
00148 
00149       integer, intent ( in)    :: status
00150       character(*), intent(in) :: file
00151       integer, intent ( in)    :: line
00152       integer :: status2
00153 
00154       if(status /= nf90_noerr) then
00155          !UNIT=6 for stdout and UNIT=0 for stderr.
00156          write(0,'("NETCDF ERROR: ",a,i6,":",a)') file,line,trim(nf90_strerror(status))
00157          write(0,*) 'closing file'
00158          status2 = nf90_close(ncid)
00159          if (status2 /= nf90_noerr) then
00160             write(0,*) 'NETCDF ERROR: ', __FILE__,__LINE__,trim(nf90_strerror(status2))
00161          end if
00162          call halt_program
00163       end if
00164    end subroutine handle_err
00165 #endif
00166 
00167    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00168    !!!!!!!!!!!!!!!!!!!   INITIALISE OUTPUT    !!!!!!!!!!!!!!!!!!!!!!!!!!!!
00169    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00170 #ifdef USENETCDF
00171    subroutine ncoutput_init(s, sl, par, tpar)
00172       use xmpi_module
00173       use params,          only: parameters
00174       use spaceparams,     only: indextos
00175       use spaceparamsdef
00176       use mnemmodule,      only: arraytype, chartoindex
00177       use timestep_module, only: timepars
00178       use means_module,    only: meanspars, meansparsglobal
00179       use logging_module,  only: writelog
00180       ! This module is awaiting comments from Robert.
00181       use getkey_module,   only: parameter, getkey, getkeys
00182       use paramsconst
00183 
00184 
00185 
00186       implicit none
00187 
00188       type(spacepars), intent(inout)               :: s ! Use s => global data and sl => local data
00189       type(spacepars), intent(in)                  :: sl ! Use s => global data and sl => local data
00190       type(parameters), intent(in)                 :: par
00191       type(timepars), intent(in)                   :: tpar
00192 
00193       ! Part of the getkey
00194       type(parameter)                              :: val
00195       type(arraytype)                              :: t
00196       type(meanspars)                              :: meanvar
00197       integer                                      :: i,j
00198       integer                                      :: rc ! return code
00199       character(slen)                              :: mnem
00200 
00201       !integer                                      :: npointstotal
00202       logical                                      :: outputp, outputg, outputm
00203       integer, dimension(:), allocatable           :: dimids ! store the dimids in a vector
00204       character(slen)                              :: coordinates
00205       character(slen)                              :: cellmethod
00206 
00207       character(slen), dimension(:), allocatable       :: keys
00208       logical :: dofortran, donetcdf
00209       ! subversion information
00210       include 'version.def'
00211       include 'version.dat'
00212 
00213 
00214       if (.not. xomaster) return
00215 
00216       dofortran = par%outputformat .eq. OUTPUTFORMAT_FORTRAN .or. &
00217       &           par%outputformat .eq. OUTPUTFORMAT_DEBUG
00218       donetcdf  = par%outputformat .eq. OUTPUTFORMAT_NETCDF .or. &
00219       &           par%outputformat .eq. OUTPUTFORMAT_DEBUG
00220 
00221       outputp = .false.
00222 
00223       ! initialize values
00224 
00225       ! set output precision for NetCDF
00226       if(par%outputprecision == OUTPUTPRECISION_SINGLE) then
00227          NCREAL = NF90_REAL
00228       else
00229          NCREAL = NF90_DOUBLE
00230       endif
00231 
00232       ! global
00233 
00234       ! store netcdf variable ids for each variable
00235       allocate(globalvarids(par%nglobalvar))
00236       globalvarids = -1 ! initialize to -1, so an error is raised when we miss something...
00237       outputg = .true.
00238 
00239       npointstotal = par%npoints+par%nrugauge
00240       outputp = (npointstotal .gt. 0) .and. (size(tpar%tpp) .gt. 0)
00241       allocate(pointsvarids(par%npointvar))
00242 
00243       allocate(driftersvarids(par%ndrifter))
00244 
00245       allocate(meanvarids(par%nmeanvar,nmeanvartypes))
00246       meanvarids = -1
00247       outputm = (par%nmeanvar .gt. 0)
00248       allocate(meanvartypes(nmeanvartypes))
00249       meanvartypes = (/ 'mean    ', 'var     ', 'min     ', 'max     '  /)
00250 
00251       ! create a file
00252 
00253       NF90(nf90_create(path = par%ncfilename, cmode=ior(NF90_CLOBBER,NF90_64BIT_OFFSET), ncid = ncid))
00254 
00255       ! dimensions TODO: only output dimensions that are used
00256       ! grid
00257       NF90(nf90_def_dim(ncid, 'nx', s%nx+1, xdimid))
00258       NF90(nf90_def_dim(ncid, 'ny', s%ny+1, ydimid))
00259 
00260       ! wave angles
00261       NF90(nf90_def_dim(ncid, 'wave_angle', s%ntheta, thetadimid))
00262 
00263       ! computational layers in bed ...
00264       NF90(nf90_def_dim(ncid, 'bed_layers', par%nd, bedlayersdimid))
00265 
00266       ! sediment classes
00267       NF90(nf90_def_dim(ncid, 'sediment_classes', par%ngd, sedimentclassesdimid))
00268 
00269       ! dimensions of length 2.... what is this.... TODO: find out what this is
00270       NF90(nf90_def_dim(ncid, 'inout', 2, inoutdimid))
00271 
00272       ! write(*,*) 'Writing ndrifter', par%ndrifter
00273       if (par%ndrifter .gt. 0) then
00274          ! create dimensions for drifters and drifterstime:
00275          NF90(nf90_def_dim(ncid, 'ndrifter',     par%ndrifter,   driftersdimid))
00276          NF90(nf90_def_dim(ncid, 'drifterstime', size(tpar%tpp), drifterstimedimid))
00277       end if
00278 
00279       ! write(*,*) 'Writing nship', par%nship
00280       if (par%nship .gt. 0) then
00281          NF90(nf90_def_dim(ncid, 'nship', par%nship, shipdimid))
00282       end if
00283 
00284       ! vegetation sections
00285       if (par%vegetation .gt. 0) then
00286          NF90(nf90_def_dim(ncid, 'nsecvegmax', s%nsecvegmax, vegdimid))
00287       endif
00288 
00289       ! write(*,*) 'Writing nz', par%nz
00290       if (par%nz .gt. 1) then
00291          NF90(nf90_def_dim(ncid, 'nz', par%nz, Q3Ddimid))
00292       end if
00293 
00294       ! time dimensions are fixed, only defined if there are points
00295       if (outputg) then
00296          NF90(nf90_def_dim(ncid, 'globaltime', NF90_unlimited, globaltimedimid))
00297       end if
00298       if (outputp) then
00299          ! points
00300          NF90(nf90_def_dim(ncid, 'points', npointstotal, pointsdimid))
00301          NF90(nf90_def_dim(ncid, 'pointtime', size(tpar%tpp), pointtimedimid))
00302          NF90(nf90_def_dim(ncid, 'pointnamelength', 64, pointnamelengthdimid))
00303       end if
00304       if (outputm) then
00305          NF90(nf90_def_dim(ncid, 'meantime', size(tpar%tpm)-1, meantimedimid))
00306       end if
00307 
00308       if (s%tidelen > 0) then
00309          NF90(nf90_def_dim(ncid, 'tidetime', s%tidelen, tidetimedimid))
00310       endif
00311 
00312       if (par%tideloc > 0) then
00313          NF90(nf90_def_dim(ncid, 'tidecorners', par%tideloc, tidecornersdimid))
00314       endif
00315 
00316       if (s%windlen > 0) then
00317          NF90(nf90_def_dim(ncid, 'windtime', s%windlen, windtimedimid))
00318       endif
00319 
00320       ! define empty parameter variable
00321       NF90(nf90_def_var(ncid, '_parameters', NCREAL, varid=parvarid))
00322       ! define space & time variables
00323       ! grid
00324       NF90(nf90_def_var(ncid, 'globalx', NCREAL, (/ xdimid, ydimid /), xvarid))
00325       NF90(nf90_put_att(ncid, xvarid, 'units', 'm'))
00326       NF90(nf90_put_att(ncid, xvarid, 'long_name', 'local x coordinate'))
00327       NF90(nf90_put_att(ncid, xvarid, 'standard_name', 'projection_x_coordinate'))
00328       NF90(nf90_put_att(ncid, xvarid, 'axis', 'X'))
00329       ! For compatibility with CSIRO Dive software
00330       if (len(trim(par%projection)) .ne. 0)  then
00331          NF90(nf90_put_att(ncid, xvarid, 'projection', par%projection))
00332          NF90(nf90_put_att(ncid, xvarid, 'rotation',( s%alfa/atan(1.0d0)*45.d0)))
00333       end if
00334 
00335       NF90(nf90_def_var(ncid, 'globaly', NCREAL, (/ xdimid, ydimid /), yvarid))
00336       NF90(nf90_put_att(ncid, yvarid, 'units', 'm'))
00337       NF90(nf90_put_att(ncid, yvarid, 'long_name', 'local y coordinate'))
00338       NF90(nf90_put_att(ncid, yvarid, 'standard_name', 'projection_y_coordinate'))
00339       NF90(nf90_put_att(ncid, yvarid, 'axis', 'Y'))
00340       ! For compatibility with CSIRO Dive software
00341       if (len(trim(par%projection)) .ne. 0)  then
00342          NF90(nf90_put_att(ncid, yvarid, 'projection', par%projection))
00343          NF90(nf90_put_att(ncid, yvarid, 'rotation',( s%alfa/atan(1.0d0)*45.d0)))
00344       end if
00345 
00346       ! Some metadata attributes
00347       NF90(nf90_put_att(ncid,nf90_global, "Conventions", "CF-1.4"))
00348       NF90(nf90_put_att(ncid,nf90_global, "Producer", "XBeach littoral zone wave model (http://www.xbeach.org)"))
00349       NF90(nf90_put_att(ncid,nf90_global, "Build-Revision", trim(Build_Revision)))
00350       NF90(nf90_put_att(ncid,nf90_global, "Build-Date", trim(Build_Date)))
00351       NF90(nf90_put_att(ncid,nf90_global, "URL", trim(Build_URL)))
00352 
00353       ! Store all the parameters
00354       ! This part is awaiting comments from Robert McCall
00355       call getkeys(par, keys)
00356       do i=1,size(keys)
00357          rc = getkey(par, keys(i), val)
00358          if (val%type == 'i') then
00359             NF90(nf90_put_att(ncid, parvarid, keys(i), val%i0 ))
00360          elseif (val%type == 'c') then
00361             NF90(nf90_put_att(ncid, parvarid, keys(i), val%c0 ))
00362          elseif (val%type == 'r') then
00363             NF90(nf90_put_att(ncid, parvarid, keys(i), val%r0 ))
00364          end if
00365       end do
00366 
00367       ! global
00368       if (outputg) then
00369          NF90(nf90_def_var(ncid, 'globaltime', NCREAL, (/ globaltimedimid /), globaltimevarid))
00370          NF90(nf90_put_att(ncid, globaltimevarid, 'units', trim(par%tunits)))
00371          NF90(nf90_put_att(ncid, globaltimevarid, 'axis', 'T'))
00372          NF90(nf90_put_att(ncid, globaltimevarid, 'standard_name', 'time'))
00373 
00374 
00375          ! default global output variables
00376          do i=1,par%nglobalvar
00377             mnem = par%globalvars(i)
00378             coordinates = ''
00379             j = chartoindex(mnem)
00380             call indextos(s,j,t)
00381             call writelog('ls', '', 'Creating netcdf variable: ', trim(mnem) )
00382 
00383             ! Build the array with dimension ids
00384             allocate(dimids(t%rank+1))
00385             select case(t%rank)
00386              case(0)
00387                dimids = (/ globaltimedimid /)
00388                coordinates = ''
00389              case(1)
00390                dimids = (/ dimensionid(t%dimensions(1)), globaltimedimid /)
00391                coordinates = ''
00392                if (dimids(1) .eq. xdimid) coordinates = 'globalx'
00393                if (dimids(1) .eq. ydimid) coordinates = 'globaly'
00394              case(2)
00395                dimids = (/ dimensionid(t%dimensions(1)), dimensionid(t%dimensions(2)), globaltimedimid /)
00396                coordinates = 'globalx globaly'
00397              case(3)
00398                dimids = (/ dimensionid(t%dimensions(1)), dimensionid(t%dimensions(2)), &
00399                &dimensionid(t%dimensions(3)), globaltimedimid /)
00400                coordinates = 'globalx globaly'
00401                ! Do we have a vertical level?
00402                if (dimids(3) .eq. bedlayersdimid) coordinates = trim(coordinates) // ' bed_layers'
00403              case(4)
00404                call writelog('ls', '', 'Variable ' // trim(mnem) // ' is of rank 4. This may not work due to an' // &
00405                &' unresolved issue. If so, remove the variable or use the fortran outputformat option.')
00406                dimids = (/ dimensionid(t%dimensions(1)), dimensionid(t%dimensions(2)), &
00407                &dimensionid(t%dimensions(3)), dimensionid(t%dimensions(4)), globaltimedimid /)
00408                coordinates = 'globalx globaly'
00409                ! Do we have a vertical level?
00410                if ((dimids(3) .eq. bedlayersdimid) .or. (dimids(4) .eq. bedlayersdimid)) then
00411                   coordinates = trim(coordinates) // ' bed_layers'
00412                end if
00413              case default
00414                call writelog('lse', '', 'mnem: ' // mnem // ' not supported, rank:', t%rank)
00415                stop 1
00416             end select
00417             select case(t%type)
00418              case('i')
00419                NF90(nf90_def_var(ncid, trim(mnem), NF90_INT, dimids, globalvarids(i)))
00420              case('r')
00421                NF90(nf90_def_var(ncid, trim(mnem), NCREAL, dimids, globalvarids(i)))
00422              case default
00423                write(0,*) 'mnem', mnem, ' not supported, type:', t%type
00424             end select
00425             deallocate(dimids)
00426             NF90(nf90_put_att(ncid, globalvarids(i), 'coordinates', trim(coordinates)))
00427             NF90(nf90_put_att(ncid, globalvarids(i), 'units', trim(t%units)))
00428             if (.not.(trim(t%standardname) .eq. '')) then
00429                NF90(nf90_put_att(ncid, globalvarids(i), 'standard_name', trim(t%standardname)))
00430             endif
00431             NF90(nf90_put_att(ncid, globalvarids(i), 'long_name', trim(t%description)))
00432             select case(t%type)
00433              case('i')
00434                NF90(nf90_put_att(ncid, globalvarids(i), '_FillValue', iFill))
00435              case('r')
00436                if(par%outputprecision == OUTPUTPRECISION_SINGLE) then
00437                   NF90(nf90_put_att(ncid, globalvarids(i), '_FillValue', sFill))
00438                else
00439                   NF90(nf90_put_att(ncid, globalvarids(i), '_FillValue', dFill))
00440                endif
00441             end select
00442          end do
00443       end if
00444 
00445       !  ! points
00446       ! default global output variables
00447       if (outputp) then
00448          NF90(nf90_def_var(ncid, 'pointtime', NCREAL, (/ pointtimedimid /), pointtimevarid))
00449          NF90(nf90_put_att(ncid, pointtimevarid, 'units', trim(par%tunits)))
00450          NF90(nf90_put_att(ncid, pointtimevarid, 'axis', 'T'))
00451          NF90(nf90_put_att(ncid, pointtimevarid, 'standard_name', 'time'))
00452 
00453          ! points
00454          NF90(nf90_def_var(ncid, 'pointx', NCREAL, (/ pointsdimid /), xpointsvarid))
00455          NF90(nf90_put_att(ncid, xpointsvarid, 'units', 'm'))
00456          NF90(nf90_put_att(ncid, xpointsvarid, 'long_name', 'local x coordinate'))
00457          NF90(nf90_put_att(ncid, xpointsvarid, 'standard_name', 'projection_x_coordinate'))
00458          NF90(nf90_put_att(ncid, xpointsvarid, 'axis', 'X'))
00459 
00460 
00461          NF90(nf90_def_var(ncid, 'pointy', NCREAL, (/ pointsdimid /), ypointsvarid))
00462          NF90(nf90_put_att(ncid, ypointsvarid, 'units', 'm'))
00463          NF90(nf90_put_att(ncid, ypointsvarid, 'long_name', 'local y coordinate'))
00464          NF90(nf90_put_att(ncid, ypointsvarid, 'standard_name', 'projection_y_coordinate'))
00465          NF90(nf90_put_att(ncid, ypointsvarid, 'axis', 'Y'))
00466 
00467          NF90(nf90_def_var(ncid, 'station_id', NF90_CHAR, (/ pointnamelengthdimid, pointsdimid /), stationidvarid))
00468          NF90(nf90_put_att(ncid, stationidvarid, 'long_name', 'station identification code'))
00469          NF90(nf90_put_att(ncid, stationidvarid, 'standard_name', 'station_id'))
00470 
00471          NF90(nf90_def_var(ncid, 'xpointindex', NF90_INT, (/ pointsdimid /), xpointindexvarid))
00472          ! wwvv above was NF90_DOUBLE
00473          NF90(nf90_put_att(ncid, xpointindexvarid, 'long_name', 'nearest x grid cell'))
00474          NF90(nf90_def_var(ncid, 'ypointindex', NF90_INT, (/ pointsdimid /), ypointindexvarid))
00475          ! wwvv above was NF90_DOUBLE
00476          NF90(nf90_put_att(ncid, ypointindexvarid, 'long_name', 'nearest y grid cell'))
00477 
00478          NF90(nf90_def_var(ncid, 'pointtypes', NF90_INT, (/ pointsdimid /), pointtypesvarid))
00479          ! wwvv above was NF90_DOUBLE
00480          NF90(nf90_put_att(ncid, pointtypesvarid, 'long_name', 'type of point (0=point, 1=rugauge)'))
00481 
00482          do i=1,par%npointvar
00483             mnem = par%pointvars(i)
00484             j = chartoindex(mnem)
00485             coordinates = ''
00486             call indextos(s,j,t)
00487             select case(t%type)
00488              case('r')
00489                ! Build the array with dimension ids
00490                call writelog('ls', '', 'Creating netcdf variable: ', 'point_'// trim(mnem) )
00491                allocate(dimids(t%rank))
00492                ! Make sure the variable has x and y as the first 2 dimensions
00493                if ((dimensionid(t%dimensions(1)) .ne. xdimid) .or. (dimensionid(t%dimensions(2)) .ne. ydimid)) then
00494                   call writelog('lse','', 'Tried to store variable ' // trim(mnem) // ', but it is not a function of x,y')
00495                endif
00496                select case(t%rank)
00497                 case(2)
00498                   dimids = (/ pointsdimid, pointtimedimid /)
00499                   coordinates = 'pointx pointy'
00500                 case(3)
00501                   dimids = (/ pointsdimid, dimensionid(t%dimensions(3)), pointtimedimid /)
00502                   coordinates = 'pointx pointy'
00503                   ! Do we have a vertical level?
00504                   if (dimids(3) .eq. bedlayersdimid) coordinates = trim(coordinates) // ' bed_layers'
00505                 case(4)
00506                   call writelog('ls', '', 'Variable ' // trim(mnem) // ' is of rank 4. This may not work due to an' // &
00507                   &' unresolved issue. If so, remove the variable or use the fortran outputformat option.')
00508                   dimids = (/ pointsdimid, dimensionid(t%dimensions(3)), dimensionid(t%dimensions(4)), pointtimedimid /)
00509                   coordinates = 'pointx pointy'
00510                   ! Do we have a vertical level?
00511                   if ((dimids(3) .eq. bedlayersdimid) .or. (dimids(4) .eq. bedlayersdimid)) then
00512                      coordinates = trim(coordinates) // ' bed_layers'
00513                   end if
00514                 case default
00515                   call writelog('lse', '', 'mnem: ' // mnem // ' not supported, rank:', t%rank)
00516                   stop 1
00517                end select
00518                NF90(nf90_def_var(ncid, 'point_' // trim(mnem), NCREAL, dimids, pointsvarids(i)))
00519                NF90(nf90_put_att(ncid, pointsvarids(i), 'coordinates', trim(coordinates)))
00520                deallocate(dimids)
00521              case default
00522                write(0,*) 'mnem', mnem, ' not supported, type:', t%type
00523             end select
00524             NF90(nf90_put_att(ncid, pointsvarids(i), 'units', trim(t%units)))
00525             if (.not.(trim(t%standardname) .eq. '')) then
00526                NF90(nf90_put_att(ncid, pointsvarids(i), 'standard_name', trim(t%standardname)))
00527             endif
00528             NF90(nf90_put_att(ncid, pointsvarids(i), 'long_name', trim(t%description)))
00529          end do
00530       endif ! outputp
00531 
00532       if (par%ndrifter .gt. 0) then
00533          allocate(dimids(2))
00534 
00535          NF90(nf90_def_var(ncid, 'driftertime', NCREAL, (/ drifterstimedimid /), drifterstimevarid))
00536          NF90(nf90_put_att(ncid, drifterstimevarid, 'units', trim(par%tunits)))
00537          NF90(nf90_put_att(ncid, drifterstimevarid, 'axis', 'T'))
00538          NF90(nf90_put_att(ncid, drifterstimevarid, 'standard_name', 'time'))
00539 
00540          ! create netcdf variables for drifters:
00541          !  each variable is a 2-d array, containing the x-y values
00542          !  the netcdf name of e.g. the 3rd array is drifter_003
00543 
00544          NF90(nf90_def_dim(ncid, 'drifterstime2', 2, driftersdimid2))
00545          do i=1,par%ndrifter
00546             ! we need the following dimensions per drifter:
00547             !    driftersdimid2    : 2
00548             !    drifterstimedimid : number of output time steps
00549             dimids(1) = driftersdimid2
00550             dimids(2) = drifterstimedimid
00551             write(mnem,'("drifter_",I0.3)') i
00552             NF90(nf90_def_var(ncid, trim(mnem), NCREAL, dimids, driftersvarids(i)))
00553             NF90(nf90_put_att(ncid, driftersvarids(i), 'coordinates', 'pointx pointy'))
00554             NF90(nf90_put_att(ncid, driftersvarids(i), 'units', 'm'))
00555          enddo
00556          deallocate(dimids)
00557 
00558       endif  ! par%ndrifter
00559 
00560       if(outputm) then
00561          NF90(nf90_def_var(ncid, 'meantime', NCREAL, (/ meantimedimid /), meantimevarid))
00562          NF90(nf90_put_att(ncid, meantimevarid, 'units', trim(par%tunits)))
00563          NF90(nf90_put_att(ncid, meantimevarid, 'axis', 'T'))
00564          NF90(nf90_put_att(ncid, meantimevarid, 'standard_name', 'time'))
00565          ! default global output variables
00566          do i=1,par%nmeanvar
00567             ! Not sure if this is required here, but it is used in varoutput
00568             ! #ifdef USEMPI
00569             !              ! No need to collect here, we're just using the types
00570             !              ! call means_collect(sl,meansparsglobal(i),meansparslocal(i))
00571             ! #else
00572             !              meansparsglobal(i)=meansparslocal(i)
00573             ! #endif
00574             coordinates = ''
00575             meanvar = meansparsglobal(i)
00576             t = meanvar%t
00577             select case(t%type)
00578              case('r')
00579                ! Build the array with dimension ids
00580                allocate(dimids(t%rank+1))
00581                select case(t%rank)
00582                 case(2)
00583                   dimids = (/ dimensionid(t%dimensions(1)), dimensionid(t%dimensions(2)), meantimedimid /)
00584                   coordinates = 'globalx globaly'
00585                 case(3)
00586                   dimids = (/ dimensionid(t%dimensions(1)), dimensionid(t%dimensions(2)), &
00587                   &dimensionid(t%dimensions(3)), meantimedimid /)
00588                   coordinates = 'globalx globaly'
00589                   ! Do we have a vertical level?
00590                   if (dimids(3) .eq. bedlayersdimid) coordinates = trim(coordinates) // ' bed_layers'
00591                 case(4)
00592                   call writelog('ls', '', 'Variable ' // trim(mnem) // ' is of rank 4. This may not work due to an' // &
00593                   &' unresolved issue. If so, remove the variable or use the fortran outputformat option.')
00594                   dimids = (/ dimensionid(t%dimensions(1)), dimensionid(t%dimensions(2)), &
00595                   &dimensionid(t%dimensions(3)), dimensionid(t%dimensions(4)), meantimedimid /)
00596                   coordinates = 'globalx globaly'
00597                   ! Do we have a vertical level?
00598                   if ((dimids(3) .eq. bedlayersdimid) .or. (dimids(4) .eq. bedlayersdimid)) then
00599                      coordinates = trim(coordinates) // ' bed_layers'
00600                   end if
00601                 case default
00602                   call writelog('lse', '', 'mnem: ' // mnem // ' not supported, rank:', t%rank)
00603                   call halt_program
00604                   stop 1
00605                end select
00606 
00607                ! Create a variable for all types of meanvars (mean, var, min, max)
00608                do j = 1,nmeanvartypes
00609                   cellmethod = meanvartypes(j)
00610                   call writelog('ls', '', 'Creating netcdf variable: ',  trim(t%name) // '_' // cellmethod)
00611                   NF90(nf90_def_var(ncid, trim(t%name) // '_' // trim(cellmethod), NCREAL, dimids, meanvarids(i,j)))
00612                   NF90(nf90_put_att(ncid, meanvarids(i,j), 'coordinates', trim(coordinates)))
00613                   if (cellmethod .eq. 'var') then
00614                      NF90(nf90_put_att(ncid, meanvarids(i,j), 'units', '(' // trim(t%units) // ')^2'))
00615                   else
00616                      NF90(nf90_put_att(ncid, meanvarids(i,j), 'units', trim(t%units)))
00617                   endif
00618                   if (.not.(trim(t%standardname) .eq. '')) then
00619                      NF90(nf90_put_att(ncid, meanvarids(i,j), 'standard_name', trim(t%standardname)))
00620                   endif
00621                   NF90(nf90_put_att(ncid, meanvarids(i,j), 'long_name', trim(t%description)))
00622                   ! For H and urms we don't compute the mean but the rms of the rms.....
00623                   if (cellmethod .eq. 'mean' .and. ((t%name .eq. 'H') .or. (t%name .eq. 'urms')))  then
00624                      cellmethod = 'rms'
00625                   end if
00626                   NF90(nf90_put_att(ncid, meanvarids(i,j), 'cell_methods', 'meantime: ' // trim(cellmethod)))
00627                end do
00628 
00629                deallocate(dimids)
00630              case default
00631                write(0,*) 'mnem', mnem, ' not supported, type:', t%type
00632             end select
00633          end do
00634       endif  ! outputm
00635 
00636       ! done defining variables
00637       call writelog('ls', '', 'Writing file definition.')
00638       NF90(nf90_enddef(ncid))
00639 
00640       ! Fill meta variables
00641       ! Grid
00642       j = chartoindex('xz')
00643       call indextos(s,j,t)
00644       NF90(nf90_put_var(ncid, xvarid, CONVREAL(t%r2)))
00645 
00646       j = chartoindex('yz')
00647       call indextos(s,j,t)
00648       NF90(nf90_put_var(ncid, yvarid, CONVREAL(t%r2)))
00649 
00650       if (outputp) then
00651          call writelog('ls', '', 'Writing point vars.')
00652          NF90(nf90_put_var(ncid, xpointsvarid, CONVREAL(par%xpointsw)))
00653          NF90(nf90_put_var(ncid, ypointsvarid, CONVREAL(par%ypointsw)))
00654          NF90(nf90_put_var(ncid, pointtypesvarid, par%pointtypes))
00655          NF90(nf90_put_var(ncid, xpointindexvarid, xpoints))
00656          NF90(nf90_put_var(ncid, ypointindexvarid, ypoints))
00657          NF90(nf90_put_var(ncid, pointtypesvarid, par%pointtypes))
00658          NF90(nf90_put_var(ncid, stationidvarid, par%stationid(1:npointstotal)))
00659       end if
00660 
00661       NF90(nf90_close(ncid))
00662       ! wwvv sl is not used so it should be removed.
00663       ! wwvv for now, to avoid warning:
00664 
00665       if (sl%nx .ne. -1) return
00666    end subroutine ncoutput_init
00667 #endif
00668    ! USENETCDF
00669 
00670 
00671    !___________________________________________________________________________________
00672 
00673    subroutine ncoutput(s,sl,par, tpar)
00674       use xmpi_module
00675       use params,          only: parameters
00676       use spaceparamsdef,  only: spacepars
00677       use spaceparams,     only: indextos
00678       use timestep_module, only: timepars
00679       use mnemmodule,      only: arraytype, mnem_Subg, mnem_Sutot, mnem_Svtot, maxnamelen, mnem_alfaz, mnem_Susg
00680       use mnemmodule,      only: mnem_Svbg, mnem_Svsg, chartoindex, mnem_wetz
00681       use means_module,    only: meansparsglobal, meansparslocal
00682       use postprocessmod,  only: get_sister_mnem, gridrotate, postprocessvar_r2
00683       use spaceparamsdef,  only: spacepars
00684       use xmpi_module
00685       use constants,       only: pi
00686       use paramsconst
00687 #ifdef USEMPI
00688       use xmpi_module
00689 
00690       use spaceparams,     only: space_collect_mnem, space_local_to_global, space_collect_index
00691       use spaceparams,     only: space_who_has, space_global_to_local
00692       use means_module,    only: means_collect
00693 #endif
00694 
00695       implicit none
00696 
00697       type(spacepars), intent(inout)         :: s ! s-> spaceparams, what is isl?
00698       !                                         s describes the global system, sl the local system
00699       !                                           in this MPI process
00700       type(spacepars), intent(inout)         :: sl ! s-> spaceparams, what is isl?
00701       type(parameters), intent(inout)        :: par
00702       type(timepars), intent(in)             :: tpar
00703 
00704       type(arraytype)                        :: t
00705       integer                                :: i,j,ii
00706 #ifdef USEMPI
00707       integer                                :: index
00708 #endif
00709       character(maxnamelen)                  :: mnem,sistermnemalloc
00710       real*8, dimension(:,:), allocatable    :: points
00711 
00712       ! some local variables to pass the data through the postprocessing function.
00713       integer                                       :: i0
00714       integer, dimension(:,:),          allocatable :: i2
00715       integer, dimension(:,:,:),        allocatable :: i3
00716       CONVREALTYPE                                  :: r0conv
00717       real*8,       dimension(:),       allocatable :: r1
00718       CONVREALTYPE, dimension(:),       allocatable :: r1conv
00719       real*8,       dimension(:,:),     allocatable :: r2
00720       CONVREALTYPE, dimension(:,:),     allocatable :: r2conv
00721       real*8,       dimension(:,:,:),   allocatable :: r3
00722       CONVREALTYPE, dimension(:,:,:),   allocatable :: r3conv
00723       real*8,       dimension(:,:,:,:), allocatable :: r4
00724       CONVREALTYPE, dimension(:,:,:,:), allocatable :: r4conv
00725       real*8,                           allocatable :: tempvectorr(:)
00726       real*8,dimension(size(tpar%tpg)+size(tpar%tpp)+size(tpar%tpm)) :: outputtimes
00727 
00728       integer                                       :: jtg,reclen,unit,idumhl,ird,iru,xmax,xmin
00729       integer                                       :: iz,jz,idum
00730       real*8                                        :: di,dj,dx,dy
00731       integer                                       :: ilocal, jlocal
00732 #ifdef USEMPI
00733       real*8, dimension(par%ndrifter)               :: idriftlocal,jdriftlocal
00734 #endif
00735       integer                                       :: pii
00736 
00737 #ifdef USENETCDF
00738       integer :: status
00739 #endif
00740 
00741       logical :: dofortran, donetcdf, dofortran_compat
00742       logical :: dooutput_global, dooutput_mean, dooutput_point, dooutput_drifter, dooutput_hotstart
00743 
00744       type pointoutput
00745          integer                                  :: rank   ! rank of the data
00746          character(len=maxnamelen)                :: name   ! name of the variable
00747          real*8, dimension(:,:), allocatable      :: r2     ! contains 2-d data  (rank = 2)
00748          real*8, dimension(:,:,:), allocatable    :: r3     ! contains 3-d data  (rank = 3)
00749          real*8, dimension(:,:,:,:), allocatable  :: r4     ! contains 4-d data  (rank = 4)
00750          !                                                    note that r2 will be allocated (1,1)
00751          !                                                              r3 will be allocated (1,1,nnn)
00752          !                                                              r4 will be allocated  (1,1,mmm,nnn)
00753          !                                                    why ? because gridrotate demands this
00754       end type pointoutput
00755 
00756       integer                                     :: xpii, ypii
00757       integer                                     :: rugx, rugy
00758 
00759       type (pointoutput), dimension(:,:), allocatable :: pointoutputs  
00760 
00761       real*8, dimension(:,:), allocatable :: runups,runups1   ! runups(:,i) will contain the 1+par%nrugdepth*3 runup values        
00762       !                                                       ! for runup number i(i=1 .. par%nrugauge)
00763       integer, dimension(:), allocatable:: xpoints1  ! for netcdf runup output
00764 
00765       ! fortran output requested?
00766       dofortran = par%outputformat .eq. OUTPUTFORMAT_FORTRAN .or. &
00767       &           par%outputformat .eq. OUTPUTFORMAT_DEBUG
00768 
00769       ! for compatibility with older version, at some places
00770       ! fortran output is only done when tpar%output = .true.
00771 
00772       dofortran_compat = dofortran .and. tpar%output
00773 
00774       !netcdf output requested?
00775       donetcdf = par%outputformat .eq. OUTPUTFORMAT_NETCDF .or. &
00776       &          par%outputformat .eq. OUTPUTFORMAT_DEBUG
00777 
00778       ! time for global output?
00779       dooutput_global = tpar%outputg .and. par%nglobalvar .gt. 0
00780 
00781       ! time for mean output?
00782       dooutput_mean   = tpar%outputm .and. par%nmeanvar   .gt. 0 .and. tpar%itm .gt. 1
00783 
00784       ! time for point output?
00785       dooutput_point  = tpar%outputp .and. par%npointvar .gt. 0  &
00786       .and. par%npoints+par%nrugauge .gt. 0
00787 
00788       ! time for drifter output?
00789       dooutput_drifter  = tpar%outputp .and. par%ndrifter .gt. 0
00790       
00791       ! time for hotstart output?
00792       dooutput_hotstart = tpar%outputh .and. par%writehotstart == 1
00793 
00794 #ifdef USEMPI
00795       ! clear collected items
00796       s%collected = s%precollected
00797 
00798       ! If we're gonna write some global output
00799       if (dooutput_global) then
00800          ! we'll need to collect the information from all nodes.
00801          do i=1,par%nglobalvar
00802             mnem = par%globalvars(i)
00803             index = chartoindex(mnem)
00804             call space_collect_index(s,sl,par,index)
00805             if (par%rotate==1) then
00806                sistermnemalloc = get_sister_mnem(mnem)
00807 
00808                select case (sistermnemalloc)
00809                 case ('none')
00810                   ! nothing
00811                 case default
00812                   call space_collect_mnem(s,sl,par,sistermnemalloc)
00813                end select
00814 
00815                select case(mnem)
00816                 case(mnem_Sutot,mnem_Svtot)
00817                   call space_collect_mnem(s,sl,par,mnem_Subg)
00818                   call space_collect_mnem(s,sl,par,mnem_Svbg)
00819                   call space_collect_mnem(s,sl,par,mnem_Susg)
00820                   call space_collect_mnem(s,sl,par,mnem_Svsg)
00821                end select
00822 
00823             endif
00824          end do
00825          if (par%rotate==1) then
00826             call space_collect_mnem(s,sl,par,mnem_alfaz)
00827          endif
00828          if(par%remdryoutput==1) then
00829             call space_collect_mnem(s,sl,par,mnem_wetz)
00830          endif
00831 
00832       endif
00833 
00834 #endif
00835       ! USEMPI
00836 
00837 
00838 #ifdef USEMPI
00839       if(dooutput_point) then
00840          ! Collect all data for which we store the points.
00841          ! TODO: This will be a lot faster if nodes write their own point. Use the parallel netcdf for that.
00842          ! Let's wait till someone needs it...
00843          ! wwvv Collecting the data could als be done using sends from the compute processes
00844          ! wwvv and receives on the xomaster process.
00845          ! wwvv the info to do this properly could be computed in _init
00846          ! wwvv in stead of sends and receives, probably more simple is the use of mpi_alltoallw
00847          !
00848       endif  !dooutput_point
00849 #endif
00850       ! USEMPI
00851 
00852       ! If we're gonna write some mean output
00853       if(dooutput_mean) then
00854 
00855          do i=1,par%nmeanvar
00856 #ifdef USEMPI
00857             call means_collect(sl,meansparsglobal(i),meansparslocal(i))
00858 #else
00859             meansparsglobal(i)=meansparslocal(i)
00860 #endif
00861          end do
00862       endif
00863       
00864       if (dooutput_hotstart) then
00865 #ifdef USEMPI
00866          call hotstartfiles_collect(s,sl,par, tpar)
00867 #endif
00868       endif
00869 
00870 
00871 #ifdef USEMPI
00872       if (par%ndrifter .gt. 0) then
00873          if(xmaster) then
00874             idriftlocal = sl%idrift
00875             jdriftlocal = sl%jdrift
00876          endif
00877          call xmpi_send(xmpi_imaster,xmpi_omaster,idriftlocal)
00878          call xmpi_send(xmpi_imaster,xmpi_omaster,jdriftlocal)
00879          if (xomaster) then
00880             s%idrift = idriftlocal
00881             s%jdrift = jdriftlocal
00882          endif
00883       endif
00884 #endif
00885 
00886       ! wwvv a more efficient implementation:
00887       !      step 1: determine which process contains the desired point
00888       !      step 2: gridrotate this point
00889       !      step 3: store this point
00890       !      step 4: send the value of this point to xomaster (xmpi_send) after
00891       !              if( .not. xomaster) return
00892       !
00893       !      the points are assembled in pointoutputs, which is an 2-d array
00894       !        of type(pointoutput), which is described above.
00895       !
00896       !        pointoutputs(i,j) contains the values for pointvariable i
00897       !                                              and coordinates   j
00898 
00899       if (dooutput_point) then
00900          if (xomaster) then
00901             allocate(pointoutputs(par%npointvar,par%npoints+par%nrugauge))
00902          endif
00903          allocate(tempvectorr(1+par%nrugdepth*3))
00904          allocate(runups (size(tempvectorr),par%nrugauge))
00905          allocate(runups1(size(tempvectorr),par%nrugauge))
00906          ! WD: new code
00907          ! first: compute run gauge
00908          if(xcompute) then
00909             allocate(xpoints1(par%nrugauge))
00910             xpoints1 = s%nx+1
00911             ! the compute processes will determine their own runup values
00912             ! if no runp is found, a value of huge(0.0d0) is used
00913             ! The runup values are collected in xomaster, using xmpi_reduce,
00914             ! taking the minimum values
00915             do ii = par%npoints+1, par%npoints+par%nrugauge
00916                iru         = ii-par%npoints   !  iru will run from 1 to par%nrugauge
00917                tempvectorr = huge(0.d0)
00918                ! for netcdf output:
00919                do ird=1,par%nrugdepth
00920 #ifdef USEMPI
00921                   call space_global_to_local(sl,1,rugrowindex(iru),rugx,rugy)
00922 #else
00923                   rugx = 1
00924                   rugy = rugrowindex(iru)
00925 #endif
00926                   ! rugy now contains the local y-coordinate
00927                   ! rugx is not used
00928                   ! if rugy is within the computational domain of this process,
00929                   ! we determine the local runup values
00930                   ! the computational domain in this process:
00931                   ! 1st dimension: sl%icls(xmpi_rank+1) .. sl%icle(xmpi_rank+1)
00932                   ! 2nd dimension: sl%jcls(xmpi_rank+1) .. sl%jcle(xmpi_rank+1)
00933 #ifdef USEMPI
00934                   if (rugy .ge. sl%jcls(xmpi_rank+1) .and. rugy .le. sl%jcle(xmpi_rank+1)) then
00935                      xmin   = sl%icls(xmpi_rank+1)
00936                      xmax   = sl%icle(xmpi_rank+1)
00937 #else
00938                   if (.true.) then
00939                      xmin   = 2
00940                      xmax   = sl%nx+1
00941 #endif
00942                      idumhl = -1        ! Set default
00943                      if (rugrowindex(iru)>0) then  ! master domain always contains this runup gauge
00944                         ! local index of minimum location where hh<rugdepth
00945                         do j=xmin+1,xmax
00946                            if ((sl%hh(j,  rugy)<=par%rugdepth(ird)) .and. &
00947                            &   (sl%hh(j-1,rugy)> par%rugdepth(ird)) ) then
00948                               idumhl=j-1
00949                               exit
00950                            endif
00951                         enddo
00952                      endif
00953 
00954                      if (par%morfacopt==1) then
00955                         tempvectorr(1) = par%t*max(par%morfac,1.d0)
00956                      else
00957                         tempvectorr(1)=par%t
00958                      endif
00959 
00960                      ! for netcdf output:
00961                      if(ird == 1) then
00962                         ! convert from local coordinates to global, y-coordinate is not relevant:
00963                         if (idumhl .gt. 0) then
00964 #ifdef USEMPI
00965                            call space_local_to_global(sl,idumhl,10,xpoints1(iru),idum)
00966 #else
00967                            xpoints1(iru) = idumhl
00968                            idum           = 10
00969 #endif
00970                         else
00971                            xpoints1(iru) = s%nx+1
00972                         endif
00973                      endif
00974 
00975                      if (idumhl .gt. 0) then
00976                         tempvectorr((ird-1)*3+2) = sl%xz(idumhl,rugy)
00977                         tempvectorr((ird-1)*3+3) = sl%yz(idumhl,rugy)
00978                         tempvectorr((ird-1)*3+4) = sl%zs(idumhl,rugy)
00979                      endif
00980 
00981                   endif  ! rugy within computational domain
00982                enddo     ! ird=1,par%nrugdepth
00983                runups(:,iru) = tempvectorr
00984             enddo        ! ii = par%npoints+1, par%npoints+par%nrugauge
00985             !  reduce the runups to runup1 on xmaster:
00986 #ifdef USEMPI
00987             call xmpi_reduce(runups,runups1,MPI_MIN)
00988 #else
00989             runups1 = runups
00990 #endif
00991 
00992             ! reduce xpoints1 to (par%npoints+1:) on xmaster:
00993 #ifdef USEMPI
00994             call xmpi_reduce(xpoints1,xpoints(par%npoints+1:),MPI_MIN)
00995 #else
00996             xpoints(par%npoints+1:) = xpoints1
00997 #endif
00998          endif ! xcompute
00999          !  send runups1 to xomaster who will receive it in runups
01000 #ifdef USEMPI
01001          if (xomaster) then
01002             call xmpi_send(xmpi_imaster,xmpi_omaster,runups)
01003          else
01004             call xmpi_send(xmpi_imaster,xmpi_omaster,runups1)
01005          endif
01006          ! same for xpoints:
01007          call xmpi_send(xmpi_imaster,xmpi_omaster,xpoints(par%npoints+1:))
01008 #else
01009          runups = runups1
01010 #endif
01011          ! WD: /new code
01012          !  end runup gauge computations
01013          do i=1,par%npointvar
01014             mnem = par%pointvars(i)
01015             j = chartoindex(mnem)
01016             ! lookup the proper array
01017             call indextos(sl,j,t)
01018             ! get the proper output points ....
01019             select case(t%type)
01020              case('r')
01021                do ii = 1, par%npoints + par%nrugauge
01022                   ! wwvv above line should probably be
01023                   !  do ii = 1, par%npoints + par%nrugauge
01024                   !  have to check this with trunk
01025                   if(xomaster) then
01026                      pointoutputs(i,ii)%name = mnem
01027                      pointoutputs(i,ii)%rank = t%rank
01028                   endif
01029                   if (xomaster) then
01030                      xpii = xpoints(ii)
01031                      ypii = ypoints(ii)
01032                   endif
01033 #ifdef USEMPI
01034                   call xmpi_bcast(xpii,xmpi_omaster,xmpi_ocomm)
01035                   call xmpi_bcast(ypii,xmpi_omaster,xmpi_ocomm)
01036                   call space_who_has(sl,xpii,ypii,pii)
01037                   if (xmpi_orank .eq. pii) then
01038                      call space_global_to_local(sl, xpii, ypii, ilocal,jlocal)
01039                   endif
01040 #else
01041                   ilocal = xpii
01042                   jlocal = ypii
01043                   pii    = xmpi_orank
01044 #endif
01045                   select case(t%rank)
01046                    case(2)
01047 #ifdef USEMPI
01048                      if(xmpi_orank .eq. pii) then
01049                         allocate(r2(1,1))
01050                         call gridrotate(par, sl, t, r2, ilocal, jlocal)
01051                         call xmpi_send(pii,xmpi_omaster,r2)
01052                      elseif(xomaster) then
01053                         allocate(pointoutputs(i,ii)%r2(1,1))
01054                         call xmpi_send(pii,xmpi_omaster,pointoutputs(i,ii)%r2)
01055                      endif
01056                      if (xmpi_orank .eq. pii) deallocate(r2)
01057 #else
01058                      allocate(pointoutputs(i,ii)%r2(1,1))
01059                      call gridrotate(par, sl, t, pointoutputs(i,ii)%r2, ilocal, jlocal)
01060 #endif
01061                    case(3)
01062 #ifdef USEMPI
01063                      if (xmpi_orank .eq. pii) then
01064                         allocate(r3(1,1,size(t%r3,3)))
01065                         call gridrotate(par, sl, t, r3, ilocal, jlocal)
01066                         call xmpi_send(pii,xmpi_omaster,r3)
01067                      elseif(xomaster) then
01068                         allocate(pointoutputs(i,ii)%r3(1,1,size(t%r3,3)))
01069                         call xmpi_send(pii,xmpi_omaster,pointoutputs(i,ii)%r3)
01070                      endif
01071                      if (xmpi_orank .eq. pii) deallocate(r3)
01072 #else
01073                      allocate(pointoutputs(i,ii)%r3(1,1,size(t%r3,3)))
01074                      call gridrotate(par, sl, t, pointoutputs(i,ii)%r3, ilocal, jlocal)
01075 #endif
01076                    case(4)
01077 #ifdef USEMPI
01078                      if (xmpi_orank .eq. pii) then
01079                         allocate(r4(1,1,size(t%r4,3),size(t%r4,4)))
01080                         call gridrotate(t, r4, ilocal, jlocal)
01081                         call xmpi_send(pii,xmpi_omaster,r4)
01082                      elseif(xomaster) then
01083                         allocate(pointoutputs(i,ii)%r4(1,1,size(t%r4,3),size(t%r4,4)))
01084                         call xmpi_send(pii,xmpi_omaster,pointoutputs(i,ii)%r4)
01085                      endif
01086                      if (xmpi_orank .eq. pii) deallocate(r4)
01087 #else
01088                      allocate(pointoutputs(i,ii)%r4(1,1,size(t%r3,3),size(t%r4,4)))
01089                      call gridrotate(t, pointoutputs(i,ii)%r4, ilocal, jlocal)
01090 #endif
01091                    case default
01092                      write(0,*) 'Can''t handle rank: ', t%rank, ' of mnemonic', mnem
01093                   end select
01094                end do
01095              case default
01096                write(0,*) 'Can''t handle type: ', t%type, ' of mnemonic', mnem
01097             end select
01098          enddo ! i=1,par%npointvar
01099          !  Here follows go the code to determine the runup values and put them
01100          !    in runups(:,1:par%nrugauge)
01101          !
01102          !   This code assumes that hh and zs are available on xomaster
01103          !     we will change this asap
01104       endif ! dooutput_point
01105 
01106       ! writing is done by xomaster, the others processes go back to work
01107 
01108       if( .not. xomaster) return
01109 
01110       ! Open the output file
01111 
01112 #ifdef USENETCDF
01113       if(donetcdf) then
01114          NF90(nf90_open(ncid=ncid, path=par%ncfilename, mode=nf90_write))
01115       endif
01116 #endif
01117 
01118       !
01119       ! some variables can only be output if others are available, see the code
01120       ! for gridrotate.
01121       !
01122       if (dooutput_global) then
01123          itg = itg+1
01124          ! Store the time (in morphological time)
01125 #ifdef USENETCDF
01126          if(donetcdf) then
01127             NF90(nf90_put_var(ncid, globaltimevarid, CONVREAL(par%t*max(par%morfac,1.d0)), (/tpar%itg/)))
01128          endif
01129 #endif
01130          ! write global output variables
01131          do i=1,par%nglobalvar
01132             mnem = par%globalvars(i)
01133             j    = chartoindex(mnem)
01134             ! lookup the proper array (should have been collected already)
01135             call indextos(s,j,t)
01136 
01137             select case(t%type)
01138              case('i')
01139                select case(t%rank)
01140                 case(0)
01141                   ! no need to allocate here
01142                   call gridrotate(t,i0)
01143 #ifdef USENETCDF
01144                   if(donetcdf) then
01145                      NF90(nf90_put_var(ncid, globalvarids(i), i0, start=(/1,tpar%itg/) ))
01146                   endif
01147 #endif
01148                   if(dofortran) then
01149                      inquire(iolength=reclen) i0
01150                      call checkfile(i,unit,reclen,jtg)
01151                      write(unit,rec=jtg) i0
01152                      call flush(unit)
01153                   endif
01154                 case(2)
01155                   allocate(i2(size(t%i2,1),size(t%i2,2)))
01156                   call gridrotate(t, i2)
01157 #ifdef USENETCDF
01158                   if(donetcdf) then
01159                      NF90(nf90_put_var(ncid, globalvarids(i), i2, start=(/1,1,tpar%itg/) ))
01160                   endif
01161 #endif
01162                   if(dofortran) then
01163                      inquire(iolength=reclen) i2
01164                      call checkfile(i,unit,reclen,jtg)
01165                      write(unit,rec=jtg) i2
01166                      call flush(unit)
01167                   endif
01168                   deallocate(i2)
01169                 case(3)
01170                   allocate(i3(size(t%i3,1),size(t%i3,2),size(t%i3,3)))
01171                   call gridrotate(t, i3)
01172 #ifdef USENETCDF
01173                   if(donetcdf) then
01174                      NF90(nf90_put_var(ncid, globalvarids(i), i3, start=(/1,1,1,tpar%itg/) ))
01175                   endif
01176 #endif
01177                   if(dofortran) then
01178                      inquire(iolength=reclen) i3
01179                      call checkfile(i,unit,reclen,jtg)
01180                      write(unit,rec=jtg) i3
01181                      call flush(unit)
01182                   endif
01183                   deallocate(i3)
01184                 case default
01185                   write(0,*) 'Can''t handle rank: ', t%rank, ' of mnemonic', mnem
01186                end select
01187              case('r')
01188                select case(t%rank)
01189                 case(0)
01190                   ! no need to allocate here
01191                   r0conv = CONVREAL(t%r0)
01192 #ifdef USENETCDF
01193                   if(donetcdf) then
01194                      NF90(nf90_put_var(ncid, globalvarids(i), r0conv, start=(/1,tpar%itg/) ))
01195                   endif
01196 #endif
01197                   if(dofortran) then
01198                      inquire(iolength=reclen) r0conv
01199                      call checkfile(i,unit,reclen,jtg)
01200                      write(unit,rec=jtg) r0conv
01201                      call flush(unit)
01202                   endif
01203                 case(1)
01204                   allocate(r1(size(t%r1,1)))
01205                   allocate(r1conv(size(t%r1,1)))
01206                   ! no need to rotate here
01207                   r1conv = CONVREAL(t%r1)
01208 #ifdef USENETCDF
01209                   if(donetcdf) then
01210                      NF90(nf90_put_var(ncid, globalvarids(i), r1conv, start=(/1,tpar%itg/) ))
01211                   endif
01212 #endif
01213                   if(dofortran) then
01214                      inquire(iolength=reclen) r1conv
01215                      call checkfile(i,unit,reclen,jtg)
01216                      write(unit,rec=jtg) r1conv
01217                      call flush(unit)
01218                   endif
01219                   deallocate(r1)
01220                   deallocate(r1conv)
01221                 case(2)
01222                   allocate(r2    (size(t%r2,1),size(t%r2,2)))
01223                   allocate(r2conv(size(t%r2,1),size(t%r2,2)))
01224                   call gridrotate(par, s, t, r2)
01225                   if(par%remdryoutput==1) then
01226                      call postprocessvar_r2(s%wetz,t%name,r2,dFill)
01227                   endif
01228                   r2conv = CONVREAL(r2)
01229 #ifdef USENETCDF
01230                   if(donetcdf) then
01231                      NF90(nf90_put_var(ncid, globalvarids(i), r2conv, start=(/1,1,tpar%itg/) ))
01232                   endif
01233 #endif
01234                   if(dofortran) then
01235                      inquire(iolength=reclen) r2conv
01236                      call checkfile(i,unit,reclen,jtg)
01237                      write(unit,rec=jtg) r2conv
01238                      call flush(unit)
01239                   endif
01240                   deallocate(r2)
01241                   deallocate(r2conv)
01242                 case(3)
01243                   allocate(r3    (size(t%r3,1),size(t%r3,2),size(t%r3,3)))
01244                   allocate(r3conv(size(t%r3,1),size(t%r3,2),size(t%r3,3)))
01245                   call gridrotate(par, s, t, r3)
01246                   r3conv = CONVREAL(r3)
01247 #ifdef USENETCDF
01248                   if(donetcdf) then
01249                      NF90(nf90_put_var(ncid, globalvarids(i), r3conv, start=(/1,1,1, tpar%itg/) ))
01250                   endif
01251 #endif
01252                   if(dofortran) then
01253                      inquire(iolength=reclen) r3conv
01254                      call checkfile(i,unit,reclen,jtg)
01255                      write(unit,rec=jtg) r3conv
01256                      call flush(unit)
01257                   endif
01258                   deallocate(r3)
01259                   deallocate(r3conv)
01260                 case(4)
01261                   allocate(r4    (size(t%r4,1),size(t%r4,2),size(t%r4,3),size(t%r4,4)))
01262                   allocate(r4conv(size(t%r4,1),size(t%r4,2),size(t%r4,3),size(t%r4,4)))
01263                   call gridrotate(t, r4)
01264                   r4conv = CONVREAL(r4)
01265 #ifdef USENETCDF
01266                   if(donetcdf) then
01267                      NF90(nf90_put_var(ncid, globalvarids(i), r4conv, start=(/1,1,1,1, tpar%itg/) ))
01268                   endif
01269 #endif
01270                   if(dofortran) then
01271                      inquire(iolength=reclen) r4conv
01272                      call checkfile(i,unit,reclen,jtg)
01273                      write(unit,rec=jtg) r4conv
01274                      call flush(unit)
01275                   endif
01276                   deallocate(r4)
01277                   deallocate(r4conv)
01278                 case default
01279                   write(0,*) 'Can''t handle rank: ', t%rank, ' of mnemonic', mnem
01280                end select
01281              case default
01282                write(0,*) 'Can''t handle type: ', t%type, ' of mnemonic', mnem
01283             end select
01284          end do
01285       end if   ! dooutput_global
01286 
01287 
01288       if(dooutput_point) then
01289          itp = itp+1
01290 
01291 #ifdef USENETCDF
01292          if(donetcdf) then
01293             NF90(nf90_put_var(ncid, pointtimevarid, CONVREAL(par%t*max(par%morfac,1.d0)), (/tpar%itp/)))
01294          endif
01295 #endif
01296 
01297          if(dofortran_compat) then
01298             if (par%npoints .gt. 0) then
01299                allocate(points(par%npoints,par%npointvar+1))
01300             else
01301                allocate(points(0,0))
01302             endif
01303          else
01304             allocate(points(0,0))
01305          endif
01306 
01307          do i=1,par%npointvar
01308             mnem = par%pointvars(i)
01309             j    = chartoindex(mnem)
01310             ! lookup the proper array
01311             call indextos(s,j,t)
01312             ! get the proper output points ....
01313             ! I have no idea what is happening in varouput so I'll try it in a different way
01314             !TODO This is not very efficient because we are using the outer counters, reorder dimensions....
01315             !
01316             select case(t%type)
01317              case('r')
01318                do ii = 1, par%npoints + par%nrugauge
01319                   select case(t%rank)
01320                    case(2)
01321                      ! This postprocessing creates an ugly dependency.
01322                      ! it would be nice if we could call gridrotate as a function
01323                      ! or if we could just have the postprocessing insert some reference processing routines to call
01324                      ! or if we could split this out of the case statement (dry)
01325                      ! or if we could defer this to a postprocessing routine (for example ncks)
01326 
01327 #ifdef USENETCDF
01328                      if (donetcdf) then
01329                         NF90(nf90_put_var(ncid, pointsvarids(i), CONVREAL(pointoutputs(i,ii)%r2(1,1)), start=(/ii,tpar%itp/) ))
01330                      endif
01331 #endif
01332                      if(dofortran_compat) then
01333                         if (ii .le. par%npoints) then
01334                            !points(ii,i+1) = r2(xpoints(ii), ypoints(ii))
01335                            points(ii,i+1) = pointoutputs(i,ii)%r2(1,1)
01336                         endif
01337                      endif
01338                    case(3)
01339 #ifdef USENETCDF
01340                      if (donetcdf) then
01341                         NF90(nf90_put_var(ncid, pointsvarids(i), CONVREAL(r3(xpoints(ii), ypoints(ii),:)), start=(/ii,1,tpar%itp/)))
01342                      endif
01343 #endif
01344                      if(dofortran_compat) then
01345                         if (ii .le. par%npoints) then
01346                            points(ii,i+1) = r3(xpoints(ii), ypoints(ii),1)    ! wwvv todo
01347                         endif
01348                      endif
01349                    case(4)
01350 #ifdef USENETCDF
01351                      if (donetcdf) then
01352                         status      = nf90_put_var(ncid, pointsvarids(i), &
01353                         &                          CONVREAL(r4(xpoints(ii), ypoints(ii),:,:)), &
01354                         &                          start=(/ii,1,1,tpar%itp/) )
01355                         if (status /= nf90_noerr) call handle_err(status,__FILE__,__LINE__)
01356                      endif
01357 #endif
01358                      if(dofortran_compat) then
01359                         if (ii .le. par%npoints) then
01360                            points(ii,i+1) = r4(xpoints(ii), ypoints(ii),1,1)    ! wwvv todo
01361                         endif
01362                      endif
01363                    case default
01364                      write(0,*) 'Can''t handle rank: ', t%rank, ' of mnemonic', mnem
01365                   end select
01366                end do
01367              case default
01368                write(0,*) 'Can''t handle type: ', t%type, ' of mnemonic', mnem
01369             end select
01370          enddo ! i=1,par%npointvar
01371 
01372          if(dofortran_compat) then
01373             do ii = 1,par%npoints
01374                if (par%morfacopt==1) then
01375                   points(ii,1) = par%t*max(par%morfac,1.d0)
01376                else
01377                   points(ii,1) = par%t
01378                endif
01379             enddo
01380             do ii = 1,par%npoints
01381                write(indextopointsunit(ii),rec=tpar%itp)CONVREAL(points(ii,:))
01382                call flush(indextopointsunit(ii))
01383             enddo
01384             deallocate(points)
01385 
01386             ! WD: new code
01387             do ii=1,par%nrugauge
01388                write(indextopointsunit(ii+par%npoints),rec=tpar%itp)CONVREAL(runups(:,ii))
01389                call flush(indextopointsunit(i+par%npoints))
01390             enddo
01391             ! WD: /new code
01392          endif ! dofortran
01393       endif   ! dooutput_point
01394 
01395 
01396 #ifdef USENETCDF
01397       if(dooutput_mean .and. donetcdf) then
01398          ! Store the time (in morphological time)
01399          NF90(nf90_put_var(ncid, meantimevarid, CONVREAL(par%t*max(par%morfac,1.d0)), (/tpar%itm-1/)))
01400          ! write global output variables
01401          do i=1,par%nmeanvar
01402             t = meansparsglobal(i)%t
01403             do j=1,nmeanvartypes
01404 
01405                select case(t%type)
01406                 case('r')
01407                   select case(t%rank)
01408                    case(2)
01409                      select case(meanvartypes(j))
01410                       case('mean')
01411                         if ((t%name .eq. 'H') .or. (t%name .eq. 'urms'))  then
01412                            status      = nf90_put_var(ncid, meanvarids(i,j), &
01413                            &                          CONVREAL(sqrt(meansparsglobal(i)%variancesquareterm2d)), &
01414                            &                          start=(/1,1,tpar%itm-1/) )
01415                            if (status /= nf90_noerr) call handle_err(status,__FILE__,__LINE__)
01416                         elseif (t%name .eq. 'thetamean') then
01417                            status = nf90_put_var(ncid, meanvarids(i,j), &
01418                            &                     CONVREAL( &
01419                            &                     mod(2.d0*par%px &
01420                            &                     + atan2(nint(meansparsglobal(i)%mean2d)/1d7, &
01421                            &                     mod(meansparsglobal(i)%mean2d,1.d0)*1d1), 2.d0*par%px) / par%px * 180), &
01422                            &                     start=(/1,1,tpar%itm-1/) )
01423                            if (status /= nf90_noerr) call handle_err(status,__FILE__,__LINE__)
01424                         else
01425                            NF90(nf90_put_var(ncid, meanvarids(i,j), CONVREAL(meansparsglobal(i)%mean2d),start=(/1,1,tpar%itm-1/)))
01426                         end if
01427                       case('var')
01428                         NF90(nf90_put_var(ncid, meanvarids(i,j), CONVREAL(meansparsglobal(i)%variance2d),start=(/1,1,tpar%itm-1/)))
01429                       case('min')
01430                         NF90(nf90_put_var(ncid, meanvarids(i,j), CONVREAL(meansparsglobal(i)%min2d),start=(/1,1,tpar%itm-1/)))
01431                       case('max')
01432                         NF90(nf90_put_var(ncid, meanvarids(i,j), CONVREAL(meansparsglobal(i)%max2d),start=(/1,1,tpar%itm-1/)))
01433                       case default
01434                         write(0,*) 'Can''t handle cell method: ', trim(meanvartypes(j)), ' of mnemonic', trim(t%name)
01435                      end select
01436                    case(3)
01437                      select case(meanvartypes(j))
01438                       case('mean')
01439                         NF90(nf90_put_var(ncid, meanvarids(i,j), CONVREAL(meansparsglobal(i)%mean3d), start=(/1,1,1,tpar%itm-1/) ))
01440                       case('var')
01441                         NF90(nf90_put_var(ncid,meanvarids(i,j),CONVREAL(meansparsglobal(i)%variance3d),start=(/1,1,1,tpar%itm-1/)))
01442                       case('min')
01443                         NF90(nf90_put_var(ncid, meanvarids(i,j), CONVREAL(meansparsglobal(i)%min3d), start=(/1,1,1,tpar%itm-1/) ))
01444                       case('max')
01445                         NF90(nf90_put_var(ncid, meanvarids(i,j), CONVREAL(meansparsglobal(i)%max3d), start=(/1,1,1,tpar%itm-1/) ))
01446                       case default
01447                         write(0,*) 'Can''t handle cell method: ', trim(meanvartypes(j)), ' of mnemonic', trim(t%name)
01448                      end select
01449                    case(4)
01450                      select case(meanvartypes(j))
01451                       case('mean')
01452                         NF90(nf90_put_var(ncid, meanvarids(i,j),CONVREAL(meansparsglobal(i)%mean4d), start=(/1,1,1,1,tpar%itm-1/)))
01453                       case('var')
01454                         NF90(nf90_put_var(ncid,meanvarids(i,j),CONVREAL(meansparsglobal(i)%variance4d),start=(/1,1,1,1,tpar%itm-1/)))
01455                       case('min')
01456                         NF90(nf90_put_var(ncid, meanvarids(i,j), CONVREAL(meansparsglobal(i)%min4d), start=(/1,1,1,1,tpar%itm-1/)))
01457                       case('max')
01458                         NF90(nf90_put_var(ncid, meanvarids(i,j), CONVREAL(meansparsglobal(i)%max4d), start=(/1,1,1,1,tpar%itm-1/)))
01459                       case default
01460                         write(0,*) 'Can''t handle cell method: ', trim(meanvartypes(j)), ' of mnemonic', trim(t%name)
01461                      end select
01462                    case default
01463                      write(0,*) 'Can''t handle rank: ', t%rank, ' of mnemonic', mnem
01464                   end select
01465                 case default
01466                   write(0,*) 'Can''t handle type: ', t%type, ' of mnemonic', mnem
01467                end select
01468             end do
01469          end do
01470       endif ! dooutput_mean .and. donetcdf
01471 #endif
01472 
01473       !if (par%nmeanvar>0 .and. dofortran .and. tpar%output) then
01474       ! Not at the first in tpm as this is the start of averaging. Only output after second in tpm
01475       if(dooutput_mean .and. dofortran_compat) then
01476          itm=itm+1  ! Note, this is a local counter, used to position in output file
01477          do i=1,par%nmeanvar
01478             select case (meansparsglobal(i)%rank)
01479              case (2)
01480                if (par%meanvars(i)=='H') then                ! Hrms changed to H
01481                   write(indextomeanunit(i),rec=itm)CONVREAL(sqrt(meansparsglobal(i)%variancesquareterm2d))
01482                elseif (par%meanvars(i)=='urms') then       ! urms
01483                   write(indextomeanunit(i),rec=itm)CONVREAL(sqrt(meansparsglobal(i)%variancesquareterm2d))
01484                elseif (par%meanvars(i)=='thetamean') then       ! thetamean
01485                   write(indextomeanunit(i),rec=itm) &
01486                   &  CONVREAL( &
01487                   &            mod(2.d0*par%px + atan2(nint(meansparsglobal(i)%mean2d)/1d7, &
01488                   &            mod(meansparsglobal(i)%mean2d,1.d0)*1d1), 2.d0*par%px) / par%px * 180 &
01489                   &  )
01490                else                                                    ! non-rms variables
01491                   write(indextomeanunit(i),rec=itm)CONVREAL(meansparsglobal(i)%mean2d)
01492                endif
01493                write(indextovarunit(i),rec=itm)CONVREAL(meansparsglobal(i)%variance2d)
01494                where(meansparsglobal(i)%min2d>0.99d0*huge(0.d0))
01495                   meansparsglobal(i)%min2d=-999.d0
01496                endwhere
01497                where(meansparsglobal(i)%max2d<-0.99d0*huge(0.d0))
01498                   meansparsglobal(i)%max2d=-999.d0
01499                endwhere
01500                write(indextominunit(i),rec=itm)CONVREAL(meansparsglobal(i)%min2d)
01501                write(indextomaxunit(i),rec=itm)CONVREAL(meansparsglobal(i)%max2d)
01502              case (3)
01503                write(indextomeanunit(i),rec=itm)CONVREAL(meansparsglobal(i)%mean3d)
01504                write(indextovarunit(i),rec=itm)CONVREAL(meansparsglobal(i)%variance3d)
01505                where(meansparsglobal(i)%min3d>0.99d0*huge(0.d0))
01506                   meansparsglobal(i)%min3d=-999.d0
01507                endwhere
01508                where(meansparsglobal(i)%max3d<-0.99d0*huge(0.d0))
01509                   meansparsglobal(i)%max3d=-999.d0
01510                endwhere
01511                write(indextominunit(i),rec=itm)CONVREAL(meansparsglobal(i)%min3d)
01512                write(indextomaxunit(i),rec=itm)CONVREAL(meansparsglobal(i)%max3d)
01513              case (4)
01514                write(indextomeanunit(i),rec=itm)CONVREAL(meansparsglobal(i)%mean4d)
01515                write(indextovarunit(i),rec=itm)CONVREAL(meansparsglobal(i)%variance4d)
01516                where(meansparsglobal(i)%min4d>0.99d0*huge(0.d0))
01517                   meansparsglobal(i)%min4d=-999.d0
01518                endwhere
01519                where(meansparsglobal(i)%max4d<-0.99d0*huge(0.d0))
01520                   meansparsglobal(i)%max4d=-999.d0
01521                endwhere
01522                write(indextominunit(i),rec=itm)CONVREAL(meansparsglobal(i)%min4d)
01523                write(indextomaxunit(i),rec=itm)CONVREAL(meansparsglobal(i)%max4d)
01524             end select
01525             call flush(indextomeanunit(i))
01526             call flush(indextovarunit(i))
01527             call flush(indextominunit(i))
01528             call flush(indextomaxunit(i))
01529          enddo
01530          par%tintm = tpar%tpm(min(itm+2,stpm))-tpar%tpm(itm+1)  ! Next averaging period (min to stop array out of bounds)
01531          par%tintm = max(par%tintm,tiny(0.d0))                  ! to prevent par%tintm=0 after last output
01532       endif  ! dooutput_mean .and. dofortran_compat
01533 
01534       if (dooutput_hotstart) then
01535           call hotstartfiles_write(s,par, tpar)
01536       endif
01537 
01538       if (dooutput_drifter) then
01539          itd = itd+1
01540 #ifdef USENETCDF
01541          if (donetcdf) then
01542             ! output time:
01543             NF90(nf90_put_var(ncid, drifterstimevarid, CONVREAL(par%t), start=(/itd/)))
01544          endif
01545 #endif
01546          do i=1,par%ndrifter
01547             if (  par%t>=s%tdriftb(i) .and. par%t<=s%tdrifte(i) .and. &
01548             &     s%idrift(i)>1       .and. s%idrift(i)<=s%nx   .and. &
01549             &     s%jdrift(i)>1       .and. s%jdrift(i)<=s%ny             ) then
01550 
01551                iz = int(s%idrift(i))
01552                jz = int(s%jdrift(i))
01553 
01554                di = mod(s%idrift(i),1.d0)
01555                dj = mod(s%jdrift(i),1.d0)
01556 
01557                dx = di*s%dsu(iz,jz)*cos(s%alfaz(iz,jz)) - &
01558                &    dj*s%dnv(iz,jz)*sin(s%alfaz(iz,jz))
01559                dy = di*s%dsu(iz,jz)*sin(s%alfaz(iz,jz)) + &
01560                &    dj*s%dnv(iz,jz)*cos(s%alfaz(iz,jz))
01561 
01562                drift(1) = s%xz(iz,jz)+dx
01563                drift(2) = s%yz(iz,jz)+dy
01564                drift(3) = par%t
01565             else
01566                drift(1) = -999
01567                drift(2) = -999
01568                drift(3) = par%t
01569             endif
01570 
01571             if (dofortran_compat) then
01572                write(indextodrifterunit(i),rec=itd) CONVREAL(drift)
01573                call flush(indextodrifterunit(i))
01574             endif
01575 #ifdef USENETCDF
01576             if (donetcdf) then
01577                ! output x,y:
01578                NF90(nf90_put_var(ncid,driftersvarids(i),CONVREAL(drift(1:2)),start=(/1,itd/)))
01579             endif
01580 #endif
01581 
01582          enddo
01583       endif
01584 #ifdef USENETCDF
01585       if(donetcdf) then
01586          NF90(nf90_close(ncid=ncid))
01587       endif
01588 #endif
01589 
01590       if(dofortran_compat) then
01591          outputtimes                                = -999.d0
01592          outputtimes(1:itg)                         = tpar%tpg(1:itg)
01593          outputtimes(itg+1:itg+itp)                 = tpar%tpp(1:itp)
01594          outputtimes(itg+itp+1:itg+itp+itm)         = tpar%tpm(2:itm+1)          ! mean output always shifted by 1
01595 
01596          if (par%morfacopt==1) outputtimes=outputtimes*max(par%morfac,1.d0)
01597 
01598          open(1998,file='dims.dat',form='unformatted',access='direct',recl=wordsize*(10+size(outputtimes)))
01599          write(1998,rec=1) CONVREAL(itg*1.d0),&
01600          &                 CONVREAL(s%nx*1.d0),&
01601          &                 CONVREAL(s%ny*1.d0),&
01602          &                 CONVREAL(s%ntheta*1.d0),&
01603          &                 CONVREAL(par%kmax*1.d0),&
01604          &                 CONVREAL(par%ngd*1.d0),&
01605          &                 CONVREAL(par%nd*1.d0), &
01606          &                 CONVREAL(itp*1.d0),&
01607          &                 CONVREAL(itc*1.d0),&
01608          &                 CONVREAL(itm*1.d0),&
01609          &                 CONVREAL(outputtimes)
01610          call flush(1998)
01611       endif
01612       ! wwvv avoid warning about unused sl:
01613       if (sl%nx .eq. -1) return
01614    end subroutine ncoutput
01615 
01616 #ifdef USENETCDF
01617    character(slen) function dimensionnames(dimids)
01618       implicit none
01619       integer, dimension(:), intent(in)           :: dimids ! store the dimids in a vector
01620 
01621       integer :: i
01622       character(slen)  :: dimensionname
01623       ! combine all the dimensionnames
01624       ! assumes all dimensions have an accompanying variable that should be used for coordinates.
01625       ! ",".join would have been nice here....
01626       dimensionnames = ''
01627       ! Fortran array dimensions are in reverse order
01628       do i=size(dimids),2,-1
01629          NF90(nf90_inquire_dimension(ncid, dimids(i), name=dimensionname))
01630          dimensionnames = trim(dimensionnames) // trim(dimensionname) // ','
01631       end do
01632       NF90(nf90_inquire_dimension(ncid, dimids(1), name=dimensionname))
01633       dimensionnames = trim(dimensionnames) // trim(dimensionname)
01634    end function dimensionnames
01635 
01636    integer function dimensionid(expression)
01637       ! Function to transform the expression in spaceparams.tmpl to an id, we might want this in the
01638       ! makeincludes module
01639       use logging_module, only: writelog
01640       implicit none
01641       character(len=*),intent(in) :: expression
01642       select case(expression)
01643        case('s%nx+1')
01644          dimensionid = xdimid
01645        case('s%ny+1')
01646          dimensionid = ydimid
01647        case('s%ntheta')
01648          dimensionid = thetadimid
01649        case('s%tidelen')
01650          dimensionid = tidetimedimid
01651        case('par%tideloc')
01652          dimensionid = tidecornersdimid
01653        case('s%windlen')
01654          dimensionid = windtimedimid
01655        case('par%ngd')
01656          dimensionid = sedimentclassesdimid
01657        case('s%ntdisch')
01658          dimensionid = inoutdimid
01659        case('2')
01660          dimensionid = inoutdimid
01661        case('par%nd')
01662          dimensionid = bedlayersdimid
01663        case('par%ndrifter')
01664          dimensionid = driftersdimid
01665        case('par%nship')
01666          dimensionid = shipdimid
01667        case('par%nz')
01668          dimensionid = Q3Ddimid
01669        case('s%nsecvegmax')
01670          dimensionid = vegdimid
01671        case default
01672          call writelog('els','','Unknown dimension expression:'  // expression)
01673          stop 1
01674       end select
01675    end function dimensionid
01676 #endif
01677    ! USENETCDF
01678 
01679    subroutine points_output_init(s,par)
01680       ! this initialize things for point output
01681       ! has to be called before fourtoutput_init and ncoutput_init
01682       use spaceparams
01683       use params,         only: parameters
01684       use postprocessmod, only: snappointstogrid
01685       use xmpi_module
01686 
01687       type(spacepars), intent(in) :: s
01688       type(parameters),intent(in) :: par
01689 
01690       allocate(rugrowindex(par%nrugauge))
01691 
01692       allocate(xpoints(par%npoints+par%nrugauge))
01693       allocate(ypoints(par%npoints+par%nrugauge))
01694 
01695       ! Convert world coordinates of points to nearest (lsm) grid point
01696       if(xomaster) then
01697          call snappointstogrid(par, s, xpoints, ypoints)
01698       endif
01699 
01700       if(xomaster) then
01701          if (par%nrugauge>0) then
01702             rugrowindex = ypoints(par%npoints+1:)
01703             !do i=1,par%nrugauge
01704             !   rugrowindex(i)=ypoints(par%npoints+i)
01705             !enddo
01706          endif
01707       endif
01708 #ifdef USEMPI
01709       call xmpi_bcast(rugrowindex,xmpi_omaster,xmpi_ocomm)
01710       call xmpi_bcast(xpoints,    xmpi_omaster,xmpi_ocomm)
01711       call xmpi_bcast(ypoints,    xmpi_omaster,xmpi_ocomm)
01712 #endif
01713    end subroutine points_output_init
01714 
01715    subroutine fortoutput_init(s,par,tpar)
01716       use params,          only: parameters
01717       use spaceparams
01718       use readkey_module
01719       use timestep_module, only: timepars
01720       use logging_module
01721       use postprocessmod
01722       use filefunctions,   only: create_new_fid
01723       use mnemmodule,      only: arraytype, chartoindex
01724       use xmpi_module
01725 
01726       implicit none
01727 
01728       type(spacepars),intent(in)          :: s
01729       type(parameters),intent(in)         :: par
01730       type(timepars),intent(in)           :: tpar
01731 
01732       integer                             :: i,fid
01733       integer                             :: reclen,reclenm,reclenp
01734       character(100)                      :: fname,fnamemean,fnamevar,fnamemin,fnamemax
01735       type(arraytype)                     :: t
01736 
01737       if (.not. xomaster) return
01738 
01739       reclenm = -123
01740 
01741       ! Initialize places in output files
01742       itg = 0
01743       itm = 0
01744       itp = 0
01745       itc = 0
01746       itd = 0
01747       stpm = size(tpar%tpm)
01748 
01749       ! Record size for global and mean output
01750       inquire(iolength=wordsize) CONVREAL(1.0d0)
01751       reclen=wordsize*(s%nx+1)*(s%ny+1)
01752 
01753       open(100,file='xy.dat',form='unformatted',access='direct',recl=reclen,status='REPLACE')
01754       write(100,rec=1)CONVREAL(s%xz)
01755       write(100,rec=2)CONVREAL(s%yz)
01756       write(100,rec=3)CONVREAL(s%x)
01757       write(100,rec=4)CONVREAL(s%y)
01758       close(100)
01759 
01760       !     GLOBAL VARS
01761 
01762       noutnumbers = par%nglobalvar
01763       ! store all indices for the global variables
01764       do i= 1,noutnumbers
01765          outnumbers(i) = chartoindex(par%globalvars(i))
01766       enddo
01767 
01768       do i=1,par%npoints+par%nrugauge
01769          fname = trim(par%stationid(i)) // '.dat'
01770          if (par%pointtypes(i)==0) then
01771             reclenp=wordsize*(par%npointvar+1)
01772          else
01773             reclenp=wordsize*(1+par%nrugdepth*3)
01774          endif
01775          open(indextopointsunit(i),file=fname,&
01776          &    form='unformatted',access='direct',recl=reclenp,status='REPLACE')
01777       enddo
01778       if (par%npoints>0) then
01779          ! write index file of point output variables
01780          fid = create_new_fid()
01781          open(fid,file='pointvars.idx',status='replace',action='write')
01782          do i=1,par%npointvar
01783             write(fid,*)trim(par%pointvars(i))
01784          enddo
01785          close(fid)
01786       endif
01787 
01788       ! TIME-AVERAGE, VARIANCE and MIN-MAX ARRAYS
01789 
01790       if (par%nmeanvar>0) then
01791          !! First time file opening for time-average output
01792          do i=1,par%nmeanvar
01793             call makeaveragenames(chartoindex(par%meanvars(i)),fnamemean,fnamevar,fnamemin,fnamemax)
01794             call indextos(s,chartoindex(par%meanvars(i)),t)
01795             reclenm = wordsize
01796             select case(t%rank)
01797              case (2)
01798                reclenm = wordsize*size(t%r2)
01799              case (3)
01800                reclenm = wordsize*size(t%r3)
01801              case (4)
01802                reclenm = wordsize*size(t%r4)
01803             end select
01804             open(indextomeanunit(i),file=fnamemean, form='unformatted',access='direct',recl=reclenm,status='REPLACE')
01805             open(indextovarunit(i), file=fnamevar,  form='unformatted',access='direct',recl=reclenm,status='REPLACE')
01806             open(indextominunit(i), file=fnamemin,  form='unformatted',access='direct',recl=reclenm,status='REPLACE')
01807             open(indextomaxunit(i), file=fnamemax,  form='unformatted',access='direct',recl=reclenm,status='REPLACE')
01808          enddo
01809       endif ! par%nmeanvar > 0
01810 
01811       !
01812       ! drifter output files
01813       !
01814       if (par%ndrifter>0) then
01815          reclen=wordsize*3
01816          do i=1,par%ndrifter
01817             write(fname,'("drifter",i0.3,".dat")') i
01818             open(indextodrifterunit(i),file=fname,form='unformatted',access='direct',recl=reclen,status='REPLACE')
01819          enddo
01820       endif ! par%ndrifter >0
01821       
01822 
01823    end subroutine fortoutput_init
01824 
01825    subroutine checkfile(index,unit,reclen,jtg)
01826       implicit none
01827       integer, intent(in)  :: index,reclen
01828       integer, intent(out) :: unit,jtg
01829       logical              :: lopen
01830       character(len=1000)  :: filename
01831 
01832       unit = indextoglobalunit(index)
01833       inquire(unit=unit, opened=lopen)
01834       if ( .not. lopen ) then
01835          filename = trim(mnemonics(outnumbers(index)))//'.dat'
01836          open(unit, file=filename,form='unformatted',&
01837          &    access='direct',recl=reclen)
01838       endif
01839       inquire(unit=unit,nextrec=jtg)
01840    end subroutine checkfile
01841 
01842    integer function outunit(ind,s)
01843       !
01844       ! given the type of output file 's' and the index 'ind'
01845       ! returns the appopriate file unit number
01846       !
01847       implicit none
01848       integer, intent(in)      :: ind
01849       character(*), intent(in) :: s
01850 
01851       integer, parameter :: offset = 10000
01852       select case(s)
01853        case('points')
01854          outunit = offset +              ind
01855        case('global')
01856          outunit = offset + 10*numvars + ind
01857        case('mean')
01858          outunit = offset + 20*numvars + ind
01859        case('min')
01860          outunit = offset + 30*numvars + ind
01861        case('max')
01862          outunit = offset + 40*numvars + ind
01863        case('var')
01864          outunit = offset + 50*numvars + ind
01865        case('drifter')
01866          outunit = offset + 60*numvars + ind
01867        case('hotstart')
01868          outunit = offset + 70*numvars + ind
01869        case default
01870          print *,'internal error in outunit: no such type: ',trim(s)
01871          outunit = -1
01872          call halt_program
01873       end select
01874    end function outunit
01875 
01876    integer function indextopointsunit(index)
01877       implicit none
01878       integer, intent(in) :: index
01879       indextopointsunit = outunit(index,'points')
01880    end function indextopointsunit
01881 
01882    integer function indextoglobalunit(index)
01883       implicit none
01884       integer, intent(in) :: index
01885       indextoglobalunit = outunit(index,'global')
01886    end function indextoglobalunit
01887 
01888    integer function indextomeanunit(index)
01889       implicit none
01890       integer, intent(in) :: index
01891       indextomeanunit = outunit(index,'mean')
01892    end function indextomeanunit
01893 
01894    integer function indextominunit(index)
01895       implicit none
01896       integer, intent(in) :: index
01897       indextominunit = outunit(index,'min')
01898    end function indextominunit
01899 
01900    integer function indextomaxunit(index)
01901       implicit none
01902       integer, intent(in) :: index
01903       indextomaxunit = outunit(index,'max')
01904    end function indextomaxunit
01905 
01906    integer function indextovarunit(index)
01907       implicit none
01908       integer, intent(in) :: index
01909       indextovarunit = outunit(index,'var')
01910    end function indextovarunit
01911 
01912    integer function indextodrifterunit(index)
01913       implicit none
01914       integer, intent(in) :: index
01915       indextodrifterunit = outunit(index,'drifter')
01916    end function indextodrifterunit
01917 
01918    subroutine makeaveragenames(counter,fnamemean,fnamevar,fnamemin&
01919    &                           ,fnamemax)
01920       use mnemmodule
01921 
01922       implicit none
01923 
01924       character(*)       :: fnamemean,fnamevar,fnamemin,fnamemax
01925       integer            :: counter
01926 
01927       fnamemean = trim(mnemonics(counter))//'_mean.dat'
01928       fnamevar  = trim(mnemonics(counter))//'_var.dat'
01929       fnamemin  = trim(mnemonics(counter))//'_min.dat'
01930       fnamemax  = trim(mnemonics(counter))//'_max.dat'
01931 
01932    end subroutine makeaveragenames
01933   
01934    
01935    subroutine hotstartfiles_collect(s,sl,par, tpar)
01936       use logging_module
01937 #ifdef USEMPI
01938       use xmpi_module
01939 #endif
01940       use params
01941       use spaceparams
01942       use timestep_module
01943       use mnemmodule
01944       use postprocessmod
01945       use paramsconst
01946       
01947       type(spacepars), intent(inout)         :: s ! s-> spaceparams, what is isl?
01948       !                                         s describes the global system, sl the local system
01949       !                                           in this MPI process
01950       type(spacepars), intent(inout)         :: sl ! s-> spaceparams, what is isl?
01951       type(parameters), intent(inout)        :: par
01952       type(timepars), intent(in)             :: tpar
01953       
01954       ! Water level, bed, velocities. Used in all models
01955 #ifdef USEMPI
01956       call space_collect_mnem(s,sl,par,mnem_zs)
01957       call space_collect_mnem(s,sl,par,mnem_zb)
01958       call space_collect_mnem(s,sl,par,mnem_uu)
01959       call space_collect_mnem(s,sl,par,mnem_vv)
01960 
01961       
01962       ! groundwater parameters
01963       if(par%gwflow==1) then
01964          call space_collect_mnem(s,sl,par,mnem_gwlevel)
01965          call space_collect_mnem(s,sl,par,mnem_gwhead)
01966          call space_collect_mnem(s,sl,par,mnem_gwcurv)
01967       endif
01968 
01969       ! wave energy
01970       if (par%swave==1) then
01971          call space_collect_mnem(s,sl,par,mnem_ee)
01972          call space_collect_mnem(s,sl,par,mnem_rr)
01973       endif      
01974       
01975       ! single-dir
01976       if (par%single_dir==1) then
01977          call space_collect_mnem(s,sl,par,mnem_ee_s)
01978       endif 
01979       
01980       ! nonh parameters
01981       if (par%wavemodel == WAVEMODEL_NONH) then
01982          call space_collect_mnem(s,sl,par,mnem_breaking)
01983          call space_collect_mnem(s,sl,par,mnem_wb)
01984          call space_collect_mnem(s,sl,par,mnem_ws)
01985       endif  
01986       
01987       ! sediment transport
01988       if (par%sedtrans==1 .and. (par%sus==1 .or. par%bulk==1)) then
01989          call space_collect_mnem(s,sl,par,mnem_ccg)
01990       endif
01991       
01992       ! turbulence
01993       if (par%turb==1) then
01994          call space_collect_mnem(s,sl,par,mnem_kturb)
01995       endif
01996       
01997       ! structures
01998       if (par%struct==1) then
01999          call space_collect_mnem(s,sl,par,mnem_structdepth)
02000       endif
02001             
02002       ! nhplus
02003       if (par%nonhq3d==1) then
02004          call space_collect_mnem(s,sl,par,mnem_dU)
02005          call space_collect_mnem(s,sl,par,mnem_dV)
02006       endif
02007       
02008       ! boundary flow
02009       if ((par%flow==1).or.(par%wavemodel==WAVEMODEL_NONH)) then
02010          call space_collect_mnem(s,sl,par,mnem_umean)
02011          call space_collect_mnem(s,sl,par,mnem_vmean)
02012       endif
02013 #endif      
02014       
02015    end subroutine hotstartfiles_collect
02016 
02017    subroutine hotstartfiles_write(s,par, tpar)
02018       use logging_module
02019 #ifdef USEMPI
02020       use xmpi_module
02021 #endif
02022       use params
02023       use spaceparams
02024       use timestep_module
02025       use mnemmodule
02026       use postprocessmod
02027           use paramsconst
02028       
02029       type(spacepars), intent(inout)         :: s ! s-> spaceparams, what is isl?
02030       !                                         s describes the global system, sl the local system
02031       !                                           in this MPI process
02032       type(parameters), intent(inout)        :: par
02033       type(timepars), intent(in)             :: tpar
02034       
02035       if (xomaster) then
02036           ! Water level, bed, velocities. Used in all models
02037           if (xomaster) then
02038              call lowlevel_write_hotstart_2d(s%zs,s%nx,s%ny,'zs',tpar%ith)
02039              call lowlevel_write_hotstart_2d(s%zb,s%nx,s%ny,'zb',tpar%ith)
02040              call lowlevel_write_hotstart_2d(s%uu,s%nx,s%ny,'uu',tpar%ith)
02041              call lowlevel_write_hotstart_2d(s%vv,s%nx,s%ny,'vv',tpar%ith)
02042           endif
02043       
02044           ! groundwater parameters
02045           if(par%gwflow==1) then
02046              call lowlevel_write_hotstart_2d(s%gwlevel,s%nx,s%ny,'gwlevel',tpar%ith)
02047              call lowlevel_write_hotstart_2d(s%gwhead,s%nx,s%ny,'gwhead',tpar%ith)
02048              call lowlevel_write_hotstart_2d(s%gwcurv,s%nx,s%ny,'gwcurv',tpar%ith)
02049           endif
02050 
02051           ! wave energy
02052           if (par%swave==1) then
02053              call lowlevel_write_hotstart_3d(s%ee,s%nx,s%ny,s%ntheta,'ee',tpar%ith)
02054              call lowlevel_write_hotstart_3d(s%rr,s%nx,s%ny,s%ntheta,'rr',tpar%ith)
02055           endif      
02056       
02057           ! single-dir
02058           if (par%single_dir==1) then
02059              call lowlevel_write_hotstart_3d(s%ee_s,s%nx,s%ny,s%ntheta_s,'ee_s',tpar%ith)
02060           endif 
02061       
02062           ! nonh parameters
02063           if (par%wavemodel == WAVEMODEL_NONH) then
02064              call lowlevel_write_hotstart_2d_int(s%breaking,s%nx,s%ny,'breaking',tpar%ith)
02065              call lowlevel_write_hotstart_2d(s%wb,s%nx,s%ny,'wb',tpar%ith)
02066              call lowlevel_write_hotstart_2d(s%ws,s%nx,s%ny,'ws',tpar%ith)
02067           endif  
02068       
02069           ! sediment transport
02070           if (par%sedtrans==1 .and. (par%sus==1 .or. par%bulk==1)) then
02071              call lowlevel_write_hotstart_3d(s%ccg,s%nx,s%ny,par%ngd,'ccg',tpar%ith)
02072           endif
02073       
02074           ! turbulence
02075           if (par%turb==1) then
02076              call lowlevel_write_hotstart_2d(s%kturb,s%nx,s%ny,'kturb',tpar%ith)
02077           endif
02078       
02079           ! structures
02080           if (par%struct==1) then
02081              call lowlevel_write_hotstart_2d(s%structdepth,s%nx,s%ny,'structdepth',tpar%ith)
02082           endif
02083           
02084           ! nhplus
02085           if (par%nonhq3d==1) then
02086              call lowlevel_write_hotstart_2d(s%dU,s%nx,s%ny,'dU',tpar%ith)
02087              call lowlevel_write_hotstart_2d(s%dV,s%nx,s%ny,'dV',tpar%ith)
02088           endif
02089           
02090           ! boundary flow
02091           if ((par%flow==1).or.(par%wavemodel==WAVEMODEL_NONH)) then
02092             call lowlevel_write_hotstart_2d(s%umean,s%nx,s%ny,'umean',tpar%ith)
02093             call lowlevel_write_hotstart_2d(s%vmean,s%nx,s%ny,'vmean',tpar%ith)
02094           endif
02095       endif   ! xomaster   
02096    end subroutine hotstartfiles_write  
02097    
02098    subroutine lowlevel_write_hotstart_2d(var,nx,ny,varname,ith)
02099    
02100       integer,intent(in)           :: nx,ny,ith
02101       real*8,dimension(nx+1,ny+1),intent(in) :: var
02102       character(*), intent(in)     :: varname
02103       
02104       integer                      :: unit,i,j,ierr
02105       character(128)               :: fname,rowfmt
02106       
02107       unit = outunit(1,'hotstart')
02108       write(fname,'(a,a,I6.6,a)') 'hotstart_',trim(varname),ith,'.dat'
02109       write(rowfmt,'(a,I12,a)') '(',ny+1,'(1X,D))'
02110       open(unit,file=fname,form='FORMATTED', iostat=ierr)
02111       do j=1,ny+1
02112          write(unit,FMT=rowfmt) (var(i,j), i=1,nx+1)
02113       enddo
02114       close(unit)
02115    
02116    end subroutine lowlevel_write_hotstart_2d
02117    
02118    subroutine lowlevel_write_hotstart_2d_int(var,nx,ny,varname,ith)
02119    
02120       integer,intent(in)           :: nx,ny,ith
02121       integer,dimension(nx+1,ny+1),intent(in) :: var
02122       character(*), intent(in)     :: varname
02123       
02124       integer                      :: unit,i,j,ierr
02125       character(128)               :: fname,rowfmt
02126       
02127       unit = outunit(2,'hotstart')
02128       write(fname,'(a,a,I6.6,a)') 'hotstart_',trim(varname),ith,'.dat'
02129       write(rowfmt,'(a,I12,a)') '(',ny+1,'(1X,I4))'
02130       open(unit,file=fname,form='FORMATTED', iostat=ierr)
02131       do j=1,ny+1
02132          write(unit,FMT=rowfmt) (var(i,j), i=1,nx+1)
02133       enddo
02134       close(unit)
02135    
02136    end subroutine lowlevel_write_hotstart_2d_int
02137    
02138     subroutine lowlevel_write_hotstart_3d(var,nx,ny,nd,varname,ith)
02139    
02140       integer,intent(in)           :: nx,ny,nd,ith
02141       real*8,dimension(nx+1,ny+1,nd),intent(in) :: var
02142       character(*), intent(in)     :: varname
02143       
02144       integer                      :: unit,i,j,k,ierr
02145       character(128)               :: fname,rowfmt
02146       
02147       unit = outunit(3,'hotstart')
02148       write(fname,'(a,a,I6.6,a)') 'hotstart_',trim(varname),ith,'.dat'
02149       write(rowfmt,'(a,I12,a)') '(',ny+1,'(1X,D))'
02150       open(unit,file=fname,form='FORMATTED', iostat=ierr)
02151       do k=1,nd
02152          do j=1,ny+1
02153             write(unit,FMT=rowfmt) (var(i,j,k), i=1,nx+1)
02154          enddo
02155       enddo
02156       close(unit)
02157    
02158    end subroutine lowlevel_write_hotstart_3d
02159    
02160 
02161 end module ncoutput_module
 All Classes Files Functions Variables Defines