LCOV - code coverage report
Current view: top level - common - mo_grid.f90 (source / functions) Hit Total Coverage
Test: mHM coverage Lines: 122 132 92.4 %
Date: 2024-04-15 17:48:09 Functions: 6 6 100.0 %

          Line data    Source code
       1             : !> \file mo_grid.f90
       2             : !> \brief \copybrief mo_grid
       3             : !> \details \copydetails mo_grid
       4             : 
       5             : !> \brief gridding tools
       6             : !> \details Common tools to deal with grids in mHM.
       7             : !> \authors Robert Schweppe
       8             : !> \date Jun 2018
       9             : !> \copyright Copyright 2005-\today, the mHM Developers, Luis Samaniego, Sabine Attinger: All rights reserved.
      10             : !! mHM is released under the LGPLv3+ license \license_note
      11             : !> \ingroup f_common
      12             : module mo_grid
      13             :   use mo_kind, only : dp, i4
      14             : 
      15             :   IMPLICIT NONE
      16             : 
      17             :   PRIVATE
      18             : 
      19             :   PUBLIC :: init_lowres_level, set_domain_indices, L0_grid_setup, &
      20             :           mapCoordinates, geoCoordinates
      21             : contains
      22             :   ! ------------------------------------------------------------------
      23             : 
      24             :   !    NAME
      25             :   !        init_lowres_level
      26             : 
      27             :   !    PURPOSE
      28             :   !>       \brief Level-1 variable initialization
      29             : 
      30             :   !>       \details following tasks are performed for L1 datasets
      31             :   !>       -  cell id & numbering
      32             :   !>       -  mask creation
      33             :   !>       -  storage of cell cordinates (row and coloum id)
      34             :   !>       -  sorage of four corner L0 cordinates
      35             :   !>       If a variable is added or removed here, then it also has to
      36             :   !>       be added or removed in the subroutine config_variables_set in
      37             :   !>       module mo_restart and in the subroutine set_config in module
      38             :   !>       mo_set_netcdf_restart
      39             : 
      40             :   !    INTENT(IN)
      41             :   !>       \param[in] "type(Grid) :: highres"
      42             :   !>       \param[in] "real(dp) :: target_resolution"
      43             : 
      44             :   !    INTENT(INOUT)
      45             :   !>       \param[inout] "type(Grid) :: lowres"
      46             : 
      47             :   !    INTENT(INOUT), OPTIONAL
      48             :   !>       \param[inout] "type(GridRemapper), optional :: highres_lowres_remap"
      49             : 
      50             :   !    HISTORY
      51             :   !>       \authors Rohini Kumar
      52             : 
      53             :   !>       \date Jan 2013
      54             : 
      55             :   ! Modifications:
      56             :   ! Robert Schweppe Jun 2018 - refactoring and reformatting
      57             : 
      58          75 :   subroutine init_lowres_level(highres, target_resolution, lowres, highres_lowres_remap)
      59             : 
      60             :     use mo_common_constants, only : nodata_dp, nodata_i4
      61             :     use mo_common_types, only : Grid, GridRemapper
      62             : 
      63             :     implicit none
      64             : 
      65             :     type(Grid), target, intent(in) :: highres
      66             : 
      67             :     real(dp), intent(in) :: target_resolution
      68             : 
      69             :     type(Grid), target, intent(inout) :: lowres
      70             : 
      71             :     type(GridRemapper), intent(inout), optional :: highres_lowres_remap
      72             : 
      73          75 :     real(dp), dimension(:, :), allocatable :: areaCell0_2D
      74             : 
      75          75 :     real(dp) :: cellFactor
      76             : 
      77             :     integer(i4) :: iup, idown
      78             : 
      79             :     integer(i4) :: jl, jr
      80             : 
      81             :     integer(i4) :: i, j, k, ic, jc
      82             : 
      83             :     ! STEPS ::
      84             : 
      85             :     !--------------------------------------------------------
      86             :     ! 1) Estimate each variable locally for a given domain
      87             :     ! 2) Pad each variable to its corresponding global one
      88             :     !--------------------------------------------------------
      89             :     ! grid properties
      90          75 :     if (.not. allocated(lowres%mask)) then
      91             :       call calculate_grid_properties(highres%nrows, highres%ncols, &
      92             :               highres%xllcorner, highres%yllcorner, highres%cellsize, &
      93             :               target_resolution, &
      94             :               lowres%nrows, lowres%ncols, &
      95          75 :               lowres%xllcorner, lowres%yllcorner, lowres%cellsize)
      96             :       ! cellfactor = leve1-1 / level-0
      97          75 :       cellFactor = anint(lowres%cellsize / highres%cellsize)
      98             : 
      99             :       ! allocation and initalization of mask at level-1
     100         300 :       allocate(lowres%mask(lowres%nrows, lowres%ncols))
     101        5457 :       lowres%mask(:, :) = .FALSE.
     102             : 
     103             :       ! create mask at level-1
     104       31323 :       do j = 1, highres%ncols
     105       31248 :         jc = ceiling(real(j, dp) / cellFactor)
     106     8961627 :         do i = 1, highres%nrows
     107     8930304 :           if (.NOT. highres%mask(i, j)) cycle
     108     3337755 :           ic = ceiling(real(i, dp) / cellFactor)
     109     8961552 :           lowres%mask(ic, jc) = .TRUE.
     110             :         end do
     111             :       end do
     112             : 
     113             :       ! estimate ncells and initalize related variables
     114        5457 :       lowres%nCells = count(lowres%mask)
     115             :       ! allocate and initalize cell1 related variables
     116         225 :       allocate(lowres%Id        (lowres%nCells))
     117        8655 :       lowres%Id = (/ (k, k = 1, lowres%nCells) /)
     118             :     end if
     119             : 
     120          75 :     if (present(highres_lowres_remap)) then
     121             :       ! cellfactor = leve1-1 / level-0, set again in case not yet initialized
     122          49 :       cellFactor = lowres%cellsize / highres%cellsize
     123             : 
     124             :       ! lowres additional properties
     125         196 :       allocate(areaCell0_2D(highres%nrows, highres%ncols))
     126          49 :       areaCell0_2D(:, :) = UNPACK(highres%CellArea, highres%mask, nodata_dp)
     127             : 
     128          49 :       if (.not. allocated(lowres%CellCoor)) then
     129         147 :         allocate(lowres%CellCoor  (lowres%nCells, 2))
     130         147 :         allocate(lowres%CellArea  (lowres%nCells))
     131             :       end if
     132             : 
     133         147 :       allocate(highres_lowres_remap%lower_bound(lowres%nCells))
     134         147 :       allocate(highres_lowres_remap%upper_bound(lowres%nCells))
     135         147 :       allocate(highres_lowres_remap%left_bound (lowres%nCells))
     136         147 :       allocate(highres_lowres_remap%right_bound(lowres%nCells))
     137         147 :       allocate(highres_lowres_remap%n_subcells (lowres%nCells))
     138         196 :       allocate(highres_lowres_remap%lowres_id_on_highres (highres%nrows, highres%ncols))
     139     5849569 :       highres_lowres_remap%lowres_id_on_highres = nodata_i4
     140             : 
     141          49 :       highres_lowres_remap%high_res_grid => highres
     142          49 :       highres_lowres_remap%low_res_grid => lowres
     143             : 
     144          49 :       k = 0
     145         519 :       do jc = 1, lowres%ncols
     146        3859 :         do ic = 1, lowres%nrows
     147        3340 :           if (.NOT. lowres%mask(ic, jc)) cycle
     148        1981 :           k = k + 1
     149             : 
     150        1981 :           lowres%CellCoor(k, 1) = ic
     151        1981 :           lowres%CellCoor(k, 2) = jc
     152             : 
     153             :           ! coord. of all corners -> of finer scale level-0
     154        1981 :           iup = (ic - 1) * nint(cellFactor, i4) + 1
     155        1981 :           idown = ic * nint(cellFactor, i4)
     156        1981 :           jl = (jc - 1) * nint(cellFactor, i4) + 1
     157        1981 :           jr = jc * nint(cellFactor, i4)
     158             : 
     159             :           ! constrain the range of up, down, left, and right boundaries
     160        1981 :           if(iup   < 1) iup = 1
     161        1981 :           if(idown > highres%nrows) idown = highres%nrows
     162        1981 :           if(jl    < 1) jl = 1
     163        1981 :           if(jr    > highres%ncols) jr = highres%ncols
     164             : 
     165        1981 :           highres_lowres_remap%upper_bound   (k) = iup
     166        1981 :           highres_lowres_remap%lower_bound (k) = idown
     167        1981 :           highres_lowres_remap%left_bound (k) = jl
     168        1981 :           highres_lowres_remap%right_bound(k) = jr
     169             : 
     170             :           ! effective area [km2] & total no. of L0 cells within a given L1 cell
     171     3706453 :           lowres%CellArea(k) = sum(areacell0_2D(iup : idown, jl : jr), highres%mask(iup : idown, jl : jr))
     172     3706453 :           highres_lowres_remap%n_subcells(k) = count(highres%mask(iup : idown, jl : jr))
     173             :           ! Delimitation of level-11 cells on level-0
     174     3706923 :           highres_lowres_remap%lowres_id_on_highres(iup : idown, jl : jr) = k
     175             :         end do
     176             :       end do
     177             : 
     178             :       ! free space
     179          49 :       deallocate(areaCell0_2D)
     180             : 
     181             :     end if
     182             : 
     183          75 :   end subroutine init_lowres_level
     184             : 
     185             :   !    NAME
     186             :   !        set_domain_indices
     187             : 
     188             :   !    PURPOSE
     189             :   !>       \brief TODO: add description
     190             : 
     191             :   !>       \details TODO: add description
     192             : 
     193             :   !    INTENT(INOUT)
     194             :   !>       \param[inout] "type(Grid), dimension(:) :: grids"
     195             : 
     196             :   !    HISTORY
     197             :   !>       \authors Robert Schweppe
     198             : 
     199             :   !>       \date Jun 2018
     200             : 
     201             :   ! Modifications:
     202             :   !        Stephan Thober, Aug 2019 - added optional indices for L0 data because L0 data can be shared among domains
     203             : 
     204         162 :   subroutine set_domain_indices(grids, indices)
     205             : 
     206          75 :     use mo_common_types, only: Grid
     207             : 
     208             :     implicit none
     209             : 
     210             :     type(Grid), intent(inout), dimension(:) :: grids
     211             :     integer(i4),   intent(in), dimension(:), optional :: indices
     212             : 
     213             :     integer(i4) :: iDomain
     214             : 
     215             : 
     216         234 :     do iDomain = 1, size(grids)
     217             :       ! Saving indices of mask and packed data
     218         153 :       if(iDomain .eq. 1_i4) then
     219          81 :         grids(iDomain)%iStart = 1_i4
     220             :       else
     221          72 :         if (present(indices)) then
     222          24 :           grids(iDomain)%iStart = grids(indices(iDomain - 1))%iEnd + 1_i4
     223             :         else
     224          48 :           grids(iDomain)%iStart = grids(iDomain - 1_i4)%iEnd + 1_i4
     225             :         end if
     226             :       end if
     227         234 :       grids(iDomain)%iEnd = grids(iDomain)%iStart + grids(iDomain)%nCells - 1_i4
     228             :     end do
     229             : 
     230          81 :   end subroutine set_domain_indices
     231             : 
     232             :   ! ------------------------------------------------------------------
     233             : 
     234             :   !    NAME
     235             :   !        L0_grid_setup
     236             : 
     237             :   !    PURPOSE
     238             :   !>       \brief level 0 variable initialization
     239             : 
     240             :   !>       \details following tasks are performed for L0 data sets
     241             :   !>       -  cell id & numbering
     242             :   !>       -  storage of cell cordinates (row and coloum id)
     243             :   !>       -  empirical dist. of terrain slope
     244             :   !>       -  flag to determine the presence of a particular soil id
     245             :   !>       in this configuration of the model run
     246             :   !>       If a variable is added or removed here, then it also has to
     247             :   !>       be added or removed in the subroutine config_variables_set in
     248             :   !>       module mo_restart and in the subroutine set_config in module
     249             :   !>       mo_set_netcdf_restart
     250             : 
     251             :   !    INTENT(INOUT)
     252             :   !>       \param[inout] "type(Grid) :: new_grid"
     253             : 
     254             :   !    HISTORY
     255             :   !>       \authors Rohini Kumar
     256             : 
     257             :   !>       \date Jan 2013
     258             : 
     259             :   ! Modifications:
     260             :   ! Rohini Kumar & Matthias Cuntz  May 2014 - cell area calulation based on a regular lat-lon grid or
     261             :   !                                           on a regular X-Y coordinate system
     262             :   ! Matthias Cuntz                 May 2014 - changed empirical distribution function so that doubles get the same value
     263             :   ! Matthias Zink & Matthias Cuntz Feb 2016 - code speed up due to reformulation of CDF calculation
     264             :   ! Rohini Kumar                   Mar 2016 - changes for handling multiple soil database options
     265             :   ! Robert Schweppe                Jun 2018 - refactoring and reformatting
     266             : 
     267          22 :   subroutine L0_grid_setup(new_grid)
     268             : 
     269          81 :     use mo_common_types, only: Grid
     270             :     use mo_common_variables, only : iFlag_cordinate_sys
     271             :     use mo_constants, only : RadiusEarth_dp, TWOPI_dp
     272             : 
     273             :     implicit none
     274             : 
     275             :     type(Grid), intent(inout) :: new_grid
     276             : 
     277          22 :     real(dp), dimension(:, :), allocatable :: areaCell_2D
     278             : 
     279             :     integer(i4) :: i, j, k
     280             : 
     281          22 :     real(dp) :: rdum, degree_to_radian, degree_to_metre
     282             : 
     283             :     ! STEPS ::
     284             : 
     285             : 
     286             :     !--------------------------------------------------------
     287             :     ! 1) Estimate each variable locally for a given domain
     288             :     ! 2) Pad each variable to its corresponding global one
     289             :     !--------------------------------------------------------
     290             :     ! level-0 information
     291     2612662 :     new_grid%nCells = count(new_grid%mask)
     292             : 
     293          66 :     allocate(new_grid%CellCoor(new_grid%nCells, 2))
     294          66 :     allocate(new_grid%Id(new_grid%nCells))
     295          66 :     allocate(new_grid%CellArea(new_grid%nCells))
     296          88 :     allocate(areaCell_2D(new_grid%nrows, new_grid%ncols))
     297             : 
     298     2918894 :     new_grid%Id = (/ (k, k = 1, new_grid%nCells) /)
     299             : 
     300             :     !------------------------------------------------
     301             :     ! start looping for cell cordinates and ids
     302             :     !------------------------------------------------
     303          22 :     k = 0
     304        9142 :     do j = 1, new_grid%ncols
     305     2612662 :       do i = 1, new_grid%nrows
     306     2603520 :         if (.NOT. new_grid%mask(i, j)) cycle
     307      972950 :         k = k + 1
     308      972950 :         new_grid%cellCoor(k, 1) = i
     309     2612640 :         new_grid%cellCoor(k, 2) = j
     310             :       end do
     311             :     end do
     312             : 
     313             :     ! ESTIMATE AREA [m2]
     314             : 
     315             :     ! regular X-Y coordinate system
     316          22 :     if(iFlag_cordinate_sys .eq. 0) then
     317      972972 :       new_grid%CellArea(:) = new_grid%cellsize * new_grid%cellsize
     318             : 
     319             :       ! regular lat-lon coordinate system
     320           0 :     else if(iFlag_cordinate_sys .eq. 1) then
     321             : 
     322           0 :       degree_to_radian = TWOPI_dp / 360.0_dp
     323           0 :       degree_to_metre = RadiusEarth_dp * TWOPI_dp / 360.0_dp
     324           0 :       do i = new_grid%ncols, 1, -1
     325           0 :         j = new_grid%ncols - i + 1
     326             :         ! get latitude in degrees
     327           0 :         rdum = new_grid%yllcorner + (real(j, dp) - 0.5_dp) * new_grid%cellsize
     328             :         ! convert to radians
     329           0 :         rdum = rdum * degree_to_radian
     330             :         !    AREA [m2]
     331           0 :         areaCell_2D(:, i) = (new_grid%cellsize * cos(rdum) * degree_to_metre) * (new_grid%cellsize * degree_to_metre)
     332             :       end do
     333           0 :       new_grid%CellArea(:) = pack(areaCell_2D(:, :), new_grid%mask)
     334             : 
     335             :     end if
     336             : 
     337             :     ! free space
     338          22 :     deallocate(areaCell_2D)
     339             : 
     340          22 :   end subroutine L0_grid_setup
     341             : 
     342             : 
     343             :   !------------------------------------------------------------------
     344             :   !    NAME
     345             :   !        mapCoordinates
     346             : 
     347             :   !    PURPOSE
     348             :   !>       \brief Generate map coordinates
     349             : 
     350             :   !>       \details Generate map coordinate arrays for given domain and level
     351             : 
     352             :   !    INTENT(IN)
     353             :   !>       \param[in] "type(Grid) :: level" -> grid reference
     354             : 
     355             :   !    INTENT(OUT)
     356             :   !>       \param[out] "real(dp), dimension(:) :: x, y"
     357             :   !>       \param[out] "real(dp), dimension(:) :: x, y"
     358             : 
     359             :   !    HISTORY
     360             :   !>       \authors Matthias Zink
     361             : 
     362             :   !>       \date Apr 2013
     363             : 
     364             :   ! Modifications:
     365             :   ! Stephan Thober Nov 2013 - removed fproj dependency
     366             :   ! David Schaefer Jun 2015 - refactored the former subroutine CoordSystem
     367             :   ! Robert Schweppe Jun 2018 - refactoring and reformatting
     368             : 
     369             : 
     370          19 :   subroutine mapCoordinates(level, y, x)
     371             : 
     372          22 :     use mo_common_types, only: Grid
     373             : 
     374             :     implicit none
     375             : 
     376             :     ! -> grid reference
     377             :     type(Grid), intent(in) :: level
     378             : 
     379             :     real(dp), intent(out), allocatable, dimension(:) :: x, y
     380             : 
     381             :     integer(i4) :: ii, ncols, nrows
     382             : 
     383          19 :     real(dp) :: cellsize
     384             : 
     385             : 
     386          19 :     cellsize = level%cellsize
     387          19 :     nrows = level%nrows
     388          19 :     ncols = level%ncols
     389             : 
     390          95 :     allocate(x(nrows), y(ncols))
     391             : 
     392          19 :     x(1) = level%xllcorner + 0.5_dp * cellsize
     393         124 :     do ii = 2, nrows
     394         124 :       x(ii) = x(ii - 1) + cellsize
     395             :     end do
     396             : 
     397             :     ! inverse for Panoply, ncview display
     398          19 :     y(ncols) = level%yllcorner + 0.5_dp * cellsize
     399         181 :     do ii = ncols - 1, 1, -1
     400         181 :       y(ii) = y(ii + 1) + cellsize
     401             :     end do
     402             : 
     403          19 :   end subroutine mapCoordinates
     404             : 
     405             :   !------------------------------------------------------------------
     406             :   !    NAME
     407             :   !        geoCoordinates
     408             : 
     409             :   !    PURPOSE
     410             :   !>       \brief Generate geographic coordinates
     411             : 
     412             :   !>       \details Generate geographic coordinate arrays for given domain and level
     413             : 
     414             :   !    INTENT(IN)
     415             :   !>       \param[in] "type(Grid) :: level" -> grid reference
     416             : 
     417             :   !    INTENT(OUT)
     418             :   !>       \param[out] "real(dp), dimension(:, :) :: lat, lon"
     419             :   !>       \param[out] "real(dp), dimension(:, :) :: lat, lon"
     420             : 
     421             :   !    HISTORY
     422             :   !>       \authors Matthias Zink
     423             : 
     424             :   !>       \date Apr 2013
     425             : 
     426             :   ! Modifications:
     427             :   ! Stephan Thober  Nov 2013 - removed fproj dependency
     428             :   ! David Schaefer  Jun 2015 - refactored the former subroutine CoordSystem
     429             :   ! Stephan Thober  Sep 2015 - using mask to unpack coordinates
     430             :   ! Stephan Thober  Oct 2015 - writing full lat/lon again
     431             :   ! Robert Schweppe Jun 2018 - refactoring and reformatting
     432             : 
     433          19 :   subroutine geoCoordinates(level, lat, lon)
     434             : 
     435          19 :     use mo_common_types, only: Grid
     436             : 
     437             :     implicit none
     438             : 
     439             :     ! -> grid reference
     440             :     type(Grid), intent(in) :: level
     441             : 
     442             :     real(dp), intent(out), allocatable, dimension(:, :) :: lat, lon
     443             : 
     444             : 
     445        1549 :     lat = level%y
     446        1549 :     lon = level%x
     447             : 
     448          19 :   end subroutine geoCoordinates
     449             : 
     450             :   ! ------------------------------------------------------------------
     451             : 
     452             :   !    NAME
     453             :   !        calculate_grid_properties
     454             : 
     455             :   !    PURPOSE
     456             :   !>       \brief Calculates basic grid properties at a required coarser level using
     457             :   !>       information of a given finer level.
     458             :   !>       Calculates basic grid properties at a required coarser level (e.g., L11) using
     459             :   !>       information of a given finer level (e.g., L0). Basic grid properties such as
     460             :   !>       nrows, ncols, xllcorner, yllcorner cellsize are estimated in this
     461             :   !>       routine.
     462             : 
     463             :   !>       \details TODO: add description
     464             : 
     465             :   !    INTENT(IN)
     466             :   !>       \param[in] "integer(i4) :: nrowsIn"       no. of rows at an input level
     467             :   !>       \param[in] "integer(i4) :: ncolsIn"       no. of cols at an input level
     468             :   !>       \param[in] "real(dp) :: xllcornerIn"      xllcorner at an input level
     469             :   !>       \param[in] "real(dp) :: yllcornerIn"      yllcorner at an input level
     470             :   !>       \param[in] "real(dp) :: cellsizeIn"       cell size at an input level
     471             :   !>       \param[in] "real(dp) :: aimingResolution" resolution of an output level
     472             : 
     473             :   !    INTENT(OUT)
     474             :   !>       \param[out] "integer(i4) :: nrowsOut"  no. of rows at an output level
     475             :   !>       \param[out] "integer(i4) :: ncolsOut"  no. of cols at an output level
     476             :   !>       \param[out] "real(dp) :: xllcornerOut" xllcorner at an output level
     477             :   !>       \param[out] "real(dp) :: yllcornerOut" yllcorner at an output level
     478             :   !>       \param[out] "real(dp) :: cellsizeOut"  cell size at an output level
     479             : 
     480             :   !    HISTORY
     481             :   !>       \authors Matthias Zink & Rohini Kumar
     482             : 
     483             :   !>       \date Feb 2013
     484             : 
     485             :   ! Modifications:
     486             :   ! R. Kumar        Sep 2013 - documentation added according to the template
     487             :   ! Robert Schweppe Jun 2018 - refactoring and reformatting
     488             : 
     489          75 :   subroutine calculate_grid_properties(nrowsIn, ncolsIn, xllcornerIn, yllcornerIn, cellsizeIn, aimingResolution, &
     490             :                                       nrowsOut, ncolsOut, xllcornerOut, yllcornerOut, cellsizeOut)
     491             : 
     492          19 :     use mo_message, only : error_message
     493             :     use mo_string_utils, only : num2str
     494             : 
     495             :     implicit none
     496             : 
     497             :     ! no. of rows at an input level
     498             :     integer(i4), intent(in) :: nrowsIn
     499             : 
     500             :     ! no. of cols at an input level
     501             :     integer(i4), intent(in) :: ncolsIn
     502             : 
     503             :     ! xllcorner at an input level
     504             :     real(dp), intent(in) :: xllcornerIn
     505             : 
     506             :     ! yllcorner at an input level
     507             :     real(dp), intent(in) :: yllcornerIn
     508             : 
     509             :     ! cell size at an input level
     510             :     real(dp), intent(in) :: cellsizeIn
     511             : 
     512             :     ! resolution of an output level
     513             :     real(dp), intent(in) :: aimingResolution
     514             : 
     515             :     ! no. of rows at an output level
     516             :     integer(i4), intent(out) :: nrowsOut
     517             : 
     518             :     ! no. of cols at an output level
     519             :     integer(i4), intent(out) :: ncolsOut
     520             : 
     521             :     ! xllcorner at an output level
     522             :     real(dp), intent(out) :: xllcornerOut
     523             : 
     524             :     ! yllcorner at an output level
     525             :     real(dp), intent(out) :: yllcornerOut
     526             : 
     527             :     ! cell size at an output level
     528             :     real(dp), intent(out) :: cellsizeOut
     529             : 
     530          75 :     real(dp) :: cellFactor, rounded
     531             :     integer(i4) :: rounded_int
     532             : 
     533             : 
     534          75 :     cellFactor = aimingResolution / cellsizeIn
     535          75 :     rounded = anint(cellFactor)
     536          75 :     rounded_int = nint(cellFactor)
     537             : 
     538          75 :     if (abs(rounded - cellFactor) > 1.e-7_dp) then
     539             :       call error_message( &
     540             :         '***ERROR: Two resolutions size do not confirm: ', &
     541             :         trim(adjustl(num2str(nint(AimingResolution)))), &
     542           0 :         trim(adjustl(num2str(nint(cellsizeIn)))))
     543             :     end if
     544             : 
     545          75 :     cellsizeOut = aimingResolution
     546          75 :     ncolsOut = nint(real(ncolsIn, dp) / cellFactor)
     547          75 :     nrowsOut = nint(real(nrowsIn, dp) / cellFactor)
     548             : 
     549             :     ! if we rounded down, but now we would miss cells, add rows and/or cols
     550          75 :     if ( ncolsOut * rounded_int < ncolsIn ) ncolsOut = ncolsOut + 1_i4
     551          75 :     if ( nrowsOut * rounded_int < nrowsIn ) nrowsOut = nrowsOut + 1_i4
     552             : 
     553          75 :     xllcornerOut = xllcornerIn + real(ncolsIn, dp) * aimingResolution / rounded - real(ncolsOut, dp) * cellsizeOut
     554          75 :     yllcornerOut = yllcornerIn + real(nrowsIn, dp) * aimingResolution / rounded - real(nrowsOut, dp) * cellsizeOut
     555             : 
     556          75 :   end subroutine calculate_grid_properties
     557             : 
     558             : end module mo_grid

Generated by: LCOV version 1.16