fvcom_tools  1.3.0
 All Data Structures Files Functions Variables Pages
module_ncio.f90
Go to the documentation of this file.
1 
4 
7 module module_ncio
8 
9  use netcdf
10  implicit none
11 
12  public :: ncio
13  ! set default to private
14  private
15  !
16  type :: ncio
17  character(len=256) :: filename
18  integer :: ncid
19  integer :: status
20  integer :: debug_level
21 
22  integer :: nDims
23  integer :: ends(4)
24  integer :: xtype
25  character(len=40) :: dimname(4)
26  contains
27  procedure :: open => open_nc
28  procedure :: close => close_nc
29  procedure :: get_dim => get_dim_nc
31  procedure :: get_att_nc_int
32  procedure :: get_att_nc_real
33  procedure :: get_att_nc_string
43  procedure :: get_var_nc_short
44  procedure :: get_var_nc_short_1d
45  procedure :: get_var_nc_short_2d
46  procedure :: get_var_nc_int
47  procedure :: get_var_nc_int_1d
48  procedure :: get_var_nc_int_2d
49  procedure :: get_var_nc_int_3d
50  procedure :: get_var_nc_real
51  procedure :: get_var_nc_real_1d
52  procedure :: get_var_nc_real_2d
53  procedure :: get_var_nc_real_3d
54  procedure :: get_var_nc_double
55  procedure :: get_var_nc_double_1d
56  procedure :: get_var_nc_double_2d
57  procedure :: get_var_nc_double_3d
58  procedure :: get_var_nc_char
59  procedure :: get_var_nc_char_1d
60  procedure :: get_var_nc_char_2d
61  procedure :: get_var_nc_char_3d
70  procedure :: replace_var_nc_int
71  procedure :: replace_var_nc_int_1d
72  procedure :: replace_var_nc_int_2d
73  procedure :: replace_var_nc_int_3d
74  procedure :: replace_var_nc_real
75  procedure :: replace_var_nc_real_1d
76  procedure :: replace_var_nc_real_2d
77  procedure :: replace_var_nc_real_3d
78  procedure :: replace_var_nc_double
82  procedure :: replace_var_nc_char
83  procedure :: replace_var_nc_char_1d
84  procedure :: replace_var_nc_char_2d
85  procedure :: replace_var_nc_char_3d
86  procedure :: handle_err
87  procedure :: convert_theta2t_2dgrid
88  procedure :: add_new_var => add_new_var_3d
89  end type ncio
90 
91 contains
92 
100  subroutine open_nc(this,filename,action,debug_level)
101 
102  implicit none
103  !
104  class(ncio) :: this
105  character(len=*),intent(in) :: filename
106  character(len=1),intent(in) :: action
107  integer,intent(in),optional :: debug_level
108 
109  integer :: ncid, status
110 
111  this%debug_level=20
112  if(present(debug_level)) this%debug_level=debug_level
113 
114  this%filename=trim(filename)
115  ! open existing netCDF dataset
116  if(action=="r" .or. action=="R") then
117  status = nf90_open(path = trim(filename), mode = nf90_nowrite, ncid = ncid)
118  elseif(action=="w" .or. action=="W") then
119  status = nf90_open(path = trim(filename), mode = nf90_write, ncid = ncid)
120  else
121  write(*,*) 'unknow action :', action
122  stop 123
123  endif
124  if (status /= nf90_noerr) call this%handle_err(status)
125  this%ncid=ncid
126 
127  if(this%debug_level>0) then
128  write(*,*) '>>> open file: ',trim(this%filename)
129  endif
130 
131  end subroutine open_nc
132 
137  subroutine close_nc(this)
138 
139  implicit none
140  !
141  class(ncio) :: this
142 
143  integer :: ncid, status
144 
145  ncid=this%ncid
146  !
147  ! close netCDF dataset
148  status = nf90_close(ncid)
149  if (status /= nf90_noerr) call this%handle_err(status)
150 
151  end subroutine close_nc
152 
159  subroutine get_att_nc_real(this,attname,rval)
160  implicit none
161  !
162  class(ncio) :: this
163  character(len=*),intent(in) :: attname
164  real, intent(out) :: rval
165 
166  integer :: ncid, status
167 
168  ! open existing netCDF dataset
169  ncid=this%ncid
170 
171  ! get date from exisiting NC file
172  status = nf90_get_att(ncid, nf90_global, trim(attname), rval)
173  if (status /= nf90_noerr) call this%handle_err(status)
174  !
175  end subroutine get_att_nc_real
176 
183  subroutine get_att_nc_int(this,attname,ival)
184  implicit none
185  !
186  class(ncio) :: this
187  character(len=*),intent(in) :: attname
188  integer, intent(out) :: ival
189 
190  integer :: ncid, status
191 
192  ! open existing netCDF dataset
193  ncid=this%ncid
194 
195  ! get date from exisiting NC file
196  status = nf90_get_att(ncid, nf90_global, trim(attname), ival)
197  if (status /= nf90_noerr) call this%handle_err(status)
198  !
199  end subroutine get_att_nc_int
200 
207  subroutine get_att_nc_string(this,attname,string)
208  implicit none
209  !
210  class(ncio) :: this
211  character(len=*),intent(in) :: attname
212  character(len=*), intent(out) :: string
213 
214  integer :: ncid, status
215 
216  ! open existing netCDF dataset
217  ncid=this%ncid
218 
219  ! get date from exisiting NC file
220  status = nf90_get_att(ncid, nf90_global, trim(attname), string)
221  if (status /= nf90_noerr) call this%handle_err(status)
222  !
223  end subroutine get_att_nc_string
224 
225 
232  subroutine get_dim_nc(this,dimname,dimvalue)
233  implicit none
234  !
235  class(ncio) :: this
236  character(len=*), intent(in) :: dimname
237  integer,intent(out) :: dimvalue
238 
239  integer :: ncid, status
240  integer :: dimid
241 
242  ! open existing netCDF dataset
243  ncid=this%ncid
244 
245  ! get dimension from exisiting NC file
246  status = nf90_inq_dimid(ncid,trim(dimname), dimid)
247  if (status /= nf90_noerr) call this%handle_err(status)
248  status = nf90_inquire_dimension(ncid, dimid, len = dimvalue)
249  if (status /= nf90_noerr) call this%handle_err(status)
250  !
251  end subroutine get_dim_nc
252 
260  subroutine replace_var_nc_char_1d(this,varname,nd1,field)
261 
262  use netcdf
263  !
264  implicit none
265  !
266  class(ncio) :: this
267  character(len=*),intent(in) :: varname ! name of the field to read
268  integer, intent(in) :: nd1 ! size of array dval
269  character, intent(in) :: field(nd1) ! values of the field read in
270  integer :: ilength
271  !
272  character*40,parameter :: thissubname='replace_var_nc_char_1d'
273  !
274  integer :: i
275  !
276  !
277  ilength=nd1
278  !
279  if(this%debug_level>100) then
280  write(*,*) trim(thissubname),' show samples:'
281  write(*,*) (field(i),i=1,min(nd1,10))
282  endif
283 
284  call this%replace_var_nc_char(varname,ilength,field)
285  !
286  end subroutine replace_var_nc_char_1d
287 
296  subroutine replace_var_nc_char_2d(this,varname,nd1,nd2,field)
297  use netcdf
298  !
299  implicit none
300  !
301  class(ncio) :: this
302  character(len=*),intent(in) :: varname ! name of the field to read
303  integer, intent(in) :: nd1,nd2 ! size of array dval
304  character, intent(in) :: field(nd1,nd2) ! values of the field read in
305  integer :: ilength
306  !
307  character,allocatable :: temp(:)
308  !
309  character*40,parameter :: thissubname='replace_var_nc_char_2d'
310  !
311  integer :: i,j,k
312  integer :: istart,iend
313  !
314  !
315  ilength=nd1*nd2
316  allocate(temp(ilength))
317 
318  do j=1,nd2
319  istart=(j-1)*nd1+1
320  iend=(j-1)*nd1+nd1
321  temp(istart:iend)=field(:,j)
322  enddo
323  !
324  if(this%debug_level>100) then
325  write(*,*) trim(thissubname),' show samples:'
326  write(*,*) field(1,1)
327  endif
328  !
329  call this%replace_var_nc_char(varname,ilength,temp)
330 
331  deallocate(temp)
332  !
333  end subroutine replace_var_nc_char_2d
334 
344  subroutine replace_var_nc_char_3d(this,varname,nd1,nd2,nd3,field)
345  use netcdf
346  !
347  implicit none
348  !
349  class(ncio) :: this
350  character(len=*),intent(in) :: varname ! name of the field to read
351  integer, intent(in) :: nd1,nd2,nd3 ! size of array dval
352  character, intent(in) :: field(nd1,nd2,nd3) ! values of the field read in
353  integer :: ilength
354  !
355  character,allocatable :: temp(:)
356  !
357  character*40,parameter :: thissubname='replace_var_nc_char_3d'
358  !
359  integer :: i,j,k
360  integer :: length2d
361  integer :: istart,iend
362  !
363  !
364  length2d=nd1*nd2
365  ilength=length2d*nd3
366  allocate(temp(ilength))
367 
368  do k=1,nd3
369  do j=1,nd2
370  istart=(k-1)*length2d+(j-1)*nd1+1
371  iend =(k-1)*length2d+(j-1)*nd1+nd1
372  temp(istart:iend)=field(:,j,k)
373  enddo
374  enddo
375  !
376  if(this%debug_level>100) then
377  write(*,*) trim(thissubname),' show samples:'
378  write(*,*) field(1,1,1)
379  endif
380 
381  call this%replace_var_nc_char(varname,ilength,temp)
382 
383  deallocate(temp)
384  !
385  end subroutine replace_var_nc_char_3d
386 
394  subroutine replace_var_nc_char(this,varname,ilength,field)
395  use netcdf
396  !
397  implicit none
398  !
399  class(ncio) :: this
400  character(len=*),intent(in) :: varname ! name of the field to read
401  integer, intent(in) :: ilength ! size of array dval
402  character, intent(in) :: field(ilength) ! values of the field read in
403  !
404  integer :: ncid
405  !
406  integer :: status
407  integer :: varid
408  integer :: ends(4),start(4)
409 
410  integer :: length4d,length3d,length2d
411  integer :: ndims,ndim
412  integer :: dimids(4)
413  integer :: xtype
414  character*40 :: dimname
415 
416  character*40,parameter :: thissubname='replace_var_nc_char'
417  !
418  integer :: i,k
419  !
420  !
421  ncid=this%ncid
422 
423  ! get variable IDs
424  status = nf90_inq_varid(ncid, trim(varname), varid)
425  if(status /= nf90_noerr) call this%handle_err(status)
426 
427  ! get dimensions
428  ends=1
429  start=1
430  this%ends=1
431 
432  this%dimname=" "
433  ! get variable type
434  status = nf90_inquire_variable(ncid, varid, xtype = xtype)
435  if(status /= nf90_noerr) call this%handle_err(status)
436  if(xtype==nf90_char) then
437  this%xtype=xtype
438  else
439  write(*,*) trim(thissubname),' ERROR: wrong data type, expect ',nf90_int,' but read in ',xtype
440  stop 123
441  endif
442 
443  ! get dimension size
444  status = nf90_inquire_variable(ncid, varid, ndims = ndims)
445  if(status /= nf90_noerr) call this%handle_err(status)
446  this%ndims=ndims
447  !
448  status = nf90_inquire_variable(ncid, varid, dimids = dimids(1:ndims))
449  if(status /= nf90_noerr) call this%handle_err(status)
450  do i=1,ndims
451  dimname=" "
452  status = nf90_inquire_dimension(ncid, dimids(i), dimname, len = ndim)
453  if (status /= nf90_noerr) call this%handle_err(status)
454  ends(i)=ndim
455  this%ends(i)=ends(i)
456  this%dimname(i)=trim(dimname)
457  if(this%ends(i) < 1) then
458  write(*,*) trim(thissubname),' Error, ends dimension should larger than 0 :', ends(i)
459  stop 1234
460  endif
461  enddo
462  length2d=ends(1)*ends(2)
463  length3d=length2d*ends(3)
464  length4d=length3d*ends(4)
465  if(ilength .ne. length4d) then
466  write(*,*) trim(thissubname),'ERROR: ',ilength,' should equal to ',length4d
467  stop 123
468  endif
469  !
470  if(ndims <=4 ) then
471  status = nf90_put_var(ncid, varid, field, &
472  start = start(1:4) , &
473  count = ends(1:4))
474  if(status /= nf90_noerr) call this%handle_err(status)
475  else
476  write(*,*) trim(thissubname),'Error: too many dimensions:',ndims
477  stop 1234
478  endif
479  !
480  if(this%debug_level>0) then
481  write(*,'(a,a)') '>>>replace variable: ',trim(varname)
482  endif
483  if(this%debug_level>10) then
484  write(*,'(8x,a,I10)') 'data type : ',this%xtype
485  write(*,'(8x,a,I10)') 'dimension size: ',this%nDims
486  do i=1,this%nDims
487  write(*,'(8x,a,I5,I10,2x,a)') 'rank, ends, name=',i,this%ends(i),trim(this%dimname(i))
488  enddo
489  endif
490  !
491  end subroutine replace_var_nc_char
492  !--- replace_var_nc_char
493 
501  subroutine replace_var_nc_real_1d(this,varname,nd1,field)
502  use netcdf
503  !
504  implicit none
505  !
506  class(ncio) :: this
507  character(len=*),intent(in) :: varname ! name of the field to read
508  integer, intent(in) :: nd1 ! size of array dval
509  real(4), intent(in) :: field(nd1) ! values of the field read in
510  integer :: ilength
511  !
512  character*40,parameter :: thissubname='replace_var_nc_real_1d'
513  !
514  integer :: i
515  !
516  !
517  ilength=nd1
518  !
519  if(this%debug_level>100) then
520  write(*,*) trim(thissubname),' show samples:'
521  write(*,*) (field(i),i=1,min(nd1,10))
522  endif
523  !
524  call this%replace_var_nc_real(varname,ilength,field)
525  !
526  end subroutine replace_var_nc_real_1d
527 
536  subroutine replace_var_nc_real_2d(this,varname,nd1,nd2,field)
537  use netcdf
538  !
539  implicit none
540  !
541  class(ncio) :: this
542  character(len=*),intent(in) :: varname ! name of the field to read
543  integer, intent(in) :: nd1,nd2 ! size of array dval
544  real(4), intent(in) :: field(nd1,nd2) ! values of the field read in
545  integer :: ilength
546  !
547  real(4),allocatable :: temp(:)
548  !
549  character*40,parameter :: thissubname='replace_var_nc_real_2d'
550  !
551  integer :: i,j,k
552  integer :: istart,iend
553  !
554  !
555  ilength=nd1*nd2
556  allocate(temp(ilength))
557 
558  do j=1,nd2
559  istart=(j-1)*nd1+1
560  iend=(j-1)*nd1+nd1
561  temp(istart:iend)=field(:,j)
562  enddo
563  !
564  if(this%debug_level>100) then
565  write(*,*) trim(thissubname),' show samples:'
566  write(*,*) 'max,min:',maxval(field(:,:)),minval(field(:,:))
567  endif
568 
569  call this%replace_var_nc_real(varname,ilength,temp)
570 
571  deallocate(temp)
572  !
573  end subroutine replace_var_nc_real_2d
574 
584  subroutine replace_var_nc_real_3d(this,varname,nd1,nd2,nd3,field)
585  !
586  ! read in one field
587  !
588  use netcdf
589  !
590  implicit none
591  !
592  class(ncio) :: this
593  character(len=*),intent(in) :: varname ! name of the field to read
594  integer, intent(in) :: nd1,nd2,nd3 ! size of array dval
595  real(4), intent(in) :: field(nd1,nd2,nd3) ! values of the field read in
596  integer :: ilength
597  !
598  real(4),allocatable :: temp(:)
599  !
600  character*40,parameter :: thissubname='replace_var_nc_real_3d'
601  !
602  integer :: i,j,k
603  integer :: length2d
604  integer :: istart,iend
605  !
606  !
607  length2d=nd1*nd2
608  ilength=length2d*nd3
609  allocate(temp(ilength))
610 
611  do k=1,nd3
612  do j=1,nd2
613  istart=(k-1)*length2d+(j-1)*nd1+1
614  iend =(k-1)*length2d+(j-1)*nd1+nd1
615  temp(istart:iend)=field(:,j,k)
616  enddo
617  enddo
618  !
619  if(this%debug_level>100) then
620  write(*,*) trim(thissubname),' show samples:'
621  do k=1,nd3
622  write(*,*) 'k,max,min:',k,maxval(field(:,:,k)),minval(field(:,:,k))
623  enddo
624  endif
625 
626  call this%replace_var_nc_real(varname,ilength,temp)
627 
628  deallocate(temp)
629  !
630  end subroutine replace_var_nc_real_3d
631 
639  subroutine replace_var_nc_real(this,varname,ilength,field)
640  use netcdf
641  !
642  implicit none
643  !
644  class(ncio) :: this
645  character(len=*),intent(in) :: varname ! name of the field to read
646  integer, intent(in) :: ilength ! size of array dval
647  real(4), intent(in) :: field(ilength) ! values of the field read in
648  !
649  integer :: ncid
650  !
651  integer :: status
652  integer :: varid
653  integer :: ends(4),start(4)
654 
655  integer :: length4d,length3d,length2d
656  integer :: ndims,ndim
657  integer :: dimids(4)
658  integer :: xtype
659  character*40 :: dimname
660 
661  character*40,parameter :: thissubname='replace_var_nc_real'
662  !
663  integer :: i,k
664  !
665  !
666  ncid=this%ncid
667 
668  ! get variable IDs
669  status = nf90_inq_varid(ncid, trim(varname), varid)
670  if(status /= nf90_noerr) call this%handle_err(status)
671 
672  ! get dimensions
673  ends=1
674  start=1
675  this%ends=1
676 
677  this%dimname=" "
678  ! get variable type
679  status = nf90_inquire_variable(ncid, varid, xtype = xtype)
680  if(status /= nf90_noerr) call this%handle_err(status)
681  if(xtype==nf90_float) then
682  this%xtype=xtype
683  else
684  write(*,*) trim(thissubname),' ERROR: wrong data type, expect ',nf90_int,' but read in ',xtype
685  stop 123
686  endif
687 
688  ! get dimension size
689  status = nf90_inquire_variable(ncid, varid, ndims = ndims)
690  if(status /= nf90_noerr) call this%handle_err(status)
691  this%ndims=ndims
692  !
693  status = nf90_inquire_variable(ncid, varid, dimids = dimids(1:ndims))
694  if(status /= nf90_noerr) call this%handle_err(status)
695  do i=1,ndims
696  dimname=" "
697  status = nf90_inquire_dimension(ncid, dimids(i), dimname, len = ndim)
698  if (status /= nf90_noerr) call this%handle_err(status)
699  ends(i)=ndim
700  this%ends(i)=ends(i)
701  this%dimname(i)=trim(dimname)
702  if(this%ends(i) < 1) then
703  write(*,*) trim(thissubname),' Error, ends dimension should larger than 0 :', ends(i)
704  stop 1234
705  endif
706  enddo
707  length2d=ends(1)*ends(2)
708  length3d=length2d*ends(3)
709  length4d=length3d*ends(4)
710  if(ilength .ne. length4d) then
711  write(*,*) trim(thissubname),'ERROR: ',ilength,' should equal to ',length4d
712  stop 123
713  endif
714  !
715  if(ndims <=4 ) then
716  status = nf90_put_var(ncid, varid, field, &
717  start = start(1:4) , &
718  count = ends(1:4))
719  if(status /= nf90_noerr) call this%handle_err(status)
720  else
721  write(*,*) trim(thissubname),'Error: too many dimensions:',ndims
722  stop 1234
723  endif
724  !
725  if(this%debug_level>0) then
726  write(*,'(a,a)') '>>>replace variable: ',trim(varname)
727  endif
728  if(this%debug_level>10) then
729  write(*,'(8x,a,I10)') 'data type : ',this%xtype
730  write(*,'(8x,a,I10)') 'dimension size: ',this%nDims
731  do i=1,this%nDims
732  write(*,'(8x,a,I5,I10,2x,a)') 'rank, ends, name=',i,this%ends(i),trim(this%dimname(i))
733  enddo
734  endif
735  !
736  end subroutine replace_var_nc_real
737 
745  subroutine replace_var_nc_double_1d(this,varname,nd1,field)
746  !
747  ! read in one field
748  !
749  use netcdf
750  !
751  implicit none
752  !
753  class(ncio) :: this
754  character(len=*),intent(in) :: varname ! name of the field to read
755  integer, intent(in) :: nd1 ! size of array dval
756  real(8), intent(in) :: field(nd1) ! values of the field read in
757  integer :: ilength
758  !
759  character*40,parameter :: thissubname='replace_var_nc_double_1d'
760  !
761  integer :: i
762  !
763  !
764  ilength=nd1
765  !
766  if(this%debug_level>100) then
767  write(*,*) trim(thissubname),' show samples:'
768  write(*,*) (field(i),i=1,min(nd1,10))
769  endif
770  !
771  call this%replace_var_nc_double(varname,ilength,field)
772  !
773  end subroutine replace_var_nc_double_1d
774 
783  subroutine replace_var_nc_double_2d(this,varname,nd1,nd2,field)
784  !
785  ! read in one field
786  !
787  use netcdf
788  !
789  implicit none
790  !
791  class(ncio) :: this
792  character(len=*),intent(in) :: varname ! name of the field to read
793  integer, intent(in) :: nd1,nd2 ! size of array dval
794  real(8), intent(in) :: field(nd1,nd2) ! values of the field read in
795  integer :: ilength
796  !
797  real(8),allocatable :: temp(:)
798  !
799  character*40,parameter :: thissubname='replace_var_nc_double_2d'
800  !
801  integer :: i,j,k
802  integer :: istart,iend
803  !
804  !
805  ilength=nd1*nd2
806  allocate(temp(ilength))
807 
808  do j=1,nd2
809  istart=(j-1)*nd1+1
810  iend=(j-1)*nd1+nd1
811  temp(istart:iend)=field(:,j)
812  enddo
813  !
814  if(this%debug_level>100) then
815  write(*,*) trim(thissubname),' show samples:'
816  write(*,*) 'max,min:',maxval(field(:,:)),minval(field(:,:))
817  endif
818 
819  call this%replace_var_nc_double(varname,ilength,temp)
820 
821  deallocate(temp)
822  !
823  end subroutine replace_var_nc_double_2d
824 
834  subroutine replace_var_nc_double_3d(this,varname,nd1,nd2,nd3,field)
835  !
836  ! read in one field
837  !
838  use netcdf
839  !
840  implicit none
841  !
842  class(ncio) :: this
843  character(len=*),intent(in) :: varname ! name of the field to read
844  integer, intent(in) :: nd1,nd2,nd3 ! size of array dval
845  real(8), intent(in) :: field(nd1,nd2,nd3) ! values of the field read in
846  integer :: ilength
847  !
848  real(8),allocatable :: temp(:)
849  !
850  character*40,parameter :: thissubname='replace_var_nc_double_3d'
851  !
852  integer :: i,j,k
853  integer :: length2d
854  integer :: istart,iend
855  !
856  !
857  length2d=nd1*nd2
858  ilength=length2d*nd3
859  allocate(temp(ilength))
860 
861  do k=1,nd3
862  do j=1,nd2
863  istart=(k-1)*length2d+(j-1)*nd1+1
864  iend =(k-1)*length2d+(j-1)*nd1+nd1
865  temp(istart:iend)=field(:,j,k)
866  enddo
867  enddo
868  !
869  if(this%debug_level>100) then
870  write(*,*) trim(thissubname),' show samples:'
871  do k=1,nd3
872  write(*,*) 'k,max,min:',k,maxval(field(:,:,k)),minval(field(:,:,k))
873  enddo
874  endif
875 
876  call this%replace_var_nc_double(varname,ilength,temp)
877 
878  deallocate(temp)
879  !
880  end subroutine replace_var_nc_double_3d
881  !
882 
890  subroutine replace_var_nc_double(this,varname,ilength,field)
891  use netcdf
892  !
893  implicit none
894  !
895  class(ncio) :: this
896  character(len=*),intent(in) :: varname ! name of the field to read
897  integer, intent(in) :: ilength ! size of array dval
898  real(8), intent(in) :: field(ilength) ! values of the field read in
899  !
900  integer :: ncid
901  !
902  integer :: status
903  integer :: varid
904  integer :: ends(4),start(4)
905 
906  integer :: length4d,length3d,length2d
907  integer :: ndims,ndim
908  integer :: dimids(4)
909  integer :: xtype
910  character*40 :: dimname
911 
912  character*40,parameter :: thissubname='replace_var_nc_double'
913  !
914  integer :: i,k
915  !
916  !
917  ncid=this%ncid
918 
919  ! get variable IDs
920  status = nf90_inq_varid(ncid, trim(varname), varid)
921  if(status /= nf90_noerr) call this%handle_err(status)
922 
923  ! get dimensions
924  ends=1
925  start=1
926  this%ends=1
927 
928  this%dimname=" "
929  ! get variable type
930  status = nf90_inquire_variable(ncid, varid, xtype = xtype)
931  if(status /= nf90_noerr) call this%handle_err(status)
932  if(xtype==nf90_double) then
933  this%xtype=xtype
934  else
935  write(*,*) trim(thissubname),' ERROR: wrong data type, expect ',nf90_int,' but read in ',xtype
936  stop 123
937  endif
938 
939  ! get dimension size
940  status = nf90_inquire_variable(ncid, varid, ndims = ndims)
941  if(status /= nf90_noerr) call this%handle_err(status)
942  this%ndims=ndims
943  !
944  status = nf90_inquire_variable(ncid, varid, dimids = dimids(1:ndims))
945  if(status /= nf90_noerr) call this%handle_err(status)
946  do i=1,ndims
947  dimname=" "
948  status = nf90_inquire_dimension(ncid, dimids(i), dimname, len = ndim)
949  if (status /= nf90_noerr) call this%handle_err(status)
950  ends(i)=ndim
951  this%ends(i)=ends(i)
952  this%dimname(i)=trim(dimname)
953  if(this%ends(i) < 1) then
954  write(*,*) trim(thissubname),' Error, ends dimension should larger than 0 :', ends(i)
955  stop 1234
956  endif
957  enddo
958  length2d=ends(1)*ends(2)
959  length3d=length2d*ends(3)
960  length4d=length3d*ends(4)
961  if(ilength .ne. length4d) then
962  write(*,*) trim(thissubname),'ERROR: ',ilength,' should equal to ',length4d
963  stop 123
964  endif
965  !
966  if(ndims <=4 ) then
967  status = nf90_put_var(ncid, varid, field, &
968  start = start(1:4) , &
969  count = ends(1:4))
970  if(status /= nf90_noerr) call this%handle_err(status)
971  else
972  write(*,*) trim(thissubname),'Error: too many dimensions:',ndims
973  stop 1234
974  endif
975  !
976  if(this%debug_level>0) then
977  write(*,'(a,a)') '>>>replace variable: ',trim(varname)
978  endif
979  if(this%debug_level>10) then
980  write(*,'(8x,a,I10)') 'data type : ',this%xtype
981  write(*,'(8x,a,I10)') 'dimension size: ',this%nDims
982  do i=1,this%nDims
983  write(*,'(8x,a,I5,I10,2x,a)') 'rank, ends, name=',i,this%ends(i),trim(this%dimname(i))
984  enddo
985  endif
986  !
987  end subroutine replace_var_nc_double
988 
996  subroutine replace_var_nc_int_1d(this,varname,nd1,field)
997  use netcdf
998  !
999  implicit none
1000  !
1001  class(ncio) :: this
1002  character(len=*),intent(in) :: varname ! name of the field to read
1003  integer, intent(in) :: nd1 ! size of array dval
1004  integer, intent(in) :: field(nd1) ! values of the field read in
1005  integer :: ilength
1006  !
1007  character*40,parameter :: thissubname='get_var_nc_int_1d'
1008  !
1009  integer :: i
1010  !
1011  !
1012  ilength=nd1
1013  !
1014  if(this%debug_level>100) then
1015  write(*,*) trim(thissubname),' show samples:'
1016  write(*,*) (field(i),i=1,min(nd1,10))
1017  endif
1018 
1019  call this%replace_var_nc_int(varname,ilength,field)
1020  !
1021  end subroutine replace_var_nc_int_1d
1022 
1031  subroutine replace_var_nc_int_2d(this,varname,nd1,nd2,field)
1032  !
1033  ! read in one field
1034  !
1035  use netcdf
1036  !
1037  implicit none
1038  !
1039  class(ncio) :: this
1040  character(len=*),intent(in) :: varname ! name of the field to read
1041  integer, intent(in) :: nd1,nd2 ! size of array dval
1042  integer, intent(in) :: field(nd1,nd2) ! values of the field read in
1043  integer :: ilength
1044  !
1045  integer,allocatable :: temp(:)
1046  !
1047  character*40,parameter :: thissubname='replace_var_nc_int_2d'
1048  !
1049  integer :: i,j,k
1050  integer :: istart,iend
1051  !
1052  !
1053  ilength=nd1*nd2
1054  allocate(temp(ilength))
1055 
1056  do j=1,nd2
1057  istart=(j-1)*nd1+1
1058  iend=(j-1)*nd1+nd1
1059  temp(istart:iend)=field(:,j)
1060  enddo
1061  !
1062  if(this%debug_level>100) then
1063  write(*,*) trim(thissubname),' show samples:'
1064  write(*,*) 'max,min:',maxval(field(:,:)),minval(field(:,:))
1065  endif
1066 
1067  call this%replace_var_nc_int(varname,ilength,temp)
1068 
1069  deallocate(temp)
1070  !
1071  end subroutine replace_var_nc_int_2d
1072 
1082  subroutine replace_var_nc_int_3d(this,varname,nd1,nd2,nd3,field)
1083  use netcdf
1084  !
1085  implicit none
1086  !
1087  class(ncio) :: this
1088  character(len=*),intent(in) :: varname ! name of the field to read
1089  integer, intent(in) :: nd1,nd2,nd3 ! size of array dval
1090  integer, intent(in) :: field(nd1,nd2,nd3) ! values of the field read in
1091  integer :: ilength
1092  !
1093  integer,allocatable :: temp(:)
1094  !
1095  character*40,parameter :: thissubname='replace_var_nc_int_3d'
1096  !
1097  integer :: i,j,k
1098  integer :: length2d
1099  integer :: istart,iend
1100  !
1101  !
1102  length2d=nd1*nd2
1103  ilength=length2d*nd3
1104  allocate(temp(ilength))
1105 
1106  do k=1,nd3
1107  do j=1,nd2
1108  istart=(k-1)*length2d+(j-1)*nd1+1
1109  iend =(k-1)*length2d+(j-1)*nd1+nd1
1110  temp(istart:iend)=field(:,j,k)
1111  enddo
1112  enddo
1113  !
1114  if(this%debug_level>100) then
1115  write(*,*) trim(thissubname),' show samples:'
1116  do k=1,nd3
1117  write(*,*) 'k,max,min:',k,maxval(field(:,:,k)),minval(field(:,:,k))
1118  enddo
1119  endif
1120 
1121  call this%replace_var_nc_int(varname,ilength,temp)
1122 
1123  deallocate(temp)
1124  !
1125  end subroutine replace_var_nc_int_3d
1126 
1134  subroutine replace_var_nc_int(this,varname,ilength,field)
1135  use netcdf
1136  !
1137  implicit none
1138  !
1139  class(ncio) :: this
1140  character(len=*),intent(in) :: varname ! name of the field to read
1141  integer, intent(in) :: ilength ! size of array dval
1142  integer, intent(in) :: field(ilength) ! values of the field read in
1143  !
1144  integer :: ncid
1145  !
1146  integer :: status
1147  integer :: varid
1148  integer :: ends(4),start(4)
1149 
1150  integer :: length4d,length3d,length2d
1151  integer :: ndims,ndim
1152  integer :: dimids(4)
1153  integer :: xtype
1154  character*40 :: dimname
1155 
1156  character*40,parameter :: thissubname='replace_var_nc_int'
1157  !
1158  integer :: i,k
1159  !
1160  !
1161  ncid=this%ncid
1162 
1163  ! get variable IDs
1164  status = nf90_inq_varid(ncid, trim(varname), varid)
1165  if(status /= nf90_noerr) call this%handle_err(status)
1166 
1167  ! get dimensions
1168  ends=1
1169  start=1
1170  this%ends=1
1171 
1172  this%dimname=" "
1173  ! get variable type
1174  status = nf90_inquire_variable(ncid, varid, xtype = xtype)
1175  if(status /= nf90_noerr) call this%handle_err(status)
1176  if(xtype==nf90_int) then
1177  this%xtype=xtype
1178  else
1179  write(*,*) trim(thissubname),' ERROR: wrong data type, expect ',nf90_int,' but read in ',xtype
1180  stop 123
1181  endif
1182 
1183  ! get dimension size
1184  status = nf90_inquire_variable(ncid, varid, ndims = ndims)
1185  if(status /= nf90_noerr) call this%handle_err(status)
1186  this%ndims=ndims
1187  !
1188  status = nf90_inquire_variable(ncid, varid, dimids = dimids(1:ndims))
1189  if(status /= nf90_noerr) call this%handle_err(status)
1190  do i=1,ndims
1191  dimname=" "
1192  status = nf90_inquire_dimension(ncid, dimids(i), dimname, len = ndim)
1193  if (status /= nf90_noerr) call this%handle_err(status)
1194  ends(i)=ndim
1195  this%ends(i)=ends(i)
1196  this%dimname(i)=trim(dimname)
1197  if(this%ends(i) < 1) then
1198  write(*,*) trim(thissubname),' Error, ends dimension should larger than 0 :', ends(i)
1199  stop 1234
1200  endif
1201  enddo
1202  length2d=ends(1)*ends(2)
1203  length3d=length2d*ends(3)
1204  length4d=length3d*ends(4)
1205  if(ilength .ne. length4d) then
1206  write(*,*) trim(thissubname),'ERROR: ',ilength,' should equal to ',length4d
1207  stop 123
1208  endif
1209  !
1210  if(ndims <=4 ) then
1211  status = nf90_put_var(ncid, varid, field, &
1212  start = start(1:4) , &
1213  count = ends(1:4))
1214  if(status /= nf90_noerr) call this%handle_err(status)
1215  else
1216  write(*,*) trim(thissubname),'Error: too many dimensions:',ndims
1217  stop 1234
1218  endif
1219  !
1220  if(this%debug_level>0) then
1221  write(*,'(a,a)') '>>>replace variable: ',trim(varname)
1222  endif
1223  if(this%debug_level>10) then
1224  write(*,'(8x,a,I10)') 'data type : ',this%xtype
1225  write(*,'(8x,a,I10)') 'dimension size: ',this%nDims
1226  do i=1,this%nDims
1227  write(*,'(8x,a,I5,I10,2x,a)') 'rank, ends, name=',i,this%ends(i),trim(this%dimname(i))
1228  enddo
1229  endif
1230  !
1231  end subroutine replace_var_nc_int
1232 
1240  subroutine get_var_nc_double_1d(this,varname,nd1,field)
1241  use netcdf
1242  !
1243  implicit none
1244  !
1245  class(ncio) :: this
1246  character(len=*),intent(in) :: varname ! name of the field to read
1247  integer, intent(in) :: nd1 ! size of array dval
1248  real(8), intent(out) :: field(nd1) ! values of the field read in
1249  integer :: ilength
1250  !
1251  character*40,parameter :: thissubname='get_var_nc_double_1d'
1252  !
1253  integer :: i
1254  !
1255  !
1256  ilength=nd1
1257  call this%get_var_nc_double(varname,ilength,field)
1258  !
1259  if(nd1==this%ends(1)) then
1260  if(this%debug_level>100) then
1261  write(*,*) trim(thissubname),' show samples:'
1262  write(*,*) (field(i),i=1,min(nd1,10))
1263  endif
1264  else
1265  write(*,*) trim(thissubname),' ERROR: dimension does not match.'
1266  endif
1267  !
1268  end subroutine get_var_nc_double_1d
1269 
1278  subroutine get_var_nc_double_2d(this,varname,nd1,nd2,field)
1279  use netcdf
1280  !
1281  implicit none
1282  !
1283  class(ncio) :: this
1284  character(len=*),intent(in) :: varname ! name of the field to read
1285  integer, intent(in) :: nd1,nd2 ! size of array dval
1286  real(8), intent(out) :: field(nd1,nd2) ! values of the field read in
1287  integer :: ilength
1288  !
1289  real(8),allocatable :: temp(:)
1290  !
1291  character*40,parameter :: thissubname='get_var_nc_double_2d'
1292  !
1293  integer :: i,j,k
1294  integer :: istart,iend
1295  !
1296  !
1297  ilength=nd1*nd2
1298  allocate(temp(ilength))
1299 
1300  call this%get_var_nc_double(varname,ilength,temp)
1301 
1302  if(nd1==this%ends(1) .and. nd2==this%ends(2)) then
1303  do j=1,nd2
1304  istart=(j-1)*nd1+1
1305  iend=(j-1)*nd1+nd1
1306  field(:,j)=temp(istart:iend)
1307  enddo
1308  !
1309  if(this%debug_level>100) then
1310  write(*,*) trim(thissubname),' show samples:'
1311  write(*,*) 'max,min:',maxval(field(:,:)),minval(field(:,:))
1312  endif
1313  else
1314  write(*,*) trim(thissubname),' ERROR: dimension does not match.'
1315  write(*,*) nd1,this%ends(1),nd2,this%ends(2)
1316  endif
1317  deallocate(temp)
1318  !
1319  end subroutine get_var_nc_double_2d
1320 
1330  subroutine get_var_nc_double_3d(this,varname,nd1,nd2,nd3,field)
1331  use netcdf
1332  !
1333  implicit none
1334  !
1335  class(ncio) :: this
1336  character(len=*),intent(in) :: varname ! name of the field to read
1337  integer, intent(in) :: nd1,nd2,nd3 ! size of array dval
1338  real(8), intent(out) :: field(nd1,nd2,nd3) ! values of the field read in
1339  integer :: ilength
1340  !
1341  real(8),allocatable :: temp(:)
1342  !
1343  character*40,parameter :: thissubname='get_var_nc_double_3d'
1344  !
1345  integer :: i,j,k
1346  integer :: length2d
1347  integer :: istart,iend
1348  !
1349  !
1350  length2d=nd1*nd2
1351  ilength=length2d*nd3
1352  allocate(temp(ilength))
1353 
1354  call this%get_var_nc_double(varname,ilength,temp)
1355 
1356  if(nd1==this%ends(1) .and. nd2==this%ends(2) .and. nd3==this%ends(3)) then
1357  do k=1,nd3
1358  do j=1,nd2
1359  istart=(k-1)*length2d+(j-1)*nd1+1
1360  iend =(k-1)*length2d+(j-1)*nd1+nd1
1361  field(:,j,k)=temp(istart:iend)
1362  enddo
1363  enddo
1364  !
1365  if(this%debug_level>100) then
1366  write(*,*) trim(thissubname),' show samples:'
1367  do k=1,nd3
1368  write(*,*) 'k,max,min:',k,maxval(field(:,:,k)),minval(field(:,:,k))
1369  enddo
1370  endif
1371  else
1372  write(*,*) trim(thissubname),' ERROR: dimension does not match.'
1373  write(*,*) nd1,this%ends(1),nd2,this%ends(2),nd3,this%ends(3)
1374  endif
1375  deallocate(temp)
1376  !
1377  end subroutine get_var_nc_double_3d
1378 
1386  subroutine get_var_nc_double(this,varname,ilength,field)
1387  use netcdf
1388  !
1389  implicit none
1390  !
1391  class(ncio) :: this
1392  character(len=*),intent(in) :: varname ! name of the field to read
1393  integer, intent(in) :: ilength ! size of array dval
1394  real(8), intent(out) :: field(ilength) ! values of the field read in
1395  !
1396  integer :: ncid
1397  !
1398  integer :: status
1399  integer :: varid
1400  integer :: ends(4),start(4)
1401 
1402  integer :: length4d,length3d,length2d
1403  integer :: ndims,ndim
1404  integer :: dimids(4)
1405  integer :: xtype
1406  character*40 :: dimname
1407 
1408  character*40,parameter :: thissubname='get_var_nc_double'
1409  !
1410  integer :: i,k
1411  !
1412  !
1413  ncid=this%ncid
1414 
1415  ! get variable IDs
1416  status = nf90_inq_varid(ncid, trim(varname), varid)
1417  if(status /= nf90_noerr) call this%handle_err(status)
1418 
1419  ! get dimensions
1420  ends=1
1421  start=1
1422  this%ends=1
1423 
1424  this%dimname=" "
1425  ! get variable type
1426  status = nf90_inquire_variable(ncid, varid, xtype = xtype)
1427  if(status /= nf90_noerr) call this%handle_err(status)
1428  if(xtype==nf90_double) then
1429  this%xtype=xtype
1430  else
1431  write(*,*) trim(thissubname),' ERROR: wrong data type, expect ',nf90_double,' but read in ',xtype
1432  stop 123
1433  endif
1434 
1435  ! get dimension size
1436  status = nf90_inquire_variable(ncid, varid, ndims = ndims)
1437  if(status /= nf90_noerr) call this%handle_err(status)
1438  this%ndims=ndims
1439  !
1440  status = nf90_inquire_variable(ncid, varid, dimids = dimids(1:ndims))
1441  if(status /= nf90_noerr) call this%handle_err(status)
1442  do i=1,ndims
1443  dimname=" "
1444  status = nf90_inquire_dimension(ncid, dimids(i), dimname, len = ndim)
1445  if (status /= nf90_noerr) call this%handle_err(status)
1446  ends(i)=ndim
1447  this%ends(i)=ends(i)
1448  this%dimname(i)=trim(dimname)
1449  if(this%ends(i) < 1) then
1450  write(*,*) trim(thissubname),' Error, ends dimension should larger than 0 :', ends(i)
1451  stop 1234
1452  endif
1453  enddo
1454  length2d=ends(1)*ends(2)
1455  length3d=length2d*ends(3)
1456  length4d=length3d*ends(4)
1457  if(ilength .ne. length4d) then
1458  write(*,*) trim(thissubname),'ERROR: ',ilength,' should equal to ',length4d
1459  stop 123
1460  endif
1461  !
1462  if(ndims <=4 ) then
1463  status = nf90_get_var(ncid, varid, field, &
1464  start = start(1:4) , &
1465  count = ends(1:4))
1466  if(status /= nf90_noerr) call this%handle_err(status)
1467  else
1468  write(*,*) trim(thissubname),'Error: too many dimensions:',ndims
1469  stop 1234
1470  endif
1471  !
1472  if(this%debug_level>0) then
1473  write(*,'(a,a)') '>>>read in variable: ',trim(varname)
1474  endif
1475  if(this%debug_level>10) then
1476  write(*,'(a,I10)') ' data type : ',this%xtype
1477  write(*,'(a,I10)')' dimension size: ',this%nDims
1478  do i=1,this%nDims
1479  write(*,'(a,I5,I10,2x,a)') ' rank, ends, name=',i,this%ends(i),trim(this%dimname(i))
1480  enddo
1481  endif
1482  !
1483  end subroutine get_var_nc_double
1484 
1492  subroutine get_var_nc_real_1d(this,varname,nd1,field)
1493  use netcdf
1494  !
1495  implicit none
1496  !
1497  class(ncio) :: this
1498  character(len=*),intent(in) :: varname ! name of the field to read
1499  integer, intent(in) :: nd1 ! size of array dval
1500  real(4), intent(out) :: field(nd1) ! values of the field read in
1501  integer :: ilength
1502  !
1503  character*40,parameter :: thissubname='get_var_nc_real_1d'
1504  !
1505  integer :: i
1506  !
1507  !
1508  ilength=nd1
1509  call this%get_var_nc_real(varname,ilength,field)
1510  !
1511  if(nd1==this%ends(1)) then
1512  if(this%debug_level>100) then
1513  write(*,*) trim(thissubname),' show samples:'
1514  write(*,*) (field(i),i=1,min(nd1,10))
1515  endif
1516  else
1517  write(*,*) trim(thissubname),' ERROR: dimension does not match.'
1518  endif
1519  !
1520  end subroutine get_var_nc_real_1d
1521 
1530  subroutine get_var_nc_real_2d(this,varname,nd1,nd2,field)
1531  !
1532  ! read in one field
1533  !
1534  use netcdf
1535  !
1536  implicit none
1537  !
1538  class(ncio) :: this
1539  character(len=*),intent(in) :: varname ! name of the field to read
1540  integer, intent(in) :: nd1,nd2 ! size of array dval
1541  real(4), intent(out) :: field(nd1,nd2) ! values of the field read in
1542  integer :: ilength
1543  !
1544  real(4),allocatable :: temp(:)
1545  !
1546  character*40,parameter :: thissubname='get_var_nc_real_2d'
1547  !
1548  integer :: i,j,k
1549  integer :: istart,iend
1550  !
1551  !
1552  ilength=nd1*nd2
1553  allocate(temp(ilength))
1554 
1555  call this%get_var_nc_real(varname,ilength,temp)
1556 
1557  if(nd1==this%ends(1) .and. nd2==this%ends(2)) then
1558  do j=1,nd2
1559  istart=(j-1)*nd1+1
1560  iend=(j-1)*nd1+nd1
1561  field(:,j)=temp(istart:iend)
1562  enddo
1563  !
1564  if(this%debug_level>100) then
1565  write(*,*) trim(thissubname),' show samples:'
1566  write(*,*) 'max,min:',maxval(field(:,:)),minval(field(:,:))
1567  endif
1568  else
1569  write(*,*) trim(thissubname),' ERROR: dimension does not match.'
1570  write(*,*) nd1,this%ends(1),nd2,this%ends(2)
1571  endif
1572  deallocate(temp)
1573  !
1574  end subroutine get_var_nc_real_2d
1575 
1585  subroutine get_var_nc_real_3d(this,varname,nd1,nd2,nd3,field)
1586  use netcdf
1587  !
1588  implicit none
1589  !
1590  class(ncio) :: this
1591  character(len=*),intent(in) :: varname ! name of the field to read
1592  integer, intent(in) :: nd1,nd2,nd3 ! size of array dval
1593  real(4), intent(out) :: field(nd1,nd2,nd3) ! values of the field read in
1594  integer :: ilength
1595  !
1596  real(4),allocatable :: temp(:)
1597  !
1598  character*40,parameter :: thissubname='get_var_nc_real_3d'
1599  !
1600  integer :: i,j,k
1601  integer :: length2d
1602  integer :: istart,iend
1603  !
1604  !
1605  length2d=nd1*nd2
1606  ilength=length2d*nd3
1607  allocate(temp(ilength))
1608 
1609  call this%get_var_nc_real(varname,ilength,temp)
1610 
1611  if(nd1==this%ends(1) .and. nd2==this%ends(2) .and. nd3==this%ends(3)) then
1612  do k=1,nd3
1613  do j=1,nd2
1614  istart=(k-1)*length2d+(j-1)*nd1+1
1615  iend =(k-1)*length2d+(j-1)*nd1+nd1
1616  field(:,j,k)=temp(istart:iend)
1617  enddo
1618  enddo
1619  !
1620  if(this%debug_level>100) then
1621  write(*,*) trim(thissubname),' show samples:'
1622  do k=1,nd3
1623  write(*,*) 'k,max,min:',k,maxval(field(:,:,k)),minval(field(:,:,k))
1624  enddo
1625  endif
1626  else
1627  write(*,*) trim(thissubname),' ERROR: dimension does not match.'
1628  write(*,*) nd1,this%ends(1),nd2,this%ends(2),nd3,this%ends(3)
1629  endif
1630  deallocate(temp)
1631  !
1632  end subroutine get_var_nc_real_3d
1633 
1641  subroutine get_var_nc_real(this,varname,ilength,field)
1642  !
1643  ! read in one field
1644  !
1645  use netcdf
1646  !
1647  implicit none
1648  !
1649  class(ncio) :: this
1650  character(len=*),intent(in) :: varname ! name of the field to read
1651  integer, intent(in) :: ilength ! size of array dval
1652  real(4), intent(out) :: field(ilength) ! values of the field read in
1653  !
1654  integer :: ncid
1655  !
1656  integer :: status
1657  integer :: varid
1658  integer :: ends(4),start(4)
1659 
1660  integer :: length4d,length3d,length2d
1661  integer :: ndims,ndim
1662  integer :: dimids(4)
1663  integer :: xtype
1664  character*40 :: dimname
1665 
1666  character*40,parameter :: thissubname='get_var_nc_real'
1667  !
1668  integer :: i,k
1669  !
1670  !
1671  ncid=this%ncid
1672 
1673  ! get variable IDs
1674  status = nf90_inq_varid(ncid, trim(varname), varid)
1675  if(status /= nf90_noerr) call this%handle_err(status)
1676 
1677  ! get dimensions
1678  ends=1
1679  start=1
1680  this%ends=1
1681 
1682  this%dimname=" "
1683  ! get variable type
1684  status = nf90_inquire_variable(ncid, varid, xtype = xtype)
1685  if(status /= nf90_noerr) call this%handle_err(status)
1686  if(xtype==nf90_float) then
1687  this%xtype=xtype
1688  else
1689  write(*,*) trim(thissubname),' ERROR: wrong data type, expect ',nf90_float,' but read in ',xtype
1690  stop 123
1691  endif
1692 
1693  ! get dimension size
1694  status = nf90_inquire_variable(ncid, varid, ndims = ndims)
1695  if(status /= nf90_noerr) call this%handle_err(status)
1696  this%ndims=ndims
1697  !
1698  status = nf90_inquire_variable(ncid, varid, dimids = dimids(1:ndims))
1699  if(status /= nf90_noerr) call this%handle_err(status)
1700  do i=1,ndims
1701  dimname=" "
1702  status = nf90_inquire_dimension(ncid, dimids(i), dimname, len = ndim)
1703  if (status /= nf90_noerr) call this%handle_err(status)
1704  ends(i)=ndim
1705  this%ends(i)=ends(i)
1706  this%dimname(i)=trim(dimname)
1707  if(this%ends(i) < 1) then
1708  write(*,*) trim(thissubname),' Error, ends dimension should larger than 0 :', ends(i)
1709  stop 1234
1710  endif
1711  enddo
1712  length2d=ends(1)*ends(2)
1713  length3d=length2d*ends(3)
1714  length4d=length3d*ends(4)
1715  if(ilength .ne. length4d) then
1716  write(*,*) trim(thissubname),'ERROR: ',ilength,' should equal to ',length4d
1717  stop 123
1718  endif
1719  !
1720  if(ndims <=4 ) then
1721  status = nf90_get_var(ncid, varid, field, &
1722  start = start(1:4) , &
1723  count = ends(1:4))
1724  if(status /= nf90_noerr) call this%handle_err(status)
1725  else
1726  write(*,*) trim(thissubname),'Error: too many dimensions:',ndims
1727  stop 1234
1728  endif
1729  !
1730  if(this%debug_level>0) then
1731  write(*,'(a,a)') '>>>read in variable: ',trim(varname)
1732  endif
1733  if(this%debug_level>10) then
1734  write(*,'(8x,a,I10)') 'data type : ',this%xtype
1735  write(*,'(8x,a,I10)') 'dimension size: ',this%nDims
1736  do i=1,this%nDims
1737  write(*,'(8x,a,I5,I10,2x,a)') 'rank, ends, name=',i,this%ends(i),trim(this%dimname(i))
1738  enddo
1739  endif
1740  !
1741  end subroutine get_var_nc_real
1742 
1750  subroutine get_var_nc_int_1d(this,varname,nd1,field)
1751  use netcdf
1752  !
1753  implicit none
1754  !
1755  class(ncio) :: this
1756  character(len=*),intent(in) :: varname ! name of the field to read
1757  integer, intent(in) :: nd1 ! size of array dval
1758  integer, intent(out) :: field(nd1) ! values of the field read in
1759  integer :: ilength
1760  !
1761  character*40,parameter :: thissubname='get_var_nc_int_1d'
1762  !
1763  integer :: i
1764  !
1765  !
1766  ilength=nd1
1767  call this%get_var_nc_int(varname,ilength,field)
1768  !
1769  if(nd1==this%ends(1)) then
1770  if(this%debug_level>100) then
1771  write(*,*) trim(thissubname),' show samples:'
1772  write(*,*) (field(i),i=1,min(nd1,10))
1773  endif
1774  else
1775  write(*,*) trim(thissubname),' ERROR: dimension does not match.'
1776  endif
1777  !
1778  end subroutine get_var_nc_int_1d
1779 
1788  subroutine get_var_nc_int_2d(this,varname,nd1,nd2,field)
1789  !
1790  ! read in one field
1791  !
1792  use netcdf
1793  !
1794  implicit none
1795  !
1796  class(ncio) :: this
1797  character(len=*),intent(in) :: varname ! name of the field to read
1798  integer, intent(in) :: nd1,nd2 ! size of array dval
1799  integer, intent(out) :: field(nd1,nd2) ! values of the field read in
1800  integer :: ilength
1801  !
1802  integer,allocatable :: temp(:)
1803  !
1804  character*40,parameter :: thissubname='get_var_nc_int_2d'
1805  !
1806  integer :: i,j,k
1807  integer :: istart,iend
1808  !
1809  !
1810  ilength=nd1*nd2
1811  allocate(temp(ilength))
1812 
1813  call this%get_var_nc_int(varname,ilength,temp)
1814 
1815  if(nd1==this%ends(1) .and. nd2==this%ends(2)) then
1816  do j=1,nd2
1817  istart=(j-1)*nd1+1
1818  iend=(j-1)*nd1+nd1
1819  field(:,j)=temp(istart:iend)
1820  enddo
1821  !
1822  if(this%debug_level>100) then
1823  write(*,*) trim(thissubname),' show samples:'
1824  write(*,*) 'max,min:',maxval(field(:,:)),minval(field(:,:))
1825  endif
1826  else
1827  write(*,*) trim(thissubname),' ERROR: dimension does not match.'
1828  write(*,*) nd1,this%ends(1),nd2,this%ends(2)
1829  endif
1830  deallocate(temp)
1831  !
1832  end subroutine get_var_nc_int_2d
1833 
1843  subroutine get_var_nc_int_3d(this,varname,nd1,nd2,nd3,field)
1844  use netcdf
1845  !
1846  implicit none
1847  !
1848  class(ncio) :: this
1849  character(len=*),intent(in) :: varname ! name of the field to read
1850  integer, intent(in) :: nd1,nd2,nd3 ! size of array dval
1851  integer, intent(out) :: field(nd1,nd2,nd3) ! values of the field read in
1852  integer :: ilength
1853  !
1854  integer,allocatable :: temp(:)
1855  !
1856  character*40,parameter :: thissubname='get_var_nc_int_3d'
1857  !
1858  integer :: i,j,k
1859  integer :: length2d
1860  integer :: istart,iend
1861  !
1862  !
1863  length2d=nd1*nd2
1864  ilength=length2d*nd3
1865  allocate(temp(ilength))
1866 
1867  call this%get_var_nc_int(varname,ilength,temp)
1868 
1869  if(nd1==this%ends(1) .and. nd2==this%ends(2) .and. nd3==this%ends(3)) then
1870  do k=1,nd3
1871  do j=1,nd2
1872  istart=(k-1)*length2d+(j-1)*nd1+1
1873  iend =(k-1)*length2d+(j-1)*nd1+nd1
1874  field(:,j,k)=temp(istart:iend)
1875  enddo
1876  enddo
1877  !
1878  if(this%debug_level>100) then
1879  write(*,*) trim(thissubname),' show samples:'
1880  do k=1,nd3
1881  write(*,*) 'k,max,min:',k,maxval(field(:,:,k)),minval(field(:,:,k))
1882  enddo
1883  endif
1884  else
1885  write(*,*) trim(thissubname),' ERROR: dimension does not match.'
1886  write(*,*) nd1,this%ends(1),nd2,this%ends(2),nd3,this%ends(3)
1887  endif
1888  deallocate(temp)
1889  !
1890  end subroutine get_var_nc_int_3d
1891 
1899  subroutine get_var_nc_int(this,varname,ilength,field)
1900  !
1901  ! read in one field
1902  !
1903  use netcdf
1904  !
1905  implicit none
1906  !
1907  class(ncio) :: this
1908  character(len=*),intent(in) :: varname ! name of the field to read
1909  integer, intent(in) :: ilength ! size of array dval
1910  integer, intent(out) :: field(ilength) ! values of the field read in
1911  !
1912  integer :: ncid
1913  !
1914  integer :: status
1915  integer :: varid
1916  integer :: ends(4),start(4)
1917 
1918  integer :: length4d,length3d,length2d
1919  integer :: ndims,ndim
1920  integer :: dimids(4)
1921  integer :: xtype
1922  character*40 :: dimname
1923 
1924  character*40,parameter :: thissubname='get_var_nc_int'
1925  !
1926  integer :: i,k
1927  !
1928  !
1929  ncid=this%ncid
1930 
1931  ! get variable IDs
1932  status = nf90_inq_varid(ncid, trim(varname), varid)
1933  if(status /= nf90_noerr) call this%handle_err(status)
1934 
1935  ! get dimensions
1936  ends=1
1937  start=1
1938  this%ends=1
1939 
1940  this%dimname=" "
1941  ! get variable type
1942  status = nf90_inquire_variable(ncid, varid, xtype = xtype)
1943  if(status /= nf90_noerr) call this%handle_err(status)
1944  if(xtype==nf90_int) then
1945  this%xtype=xtype
1946  else
1947  write(*,*) trim(thissubname),' ERROR: wrong data type, expect ',nf90_int,' but read in ',xtype
1948  stop 123
1949  endif
1950 
1951  ! get dimension size
1952  status = nf90_inquire_variable(ncid, varid, ndims = ndims)
1953  if(status /= nf90_noerr) call this%handle_err(status)
1954  this%ndims=ndims
1955  !
1956  status = nf90_inquire_variable(ncid, varid, dimids = dimids(1:ndims))
1957  if(status /= nf90_noerr) call this%handle_err(status)
1958  do i=1,ndims
1959  dimname=" "
1960  status = nf90_inquire_dimension(ncid, dimids(i), dimname, len = ndim)
1961  if (status /= nf90_noerr) call this%handle_err(status)
1962  ends(i)=ndim
1963  this%ends(i)=ends(i)
1964  this%dimname(i)=trim(dimname)
1965  if(this%ends(i) < 1) then
1966  write(*,*) trim(thissubname),' Error, ends dimension should larger than 0 :', ends(i)
1967  stop 1234
1968  endif
1969  enddo
1970  length2d=ends(1)*ends(2)
1971  length3d=length2d*ends(3)
1972  length4d=length3d*ends(4)
1973  if(ilength .ne. length4d) then
1974  write(*,*) trim(thissubname),'ERROR: ',ilength,' should equal to ',length4d
1975  stop 123
1976  endif
1977  !
1978  if(ndims <=4 ) then
1979  status = nf90_get_var(ncid, varid, field, &
1980  start = start(1:4) , &
1981  count = ends(1:4))
1982  if(status /= nf90_noerr) call this%handle_err(status)
1983  else
1984  write(*,*) trim(thissubname),'Error: too many dimensions:',ndims
1985  stop 1234
1986  endif
1987  !
1988  if(this%debug_level>0) then
1989  write(*,'(a,a)') '>>>read in variable: ',trim(varname)
1990  endif
1991  if(this%debug_level>10) then
1992  write(*,'(8x,a,I10)') 'data type : ',this%xtype
1993  write(*,'(8x,a,I10)') 'dimension size: ',this%nDims
1994  do i=1,this%nDims
1995  write(*,'(8x,a,I5,I10,2x,a)') 'rank, ends, name=',i,this%ends(i),trim(this%dimname(i))
1996  enddo
1997  endif
1998  !
1999  end subroutine get_var_nc_int
2000 
2008  subroutine get_var_nc_short_1d(this,varname,nd1,field)
2009  use netcdf
2010  !
2011  implicit none
2012  !
2013  class(ncio) :: this
2014  character(len=*),intent(in) :: varname ! name of the field to read
2015  integer, intent(in) :: nd1 ! size of array dval
2016  integer(2), intent(out) :: field(nd1) ! values of the field read in
2017  integer :: ilength
2018  !
2019  character*40,parameter :: thissubname='get_var_nc_short_1d'
2020  !
2021  integer :: i
2022  !
2023  !
2024  ilength=nd1
2025  call this%get_var_nc_short(varname,ilength,field)
2026  !
2027  if(nd1==this%ends(1)) then
2028  if(this%debug_level>100) then
2029  write(*,*) trim(thissubname),' show samples:'
2030  write(*,*) (field(i),i=1,min(nd1,10))
2031  endif
2032  else
2033  write(*,*) trim(thissubname),' ERROR: dimension does not match.'
2034  endif
2035  !
2036  end subroutine get_var_nc_short_1d
2037 
2046  subroutine get_var_nc_short_2d(this,varname,nd1,nd2,field)
2047  !
2048  ! read in one field
2049  !
2050  use netcdf
2051  !
2052  implicit none
2053  !
2054  class(ncio) :: this
2055  character(len=*),intent(in) :: varname ! name of the field to read
2056  integer, intent(in) :: nd1,nd2 ! size of array dval
2057  integer(2), intent(out) :: field(nd1,nd2) ! values of the field read in
2058  integer :: ilength
2059  !
2060  integer(2),allocatable :: temp(:)
2061  !
2062  character*40,parameter :: thissubname='get_var_nc_short_2d'
2063  !
2064  integer :: i,j,k
2065  integer :: istart,iend
2066  !
2067  !
2068  ilength=nd1*nd2
2069  allocate(temp(ilength))
2070 
2071  call this%get_var_nc_short(varname,ilength,temp)
2072 
2073  if(nd1==this%ends(1) .and. nd2==this%ends(2)) then
2074  do j=1,nd2
2075  istart=(j-1)*nd1+1
2076  iend=(j-1)*nd1+nd1
2077  field(:,j)=temp(istart:iend)
2078  enddo
2079  !
2080  if(this%debug_level>100) then
2081  write(*,*) trim(thissubname),' show samples:'
2082  write(*,*) 'max,min:',maxval(field(:,:)),minval(field(:,:))
2083  endif
2084  else
2085  write(*,*) trim(thissubname),' ERROR: dimension does not match.'
2086  write(*,*) nd1,this%ends(1),nd2,this%ends(2)
2087  endif
2088  deallocate(temp)
2089  !
2090  end subroutine get_var_nc_short_2d
2091  !
2099  subroutine get_var_nc_short(this,varname,ilength,field)
2100  use netcdf
2101  !
2102  implicit none
2103  !
2104  class(ncio) :: this
2105  character(len=*),intent(in) :: varname ! name of the field to read
2106  integer, intent(in) :: ilength ! size of array dval
2107  integer(2), intent(out) :: field(ilength) ! values of the field read in
2108  !
2109  integer :: ncid
2110  !
2111  integer :: status
2112  integer :: varid
2113  integer :: ends(4),start(4)
2114 
2115  integer :: length4d,length3d,length2d
2116  integer :: ndims,ndim
2117  integer :: dimids(4)
2118  integer :: xtype
2119  character*40 :: dimname
2120 
2121  character*40,parameter :: thissubname='get_var_nc_short'
2122  !
2123  integer :: i,k
2124  !
2125  !
2126  ncid=this%ncid
2127 
2128  ! get variable IDs
2129  status = nf90_inq_varid(ncid, trim(varname), varid)
2130  if(status /= nf90_noerr) call this%handle_err(status)
2131 
2132  ! get dimensions
2133  ends=1
2134  start=1
2135  this%ends=1
2136 
2137  this%dimname=" "
2138  ! get variable type
2139  status = nf90_inquire_variable(ncid, varid, xtype = xtype)
2140  if(status /= nf90_noerr) call this%handle_err(status)
2141  if(xtype==nf90_short) then
2142  this%xtype=xtype
2143  else
2144  write(*,*) trim(thissubname),' ERROR: wrong data type, expect ',nf90_short,' but read in ',xtype
2145  stop 123
2146  endif
2147 
2148  ! get dimension size
2149  status = nf90_inquire_variable(ncid, varid, ndims = ndims)
2150  if(status /= nf90_noerr) call this%handle_err(status)
2151  this%ndims=ndims
2152  !
2153  status = nf90_inquire_variable(ncid, varid, dimids = dimids(1:ndims))
2154  if(status /= nf90_noerr) call this%handle_err(status)
2155  do i=1,ndims
2156  dimname=" "
2157  status = nf90_inquire_dimension(ncid, dimids(i), dimname, len = ndim)
2158  if (status /= nf90_noerr) call this%handle_err(status)
2159  ends(i)=ndim
2160  this%ends(i)=ends(i)
2161  this%dimname(i)=trim(dimname)
2162  if(this%ends(i) < 1) then
2163  write(*,*) trim(thissubname),' Error, ends dimension should larger than 0 :', ends(i)
2164  stop 1234
2165  endif
2166  enddo
2167  length2d=ends(1)*ends(2)
2168  length3d=length2d*ends(3)
2169  length4d=length3d*ends(4)
2170  if(ilength .ne. length4d) then
2171  write(*,*) trim(thissubname),'ERROR: ',ilength,' should equal to ',length4d
2172  stop 123
2173  endif
2174  !
2175  if(ndims <=4 ) then
2176  status = nf90_get_var(ncid, varid, field, &
2177  start = start(1:4) , &
2178  count = ends(1:4))
2179  if(status /= nf90_noerr) call this%handle_err(status)
2180  else
2181  write(*,*) trim(thissubname),'Error: too many dimensions:',ndims
2182  stop 1234
2183  endif
2184  !
2185  if(this%debug_level>0) then
2186  write(*,'(a,a)') '>>>read in variable: ',trim(varname)
2187  endif
2188  if(this%debug_level>10) then
2189  write(*,'(8x,a,I10)') 'data type : ',this%xtype
2190  write(*,'(8x,a,I10)') 'dimension size: ',this%nDims
2191  do i=1,this%nDims
2192  write(*,'(8x,a,I5,I10,2x,a)') 'rank, ends, name=',i,this%ends(i),trim(this%dimname(i))
2193  enddo
2194  endif
2195  !
2196  end subroutine get_var_nc_short
2197 
2205  subroutine get_var_nc_char_1d(this,varname,nd1,field)
2206  use netcdf
2207  !
2208  implicit none
2209  !
2210  class(ncio) :: this
2211  character(len=*),intent(in) :: varname ! name of the field to read
2212  integer, intent(in) :: nd1 ! size of array dval
2213  character, intent(out) :: field(nd1) ! values of the field read in
2214  integer :: ilength
2215  !
2216  character*40,parameter :: thissubname='get_var_nc_char_1d'
2217  !
2218  integer :: i
2219  !
2220  !
2221  ilength=nd1
2222  call this%get_var_nc_char(varname,ilength,field)
2223  !
2224  if(nd1==this%ends(1)) then
2225  if(this%debug_level>100) then
2226  write(*,*) trim(thissubname),' show samples:'
2227  write(*,*) (field(i),i=1,min(nd1,10))
2228  endif
2229  else
2230  write(*,*) trim(thissubname),' ERROR: dimension does not match.'
2231  endif
2232  !
2233  end subroutine get_var_nc_char_1d
2234 
2243  subroutine get_var_nc_char_2d(this,varname,nd1,nd2,field)
2244  use netcdf
2245  !
2246  implicit none
2247  !
2248  class(ncio) :: this
2249  character(len=*),intent(in) :: varname ! name of the field to read
2250  integer, intent(in) :: nd1,nd2 ! size of array dval
2251  character, intent(out) :: field(nd1,nd2) ! values of the field read in
2252  integer :: ilength
2253  !
2254  character,allocatable :: temp(:)
2255  !
2256  character*40,parameter :: thissubname='get_var_nc_char_2d'
2257  !
2258  integer :: i,j,k
2259  integer :: istart,iend
2260  !
2261  !
2262  ilength=nd1*nd2
2263  allocate(temp(ilength))
2264 
2265  call this%get_var_nc_char(varname,ilength,temp)
2266 
2267  if(nd1==this%ends(1) .and. nd2==this%ends(2)) then
2268  do j=1,nd2
2269  istart=(j-1)*nd1+1
2270  iend=(j-1)*nd1+nd1
2271  field(:,j)=temp(istart:iend)
2272  enddo
2273  !
2274  if(this%debug_level>100) then
2275  write(*,*) trim(thissubname),' show samples:'
2276  write(*,*) field(1,1)
2277  endif
2278  else
2279  write(*,*) trim(thissubname),' ERROR: dimension does not match.'
2280  write(*,*) nd1,this%ends(1),nd2,this%ends(2)
2281  endif
2282  deallocate(temp)
2283  !
2284  end subroutine get_var_nc_char_2d
2285 
2295  subroutine get_var_nc_char_3d(this,varname,nd1,nd2,nd3,field)
2296  use netcdf
2297  !
2298  implicit none
2299  !
2300  class(ncio) :: this
2301  character(len=*),intent(in) :: varname ! name of the field to read
2302  integer, intent(in) :: nd1,nd2,nd3 ! size of array dval
2303  character, intent(out) :: field(nd1,nd2,nd3) ! values of the field read in
2304  integer :: ilength
2305  !
2306  character,allocatable :: temp(:)
2307  !
2308  character*40,parameter :: thissubname='get_var_nc_char_3d'
2309  !
2310  integer :: i,j,k
2311  integer :: length2d
2312  integer :: istart,iend
2313  !
2314  !
2315  length2d=nd1*nd2
2316  ilength=length2d*nd3
2317  allocate(temp(ilength))
2318 
2319  call this%get_var_nc_char(varname,ilength,temp)
2320 
2321  if(nd1==this%ends(1) .and. nd2==this%ends(2) .and. nd3==this%ends(3)) then
2322  do k=1,nd3
2323  do j=1,nd2
2324  istart=(k-1)*length2d+(j-1)*nd1+1
2325  iend =(k-1)*length2d+(j-1)*nd1+nd1
2326  field(:,j,k)=temp(istart:iend)
2327  enddo
2328  enddo
2329  !
2330  if(this%debug_level>100) then
2331  write(*,*) trim(thissubname),' show samples:'
2332  write(*,*) field(1,1,1)
2333  endif
2334  else
2335  write(*,*) trim(thissubname),' ERROR: dimension does not match.'
2336  write(*,*) nd1,this%ends(1),nd2,this%ends(2),nd3,this%ends(3)
2337  endif
2338  deallocate(temp)
2339  !
2340  end subroutine get_var_nc_char_3d
2341  !
2349  subroutine get_var_nc_char(this,varname,ilength,field)
2350  !
2351  ! read in one field
2352  !
2353  use netcdf
2354  !
2355  implicit none
2356  !
2357  class(ncio) :: this
2358  character(len=*),intent(in) :: varname ! name of the field to read
2359  integer, intent(in) :: ilength ! size of array dval
2360  character, intent(out) :: field(ilength) ! values of the field read in
2361  !
2362  integer :: ncid
2363  !
2364  integer :: status
2365  integer :: varid
2366  integer :: ends(4),start(4)
2367 
2368  integer :: length4d,length3d,length2d
2369  integer :: ndims,ndim
2370  integer :: dimids(4)
2371  integer :: xtype
2372  character*40 :: dimname
2373 
2374  character*40,parameter :: thissubname='get_var_nc_char'
2375  !
2376  integer :: i,k
2377  !
2378  !
2379  ncid=this%ncid
2380 
2381  ! get variable IDs
2382  status = nf90_inq_varid(ncid, trim(varname), varid)
2383  if(status /= nf90_noerr) call this%handle_err(status)
2384 
2385  ! get dimensions
2386  ends=1
2387  start=1
2388  this%ends=1
2389 
2390  this%dimname=" "
2391  ! get variable type
2392  status = nf90_inquire_variable(ncid, varid, xtype = xtype)
2393  if(status /= nf90_noerr) call this%handle_err(status)
2394  if(xtype==nf90_char) then
2395  this%xtype=xtype
2396  else
2397  write(*,*) trim(thissubname),' ERROR: wrong data type, expect ',nf90_char,' but read in ',xtype
2398  stop 123
2399  endif
2400 
2401  ! get dimension size
2402  status = nf90_inquire_variable(ncid, varid, ndims = ndims)
2403  if(status /= nf90_noerr) call this%handle_err(status)
2404  this%ndims=ndims
2405  !
2406  status = nf90_inquire_variable(ncid, varid, dimids = dimids(1:ndims))
2407  if(status /= nf90_noerr) call this%handle_err(status)
2408  do i=1,ndims
2409  dimname=" "
2410  status = nf90_inquire_dimension(ncid, dimids(i), dimname, len = ndim)
2411  if (status /= nf90_noerr) call this%handle_err(status)
2412  ends(i)=ndim
2413  this%ends(i)=ends(i)
2414  this%dimname(i)=trim(dimname)
2415  if(this%ends(i) < 1) then
2416  write(*,*) trim(thissubname),' Error, ends dimension should larger than 0 :', ends(i)
2417  stop 1234
2418  endif
2419  enddo
2420  length2d=ends(1)*ends(2)
2421  length3d=length2d*ends(3)
2422  length4d=length3d*ends(4)
2423  if(ilength .ne. length4d) then
2424  write(*,*) trim(thissubname),'ERROR: ',ilength,' should equal to ',length4d
2425  stop 123
2426  endif
2427  !
2428  if(ndims <=4 ) then
2429  status = nf90_get_var(ncid, varid, field, &
2430  start = start(1:4) , &
2431  count = ends(1:4))
2432  if(status /= nf90_noerr) call this%handle_err(status)
2433  else
2434  write(*,*) trim(thissubname),'Error: too many dimensions:',ndims
2435  stop 1234
2436  endif
2437  !
2438  if(this%debug_level>0) then
2439  write(*,'(a,a)') '>>>read in variable: ',trim(varname)
2440  endif
2441  if(this%debug_level>10) then
2442  write(*,'(8x,a,I10)') 'data type : ',this%xtype
2443  write(*,'(8x,a,I10)') 'dimension size: ',this%nDims
2444  do i=1,this%nDims
2445  write(*,'(8x,a,I5,I10,2x,a)') 'rank, ends, name=',i,this%ends(i),trim(this%dimname(i))
2446  enddo
2447  endif
2448  !
2449  end subroutine get_var_nc_char
2450 
2456  subroutine handle_err(this,status)
2457  use netcdf
2458  implicit none
2459  class(ncio) :: this
2460  !
2461  integer, intent ( in) :: status
2462  if(status /= nf90_noerr) then
2463  print *, trim(nf90_strerror(status))
2464  stop "Stopped"
2465  end if
2466  end subroutine handle_err
2467 
2476  subroutine convert_theta2t_2dgrid(this,nx,ny,ps,t2)
2477  implicit none
2478  class(ncio) :: this
2479 
2480  integer :: nx,ny
2481  real, intent(in ) :: ps(nx,ny)
2482  real, intent(inout) :: t2(nx,ny)
2483 
2484  integer :: i,j
2485  real(8) :: rd,cp,rd_over_cp
2486 
2487 
2488  rd = 2.8705e+2_8
2489  cp = 1.0046e+3_8 ! specific heat of air @pressure (J/kg/K)
2490  rd_over_cp = rd/cp
2491 
2492  do j=1,ny
2493  do i=1,nx
2494  t2(i,j)=t2(i,j)*(ps(i,j)/1000.0)**rd_over_cp - 273.15
2495  enddo
2496  enddo
2497 
2498  end subroutine convert_theta2t_2dgrid
2499 
2512  subroutine add_new_var_3d(this,varname,dname1,dname2,dname3,lname,units)
2513  implicit none
2514  !
2515  class(ncio) :: this
2516  character(len=*),intent(in) :: varname,dname1,dname2,dname3 &
2517  ,lname,units
2518  integer :: status, ncid, dim1id, dim2id, dim3id, varid
2519 
2520  status = nf90_redef(this%ncid) !Enter Define Mode
2521  if (status /= nf90_noerr) call this%handle_err(status)
2522 
2523  status = nf90_inq_dimid(this%ncid, dname1, dim1id)
2524  if (status /= nf90_noerr) call this%handle_err(status)
2525  status = nf90_inq_dimid(this%ncid, dname2, dim2id)
2526  if (status /= nf90_noerr) call this%handle_err(status)
2527  status = nf90_inq_dimid(this%ncid, dname3, dim3id)
2528  if (status /= nf90_noerr) call this%handle_err(status)
2529 
2530  status = nf90_def_var(this%ncid, varname, nf90_double, &
2531  (/ dim1id, dim2id, dim3id /), varid)
2532  if (status /= nf90_noerr) call this%handle_err(status)
2533 
2534  status = nf90_put_att(this%ncid, varid, 'long_name', lname)
2535  if (status /= nf90_noerr) call this%handle_err(status)
2536  status = nf90_put_att(this%ncid, varid, 'units', units)
2537  if (status /= nf90_noerr) call this%handle_err(status)
2538 
2539  status = nf90_enddef(this%ncid) !Exit Define Mode and
2540  ! return to Data Mode
2541  if (status /= nf90_noerr) call this%handle_err(status)
2542 
2543  end subroutine add_new_var_3d
2544 
2545 end module module_ncio
procedure get_var_nc_int
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:46
procedure get_var_nc_short_1d
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:44
procedure replace_var_nc_real
Replace 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:74
procedure get_var_nc_int_1d
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:47
generic get_var=> get_var_nc_double_1d, get_var_nc_double_2d,get_var_nc_double_3d,get_var_nc_real_1d, get_var_nc_real_2d,get_var_nc_real_3d,get_var_nc_short_1d, get_var_nc_short_2d,get_var_nc_int_1d, get_var_nc_int_2d,get_var_nc_int_3d,get_var_nc_char_1d, get_var_nc_char_2d,get_var_nc_char_3d
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:34
procedure replace_var_nc_int_2d
Replace 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:72
procedure get_var_nc_int_3d
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:49
procedure replace_var_nc_double_3d
Replace 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:81
procedure get_att_nc_real
Get attribute.
Definition: module_ncio.f90:32
subroutine open_nc(this, filename, action, debug_level)
Open a netcdf file, set initial debug level.
generic get_att=> get_att_nc_int, get_att_nc_real, get_att_nc_string
Get attribute.
Definition: module_ncio.f90:30
procedure add_new_var=> add_new_var_3d
Add a new 3d variable to output file.
Definition: module_ncio.f90:88
subroutine close_nc(this)
Close a netcdf file.
procedure replace_var_nc_char_1d
Replace character type variable.
Definition: module_ncio.f90:83
procedure get_var_nc_double_2d
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:56
procedure get_var_nc_real_1d
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:51
procedure get_var_nc_double_1d
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:55
procedure get_var_nc_real_3d
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:53
Functions to read and write netcdf files.
Definition: module_ncio.f90:7
procedure get_var_nc_real
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:50
procedure get_var_nc_short_2d
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:45
subroutine add_new_var_3d(this, varname, dname1, dname2, dname3, lname, units)
Add a new variable to sfc_data.nc with dimensions (Time, yaxis_1, xaxis_1).
procedure replace_var_nc_char
Replace character type variable.
Definition: module_ncio.f90:82
procedure replace_var_nc_real_2d
Replace 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:76
procedure convert_theta2t_2dgrid
Convert theta T (Kelvin) to T (deg C).
Definition: module_ncio.f90:87
procedure replace_var_nc_int_1d
Replace 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:71
procedure get_var_nc_char
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:58
procedure replace_var_nc_real_1d
Replace 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:75
procedure get_var_nc_short
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:43
subroutine get_dim_nc(this, dimname, dimvalue)
Get dimensions in netcdf file.
procedure get_dim=> get_dim_nc
read in dimension from the nc file
Definition: module_ncio.f90:29
procedure replace_var_nc_int
Replace 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:70
procedure handle_err
Handle netCDF errors.
Definition: module_ncio.f90:86
procedure get_var_nc_real_2d
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:52
procedure replace_var_nc_real_3d
Replace 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:77
procedure replace_var_nc_double_1d
Replace 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:79
procedure get_var_nc_double
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:54
procedure replace_var_nc_double
Replace 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:78
procedure replace_var_nc_double_2d
Replace 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:80
procedure replace_var_nc_char_2d
Replace character type variable.
Definition: module_ncio.f90:84
procedure get_att_nc_string
Get attribute.
Definition: module_ncio.f90:33
procedure get_var_nc_int_2d
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:48
procedure get_var_nc_char_1d
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:59
procedure get_var_nc_char_2d
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:60
procedure get_var_nc_char_3d
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:61
procedure get_var_nc_double_3d
Read in a 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:57
procedure replace_var_nc_char_3d
Replace 3D character type variable.
Definition: module_ncio.f90:85
generic replace_var=> replace_var_nc_double_1d, replace_var_nc_double_2d,replace_var_nc_double_3d,replace_var_nc_real_1d, replace_var_nc_real_2d,replace_var_nc_real_3d,replace_var_nc_int_1d, replace_var_nc_int_2d,replace_var_nc_int_3d,replace_var_nc_char_1d, replace_var_nc_char_2d,replace_var_nc_char_3d
Replace 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:62
procedure get_att_nc_int
Get attribute.
Definition: module_ncio.f90:31
procedure replace_var_nc_int_3d
Replace 1d, 2d, 3d, or 4d field from the nc file.
Definition: module_ncio.f90:73