|
libsim Versione 8.0.0
|
◆ volgrid6d_transform()
Performs the specified abstract transformation on the data provided. The abstract transformation is specified by this parameter; the corresponding specifical transformation (grid_transform object) is created and destroyed internally. The output transformed object is created internally and it does not require preliminary initialisation.
Definizione alla linea 1839 del file volgrid6d_class.F90. 1841 ENDDO
1842
1843 IF (c_e(var_coord_vol)) THEN
1844 CALL l4f_category_log(volgrid6d_in%category, l4f_info, &
1845 'Coordinate for vertint found in input volume at position '// &
1846 t2c(var_coord_vol))
1847 ENDIF
1848
1849 ENDIF
1850 ENDIF
1851
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)
1857 ELSE
1858 CALL init(grid_trans, this, lev_in=volgrid6d_in%level, lev_out=lev_out, &
1859 categoryappend=categoryappend)
1860 ENDIF
1861
1862 CALL get_val(grid_trans, output_level_auto=llev_out) ! get levels if auto-generated
1863 IF (.NOT.ASSOCIATED(llev_out)) llev_out => lev_out
1864 nlevel = SIZE(llev_out)
1865 ELSE
1866 CALL l4f_category_log(volgrid6d_in%category, l4f_error, &
1867 'volgrid6d_transform: vertint requested but lev_out not provided')
1868 CALL init(volgrid6d_out) ! initialize to empty
1869 CALL raise_error()
1870 RETURN
1871 ENDIF
1872
1873ELSE
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)
1878ENDIF
1879
1880
1881IF (c_e(grid_trans)) THEN ! transformation is valid
1882
1883 CALL volgrid6d_alloc(volgrid6d_out, ntime=ntime, nlevel=nlevel, &
1884 ntimerange=ntimerange, nvar=nvar)
1885
1886 IF (PRESENT(decode)) THEN ! explicitly set decode status
1887 ldecode = decode
1888 ELSE ! take it from input
1889 ldecode = ASSOCIATED(volgrid6d_in%voldati)
1890 ENDIF
1891! force decode if gaid is readonly
1892 decode_loop: DO i6 = 1,nvar
1893 DO i5 = 1, ntimerange
1894 DO i4 = 1, ntime
1895 DO i3 = 1, nlevel
1896 IF (c_e(volgrid6d_in%gaid(i3,i4,i5,i6))) THEN
1897.OR. ldecode = ldecode grid_id_readonly(volgrid6d_in%gaid(i3,i4,i5,i6))
1898 EXIT decode_loop
1899 ENDIF
1900 ENDDO
1901 ENDDO
1902 ENDDO
1903 ENDDO decode_loop
1904
1905 IF (PRESENT(decode)) THEN
1906.NEQV. IF (ldecodedecode) THEN
1907 CALL l4f_category_log(volgrid6d_in%category, L4F_WARN, &
1908 'volgrid6d_transform: decode status forced to .true. because driver does not allow copy')
1909 ENDIF
1910 ENDIF
1911
1912 CALL volgrid6d_alloc_vol(volgrid6d_out, decode=ldecode)
1913
1914!ensure unproj was called
1915!call griddim_unproj(volgrid6d_out%griddim)
1916
1917 IF (trans_type == 'vertint') THEN
1918#ifdef DEBUG
1919 CALL l4f_category_log(volgrid6d_in%category, L4F_DEBUG, &
1920 "volgrid6d_transform: vertint to "//t2c(nlevel)//" levels")
1921#endif
1922 CALL compute(grid_trans, volgrid6d_in, volgrid6d_out, lev_out=llev_out, &
1923 var_coord_vol=var_coord_vol, clone=clone)
1924 ELSE
1925 CALL compute(grid_trans, volgrid6d_in, volgrid6d_out, clone=clone)
1926 ENDIF
1927
1928 IF (cf_out == 0) THEN ! unrotated components are desired
1929 CALL wind_unrot(volgrid6d_out) ! unrotate if necessary
1930 ELSE IF (cf_out == 1) THEN ! rotated components are desired
1931 CALL wind_rot(volgrid6d_out) ! rotate if necessary
1932 ENDIF
1933
1934ELSE
1935! should log with grid_trans%category, but it is private
1936 CALL l4f_category_log(volgrid6d_in%category, L4F_ERROR, &
1937 'volgrid6d_transform: transformation not valid')
1938 CALL raise_error()
1939ENDIF
1940
1941CALL delete (grid_trans)
1942
1943END SUBROUTINE volgrid6d_transform
1944
1945
1946!> Performs the specified abstract transformation on the arrays of
1947!! data provided. The abstract transformation is specified by \a this
1948!! parameter; the corresponding specifical transformation (\a
1949!! grid_transform object) is created and destroyed internally. The
1950!! output transformed object is created internally and it does not
1951!! require preliminary initialisation. According to the input data and
1952!! to the transformation type, the output array may have of one or
1953!! more \a volgrid6d elements on different grids.
1954SUBROUTINE volgrid6dv_transform(this, griddim, volgrid6d_in, volgrid6d_out, &
1955 lev_out, volgrid6d_coord_in, maskgrid, maskbounds, clone, decode, categoryappend)
1956TYPE(transform_def),INTENT(in) :: this !< object specifying the abstract transformation
1957TYPE(griddim_def),INTENT(in),OPTIONAL :: griddim !< griddim specifying the output grid (required by most transformation types)
1958TYPE(volgrid6d),INTENT(inout) :: volgrid6d_in(:) !< object to be transformed, it is an array of volgrid6d objects, each of which will be transformed, it is not modified, despite the INTENT(inout)
1959TYPE(volgrid6d),POINTER :: volgrid6d_out(:) !< transformed object, it is a non associated pointer to an array of volgrid6d objects which will be allocated by the method
1960TYPE(vol7d_level),INTENT(in),OPTIONAL :: lev_out(:) !< vol7d_level object defining target vertical grid
1961TYPE(volgrid6d),INTENT(in),OPTIONAL :: volgrid6d_coord_in !< object providing time constant input vertical coordinate for some kind of vertical interpolations
1962REAL,INTENT(in),OPTIONAL :: maskgrid(:,:) !< 2D field to be used for defining subareas according to its values, it must have the same shape as the field to be interpolated (for transformation subtype 'maskfill')
1963REAL,INTENT(in),OPTIONAL :: maskbounds(:) !< array of boundary values for defining a subset of valid points where the values of \a maskgrid are within the first and last value of \a maskbounds (for transformation type 'metamorphosis:maskfill')
1964LOGICAL,INTENT(in),OPTIONAL :: clone !< if provided and \a .TRUE. , clone the \a gaid's from \a volgrid6d_in to \a volgrid6d_out
1965LOGICAL,INTENT(in),OPTIONAL :: decode !< if provided and \a .FALSE. the data volume is not allocated, but work is performed on grid_id's
1966CHARACTER(len=*),INTENT(in),OPTIONAL :: categoryappend !< append this suffix to log4fortran namespace category
1967
1968INTEGER :: i, stallo
1969
1970
1971allocate(volgrid6d_out(size(volgrid6d_in)),stat=stallo)
1972if (stallo /= 0)then
1973 call l4f_log(l4f_fatal,"allocating memory")
1974 call raise_fatal_error()
1975end if
1976
1977do 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)
1982end do
1983
1984END SUBROUTINE volgrid6dv_transform
1985
1986
1987! Internal method for performing grid to sparse point computations
1988SUBROUTINE volgrid6d_v7d_transform_compute(this, volgrid6d_in, vol7d_out, &
1989 networkname, noconvert)
1990TYPE(grid_transform),INTENT(in) :: this ! oggetto di trasformazione per grigliato
1991type(volgrid6d), INTENT(in) :: volgrid6d_in ! oggetto da trasformare
1992type(vol7d), INTENT(inout) :: vol7d_out ! oggetto trasformato
1993CHARACTER(len=*),OPTIONAL,INTENT(in) :: networkname ! imposta il network in vol7d_out (default='generic')
1994LOGICAL,OPTIONAL,INTENT(in) :: noconvert !< do not try to match variable and convert values during transform
1995
1996INTEGER :: nntime, nana, ntime, ntimerange, nlevel, nvar, stallo
1997INTEGER :: itime, itimerange, ivar, inetwork
1998REAL,ALLOCATABLE :: voldatir_out(:,:,:)
1999TYPE(conv_func),POINTER :: c_func(:)
2000TYPE(datetime),ALLOCATABLE :: validitytime(:,:)
2001REAL,POINTER :: voldatiin(:,:,:)
2002
2003#ifdef DEBUG
2004call l4f_category_log(volgrid6d_in%category,L4F_DEBUG,"start volgrid6d_v7d_transform_compute")
2005#endif
2006
2007ntime=0
2008ntimerange=0
2009nlevel=0
2010nvar=0
2011NULLIFY(c_func)
2012
2013if (present(networkname))then
2014 call init(vol7d_out%network(1),name=networkname)
2015else
2016 call init(vol7d_out%network(1),name='generic')
2017end if
2018
2019if (associated(volgrid6d_in%timerange))then
2020 ntimerange=size(volgrid6d_in%timerange)
2021 vol7d_out%timerange=volgrid6d_in%timerange
2022end if
2023
2024if (associated(volgrid6d_in%time))then
2025 ntime=size(volgrid6d_in%time)
2026
2027 if (vol7d_out%time_definition == volgrid6d_in%time_definition) then
2028
2029 ! i time sono definiti uguali: assegno
2030 vol7d_out%time=volgrid6d_in%time
2031
2032 else
2033 ! converto reference in validity
2034 allocate (validitytime(ntime,ntimerange),stat=stallo)
2035 if (stallo /=0)then
2036 call l4f_category_log(volgrid6d_in%category,l4f_fatal,"allocating memory")
2037 call raise_fatal_error()
2038 end if
2039
2040 do itime=1,ntime
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)
2045 else
2046 validitytime(itime,itimerange) = &
2047 volgrid6d_in%time(itime) - timedelta_new(sec=volgrid6d_in%timerange(itimerange)%p1)
2048 end if
2049 end do
2050 end do
2051
2052 nntime = count_distinct(reshape(validitytime,(/ntime*ntimerange/)), back=.true.)
2053 vol7d_out%time=pack_distinct(reshape(validitytime,(/ntime*ntimerange/)), nntime,back=.true.)
2054
2055 end if
2056end if
2057
2058IF (ASSOCIATED(volgrid6d_in%level)) THEN
2059 nlevel = SIZE(volgrid6d_in%level)
2060 vol7d_out%level=volgrid6d_in%level
2061ENDIF
2062
2063IF (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)
2067 ENDIF
2068ENDIF
2069
2070nana = SIZE(vol7d_out%ana)
2071
2072! allocate once for speed
2073IF (.NOT.ASSOCIATED(volgrid6d_in%voldati)) THEN
2074 ALLOCATE(voldatiin(volgrid6d_in%griddim%dim%nx, volgrid6d_in%griddim%dim%ny, &
2075 nlevel))
2076ENDIF
2077
2078ALLOCATE(voldatir_out(nana,1,nlevel),stat=stallo)
2079IF (stallo /= 0) THEN
2080 CALL l4f_category_log(volgrid6d_in%category,l4f_fatal,"allocating memory")
2081 CALL raise_fatal_error()
2082ENDIF
2083
2084inetwork=1
2085do itime=1,ntime
2086 do itimerange=1,ntimerange
2087! do ilevel=1,nlevel
2088 do ivar=1,nvar
2089
2090 !non è chiaro se questa sezione è utile o no
2091 !ossia il compute sotto sembra prevedere voldatir_out solo in out
2092!!$ if (vol7d_out%time_definition == volgrid6d_in%time_definition) then
2093!!$ voldatir_out=reshape(vol7d_out%voldatir(:,itime,ilevel,itimerange,ivar,inetwork),(/nana,1/))
2094!!$ else
2095!!$ voldatir_out=reshape(vol7d_out%voldatir(:,index(vol7d_out%time,validitytime(itime,ilevel)),ilevel,itimerange,ivar,inetwork),(/nana,1/))
2096!!$ end if
2097
2098 CALL volgrid_get_vol_3d(volgrid6d_in, itime, itimerange, ivar, &
2099 voldatiin)
2100
2101 CALL compute(this, voldatiin, voldatir_out, vol7d_out%dativar%r(ivar))
2102
2103 if (vol7d_out%time_definition == volgrid6d_in%time_definition) then
2104 vol7d_out%voldatir(:,itime,:,itimerange,ivar,inetwork) = &
2105 voldatir_out(:,1,:)
2106 else
2107 vol7d_out%voldatir(:,index(vol7d_out%time,validitytime(itime,itimerange)),:,itimerange,ivar,inetwork)=&
2108 reshape(voldatir_out,(/nana,nlevel/))
2109 end if
2110
2111! 1 indice della dimensione "anagrafica"
2112! 2 indice della dimensione "tempo"
2113! 3 indice della dimensione "livello verticale"
2114! 4 indice della dimensione "intervallo temporale"
2115! 5 indice della dimensione "variabile"
2116! 6 indice della dimensione "rete"
2117
2118 end do
2119! end do
2120 end do
2121end do
2122
2123deallocate(voldatir_out)
2124IF (.NOT.ASSOCIATED(volgrid6d_in%voldati)) THEN
2125 DEALLOCATE(voldatiin)
2126ENDIF
2127if (allocated(validitytime)) deallocate(validitytime)
2128
2129! Rescale valid data according to variable conversion table
2130IF (ASSOCIATED(c_func)) THEN
|