! <-~~~=| (+) Subroutine to write netCDF file with 3 options: 2d, 3d, 4d ~ lon, lat, time, lev  =@
! <-~~~=| (-) Only avaiable to write 1 variables 						=@
! <-~~~=| Reference: http://spanlib.sourceforge.net/doc/doc_f90_exa.html			=@
! <-~~~=| --------------------									=@
! <-~~~=| To compile: 										=@
! <-~~~=|            ifort -L ${netcdf}lib/ -lnetcdff -I ${netcdf}include/ main_program.F90	=@
! <-~~~=| ----------:										=@
! <-~~~=|            where: netcdf="/opt/apps/intel_12.0/linux86_64/netcdf/4.1.3/"		=@
! <-~~~=|==-------------------------------------------------------------------------------------=@

! <-~~~=| Write 2D netCDF ...
SUBROUTINE wr_ncdf_2d (filenm,lon,lat,nlon,nlat,var,var_nm, var_long_name, var_unit, flag)
   character (len = *), intent (in) :: filenm, var_nm, var_long_name, var_unit
   character (len = *), parameter :: lon_nm = "lon", lat_nm = "lat"
   integer, parameter :: NDIMS = 2
   integer :: ncid, var_id, dims_id(NDIMS)
   integer :: lon_id, lat_id
   integer, intent (in) :: nlon, nlat
   real, dimension (nlon,nlat), intent (in) :: var
   real, intent (in) :: lon(nlon), lat(nlat), flag

   print*,"   Writing netCDF file: ",filenm,"..."
   call hulk ( nf90_create (filenm, nf90_write, ncid) )
        call hulk ( nf90_def_dim (ncid, lon_nm, nlon, dims_id(1)) )
        call hulk ( nf90_def_dim (ncid, lat_nm, nlat, dims_id(2)) )

        call hulk ( nf90_def_var (ncid, lon_nm, nf90_float, dims_id(1),   lon_id) )
        call hulk ( nf90_def_var (ncid, lat_nm, nf90_float, dims_id(2),   lat_id) )
        call hulk ( nf90_def_var (ncid, var_nm, nf90_float, dims_id(1:2), var_id) )
             call hulk ( nf90_put_att (ncid, lon_id, "long_name",     "Longitude") )
             call hulk ( nf90_put_att (ncid, lon_id, "units",         "degree_east") )
             call hulk ( nf90_put_att (ncid, lat_id, "long_name",     "Latitude") )
             call hulk ( nf90_put_att (ncid, lat_id, "units",         "degree_north") )
             call hulk ( nf90_put_att (ncid, var_id, "long_name",     trim(var_long_name))) !"What the hell (!@.@) !!!") )
             call hulk ( nf90_put_att (ncid, var_id, "units",         trim(var_unit)))      ! "OMG (@.@!)") )
             call hulk ( nf90_put_att (ncid, var_id, "missing_value", flag) )
        call hulk ( nf90_enddef(ncid) )

        call hulk ( nf90_put_var (ncid, lon_id, lon) )
        call hulk ( nf90_put_var (ncid, lat_id, lat) )
        call hulk ( nf90_put_var (ncid, var_id, var) )
   call hulk ( nf90_close (ncid) )
   print*,"   Completed writing file ",filenm

   return
END SUBROUTINE wr_ncdf_2d

! <-~~~=| Write 3D netCDF ...
SUBROUTINE wr_ncdf_3d (filenm,lon,lat,t,nlon,nlat,nt,var,var_nm,t_unit, var_long_name, var_unit, flag)
   character (len = *), intent (in) :: filenm, var_nm, t_unit, var_long_name, var_unit
   character (len = *), parameter :: lon_nm = "lon", lat_nm = "lat", t_nm = "time"
   integer, parameter :: NDIMS = 3
   integer :: ncid, var_id, dims_id(NDIMS)
   integer :: lon_id, lat_id, t_id
   integer, intent (in) :: nlon, nlat, nt
   real, dimension (nlon,nlat,nt), intent (in) :: var
   real, intent (in) :: lon(nlon), lat(nlat), t(nt), flag
   
   print*,"   Writing netCDF file: ",filenm,"..."
   call hulk ( nf90_create (filenm, nf90_write, ncid) )
        call hulk ( nf90_def_dim (ncid, lon_nm, nlon, dims_id(1)) )
        call hulk ( nf90_def_dim (ncid, lat_nm, nlat, dims_id(2)) )
        call hulk ( nf90_def_dim (ncid, t_nm,   nt,   dims_id(3)) )

        call hulk ( nf90_def_var (ncid,lon_nm,nf90_float,dims_id(1),lon_id) )
        call hulk ( nf90_def_var (ncid,lat_nm,nf90_float,dims_id(2),lat_id) )
        call hulk ( nf90_def_var (ncid,t_nm,nf90_float,dims_id(3),t_id) )
        call hulk ( nf90_def_var (ncid,var_nm,nf90_float,dims_id(1:3),var_id) )
             call hulk ( nf90_put_att (ncid,lon_id,"long_name","Longitude") )
             call hulk ( nf90_put_att (ncid,lon_id,"units","degree_east") )
             call hulk ( nf90_put_att (ncid,lat_id,"long_name","Latitude") )
             call hulk ( nf90_put_att (ncid,lat_id,"units","degree_north") )
             call hulk ( nf90_put_att (ncid,t_id,"long_name","Time") )

!             call hulk ( nf90_put_att (ncid,t_id,"units","months since 1986-01-15 00:00:00") )
             call hulk ( nf90_put_att (ncid,t_id,"units",trim(t_unit)//" 00:00:00") )
             call hulk ( nf90_put_att (ncid,t_id,"calendar","proleptic_gregorian") )
             call hulk ( nf90_put_att (ncid,var_id,"long_name",      trim(var_long_name)))  !"What the hell (!@.@) !!!") )
             call hulk ( nf90_put_att (ncid,var_id,"units",          trim(var_unit)))       !"OMG (@.@!)") )
             call hulk ( nf90_put_att (ncid,var_id,"missing_value",flag) )
        call hulk ( nf90_enddef (ncid) )
        call hulk ( nf90_put_var (ncid,lon_id,lon) )
        call hulk ( nf90_put_var (ncid,lat_id,lat) )
        call hulk ( nf90_put_var (ncid,t_id,t) )
        call hulk ( nf90_put_var (ncid,var_id,var) )
   call hulk ( nf90_close (ncid) )
   print*,"   Completed writing file ",filenm

   return
END SUBROUTINE wr_ncdf_3d

! <-~~~=|= Write 2D variable to existed file, need to have same dimensions
SUBROUTINE wr_ncdf_2d_apd (filenm,var,var_nm,nlon,nlat, var_long_name, var_unit, flag)
   character (len = *), intent (in) :: filenm, var_nm, var_long_name, var_unit
   character (len = *), parameter :: lon_nm = "lon", lat_nm = "lat"
   integer, parameter :: NDIMS = 2
   integer :: ncid, var_id, dims_id(NDIMS)
   integer, intent (in) :: nlon, nlat
   real, dimension (nlon,nlat), intent (in) :: var
   real, intent (in) :: flag

   print*,"   Writing append to netCDF file: ",filenm,"..."
   call hulk ( nf90_open (filenm, nf90_write, ncid) )
        call hulk ( nf90_inq_dimid (ncid, lon_nm, dims_id(1)) )
        call hulk ( nf90_inq_dimid (ncid, lat_nm, dims_id(2)) )
        call hulk ( nf90_redef (ncid) )
             call hulk ( nf90_def_var (ncid, var_nm,nf90_float,dims_id(1:2),var_id) )
             call hulk ( nf90_put_att (ncid, var_id, "long_name",     trim(var_long_name)))  !"What the hell (!@.@) !!!") )
             call hulk ( nf90_put_att (ncid, var_id, "units",         trim(var_unit)))       !"OMG (@.@!)") )
             call hulk ( nf90_put_att (ncid, var_id, "missing_value", flag) )        
        call hulk ( nf90_enddef (ncid) )
        call hulk ( nf90_put_var (ncid, var_id, var) )
   call hulk ( nf90_close (ncid) )
   print*,"   Completed writing append to file ",filenm

   return
END SUBROUTINE wr_ncdf_2d_apd

! <-~~~=|= Write 3D variable to existed file, need to have same dimensions
SUBROUTINE wr_ncdf_3d_apd (filenm,var,var_nm,nlon,nlat,nt, var_long_name, var_unit, flag)
   character (len = *), intent (in) :: filenm, var_nm, var_long_name, var_unit
   character (len = *), parameter :: lon_nm = "lon", lat_nm = "lat", t_nm = "time"
   integer, parameter :: NDIMS = 3
   integer :: ncid, var_id, dims_id(NDIMS)
   integer, intent (in) :: nlon, nlat, nt
   real, dimension (nlon,nlat,nt), intent (in) :: var
   real, intent (in) :: flag

   print*,"   Writing append to netCDF file: ",filenm,"..."
   call hulk ( nf90_open (filenm, nf90_write, ncid) )
        call hulk ( nf90_inq_dimid (ncid, lon_nm, dims_id(1)) )
        call hulk ( nf90_inq_dimid (ncid, lat_nm, dims_id(2)) )
        call hulk ( nf90_inq_dimid (ncid, t_nm,   dims_id(3)) )
        call hulk ( nf90_redef (ncid) )
             call hulk ( nf90_def_var (ncid, var_nm,nf90_float,dims_id(1:3),var_id) )
             call hulk ( nf90_put_att (ncid, var_id, "long_name",    trim(var_long_name)))  ! "What the hell (!@.@) !!!") )
             call hulk ( nf90_put_att (ncid, var_id, "units",        trim(var_unit)))       ! "OMG (@.@!)") )
             call hulk ( nf90_put_att (ncid, var_id, "missing_value", flag) )
        call hulk ( nf90_enddef (ncid) )
        call hulk ( nf90_put_var (ncid, var_id, var) )
   call hulk ( nf90_close (ncid) )
   print*,"   Completed writing append to file ",filenm

   return
END SUBROUTINE wr_ncdf_3d_apd

! <-~~~=| Nf90 checking errors ...
SUBROUTINE hulk (stat)
   use netcdf
   integer :: stat
   if ( stat .ne. nf90_noerr) then
      print*, trim(nf90_strerror(stat))
      stop
   endif
END SUBROUTINE hulk
! <-~~~=|==-------------------------------------------------------------------------------------=@
