crsini.F90 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. MODULE crsini
  2. !!======================================================================
  3. !! *** MODULE crsini ***
  4. !! Manage the grid coarsening module initialization
  5. !!======================================================================
  6. !! History 2012-05 (J. Simeon, G. Madec, C. Ethe, C. Calone) Original code
  7. !!----------------------------------------------------------------------
  8. USE timing ! Timing
  9. USE par_oce ! For parameter jpi,jpj,jphgr_msh
  10. USE dom_oce ! For parameters in par_oce (jperio, lk_vvl)
  11. USE crs ! Coarse grid domain
  12. USE phycst, ONLY: omega, rad ! physical constants
  13. USE wrk_nemo
  14. USE in_out_manager
  15. USE par_kind, ONLY: wp
  16. USE iom
  17. USE crsdom
  18. USE crsdomwri
  19. USE crslbclnk
  20. USE lib_mpp
  21. IMPLICIT NONE
  22. PRIVATE
  23. PUBLIC crs_init
  24. !! * Substitutions
  25. # include "domzgr_substitute.h90"
  26. !! $Id: crsini.F90 2355 2015-05-20 07:11:50Z ufla $
  27. CONTAINS
  28. SUBROUTINE crs_init
  29. !!-------------------------------------------------------------------
  30. !! *** SUBROUTINE crs_init
  31. !! ** Purpose : Initialization of the grid coarsening module
  32. !! 1. Read namelist
  33. !! X2. MOVE TO crs_dom.F90 Set the domain definitions for coarse grid
  34. !! a. Define the coarse grid starting/ending indices on parent grid
  35. !! Here is where the T-pivot or F-pivot grids are discerned
  36. !! b. TODO. Include option for north-centric or equator-centric binning.
  37. !! (centered only for odd reduction factors; even reduction bins bias equator to the south)
  38. !! 3. Mask and mesh creation. => calls to crsfun
  39. !! a. Use crsfun_mask to generate tmask,umask, vmask, fmask.
  40. !! b. Use crsfun_coordinates to get coordinates
  41. !! c. Use crsfun_UV to get horizontal scale factors
  42. !! d. Use crsfun_TW to get initial vertical scale factors
  43. !! 4. Volumes and weights jes.... TODO. Updates for vvl? Where to do this? crsstp.F90?
  44. !! a. Calculate initial coarse grid box volumes: pvol_T, pvol_W
  45. !! b. Calculate initial coarse grid surface-averaging weights
  46. !! c. Calculate initial coarse grid volume-averaging weights
  47. !!
  48. !! X5. MOVE TO crs_dom_wri.F90 Using iom_rstput output the initial meshmask.
  49. !! ?. Another set of "masks" to generate
  50. !! are the u- and v- surface areas for U- and V- area-weighted means.
  51. !! Need to put this somewhere in section 3?
  52. !! jes. What do to about the vvl? GM. could separate the weighting (denominator), so
  53. !! output C*dA or C*dV as summation not mran, then do mean (division) at moment of output.
  54. !! As is, crsfun takes into account vvl.
  55. !! Talked about pre-setting the surface array to avoid IF/ENDIFS and division.
  56. !! But have then to make that preset array here and elsewhere.
  57. !! that is called every timestep...
  58. !!
  59. !! - Read in pertinent data ?
  60. !!-------------------------------------------------------------------
  61. !! Local variables
  62. INTEGER :: ji,jj,jk ! dummy indices
  63. INTEGER :: ierr ! allocation error status
  64. INTEGER :: ios ! Local integer output status for namelist read
  65. REAL(wp), DIMENSION(:,:,:), POINTER :: zfse3t, zfse3u, zfse3v, zfse3w
  66. NAMELIST/namcrs/ nn_factx, nn_facty, nn_binref, nn_msh_crs, nn_crs_kz, ln_crs_wn
  67. !!----------------------------------------------------------------------
  68. !
  69. IF( nn_timing == 1 ) CALL timing_start('crs_init')
  70. !
  71. IF(lwp) THEN
  72. WRITE(numout,*)
  73. WRITE(numout,*) 'crs_init : Initializing the grid coarsening module '
  74. ENDIF
  75. !---------------------------------------------------------
  76. ! 1. Read Namelist file
  77. !---------------------------------------------------------
  78. !
  79. REWIND( numnam_ref ) ! Namelist namrun in reference namelist : Parameters of the run
  80. READ ( numnam_ref, namcrs, IOSTAT = ios, ERR = 901)
  81. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namcrs in reference namelist', lwp )
  82. REWIND( numnam_cfg ) ! Namelist namrun in configuration namelist : Parameters of the run
  83. READ ( numnam_cfg, namcrs, IOSTAT = ios, ERR = 902 )
  84. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namcrs in configuration namelist', lwp )
  85. IF(lwm) WRITE ( numond, namcrs )
  86. IF(lwp) THEN
  87. WRITE(numout,*)
  88. WRITE(numout,*) 'crs_init: Namelist namcrs '
  89. WRITE(numout,*) ' coarsening factor in i-direction nn_factx = ', nn_factx
  90. WRITE(numout,*) ' coarsening factor in j-direction nn_facty = ', nn_facty
  91. WRITE(numout,*) ' bin centering preference nn_binref = ', nn_binref
  92. WRITE(numout,*) ' create (=1) a mesh file or not (=0) nn_msh_crs = ', nn_msh_crs
  93. WRITE(numout,*) ' type of Kz coarsening (0,1,2) nn_crs_kz = ', nn_crs_kz
  94. WRITE(numout,*) ' wn coarsened or computed using hdivn ln_crs_wn = ', ln_crs_wn
  95. ENDIF
  96. rfactx_r = 1. / nn_factx
  97. rfacty_r = 1. / nn_facty
  98. !---------------------------------------------------------
  99. ! 2. Define Global Dimensions of the coarsened grid
  100. !---------------------------------------------------------
  101. CALL crs_dom_def
  102. !---------------------------------------------------------
  103. ! 3. Mask and Mesh
  104. !---------------------------------------------------------
  105. ! Set up the masks and meshes
  106. ! 3.a. Get the masks
  107. CALL crs_dom_msk
  108. ! 3.b. Get the coordinates
  109. ! Odd-numbered reduction factor, center coordinate on T-cell
  110. ! Even-numbered reduction factor, center coordinate on U-,V- faces or f-corner.
  111. !
  112. IF ( nresty /= 0 .AND. nrestx /= 0 ) THEN
  113. CALL crs_dom_coordinates( gphit, glamt, 'T', gphit_crs, glamt_crs )
  114. CALL crs_dom_coordinates( gphiu, glamu, 'U', gphiu_crs, glamu_crs )
  115. CALL crs_dom_coordinates( gphiv, glamv, 'V', gphiv_crs, glamv_crs )
  116. CALL crs_dom_coordinates( gphif, glamf, 'F', gphif_crs, glamf_crs )
  117. ELSEIF ( nresty /= 0 .AND. nrestx == 0 ) THEN
  118. CALL crs_dom_coordinates( gphiu, glamu, 'T', gphit_crs, glamt_crs )
  119. CALL crs_dom_coordinates( gphiu, glamu, 'U', gphiu_crs, glamu_crs )
  120. CALL crs_dom_coordinates( gphif, glamf, 'V', gphiv_crs, glamv_crs )
  121. CALL crs_dom_coordinates( gphif, glamf, 'F', gphif_crs, glamf_crs )
  122. ELSEIF ( nresty == 0 .AND. nrestx /= 0 ) THEN
  123. CALL crs_dom_coordinates( gphiv, glamv, 'T', gphit_crs, glamt_crs )
  124. CALL crs_dom_coordinates( gphif, glamf, 'U', gphiu_crs, glamu_crs )
  125. CALL crs_dom_coordinates( gphiv, glamv, 'V', gphiv_crs, glamv_crs )
  126. CALL crs_dom_coordinates( gphif, glamf, 'F', gphif_crs, glamf_crs )
  127. ELSE
  128. CALL crs_dom_coordinates( gphif, glamf, 'T', gphit_crs, glamt_crs )
  129. CALL crs_dom_coordinates( gphif, glamf, 'U', gphiu_crs, glamu_crs )
  130. CALL crs_dom_coordinates( gphif, glamf, 'V', gphiv_crs, glamv_crs )
  131. CALL crs_dom_coordinates( gphif, glamf, 'F', gphif_crs, glamf_crs )
  132. ENDIF
  133. ! 3.c. Get the horizontal mesh
  134. ! 3.c.1 Horizontal scale factors
  135. CALL crs_dom_hgr( e1t, e2t, 'T', e1t_crs, e2t_crs )
  136. CALL crs_dom_hgr( e1u, e2u, 'U', e1u_crs, e2u_crs )
  137. CALL crs_dom_hgr( e1v, e2v, 'V', e1v_crs, e2v_crs )
  138. CALL crs_dom_hgr( e1f, e2f, 'F', e1f_crs, e2f_crs )
  139. e1e2t_crs(:,:) = e1t_crs(:,:) * e2t_crs(:,:)
  140. ! 3.c.2 Coriolis factor
  141. SELECT CASE( jphgr_msh ) ! type of horizontal mesh
  142. CASE ( 0, 1, 4 ) ! mesh on the sphere
  143. ff_crs(:,:) = 2. * omega * SIN( rad * gphif_crs(:,:) )
  144. CASE DEFAULT
  145. IF(lwp) WRITE(numout,*) 'crsini.F90. crs_init. Only jphgr_msh = 0, 1 or 4 supported'
  146. END SELECT
  147. ! 3.d.1 mbathy ( vertical k-levels of bathymetry )
  148. CALL crs_dom_bat
  149. !
  150. CALL wrk_alloc(jpi, jpj, jpk, zfse3t, zfse3u, zfse3v, zfse3w )
  151. !
  152. zfse3t(:,:,:) = fse3t(:,:,:)
  153. zfse3u(:,:,:) = fse3u(:,:,:)
  154. zfse3v(:,:,:) = fse3v(:,:,:)
  155. zfse3w(:,:,:) = fse3w(:,:,:)
  156. ! 3.d.2 Surfaces
  157. CALL crs_dom_sfc( tmask, 'W', e1e2w_crs, e1e2w_msk, p_e1=e1t, p_e2=e2t )
  158. CALL crs_dom_sfc( umask, 'U', e2e3u_crs, e2e3u_msk, p_e2=e2u, p_e3=zfse3u )
  159. CALL crs_dom_sfc( vmask, 'V', e1e3v_crs, e1e3v_msk, p_e1=e1v, p_e3=zfse3v )
  160. facsurfu(:,:,:) = umask_crs(:,:,:) * e2e3u_msk(:,:,:) / e2e3u_crs(:,:,:)
  161. facsurfv(:,:,:) = vmask_crs(:,:,:) * e1e3v_msk(:,:,:) / e1e3v_crs(:,:,:)
  162. ! 3.d.3 Vertical scale factors
  163. !
  164. CALL crs_dom_e3( e1t, e2t, zfse3t, e1e2w_crs, 'T', tmask, e3t_crs, e3t_max_crs)
  165. CALL crs_dom_e3( e1u, e2u, zfse3u, e2e3u_crs, 'U', umask, e3u_crs, e3u_max_crs)
  166. CALL crs_dom_e3( e1v, e2v, zfse3v, e1e3v_crs, 'V', vmask, e3v_crs, e3v_max_crs)
  167. CALL crs_dom_e3( e1t, e2t, zfse3w, e1e2w_crs, 'W', tmask, e3w_crs, e3w_max_crs)
  168. ! Reset 0 to e3t_0 or e3w_0
  169. DO jk = 1, jpk
  170. DO ji = 1, jpi_crs
  171. DO jj = 1, jpj_crs
  172. IF( e3t_crs(ji,jj,jk) == 0._wp ) e3t_crs(ji,jj,jk) = e3t_1d(jk)
  173. IF( e3w_crs(ji,jj,jk) == 0._wp ) e3w_crs(ji,jj,jk) = e3w_1d(jk)
  174. IF( e3u_crs(ji,jj,jk) == 0._wp ) e3u_crs(ji,jj,jk) = e3t_1d(jk)
  175. IF( e3v_crs(ji,jj,jk) == 0._wp ) e3v_crs(ji,jj,jk) = e3t_1d(jk)
  176. ENDDO
  177. ENDDO
  178. ENDDO
  179. ! 3.d.3 Vertical depth (meters)
  180. CALL crs_dom_ope( gdept_0, 'MAX', 'T', tmask, gdept_crs, p_e3=zfse3t, psgn=1.0 )
  181. CALL crs_dom_ope( gdepw_0, 'MAX', 'W', tmask, gdepw_crs, p_e3=zfse3w, psgn=1.0 )
  182. !---------------------------------------------------------
  183. ! 4. Coarse grid ocean volume and averaging weights
  184. !---------------------------------------------------------
  185. ! 4.a. Ocean volume or area unmasked and masked
  186. CALL crs_dom_facvol( tmask, 'T', e1t, e2t, zfse3t, ocean_volume_crs_t, facvol_t )
  187. !
  188. bt_crs(:,:,:) = ocean_volume_crs_t(:,:,:) * facvol_t(:,:,:)
  189. !
  190. r1_bt_crs(:,:,:) = 0._wp
  191. WHERE( bt_crs /= 0._wp ) r1_bt_crs(:,:,:) = 1._wp / bt_crs(:,:,:)
  192. CALL crs_dom_facvol( tmask, 'W', e1t, e2t, zfse3w, ocean_volume_crs_w, facvol_w )
  193. !
  194. !---------------------------------------------------------
  195. ! 5. Write out coarse meshmask (see OPA_SRC/DOM/domwri.F90 for ideas later)
  196. !---------------------------------------------------------
  197. IF( nn_msh_crs > 0 ) THEN
  198. CALL dom_grid_crs ! Save the parent grid information & Switch to coarse grid domain
  199. CALL crs_dom_wri
  200. CALL dom_grid_glo ! Return to parent grid domain
  201. ENDIF
  202. !---------------------------------------------------------
  203. ! 7. Finish and clean-up
  204. !---------------------------------------------------------
  205. CALL wrk_dealloc(jpi, jpj, jpk, zfse3t, zfse3u, zfse3v, zfse3w )
  206. END SUBROUTINE crs_init
  207. !!======================================================================
  208. END MODULE crsini