73 character (len=255),
parameter:: subcategory=
"volgrid6d_class" 77 type(griddim_def) :: griddim
78 TYPE(datetime),
pointer :: time(:)
79 TYPE(vol7d_timerange),
pointer :: timerange(:)
80 TYPE(vol7d_level),
pointer :: level(:)
81 TYPE(volgrid6d_var),
pointer :: var(:)
82 TYPE(grid_id),
POINTER :: gaid(:,:,:,:)
83 REAL,
POINTER :: voldati(:,:,:,:,:,:)
84 INTEGER :: time_definition
85 TYPE(l4f_handle) :: category
90 MODULE PROCEDURE volgrid6d_init
96 MODULE PROCEDURE volgrid6d_delete, volgrid6dv_delete
102 MODULE PROCEDURE volgrid6d_read_from_file
103 MODULE PROCEDURE import_from_gridinfo, import_from_gridinfovv, &
104 volgrid6d_import_from_file
110 MODULE PROCEDURE volgrid6d_write_on_file
111 MODULE PROCEDURE export_to_gridinfo, export_to_gridinfov, export_to_gridinfovv,&
112 volgrid6d_export_to_file
118 MODULE PROCEDURE volgrid6d_transform_compute, volgrid6d_v7d_transform_compute,&
119 v7d_volgrid6d_transform_compute, v7d_v7d_transform_compute
125 MODULE PROCEDURE volgrid6d_transform, volgrid6dv_transform,&
126 volgrid6d_v7d_transform, volgrid6dv_v7d_transform, v7d_volgrid6d_transform, &
131 MODULE PROCEDURE vg6d_wind_rot
135 MODULE PROCEDURE vg6d_wind_unrot
141 MODULE PROCEDURE display_volgrid6d,display_volgrid6dv
156 MODULE PROCEDURE vg6d_rounding, vg6dv_rounding
162 wind_rot,wind_unrot,vg6d_c2a,
display,volgrid6d_alloc,volgrid6d_alloc_vol, &
163 volgrid_get_vol_2d, volgrid_set_vol_2d, volgrid_get_vol_3d, volgrid_set_vol_3d
173 SUBROUTINE volgrid6d_init(this, griddim, time_definition, categoryappend)
174 TYPE(volgrid6d) :: this
175 TYPE(griddim_def),
OPTIONAL :: griddim
176 INTEGER,
INTENT(IN),
OPTIONAL :: time_definition
177 CHARACTER(len=*),
INTENT(in),
OPTIONAL :: categoryappend
179 character(len=512) :: a_name
181 if (
present(categoryappend))
then 182 call l4f_launcher(a_name,a_name_append=trim(subcategory)//
"."//trim(categoryappend))
184 call l4f_launcher(a_name,a_name_append=trim(subcategory))
186 this%category=l4f_category_get_handle(a_name)
192 call init(this%griddim)
194 if (
present(griddim))
then 195 call copy (griddim,this%griddim)
198 if(
present(time_definition))
then 199 this%time_definition = time_definition
201 this%time_definition = 0
204 nullify (this%time,this%timerange,this%level,this%var)
205 nullify (this%gaid,this%voldati)
207 END SUBROUTINE volgrid6d_init
220 SUBROUTINE volgrid6d_alloc(this, dim, ntime, nlevel, ntimerange, nvar, ini)
221 TYPE(volgrid6d),
INTENT(inout) :: this
222 TYPE(grid_dim),
INTENT(in),
OPTIONAL :: dim
223 INTEGER,
INTENT(in),
OPTIONAL :: ntime
224 INTEGER,
INTENT(in),
OPTIONAL :: nlevel
225 INTEGER,
INTENT(in),
OPTIONAL :: ntimerange
226 INTEGER,
INTENT(in),
OPTIONAL :: nvar
227 LOGICAL,
INTENT(in),
OPTIONAL :: ini
236 IF (
PRESENT(ini))
THEN 243 if (
present(dim))
call copy (dim,this%griddim%dim)
246 IF (
PRESENT(ntime))
THEN 248 IF (
ASSOCIATED(this%time))
DEALLOCATE(this%time)
252 ALLOCATE(this%time(ntime),stat=stallo)
255 CALL raise_fatal_error()
259 this%time(i) = datetime_miss
266 IF (
PRESENT(nlevel))
THEN 267 IF (nlevel >= 0)
THEN 268 IF (
ASSOCIATED(this%level))
DEALLOCATE(this%level)
272 ALLOCATE(this%level(nlevel),stat=stallo)
275 CALL raise_fatal_error()
284 IF (
PRESENT(ntimerange))
THEN 285 IF (ntimerange >= 0)
THEN 286 IF (
ASSOCIATED(this%timerange))
DEALLOCATE(this%timerange)
290 ALLOCATE(this%timerange(ntimerange),stat=stallo)
293 CALL raise_fatal_error()
297 CALL init(this%timerange(i))
302 IF (
PRESENT(nvar))
THEN 304 IF (
ASSOCIATED(this%var))
DEALLOCATE(this%var)
308 ALLOCATE(this%var(nvar),stat=stallo)
311 CALL raise_fatal_error()
315 CALL init(this%var(i))
321 end SUBROUTINE volgrid6d_alloc
332 SUBROUTINE volgrid6d_alloc_vol(this, ini, inivol, decode)
333 TYPE(volgrid6d),
INTENT(inout) :: this
334 LOGICAL,
INTENT(in),
OPTIONAL :: ini
335 LOGICAL,
INTENT(in),
OPTIONAL :: inivol
336 LOGICAL,
INTENT(in),
OPTIONAL :: decode
345 IF (
PRESENT(inivol))
THEN 351 IF (this%griddim%dim%nx > 0 .AND. this%griddim%dim%ny > 0)
THEN 354 IF (.NOT.
ASSOCIATED(this%var))
CALL volgrid6d_alloc(this, nvar=1, ini=ini)
355 IF (.NOT.
ASSOCIATED(this%time))
CALL volgrid6d_alloc(this, ntime=1, ini=ini)
356 IF (.NOT.
ASSOCIATED(this%level))
CALL volgrid6d_alloc(this, nlevel=1, ini=ini)
357 IF (.NOT.
ASSOCIATED(this%timerange))
CALL volgrid6d_alloc(this, ntimerange=1, ini=ini)
359 IF (optio_log(decode))
THEN 360 IF (.NOT.
ASSOCIATED(this%voldati))
THEN 365 ALLOCATE(this%voldati(this%griddim%dim%nx,this%griddim%dim%ny,&
366 SIZE(this%level),
SIZE(this%time), &
367 SIZE(this%timerange),
SIZE(this%var)),stat=stallo)
370 CALL raise_fatal_error()
375 IF (linivol) this%voldati = rmiss
380 IF (.NOT.
ASSOCIATED(this%gaid))
THEN 384 ALLOCATE(this%gaid(
SIZE(this%level),
SIZE(this%time), &
385 SIZE(this%timerange),
SIZE(this%var)),stat=stallo)
388 CALL raise_fatal_error()
402 this%gaid = grid_id_new()
408 &trying to allocate a volume with an invalid or unspecified horizontal grid')
409 CALL raise_fatal_error()
412 END SUBROUTINE volgrid6d_alloc_vol
428 SUBROUTINE volgrid_get_vol_2d(this, ilevel, itime, itimerange, ivar, voldati)
429 TYPE(volgrid6d),
INTENT(in) :: this
430 INTEGER,
INTENT(in) :: ilevel
431 INTEGER,
INTENT(in) :: itime
432 INTEGER,
INTENT(in) :: itimerange
433 INTEGER,
INTENT(in) :: ivar
434 REAL,
POINTER :: voldati(:,:)
436 IF (
ASSOCIATED(this%voldati))
THEN 437 voldati => this%voldati(:,:,ilevel,itime,itimerange,ivar)
440 IF (.NOT.
ASSOCIATED(voldati))
THEN 441 ALLOCATE(voldati(this%griddim%dim%nx,this%griddim%dim%ny))
443 CALL grid_id_decode_data(this%gaid(ilevel,itime,itimerange,ivar), voldati)
446 END SUBROUTINE volgrid_get_vol_2d
462 SUBROUTINE volgrid_get_vol_3d(this, itime, itimerange, ivar, voldati, zlist)
463 TYPE(volgrid6d),
INTENT(in) :: this
464 INTEGER,
INTENT(in) :: itime
465 INTEGER,
INTENT(in) :: itimerange
466 INTEGER,
INTENT(in) :: ivar
467 REAL,
POINTER :: voldati(:,:,:)
468 LOGICAL,
OPTIONAL,
INTENT(out),
ALLOCATABLE :: zlist(:)
473 IF (
ASSOCIATED(this%voldati))
THEN 474 voldati => this%voldati(:,:,:,itime,itimerange,ivar)
475 IF (
PRESENT(zlist)) zlist(:) =
c_e(this%gaid(:,itime,itimerange,ivar))
478 IF (.NOT.
ASSOCIATED(voldati))
THEN 479 ALLOCATE(voldati(this%griddim%dim%nx,this%griddim%dim%ny,
SIZE(this%level)))
481 IF (
PRESENT(zlist))
THEN 482 ALLOCATE(zlist(
SIZE(this%level)))
486 DO ilevel = 1,
SIZE(this%level)
488 CALL grid_id_decode_data(this%gaid(ilevel,itime,itimerange,ivar), &
489 voldati(:,:,ilevel),done)
490 IF (
PRESENT(zlist)) zlist(ilevel) = done
497 END SUBROUTINE volgrid_get_vol_3d
511 SUBROUTINE volgrid_set_vol_2d(this, ilevel, itime, itimerange, ivar, voldati)
512 TYPE(volgrid6d),
INTENT(inout) :: this
513 INTEGER,
INTENT(in) :: ilevel
514 INTEGER,
INTENT(in) :: itime
515 INTEGER,
INTENT(in) :: itimerange
516 INTEGER,
INTENT(in) :: ivar
517 REAL,
INTENT(in) :: voldati(:,:)
519 IF (
ASSOCIATED(this%voldati))
THEN 522 CALL grid_id_encode_data(this%gaid(ilevel,itime,itimerange,ivar), voldati)
525 END SUBROUTINE volgrid_set_vol_2d
539 SUBROUTINE volgrid_set_vol_3d(this, itime, itimerange, ivar, voldati)
540 TYPE(volgrid6d),
INTENT(inout) :: this
541 INTEGER,
INTENT(in) :: itime
542 INTEGER,
INTENT(in) :: itimerange
543 INTEGER,
INTENT(in) :: ivar
544 REAL,
INTENT(in) :: voldati(:,:,:)
548 IF (
ASSOCIATED(this%voldati))
THEN 553 DO ilevel = 1,
SIZE(this%level)
555 CALL grid_id_encode_data(this%gaid(ilevel,itime,itimerange,ivar), &
563 END SUBROUTINE volgrid_set_vol_3d
569 SUBROUTINE volgrid6d_delete(this)
570 TYPE(volgrid6d),
INTENT(inout) :: this
572 INTEGER :: i, ii, iii, iiii
578 if (
associated(this%gaid))
then 580 DO i=1 ,
SIZE(this%gaid,1)
581 DO ii=1 ,
SIZE(this%gaid,2)
582 DO iii=1 ,
SIZE(this%gaid,3)
583 DO iiii=1 ,
SIZE(this%gaid,4)
584 CALL delete(this%gaid(i,ii,iii,iiii))
589 DEALLOCATE(this%gaid)
600 if (
associated( this%time ))
deallocate(this%time)
601 if (
associated( this%timerange ))
deallocate(this%timerange)
602 if (
associated( this%level ))
deallocate(this%level)
603 if (
associated( this%var ))
deallocate(this%var)
605 if (
associated(this%voldati))
deallocate(this%voldati)
609 call l4f_category_delete(this%category)
611 END SUBROUTINE volgrid6d_delete
623 subroutine volgrid6d_write_on_file (this,unit,description,filename,filename_auto)
625 TYPE(volgrid6d),
INTENT(IN) :: this
626 integer,
optional,
intent(inout) :: unit
627 character(len=*),
intent(in),
optional :: filename
628 character(len=*),
intent(out),
optional :: filename_auto
629 character(len=*),
INTENT(IN),
optional :: description
632 character(len=254) :: ldescription,arg,lfilename
633 integer :: ntime, ntimerange, nlevel, nvar
635 logical :: opened,exist
647 call date_and_time(values=tarray)
650 if (
present(description))
then 651 ldescription=description
653 ldescription=
"Volgrid6d generated by: "//trim(arg)
656 if (.not.
present(unit))
then 667 lfilename=trim(arg)//
".vg6d" 668 if (
index(arg,
'/',back=.true.) > 0) lfilename=lfilename(
index(arg,
'/',back=.true.)+1 : )
670 if (
present(filename))
then 671 if (filename /=
"")
then 676 if (
present(filename_auto))filename_auto=lfilename
679 inquire(unit=lunit,opened=opened)
680 if (.not. opened)
then 681 inquire(file=lfilename,exist=exist)
682 if (exist)
CALL raise_error(
'file exist; cannot open new file')
683 if (.not.exist)
open (unit=lunit,file=lfilename,form=
"UNFORMATTED")
687 if (
associated(this%time)) ntime=
size(this%time)
688 if (
associated(this%timerange)) ntimerange=
size(this%timerange)
689 if (
associated(this%level)) nlevel=
size(this%level)
690 if (
associated(this%var)) nvar=
size(this%var)
693 write(unit=lunit)ldescription
694 write(unit=lunit)tarray
697 write(unit=lunit) ntime, ntimerange, nlevel, nvar
700 if (
associated(this%time))
call write_unit(this%time, lunit)
701 if (
associated(this%level))
write(unit=lunit)this%level
702 if (
associated(this%timerange))
write(unit=lunit)this%timerange
703 if (
associated(this%var))
write(unit=lunit)this%var
708 if (
associated(this%voldati))
write(unit=lunit)this%voldati
710 if (.not.
present(unit))
close(unit=lunit)
712 end subroutine volgrid6d_write_on_file
721 subroutine volgrid6d_read_from_file (this,unit,filename,description,tarray,filename_auto)
724 integer,
intent(inout),
optional :: unit
725 character(len=*),
INTENT(in),
optional :: filename
726 character(len=*),
intent(out),
optional :: filename_auto
727 character(len=*),
INTENT(out),
optional :: description
728 integer,
intent(out),
optional :: tarray(8)
730 integer :: ntime, ntimerange, nlevel, nvar
732 character(len=254) :: ldescription,lfilename,arg
733 integer :: ltarray(8),lunit
734 logical :: opened,exist
742 if (.not.
present(unit))
then 753 lfilename=trim(arg)//
".vg6d" 754 if (
index(arg,
'/',back=.true.) > 0) lfilename=lfilename(
index(arg,
'/',back=.true.)+1 : )
756 if (
present(filename))
then 757 if (filename /=
"")
then 762 if (
present(filename_auto))filename_auto=lfilename
765 inquire(unit=lunit,opened=opened)
766 if (.not. opened)
then 767 inquire(file=lfilename,exist=exist)
768 IF (.NOT. exist)
CALL raise_fatal_error(
'file '//trim(lfilename)//
' does not exist, cannot open')
769 open (unit=lunit,file=lfilename,form=
"UNFORMATTED")
772 read(unit=lunit)ldescription
773 read(unit=lunit)ltarray
775 call l4f_log(l4f_info,
"Info: reading volgrid6d from file: "//trim(lfilename))
776 call l4f_log(l4f_info,
"Info: description: "//trim(ldescription))
779 if (
present(description))description=ldescription
780 if (
present(tarray))tarray=ltarray
784 read(unit=lunit) ntime, ntimerange, nlevel, nvar
787 call volgrid6d_alloc (this, &
788 ntime=ntime, ntimerange=ntimerange, nlevel=nlevel, nvar=nvar)
790 call volgrid6d_alloc_vol (this)
792 if (
associated(this%time))
call read_unit(this%time, lunit)
793 if (
associated(this%level))
read(unit=lunit)this%level
794 if (
associated(this%timerange))
read(unit=lunit)this%timerange
795 if (
associated(this%var))
read(unit=lunit)this%var
800 if (
associated(this%voldati))
read(unit=lunit)this%voldati
802 if (.not.
present(unit))
close(unit=lunit)
804 end subroutine volgrid6d_read_from_file
826 SUBROUTINE import_from_gridinfo(this, gridinfo, force, dup_mode, clone, &
828 TYPE(volgrid6d),
INTENT(inout) :: this
829 TYPE(gridinfo_def),
INTENT(in) :: gridinfo
830 LOGICAL,
INTENT(in),
OPTIONAL :: force
831 INTEGER,
INTENT(in),
OPTIONAL :: dup_mode
832 LOGICAL ,
INTENT(in),
OPTIONAL :: clone
833 LOGICAL,
INTENT(IN),
OPTIONAL :: isanavar
835 CHARACTER(len=255) :: type
836 INTEGER :: itime0, itimerange0, itime1, itimerange1, itime, itimerange, &
837 ilevel, ivar, ldup_mode
839 TYPE(datetime) :: correctedtime
840 TYPE(vol7d_timerange) :: correctedtimerange
841 REAL,
ALLOCATABLE :: tmpgrid(:,:)
843 IF (
PRESENT(dup_mode))
THEN 849 call get_val(this%griddim,proj_type=type)
852 call l4f_category_log(this%category,l4f_debug,
"import_from_gridinfo: "//trim(type))
855 if (.not.
c_e(type))
then 856 call copy(gridinfo%griddim, this%griddim)
860 CALL volgrid6d_alloc_vol(this, ini=.true.)
862 else if (.not. (this%griddim == gridinfo%griddim ))
then 865 "volgrid and gridinfo grid type or size are different, gridinfo rejected")
872 ilevel =
index(this%level, gridinfo%level)
873 IF (ilevel == 0 .AND. optio_log(force))
THEN 874 ilevel =
index(this%level, vol7d_level_miss)
875 IF (ilevel /= 0) this%level(ilevel) = gridinfo%level
878 IF (ilevel == 0)
THEN 880 "volgrid6d: level not valid for volume, gridinfo rejected")
885 IF (optio_log(isanavar))
THEN 887 itime1 =
SIZE(this%time)
889 itimerange1 =
SIZE(this%timerange)
891 correctedtime = gridinfo%time
892 IF (this%time_definition == 1 .OR. this%time_definition == 2) correctedtime = correctedtime + &
893 timedelta_new(sec=gridinfo%timerange%p1)
894 itime0 =
index(this%time, correctedtime)
895 IF (itime0 == 0 .AND. optio_log(force))
THEN 896 itime0 =
index(this%time, datetime_miss)
897 IF (itime0 /= 0) this%time(itime0) = correctedtime
899 IF (itime0 == 0)
THEN 901 "volgrid6d: time not valid for volume, gridinfo rejected")
907 correctedtimerange = gridinfo%timerange
908 IF (this%time_definition == 2) correctedtimerange%p1 = 0
909 itimerange0 =
index(this%timerange, correctedtimerange)
910 IF (itimerange0 == 0 .AND. optio_log(force))
THEN 911 itimerange0 =
index(this%timerange, vol7d_timerange_miss)
912 IF (itimerange0 /= 0) this%timerange(itimerange0) = gridinfo%timerange
914 IF (itimerange0 == 0)
THEN 916 "volgrid6d: timerange not valid for volume, gridinfo rejected")
920 itimerange1 = itimerange0
923 ivar =
index(this%var, gridinfo%var)
924 IF (ivar == 0 .AND. optio_log(force))
THEN 925 ivar =
index(this%var, volgrid6d_var_miss)
926 IF (ivar /= 0) this%var(ivar) = gridinfo%var
930 "volgrid6d: var not valid for volume, gridinfo rejected")
935 DO itimerange = itimerange0, itimerange1
936 DO itime = itime0, itime1
937 IF (
ASSOCIATED(this%gaid))
THEN 939 IF (
c_e(this%gaid(ilevel,itime,itimerange,ivar)))
THEN 943 IF (optio_log(
clone))
CALL delete(this%gaid(ilevel,itime,itimerange,ivar))
946 IF (optio_log(
clone))
THEN 947 CALL copy(gridinfo%gaid, this%gaid(ilevel,itime,itimerange,ivar))
952 this%gaid(ilevel,itime,itimerange,ivar) = gridinfo%gaid
955 IF (
ASSOCIATED(this%voldati))
THEN 956 IF (.NOT.dup .OR. ldup_mode == 0)
THEN 957 this%voldati(:,:,ilevel,itime,itimerange,ivar) =
decode_gridinfo(gridinfo)
958 ELSE IF (ldup_mode == 1)
THEN 961 this%voldati(:,:,ilevel,itime,itimerange,ivar) = tmpgrid(:,:)
963 ELSE IF (ldup_mode == 2)
THEN 964 WHERE(.NOT.
c_e(this%voldati(:,:,ilevel,itime,itimerange,ivar)))
965 this%voldati(:,:,ilevel,itime,itimerange,ivar) =
decode_gridinfo(gridinfo)
972 "gaid not allocated, you probably need to call volgrid6d_alloc_vol first")
980 END SUBROUTINE import_from_gridinfo
987 SUBROUTINE export_to_gridinfo(this, gridinfo, itime, itimerange, ilevel, ivar, &
988 gaid_template, clone)
989 TYPE(volgrid6d),
INTENT(in) :: this
990 TYPE(gridinfo_def),
INTENT(inout) :: gridinfo
992 INTEGER :: itimerange
995 TYPE(grid_id),
INTENT(in),
OPTIONAL :: gaid_template
996 LOGICAL,
INTENT(in),
OPTIONAL :: clone
998 TYPE(grid_id) :: gaid
999 LOGICAL :: usetemplate
1000 REAL,
POINTER :: voldati(:,:)
1001 TYPE(datetime) :: correctedtime
1007 IF (.NOT.
c_e(this%gaid(ilevel,itime,itimerange,ivar)))
THEN 1009 CALL l4f_category_log(this%category,l4f_debug,
"empty gaid found, skipping export")
1014 usetemplate = .false.
1015 IF (
PRESENT(gaid_template))
THEN 1016 CALL copy(gaid_template, gaid)
1018 CALL l4f_category_log(this%category,l4f_debug,
"template cloned to a new gaid")
1020 usetemplate =
c_e(gaid)
1023 IF (.NOT.usetemplate)
THEN 1024 IF (optio_log(
clone))
THEN 1025 CALL copy(this%gaid(ilevel,itime,itimerange,ivar), gaid)
1027 CALL l4f_category_log(this%category,l4f_debug,
"original gaid cloned to a new one")
1030 gaid = this%gaid(ilevel,itime,itimerange,ivar)
1034 IF (this%time_definition == 1 .OR. this%time_definition == 2)
THEN 1035 correctedtime = this%time(itime) - &
1036 timedelta_new(sec=this%timerange(itimerange)%p1)
1038 correctedtime = this%time(itime)
1041 CALL init(gridinfo,gaid, this%griddim, correctedtime, this%timerange(itimerange), &
1042 this%level(ilevel), this%var(ivar))
1045 CALL export(gridinfo%griddim, gridinfo%gaid)
1047 IF (
ASSOCIATED(this%voldati))
THEN 1048 CALL encode_gridinfo(gridinfo, this%voldati(:,:,ilevel,itime,itimerange,ivar))
1049 ELSE IF (usetemplate)
THEN 1051 CALL volgrid_get_vol_2d(this, ilevel, itime, itimerange, ivar, voldati)
1056 END SUBROUTINE export_to_gridinfo
1076 SUBROUTINE import_from_gridinfovv(this, gridinfov, dup_mode, clone, decode, &
1077 time_definition, anavar, categoryappend)
1078 TYPE(volgrid6d),
POINTER :: this(:)
1079 TYPE(arrayof_gridinfo),
INTENT(in) :: gridinfov
1080 INTEGER,
INTENT(in),
OPTIONAL :: dup_mode
1081 LOGICAL ,
INTENT(in),
OPTIONAL :: clone
1082 LOGICAL,
INTENT(in),
OPTIONAL :: decode
1083 INTEGER,
INTENT(IN),
OPTIONAL :: time_definition
1084 CHARACTER(len=*),
INTENT(IN),
OPTIONAL :: anavar(:)
1085 CHARACTER(len=*),
INTENT(in),
OPTIONAL :: categoryappend
1087 INTEGER :: i, j, stallo
1088 INTEGER :: ngrid, ntime, ntimerange, nlevel, nvar, ltime_definition
1089 TYPE(l4f_handle) :: category
1090 CHARACTER(len=512) :: a_name
1091 TYPE(datetime),
ALLOCATABLE :: correctedtime(:)
1092 LOGICAL,
ALLOCATABLE :: isanavar(:)
1093 TYPE(vol7d_var) :: lvar
1094 TYPE(vol7d_timerange),
ALLOCATABLE :: correctedtimerange(:)
1097 if (
present(categoryappend))
then 1098 call l4f_launcher(a_name,a_name_append=trim(subcategory)//
"."//trim(categoryappend))
1100 call l4f_launcher(a_name,a_name_append=trim(subcategory))
1102 category=l4f_category_get_handle(a_name)
1108 IF (
PRESENT(time_definition))
THEN 1109 ltime_definition = max(min(time_definition, 2), 0)
1111 ltime_definition = 0
1114 ngrid=count_distinct(gridinfov%array(1:gridinfov%arraysize)%griddim,back=.true.)
1116 ' different grid definition(s) found in input data')
1118 ALLOCATE(this(ngrid),stat=stallo)
1119 IF (stallo /= 0)
THEN 1121 CALL raise_fatal_error()
1124 IF (
PRESENT(categoryappend))
THEN 1125 CALL init(this(i), time_definition=ltime_definition, categoryappend=trim(categoryappend)//
"-vol"//
t2c(i))
1127 CALL init(this(i), time_definition=ltime_definition, categoryappend=
"vol"//
t2c(i))
1131 this(:)%griddim=pack_distinct(gridinfov%array(1:gridinfov%arraysize)%griddim, &
1135 ALLOCATE(isanavar(gridinfov%arraysize))
1136 isanavar(:) = .false.
1137 IF (
PRESENT(anavar))
THEN 1138 DO i = 1, gridinfov%arraysize
1139 DO j = 1,
SIZE(anavar)
1140 lvar =
convert(gridinfov%array(i)%var)
1141 IF (lvar%btable == anavar(j))
THEN 1142 isanavar(i) = .true.
1148 t2c(gridinfov%arraysize)//
' constant-data messages found in input data')
1151 IF (ltime_definition == 1 .OR. ltime_definition == 2)
THEN 1152 ALLOCATE(correctedtime(gridinfov%arraysize))
1153 correctedtime(:) = gridinfov%array(1:gridinfov%arraysize)%time
1154 DO i = 1, gridinfov%arraysize
1155 correctedtime(i) = correctedtime(i) + &
1156 timedelta_new(sec=gridinfov%array(i)%timerange%p1)
1159 IF (ltime_definition == 2)
THEN 1160 ALLOCATE(correctedtimerange(gridinfov%arraysize))
1161 correctedtimerange(:) = gridinfov%array(1:gridinfov%arraysize)%timerange
1162 correctedtimerange(:)%p1 = 0
1166 IF (
PRESENT(anavar))
THEN 1167 j = count((this(i)%griddim == gridinfov%array(1:gridinfov%arraysize)%griddim) &
1168 .AND. .NOT.isanavar(:))
1171 ' has only constant data, this is not allowed')
1173 CALL raise_fatal_error()
1176 IF (ltime_definition == 1 .OR. ltime_definition == 2)
THEN 1177 ntime = count_distinct(correctedtime, &
1178 mask=(this(i)%griddim == gridinfov%array(1:gridinfov%arraysize)%griddim) &
1179 .AND. .NOT.isanavar(:), back=.true.)
1181 ntime = count_distinct(gridinfov%array(1:gridinfov%arraysize)%time, &
1182 mask=(this(i)%griddim == gridinfov%array(1:gridinfov%arraysize)%griddim) &
1183 .AND. .NOT.isanavar(:), back=.true.)
1185 IF (ltime_definition == 2)
THEN 1186 ntimerange = count_distinct(correctedtimerange, &
1187 mask=(this(i)%griddim == gridinfov%array(1:gridinfov%arraysize)%griddim) &
1188 .AND. .NOT.isanavar(:), back=.true.)
1190 ntimerange = count_distinct(gridinfov%array(1:gridinfov%arraysize)%timerange, &
1191 mask=(this(i)%griddim == gridinfov%array(1:gridinfov%arraysize)%griddim) &
1192 .AND. .NOT.isanavar(:), back=.true.)
1194 nlevel = count_distinct(gridinfov%array(1:gridinfov%arraysize)%level, &
1195 mask=(this(i)%griddim == gridinfov%array(1:gridinfov%arraysize)%griddim), &
1197 nvar = count_distinct(gridinfov%array(1:gridinfov%arraysize)%var, &
1198 mask=(this(i)%griddim == gridinfov%array(1:gridinfov%arraysize)%griddim), &
1205 CALL volgrid6d_alloc(this(i),this(i)%griddim%dim,ntime=ntime, &
1206 ntimerange=ntimerange,nlevel=nlevel,nvar=nvar)
1208 IF (ltime_definition == 1 .OR. ltime_definition == 2)
THEN 1209 this(i)%time = pack_distinct(correctedtime, ntime, &
1210 mask=(this(i)%griddim == gridinfov%array(1:gridinfov%arraysize)%griddim) &
1211 .AND. .NOT.isanavar(:), back=.true.)
1213 this(i)%time = pack_distinct(gridinfov%array(1:gridinfov%arraysize)%time, ntime, &
1214 mask=(this(i)%griddim == gridinfov%array(1:gridinfov%arraysize)%griddim) &
1215 .AND. .NOT.isanavar(:), back=.true.)
1217 CALL sort(this(i)%time)
1219 IF (ltime_definition == 2)
THEN 1220 this(i)%timerange = pack_distinct(correctedtimerange, ntimerange, &
1221 mask=(this(i)%griddim == gridinfov%array(1:gridinfov%arraysize)%griddim) &
1222 .AND. .NOT.isanavar(:), back=.true.)
1224 this(i)%timerange = pack_distinct(gridinfov%array(1:gridinfov%arraysize)%timerange, &
1225 ntimerange, mask=(this(i)%griddim == gridinfov%array(1:gridinfov%arraysize)%griddim) &
1226 .AND. .NOT.isanavar(:), back=.true.)
1228 CALL sort(this(i)%timerange)
1230 this(i)%level=pack_distinct(gridinfov%array(1:gridinfov%arraysize)%level, &
1231 nlevel,mask=(this(i)%griddim == gridinfov%array(1:gridinfov%arraysize)%griddim), &
1233 CALL sort(this(i)%level)
1235 this(i)%var=pack_distinct(gridinfov%array(1:gridinfov%arraysize)%var, nvar, &
1236 mask=(this(i)%griddim == gridinfov%array(1:gridinfov%arraysize)%griddim), &
1242 CALL volgrid6d_alloc_vol(this(i), decode=decode)
1246 IF (ltime_definition == 1 .OR. ltime_definition == 2)
DEALLOCATE(correctedtime)
1247 IF (ltime_definition == 2)
DEALLOCATE(correctedtimerange)
1249 DO i = 1, gridinfov%arraysize
1254 "to volgrid6d index: "//
t2c(
index(this%griddim, gridinfov%array(i)%griddim)))
1257 CALL import(this(
index(this%griddim, gridinfov%array(i)%griddim)), &
1258 gridinfov%array(i), dup_mode=dup_mode,
clone=
clone, isanavar=isanavar(i))
1263 CALL l4f_category_delete(category)
1265 END SUBROUTINE import_from_gridinfovv
1273 SUBROUTINE export_to_gridinfov(this, gridinfov, gaid_template, clone)
1274 TYPE(volgrid6d),
INTENT(inout) :: this
1275 TYPE(arrayof_gridinfo),
INTENT(inout) :: gridinfov
1276 TYPE(grid_id),
INTENT(in),
OPTIONAL :: gaid_template
1277 LOGICAL,
INTENT(in),
OPTIONAL :: clone
1279 INTEGER :: i ,itime, itimerange, ilevel, ivar
1280 INTEGER :: ntime, ntimerange, nlevel, nvar
1281 TYPE(gridinfo_def) :: gridinfol
1290 CALL dealloc(this%griddim%dim)
1293 ntime=
size(this%time)
1294 ntimerange=
size(this%timerange)
1295 nlevel=
size(this%level)
1299 DO itimerange=1,ntimerange
1303 CALL init(gridinfol)
1304 CALL export(this, gridinfol, itime, itimerange, ilevel, ivar, &
1306 IF (
c_e(gridinfol%gaid))
THEN 1307 CALL insert(gridinfov, gridinfol)
1317 END SUBROUTINE export_to_gridinfov
1325 SUBROUTINE export_to_gridinfovv(this, gridinfov, gaid_template, clone)
1328 TYPE(volgrid6d),
INTENT(inout) :: this(:)
1329 TYPE(arrayof_gridinfo),
INTENT(inout) :: gridinfov
1330 TYPE(grid_id),
INTENT(in),
OPTIONAL :: gaid_template
1331 LOGICAL,
INTENT(in),
OPTIONAL :: clone
1335 DO i = 1,
SIZE(this)
1338 "export_to_gridinfovv grid index: "//
t2c(i))
1343 END SUBROUTINE export_to_gridinfovv
1355 SUBROUTINE volgrid6d_import_from_file(this, filename, dup_mode, decode, &
1356 time_definition, anavar, categoryappend)
1357 TYPE(volgrid6d),
POINTER :: this(:)
1358 CHARACTER(len=*),
INTENT(in) :: filename
1359 INTEGER,
INTENT(in),
OPTIONAL :: dup_mode
1360 LOGICAL,
INTENT(in),
OPTIONAL :: decode
1361 INTEGER,
INTENT(IN),
OPTIONAL :: time_definition
1362 CHARACTER(len=*),
INTENT(IN),
OPTIONAL :: anavar(:)
1363 character(len=*),
INTENT(in),
OPTIONAL :: categoryappend
1365 TYPE(arrayof_gridinfo) :: gridinfo
1366 TYPE(l4f_handle) :: category
1367 CHARACTER(len=512) :: a_name
1371 IF (
PRESENT(categoryappend))
THEN 1372 CALL l4f_launcher(a_name,a_name_append= &
1373 trim(subcategory)//
"."//trim(categoryappend))
1375 CALL l4f_launcher(a_name,a_name_append=trim(subcategory))
1377 category=l4f_category_get_handle(a_name)
1379 CALL import(gridinfo, filename=filename, categoryappend=categoryappend)
1381 IF (gridinfo%arraysize > 0)
THEN 1383 CALL import(this, gridinfo, dup_mode=dup_mode,
clone=.true., decode=decode, &
1384 time_definition=time_definition, anavar=anavar, &
1385 categoryappend=categoryappend)
1391 CALL l4f_category_log(category,l4f_info,
"file does not contain gridded data")
1395 CALL l4f_category_delete(category)
1397 END SUBROUTINE volgrid6d_import_from_file
1407 SUBROUTINE volgrid6d_export_to_file(this, filename, gaid_template, categoryappend)
1408 TYPE(volgrid6d) :: this(:)
1409 CHARACTER(len=*),
INTENT(in) :: filename
1410 TYPE(grid_id),
INTENT(in),
OPTIONAL :: gaid_template
1411 character(len=*),
INTENT(in),
OPTIONAL :: categoryappend
1413 TYPE(arrayof_gridinfo) :: gridinfo
1414 TYPE(l4f_handle) :: category
1415 CHARACTER(len=512) :: a_name
1417 IF (
PRESENT(categoryappend))
THEN 1418 CALL l4f_launcher(a_name,a_name_append=trim(subcategory)//
"."//trim(categoryappend))
1420 CALL l4f_launcher(a_name,a_name_append=trim(subcategory))
1422 category=l4f_category_get_handle(a_name)
1428 CALL l4f_category_log(category,l4f_info,
"writing volgrid6d to grib file: "//trim(filename))
1431 CALL export(this, gridinfo, gaid_template=gaid_template,
clone=.true.)
1432 IF (gridinfo%arraysize > 0)
THEN 1433 CALL export(gridinfo, filename)
1441 CALL l4f_category_delete(category)
1443 END SUBROUTINE volgrid6d_export_to_file
1449 SUBROUTINE volgrid6dv_delete(this)
1450 TYPE(volgrid6d),
POINTER :: this(:)
1454 IF (
ASSOCIATED(this))
THEN 1455 DO i = 1,
SIZE(this)
1458 "delete volgrid6d vector index: "//trim(
to_char(i)))
1465 END SUBROUTINE volgrid6dv_delete
1469 SUBROUTINE volgrid6d_transform_compute(this, volgrid6d_in, volgrid6d_out, &
1470 lev_out, var_coord_vol, clone)
1471 TYPE(grid_transform),
INTENT(in) :: this
1472 type(volgrid6d),
INTENT(in) :: volgrid6d_in
1473 type(volgrid6d),
INTENT(inout) :: volgrid6d_out
1474 TYPE(vol7d_level),
INTENT(in),
OPTIONAL :: lev_out(:)
1475 INTEGER,
INTENT(in),
OPTIONAL :: var_coord_vol
1476 LOGICAL,
INTENT(in),
OPTIONAL :: clone
1478 INTEGER :: ntime, ntimerange, inlevel, onlevel, nvar, &
1479 itime, itimerange, ilevel, ivar, levshift, levused, lvar_coord_vol, spos
1480 REAL,
POINTER :: voldatiin(:,:,:), voldatiout(:,:,:), coord_3d_in(:,:,:)
1481 TYPE(vol7d_level) :: output_levtype
1482 LOGICAL,
ALLOCATABLE :: zlist(:)
1486 call l4f_category_log(volgrid6d_in%category,l4f_debug,
"start volgrid6d_transform_compute")
1494 lvar_coord_vol = optio_i(var_coord_vol)
1496 if (
associated(volgrid6d_in%time))
then 1497 ntime=
size(volgrid6d_in%time)
1498 volgrid6d_out%time=volgrid6d_in%time
1501 if (
associated(volgrid6d_in%timerange))
then 1502 ntimerange=
size(volgrid6d_in%timerange)
1503 volgrid6d_out%timerange=volgrid6d_in%timerange
1506 IF (
ASSOCIATED(volgrid6d_in%level))
THEN 1507 inlevel=
SIZE(volgrid6d_in%level)
1509 IF (
PRESENT(lev_out))
THEN 1510 onlevel=
SIZE(lev_out)
1511 volgrid6d_out%level=lev_out
1512 ELSE IF (
ASSOCIATED(volgrid6d_in%level))
THEN 1513 onlevel=
SIZE(volgrid6d_in%level)
1514 volgrid6d_out%level=volgrid6d_in%level
1517 if (
associated(volgrid6d_in%var))
then 1518 nvar=
size(volgrid6d_in%var)
1519 volgrid6d_out%var=volgrid6d_in%var
1522 IF (.NOT.
ASSOCIATED(volgrid6d_in%voldati))
THEN 1523 ALLOCATE(voldatiin(volgrid6d_in%griddim%dim%nx, volgrid6d_in%griddim%dim%ny, &
1526 IF (.NOT.
ASSOCIATED(volgrid6d_out%voldati))
THEN 1527 ALLOCATE(voldatiout(volgrid6d_out%griddim%dim%nx, volgrid6d_out%griddim%dim%ny, &
1531 CALL get_val(this, levshift=levshift, levused=levused)
1533 IF (
c_e(lvar_coord_vol))
THEN 1534 CALL get_val(this%trans, output_levtype=output_levtype)
1535 IF (output_levtype%level1 == 103 .OR. output_levtype%level1 == 108)
THEN 1538 spos = firsttrue(volgrid6d_in%level(:) == vol7d_level_new(1))
1541 'output level '//
t2c(output_levtype%level1)// &
1542 ' requested, but height/press of surface not provided in volume')
1544 IF (.NOT.
c_e(levshift) .AND. .NOT.
c_e(levused))
THEN 1546 'internal inconsistence, levshift and levused undefined when they should be')
1555 DO itimerange=1,ntimerange
1558 IF (
c_e(levshift) .AND.
c_e(levused))
THEN 1560 volgrid6d_in%gaid(levshift+1:levshift+levused,itime,itimerange,ivar) &
1563 DO ilevel = 1, min(inlevel,onlevel)
1565 IF (
c_e(volgrid6d_in%gaid(ilevel,itime,itimerange,ivar)) .AND. .NOT. &
1566 c_e(volgrid6d_out%gaid(ilevel,itime,itimerange,ivar)))
THEN 1568 IF (optio_log(
clone))
THEN 1569 CALL copy(volgrid6d_in%gaid(ilevel,itime,itimerange,ivar),&
1570 volgrid6d_out%gaid(ilevel,itime,itimerange,ivar))
1573 "cloning gaid, level "//
t2c(ilevel))
1576 volgrid6d_out%gaid(ilevel,itime,itimerange,ivar) = &
1577 volgrid6d_in%gaid(ilevel,itime,itimerange,ivar)
1582 DO ilevel = min(inlevel,onlevel) + 1, onlevel
1583 IF (
c_e(volgrid6d_in%gaid(inlevel,itime,itimerange,ivar)) .AND. .NOT. &
1584 c_e(volgrid6d_out%gaid(ilevel,itime,itimerange,ivar)))
then 1586 CALL copy(volgrid6d_in%gaid(inlevel,itime,itimerange,ivar),&
1587 volgrid6d_out%gaid(ilevel,itime,itimerange,ivar))
1590 "forced cloning gaid, level "//
t2c(inlevel)//
"->"//
t2c(ilevel))
1595 IF (
c_e(lvar_coord_vol))
THEN 1596 NULLIFY(coord_3d_in)
1597 CALL volgrid_get_vol_3d(volgrid6d_in, itime, itimerange, lvar_coord_vol, &
1601 coord_3d_in(:,:,levshift+1:levshift+levused) = rmiss
1603 DO ilevel = levshift+1, levshift+levused
1604 WHERE(
c_e(coord_3d_in(:,:,ilevel)) .AND.
c_e(coord_3d_in(:,:,spos)))
1605 coord_3d_in(:,:,ilevel) = coord_3d_in(:,:,ilevel) - &
1606 coord_3d_in(:,:,spos)
1608 coord_3d_in(:,:,ilevel) = rmiss
1614 CALL volgrid_get_vol_3d(volgrid6d_in, itime, itimerange, ivar, &
1616 IF (
ASSOCIATED(volgrid6d_out%voldati)) &
1617 CALL volgrid_get_vol_3d(volgrid6d_out, itime, itimerange, ivar, &
1619 IF (
c_e(lvar_coord_vol))
THEN 1620 CALL compute(this, voldatiin, voldatiout, var=
convert(volgrid6d_in%var(ivar)), &
1621 coord_3d_in=coord_3d_in(:,:,levshift+1:levshift+levused))
1623 CALL compute(this, voldatiin, voldatiout, var=
convert(volgrid6d_in%var(ivar)), zlist=zlist)
1625 CALL volgrid_set_vol_3d(volgrid6d_out, itime, itimerange, ivar, &
1631 IF (
c_e(lvar_coord_vol))
THEN 1632 DEALLOCATE(coord_3d_in)
1634 IF (.NOT.
ASSOCIATED(volgrid6d_in%voldati))
THEN 1635 DEALLOCATE(voldatiin)
1637 IF (.NOT.
ASSOCIATED(volgrid6d_out%voldati))
THEN 1638 DEALLOCATE(voldatiout)
1642 END SUBROUTINE volgrid6d_transform_compute
1651 SUBROUTINE volgrid6d_transform(this, griddim, volgrid6d_in, volgrid6d_out, &
1652 lev_out, volgrid6d_coord_in, maskgrid, maskbounds, clone, decode, categoryappend)
1653 TYPE(transform_def),
INTENT(in) :: this
1654 TYPE(griddim_def),
INTENT(in),
OPTIONAL :: griddim
1655 TYPE(volgrid6d),
INTENT(inout) :: volgrid6d_in
1656 TYPE(volgrid6d),
INTENT(out) :: volgrid6d_out
1657 TYPE(vol7d_level),
INTENT(in),
OPTIONAL,
TARGET :: lev_out(:)
1658 TYPE(volgrid6d),
INTENT(in),
OPTIONAL :: volgrid6d_coord_in
1659 REAL,
INTENT(in),
OPTIONAL :: maskgrid(:,:)
1660 REAL,
INTENT(in),
OPTIONAL :: maskbounds(:)
1661 LOGICAL,
INTENT(in),
OPTIONAL :: clone
1662 LOGICAL,
INTENT(in),
OPTIONAL :: decode
1663 CHARACTER(len=*),
INTENT(in),
OPTIONAL :: categoryappend
1665 TYPE(grid_transform) :: grid_trans
1666 TYPE(vol7d_level),
POINTER :: llev_out(:)
1667 TYPE(vol7d_level) :: input_levtype, output_levtype
1668 TYPE(vol7d_var) :: vcoord_var
1669 INTEGER :: i, k, ntime, ntimerange, nlevel, nvar, var_coord_in, var_coord_vol, &
1670 cf_out, nxc, nyc, nxi, nyi, i3, i4, i5, i6, &
1671 ulstart, ulend, spos
1672 REAL,
ALLOCATABLE :: coord_3d_in(:,:,:)
1673 TYPE(geo_proj) :: proj_in, proj_out
1674 CHARACTER(len=80) :: trans_type
1676 LOGICAL,
ALLOCATABLE :: mask_in(:)
1679 call l4f_category_log(volgrid6d_in%category, l4f_debug,
"start volgrid6d_transform")
1687 if (
associated(volgrid6d_in%time)) ntime=
size(volgrid6d_in%time)
1688 if (
associated(volgrid6d_in%timerange)) ntimerange=
size(volgrid6d_in%timerange)
1689 if (
associated(volgrid6d_in%level)) nlevel=
size(volgrid6d_in%level)
1690 if (
associated(volgrid6d_in%var)) nvar=
size(volgrid6d_in%var)
1692 IF (ntime == 0 .OR. ntimerange == 0 .OR. nlevel == 0 .OR. nvar == 0)
THEN 1694 "trying to transform an incomplete volgrid6d object, ntime="//
t2c(ntime)// &
1695 ' ntimerange='//
t2c(ntimerange)//
' nlevel='//
t2c(nlevel)//
' nvar='//
t2c(nvar))
1696 CALL init(volgrid6d_out)
1701 CALL get_val(this, trans_type=trans_type)
1705 IF (
PRESENT(griddim) .AND. (trans_type ==
'inter' .OR. trans_type ==
'boxinter' &
1706 .OR. trans_type ==
'stencilinter'))
THEN 1708 CALL get_val(griddim, component_flag=cf_out,
proj=proj_out)
1710 IF (proj_in /= proj_out)
CALL vg6d_wind_unrot(volgrid6d_in)
1711 ELSE IF (
PRESENT(griddim))
THEN 1712 CALL get_val(griddim, component_flag=cf_out)
1716 var_coord_in = imiss
1717 var_coord_vol = imiss
1718 IF (trans_type ==
'vertint')
THEN 1719 IF (
PRESENT(lev_out))
THEN 1722 IF (
PRESENT(volgrid6d_coord_in))
THEN 1723 IF (
ASSOCIATED(volgrid6d_coord_in%voldati))
THEN 1726 IF (
SIZE(volgrid6d_coord_in%voldati,4) /= 1 .OR. &
1727 SIZE(volgrid6d_coord_in%voldati,5) /= 1)
THEN 1729 'volume providing constant input vertical coordinate must have & 1730 &only 1 time and 1 timerange')
1731 CALL init(volgrid6d_out)
1737 CALL get_val(this, output_levtype=output_levtype)
1739 IF (.NOT.
c_e(vcoord_var))
THEN 1741 'requested output level type '//
t2c(output_levtype%level1)// &
1742 ' does not correspond to any known physical variable for & 1743 &providing vertical coordinate')
1744 CALL init(volgrid6d_out)
1749 DO i = 1,
SIZE(volgrid6d_coord_in%var)
1750 IF (
convert(volgrid6d_coord_in%var(i)) == vcoord_var)
THEN 1756 IF (.NOT.
c_e(var_coord_in))
THEN 1758 'volume providing constant input vertical coordinate contains no & 1759 &variables matching output level type '//
t2c(output_levtype%level1))
1760 CALL init(volgrid6d_out)
1765 'Coordinate for vertint found in coord volume at position '// &
1771 CALL get_val(volgrid6d_coord_in%griddim, nx=nxc, ny=nyc)
1772 CALL get_val(volgrid6d_in%griddim, nx=nxi, ny=nyi)
1773 IF (nxc /= nxi .OR. nyc /= nyi)
THEN 1775 'volume providing constant input vertical coordinate must have & 1776 &the same grid as the input')
1778 'vertical coordinate: '//
t2c(nxc)//
'x'//
t2c(nyc)// &
1779 ', input volume: '//
t2c(nxi)//
'x'//
t2c(nyi))
1780 CALL init(volgrid6d_out)
1786 CALL get_val(this, input_levtype=input_levtype)
1788 (volgrid6d_coord_in%level(:)%level1 == input_levtype%level1) .AND. &
1789 (volgrid6d_coord_in%level(:)%level2 == input_levtype%level2)
1790 ulstart = firsttrue(mask_in)
1791 ulend = lasttrue(mask_in)
1792 IF (ulstart == 0 .OR. ulend == 0)
THEN 1794 'coordinate file does not contain levels of type '// &
1795 t2c(input_levtype%level1)//
'/'//
t2c(input_levtype%level2)// &
1796 ' specified for input data')
1797 CALL init(volgrid6d_out)
1802 coord_3d_in = volgrid6d_coord_in%voldati(:,:,ulstart:ulend,1,1,var_coord_in)
1804 IF (output_levtype%level1 == 103 .OR. &
1805 output_levtype%level1 == 108)
THEN 1807 spos = firsttrue(volgrid6d_coord_in%level(:) == vol7d_level_new(level1=1) .OR. &
1808 volgrid6d_coord_in%level(:) == vol7d_level_new(level1=1, level2=101))
1811 'output level '//
t2c(output_levtype%level1)// &
1812 ' requested, but height/press of surface not provided in coordinate file')
1813 CALL init(volgrid6d_out)
1817 DO k = 1,
SIZE(coord_3d_in,3)
1818 WHERE(
c_e(coord_3d_in(:,:,k)) .AND. &
1819 c_e(volgrid6d_coord_in%voldati(:,:,spos,1,1,var_coord_in)))
1820 coord_3d_in(:,:,k) = coord_3d_in(:,:,k) - &
1821 volgrid6d_coord_in%voldati(:,:,spos,1,1,var_coord_in)
1823 coord_3d_in(:,:,k) = rmiss
1831 IF (.NOT.
c_e(var_coord_in))
THEN 1833 CALL get_val(this, output_levtype=output_levtype)
1835 IF (
c_e(vcoord_var))
THEN 1836 DO i = 1,
SIZE(volgrid6d_in%var)
1837 IF (
convert(volgrid6d_in%var(i)) == vcoord_var)
THEN 1843 IF (
c_e(var_coord_vol))
THEN 1845 'Coordinate for vertint found in input volume at position '// &
1852 CALL init(volgrid6d_out, griddim=volgrid6d_in%griddim, &
1853 time_definition=volgrid6d_in%time_definition, categoryappend=categoryappend)
1854 IF (
c_e(var_coord_in))
THEN 1855 CALL init(grid_trans, this, lev_in=volgrid6d_in%level, lev_out=lev_out, &
1856 coord_3d_in=coord_3d_in, categoryappend=categoryappend)
1858 CALL init(grid_trans, this, lev_in=volgrid6d_in%level, lev_out=lev_out, &
1859 categoryappend=categoryappend)
1862 CALL get_val(grid_trans, output_level_auto=llev_out)
1863 IF (.NOT.
ASSOCIATED(llev_out)) llev_out => lev_out
1864 nlevel =
SIZE(llev_out)
1867 'volgrid6d_transform: vertint requested but lev_out not provided')
1868 CALL init(volgrid6d_out)
1874 CALL init(volgrid6d_out, griddim=griddim, &
1875 time_definition=volgrid6d_in%time_definition, categoryappend=categoryappend)
1876 CALL init(grid_trans, this, in=volgrid6d_in%griddim, out=volgrid6d_out%griddim, &
1877 maskgrid=maskgrid, maskbounds=maskbounds, categoryappend=categoryappend)
1881 IF (
c_e(grid_trans))
THEN 1883 CALL volgrid6d_alloc(volgrid6d_out, ntime=ntime, nlevel=nlevel, &
1884 ntimerange=ntimerange, nvar=nvar)
1886 IF (
PRESENT(decode))
THEN 1889 ldecode =
ASSOCIATED(volgrid6d_in%voldati)
1892 decode_loop:
DO i6 = 1,nvar
1893 DO i5 = 1, ntimerange
1896 IF (
c_e(volgrid6d_in%gaid(i3,i4,i5,i6)))
THEN 1897 ldecode = ldecode .OR. grid_id_readonly(volgrid6d_in%gaid(i3,i4,i5,i6))
1905 IF (
PRESENT(decode))
THEN 1906 IF (ldecode.NEQV.decode)
THEN 1908 'volgrid6d_transform: decode status forced to .TRUE. because driver does not allow copy')
1912 CALL volgrid6d_alloc_vol(volgrid6d_out, decode=ldecode)
1917 IF (trans_type ==
'vertint')
THEN 1920 "volgrid6d_transform: vertint to "//
t2c(nlevel)//
" levels")
1922 CALL compute(grid_trans, volgrid6d_in, volgrid6d_out, lev_out=llev_out, &
1925 CALL compute(grid_trans, volgrid6d_in, volgrid6d_out,
clone=
clone)
1928 IF (cf_out == 0)
THEN 1929 CALL wind_unrot(volgrid6d_out)
1930 ELSE IF (cf_out == 1)
THEN 1931 CALL wind_rot(volgrid6d_out)
1937 'volgrid6d_transform: transformation not valid')
1943 END SUBROUTINE volgrid6d_transform
1954 SUBROUTINE volgrid6dv_transform(this, griddim, volgrid6d_in, volgrid6d_out, &
1955 lev_out, volgrid6d_coord_in, maskgrid, maskbounds, clone, decode, categoryappend)
1956 TYPE(transform_def),
INTENT(in) :: this
1957 TYPE(griddim_def),
INTENT(in),
OPTIONAL :: griddim
1958 TYPE(volgrid6d),
INTENT(inout) :: volgrid6d_in(:)
1959 TYPE(volgrid6d),
POINTER :: volgrid6d_out(:)
1960 TYPE(vol7d_level),
INTENT(in),
OPTIONAL :: lev_out(:)
1961 TYPE(volgrid6d),
INTENT(in),
OPTIONAL :: volgrid6d_coord_in
1962 REAL,
INTENT(in),
OPTIONAL :: maskgrid(:,:)
1963 REAL,
INTENT(in),
OPTIONAL :: maskbounds(:)
1964 LOGICAL,
INTENT(in),
OPTIONAL :: clone
1965 LOGICAL,
INTENT(in),
OPTIONAL :: decode
1966 CHARACTER(len=*),
INTENT(in),
OPTIONAL :: categoryappend
1968 INTEGER :: i, stallo
1971 allocate(volgrid6d_out(
size(volgrid6d_in)),stat=stallo)
1972 if (stallo /= 0)
then 1973 call l4f_log(l4f_fatal,
"allocating memory")
1974 call raise_fatal_error()
1977 do i=1,
size(volgrid6d_in)
1978 call transform(this, griddim, volgrid6d_in(i), volgrid6d_out(i), &
1979 lev_out=lev_out, volgrid6d_coord_in=volgrid6d_coord_in, &
1980 maskgrid=maskgrid, maskbounds=maskbounds, &
1981 clone=
clone, decode=decode, categoryappend=categoryappend)
1984 END SUBROUTINE volgrid6dv_transform
1988 SUBROUTINE volgrid6d_v7d_transform_compute(this, volgrid6d_in, vol7d_out, &
1989 networkname, noconvert)
1990 TYPE(grid_transform),
INTENT(in) :: this
1991 type(volgrid6d),
INTENT(in) :: volgrid6d_in
1992 type(vol7d),
INTENT(inout) :: vol7d_out
1993 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: networkname
1994 LOGICAL,
OPTIONAL,
INTENT(in) :: noconvert
1996 INTEGER :: nntime, nana, ntime, ntimerange, nlevel, nvar, stallo
1997 INTEGER :: itime, itimerange, ivar, inetwork
1998 REAL,
ALLOCATABLE :: voldatir_out(:,:,:)
1999 TYPE(conv_func),
POINTER :: c_func(:)
2000 TYPE(datetime),
ALLOCATABLE :: validitytime(:,:)
2001 REAL,
POINTER :: voldatiin(:,:,:)
2004 call l4f_category_log(volgrid6d_in%category,l4f_debug,
"start volgrid6d_v7d_transform_compute")
2013 if (
present(networkname))
then 2014 call init(vol7d_out%network(1),name=networkname)
2016 call init(vol7d_out%network(1),name=
'generic')
2019 if (
associated(volgrid6d_in%timerange))
then 2020 ntimerange=
size(volgrid6d_in%timerange)
2021 vol7d_out%timerange=volgrid6d_in%timerange
2024 if (
associated(volgrid6d_in%time))
then 2025 ntime=
size(volgrid6d_in%time)
2027 if (vol7d_out%time_definition == volgrid6d_in%time_definition)
then 2030 vol7d_out%time=volgrid6d_in%time
2034 allocate (validitytime(ntime,ntimerange),stat=stallo)
2037 call raise_fatal_error()
2041 do itimerange=1,ntimerange
2042 if (vol7d_out%time_definition > volgrid6d_in%time_definition)
then 2043 validitytime(itime,itimerange) = &
2044 volgrid6d_in%time(itime) + timedelta_new(sec=volgrid6d_in%timerange(itimerange)%p1)
2046 validitytime(itime,itimerange) = &
2047 volgrid6d_in%time(itime) - timedelta_new(sec=volgrid6d_in%timerange(itimerange)%p1)
2052 nntime = count_distinct(reshape(validitytime,(/ntime*ntimerange/)), back=.true.)
2053 vol7d_out%time=pack_distinct(reshape(validitytime,(/ntime*ntimerange/)), nntime,back=.true.)
2058 IF (
ASSOCIATED(volgrid6d_in%level))
THEN 2059 nlevel =
SIZE(volgrid6d_in%level)
2060 vol7d_out%level=volgrid6d_in%level
2063 IF (
ASSOCIATED(volgrid6d_in%var))
THEN 2064 nvar =
SIZE(volgrid6d_in%var)
2065 IF (.NOT. optio_log(noconvert))
THEN 2066 CALL vargrib2varbufr(volgrid6d_in%var, vol7d_out%dativar%r, c_func)
2070 nana =
SIZE(vol7d_out%ana)
2073 IF (.NOT.
ASSOCIATED(volgrid6d_in%voldati))
THEN 2074 ALLOCATE(voldatiin(volgrid6d_in%griddim%dim%nx, volgrid6d_in%griddim%dim%ny, &
2078 ALLOCATE(voldatir_out(nana,1,nlevel),stat=stallo)
2079 IF (stallo /= 0)
THEN 2081 CALL raise_fatal_error()
2086 do itimerange=1,ntimerange
2098 CALL volgrid_get_vol_3d(volgrid6d_in, itime, itimerange, ivar, &
2101 CALL compute(this, voldatiin, voldatir_out, vol7d_out%dativar%r(ivar))
2103 if (vol7d_out%time_definition == volgrid6d_in%time_definition)
then 2104 vol7d_out%voldatir(:,itime,:,itimerange,ivar,inetwork) = &
2107 vol7d_out%voldatir(:,
index(vol7d_out%time,validitytime(itime,itimerange)),:,itimerange,ivar,inetwork)=&
2108 reshape(voldatir_out,(/nana,nlevel/))
2123 deallocate(voldatir_out)
2124 IF (.NOT.
ASSOCIATED(volgrid6d_in%voldati))
THEN 2125 DEALLOCATE(voldatiin)
2127 if (
allocated(validitytime))
deallocate(validitytime)
2130 IF (
ASSOCIATED(c_func))
THEN 2132 CALL compute(c_func(ivar), vol7d_out%voldatir(:,:,:,:,ivar,:))
2137 end SUBROUTINE volgrid6d_v7d_transform_compute
2146 SUBROUTINE volgrid6d_v7d_transform(this, volgrid6d_in, vol7d_out, v7d, &
2147 maskgrid, maskbounds, networkname, noconvert, find_index, categoryappend)
2148 TYPE(transform_def),
INTENT(in) :: this
2149 TYPE(volgrid6d),
INTENT(inout) :: volgrid6d_in
2150 TYPE(vol7d),
INTENT(out) :: vol7d_out
2151 TYPE(vol7d),
INTENT(in),
OPTIONAL :: v7d
2152 REAL,
INTENT(in),
OPTIONAL :: maskgrid(:,:)
2153 REAL,
INTENT(in),
OPTIONAL :: maskbounds(:)
2154 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: networkname
2155 LOGICAL,
OPTIONAL,
INTENT(in) :: noconvert
2156 PROCEDURE(basic_find_index),
POINTER,
OPTIONAL :: find_index
2157 CHARACTER(len=*),
INTENT(in),
OPTIONAL :: categoryappend
2159 type(grid_transform) :: grid_trans
2160 INTEGER :: ntime, ntimerange, nlevel, nvar, nana, time_definition, nnetwork, stallo
2161 INTEGER :: itime, itimerange, inetwork
2162 TYPE(datetime),
ALLOCATABLE :: validitytime(:,:)
2163 INTEGER,
ALLOCATABLE :: point_index(:)
2164 TYPE(vol7d) :: v7d_locana
2167 call l4f_category_log(volgrid6d_in%category,l4f_debug,
"start volgrid6d_v7d_transform")
2170 call vg6d_wind_unrot(volgrid6d_in)
2178 call get_val(this,time_definition=time_definition)
2179 if (.not.
c_e(time_definition))
then 2183 IF (
PRESENT(v7d))
THEN 2184 CALL vol7d_copy(v7d, v7d_locana)
2186 CALL init(v7d_locana)
2189 if (
associated(volgrid6d_in%timerange)) ntimerange=
size(volgrid6d_in%timerange)
2191 if (
associated(volgrid6d_in%time))
then 2193 ntime=
size(volgrid6d_in%time)
2195 if (time_definition /= volgrid6d_in%time_definition)
then 2198 allocate (validitytime(ntime,ntimerange),stat=stallo)
2201 call raise_fatal_error()
2205 do itimerange=1,ntimerange
2206 if (time_definition > volgrid6d_in%time_definition)
then 2207 validitytime(itime,itimerange) = &
2208 volgrid6d_in%time(itime) + timedelta_new(sec=volgrid6d_in%timerange(itimerange)%p1)
2210 validitytime(itime,itimerange) = &
2211 volgrid6d_in%time(itime) - timedelta_new(sec=volgrid6d_in%timerange(itimerange)%p1)
2216 ntime = count_distinct(reshape(validitytime,(/ntime*ntimerange/)), back=.true.)
2217 deallocate (validitytime)
2223 if (
associated(volgrid6d_in%level)) nlevel=
size(volgrid6d_in%level)
2224 if (
associated(volgrid6d_in%var)) nvar=
size(volgrid6d_in%var)
2226 CALL init(grid_trans, this, volgrid6d_in%griddim, v7d_locana, &
2227 maskgrid=maskgrid, maskbounds=maskbounds, find_index=find_index, &
2228 categoryappend=categoryappend)
2229 CALL init (vol7d_out,time_definition=time_definition)
2231 IF (
c_e(grid_trans))
THEN 2233 nana=
SIZE(v7d_locana%ana)
2234 CALL vol7d_alloc(vol7d_out, nana=nana, ntime=ntime, nlevel=nlevel, &
2235 ntimerange=ntimerange, ndativarr=nvar, nnetwork=nnetwork)
2236 vol7d_out%ana = v7d_locana%ana
2238 CALL get_val(grid_trans, output_point_index=point_index)
2239 IF (
ALLOCATED(point_index))
THEN 2241 CALL vol7d_alloc(vol7d_out, nanavari=1)
2242 CALL init(vol7d_out%anavar%i(1),
'B01192')
2245 CALL vol7d_alloc_vol(vol7d_out)
2247 IF (
ALLOCATED(point_index))
THEN 2248 DO inetwork = 1, nnetwork
2249 vol7d_out%volanai(:,1,inetwork) = point_index(:)
2252 CALL compute(grid_trans, volgrid6d_in, vol7d_out, networkname, noconvert)
2254 CALL l4f_log(l4f_error,
'vg6d_v7d_transform: transformation not valid')
2262 CALL vol7d_dballe_set_var_du(vol7d_out)
2267 END SUBROUTINE volgrid6d_v7d_transform
2278 SUBROUTINE volgrid6dv_v7d_transform(this, volgrid6d_in, vol7d_out, v7d, &
2279 maskgrid, maskbounds, networkname, noconvert, find_index, categoryappend)
2280 TYPE(transform_def),
INTENT(in) :: this
2281 TYPE(volgrid6d),
INTENT(inout) :: volgrid6d_in(:)
2282 TYPE(vol7d),
INTENT(out) :: vol7d_out
2283 TYPE(vol7d),
INTENT(in),
OPTIONAL :: v7d
2284 REAL,
INTENT(in),
OPTIONAL :: maskgrid(:,:)
2285 REAL,
INTENT(in),
OPTIONAL :: maskbounds(:)
2286 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: networkname
2287 LOGICAL,
OPTIONAL,
INTENT(in) :: noconvert
2288 PROCEDURE(basic_find_index),
POINTER,
OPTIONAL :: find_index
2289 CHARACTER(len=*),
INTENT(in),
OPTIONAL :: categoryappend
2292 TYPE(vol7d) :: v7dtmp
2296 CALL init(vol7d_out)
2298 DO i=1,
SIZE(volgrid6d_in)
2299 CALL transform(this, volgrid6d_in(i), v7dtmp, v7d=v7d, &
2300 maskgrid=maskgrid, maskbounds=maskbounds, &
2301 networkname=networkname, noconvert=noconvert, find_index=find_index, &
2302 categoryappend=categoryappend)
2303 CALL vol7d_append(vol7d_out, v7dtmp)
2306 END SUBROUTINE volgrid6dv_v7d_transform
2310 SUBROUTINE v7d_volgrid6d_transform_compute(this, vol7d_in, volgrid6d_out, networkname, gaid_template)
2311 TYPE(grid_transform),
INTENT(in) :: this
2312 type(vol7d),
INTENT(in) :: vol7d_in
2313 type(volgrid6d),
INTENT(inout) :: volgrid6d_out
2314 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: networkname
2315 TYPE(grid_id),
OPTIONAL,
INTENT(in) :: gaid_template
2317 integer :: nana, ntime, ntimerange, nlevel, nvar
2318 INTEGER :: ilevel, itime, itimerange, ivar, inetwork
2320 REAL,
POINTER :: voldatiout(:,:,:)
2321 type(vol7d_network) :: network
2322 TYPE(conv_func),
pointer :: c_func(:)
2326 'start v7d_volgrid6d_transform_compute')
2334 IF (
PRESENT(networkname))
THEN 2335 CALL init(network,name=networkname)
2336 inetwork =
index(vol7d_in%network,network)
2337 IF (inetwork <= 0)
THEN 2339 'network '//trim(networkname)//
' not found, first network will be transformed')
2347 if (
associated(vol7d_in%time))
then 2348 ntime=
size(vol7d_in%time)
2349 volgrid6d_out%time=vol7d_in%time
2352 if (
associated(vol7d_in%timerange))
then 2353 ntimerange=
size(vol7d_in%timerange)
2354 volgrid6d_out%timerange=vol7d_in%timerange
2357 if (
associated(vol7d_in%level))
then 2358 nlevel=
size(vol7d_in%level)
2359 volgrid6d_out%level=vol7d_in%level
2362 if (
associated(vol7d_in%dativar%r))
then 2363 nvar=
size(vol7d_in%dativar%r)
2364 CALL varbufr2vargrib(vol7d_in%dativar%r, volgrid6d_out%var, c_func, gaid_template)
2367 nana=
SIZE(vol7d_in%voldatir, 1)
2369 IF (.NOT.
ASSOCIATED(volgrid6d_out%voldati))
THEN 2370 ALLOCATE(voldatiout(volgrid6d_out%griddim%dim%nx, volgrid6d_out%griddim%dim%ny, &
2375 DO itimerange=1,ntimerange
2379 IF (
PRESENT(gaid_template))
THEN 2380 DO ilevel = 1, nlevel
2381 IF (any(
c_e(vol7d_in%voldatir(:,itime,ilevel,itimerange,ivar,inetwork))))
THEN 2382 CALL copy(gaid_template, volgrid6d_out%gaid(ilevel,itime,itimerange,ivar))
2384 volgrid6d_out%gaid(ilevel,itime,itimerange,ivar) = grid_id_new()
2390 IF (
ASSOCIATED(volgrid6d_out%voldati)) &
2391 CALL volgrid_get_vol_3d(volgrid6d_out, itime, itimerange, ivar, &
2394 CALL compute(this, &
2395 vol7d_in%voldatir(:,itime,:,itimerange,ivar,inetwork), voldatiout, &
2396 vol7d_in%dativar%r(ivar))
2398 IF (
ASSOCIATED(c_func))
THEN 2399 CALL compute(c_func(ivar), voldatiout(:,:,:))
2402 CALL volgrid_set_vol_3d(volgrid6d_out, itime, itimerange, ivar, &
2409 IF (.NOT.
ASSOCIATED(volgrid6d_out%voldati))
THEN 2410 DEALLOCATE(voldatiout)
2412 IF (
ASSOCIATED(c_func))
THEN 2416 END SUBROUTINE v7d_volgrid6d_transform_compute
2425 SUBROUTINE v7d_volgrid6d_transform(this, griddim, vol7d_in, volgrid6d_out, &
2426 networkname, gaid_template, categoryappend)
2427 TYPE(transform_def),
INTENT(in) :: this
2428 TYPE(griddim_def),
INTENT(in),
OPTIONAL :: griddim
2430 TYPE(vol7d),
INTENT(inout) :: vol7d_in
2431 TYPE(volgrid6d),
INTENT(out) :: volgrid6d_out
2432 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: networkname
2433 TYPE(grid_id),
OPTIONAL,
INTENT(in) :: gaid_template
2434 CHARACTER(len=*),
INTENT(in),
OPTIONAL :: categoryappend
2436 type(grid_transform) :: grid_trans
2437 integer :: ntime, ntimerange, nlevel, nvar
2443 CALL vol7d_alloc_vol(vol7d_in)
2444 ntime=
SIZE(vol7d_in%time)
2445 ntimerange=
SIZE(vol7d_in%timerange)
2446 nlevel=
SIZE(vol7d_in%level)
2448 if (
associated(vol7d_in%dativar%r)) nvar=
size(vol7d_in%dativar%r)
2451 CALL l4f_log(l4f_error, &
2452 "trying to transform a vol7d object incomplete or without real variables")
2453 CALL init(volgrid6d_out)
2458 CALL init(grid_trans, this, vol7d_in, griddim, categoryappend=categoryappend)
2459 CALL init(volgrid6d_out, griddim, time_definition=vol7d_in%time_definition, &
2460 categoryappend=categoryappend)
2462 IF (
c_e(grid_trans))
THEN 2464 CALL volgrid6d_alloc(volgrid6d_out, griddim%dim, ntime=ntime, nlevel=nlevel, &
2465 ntimerange=ntimerange, nvar=nvar)
2467 CALL volgrid6d_alloc_vol(volgrid6d_out, decode=.true.)
2469 CALL compute(grid_trans, vol7d_in, volgrid6d_out, networkname, gaid_template)
2471 CALL vg6d_wind_rot(volgrid6d_out)
2474 CALL l4f_log(l4f_error,
'v7d_vg6d_transform: transformation not valid')
2480 END SUBROUTINE v7d_volgrid6d_transform
2484 SUBROUTINE v7d_v7d_transform_compute(this, vol7d_in, vol7d_out, lev_out, &
2486 TYPE(grid_transform),
INTENT(in) :: this
2487 type(vol7d),
INTENT(in) :: vol7d_in
2488 type(vol7d),
INTENT(inout) :: vol7d_out
2489 TYPE(vol7d_level),
INTENT(in),
OPTIONAL :: lev_out(:)
2490 INTEGER,
INTENT(in),
OPTIONAL :: var_coord_vol
2492 INTEGER :: itime, itimerange, ilevel, ivar, inetwork, &
2493 levshift, levused, lvar_coord_vol, spos
2494 REAL,
ALLOCATABLE :: coord_3d_in(:,:,:)
2495 TYPE(vol7d_level) :: output_levtype
2497 lvar_coord_vol = optio_i(var_coord_vol)
2498 vol7d_out%time(:) = vol7d_in%time(:)
2499 vol7d_out%timerange(:) = vol7d_in%timerange(:)
2500 IF (
PRESENT(lev_out))
THEN 2501 vol7d_out%level(:) = lev_out(:)
2503 vol7d_out%level(:) = vol7d_in%level(:)
2505 vol7d_out%network(:) = vol7d_in%network(:)
2506 IF (
ASSOCIATED(vol7d_in%dativar%r))
THEN 2507 vol7d_out%dativar%r(:) = vol7d_in%dativar%r(:)
2509 CALL get_val(this, levshift=levshift, levused=levused)
2511 IF (
c_e(lvar_coord_vol))
THEN 2512 CALL get_val(this%trans, output_levtype=output_levtype)
2513 IF (output_levtype%level1 == 103 .OR. output_levtype%level1 == 108)
THEN 2514 spos = firsttrue(vol7d_in%level(:) == vol7d_level_new(1))
2516 CALL l4f_log(l4f_error, &
2517 'output level '//
t2c(output_levtype%level1)// &
2518 ' requested, but height/press of surface not provided in volume')
2520 IF (.NOT.
c_e(levshift) .AND. .NOT.
c_e(levused))
THEN 2521 CALL l4f_log(l4f_error, &
2522 'internal inconsistence, levshift and levused undefined when they should be')
2524 ALLOCATE(coord_3d_in(
SIZE(vol7d_in%ana),1,
SIZE(vol7d_in%level)))
2529 DO inetwork = 1,
SIZE(vol7d_in%network)
2530 DO ivar = 1,
SIZE(vol7d_in%dativar%r)
2531 DO itimerange = 1,
SIZE(vol7d_in%timerange)
2532 DO itime = 1,
SIZE(vol7d_in%time)
2535 IF (
c_e(lvar_coord_vol))
THEN 2538 coord_3d_in(:,:,levshift+1:levshift+levused) = rmiss
2540 DO ilevel = levshift+1, levshift+levused
2541 WHERE(
c_e(vol7d_in%voldatir(:,itime:itime,ilevel,itimerange,lvar_coord_vol,inetwork)) .AND. &
2542 c_e(vol7d_in%voldatir(:,itime:itime,spos,itimerange,lvar_coord_vol,inetwork)))
2543 coord_3d_in(:,:,ilevel) = vol7d_in%voldatir(:,itime:itime,ilevel,itimerange,lvar_coord_vol,inetwork) - &
2544 vol7d_in%voldatir(:,itime:itime,spos,itimerange,lvar_coord_vol,inetwork)
2546 coord_3d_in(:,:,ilevel) = rmiss
2550 CALL compute(this, &
2551 vol7d_in%voldatir(:,itime,:,itimerange,ivar,inetwork), &
2552 vol7d_out%voldatir(:,itime:itime,:,itimerange,ivar,inetwork), &
2553 var=vol7d_in%dativar%r(ivar), &
2554 coord_3d_in=coord_3d_in)
2556 CALL compute(this, &
2557 vol7d_in%voldatir(:,itime,:,itimerange,ivar,inetwork), &
2558 vol7d_out%voldatir(:,itime:itime,:,itimerange,ivar,inetwork), &
2559 var=vol7d_in%dativar%r(ivar), &
2560 coord_3d_in=vol7d_in%voldatir(:,itime:itime,:,itimerange, &
2561 lvar_coord_vol,inetwork))
2564 CALL compute(this, &
2565 vol7d_in%voldatir(:,itime,:,itimerange,ivar,inetwork), &
2566 vol7d_out%voldatir(:,itime:itime,:,itimerange,ivar,inetwork), &
2567 var=vol7d_in%dativar%r(ivar))
2576 END SUBROUTINE v7d_v7d_transform_compute
2586 SUBROUTINE v7d_v7d_transform(this, vol7d_in, vol7d_out, v7d, maskbounds, &
2587 lev_out, vol7d_coord_in, categoryappend)
2588 TYPE(transform_def),
INTENT(in) :: this
2589 TYPE(vol7d),
INTENT(inout) :: vol7d_in
2590 TYPE(vol7d),
INTENT(out) :: vol7d_out
2591 TYPE(vol7d),
INTENT(in),
OPTIONAL :: v7d
2592 REAL,
INTENT(in),
OPTIONAL :: maskbounds(:)
2593 TYPE(vol7d_level),
INTENT(in),
OPTIONAL,
TARGET :: lev_out(:)
2594 TYPE(vol7d),
INTENT(in),
OPTIONAL :: vol7d_coord_in
2595 CHARACTER(len=*),
INTENT(in),
OPTIONAL :: categoryappend
2597 INTEGER :: nvar, inetwork
2598 TYPE(grid_transform) :: grid_trans
2599 TYPE(vol7d_level),
POINTER :: llev_out(:)
2600 TYPE(vol7d_level) :: input_levtype, output_levtype
2601 TYPE(vol7d_var) :: vcoord_var
2602 REAL,
ALLOCATABLE :: coord_3d_in(:,:,:)
2603 INTEGER :: var_coord_in, var_coord_vol, i, k, ulstart, ulend, spos
2604 INTEGER,
ALLOCATABLE :: point_index(:)
2605 TYPE(vol7d) :: v7d_locana, vol7d_tmpana
2606 CHARACTER(len=80) :: trans_type
2607 LOGICAL,
ALLOCATABLE :: mask_in(:), point_mask(:)
2609 CALL vol7d_alloc_vol(vol7d_in)
2611 IF (
ASSOCIATED(vol7d_in%dativar%r)) nvar=
SIZE(vol7d_in%dativar%r)
2613 CALL init(v7d_locana)
2614 IF (
PRESENT(v7d)) v7d_locana = v7d
2615 CALL init(vol7d_out, time_definition=vol7d_in%time_definition)
2617 CALL get_val(this, trans_type=trans_type)
2619 var_coord_vol = imiss
2620 IF (trans_type ==
'vertint')
THEN 2622 IF (
PRESENT(lev_out))
THEN 2626 IF (
PRESENT(vol7d_coord_in))
THEN 2627 IF (
ASSOCIATED(vol7d_coord_in%voldatir) .AND. &
2628 ASSOCIATED(vol7d_coord_in%dativar%r))
THEN 2631 IF (
SIZE(vol7d_coord_in%voldatir,2) /= 1 .OR. &
2632 SIZE(vol7d_coord_in%voldatir,4) /= 1 .OR. &
2633 SIZE(vol7d_coord_in%voldatir,6) /= 1)
THEN 2634 CALL l4f_log(l4f_error, &
2635 'volume providing constant input vertical coordinate must have & 2636 &only 1 time, 1 timerange and 1 network')
2642 CALL get_val(this, output_levtype=output_levtype)
2644 IF (.NOT.
c_e(vcoord_var))
THEN 2645 CALL l4f_log(l4f_error, &
2646 'requested output level type '//
t2c(output_levtype%level1)// &
2647 ' does not correspond to any known physical variable for & 2648 &providing vertical coordinate')
2653 var_coord_in =
index(vol7d_coord_in%dativar%r, vcoord_var)
2655 IF (var_coord_in <= 0)
THEN 2656 CALL l4f_log(l4f_error, &
2657 'volume providing constant input vertical coordinate contains no & 2658 &real variables matching output level type '//
t2c(output_levtype%level1))
2662 CALL l4f_log(l4f_info, &
2663 'Coordinate for vertint found in coord volume at position '// &
2667 CALL get_val(this, input_levtype=input_levtype)
2669 (vol7d_coord_in%level(:)%level1 == input_levtype%level1) .AND. &
2670 (vol7d_coord_in%level(:)%level2 == input_levtype%level2)
2671 ulstart = firsttrue(mask_in)
2672 ulend = lasttrue(mask_in)
2673 IF (ulstart == 0 .OR. ulend == 0)
THEN 2674 CALL l4f_log(l4f_error, &
2675 'coordinate file does not contain levels of type '// &
2676 t2c(input_levtype%level1)//
'/'//
t2c(input_levtype%level2)// &
2677 ' specified for input data')
2682 coord_3d_in = vol7d_coord_in%voldatir(:,1:1,ulstart:ulend,1,var_coord_in,1)
2684 IF (output_levtype%level1 == 103 &
2685 .OR. output_levtype%level1 == 108)
THEN 2686 spos = firsttrue(vol7d_coord_in%level(:) == vol7d_level_new(1))
2688 CALL l4f_log(l4f_error, &
2689 'output level '//
t2c(output_levtype%level1)// &
2690 ' requested, but height/press of surface not provided in coordinate file')
2694 DO k = 1,
SIZE(coord_3d_in,3)
2695 WHERE(
c_e(coord_3d_in(:,:,k)) .AND. &
2696 c_e(vol7d_coord_in%voldatir(:,1:1,spos,1,var_coord_in,1)))
2697 coord_3d_in(:,:,k) = coord_3d_in(:,:,k) - &
2698 vol7d_coord_in%voldatir(:,1:1,spos,1,var_coord_in,1)
2700 coord_3d_in(:,:,k) = rmiss
2708 IF (var_coord_in <= 0)
THEN 2710 CALL get_val(this, output_levtype=output_levtype)
2712 IF (
c_e(vcoord_var))
THEN 2713 DO i = 1,
SIZE(vol7d_in%dativar%r)
2714 IF (vol7d_in%dativar%r(i) == vcoord_var)
THEN 2720 IF (
c_e(var_coord_vol))
THEN 2721 CALL l4f_log(l4f_info, &
2722 'Coordinate for vertint found in input volume at position '// &
2729 IF (var_coord_in > 0)
THEN 2730 CALL init(grid_trans, this, lev_in=vol7d_in%level, lev_out=lev_out, &
2731 coord_3d_in=coord_3d_in, categoryappend=categoryappend)
2733 CALL init(grid_trans, this, lev_in=vol7d_in%level, lev_out=lev_out, &
2734 categoryappend=categoryappend)
2737 CALL get_val(grid_trans, output_level_auto=llev_out)
2738 IF (.NOT.
associated(llev_out)) llev_out => lev_out
2740 IF (
c_e(grid_trans)) then
2742 CALL vol7d_alloc(vol7d_out, nana=
SIZE(vol7d_in%ana), &
2743 ntime=
SIZE(vol7d_in%time), ntimerange=
SIZE(vol7d_in%timerange), &
2744 nlevel=
SIZE(llev_out), nnetwork=
SIZE(vol7d_in%network), ndativarr=nvar)
2745 vol7d_out%ana(:) = vol7d_in%ana(:)
2747 CALL vol7d_alloc_vol(vol7d_out)
2752 CALL compute(grid_trans, vol7d_in, vol7d_out, llev_out, &
2753 var_coord_vol=var_coord_vol)
2755 CALL l4f_log(l4f_error,
'v7d_v7d_transform: transformation not valid')
2759 CALL l4f_log(l4f_error, &
2760 'v7d_v7d_transform: vertint requested but lev_out not provided')
2766 CALL init(grid_trans, this, vol7d_in, v7d_locana, maskbounds=maskbounds, &
2767 categoryappend=categoryappend)
2770 IF (
c_e(grid_trans)) then
2772 CALL vol7d_alloc(vol7d_out, nana=
SIZE(v7d_locana%ana), &
2773 ntime=
SIZE(vol7d_in%time), ntimerange=
SIZE(vol7d_in%timerange), &
2774 nlevel=
SIZE(vol7d_in%level), nnetwork=
SIZE(vol7d_in%network), ndativarr=nvar)
2775 vol7d_out%ana = v7d_locana%ana
2777 CALL get_val(grid_trans, point_mask=point_mask, output_point_index=point_index)
2779 IF (
ALLOCATED(point_index))
THEN 2780 CALL vol7d_alloc(vol7d_out, nanavari=1)
2781 CALL init(vol7d_out%anavar%i(1),
'B01192')
2784 CALL vol7d_alloc_vol(vol7d_out)
2786 IF (
ALLOCATED(point_index))
THEN 2787 DO inetwork = 1,
SIZE(vol7d_in%network)
2788 vol7d_out%volanai(:,1,inetwork) = point_index(:)
2791 CALL compute(grid_trans, vol7d_in, vol7d_out)
2793 IF (
ALLOCATED(point_mask))
THEN 2794 IF (
SIZE(point_mask) /=
SIZE(vol7d_in%ana))
THEN 2795 CALL l4f_log(l4f_warn, &
2796 'v7d_v7d_transform: inconsistency in point size: '//
t2c(
SIZE(point_mask)) &
2797 //
':'//
t2c(
SIZE(vol7d_in%ana)))
2800 CALL l4f_log(l4f_debug,
'v7d_v7d_transform: merging ana from in to out')
2802 CALL vol7d_copy(vol7d_in, vol7d_tmpana, &
2803 lana=point_mask, lnetwork=(/.true./), &
2804 ltime=(/.false./), ltimerange=(/.false./), llevel=(/.false./))
2805 CALL vol7d_append(vol7d_out, vol7d_tmpana)
2810 CALL l4f_log(l4f_error,
'v7d_v7d_transform: transformation not valid')
2817 IF (.NOT.
PRESENT(v7d))
CALL delete(v7d_locana)
2819 END SUBROUTINE v7d_v7d_transform
2829 subroutine vg6d_wind_unrot(this)
2830 type(volgrid6d) :: this
2832 integer :: component_flag
2834 call get_val(this%griddim,component_flag=component_flag)
2836 if (component_flag == 1)
then 2838 "unrotating vector components")
2839 call vg6d_wind__un_rot(this,.false.)
2840 call set_val(this%griddim,component_flag=0)
2843 "no need to unrotate vector components")
2846 end subroutine vg6d_wind_unrot
2854 subroutine vg6d_wind_rot(this)
2855 type(volgrid6d) :: this
2857 integer :: component_flag
2859 call get_val(this%griddim,component_flag=component_flag)
2861 if (component_flag == 0)
then 2863 "rotating vector components")
2864 call vg6d_wind__un_rot(this,.true.)
2865 call set_val(this%griddim,component_flag=1)
2868 "no need to rotate vector components")
2871 end subroutine vg6d_wind_rot
2875 SUBROUTINE vg6d_wind__un_rot(this,rot)
2876 TYPE(volgrid6d) :: this
2879 INTEGER :: i, j, k, l, a11, a12, a21, a22, stallo
2880 double precision,
pointer :: rot_mat(:,:,:)
2881 real,
allocatable :: tmp_arr(:,:)
2882 REAL,
POINTER :: voldatiu(:,:), voldativ(:,:)
2883 INTEGER,
POINTER :: iu(:), iv(:)
2885 IF (.NOT.
ASSOCIATED(this%var))
THEN 2887 "trying to unrotate an incomplete volgrid6d object")
2888 CALL raise_fatal_error()
2892 CALL volgrid6d_var_hor_comp_index(this%var, iu, iv)
2893 IF (.NOT.
ASSOCIATED(iu))
THEN 2895 "unrotation impossible")
2896 CALL raise_fatal_error()
2901 ALLOCATE(tmp_arr(this%griddim%dim%nx, this%griddim%dim%ny),stat=stallo)
2902 IF (stallo /= 0)
THEN 2904 CALL raise_fatal_error()
2907 IF (.NOT.
ASSOCIATED(this%voldati))
THEN 2908 ALLOCATE(voldatiu(this%griddim%dim%nx, this%griddim%dim%ny), &
2909 voldativ(this%griddim%dim%nx, this%griddim%dim%ny))
2912 CALL griddim_unproj(this%griddim)
2913 CALL wind_unrot(this%griddim, rot_mat)
2926 DO k = 1,
SIZE(this%timerange)
2927 DO j = 1,
SIZE(this%time)
2928 DO i = 1,
SIZE(this%level)
2930 CALL volgrid_get_vol_2d(this, i, j, k, iu(l), voldatiu)
2931 CALL volgrid_get_vol_2d(this, i, j, k, iv(l), voldativ)
2937 WHERE(voldatiu /= rmiss .AND. voldativ /= rmiss)
2938 tmp_arr(:,:) =
real(voldatiu(:,:)*rot_mat(:,:,a11) + &
2939 voldativ(:,:)*rot_mat(:,:,a12))
2940 voldativ(:,:) =
real(voldatiu(:,:)*rot_mat(:,:,a21) + &
2941 voldativ(:,:)*rot_mat(:,:,a22))
2942 voldatiu(:,:) = tmp_arr(:,:)
2948 CALL volgrid_set_vol_2d(this, i, j, k, iu(l), voldatiu)
2949 CALL volgrid_set_vol_2d(this, i, j, k, iv(l), voldativ)
2955 IF (.NOT.
ASSOCIATED(this%voldati))
THEN 2956 DEALLOCATE(voldatiu, voldativ)
2958 DEALLOCATE(rot_mat, tmp_arr, iu, iv)
2960 END SUBROUTINE vg6d_wind__un_rot
3006 subroutine vg6d_c2a (this)
3008 TYPE(volgrid6d),
INTENT(inout) :: this(:)
3010 integer :: ngrid,igrid,jgrid,ugrid,vgrid,tgrid
3011 doubleprecision :: xmin, xmax, ymin, ymax
3012 doubleprecision :: xmin_t, xmax_t, ymin_t, ymax_t
3013 doubleprecision :: step_lon_t,step_lat_t
3014 character(len=80) :: type_t,type
3015 TYPE(griddim_def):: griddim_t
3021 call init(griddim_t)
3023 call get_val(this(igrid)%griddim,xmin=xmin_t, xmax=xmax_t, ymin=ymin_t, ymax=ymax_t,proj_type=type_t)
3024 step_lon_t=(xmax_t-xmin_t)/dble(this(igrid)%griddim%dim%nx-1)
3025 step_lat_t=(ymax_t-ymin_t)/dble(this(igrid)%griddim%dim%ny-1)
3038 if (this(igrid)%griddim == this(jgrid)%griddim ) cycle
3040 if (this(igrid)%griddim%dim%nx == this(jgrid)%griddim%dim%nx .and. &
3041 this(igrid)%griddim%dim%ny == this(jgrid)%griddim%dim%ny )
then 3043 call get_val(this(jgrid)%griddim,xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,proj_type=type)
3045 if (type_t /=
type )cycle
3051 call l4f_category_log(this(igrid)%category,l4f_debug,
"diff coordinate lon"//&
3052 to_char(
abs(xmin - (xmin_t+step_lon_t/2.d0)))//&
3054 call l4f_category_log(this(igrid)%category,l4f_debug,
"diff coordinate lat"//&
3055 to_char(
abs(ymin - (ymin_t+step_lat_t/2.d0)))//&
3056 to_char(
abs(ymax - (ymax_t+step_lat_t/2.d0))))
3059 if (
abs(xmin - (xmin_t+step_lon_t/2.d0)) < 1.d-3 .and.
abs(xmax - (xmax_t+step_lon_t/2.d0)) < 1.d-3 )
then 3060 if (
abs(ymin - ymin_t) < 1.d-3 .and.
abs(ymax - ymax_t) < 1.d-3 )
then 3076 if (
abs(ymin - (ymin_t+step_lat_t/2.d0)) < 1.d-3 .and.
abs(ymax - (ymax_t+step_lat_t/2.d0)) < 1.d-3 )
then 3077 if (
abs(xmin - xmin_t) < 1.d-3 .and.
abs(xmax - xmax_t) < 1.d-3 )
then 3092 call l4f_category_log(this(igrid)%category,l4f_debug,
"C grid: test U and V"//&
3096 call l4f_category_log(this(igrid)%category,l4f_debug,
"UV diff coordinate lon"//&
3097 to_char(
abs(xmin_t - xmin)-step_lon_t/2.d0)//&
3099 call l4f_category_log(this(igrid)%category,l4f_debug,
"UV diff coordinate lat"//&
3100 to_char(
abs(ymin_t - ymin) -step_lat_t/2.d0)//&
3104 if (
abs(ymin - (ymin_t+step_lat_t/2.d0)) < 2.d-3 .and.
abs(ymax - (ymax_t+step_lat_t/2.d0)) < 2.d-3 )
then 3105 if (
abs(xmin_t - (xmin+step_lon_t/2.d0)) < 2.d-3 .and.
abs(xmax_t - (xmax+step_lon_t/2.d0)) < 2.d-3 )
then 3108 call l4f_category_log(this(igrid)%category,l4f_debug,
"C grid: found U and V case up and right")
3114 call init(griddim_t,xmin=xmin, xmax=xmax, ymin=ymin_t, ymax=ymax_t)
3121 if (
c_e(ugrid))
then 3126 call vg6d_c2a_grid(this(ugrid),this(tgrid)%griddim,cgrid=1)
3128 call vg6d_c2a_grid(this(ugrid),griddim_t,cgrid=1)
3130 call vg6d_c2a_mat(this(ugrid),cgrid=1)
3133 if (
c_e(vgrid))
then 3138 call vg6d_c2a_grid(this(vgrid),this(tgrid)%griddim,cgrid=2)
3140 call vg6d_c2a_grid(this(vgrid),griddim_t,cgrid=2)
3142 call vg6d_c2a_mat(this(vgrid),cgrid=2)
3152 end subroutine vg6d_c2a
3156 subroutine vg6d_c2a_grid(this,griddim_t,cgrid)
3158 type(volgrid6d),
intent(inout) :: this
3159 type(griddim_def),
intent(in),
optional :: griddim_t
3160 integer,
intent(in) :: cgrid
3162 doubleprecision :: xmin, xmax, ymin, ymax
3163 doubleprecision :: step_lon,step_lat
3166 if (
present(griddim_t))
then 3168 call get_val(griddim_t,xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)
3169 call set_val(this%griddim,xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)
3171 CALL griddim_setsteps(this%griddim)
3180 call l4f_category_log(this%category,l4f_debug,
"C grid: T points, nothing to do")
3187 call l4f_category_log(this%category,l4f_debug,
"C grid: U points, we need interpolation")
3190 call get_val(this%griddim, xmin=xmin, xmax=xmax)
3191 step_lon=(xmax-xmin)/dble(this%griddim%dim%nx-1)
3192 xmin=xmin-step_lon/2.d0
3193 xmax=xmax-step_lon/2.d0
3194 call set_val(this%griddim, xmin=xmin, xmax=xmax)
3196 CALL griddim_setsteps(this%griddim)
3201 call l4f_category_log(this%category,l4f_debug,
"C grid: V points, we need interpolation")
3204 call get_val(this%griddim, ymin=ymin, ymax=ymax)
3205 step_lat=(ymax-ymin)/dble(this%griddim%dim%ny-1)
3206 ymin=ymin-step_lat/2.d0
3207 ymax=ymax-step_lat/2.d0
3208 call set_val(this%griddim, ymin=ymin, ymax=ymax)
3210 CALL griddim_setsteps(this%griddim)
3215 call raise_fatal_error ()
3222 call griddim_unproj(this%griddim)
3225 end subroutine vg6d_c2a_grid
3228 subroutine vg6d_c2a_mat(this,cgrid)
3231 integer,
intent(in) :: cgrid
3233 INTEGER :: i, j, k, iv, stallo
3234 REAL,
ALLOCATABLE :: tmp_arr(:,:)
3235 REAL,
POINTER :: voldatiuv(:,:)
3238 IF (cgrid == 0)
RETURN 3239 IF (cgrid /= 1 .AND. cgrid /= 2)
THEN 3241 trim(
to_char(cgrid))//
" not known")
3247 ALLOCATE(tmp_arr(this%griddim%dim%nx, this%griddim%dim%ny),stat=stallo)
3249 call l4f_log(l4f_fatal,
"allocating memory")
3250 call raise_fatal_error()
3254 IF (.NOT.
ASSOCIATED(this%voldati))
THEN 3255 ALLOCATE(voldatiuv(this%griddim%dim%nx, this%griddim%dim%ny), stat=stallo)
3256 IF (stallo /= 0)
THEN 3257 CALL l4f_log(l4f_fatal,
"allocating memory")
3258 CALL raise_fatal_error()
3262 IF (cgrid == 1)
THEN 3263 DO iv = 1,
SIZE(this%var)
3264 DO k = 1,
SIZE(this%timerange)
3265 DO j = 1,
SIZE(this%time)
3266 DO i = 1,
SIZE(this%level)
3267 tmp_arr(:,:) = rmiss
3268 CALL volgrid_get_vol_2d(this, i, j, k, iv, voldatiuv)
3271 WHERE(voldatiuv(1,:) /= rmiss .AND. voldatiuv(2,:) /= rmiss)
3272 tmp_arr(1,:) = voldatiuv(1,:) - (voldatiuv(2,:) - voldatiuv(1,:)) / 2.
3276 WHERE(voldatiuv(1:this%griddim%dim%nx-1,:) /= rmiss .AND. &
3277 voldatiuv(2:this%griddim%dim%nx,:) /= rmiss)
3278 tmp_arr(2:this%griddim%dim%nx,:) = &
3279 (voldatiuv(1:this%griddim%dim%nx-1,:) + &
3280 voldatiuv(2:this%griddim%dim%nx,:)) / 2.
3283 voldatiuv(:,:) = tmp_arr
3284 CALL volgrid_set_vol_2d(this, i, j, k, iv, voldatiuv)
3290 ELSE IF (cgrid == 2)
THEN 3291 DO iv = 1,
SIZE(this%var)
3292 DO k = 1,
SIZE(this%timerange)
3293 DO j = 1,
SIZE(this%time)
3294 DO i = 1,
SIZE(this%level)
3295 tmp_arr(:,:) = rmiss
3296 CALL volgrid_get_vol_2d(this, i, j, k, iv, voldatiuv)
3299 WHERE(voldatiuv(:,1) /= rmiss .AND. voldatiuv(:,2) /= rmiss)
3300 tmp_arr(:,1) = voldatiuv(:,1) - (voldatiuv(:,2) - voldatiuv(:,1)) / 2.
3304 WHERE(voldatiuv(:,1:this%griddim%dim%ny-1) /= rmiss .AND. &
3305 voldatiuv(:,2:this%griddim%dim%ny) /= rmiss)
3306 tmp_arr(:,2:this%griddim%dim%ny) = &
3307 (voldatiuv(:,1:this%griddim%dim%ny-1) + &
3308 voldatiuv(:,2:this%griddim%dim%ny)) / 2.
3311 voldatiuv(:,:) = tmp_arr
3312 CALL volgrid_set_vol_2d(this, i, j, k, iv, voldatiuv)
3319 IF (.NOT.
ASSOCIATED(this%voldati))
THEN 3320 DEALLOCATE(voldatiuv)
3322 DEALLOCATE (tmp_arr)
3324 end subroutine vg6d_c2a_mat
3330 subroutine display_volgrid6d (this)
3339 print*,
"----------------------- volgrid6d display ---------------------" 3342 IF (
ASSOCIATED(this%time))
then 3343 print*,
"---- time vector ----" 3344 print*,
"elements=",
size(this%time)
3345 do i=1,
size(this%time)
3350 IF (
ASSOCIATED(this%timerange))
then 3351 print*,
"---- timerange vector ----" 3352 print*,
"elements=",
size(this%timerange)
3353 do i=1,
size(this%timerange)
3354 call display(this%timerange(i))
3358 IF (
ASSOCIATED(this%level))
then 3359 print*,
"---- level vector ----" 3360 print*,
"elements=",
size(this%level)
3361 do i=1,
size(this%level)
3366 IF (
ASSOCIATED(this%var))
then 3367 print*,
"---- var vector ----" 3368 print*,
"elements=",
size(this%var)
3369 do i=1,
size(this%var)
3374 IF (
ASSOCIATED(this%gaid))
then 3375 print*,
"---- gaid vector (present mask only) ----" 3376 print*,
"elements=",shape(this%gaid)
3377 print*,
c_e(reshape(this%gaid,(/
SIZE(this%gaid)/)))
3380 print*,
"--------------------------------------------------------------" 3383 end subroutine display_volgrid6d
3389 subroutine display_volgrid6dv (this)
3394 print*,
"----------------------- volgrid6d vector ---------------------" 3396 print*,
"elements=",
size(this)
3401 call l4f_category_log(this(i)%category,l4f_debug,
"ora mostro il vettore volgrid6d" )
3407 print*,
"--------------------------------------------------------------" 3409 end subroutine display_volgrid6dv
3414 subroutine vg6dv_rounding(vg6din,vg6dout,level,timerange,nostatproc,merge)
3416 type(
volgrid6d),
intent(out),
pointer :: vg6dout(:)
3419 logical,
intent(in),
optional :: merge
3420 logical,
intent(in),
optional :: nostatproc
3424 allocate(vg6dout(
size(vg6din)))
3426 do i = 1,
size(vg6din)
3427 call vg6d_rounding(vg6din(i),vg6dout(i),level,timerange,nostatproc,merge)
3430 end subroutine vg6dv_rounding
3443 subroutine vg6d_rounding(vg6din,vg6dout,level,timerange,nostatproc,merge)
3448 logical,
intent(in),
optional :: merge
3450 logical,
intent(in),
optional :: nostatproc
3452 integer :: ilevel,itimerange
3453 type(
vol7d_level) :: roundlevel(size(vg6din%level))
3456 roundlevel=vg6din%level
3458 if (
present(level))
then 3459 do ilevel = 1,
size(vg6din%level)
3460 if ((any(vg6din%level(ilevel) .almosteq. level)))
then 3461 roundlevel(ilevel)=level(1)
3466 roundtimerange=vg6din%timerange
3468 if (
present(timerange))
then 3469 do itimerange = 1,
size(vg6din%timerange)
3470 if ((any(vg6din%timerange(itimerange) .almosteq. timerange)))
then 3471 roundtimerange(itimerange)=timerange(1)
3478 if (optio_log(nostatproc))
then 3479 roundtimerange(:)%timerange=254
3480 roundtimerange(:)%p2=0
3484 call vg6d_reduce(vg6din,vg6dout,roundlevel,roundtimerange,merge)
3486 end subroutine vg6d_rounding
3496 subroutine vg6d_reduce(vg6din,vg6dout,roundlevel,roundtimerange,merge)
3501 logical,
intent(in),
optional :: merge
3503 integer :: nlevel,ntime,ntimerange,nvar,ilevel,itimerange,ivar,indl,indt,itime,nx,ny
3504 real,
allocatable :: vol2d(:,:)
3506 nx=vg6din%griddim%dim%nx
3507 ny=vg6din%griddim%dim%ny
3508 nlevel=count_distinct(roundlevel,back=.true.)
3509 ntime=
size(vg6din%time)
3510 ntimerange=count_distinct(roundtimerange,back=.true.)
3511 nvar=
size(vg6din%var)
3513 call init(vg6dout, vg6din%griddim, vg6din%time_definition, categoryappend=
"generated by vg6d_reduce")
3514 call volgrid6d_alloc(vg6dout, vg6din%griddim%dim, ntime, nlevel, ntimerange, nvar)
3516 if (
ASSOCIATED(vg6din%voldati) .or. optio_log(merge))
then 3517 call volgrid6d_alloc_vol(vg6dout,inivol=.true.,decode=.true.)
3518 allocate(vol2d(nx,ny))
3520 call volgrid6d_alloc_vol(vg6dout,inivol=.true.,decode=.false.)
3523 vg6dout%time=vg6din%time
3524 vg6dout%var=vg6din%var
3525 vg6dout%timerange=pack_distinct(roundtimerange,ntimerange,back=.true.)
3526 vg6dout%level=pack_distinct(roundlevel,nlevel,back=.true.)
3528 CALL sort(vg6dout%timerange)
3529 CALL sort(vg6dout%level)
3531 do ilevel=1,
size(vg6din%level)
3532 indl=
index(vg6dout%level,roundlevel(ilevel))
3533 do itimerange=1,
size(vg6din%timerange)
3534 indt=
index(vg6dout%timerange,roundtimerange(itimerange))
3538 if (
ASSOCIATED(vg6din%voldati))
then 3539 vol2d=vg6din%voldati(:,:,ilevel,itime,itimerange,ivar)
3542 if (optio_log(merge))
then 3544 if ( .not.
ASSOCIATED(vg6din%voldati))
then 3545 CALL grid_id_decode_data(vg6din%gaid(ilevel,itime,itimerange,ivar), vol2d)
3549 where (.not.
c_e(vg6dout%voldati(:,:,indl,itime,indt,ivar)))
3551 vg6dout%voldati(:,:,indl,itime,indt,ivar)=vol2d
3554 else if (
ASSOCIATED(vg6din%voldati))
then 3555 if (.not. any(
c_e(vg6dout%voldati(:,:,indl,itime,indt,ivar))))
then 3556 vg6dout%voldati(:,:,indl,itime,indt,ivar)=vol2d
3560 if (
c_e(vg6din%gaid(ilevel,itime,itimerange,ivar)).and. .not.
c_e(vg6dout%gaid(indl,itime,indt,ivar)))
then 3561 call copy (vg6din%gaid(ilevel,itime,itimerange,ivar), vg6dout%gaid(indl,itime,indt,ivar))
3568 if (
ASSOCIATED(vg6din%voldati) .or. optio_log(merge))
then 3572 end subroutine vg6d_reduce
Write the object on a formatted or unformatted file.
Read the object from a formatted or unformatted file.
Functions that return a trimmed CHARACTER representation of the input variable.
Compute forward coordinate transformation from geographical system to projected system.
Represent level object in a pretty string.
Constructor, it creates a new instance of the object.
Operatore di valore assoluto di un intervallo.
Module for quickly interpreting the OPTIONAL parameters passed to a subprogram.
Destructor, it releases every information and memory buffer associated with the object.
Object describing a rectangular, homogeneous gridded dataset.
This module defines an abstract interface to different drivers for access to files containing gridded...
Apply the conversion function this to values.
Module for describing geographically referenced regular grids.
Decode and return the data array from a grid_id object associated to a gridinfo object.
Encode a data array into a grid_id object associated to a gridinfo object.
Classi per la gestione delle coordinate temporali.
This module defines objects and methods for managing data volumes on rectangular georeferenced grids...
classe per import ed export di volumi da e in DB-All.e
Convert a level type to a physical variable.
Definisce l'intervallo temporale di un'osservazione meteo.
Import an object dirctly from a native file, from a gridinfo object or from a supported file format t...
Export an object dirctly to a native file, to a gridinfo object or to a supported file format through...
Classe per la gestione dei livelli verticali in osservazioni meteo e affini.
Classe per la gestione di un volume completo di dati osservati.
This module defines usefull general purpose function and subroutine.
Class for managing information about a single gridded georeferenced field, typically imported from an...
Definisce il livello verticale di un'osservazione.
Classe per la gestione degli intervalli temporali di osservazioni meteo e affini. ...
Display on standard output a description of the volgrid6d object provided.
Module for defining the extension and coordinates of a rectangular georeferenced grid.
Clone the object, creating a new independent instance of the object exactly equal to the starting one...
classe per la gestione del logging
Class for managing physical variables in a grib 1/2 fashion.
Method for inserting elements of the array at a desired position.
Method for setting the contents of the object.
Emit log message for a category with specific priority.
Reduce some dimensions (level and timerage) for semplification (rounding).