293
293
if ( present(mode) ) exist = .true.
294
294
if ( present(comm) ) then
295
if ( comm >= 0 ) exist = .true.
295
if ( comm >= 0 ) exist = .true.
297
297
if ( present(parallel) ) then
298
if ( parallel ) exist = .false.
298
if ( parallel ) exist = .false.
300
300
if ( .not. exist ) then
301
! Our default is the 64 bit offset files...
302
! The best backwards compatibility format
303
this%mode = IOR(this%mode,NF90_64BIT_OFFSET)
301
! Our default is the 64 bit offset files...
302
! The best backwards compatibility format
303
this%mode = IOR(this%mode,NF90_64BIT_OFFSET)
306
306
if ( present(mode) ) then
309
309
! This will create the correct order
311
311
if ( present(parallel) ) then
312
if ( parallel ) exist = .true.
312
if ( parallel ) exist = .true.
314
314
if ( present(comm) ) then
315
if ( comm >= 0 ) exist = .false.
315
if ( comm >= 0 ) exist = .false.
317
317
if ( exist ) then
318
this%parallel = parallel
319
! The parallel flag is for the sequential parallel access !
320
! This will be reset to a zero mode if a communicator is supplied
321
! In this way we can have "parallel" access for reading purposes...
322
! Check that the mode is not existing in the passed mode
323
this%mode = ior(this%mode, NF90_SHARE)
318
this%parallel = parallel
319
! The parallel flag is for the sequential parallel access !
320
! This will be reset to a zero mode if a communicator is supplied
321
! In this way we can have "parallel" access for reading purposes...
322
! Check that the mode is not existing in the passed mode
323
this%mode = ior(this%mode, NF90_SHARE)
325
325
if ( present(comm) ) then
327
! If the communicator is negative we
328
! must assume that it is not parallel
327
! If the communicator is negative we
328
! must assume that it is not parallel
332
332
! Define whether it should not be clobbered
333
333
inquire(file=""//this,exist=exist)
334
334
if ( present(overwrite) ) then
335
if ( exist .and. .not. overwrite ) then
336
this%mode = ior(this%mode, NF90_NOCLOBBER)
335
if ( exist .and. .not. overwrite ) then
336
this%mode = ior(this%mode, NF90_NOCLOBBER)
339
339
end subroutine ncdf_init
340
340
subroutine ncdf_create(this,filename,mode,overwrite,parallel,comm, &
342
342
type(hNCDF), intent(inout) :: this
343
343
character(len=*), intent(in) :: filename
344
344
integer, optional, intent(in) :: mode
349
349
integer :: file_format
351
351
call ncdf_init(this,name=filename, &
352
mode=mode,parallel=parallel,comm=comm, &
353
overwrite=overwrite, &
354
compress_lvl=compress_lvl)
352
mode=mode,parallel=parallel,comm=comm, &
353
overwrite=overwrite, &
354
compress_lvl=compress_lvl)
355
355
! We need to correct the definition for netCDF-3 files
356
356
inquire(file=this%name, exist=exist)
357
357
if ( present(overwrite) ) then
358
if ( overwrite ) then
358
if ( overwrite ) then
362
362
if ( iand(NF90_NETCDF4,this%mode) == NF90_NETCDF4 ) then
365
365
if ( .not. ncdf_participate(this) ) return
366
366
if ( exist ) then
367
call ncdf_die("File: "//this//" already exists! "//&
368
"Please delete the file (or request overwriting).")
367
call ncdf_die("File: "//this//" already exists! "//&
368
"Please delete the file (or request overwriting).")
370
370
if ( this%parallel .and. this%comm >= 0 ) then
371
call ncdf_err(-100,"Not compiled with communicater parallel")
371
call ncdf_err(-100,"Not compiled with communicater parallel")
372
372
else if ( this%parallel ) then
373
call ncdf_err(nf90_create(filename, this%mode , this%f_id), &
374
"Creating file: "//this//" in parallel")
373
call ncdf_err(nf90_create(filename, this%mode , this%f_id), &
374
"Creating file: "//this//" in parallel")
376
call ncdf_err(nf90_create(filename, this%mode , this%f_id), &
377
"Creating file: "//this)
376
call ncdf_err(nf90_create(filename, this%mode , this%f_id), &
377
"Creating file: "//this)
379
379
! We could check for mode == NF90_SHARE in case of parallel...
380
380
! However, it does not make sense as the other is still correct, just slow
393
393
! Save the general information which should be accesible to all processors
394
394
call ncdf_init(this,name=filename,mode=mode, &
395
parallel=parallel,comm=comm, &
396
compress_lvl=compress_lvl)
395
parallel=parallel,comm=comm, &
396
compress_lvl=compress_lvl)
397
397
! When we open a file, it will always be in data mode...
398
398
if ( iand(NF90_NETCDF4,this%mode) == NF90_NETCDF4 ) then
403
403
if ( .not. ncdf_participate(this) ) return
404
404
inquire(file=filename, exist=exist)
405
405
if ( .not. exist ) then
406
call ncdf_die("File: "//trim(filename)//" does not exist! "//&
407
"Please check your inqueries.")
406
call ncdf_die("File: "//trim(filename)//" does not exist! "//&
407
"Please check your inqueries.")
409
409
! If we have not added a mode it must be for non-writing purposes
410
410
if ( .not. present(mode) ) then
411
this%mode = IOR(this%mode,NF90_NOWRITE)
411
this%mode = IOR(this%mode,NF90_NOWRITE)
413
413
if ( this%parallel .and. this%comm >= 0 ) then
414
call ncdf_err(-100,"Code not compiled with NCDF_PARALLEL")
414
call ncdf_err(-100,"Code not compiled with NCDF_PARALLEL")
415
415
else if ( this%parallel ) then
416
call ncdf_err(nf90_open(filename, this%mode , this%f_id), &
417
"Opening file: "//this//" in parallel")
416
call ncdf_err(nf90_open(filename, this%mode , this%f_id), &
417
"Opening file: "//this//" in parallel")
419
call ncdf_err(nf90_open(filename, this%mode , this%f_id), &
420
"Opening file: "//this)
419
call ncdf_err(nf90_open(filename, this%mode , this%f_id), &
420
"Opening file: "//this)
422
422
! Copy so that we can create inquiry
423
423
this%id = this%f_id
424
424
if ( present(group) ) then
425
this%grp = '/'//trim(group)
426
call ncdf_err(nf90_inq_grp_full_ncid(this%f_id, trim(this%grp), this%id))
425
this%grp = '/'//trim(group)
426
call ncdf_err(nf90_inq_grp_full_ncid(this%f_id, trim(this%grp), this%id))
428
428
end subroutine ncdf_open
429
429
! A specific routine for generating a NetCDF file
449
449
! Create all dimensions
451
451
do while ( .not. (.empty. d) )
453
if ( key(1:3) == 'DIM' ) then
455
! We have a dimension
456
! { DIMname : <size> }
461
call ncdf_def_dim(this,key,d_n)
462
! 3. just nullify the variable, let the user delete
463
! the dictionary, we cannot know whether the
464
! variable is a pointer.
453
if ( key(1:3) == 'DIM' ) then
455
! We have a dimension
456
! { DIMname : <size> }
461
call ncdf_def_dim(this,key,d_n)
462
! 3. just nullify the variable, let the user delete
463
! the dictionary, we cannot know whether the
464
! variable is a pointer.
469
469
! Create all variables
471
471
do while ( .not. (.empty. d) )
473
if ( key(1:3) == 'VAR' ) then
475
!print *,'Creating variable: ',trim(key)
477
! { VARname : <dict> } dict ->
479
! dims : '1st,2nd,3rd', ! Comma-seperated list
480
! type : NF90_INT|NF90_FLOAT|..., ! Integer, or logical for complex
481
! atts : <dict>, ! Dictionary of attributes.
482
! chunks : <array of int>, ! For specifying chunk-sizes
484
call associate(d_var,d)
486
! We have the dictionary of the variable
487
! 0. in case 'name' exists, it must be the name
488
if ( 'name'.in.d_var ) then
489
call associate(v,d_var,'name')
490
if ( which(v) /= 'a1' ) then
491
call ncdf_err(-200, &
492
'Name of variable is not a character variable.')
497
! 1. Get the dimensions
498
if ( 'dims'.nin. d_var ) then
499
call ncdf_err(-200, &
500
'Unable to retrieve the dimension &
501
&key from a variable dictionary. A variable &
502
&MUST be defined with a comma separated dimension.')
504
!print *,'Retrieve dims (1): ',trim(key)
505
call associate(v,d_var,'dims')
506
! The dimensions has to be given in a comma separated list
473
if ( key(1:3) == 'VAR' ) then
475
!print *,'Creating variable: ',trim(key)
477
! { VARname : <dict> } dict ->
479
! dims : '1st,2nd,3rd', ! Comma-seperated list
480
! type : NF90_INT|NF90_FLOAT|..., ! Integer, or logical for complex
481
! atts : <dict>, ! Dictionary of attributes.
482
! chunks : <array of int>, ! For specifying chunk-sizes
484
call associate(d_var,d)
486
! We have the dictionary of the variable
487
! 0. in case 'name' exists, it must be the name
488
if ( 'name'.in.d_var ) then
489
call associate(v,d_var,'name')
507
490
if ( which(v) /= 'a1' ) then
508
call ncdf_err(-200, &
509
'Dimension variable is not a character variable.')
511
! Ensure we have a completely empty character.
512
!print *,'Retrieve dims (2): ',trim(key)
515
! Count number of dimensions
517
do i = 1 , len_trim(key)
518
if ( key(i:i) == ',' ) then
523
! Copy over the dimensions
526
do i = 2 , len_trim(key)
527
if ( key(i:i) == ',' ) then
529
dims(n_d) = trim(adjustl(key(j:i-1)))
534
! Grab the last dimension
535
dims(n_d) = trim(adjustl(key(j:)))
536
! Figure out the type
537
if ( 'type' .nin. d_var ) then
538
call ncdf_err(-200, &
539
'Unable to retrieve the type &
540
&key from a variable dictionary. A variable &
541
&MUST have a clear type.')
543
!print *,'Retrieve type: ',trim(key)
544
call associate(v,d_var,'type')
546
if ( trim(char) /= 'b0' .and. &
547
trim(char) /= 'i0' ) then
548
call ncdf_err(-200, &
549
'Type of variable is not defined with a &
550
&proper variable designator.')
552
if ( trim(char) == 'i0' ) then
557
! Check if there are any attributes in the dictionary
558
if ( 'atts' .in. d_var ) then
559
call associate(atts,d_var,'atts')
561
! We have now gathered all information.
562
! Lets create that variable, alrighty! :)
563
if ( trim(char) == 'i0' ) then
564
call ncdf_def_var(this,name,itype, &
567
call ncdf_def_var(this,name,ltype, &
574
else if ( key(1:5) == 'GROUP' ) then
575
name = key(6:) ! default name
576
if ( 'name' .in. d_var ) then
577
call associate(v,d_var,'name')
581
call ncdf_def_grp(this,name,grp)
582
call associate(d_var,d)
583
call ncdf_crt(grp,d_var)
491
call ncdf_err(-200, &
492
'Name of variable is not a character variable.')
497
! 1. Get the dimensions
498
if ( 'dims'.nin. d_var ) then
499
call ncdf_err(-200, &
500
'Unable to retrieve the dimension &
501
&key from a variable dictionary. A variable &
502
&MUST be defined with a comma separated dimension.')
504
!print *,'Retrieve dims (1): ',trim(key)
505
call associate(v,d_var,'dims')
506
! The dimensions has to be given in a comma separated list
507
if ( which(v) /= 'a1' ) then
508
call ncdf_err(-200, &
509
'Dimension variable is not a character variable.')
511
! Ensure we have a completely empty character.
512
!print *,'Retrieve dims (2): ',trim(key)
515
! Count number of dimensions
517
do i = 1 , len_trim(key)
518
if ( key(i:i) == ',' ) then
523
! Copy over the dimensions
526
do i = 2 , len_trim(key)
527
if ( key(i:i) == ',' ) then
529
dims(n_d) = trim(adjustl(key(j:i-1)))
534
! Grab the last dimension
535
dims(n_d) = trim(adjustl(key(j:)))
536
! Figure out the type
537
if ( 'type' .nin. d_var ) then
538
call ncdf_err(-200, &
539
'Unable to retrieve the type &
540
&key from a variable dictionary. A variable &
541
&MUST have a clear type.')
543
!print *,'Retrieve type: ',trim(key)
544
call associate(v,d_var,'type')
546
if ( trim(char) /= 'b0' .and. &
547
trim(char) /= 'i0' ) then
548
call ncdf_err(-200, &
549
'Type of variable is not defined with a &
550
&proper variable designator.')
552
if ( trim(char) == 'i0' ) then
557
! Check if there are any attributes in the dictionary
558
if ( 'atts' .in. d_var ) then
559
call associate(atts,d_var,'atts')
561
! We have now gathered all information.
562
! Lets create that variable, alrighty! :)
563
if ( trim(char) == 'i0' ) then
564
call ncdf_def_var(this,name,itype, &
567
call ncdf_def_var(this,name,ltype, &
574
else if ( key(1:5) == 'GROUP' ) then
575
name = key(6:) ! default name
576
if ( 'name' .in. d_var ) then
577
call associate(v,d_var,'name')
581
call ncdf_def_grp(this,name,grp)
582
call associate(d_var,d)
583
call ncdf_crt(grp,d_var)
588
588
end subroutine ncdf_crt
589
589
! Handy routine for completely deleting a
642
642
if ( .not. ncdf_participate(this) ) return
643
643
! A file-check has been requested...
644
644
if ( present(exist) ) then
645
inquire(file=this%name,exist=exist)
646
! if it does not exist we simply return
647
! this ensures that the user can request all the information
649
if ( .not. exist ) then
645
inquire(file=this%name,exist=exist)
646
! if it does not exist we simply return
647
! this ensures that the user can request all the information
649
if ( .not. exist ) then
653
653
call ncdf_err(nf90_inquire(this%id,ldims,lvars,latts,formatNum=lformat), &
654
"Inquiring file information "//this)
654
"Inquiring file information "//this)
655
655
! Copy over requested information...
656
656
if ( present(dims) ) dims = ldims
657
657
if ( present(vars) ) vars = lvars
658
658
if ( present(atts) ) atts = latts
659
659
if ( present(format) ) format = lformat
660
660
if ( present(dict_dim) ) then
661
call delete(dict_dim)
663
call ncdf_err(nf90_inquire_dimension(this%id,i,name=key))
664
call ncdf_inq_dim(this,key,len=val)
665
dict_dim = dict_dim // (trim(key).kv.val)
661
call delete(dict_dim)
663
call ncdf_err(nf90_inquire_dimension(this%id,i,name=key))
664
call ncdf_inq_dim(this,key,len=val)
665
dict_dim = dict_dim // (trim(key).kv.val)
668
668
if ( present(dict_att) ) then
669
call delete(dict_att)
670
call get_atts_id(this,NF90_GLOBAL,dict_att)
669
call delete(dict_att)
670
call get_atts_id(this,NF90_GLOBAL,dict_att)
672
672
if ( present(grps) ) then
673
if ( IAND(this%mode,NF90_NETCDF4) == NF90_NETCDF4 ) then
673
if ( IAND(this%mode,NF90_NETCDF4) == NF90_NETCDF4 ) then
675
call ncdf_err(nf90_inq_grps(this%id,grps,grp_id), &
676
"Inquiring file information "//this)
677
if ( grps > size(grp_id) ) then
679
allocate(grp_id(grps))
675
680
call ncdf_err(nf90_inq_grps(this%id,grps,grp_id), &
676
"Inquiring file information "//this)
677
if ( grps > size(grp_id) ) then
679
allocate(grp_id(grps))
680
call ncdf_err(nf90_inq_grps(this%id,grps,grp_id), &
681
"Inquiring file information "//this)
681
"Inquiring file information "//this)
688
688
end subroutine ncdf_inq_ncdf
689
689
subroutine ncdf_inq_name(name,dims,vars,atts,format,grps,exist, &
692
692
character(len=*), intent(in) :: name
693
693
integer, optional, intent(out) :: dims, vars, atts, format, grps
725
725
type(hNCDF) :: grp
726
726
if ( .not. ncdf_participate(this) ) return
727
727
if ( present(exist) ) then
728
i = nf90_inq_grp_ncid(this%id,group,val)
729
if ( i == NF90_NOERR ) then
731
else if ( i == NF90_ENOGRP ) then
735
'Inquiring group information'//this)
738
! We can fetch the other information
739
call ncdf_open_grp(this,group,grp)
740
call ncdf_inq(grp,dims=dims,vars=vars,atts=atts,format=format, &
741
grps=grps,dict_dim=dict_dim,dict_att=dict_att)
728
i = nf90_inq_grp_ncid(this%id,group,val)
729
if ( i == NF90_NOERR ) then
731
else if ( i == NF90_ENOGRP ) then
735
'Inquiring group information'//this)
738
! We can fetch the other information
739
call ncdf_open_grp(this,group,grp)
740
call ncdf_inq(grp,dims=dims,vars=vars,atts=atts,format=format, &
741
grps=grps,dict_dim=dict_dim,dict_att=dict_att)
745
745
call ncdf_open_grp(this,group,grp)
746
746
call ncdf_inq(grp,dims=dims,vars=vars,atts=atts,format=format, &
747
grps=grps,dict_dim=dict_dim,dict_att=dict_att)
747
grps=grps,dict_dim=dict_dim,dict_att=dict_att)
748
748
end subroutine ncdf_inq_grp
749
749
! Routine to assert that a NetCDF file has
750
750
! certain dimensions, attributes, and variables.
788
788
if ( .not. ncdf_participate(this) ) return
789
789
if ( present(dims) ) then
790
! We check the dimensions of the file
792
do while ( .not. (.empty. dic) )
794
! Check that the dimension exists
795
call ncdf_inq_dim(this,key,exist=assert)
796
if ( .not. assert ) exit
797
! Get the value in the dictionary
790
! We check the dimensions of the file
792
do while ( .not. (.empty. dic) )
794
! Check that the dimension exists
795
call ncdf_inq_dim(this,key,exist=assert)
796
if ( .not. assert ) exit
797
! Get the value in the dictionary
799
call assign(i0,ivar,success=success)
800
if ( .not. success ) then
801
! Error in type of dictionary...
802
call ncdf_err(-100, &
803
'Request of dimension in ncdf_assert &
804
&went wrong, the dimension is not an integer.')
807
! Now find the dimension size
808
call ncdf_inq_dim(this,key,len=i)
809
! Now we can actually check it...
811
if ( .not. assert ) exit
814
! Clean up... (the variable allocates the "enc")
816
if ( .not. assert ) return
818
if ( present(vars) ) then
819
! We retrieve the epsilon for check
821
if ( present(s_EPS) ) ls_EPS = s_EPS
823
if ( present(d_EPS) ) ld_EPS = d_EPS
824
! We check the dimensions of the file
826
do while ( .not. (.empty. dic) )
828
! Check that the variable exists
829
call ncdf_inq_var(this,key,exist=assert)
830
if ( .not. assert ) exit
831
! Get the value in the dictionary
799
836
call assign(i0,ivar,success=success)
800
if ( .not. success ) then
801
! Error in type of dictionary...
802
call ncdf_err(-100, &
803
'Request of dimension in ncdf_assert &
804
&went wrong, the dimension is not an integer.')
807
! Now find the dimension size
808
call ncdf_inq_dim(this,key,len=i)
809
! Now we can actually check it...
838
call associate(i1,ivar,success=success)
840
call associate(i2,ivar,success=success)
842
call associate(s1,ivar,success=success)
844
call associate(s2,ivar,success=success)
846
call associate(d1,ivar,success=success)
848
call associate(d2,ivar,success=success)
852
if ( .not. success ) then
853
! Error in type of dictionary...
854
call ncdf_err(-100, &
855
'Request of variable in input vars in ncdf_assert &
856
&went wrong, the variable is not [i0,i1,i2,s1,s2,d1,d2].')
858
! Do not deallocate the dictionary stuff
860
! Now grab the first elements of the variable
861
! First we need to allocate the read in data
865
call ncdf_get_var(this,key,i)
810
866
assert = ( i == i0 )
811
if ( .not. assert ) exit
814
! Clean up... (the variable allocates the "enc")
816
if ( .not. assert ) return
818
if ( present(vars) ) then
819
! We retrieve the epsilon for check
821
if ( present(s_EPS) ) ls_EPS = s_EPS
823
if ( present(d_EPS) ) ld_EPS = d_EPS
824
! We check the dimensions of the file
826
do while ( .not. (.empty. dic) )
828
! Check that the variable exists
829
call ncdf_inq_var(this,key,exist=assert)
830
if ( .not. assert ) exit
831
! Get the value in the dictionary
836
call assign(i0,ivar,success=success)
838
call associate(i1,ivar,success=success)
840
call associate(i2,ivar,success=success)
842
call associate(s1,ivar,success=success)
844
call associate(s2,ivar,success=success)
846
call associate(d1,ivar,success=success)
848
call associate(d2,ivar,success=success)
852
if ( .not. success ) then
853
! Error in type of dictionary...
854
call ncdf_err(-100, &
855
'Request of variable in input vars in ncdf_assert &
856
&went wrong, the variable is not [i0,i1,i2,s1,s2,d1,d2].')
858
! Do not deallocate the dictionary stuff
860
! Now grab the first elements of the variable
861
! First we need to allocate the read in data
865
call ncdf_get_var(this,key,i)
868
allocate(i1a(size(i1)))
869
call ncdf_get_var(this,key,i1a)
870
assert = all( i1 == i1a )
873
allocate(i2a(size(i2,dim=1),size(i2,dim=2)))
874
call ncdf_get_var(this,key,i2a)
875
assert = all( i2 == i2a )
878
allocate(s1a(size(s1)))
879
call ncdf_get_var(this,key,s1a)
880
assert = all( abs(s1 - s1a) <= ls_EPS )
883
allocate(s2a(size(s2,dim=1),size(s2,dim=2)))
884
call ncdf_get_var(this,key,s2a)
885
assert = all( abs(s2 - s2a) <= ls_EPS )
888
allocate(d1a(size(d1)))
889
call ncdf_get_var(this,key,d1a)
890
assert = all( abs(d1 - d1a) <= ld_EPS )
893
allocate(d2a(size(d2,dim=1),size(d2,dim=2)))
894
call ncdf_get_var(this,key,d2a)
895
assert = all( abs(d2 - d2a) <= ld_EPS )
899
if ( .not. assert ) exit
904
if ( .not. assert ) return
868
allocate(i1a(size(i1)))
869
call ncdf_get_var(this,key,i1a)
870
assert = all( i1 == i1a )
873
allocate(i2a(size(i2,dim=1),size(i2,dim=2)))
874
call ncdf_get_var(this,key,i2a)
875
assert = all( i2 == i2a )
878
allocate(s1a(size(s1)))
879
call ncdf_get_var(this,key,s1a)
880
assert = all( abs(s1 - s1a) <= ls_EPS )
883
allocate(s2a(size(s2,dim=1),size(s2,dim=2)))
884
call ncdf_get_var(this,key,s2a)
885
assert = all( abs(s2 - s2a) <= ls_EPS )
888
allocate(d1a(size(d1)))
889
call ncdf_get_var(this,key,d1a)
890
assert = all( abs(d1 - d1a) <= ld_EPS )
893
allocate(d2a(size(d2,dim=1),size(d2,dim=2)))
894
call ncdf_get_var(this,key,d2a)
895
assert = all( abs(d2 - d2a) <= ld_EPS )
899
if ( .not. assert ) exit
904
if ( .not. assert ) return
906
906
if ( present(has_dims) ) then
907
! We check the dimensions of the file
908
dic = .first. has_dims
909
do while ( .not. (.empty. dic) )
911
call ncdf_inq_dim(this,key,exist=assert)
912
if ( .not. assert ) return
907
! We check the dimensions of the file
908
dic = .first. has_dims
909
do while ( .not. (.empty. dic) )
911
call ncdf_inq_dim(this,key,exist=assert)
912
if ( .not. assert ) return
916
916
if ( present(has_vars) ) then
917
dic = .first. has_vars
918
do while ( .not. (.empty. dic) )
920
call ncdf_inq_var(this,key,exist=assert)
921
if ( .not. assert ) return
917
dic = .first. has_vars
918
do while ( .not. (.empty. dic) )
920
call ncdf_inq_var(this,key,exist=assert)
921
if ( .not. assert ) return
925
925
end subroutine ncdf_assert
926
! Simplify the addition of any dimension
926
! Simplify the addition of any dimension
927
927
subroutine ncdf_def_dim(this,name,size)
928
928
type(hNCDF), intent(inout) :: this
929
929
character(len=*), intent(in) :: name
999
999
integer :: iret, i, ldims(size(dims))
1000
1000
call ncdf_redef(this)
1001
1001
do i = 1 , size(dims)
1002
call ncdf_inq_dim(this,trim(dims(i)),id=ldims(i))
1002
call ncdf_inq_dim(this,trim(dims(i)),id=ldims(i))
1004
! Determine whether we have NetCDF 4 enabled, in that case do compression if asked for
1004
! Determine whether we have NetCDF 4 enabled, in that case do compression if asked for
1005
1005
! In case of NetCDF 3
1006
1006
iret = nf90_def_var(this%id, name, type, ldims, id)
1007
1007
call ncdf_err(iret,"Defining variable: "//trim(name)//" in file: "//this)
1008
1008
if ( present(atts) ) then
1009
call put_atts_id(this,id,atts)
1009
call put_atts_id(this,id,atts)
1011
1011
if ( present(access) ) then
1012
call ncdf_par_access(this,name=name,access=access)
1012
call ncdf_par_access(this,name=name,access=access)
1014
1014
end subroutine ncdf_def_var_generic
1015
1015
subroutine ncdf_def_var_integer(this, name, type, dims, &
1016
atts, compress_lvl, shuffle, fill, &
1016
atts, compress_lvl, shuffle, fill, &
1019
1019
type(hNCDF), intent(inout) :: this
1020
1020
character(len=*), intent(in) :: name
1026
1026
integer, intent(in), optional :: access, chunks(:)
1028
1028
if ( .not. ncdf_participate(this) ) then
1029
! in case the attributes are present, we
1030
! still need to clean-up if asked
1031
if ( present(atts) ) then
1032
if ( 'ATT_DELETE' .in. atts ) then
1029
! in case the attributes are present, we
1030
! still need to clean-up if asked
1031
if ( present(atts) ) then
1032
if ( 'ATT_DELETE' .in. atts ) then
1038
1038
call ncdf_def_var_generic(this, name, type, dims, id, &
1039
atts=atts, compress_lvl=compress_lvl, shuffle=shuffle, &
1040
access=access, chunks=chunks)
1039
atts=atts, compress_lvl=compress_lvl, shuffle=shuffle, &
1040
access=access, chunks=chunks)
1041
1041
if ( present(fill) ) then
1043
call ncdf_err(nf90_def_var_fill(this%id,id, 1, 0), &
1044
"Setting the variable "//trim(name)//" to NOFILL in file "//this)
1046
call ncdf_err(nf90_def_var_fill(this%id,id, 0, 0), &
1047
"Setting the variable "//trim(name)//" to FILL in file "//this)
1043
call ncdf_err(nf90_def_var_fill(this%id,id, 1, 0), &
1044
"Setting the variable "//trim(name)//" to NOFILL in file "//this)
1046
call ncdf_err(nf90_def_var_fill(this%id,id, 0, 0), &
1047
"Setting the variable "//trim(name)//" to FILL in file "//this)
1050
1050
end subroutine ncdf_def_var_integer
1051
1051
subroutine ncdf_def_var_logical(this, name, type, dims, &
1052
atts, compress_lvl, shuffle, fill, &
1052
atts, compress_lvl, shuffle, fill, &
1055
1055
type(hNCDF), intent(inout) :: this
1056
1056
character(len=*), intent(in) :: name
1064
1064
integer :: ltype
1065
1065
if ( .not. ncdf_participate(this) ) then
1066
! in case the attributes are present, we
1067
! still need to clean-up if asked
1068
if ( present(atts) ) then
1069
if ( 'ATT_DELETE' .in. atts ) then
1075
if ( type .eqv. NF90_DOUBLE_COMPLEX ) then
1080
if ( type .eqv. NF90_DOUBLE_COMPLEX ) then
1066
! in case the attributes are present, we
1067
! still need to clean-up if asked
1068
if ( present(atts) ) then
1069
if ( 'ATT_DELETE' .in. atts ) then
1075
if ( type .eqv. NF90_DOUBLE_COMPLEX ) then
1080
if ( type .eqv. NF90_DOUBLE_COMPLEX ) then
1085
1085
call ncdf_def_var_generic(this, "Re"//trim(name), ltype, dims, id, &
1086
atts=atts, compress_lvl=compress_lvl, shuffle=shuffle, &
1087
access=access, chunks=chunks)
1086
atts=atts, compress_lvl=compress_lvl, shuffle=shuffle, &
1087
access=access, chunks=chunks)
1088
1088
if ( present(fill) ) then
1090
call ncdf_err(nf90_def_var_fill(this%id,id, 1, 0), &
1091
"Setting the variable "//trim(name)//" to NOFILL in file "//this)
1093
call ncdf_err(nf90_def_var_fill(this%id,id, 0, 0), &
1094
"Setting the variable "//trim(name)//" to FILL in file "//this)
1090
call ncdf_err(nf90_def_var_fill(this%id,id, 1, 0), &
1091
"Setting the variable "//trim(name)//" to NOFILL in file "//this)
1093
call ncdf_err(nf90_def_var_fill(this%id,id, 0, 0), &
1094
"Setting the variable "//trim(name)//" to FILL in file "//this)
1097
1097
call ncdf_def_var_generic(this, "Im"//trim(name), ltype, dims, id, &
1098
atts=atts, compress_lvl=compress_lvl, shuffle=shuffle, &
1099
access=access, chunks=chunks)
1098
atts=atts, compress_lvl=compress_lvl, shuffle=shuffle, &
1099
access=access, chunks=chunks)
1100
1100
if ( present(fill) ) then
1102
call ncdf_err(nf90_def_var_fill(this%id,id, 1, 0), &
1103
"Setting the variable "//trim(name)//" to NOFILL in file "//this)
1105
call ncdf_err(nf90_def_var_fill(this%id,id, 0, 0), &
1106
"Setting the variable "//trim(name)//" to FILL in file "//this)
1102
call ncdf_err(nf90_def_var_fill(this%id,id, 1, 0), &
1103
"Setting the variable "//trim(name)//" to NOFILL in file "//this)
1105
call ncdf_err(nf90_def_var_fill(this%id,id, 0, 0), &
1106
"Setting the variable "//trim(name)//" to FILL in file "//this)
1109
1109
end subroutine ncdf_def_var_logical
1110
1110
subroutine ncdf_default(this,access,compress_lvl)
1132
1132
! The variable must exist
1133
1133
lexist = iret == NF90_NOERR
1134
1134
if ( present(exist) ) then
1136
1136
else if ( .not. lexist ) then
1137
call ncdf_err(iret,"Retrieving information about: "//trim(name)//" in file: "//this)
1137
call ncdf_err(iret,"Retrieving information about: "//trim(name)//" in file: "//this)
1139
1139
! If there is nothing to inquire: return
1140
1140
if ( .not. lexist ) return
1141
1141
if ( present(id) ) id = lid
1142
1142
! If the user has requested information about the size of the variable...
1143
1143
if ( present(size) ) then
1144
call ncdf_err(nf90_inquire_variable(this%id, lid, ndims=nids, dimids=ldids))
1145
do i = 1 , min(nids,ubound(size,1))
1146
call ncdf_err(nf90_inquire_dimension(this%id,ldids(i),name=dim), &
1147
"Retrieving dimension name in inq_var for file: "//this)
1148
! Save the dimension size in array "size"
1149
call ncdf_inq_dim(this,trim(dim),len=size(i))
1144
call ncdf_err(nf90_inquire_variable(this%id, lid, ndims=nids, dimids=ldids))
1145
do i = 1 , min(nids,ubound(size,1))
1146
call ncdf_err(nf90_inquire_dimension(this%id,ldids(i),name=dim), &
1147
"Retrieving dimension name in inq_var for file: "//this)
1148
! Save the dimension size in array "size"
1149
call ncdf_inq_dim(this,trim(dim),len=size(i))
1152
1152
! The user has requested information about the attributes associated...
1153
1153
if ( present(atts) ) then
1154
call get_atts_id(this,lid,atts=atts)
1154
call get_atts_id(this,lid,atts=atts)
1156
1156
end subroutine ncdf_inq_var_def
1157
1157
subroutine ncdf_inq_dim(this,name,exist,id,len)
1340
1340
call ncdf_redef(this)
1341
1341
select case ( which(att) )
1342
1342
case ( 'a1' ) ! character array
1343
call assign(tmp,att)
1344
iret = nf90_put_att(this%id, id, trim(name), tmp)
1343
call assign(tmp,att)
1344
iret = nf90_put_att(this%id, id, trim(name), tmp)
1346
call associate(h0,att)
1347
iret = nf90_put_att(this%id, id, trim(name), h0)
1346
call associate(h0,att)
1347
iret = nf90_put_att(this%id, id, trim(name), h0)
1349
call associate(h1,att)
1350
iret = nf90_put_att(this%id, id, trim(name), h1)
1349
call associate(h1,att)
1350
iret = nf90_put_att(this%id, id, trim(name), h1)
1352
call associate(i0,att)
1353
iret = nf90_put_att(this%id, id, trim(name), i0)
1352
call associate(i0,att)
1353
iret = nf90_put_att(this%id, id, trim(name), i0)
1355
call associate(i1,att)
1356
iret = nf90_put_att(this%id, id, trim(name), i1)
1355
call associate(i1,att)
1356
iret = nf90_put_att(this%id, id, trim(name), i1)
1358
call associate(s0,att)
1359
iret = nf90_put_att(this%id, id, trim(name), s0)
1358
call associate(s0,att)
1359
iret = nf90_put_att(this%id, id, trim(name), s0)
1361
call associate(s1,att)
1362
iret = nf90_put_att(this%id, id, trim(name), s1)
1361
call associate(s1,att)
1362
iret = nf90_put_att(this%id, id, trim(name), s1)
1364
call associate(d0,att)
1365
iret = nf90_put_att(this%id, id, trim(name), d0)
1364
call associate(d0,att)
1365
iret = nf90_put_att(this%id, id, trim(name), d0)
1367
call associate(d1,att)
1368
iret = nf90_put_att(this%id, id, trim(name), d1)
1367
call associate(d1,att)
1368
iret = nf90_put_att(this%id, id, trim(name), d1)
1372
1372
call ncdf_err(iret, &
1373
"Saving attribute: "//trim(name)// &
1373
"Saving attribute: "//trim(name)// &
1375
1375
end subroutine put_att_id
1376
1376
subroutine get_atts_id(this,id,atts)
1406
1406
character(len=*), intent(in) :: name
1407
1407
type(var), intent(inout) :: att
1408
1408
integer :: xtype, att_len
1409
character(len=500) :: att_char
1409
character(len=512) :: att_char
1410
1410
real(sp), allocatable :: a_sp(:)
1411
1411
real(dp), allocatable :: a_dp(:)
1412
1412
integer(ih), allocatable :: a_ih(:)
1413
1413
integer(is), allocatable :: a_is(:)
1414
1414
! retrieve the attribute length and data-type
1415
1415
call ncdf_err(nf90_inquire_attribute(this%id,id,trim(name), &
1416
xtype=xtype,len=att_len),'Retriving inquire_attribute: '//this)
1416
xtype=xtype,len=att_len),'Retriving inquire_attribute: '//this)
1417
1417
select case ( xtype )
1418
1418
case ( NF90_CHAR )
1420
call ncdf_err(nf90_get_att(this%id, id, trim(name), att_char), &
1421
"Retrieving the attribute value for file: "//this)
1422
call assign(att,trim(att_char))
1420
call ncdf_err(nf90_get_att(this%id, id, trim(name), att_char), &
1421
"Retrieving the attribute value for file: "//this)
1422
call assign(att,trim(att_char))
1423
1423
case ( NF90_SHORT )
1424
allocate(a_ih(att_len))
1425
call ncdf_err(nf90_get_att(this%id, id, trim(name), a_ih), &
1426
"Retrieving the attribute value for file: "//this)
1427
if ( att_len == 1 ) then
1428
call assign(att,a_ih(1))
1430
call assign(att,a_ih)
1424
allocate(a_ih(att_len))
1425
call ncdf_err(nf90_get_att(this%id, id, trim(name), a_ih), &
1426
"Retrieving the attribute value for file: "//this)
1427
if ( att_len == 1 ) then
1428
call assign(att,a_ih(1))
1430
call assign(att,a_ih)
1433
1433
case ( NF90_INT )
1434
allocate(a_is(att_len))
1435
call ncdf_err(nf90_get_att(this%id, id, trim(name), a_is), &
1436
"Retrieving the attribute value for file: "//this)
1437
if ( att_len == 1 ) then
1438
call assign(att,a_is(1))
1440
call assign(att,a_is)
1434
allocate(a_is(att_len))
1435
call ncdf_err(nf90_get_att(this%id, id, trim(name), a_is), &
1436
"Retrieving the attribute value for file: "//this)
1437
if ( att_len == 1 ) then
1438
call assign(att,a_is(1))
1440
call assign(att,a_is)
1443
1443
case ( NF90_FLOAT )
1444
allocate(a_sp(att_len))
1445
call ncdf_err(nf90_get_att(this%id, id, trim(name), a_sp), &
1446
"Retrieving the attribute value for file: "//this)
1447
if ( att_len == 1 ) then
1448
call assign(att,a_sp(1))
1450
call assign(att,a_sp)
1444
allocate(a_sp(att_len))
1445
call ncdf_err(nf90_get_att(this%id, id, trim(name), a_sp), &
1446
"Retrieving the attribute value for file: "//this)
1447
if ( att_len == 1 ) then
1448
call assign(att,a_sp(1))
1450
call assign(att,a_sp)
1453
1453
case ( NF90_DOUBLE )
1454
allocate(a_dp(att_len))
1455
call ncdf_err(nf90_get_att(this%id, id, trim(name), a_dp), &
1456
"Retrieving the attribute value for file: "//this)
1457
if ( att_len == 1 ) then
1458
call assign(att,a_dp(1))
1460
call assign(att,a_dp)
1454
allocate(a_dp(att_len))
1455
call ncdf_err(nf90_get_att(this%id, id, trim(name), a_dp), &
1456
"Retrieving the attribute value for file: "//this)
1457
if ( att_len == 1 ) then
1458
call assign(att,a_dp(1))
1460
call assign(att,a_dp)
1464
1464
end subroutine get_att_id
1465
1465
! Delete attributes
2180
2180
! if ( present(fill_val) ) then
2181
!fill_val = cmplx(lfill_valr,lfill_valc)
2182
fill_val = cmplx(0.,0.)
2181
!fill_val = cmplx(lfill_valr,lfill_valc, sp)
2182
fill_val = cmplx(0,0, sp)
2184
2184
end subroutine inq_var_c0
2185
2185
subroutine put_var_c1_name(this,name,var,start,count)
2186
2186
type(hNCDF), intent(inout) :: this
2187
2187
character(len=*), intent(in) :: name
2188
complex(sp), intent(in), dimension(:) :: var
2188
complex(sp), intent(in) :: var (:)
2189
2189
integer, intent(in), optional :: start(:)
2190
2190
integer, intent(in), optional :: count(:)
2192
real(sp), allocatable , dimension(:) :: r
2192
real(sp), allocatable :: r (:)
2193
2193
if ( .not. ncdf_participate(this) ) return
2194
2194
if ( this%define > -1 ) call ncdf_enddef(this)
2195
2195
allocate(r(size(var)))
2196
r (:) = real(var, sp)
2197
2197
call ncdf_inq_var(this,'Re'//name,id=id)
2198
2198
call ncdf_err(nf90_put_var(this%id, id, r,start=start,count=count), &
2199
2199
"Saving variable (VAR) Re"//trim(name)//' in file: '//this)
2200
2200
call ncdf_inq_var(this,'Im'//name,id=id)
2202
2202
call ncdf_err(nf90_put_var(this%id, id, r,start=start,count=count), &
2203
2203
'Saving variable (VAR) Im'//trim(name)//' in file: '//this)
2222
2222
call ncdf_inq_var(this,'Im'//name,id=id)
2223
2223
call ncdf_err(nf90_get_var(this%id, id, i,start=start,count=count,stride=stride), &
2224
2224
'Retrieving variable (VAR) Im'//trim(name)//' in file: '//this)
2225
var (:) = cmplx(r,i, sp)
2226
2226
deallocate(r,i)
2227
2227
end subroutine get_var_c1_name
2228
2228
subroutine put_var_c2_name(this,name,var,start,count)
2229
2229
type(hNCDF), intent(inout) :: this
2230
2230
character(len=*), intent(in) :: name
2231
complex(sp), intent(in), dimension(:,:) :: var
2231
complex(sp), intent(in) :: var (:,:)
2232
2232
integer, intent(in), optional :: start(:)
2233
2233
integer, intent(in), optional :: count(:)
2235
real(sp), allocatable , dimension(:,:) :: r
2235
real(sp), allocatable :: r (:,:)
2236
2236
if ( .not. ncdf_participate(this) ) return
2237
2237
if ( this%define > -1 ) call ncdf_enddef(this)
2238
2238
allocate(r(size(var,1),size(var,2)))
2239
r (:,:) = real(var, sp)
2240
2240
call ncdf_inq_var(this,'Re'//name,id=id)
2241
2241
call ncdf_err(nf90_put_var(this%id, id, r,start=start,count=count), &
2242
2242
"Saving variable (VAR) Re"//trim(name)//' in file: '//this)
2243
2243
call ncdf_inq_var(this,'Im'//name,id=id)
2244
r (:,:) = aimag(var)
2245
2245
call ncdf_err(nf90_put_var(this%id, id, r,start=start,count=count), &
2246
2246
'Saving variable (VAR) Im'//trim(name)//' in file: '//this)
2265
2265
call ncdf_inq_var(this,'Im'//name,id=id)
2266
2266
call ncdf_err(nf90_get_var(this%id, id, i,start=start,count=count,stride=stride), &
2267
2267
'Retrieving variable (VAR) Im'//trim(name)//' in file: '//this)
2268
var (:,:) = cmplx(r,i, sp)
2269
2269
deallocate(r,i)
2270
2270
end subroutine get_var_c2_name
2271
2271
subroutine put_var_c3_name(this,name,var,start,count)
2272
2272
type(hNCDF), intent(inout) :: this
2273
2273
character(len=*), intent(in) :: name
2274
complex(sp), intent(in), dimension(:,:,:) :: var
2274
complex(sp), intent(in) :: var (:,:,:)
2275
2275
integer, intent(in), optional :: start(:)
2276
2276
integer, intent(in), optional :: count(:)
2278
real(sp), allocatable , dimension(:,:,:) :: r
2278
real(sp), allocatable :: r (:,:,:)
2279
2279
if ( .not. ncdf_participate(this) ) return
2280
2280
if ( this%define > -1 ) call ncdf_enddef(this)
2281
2281
allocate(r(size(var,1),size(var,2),size(var,3)))
2282
r (:,:,:) = real(var, sp)
2283
2283
call ncdf_inq_var(this,'Re'//name,id=id)
2284
2284
call ncdf_err(nf90_put_var(this%id, id, r,start=start,count=count), &
2285
2285
"Saving variable (VAR) Re"//trim(name)//' in file: '//this)
2286
2286
call ncdf_inq_var(this,'Im'//name,id=id)
2287
r (:,:,:) = aimag(var)
2288
2288
call ncdf_err(nf90_put_var(this%id, id, r,start=start,count=count), &
2289
2289
'Saving variable (VAR) Im'//trim(name)//' in file: '//this)
2389
2389
! if ( present(fill_val) ) then
2390
!fill_val = cmplx(lfill_valr,lfill_valc)
2391
fill_val = cmplx(0.,0.)
2390
!fill_val = cmplx(lfill_valr,lfill_valc, dp)
2391
fill_val = cmplx(0,0, dp)
2393
2393
end subroutine inq_var_z0
2394
2394
subroutine put_var_z1_name(this,name,var,start,count)
2395
2395
type(hNCDF), intent(inout) :: this
2396
2396
character(len=*), intent(in) :: name
2397
complex(dp), intent(in), dimension(:) :: var
2397
complex(dp), intent(in) :: var (:)
2398
2398
integer, intent(in), optional :: start(:)
2399
2399
integer, intent(in), optional :: count(:)
2401
real(dp), allocatable , dimension(:) :: r
2401
real(dp), allocatable :: r (:)
2402
2402
if ( .not. ncdf_participate(this) ) return
2403
2403
if ( this%define > -1 ) call ncdf_enddef(this)
2404
2404
allocate(r(size(var)))
2405
r (:) = real(var, dp)
2406
2406
call ncdf_inq_var(this,'Re'//name,id=id)
2407
2407
call ncdf_err(nf90_put_var(this%id, id, r,start=start,count=count), &
2408
2408
"Saving variable (VAR) Re"//trim(name)//' in file: '//this)
2409
2409
call ncdf_inq_var(this,'Im'//name,id=id)
2411
2411
call ncdf_err(nf90_put_var(this%id, id, r,start=start,count=count), &
2412
2412
'Saving variable (VAR) Im'//trim(name)//' in file: '//this)
2431
2431
call ncdf_inq_var(this,'Im'//name,id=id)
2432
2432
call ncdf_err(nf90_get_var(this%id, id, i,start=start,count=count,stride=stride), &
2433
2433
'Retrieving variable (VAR) Im'//trim(name)//' in file: '//this)
2434
var (:) = cmplx(r,i, dp)
2435
2435
deallocate(r,i)
2436
2436
end subroutine get_var_z1_name
2437
2437
subroutine put_var_z2_name(this,name,var,start,count)
2438
2438
type(hNCDF), intent(inout) :: this
2439
2439
character(len=*), intent(in) :: name
2440
complex(dp), intent(in), dimension(:,:) :: var
2440
complex(dp), intent(in) :: var (:,:)
2441
2441
integer, intent(in), optional :: start(:)
2442
2442
integer, intent(in), optional :: count(:)
2444
real(dp), allocatable , dimension(:,:) :: r
2444
real(dp), allocatable :: r (:,:)
2445
2445
if ( .not. ncdf_participate(this) ) return
2446
2446
if ( this%define > -1 ) call ncdf_enddef(this)
2447
2447
allocate(r(size(var,1),size(var,2)))
2448
r (:,:) = real(var, dp)
2449
2449
call ncdf_inq_var(this,'Re'//name,id=id)
2450
2450
call ncdf_err(nf90_put_var(this%id, id, r,start=start,count=count), &
2451
2451
"Saving variable (VAR) Re"//trim(name)//' in file: '//this)
2452
2452
call ncdf_inq_var(this,'Im'//name,id=id)
2453
r (:,:) = aimag(var)
2454
2454
call ncdf_err(nf90_put_var(this%id, id, r,start=start,count=count), &
2455
2455
'Saving variable (VAR) Im'//trim(name)//' in file: '//this)
2474
2474
call ncdf_inq_var(this,'Im'//name,id=id)
2475
2475
call ncdf_err(nf90_get_var(this%id, id, i,start=start,count=count,stride=stride), &
2476
2476
'Retrieving variable (VAR) Im'//trim(name)//' in file: '//this)
2477
var (:,:) = cmplx(r,i, dp)
2478
2478
deallocate(r,i)
2479
2479
end subroutine get_var_z2_name
2480
2480
subroutine put_var_z3_name(this,name,var,start,count)
2481
2481
type(hNCDF), intent(inout) :: this
2482
2482
character(len=*), intent(in) :: name
2483
complex(dp), intent(in), dimension(:,:,:) :: var
2483
complex(dp), intent(in) :: var (:,:,:)
2484
2484
integer, intent(in), optional :: start(:)
2485
2485
integer, intent(in), optional :: count(:)
2487
real(dp), allocatable , dimension(:,:,:) :: r
2487
real(dp), allocatable :: r (:,:,:)
2488
2488
if ( .not. ncdf_participate(this) ) return
2489
2489
if ( this%define > -1 ) call ncdf_enddef(this)
2490
2490
allocate(r(size(var,1),size(var,2),size(var,3)))
2491
r (:,:,:) = real(var, dp)
2492
2492
call ncdf_inq_var(this,'Re'//name,id=id)
2493
2493
call ncdf_err(nf90_put_var(this%id, id, r,start=start,count=count), &
2494
2494
"Saving variable (VAR) Re"//trim(name)//' in file: '//this)
2495
2495
call ncdf_inq_var(this,'Im'//name,id=id)
2496
r (:,:,:) = aimag(var)
2497
2497
call ncdf_err(nf90_put_var(this%id, id, r,start=start,count=count), &
2498
2498
'Saving variable (VAR) Im'//trim(name)//' in file: '//this)
2798
2798
! reading or writing of the NetCDF handle...
2799
2799
! if ( .not. ncdf_participate() ) return
2800
2800
if (status .ne. nf90_noerr) then
2801
if (present(msg)) write(*,"(a)") trim(msg)
2803
write(*,"(a)") "Error occured in NCDF:"
2804
write(0,"(a)") "Error occured in NCDF:"
2805
select case ( status )
2806
case ( -130 ) ! include/netcdf.h:"define" NC_ECANTEXTEND (-130)
2807
! < Attempt to extend dataset during ind. I/O operation. >!
2808
write(*,"(a)") 'Attempt to extend (UNLIMITED dimension) a parallel file in INDEPENDENT ACCESS mode'
2809
write(0,"(a)") 'Attempt to extend (UNLIMITED dimension) a parallel file in INDEPENDENT ACCESS mode'
2811
write(*,"(a)") trim(nf90_strerror(status))
2812
write(0,"(a)") trim(nf90_strerror(status))
2814
write(*,"(a,tr1,i0)") "Status number:",status
2815
write(0,"(a,tr1,i0)") "Status number:",status
2816
call ncdf_die("Stopped due to error in NetCDF file")
2801
if (present(msg)) write(*,"(a)") trim(msg)
2803
write(*,"(a)") "Error occured in NCDF:"
2804
write(0,"(a)") "Error occured in NCDF:"
2805
select case ( status )
2806
case ( -130 ) ! include/netcdf.h:"define" NC_ECANTEXTEND (-130)
2807
! < Attempt to extend dataset during ind. I/O operation. >!
2808
write(*,"(a)") 'Attempt to extend (UNLIMITED dimension) a parallel file in INDEPENDENT ACCESS mode'
2809
write(0,"(a)") 'Attempt to extend (UNLIMITED dimension) a parallel file in INDEPENDENT ACCESS mode'
2811
write(*,"(a)") trim(nf90_strerror(status))
2812
write(0,"(a)") trim(nf90_strerror(status))
2814
write(*,"(a,tr1,i0)") "Status number:",status
2815
write(0,"(a,tr1,i0)") "Status number:",status
2816
call ncdf_die("Stopped due to error in NetCDF file")
2818
2818
end subroutine ncdf_err
2819
!"#############################################################"
2820
!"#############" Routines for handling the groups"############"
2821
!"#########" of the NetCDF files. We allow this to"##########"
2822
!"#########" always be present due to reduction of"##########"
2823
!"###############" preprocessor flags"#######################"
2824
!"#############################################################"
2819
!"#############################################################"
2820
!"#############" Routines for handling the groups"############"
2821
!"#########" of the NetCDF files. We allow this to"##########"
2822
!"#########" always be present due to reduction of"##########"
2823
!"###############" preprocessor flags"#######################"
2824
!"#############################################################"
2825
2825
! Create groups in a NetCDF4 file
2826
2826
subroutine ncdf_def_grp(this,name,grp)
2827
2827
type(hNCDF), intent(in out) :: this
2893
2893
! This will fail if it is not the 0th Node in the communicator
2894
2894
! For instance a subgroup in the Comm_World...
2895
2895
if ( Node == 0 ) then
2896
write(*,"(a20,a)") "NetCDF filename: ",trim(this%name)
2897
if ( len_trim(this%grp) /= 0 ) then
2898
write(*,"(a20,a)") "NetCDF group name: ",trim(this%grp)
2900
write(*,"(a20,i7)") "NetCDF ID: ",this%id
2901
if ( this%parallel ) then
2902
write(*,"(a20,a)") "Parallel access: ","True"
2903
write(*,"(a20,tr1,i0)") "Parallel processors:",Nodes
2905
write(*,"(a20,a)") "Parallel access: ","False"
2907
if ( this%define == 0 ) then
2908
write(*,"(a20,a)") "In define-mode: ","True"
2909
else if ( this%define == 1 ) then
2910
write(*,"(a20,a)") "In define-mode: ","False"
2912
call ncdf_inq(this, dims=ndims, vars=nvars, atts=ngatts, &
2896
write(*,"(a20,a)") "NetCDF filename: ",trim(this%name)
2897
if ( len_trim(this%grp) /= 0 ) then
2898
write(*,"(a20,a)") "NetCDF group name: ",trim(this%grp)
2900
write(*,"(a20,i7)") "NetCDF ID: ",this%id
2901
if ( this%parallel ) then
2902
write(*,"(a20,a)") "Parallel access: ","True"
2903
write(*,"(a20,tr1,i0)") "Parallel processors:",Nodes
2905
write(*,"(a20,a)") "Parallel access: ","False"
2907
if ( this%define == 0 ) then
2908
write(*,"(a20,a)") "In define-mode: ","True"
2909
else if ( this%define == 1 ) then
2910
write(*,"(a20,a)") "In define-mode: ","False"
2912
if ( this%f_id >= 0 ) then
2913
call ncdf_inq(this, dims=ndims, vars=nvars, atts=ngatts, &
2913
2914
grps=ngrps, format=file_format)
2914
select case ( file_format )
2915
case ( NF90_FORMAT_CLASSIC )
2915
select case ( file_format )
2916
case ( NF90_FORMAT_CLASSIC )
2916
2917
write(*,"(a20,a)") "File format: ","Classic"
2917
case ( NF90_FORMAT_64BIT )
2918
case ( NF90_FORMAT_64BIT )
2918
2919
write(*,"(a20,a)") "File format: ","Classic 64Bit"
2919
case ( NF90_FORMAT_NETCDF4 )
2920
case ( NF90_FORMAT_NETCDF4 )
2920
2921
write(*,"(a20,a)") "File format: ","NetCDF4"
2921
2922
write(*,"(a20,i7)")"Default compression:",this%comp_lvl
2922
case ( NF90_FORMAT_NETCDF4_CLASSIC )
2923
case ( NF90_FORMAT_NETCDF4_CLASSIC )
2923
2924
write(*,"(a20,a)") "File format: ","NetCDF4 Classic format"
2924
2925
write(*,"(a22,i7)")"Default compression: ",this%comp_lvl
2926
2927
write(*,"(a20,a)") "File format: ","Could not be determined"
2928
write(*,"(a20,i7)") "Number of dimensions: ",ndims
2929
write(*,"(a20,i7)") "Number of variables: ",nvars
2930
write(*,"(a20,i7)") "Number of attributes: ",ngatts
2931
if ( ngrps >= 0 ) then
2932
write(*,"(a20,i7)") "Number of groups: ",ngrps
2934
if ( iand(NF90_WRITE,this%mode) == NF90_WRITE ) &
2929
write(*,"(a20,i7)") "Number of dimensions: ",ndims
2930
write(*,"(a20,i7)") "Number of variables: ",nvars
2931
write(*,"(a20,i7)") "Number of attributes: ",ngatts
2932
if ( ngrps >= 0 ) then
2933
write(*,"(a20,i7)") "Number of groups: ",ngrps
2936
if ( iand(NF90_WRITE,this%mode) == NF90_WRITE ) &
2935
2937
write(*,"(a20,a)") "NetCDF mode: ","NF90_WRITE"
2936
if ( iand(NF90_NOCLOBBER,this%mode) == NF90_NOCLOBBER ) then
2938
if ( iand(NF90_NOCLOBBER,this%mode) == NF90_NOCLOBBER ) then
2937
2939
write(*,"(a20,a)") "NetCDF mode: ","NF90_NOCLOBBER"
2939
2941
write(*,"(a20,a)") "NetCDF mode: ","NF90_CLOBBER"
2941
if ( iand(NF90_NOFILL,this%mode) == NF90_NOFILL ) &
2942
write(*,"(a20,a)") "NetCDF mode: ","NF90_NOFILL"
2943
if ( iand(NF90_64BIT_OFFSET,this%mode) == NF90_64BIT_OFFSET ) &
2944
write(*,"(a20,a)") "NetCDF mode: ","NF90_64BIT_OFFSET"
2945
if ( iand(NF90_LOCK,this%mode) == NF90_LOCK ) &
2946
write(*,"(a20,a)") "NetCDF mode: ","NF90_LOCK"
2947
if ( iand(NF90_SHARE,this%mode) == NF90_SHARE ) &
2948
write(*,"(a20,a)") "NetCDF mode: ","NF90_SHARE"
2949
if ( iand(NF90_NETCDF4,this%mode) == NF90_NETCDF4 ) &
2950
write(*,"(a20,a)") "NetCDF mode: ","NF90_NETCDF4"
2951
if ( iand(NF90_CLASSIC_MODEL,this%mode) == NF90_CLASSIC_MODEL ) &
2952
write(*,"(a20,a)") "NetCDF mode: ","NF90_CLASSIC_MODEL"
2943
if ( iand(NF90_NOFILL,this%mode) == NF90_NOFILL ) &
2944
write(*,"(a20,a)") "NetCDF mode: ","NF90_NOFILL"
2945
if ( iand(NF90_64BIT_OFFSET,this%mode) == NF90_64BIT_OFFSET ) &
2946
write(*,"(a20,a)") "NetCDF mode: ","NF90_64BIT_OFFSET"
2947
if ( iand(NF90_LOCK,this%mode) == NF90_LOCK ) &
2948
write(*,"(a20,a)") "NetCDF mode: ","NF90_LOCK"
2949
if ( iand(NF90_SHARE,this%mode) == NF90_SHARE ) &
2950
write(*,"(a20,a)") "NetCDF mode: ","NF90_SHARE"
2951
if ( iand(NF90_NETCDF4,this%mode) == NF90_NETCDF4 ) &
2952
write(*,"(a20,a)") "NetCDF mode: ","NF90_NETCDF4"
2953
if ( iand(NF90_CLASSIC_MODEL,this%mode) == NF90_CLASSIC_MODEL ) &
2954
write(*,"(a20,a)") "NetCDF mode: ","NF90_CLASSIC_MODEL"
2954
2956
end subroutine ncdf_print
2955
! A standard die routine... It is not pretty... But it works...
2956
! Recommended to be adapted!
2957
! A standard die routine... It is not pretty... But it works...
2958
! Recommended to be adapted!
2957
2959
subroutine ncdf_die(str)
2958
2960
character(len=*), intent(in) :: str
2959
2961
write(0,"(2a)") 'ncdf: ',trim(str)