libsim  Versione8.0.0

◆ grid_transform_init()

subroutine grid_transform_class::grid_transform_init ( type(grid_transform), intent(out)  this,
type(transform_def), intent(in)  trans,
type(griddim_def), intent(inout)  in,
type(griddim_def), intent(inout)  out,
real, dimension(:,:), intent(in), optional  maskgrid,
real, dimension(:), intent(in), optional  maskbounds,
character(len=*), intent(in), optional  categoryappend 
)
private

Constructor for a grid_transform object, defining a particular grid-to-grid transformation.

It defines an object describing a transformation from one rectangular grid to another; the abstract type of transformation is described in the transformation object trans (type transform_def) which must have been properly initialised. The additional information required here is the description of the input grid in (type griddim_def), the description of the output grid out (type griddim_def as well). The description of the output grid must be initialized for interpolating type transformations ('inter' and 'boxinter'), while it is generated by this constructor and returned in output for 'zoom', 'boxregrid', 'maskgen' and 'polyinter' transformations.

The generated grid_transform object is specific to the input and output grids involved. The function c_e can be used in order to check whether the object has been successfully initialised, if the result is .FALSE., it should not be used further on.

Parametri
[out]thisgrid_transformation object
[in]transtransformation object
[in,out]ingriddim object to transform
[in,out]outgriddim object defining target grid (input or output depending on type of transformation)
[in]maskgrid2D field to be used for defining valid points, it must have the same shape as the field to be interpolated (for transformation type 'metamorphosis:maskvalid')
[in]maskboundsarray of boundary values for defining a subset of valid points where the values of maskgrid are within the first and last value of maskbounds (for transformation type 'metamorphosis:maskvalid/settoinvalid' and others)
[in]categoryappendappend this suffix to log4fortran namespace category

Definizione alla linea 1430 del file grid_transform_class.F90.

1430 ! compute coordinates of output grid in input system
1431  CALL proj(in, lout%dim%lon, lout%dim%lat, this%inter_xp, this%inter_yp)
1432 
1433  ELSE ! near, shapiro_near
1434  CALL this%find_index(in, .true., &
1435  this%innx, this%inny, xmin, xmax, ymin, ymax, &
1436  lout%dim%lon, lout%dim%lat, this%trans%extrap, &
1437  this%inter_index_x, this%inter_index_y)
1438 
1439  IF (this%trans%trans_type == 'intersearch') THEN ! replicate code above
1440  ALLOCATE(this%inter_x(this%innx,this%inny), &
1441  this%inter_y(this%innx,this%inny))
1442  ALLOCATE(this%inter_xp(this%outnx,this%outny), &
1443  this%inter_yp(this%outnx,this%outny))
1444 
1445 ! compute coordinates of input grid
1446  CALL griddim_gen_coord(in, this%inter_x, this%inter_y)
1447 ! compute coordinates of output grid in input system
1448  CALL proj(in, lout%dim%lon, lout%dim%lat, this%inter_xp, this%inter_yp)
1449  ENDIF
1450  ENDIF
1451 
1452  CALL delete(lout)
1453  this%valid = .true.
1454  ENDIF
1455 
1456 ELSE IF (this%trans%trans_type == 'boxinter') THEN
1457 
1458  CALL outgrid_setup() ! common setup for grid-generating methods
1459  CALL get_val(in, nx=this%innx, ny=this%inny)
1460  CALL get_val(out, nx=this%outnx, ny=this%outny, &
1461  xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)
1462 ! TODO now box size is ignored
1463 ! if box size not provided, use the actual grid step
1464  IF (.NOT.c_e(this%trans%area_info%boxdx)) &
1465  CALL get_val(out, dx=this%trans%area_info%boxdx)
1466  IF (.NOT.c_e(this%trans%area_info%boxdy)) &
1467  CALL get_val(out, dx=this%trans%area_info%boxdy)
1468 ! half size is actually needed
1469  this%trans%area_info%boxdx = this%trans%area_info%boxdx*0.5d0
1470  this%trans%area_info%boxdy = this%trans%area_info%boxdy*0.5d0
1471 ! unlike before, here index arrays must have the shape of input grid
1472  ALLOCATE(this%inter_index_x(this%innx,this%inny), &
1473  this%inter_index_y(this%innx,this%inny))
1474 
1475 ! compute coordinates of input grid in geo system
1476  CALL copy(in, lin)
1477  CALL unproj(lin)
1478 ! use find_index in the opposite way, here extrap does not make sense
1479  CALL this%find_index(out, .true., &
1480  this%outnx, this%outny, xmin, xmax, ymin, ymax, &
1481  lin%dim%lon, lin%dim%lat, .false., &
1482  this%inter_index_x, this%inter_index_y)
1483 
1484  CALL delete(lin)
1485  this%valid = .true. ! warning, no check of subtype
1486 
1487 ELSE IF (this%trans%trans_type == 'stencilinter') THEN
1488 
1489  CALL outgrid_setup() ! common setup for grid-generating methods
1490 ! from inter:near
1491  CALL get_val(in, nx=this%innx, ny=this%inny, &
1492  xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)
1493  CALL get_val(out, nx=this%outnx, ny=this%outny)
1494 
1495  ALLOCATE (this%inter_index_x(this%outnx,this%outny), &
1496  this%inter_index_y(this%outnx,this%outny))
1497  CALL copy(out, lout)
1498  CALL unproj(lout)
1499  CALL this%find_index(in, .true., &
1500  this%innx, this%inny, xmin, xmax, ymin, ymax, &
1501  lout%dim%lon, lout%dim%lat, this%trans%extrap, &
1502  this%inter_index_x, this%inter_index_y)
1503 
1504 ! define the stencil mask
1505  nr = int(this%trans%area_info%radius) ! integer radius
1506  n = nr*2+1 ! n. of points
1507  nm = nr + 1 ! becomes index of center
1508  r2 = this%trans%area_info%radius**2
1509  ALLOCATE(this%stencil(n,n))
1510  this%stencil(:,:) = .true.
1511  DO iy = 1, n
1512  DO ix = 1, n
1513  IF ((ix-nm)**2+(iy-nm)**2 > r2) this%stencil(ix,iy) = .false.
1514  ENDDO
1515  ENDDO
1516 
1517 ! set to missing the elements of inter_index too close to the domain
1518 ! borders
1519  xnmin = nr + 1
1520  xnmax = this%innx - nr
1521  ynmin = nr + 1
1522  ynmax = this%inny - nr
1523  DO iy = 1, this%outny
1524  DO ix = 1, this%outnx
1525  IF (this%inter_index_x(ix,iy) < xnmin .OR. &
1526  this%inter_index_x(ix,iy) > xnmax .OR. &
1527  this%inter_index_y(ix,iy) < ynmin .OR. &
1528  this%inter_index_y(ix,iy) > ynmax) THEN
1529  this%inter_index_x(ix,iy) = imiss
1530  this%inter_index_y(ix,iy) = imiss
1531  ENDIF
1532  ENDDO
1533  ENDDO
1534 
1535 #ifdef DEBUG
1536  CALL l4f_category_log(this%category, l4f_debug, &
1537  'stencilinter: stencil size '//t2c(n*n))
1538  CALL l4f_category_log(this%category, l4f_debug, &
1539  'stencilinter: stencil points '//t2c(count(this%stencil)))
1540 #endif
1541 
1542  CALL delete(lout)
1543  this%valid = .true. ! warning, no check of subtype
1544 
1545 ELSE IF (this%trans%trans_type == 'maskgen') THEN
1546 
1547  IF (this%trans%sub_type == 'poly') THEN
1548 
1549  CALL copy(in, out)
1550  CALL get_val(in, nx=this%innx, ny=this%inny)
1551  this%outnx = this%innx
1552  this%outny = this%inny
1553 
1554 ! unlike before, here index arrays must have the shape of input grid
1555  ALLOCATE(this%inter_index_x(this%innx,this%inny), &
1556  this%inter_index_y(this%innx,this%inny))
1557  this%inter_index_x(:,:) = imiss
1558  this%inter_index_y(:,:) = 1
1559 
1560 ! compute coordinates of input grid in geo system
1561  CALL unproj(out) ! should be unproj(lin)
1562 
1563  nprev = 1
1564 !$OMP PARALLEL DEFAULT(SHARED)
1565 !$OMP DO PRIVATE(j, i, n, point) FIRSTPRIVATE(nprev)
1566  DO j = 1, this%inny
1567  inside_x: DO i = 1, this%innx
1568  point = georef_coord_new(x=out%dim%lon(i,j), y=out%dim%lat(i,j))
1569 
1570  DO n = nprev, this%trans%poly%arraysize ! optimize starting from last matched polygon
1571  IF (inside(point, this%trans%poly%array(n))) THEN ! stop at the first matching polygon
1572  this%inter_index_x(i,j) = n
1573  nprev = n
1574  cycle inside_x
1575  ENDIF
1576  ENDDO
1577  DO n = nprev-1, 1, -1 ! test the other polygons
1578  IF (inside(point, this%trans%poly%array(n))) THEN ! stop at the first matching polygon
1579  this%inter_index_x(i,j) = n
1580  nprev = n
1581  cycle inside_x
1582  ENDIF
1583  ENDDO
1584 
1585 ! CALL delete(point) ! speedup
1586  ENDDO inside_x
1587  ENDDO
1588 !$OMP END PARALLEL
1589 
1590  ELSE IF (this%trans%sub_type == 'grid') THEN
1591 ! here out(put grid) is abused for indicating the box-generating grid
1592 ! but the real output grid is the input grid
1593  CALL copy(out, lout) ! save out for local use
1594  CALL delete(out) ! needed before copy
1595  CALL copy(in, out)
1596  CALL get_val(in, nx=this%innx, ny=this%inny)
1597  this%outnx = this%innx
1598  this%outny = this%inny
1599  CALL get_val(lout, nx=nx, ny=ny, &
1600  xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)
1601 
1602 ! unlike before, here index arrays must have the shape of input grid
1603  ALLOCATE(this%inter_index_x(this%innx,this%inny), &
1604  this%inter_index_y(this%innx,this%inny))
1605 
1606 ! compute coordinates of input/output grid in geo system
1607  CALL unproj(out)
1608 
1609 ! use find_index in the opposite way, here extrap does not make sense
1610  CALL this%find_index(lout, .true., &
1611  nx, ny, xmin, xmax, ymin, ymax, &
1612  out%dim%lon, out%dim%lat, .false., &
1613  this%inter_index_x, this%inter_index_y)
1614 ! transform indices to 1-d for mask generation
1615  WHERE(c_e(this%inter_index_x(:,:)))
1616  this%inter_index_x(:,:) = this%inter_index_x(:,:) + &
1617  (this%inter_index_y(:,:)-1)*nx
1618  END WHERE
1619 
1620  CALL delete(lout)
1621  ENDIF
1622 
1623  this%valid = .true.
1624 
1625 ELSE IF (this%trans%trans_type == 'polyinter') THEN
1626 
1627 ! this is the only difference wrt maskgen:poly
1628  this%recur = .true. ! grid-to-grid polyinter is done in two steps!
1629 
1630  CALL copy(in, out)
1631  CALL get_val(in, nx=this%innx, ny=this%inny)
1632  this%outnx = this%innx
1633  this%outny = this%inny
1634 
1635 ! unlike before, here index arrays must have the shape of input grid
1636  ALLOCATE(this%inter_index_x(this%innx,this%inny), &
1637  this%inter_index_y(this%innx,this%inny))
1638  this%inter_index_x(:,:) = imiss
1639  this%inter_index_y(:,:) = 1
1640 
1641 ! compute coordinates of input grid in geo system
1642  CALL unproj(out) ! should be unproj(lin)
1643 
1644  nprev = 1
1645 !$OMP PARALLEL DEFAULT(SHARED)
1646 !$OMP DO PRIVATE(j, i, n, point) FIRSTPRIVATE(nprev)
1647  DO j = 1, this%inny
1648  inside_x_2: DO i = 1, this%innx
1649  point = georef_coord_new(x=out%dim%lon(i,j), y=out%dim%lat(i,j))
1650 
1651  DO n = nprev, this%trans%poly%arraysize ! optimize starting from last matched polygon
1652  IF (inside(point, this%trans%poly%array(n))) THEN ! stop at the first matching polygon
1653  this%inter_index_x(i,j) = n
1654  nprev = n
1655  cycle inside_x_2
1656  ENDIF
1657  ENDDO
1658  DO n = nprev-1, 1, -1 ! test the other polygons
1659  IF (inside(point, this%trans%poly%array(n))) THEN ! stop at the first matching polygon
1660  this%inter_index_x(i,j) = n
1661  nprev = n
1662  cycle inside_x_2
1663  ENDIF
1664  ENDDO
1665 
1666 ! CALL delete(point) ! speedup
1667  ENDDO inside_x_2
1668  ENDDO
1669 !$OMP END PARALLEL
1670 
1671  this%valid = .true. ! warning, no check of subtype
1672 
1673 ELSE IF (this%trans%trans_type == 'metamorphosis') THEN
1674 
1675  CALL copy(in, out)
1676  CALL get_val(in, nx=this%innx, ny=this%inny)
1677  this%outnx = this%innx
1678  this%outny = this%inny
1679 
1680  IF (this%trans%sub_type == 'maskvalid' .OR. this%trans%sub_type == 'maskinvalid') THEN
1681 
1682  IF (.NOT.PRESENT(maskgrid)) THEN
1683  CALL l4f_category_log(this%category,l4f_error, &
1684  'grid_transform_init maskgrid argument missing for metamorphosis:'// &
1685  trim(this%trans%sub_type)//' transformation')
1686  CALL raise_error()
1687  RETURN
1688  ENDIF
1689 
1690  IF (this%innx /= SIZE(maskgrid,1) .OR. this%inny /= SIZE(maskgrid,2)) THEN
1691  CALL l4f_category_log(this%category,l4f_error, &
1692  'grid_transform_init mask non conformal with input field')
1693  CALL l4f_category_log(this%category,l4f_error, &
1694  'mask: '//t2c(SIZE(maskgrid,1))//'x'//t2c(SIZE(maskgrid,2))// &
1695  ' input field:'//t2c(this%innx)//'x'//t2c(this%inny))
1696  CALL raise_error()
1697  RETURN
1698  ENDIF
1699 
1700  ALLOCATE(this%point_mask(this%innx,this%inny))
1701 
1702  IF (this%trans%sub_type == 'maskvalid') THEN
1703 ! behavior depends on the presence/usability of maskbounds,
1704 ! simplified wrt its use in metamorphosis:mask
1705  IF (.NOT.PRESENT(maskbounds)) THEN
1706  this%point_mask(:,:) = c_e(maskgrid(:,:))
1707  ELSE IF (SIZE(maskbounds) < 2) THEN
1708  this%point_mask(:,:) = c_e(maskgrid(:,:))
1709  ELSE
1710  this%point_mask(:,:) = c_e(maskgrid(:,:)) .AND. &
1711  maskgrid(:,:) > maskbounds(1) .AND. &
1712  maskgrid(:,:) <= maskbounds(SIZE(maskbounds))
1713  ENDIF
1714  ELSE ! reverse condition
1715  this%point_mask(:,:) = .NOT.c_e(maskgrid(:,:))
1716  ENDIF
1717 
1718  this%valid = .true.
1719 
1720  ELSE IF (this%trans%sub_type == 'lemaskinvalid' .OR. &
1721  this%trans%sub_type == 'ltmaskinvalid' .OR. &
1722  this%trans%sub_type == 'gemaskinvalid' .OR. &
1723  this%trans%sub_type == 'gtmaskinvalid') THEN
1724 ! here i can only store field for computing mask runtime
1725 
1726  this%val_mask = maskgrid
1727  this%valid = .true.
1728 
1729  ELSE IF (this%trans%sub_type == 'setinvalidto') THEN
1730 
1731  IF (.NOT.PRESENT(maskbounds)) THEN
1732  CALL l4f_category_log(this%category,l4f_error, &
1733  'grid_transform_init maskbounds missing for metamorphosis:'// &
1734  trim(this%trans%sub_type)//' transformation')
1735  RETURN
1736  ELSE IF (SIZE(maskbounds) < 1) THEN
1737  CALL l4f_category_log(this%category,l4f_error, &
1738  'grid_transform_init maskbounds empty for metamorphosis:'// &
1739  trim(this%trans%sub_type)//' transformation')
1740  RETURN
1741  ELSE
1742  this%val1 = maskbounds(1)
1743 #ifdef DEBUG
1744  CALL l4f_category_log(this%category, l4f_debug, &
1745  "grid_transform_init setting invalid data to "//t2c(this%val1))
1746 #endif
1747  ENDIF
1748 
1749  this%valid = .true.
1750 
1751  ELSE IF (this%trans%sub_type == 'settoinvalid') THEN
1752 
1753  IF (.NOT.PRESENT(maskbounds)) THEN
1754  CALL l4f_category_log(this%category,l4f_error, &
1755  'grid_transform_init maskbounds missing for metamorphosis:'// &
1756  trim(this%trans%sub_type)//' transformation')
1757  CALL raise_error()
1758  RETURN
1759  ELSE IF (SIZE(maskbounds) < 2) THEN
1760  CALL l4f_category_log(this%category,l4f_error, &
1761  'grid_transform_init maskbounds must have at least 2 elements for metamorphosis:'// &
1762  trim(this%trans%sub_type)//' transformation')
1763  CALL raise_error()
1764  RETURN
1765  ELSE
1766  this%val1 = maskbounds(1)
1767  this%val2 = maskbounds(SIZE(maskbounds))
1768 #ifdef DEBUG
1769  CALL l4f_category_log(this%category, l4f_debug, &
1770  "grid_transform_init setting to invalid interval ]"//t2c(this%val1)//','// &
1771  t2c(this%val2)//']')
1772 #endif
1773  ENDIF
1774 
1775  this%valid = .true.
1776 
1777  ENDIF
1778 
1779 ENDIF
1780 
1781 CONTAINS
1782 
1783 ! local subroutine to be called by all methods interpolating to a new
1784 ! grid, no parameters passed, used as a macro to avoid repeating code
1785 SUBROUTINE outgrid_setup()
1786 
1787 ! set increments in new grid in order for all the baraque to work
1788 CALL griddim_setsteps(out)
1789 ! check component flag
1790 CALL get_val(in, proj=proj_in, component_flag=cf_i)
1791 CALL get_val(out, proj=proj_out, component_flag=cf_o)
1792 IF (proj_in == proj_out) THEN
1793 ! same projection: set output component flag equal to input regardless
1794 ! of its value
1795  CALL set_val(out, component_flag=cf_i)
1796 ELSE
1797 ! different projection, interpolation possible only with vector data
1798 ! referred to geograpical axes
1799  IF (cf_i == 1) THEN
1800  CALL l4f_category_log(this%category,l4f_warn, &
1801  'trying to interpolate a grid with component flag 1 to a grid on a different projection')
1802  CALL l4f_category_log(this%category,l4f_warn, &
1803  'vector fields will probably be wrong')
1804  ELSE
1805  CALL set_val(out, component_flag=cf_i)
1806  ENDIF
1807 ENDIF
1808 ! rotate the input grid by n*360 degrees to bring it closer to the output grid
1809 CALL griddim_set_central_lon(in, griddim_central_lon(out))
1810 
1811 END SUBROUTINE outgrid_setup
1812 
1813 END SUBROUTINE grid_transform_init
1814 
1815 
1858 SUBROUTINE grid_transform_grid_vol7d_init(this, trans, in, v7d_out, &
1859  maskgrid, maskbounds, find_index, categoryappend)
1860 TYPE(grid_transform),INTENT(out) :: this
1861 TYPE(transform_def),INTENT(in) :: trans
1862 TYPE(griddim_def),INTENT(in) :: in
1863 TYPE(vol7d),INTENT(inout) :: v7d_out
1864 REAL,INTENT(in),OPTIONAL :: maskgrid(:,:)
1865 REAL,INTENT(in),OPTIONAL :: maskbounds(:)
1866 PROCEDURE(basic_find_index),POINTER,OPTIONAL :: find_index
1867 CHARACTER(len=*),INTENT(in),OPTIONAL :: categoryappend
1868 
1869 INTEGER :: ix, iy, n, nm, nr, nprev, nmaskarea, xnmin, xnmax, ynmin, ynmax, &
1870  time_definition
1871 DOUBLE PRECISION :: xmin, xmax, ymin, ymax, r2, lonref
1872 DOUBLE PRECISION,ALLOCATABLE :: lon1(:), lat1(:), lon(:,:), lat(:,:)
1873 REAL,ALLOCATABLE :: lmaskbounds(:)
1874 TYPE(georef_coord) :: point
1875 TYPE(griddim_def) :: lin
1876 !$ INTEGER :: outnx
1877 
1878 IF (PRESENT(find_index)) THEN ! move in init_common?
1879  IF (ASSOCIATED(find_index)) THEN
1880  this%find_index => find_index
1881  ENDIF
1882 ENDIF
1883 CALL grid_transform_init_common(this, trans, categoryappend)
1884 #ifdef DEBUG
1885 CALL l4f_category_log(this%category, l4f_debug, "grid_transform vg6d-v7d")
1886 #endif
1887 
1888 ! used after in some transformations
1889 CALL get_val(trans, time_definition=time_definition)
1890 IF (.NOT. c_e(time_definition)) THEN
1891  time_definition=1 ! default to validity time
1892 ENDIF
1893 
1894 IF (this%trans%trans_type == 'inter') THEN
1895 
1896  IF (this%trans%sub_type == 'near' .OR. this%trans%sub_type == 'bilin' &
1897  .OR. this%trans%sub_type == 'shapiro_near') THEN
1898 
1899  CALL copy(in, lin)
1900  CALL get_val(lin, nx=this%innx, ny=this%inny)
1901  this%outnx = SIZE(v7d_out%ana)
1902  this%outny = 1
1903 
1904  ALLOCATE (this%inter_index_x(this%outnx,this%outny),&
1905  this%inter_index_y(this%outnx,this%outny))
1906  ALLOCATE(lon(this%outnx,1),lat(this%outnx,1))
1907 
1908  CALL getval(v7d_out%ana(:)%coord,lon=lon(:,1),lat=lat(:,1))
1909 ! equalize in/out coordinates
1910  lonref = 0.5d0*(maxval(lon(:,1), mask=c_e(lon(:,1))) + minval(lon(:,1), mask=c_e(lon(:,1))))
1911  CALL griddim_set_central_lon(lin, lonref)
1912  CALL get_val(lin, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)
1913 
1914  IF (this%trans%sub_type == 'bilin') THEN
1915  CALL this%find_index(lin, .false., &
1916  this%innx, this%inny, xmin, xmax, ymin, ymax, &
1917  lon, lat, this%trans%extrap, &
1918  this%inter_index_x, this%inter_index_y)
1919 
1920  ALLOCATE(this%inter_x(this%innx,this%inny),this%inter_y(this%innx,this%inny))
1921  ALLOCATE(this%inter_xp(this%outnx,this%outny),this%inter_yp(this%outnx,this%outny))
1922 
1923  CALL griddim_gen_coord(lin, this%inter_x, this%inter_y)
1924  CALL proj(lin, lon, lat, this%inter_xp, this%inter_yp)
1925 
1926  ELSE ! near shapiro_near
1927  CALL this%find_index(lin, .true., &
1928  this%innx, this%inny, xmin, xmax, ymin, ymax, &
1929  lon, lat, this%trans%extrap, &
1930  this%inter_index_x, this%inter_index_y)
1931 
1932  IF (this%trans%trans_type == 'intersearch') THEN ! replicate code above
1933  ALLOCATE(this%inter_x(this%innx,this%inny),this%inter_y(this%innx,this%inny))
1934  ALLOCATE(this%inter_xp(this%outnx,this%outny),this%inter_yp(this%outnx,this%outny))
1935 
1936  CALL griddim_gen_coord(lin, this%inter_x, this%inter_y)
1937  CALL proj(lin, lon, lat, this%inter_xp, this%inter_yp)
1938  ENDIF
1939  ENDIF
1940 
1941  DEALLOCATE(lon,lat)
1942  CALL delete(lin)
1943 
1944  this%valid = .true.
1945 
1946  ENDIF
1947 
1948 ELSE IF (this%trans%trans_type == 'polyinter') THEN
1949 
1950  CALL get_val(in, nx=this%innx, ny=this%inny)
1951 ! unlike before, here index arrays must have the shape of input grid
1952  ALLOCATE(this%inter_index_x(this%innx,this%inny), &
1953  this%inter_index_y(this%innx,this%inny))
1954  this%inter_index_x(:,:) = imiss
1955  this%inter_index_y(:,:) = 1
1956 
1957 ! compute coordinates of input grid in geo system
1958  CALL copy(in, lin)
1959  CALL unproj(lin)
1960 
1961  this%outnx = this%trans%poly%arraysize
1962  this%outny = 1
1963  CALL delete(v7d_out) ! required to avoid leaks because intent(inout), dangerous
1964  CALL init(v7d_out, time_definition=time_definition)
1965  CALL vol7d_alloc(v7d_out, nana=this%outnx)
1966 
1967 ! equalize in/out coordinates
1968  ALLOCATE(lon(this%outnx,1))
1969  CALL getval(v7d_out%ana(:)%coord,lon=lon(:,1))
1970  lonref = 0.5d0*(maxval(lon(:,1), mask=c_e(lon(:,1))) + minval(lon(:,1), mask=c_e(lon(:,1))))
1971  CALL griddim_set_central_lon(lin, lonref)
1972  DEALLOCATE(lon)
1973 
1974 ! setup output point list, equal to average of polygon points
1975 ! warning, in case of concave areas points may coincide!
1976  CALL poly_to_coordinates(this%trans%poly, v7d_out)
1977 
1978  nprev = 1
1979 !$OMP PARALLEL DEFAULT(SHARED)
1980 !$OMP DO PRIVATE(iy, ix, n, point) FIRSTPRIVATE(nprev)
1981  DO iy = 1, this%inny
1982  inside_x: DO ix = 1, this%innx
1983  point = georef_coord_new(x=lin%dim%lon(ix,iy), y=lin%dim%lat(ix,iy))
1984 
1985  DO n = nprev, this%trans%poly%arraysize ! optimize starting from last matched polygon
1986  IF (inside(point, this%trans%poly%array(n))) THEN ! stop at the first matching polygon
1987  this%inter_index_x(ix,iy) = n
1988  nprev = n
1989  cycle inside_x
1990  ENDIF
1991  ENDDO
1992  DO n = nprev-1, 1, -1 ! test the other polygons
1993  IF (inside(point, this%trans%poly%array(n))) THEN ! stop at the first matching polygon
1994  this%inter_index_x(ix,iy) = n
1995  nprev = n
1996  cycle inside_x
1997  ENDIF
1998  ENDDO
1999 
2000 ! CALL delete(point) ! speedup
2001  ENDDO inside_x
2002  ENDDO
2003 !$OMP END PARALLEL
2004 
2005 #ifdef DEBUG
2006  DO n = 1, this%trans%poly%arraysize
2007  CALL l4f_category_log(this%category, l4f_debug, &
2008  'Polygon: '//t2c(n)//' grid points: '// &
2009  t2c(count(this%inter_index_x(:,:) == n)))
2010  ENDDO

Generated with Doxygen.