tmm_mf_prism.F90 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743
  1. !
  2. #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
  3. !
  4. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  5. #define IF_ERROR_RETURN(action) if (status >0) then; TRACEBACK; action; return; end if
  6. !
  7. #include "tm5.inc"
  8. !
  9. !-----------------------------------------------------------------------------
  10. ! TM5 !
  11. !-----------------------------------------------------------------------------
  12. !BOP
  13. !
  14. ! !MODULE: TMM_MF_PRISM
  15. !
  16. ! !DESCRIPTION: Input/output of meteofiles : OASIS3/PRISM version.
  17. !\\
  18. !\\
  19. ! !INTERFACE:
  20. !
  21. MODULE TMM_MF_PRISM
  22. !
  23. ! !USES:
  24. !
  25. use GO, only : gol, goPr, goErr, goBug, goLabel, TDate
  26. use TM5_Prism, only : TshRemap, comp_id
  27. use tm5_distgrid, only : dgrid, Get_DistGrid
  28. implicit none
  29. !
  30. ! !PUBLIC MEMBER FUNCTIONS:
  31. !
  32. public :: cf_overhead ! cloud fraction overhead
  33. public :: mfPrism_Init, mfPrism_Done ! init/done tools for reading MF
  34. public :: TMeteoFile_prism ! MF type for reading prism meteo
  35. public :: Init, Done, ReadRecord ! methods for MF type
  36. !
  37. ! !PUBLIC DATA MEMBERS:
  38. !
  39. character(len=*), parameter :: mname = 'module tmm_mf_prism'
  40. !
  41. ! !PUBLIC TYPES:
  42. !
  43. type TMeteoFile_prism
  44. type(TDate) :: tday ! reference date
  45. end type TMeteoFile_prism
  46. type(TshRemap), save :: shRemap2d, shRemap3d
  47. real, pointer :: spinf2d_sh_raw(:,:,:)
  48. integer :: itim_readrecord ! timer id
  49. !
  50. ! !INTERFACE:
  51. !
  52. interface Init
  53. module procedure mf_Init
  54. end interface
  55. interface Done
  56. module procedure mf_Done
  57. end interface
  58. interface ReadRecord
  59. #ifdef parallel_cplng
  60. module procedure mf_ReadRecord_parallel
  61. #else
  62. module procedure mf_ReadRecord
  63. #endif
  64. end interface
  65. !
  66. ! !REVISION HISTORY:
  67. ! 16 Sep 2013 - Ph. Le Sager - doc, clean up, updated for TM5v4. Remove
  68. ! oasis4 stuff for clarity.
  69. !
  70. ! !REMARKS:
  71. !
  72. !EOP
  73. !------------------------------------------------------------------------
  74. CONTAINS
  75. !--------------------------------------------------------------------------
  76. ! TM5 !
  77. !--------------------------------------------------------------------------
  78. !BOP
  79. !
  80. ! !IROUTINE: MFPRISM_INIT
  81. !
  82. ! !DESCRIPTION: Init tools for remapping spectral fields. Init timer.
  83. !\\
  84. !\\
  85. ! !INTERFACE:
  86. !
  87. SUBROUTINE MFPRISM_INIT( status )
  88. !
  89. ! !USES:
  90. !
  91. use GO, only : NewDate, GO_Timer_Def
  92. use TM5_Prism, only : Init
  93. !
  94. ! !OUTPUT PARAMETERS:
  95. !
  96. integer, intent(out) :: status
  97. !
  98. ! !REMARKS:
  99. !
  100. !EOP
  101. !------------------------------------------------------------------------
  102. !BOC
  103. character(len=*), parameter :: rname = mname//'/mfPrism_Init'
  104. integer :: icache
  105. ! --- begin -----------------------------------------
  106. !
  107. ! spectral remapping
  108. !
  109. call Init( shRemap2d, status )
  110. IF_NOTOK_RETURN(status=1)
  111. call Init( shRemap3d, status )
  112. IF_NOTOK_RETURN(status=1)
  113. nullify( spinf2d_sh_raw )
  114. ! define timer (expected by tmm.F90)
  115. call GO_Timer_Def( itim_readrecord, 'tmm prism readrecord', status )
  116. IF_NOTOK_RETURN(status=1)
  117. status = 0
  118. END SUBROUTINE MFPRISM_INIT
  119. !EOC
  120. !--------------------------------------------------------------------------
  121. ! TM5 !
  122. !--------------------------------------------------------------------------
  123. !BOP
  124. !
  125. ! !IROUTINE: MFPRISM_DONE
  126. !
  127. ! !DESCRIPTION:
  128. !\\
  129. !\\
  130. ! !INTERFACE:
  131. !
  132. SUBROUTINE MFPRISM_DONE( status )
  133. !
  134. ! !USES:
  135. !
  136. use TM5_Prism, only : Done
  137. !
  138. ! !OUTPUT PARAMETERS:
  139. !
  140. integer, intent(out) :: status
  141. !
  142. ! !REMARKS:
  143. !
  144. !EOP
  145. !------------------------------------------------------------------------
  146. !BOC
  147. character(len=*), parameter :: rname = mname//'/mfPrism_Done'
  148. ! --- begin -----------------------------------------
  149. call Done( shRemap2d, status )
  150. IF_NOTOK_RETURN(status=1)
  151. call Done( shRemap3d, status )
  152. IF_NOTOK_RETURN(status=1)
  153. if ( associated(spinf2d_sh_raw) ) deallocate( spinf2d_sh_raw )
  154. status = 0
  155. END SUBROUTINE MFPRISM_DONE
  156. !EOC
  157. !--------------------------------------------------------------------------
  158. ! TM5 !
  159. !--------------------------------------------------------------------------
  160. !BOP
  161. !
  162. ! !IROUTINE: MF_INIT
  163. !
  164. ! !DESCRIPTION: init an prism MF object
  165. !\\
  166. !\\
  167. ! !INTERFACE:
  168. !
  169. SUBROUTINE MF_INIT( mf, tday, status )
  170. !
  171. ! !USES:
  172. !
  173. use GO, only : TDate
  174. !
  175. ! !OUTPUT PARAMETERS:
  176. !
  177. type(TMeteoFile_prism), intent(out) :: mf
  178. !
  179. ! !INPUT PARAMETERS:
  180. !
  181. type(TDate), intent(in) :: tday
  182. integer, intent(out) :: status
  183. !
  184. ! !REMARKS:
  185. !
  186. !EOP
  187. !------------------------------------------------------------------------
  188. !BOC
  189. character(len=*), parameter :: rname = mname//'/mf_Init'
  190. ! --- begin --------------------------------
  191. mf%tday = tday
  192. status = 0
  193. END SUBROUTINE MF_INIT
  194. !EOC
  195. !--------------------------------------------------------------------------
  196. ! TM5 !
  197. !--------------------------------------------------------------------------
  198. !BOP
  199. !
  200. ! !IROUTINE: MF_DONE
  201. !
  202. ! !DESCRIPTION:
  203. !\\
  204. !\\
  205. ! !INTERFACE:
  206. !
  207. SUBROUTINE MF_DONE( mf, status )
  208. !
  209. ! !INPUT/OUTPUT PARAMETERS:
  210. !
  211. type(TMeteoFile_prism), intent(inout) :: mf
  212. !
  213. ! !OUTPUT PARAMETERS:
  214. !
  215. integer, intent(out) :: status
  216. !
  217. ! !REMARKS:
  218. !
  219. !EOP
  220. !------------------------------------------------------------------------
  221. !BOC
  222. character(len=*), parameter :: rname = mname//'/mf_Done'
  223. status = 0
  224. end subroutine mf_Done
  225. !EOC
  226. !--------------------------------------------------------------------------
  227. ! TM5 !
  228. !--------------------------------------------------------------------------
  229. !BOP
  230. !
  231. ! !IROUTINE: MF_READRECORD
  232. !
  233. ! !DESCRIPTION: fill in met field with fields from OASIS3/PRISM coupler
  234. !\\
  235. !\\
  236. ! !INTERFACE:
  237. !
  238. subroutine mf_ReadRecord( mf, paramkey, t1, t2, nuv, nw, &
  239. gridtype, levi, &
  240. lli, ll, sp_ll, &
  241. ggi, gg, sp_gg, &
  242. shi, sh, lnsp_sh, &
  243. tmi, status )
  244. !
  245. ! !USES:
  246. !
  247. use parray, only : pa_SetShape
  248. use GO, only : TDate, wrtgol, IsAnyDate
  249. use GO, only : operator(+), operator(-), operator(/), operator(==), operator(/=)
  250. use GO, only : GO_Timer_Start, GO_Timer_End
  251. use Grid, only : TllGridInfo, TggGridInfo, TshGridInfo, TLevelInfo
  252. use Grid, only : Init, Set
  253. use tmm_info, only : TMeteoInfo, Init, AddHistory
  254. use binas, only : grav
  255. use mod_oasis
  256. use TM5_Prism, only : SetPrismTime
  257. use TM5_Prism, only : Setup, Remap
  258. use TM5_Prism, only : InqCplVar, CplVar
  259. !
  260. ! !INPUT/OUTPUT PARAMETERS:
  261. !
  262. type(TMeteoFile_prism), intent(inout) :: mf
  263. !
  264. ! !INPUT PARAMETERS:
  265. !
  266. character(len=*), intent(in) :: paramkey
  267. type(TDate), intent(in) :: t1, t2
  268. character(len=1), intent(in) :: nuv
  269. character(len=1), intent(in) :: nw
  270. !
  271. ! !OUTPUT PARAMETERS:
  272. !
  273. character(len=2), intent(out) :: gridtype
  274. type(TLevelInfo), intent(out) :: levi
  275. type(TllGridInfo), intent(inout) :: lli
  276. real, pointer :: ll(:,:,:)
  277. real, pointer :: sp_ll(:,:)
  278. type(TggGridInfo), intent(inout) :: ggi
  279. real, pointer :: gg(:,:)
  280. real, pointer :: sp_gg(:)
  281. type(TshGridInfo), intent(inout) :: shi
  282. complex, pointer :: sh(:,:)
  283. complex, pointer :: lnsp_sh(:)
  284. type(TMeteoInfo), intent(out) :: tmi
  285. integer, intent(out) :: status
  286. !
  287. ! !REMARKS:
  288. ! (1) only root arrives here, called from tmm_mf/ReadRecord
  289. !
  290. !EOP
  291. !------------------------------------------------------------------------
  292. !BOC
  293. character(len=*), parameter :: rname = mname//'/mf_ReadRecord'
  294. ! value filled into spinf arrays to define not a number:
  295. real, parameter :: spinf_nan = -1.2345
  296. ! --- local -----------------------------------
  297. type(TDate) :: tmid
  298. integer :: prism_t
  299. real(ip_realwp_p), allocatable :: ifs_ll(:,:)
  300. real(ip_realwp_p), allocatable :: ifs_sp(:)
  301. integer :: ilev
  302. integer :: k
  303. real, allocatable :: sh_raw(:,:,:)
  304. real, allocatable :: sh_zcl(:,:,:)
  305. real, allocatable :: cc_col(:)
  306. real, allocatable :: cc_rev(:)
  307. real, allocatable :: cco_col(:)
  308. real, allocatable :: ccu_rev(:)
  309. integer :: lme
  310. integer :: ivar
  311. integer :: ivar_cco, ivar_ccu
  312. integer :: info
  313. real :: tb_sec
  314. integer :: icache
  315. integer :: i,j,l
  316. character(len=256) :: error_message
  317. ! --- begin ---------------------------------
  318. call goLabel(rname)
  319. call GO_Timer_Start( itim_readrecord, status )
  320. IF_NOTOK_RETURN(status=1)
  321. ! no times defined in t1 and t2 ?
  322. if ( IsAnyDate(t1) .and. IsAnyDate(t2) ) then
  323. ! for constant fields (orography), t1 and t2 are any date;
  324. ! use the tday stored in mf structure for the orography time:
  325. tmid = mf%tday
  326. else
  327. ! in oasis3 always begin of interval:
  328. tmid = t1
  329. end if
  330. ! convert from tm5 time structure to prism time structure:
  331. call SetPrismTime( prism_t, tmid, status )
  332. IF_ERROR_RETURN(status=1)
  333. !write (gol,*) trim(rname)//' '// trim(paramkey); call goPr
  334. ! *************************** READ FIELD ******************************
  335. PARAM: SELECT CASE ( paramkey )
  336. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  337. ! 3D lat/lon fields
  338. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  339. ! Temperature, humidity, cloud fields, convective fluxes and detrainment rates
  340. ! Cloud details:
  341. ! CLWC liquid water content (kg/kg) (halo=0)
  342. ! CIWC ice water content (kg/kg) (halo=0)
  343. ! CC cloud cover (fraction) (halo=0)
  344. case ( 'T', 'Q', 'CLWC', 'CIWC', 'CC', 'CCO','CCU', 'UDMF', 'DDMF', 'UDDR','DDDR' )
  345. call InqCplVar( paramkey, status, ivar=ivar ) ! inquire field number of coupled field
  346. IF_NOTOK_RETURN(status=1)
  347. gridtype = 'll'
  348. ! fill lli
  349. call Get_DistGrid( dgrid( CplVar(ivar)%region ), global_lli=lli )
  350. ! allocate arrays if necessary:
  351. call pa_SetShape( sp_ll, CplVar(ivar)%nlon, CplVar(ivar)%nlat )
  352. call pa_SetShape( ll , CplVar(ivar)%nlon, CplVar(ivar)%nlat, CplVar(ivar)%nlev )
  353. ! ~~ SURFACE PRESSURE ~~
  354. ! inquire field number of coupled field:
  355. call InqCplVar( 'sp', status, ivar=ivar )
  356. IF_NOTOK_RETURN(status=1)
  357. ! in cache ?
  358. if ( CplVar(ivar)%cache_tmid == tmid ) then
  359. sp_ll = CplVar(ivar)%cache_data(:,:,1) ! copy from cache
  360. !write (gol,'(a,i3.3)') " getting SP from CACHE, ivar=",ivar; call goPr
  361. else
  362. !write (gol,'(a,i3.3)') " getting SP from OASIS, ivar=",ivar; call goPr
  363. ilev = 1
  364. allocate( ifs_ll(CplVar(ivar)%nlon,CplVar(ivar)%nlat) ) ! temporary storage with correct kind
  365. CALL OASIS_GET( CplVar(ivar)%var_id(ilev), prism_t, ifs_ll, status )
  366. SELECT CASE ( status )
  367. CASE (OASIS_Recvd, OASIS_FromRest, OASIS_Input, OASIS_RecvOut, OASIS_FromRestOut)
  368. CONTINUE
  369. CASE ( OASIS_OK )
  370. TRACEBACK
  371. WRITE (error_message,'("TMM_MF_PRISM: no exchange, while expected!")')
  372. CALL OASIS_ABORT( comp_id, rname, error_message )
  373. CASE DEFAULT
  374. TRACEBACK
  375. WRITE (error_message,'("TMM_MF_PRISM: Error in OASIS_GET:",i6)') status
  376. CALL OASIS_ABORT( comp_id, rname, error_message )
  377. END SELECT
  378. sp_ll = ifs_ll
  379. deallocate( ifs_ll )
  380. CplVar(ivar)%cache_tmid = tmid ! store in cache
  381. CplVar(ivar)%cache_data(:,:,1) = sp_ll
  382. end if
  383. ! ~~ 3D FIELD ~~
  384. call InqCplVar( paramkey, status, ivar=ivar ) ! inquire field number of coupled field
  385. IF_NOTOK_RETURN(status=1)
  386. !write (gol,'(a,x,a,x,a,i3.3)') " getting", trim(paramkey), "from OASIS, ivar=",ivar; call goPr
  387. ALLOCATE( ifs_ll(CplVar(ivar)%nlon,CplVar(ivar)%nlat) ) ! temporary storage with correct kind
  388. DO ilev = 1, CplVar(ivar)%nlev
  389. CALL OASIS_GET( CplVar(ivar)%var_id(ilev), prism_t, ifs_ll, status )
  390. SELECT CASE ( status )
  391. CASE (OASIS_Recvd, OASIS_FromRest, OASIS_Input, OASIS_RecvOut, OASIS_FromRestOut)
  392. CONTINUE
  393. CASE ( OASIS_OK )
  394. TRACEBACK
  395. WRITE (error_message,'("TMM_MF_PRISM: no exchange, while expected!")')
  396. CALL OASIS_ABORT( comp_id, rname, error_message )
  397. CASE DEFAULT
  398. TRACEBACK
  399. WRITE (error_message,'("TMM_MF_PRISM: Error in OASIS_GET:",i6)') status
  400. CALL OASIS_ABORT( comp_id, rname, error_message )
  401. END SELECT
  402. ll(:,:,CplVar(ivar)%nlev+1-ilev) = ifs_ll ! store; reverse layer order
  403. ENDDO
  404. DEALLOCATE( ifs_ll )
  405. ! convert ...
  406. select case ( paramkey )
  407. case ( 'Q' ) ; ll = min( max( 0.0, ll ), 1.0 ) ! [0-1]
  408. case ( 'CLWC' ) ; ll = min( max( 0.0, ll ), 1.0 ) ! [0-1]
  409. case ( 'CIWC' ) ; ll = min( max( 0.0, ll ), 1.0 ) ! [0-1]
  410. case ( 'CC' ) ; ll = min( max( 0.0, ll ), 1.0 ) ! [0-1]
  411. case ( 'CCO' ) ; ll = min( max( 0.0, ll ), 1.0 ) ! [0-1]
  412. case ( 'CCU' ) ; ll = min( max( 0.0, ll ), 1.0 ) ! [0-1]
  413. end select
  414. ! evaluate CCO / CCU
  415. select case ( paramkey )
  416. case ( 'CCO' )
  417. ! --- overhead cloud cover:
  418. lme = CplVar(ivar)%nlev
  419. allocate( cc_col(lme) )
  420. allocate( cco_col(lme) )
  421. ! !$OMP PARALLEL
  422. do j = 1, CplVar(ivar)%nlat
  423. do i = 1, CplVar(ivar)%nlon
  424. ! cf_overhead requires CC in the reversed vertical order of IFS
  425. do l = 1, lme
  426. cc_col(l) = ll(i,j,lme+1-l)
  427. enddo
  428. call cf_overhead ( lme, cc_col, cco_col )
  429. ! cf_overhead delivers CCO at layer base in the reversed vertical order of IFS
  430. do l = 1, lme
  431. ll(i,j,l)=cco_col(lme+1-l)
  432. enddo
  433. end do
  434. end do
  435. ! !$OMP END PARALLEL
  436. deallocate( cc_col)
  437. deallocate( cco_col)
  438. case ( 'CCU' )
  439. ! --- underfeet cloud cover:
  440. lme = CplVar(ivar)%nlev
  441. allocate( cc_rev(lme) )
  442. allocate( ccu_rev(lme) )
  443. ! !$OMP PARALLEL
  444. do j = 1, CplVar(ivar)%nlat
  445. do i = 1, CplVar(ivar)%nlon
  446. ! for calculating CCU cf_overhead requires CC in the vertical order of TM5
  447. cc_rev = ll(i,j,:)
  448. call cf_overhead( lme, cc_rev, ccu_rev )
  449. ! cf_overhead delivers CCU at layer top in the vertical order of TM5
  450. ll(i,j,:)=ccu_rev
  451. end do
  452. end do
  453. ! !$OMP END PARALLEL
  454. deallocate( cc_rev)
  455. deallocate( ccu_rev)
  456. end select
  457. ! ~~ levels ~~
  458. call InqCplVar( paramkey, status, ivar=ivar )
  459. IF_NOTOK_RETURN(status=1)
  460. ! level info: field is stored in tm level order after receiving
  461. select case ( CplVar(ivar)%nlev )
  462. case ( 19 )
  463. call Init( levi, 'tm19', status )
  464. IF_NOTOK_RETURN(status=1)
  465. case ( 31 )
  466. call Init( levi, 'tm31', status )
  467. IF_NOTOK_RETURN(status=1)
  468. case ( 34 )
  469. call Init( levi, 'tm34', status )
  470. IF_NOTOK_RETURN(status=1)
  471. case ( 40 )
  472. call Init( levi, 'tm40', status )
  473. IF_NOTOK_RETURN(status=1)
  474. case ( 60 )
  475. call Init( levi, 'tm60', status )
  476. IF_NOTOK_RETURN(status=1)
  477. case ( 62 )
  478. call Init( levi, 'tm62', status )
  479. IF_NOTOK_RETURN(status=1)
  480. case ( 91 )
  481. call Init( levi, 'tm91', status )
  482. IF_NOTOK_RETURN(status=1)
  483. case default
  484. write (gol,'("unsupported ifs nlev : ",i4)') CplVar(ivar)%nlev; call goErr
  485. write (gol,'("in ",a)') rname; call goErr; status=1; return
  486. end select
  487. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  488. ! 2D surface fields
  489. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  490. case ( 'sshf', 'slhf', 'ewss', 'nsss', 'oro', 'lsm', &
  491. 'albedo', 'sr', 'ci', 'sst', 'cp', 'lsp', 'sf', &
  492. 'u10m', 'v10m', 'd2m', 't2m', 'ssr', 'skt', 'src', 'sd', 'swvl1', &
  493. 'tv01', 'tv02', 'tv03', 'tv04', 'tv05', 'tv06', 'tv07', 'tv09', &
  494. 'tv10', 'tv11', 'tv13', 'tv16', 'tv17', 'tv18', 'tv19', 'cvl', 'cvh' )
  495. call InqCplVar( paramkey, status, ivar=ivar )
  496. IF_NOTOK_RETURN(status=1)
  497. gridtype = 'll'
  498. ! intialize lat/lon info:
  499. call Get_DistGrid( dgrid( CplVar(ivar)%region ), global_lli=lli )
  500. ! allocate arrays if necessary:
  501. call pa_SetShape( ll, CplVar(ivar)%nlon, CplVar(ivar)%nlat, 1 )
  502. allocate( ifs_ll(CplVar(ivar)%nlon,CplVar(ivar)%nlat) )
  503. ilev = 1
  504. !write (gol,'(a,x,a,x,a,i3.3)') " getting", trim(paramkey), "from OASIS, ivar=",ivar; call goPr
  505. CALL OASIS_GET( CplVar(ivar)%var_id(ilev), prism_t, ifs_ll, status )
  506. SELECT CASE ( status )
  507. CASE (OASIS_Recvd, OASIS_FromRest, OASIS_Input, OASIS_RecvOut, OASIS_FromRestOut)
  508. CONTINUE
  509. CASE ( OASIS_OK )
  510. TRACEBACK
  511. WRITE (error_message,'("TMM_MF_PRISM: no exchange, while expected!")')
  512. CALL OASIS_ABORT( comp_id, rname, error_message )
  513. CASE DEFAULT
  514. TRACEBACK
  515. WRITE (error_message,'("TMM_MF_PRISM: Error in OASIS_GET:",i6)') status
  516. CALL OASIS_ABORT( comp_id, rname, error_message )
  517. END SELECT
  518. ll(:,:,1) = ifs_ll
  519. deallocate( ifs_ll )
  520. ! CONVERT
  521. select case ( paramkey )
  522. !case ( 'oro' ) ; ll = ll/grav ! m m/s2 -> m <-- oro is in m*m/s2
  523. case ( 'lsm' ) ; ll = min( max( 0.0, ll * 100.0 ), 100.0 ) ! 0-1 -> %
  524. case ( 'albedo', 'ci', 'swvl1', 'cvl', 'cvh' ) ; ll = min( max( 0.0, ll ), 1.0 ) ! [0-1]
  525. case ( 'lsp', 'cp' ) ; ll = max( 0.0, ll / 1000.0 ) ! mm/s -> m/s
  526. ! Snow depth is received as kg/m3,
  527. ! and should be converted to height in m of water equivalent.
  528. ! The water density is here set to 1000. kg/m3.
  529. case ( 'sd', 'src' ) ; ll = max( 0.0, ll / 1000.0 ) ! mm -> m
  530. case ( 'sr', 'sf', 'ssr' ) ; ll = max( 0.0, ll)
  531. case ( 'tv01', 'tv02', 'tv03', 'tv04', 'tv05', 'tv06', 'tv07', 'tv09', &
  532. 'tv10', 'tv11', 'tv13', 'tv16', 'tv17', 'tv18', 'tv19' )
  533. ll = min( max( 0.0, ll ), 100.0 ) ! %
  534. end select
  535. ! * level info (dummy levels)
  536. call Init( levi, 1, (/0.0,0.0/), (/1.0,0.0/), status )
  537. IF_NOTOK_RETURN(status=1)
  538. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  539. ! 2D spectral fields
  540. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  541. case ( 'LNSP' )
  542. call InqCplVar( 'spinf2d', status, ivar=ivar )
  543. IF_NOTOK_RETURN(status=1)
  544. gridtype = 'sh'
  545. ! intialize spherical harmonic field info:
  546. call Init( shi, CplVar(ivar)%shT, status )
  547. IF_NOTOK_RETURN(status=1)
  548. ! allocate array if necessary:
  549. call pa_SetShape( sh, CplVar(ivar)%shn, 1 )
  550. ! raw spectral field from coupler:
  551. allocate( sh_raw(CplVar(ivar)%shn_recv*2,1,1) )
  552. allocate( sh_zcl(2,CplVar(ivar)%shn,1) )
  553. ! * SPINF2D
  554. ! setup remapping if not done yet
  555. if ( shRemap2d%t /= tmid ) then ! receive info field every time step
  556. call InqCplVar( 'spinf2d', status, ivar=ivar )
  557. IF_NOTOK_RETURN(status=1)
  558. allocate( ifs_sp(CplVar(ivar)%shn_recv*2) )
  559. ifs_sp = spinf_nan ! fill with nan
  560. ilev = 1
  561. !write (gol,'(a,i3.3)') " getting SPINF2D from OASIS, ivar=",ivar; call goPr
  562. call OASIS_Get( CplVar(ivar)%var_id(ilev), prism_t, ifs_sp, status )
  563. SELECT CASE ( status )
  564. CASE (OASIS_Recvd, OASIS_FromRest, OASIS_Input, OASIS_RecvOut, OASIS_FromRestOut)
  565. CONTINUE
  566. CASE ( OASIS_OK )
  567. TRACEBACK
  568. WRITE (error_message,'("TMM_MF_PRISM: no exchange, while expected!")')
  569. CALL OASIS_ABORT( comp_id, rname, error_message )
  570. CASE DEFAULT
  571. TRACEBACK
  572. WRITE (error_message,'("TMM_MF_PRISM: Error in OASIS_GET:",i6)') status
  573. CALL OASIS_ABORT( comp_id, rname, error_message )
  574. END SELECT
  575. sh_raw(:,1,1) = ifs_sp
  576. deallocate( ifs_sp )
  577. if ( .not. associated(spinf2d_sh_raw) ) allocate( spinf2d_sh_raw(CplVar(ivar)%shn_recv*2,1,1) )
  578. spinf2d_sh_raw = sh_raw
  579. call Setup( shRemap2d, sh_raw, spinf_nan, status ) ! setup remapping
  580. IF_NOTOK_RETURN(status=1)
  581. shRemap2d%t = tmid ! store time
  582. end if
  583. ! * LNSP
  584. call InqCplVar( 'LNSP', status, ivar=ivar )
  585. IF_NOTOK_RETURN(status=1)
  586. if ( CplVar(ivar)%cache_tmid == tmid ) then ! in cache?
  587. sh_zcl = CplVar(ivar)%cache_data
  588. !write (gol,'(a,i3.3)') " getting LNSP from CACHE, ivar=",ivar; call goPr
  589. else
  590. allocate( ifs_sp(CplVar(ivar)%shn_recv*2) )
  591. ifs_sp = spinf_nan
  592. ilev = 1
  593. !write (gol,'(a,i3.3)') " getting LNSP from OASIS, ivar=",ivar; call goPr
  594. call OASIS_Get( CplVar(ivar)%var_id(ilev), prism_t, ifs_sp, status )
  595. SELECT CASE ( status )
  596. CASE (OASIS_Recvd, OASIS_FromRest, OASIS_Input, OASIS_RecvOut, OASIS_FromRestOut)
  597. CONTINUE
  598. CASE ( OASIS_OK )
  599. TRACEBACK
  600. WRITE (error_message,'("TMM_MF_PRISM: no exchange, while expected!")')
  601. CALL OASIS_ABORT( comp_id, rname, error_message )
  602. CASE DEFAULT
  603. TRACEBACK
  604. WRITE (error_message,'("TMM_MF_PRISM: Error in OASIS_GET:",i6)') status
  605. CALL OASIS_ABORT( comp_id, rname, error_message )
  606. END SELECT
  607. sh_raw(:,1,1) = ifs_sp
  608. deallocate( ifs_sp )
  609. call Remap( shRemap2d, sh_raw, shi, sh_zcl, status )
  610. IF_NOTOK_RETURN(status=1)
  611. CplVar(ivar)%cache_tmid = tmid
  612. CplVar(ivar)%cache_data = sh_zcl
  613. end if
  614. sh = cmplx(sh_zcl(1,:,:),sh_zcl(2,:,:)) ! convert to complex
  615. deallocate( sh_raw )
  616. deallocate( sh_zcl )
  617. ! * level info (dummy levels)
  618. call Init( levi, 1, (/0.0,0.0/), (/1.0,0.0/), status )
  619. IF_NOTOK_RETURN(status=1)
  620. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  621. ! 3D spectral fields
  622. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  623. case ( 'VO', 'D' )
  624. call InqCplVar( paramkey, status, ivar=ivar )
  625. IF_NOTOK_RETURN(status=1)
  626. gridtype = 'sh'
  627. ! intialize spherical harmonic field info:
  628. call Init( shi, CplVar(ivar)%shT, status )
  629. IF_NOTOK_RETURN(status=1)
  630. ! allocate arrays if necessary:
  631. call pa_SetShape( sh , CplVar(ivar)%shn, CplVar(ivar)%nlev )
  632. call pa_SetShape( lnsp_sh, CplVar(ivar)%shn )
  633. ! raw spectral field from coupler:
  634. allocate( sh_raw(CplVar(ivar)%shn_recv*2,CplVar(ivar)%nlev,1) )
  635. allocate( sh_zcl(2,CplVar(ivar)%shn,CplVar(ivar)%nlev) )
  636. ! * SPINF3D
  637. ! setup remapping if not done yet
  638. if ( shRemap3d%t /= tmid ) then
  639. sh_raw = spinf_nan
  640. ! use save field:
  641. do ilev = 1, CplVar(ivar)%nlev
  642. do k = 1, CplVar(ivar)%shn_recv*2
  643. if ( spinf2d_sh_raw(k,1,1) /= spinf_nan ) then
  644. sh_raw(k,ilev,1) = spinf2d_sh_raw(k,1,1) + sign(ilev*0.01,spinf2d_sh_raw(k,1,1))
  645. end if
  646. end do
  647. end do
  648. call Setup( shRemap3d, sh_raw, spinf_nan, status )
  649. IF_NOTOK_RETURN(status=1)
  650. shRemap3d%t = tmid
  651. end if
  652. ! * 3D SPECTRAL FIELD
  653. call InqCplVar( paramkey, status, ivar=ivar )
  654. IF_NOTOK_RETURN(status=1)
  655. if ( CplVar(ivar)%cache_tmid == tmid ) then ! in cache ?
  656. sh_zcl = CplVar(ivar)%cache_data
  657. !write (gol,'(a,x,a,x,a,i3.3)') " getting", trim(paramkey), "from CACHE, ivar=",ivar; call goPr
  658. else
  659. allocate( ifs_sp(CplVar(ivar)%shn_recv*2) )
  660. ifs_sp = spinf_nan
  661. !write (gol,'(a,x,a,x,a,i3.3)') " getting", trim(paramkey), "from OASIS, ivar=",ivar; call goPr
  662. do ilev = 1, CplVar(ivar)%nlev
  663. CALL OASIS_GET( CplVar(ivar)%var_id(ilev), prism_t, ifs_sp, status )
  664. SELECT CASE ( status )
  665. CASE (OASIS_Recvd, OASIS_FromRest, OASIS_Input, OASIS_RecvOut, OASIS_FromRestOut)
  666. CONTINUE
  667. CASE ( OASIS_OK )
  668. TRACEBACK
  669. WRITE (error_message,'("TMM_MF_PRISM: no exchange, while expected!")')
  670. CALL OASIS_ABORT( comp_id, rname, error_message )
  671. CASE DEFAULT
  672. TRACEBACK
  673. WRITE (error_message,'("TMM_MF_PRISM: Error in OASIS_GET:",i6)') status
  674. CALL OASIS_ABORT( comp_id, rname, error_message )
  675. END SELECT
  676. sh_raw(:,ilev,1) = ifs_sp
  677. end do
  678. deallocate( ifs_sp )
  679. call Remap( shRemap3d, sh_raw, shi, sh_zcl, status )
  680. IF_NOTOK_RETURN(status=1)
  681. CplVar(ivar)%cache_tmid = tmid
  682. CplVar(ivar)%cache_data = sh_zcl
  683. end if
  684. ! convert to complex:
  685. sh = cmplx(sh_zcl(1,:,:),sh_zcl(2,:,:))
  686. ! * LNSP
  687. call InqCplVar( 'LNSP', status, ivar=ivar )
  688. IF_NOTOK_RETURN(status=1)
  689. ! copy from cache:
  690. lnsp_sh = cmplx(CplVar(ivar)%cache_data(1,:,1),CplVar(ivar)%cache_data(2,:,1))
  691. deallocate( sh_raw )
  692. deallocate( sh_zcl )
  693. ! * level info
  694. call InqCplVar( paramkey, status, ivar=ivar )
  695. IF_NOTOK_RETURN(status=1)
  696. ! gridless fields are received in original ec order!
  697. select case ( CplVar(ivar)%nlev )
  698. case ( 19 )
  699. call Init( levi, 'ec19', status )
  700. IF_NOTOK_RETURN(status=1)
  701. case ( 31 )
  702. call Init( levi, 'ec31', status )
  703. IF_NOTOK_RETURN(status=1)
  704. case ( 34 )
  705. call Init( levi, 'ec34', status )
  706. IF_NOTOK_RETURN(status=1)
  707. case ( 40 )
  708. call Init( levi, 'ec40', status )
  709. IF_NOTOK_RETURN(status=1)
  710. case ( 60 )
  711. call Init( levi, 'ec60', status )
  712. IF_NOTOK_RETURN(status=1)
  713. case ( 62 )
  714. call Init( levi, 'ec62', status )
  715. IF_NOTOK_RETURN(status=1)
  716. case ( 91 )
  717. call Init( levi, 'ec91', status )
  718. IF_NOTOK_RETURN(status=1)
  719. case default
  720. write (gol,'("unsupported ifs nlev : ",i4)') CplVar(ivar)%nlev; call goErr
  721. write (gol,'("in ",a)') rname; call goErr; status=1; return
  722. end select
  723. case default
  724. write (gol,'("unsupported paramkey `",a,"`")') trim(paramkey); call goErr
  725. write (gol,'("in ",a)') rname; status=1; return; call goErr
  726. END SELECT PARAM
  727. ! fill some info values
  728. call Init( tmi, paramkey, 'unkown', status )
  729. call AddHistory( tmi, 'model==oasis_coupler', status )
  730. call GO_Timer_End( itim_readrecord, status )
  731. IF_NOTOK_RETURN(status=1)
  732. call goLabel()
  733. status = 0
  734. end subroutine mf_ReadRecord
  735. !EOC
  736. subroutine mf_ReadRecord_parallel( mf, paramkey, t1, t2, nuv, nw, &
  737. gridtype, levi, &
  738. lli, ll, sp_ll, &
  739. ggi, gg, sp_gg, &
  740. shi, sh, lnsp_sh, &
  741. tmi, status )
  742. !
  743. ! !USES:
  744. !
  745. use parray, only : pa_SetShape
  746. use GO, only : TDate, wrtgol, IsAnyDate
  747. use GO, only : operator(+), operator(-), operator(/), operator(==), operator(/=)
  748. use GO, only : GO_Timer_Start, GO_Timer_End
  749. use Grid, only : TllGridInfo, TggGridInfo, TshGridInfo, TLevelInfo
  750. use Grid, only : Init, Set
  751. use tmm_info, only : TMeteoInfo, Init, AddHistory
  752. use binas, only : grav
  753. use mod_oasis
  754. use TM5_Prism, only : SetPrismTime
  755. use TM5_Prism, only : Setup, Remap
  756. use TM5_Prism, only : InqCplVar, CplVar
  757. !
  758. ! !INPUT/OUTPUT PARAMETERS:
  759. !
  760. type(TMeteoFile_prism), intent(inout) :: mf
  761. !
  762. ! !INPUT PARAMETERS:
  763. !
  764. character(len=*), intent(in) :: paramkey
  765. type(TDate), intent(in) :: t1, t2
  766. character(len=1), intent(in) :: nuv
  767. character(len=1), intent(in) :: nw
  768. !
  769. ! !OUTPUT PARAMETERS:
  770. !
  771. character(len=2), intent(out) :: gridtype
  772. type(TLevelInfo), intent(out) :: levi
  773. type(TllGridInfo), intent(inout) :: lli
  774. real, pointer :: ll(:,:,:)
  775. real, pointer :: sp_ll(:,:)
  776. type(TggGridInfo), intent(inout) :: ggi
  777. real, pointer :: gg(:,:)
  778. real, pointer :: sp_gg(:)
  779. type(TshGridInfo), intent(inout) :: shi
  780. complex, pointer :: sh(:,:)
  781. complex, pointer :: lnsp_sh(:)
  782. type(TMeteoInfo), intent(out) :: tmi
  783. integer, intent(out) :: status
  784. !
  785. ! !REMARKS:
  786. !
  787. !EOP
  788. !------------------------------------------------------------------------
  789. !BOC
  790. character(len=*), parameter :: rname = mname//'/mf_ReadRecord_parallel'
  791. ! value filled into spinf arrays to define not a number:
  792. real, parameter :: spinf_nan = -1.2345
  793. ! --- local -----------------------------------
  794. type(TDate) :: tmid
  795. integer :: prism_t
  796. real(ip_realwp_p), allocatable :: ifs_ll(:,:)
  797. real(ip_realwp_p), allocatable :: ifs_sp(:)
  798. integer :: ilev
  799. integer :: k
  800. real, allocatable :: sh_raw(:,:,:)
  801. real, allocatable :: sh_zcl(:,:,:)
  802. real, allocatable :: cc_col(:)
  803. real, allocatable :: cc_rev(:)
  804. real, allocatable :: cco_col(:)
  805. real, allocatable :: ccu_rev(:)
  806. integer :: lme
  807. integer :: ivar
  808. integer :: ivar_cco, ivar_ccu
  809. integer :: info
  810. real :: tb_sec
  811. integer :: icache
  812. integer :: i,j,l
  813. character(len=256) :: error_message
  814. ! --- begin ---------------------------------
  815. call goLabel(rname)
  816. call GO_Timer_Start( itim_readrecord, status )
  817. IF_NOTOK_RETURN(status=1)
  818. ! no times defined in t1 and t2 ?
  819. if ( IsAnyDate(t1) .and. IsAnyDate(t2) ) then
  820. ! for constant fields (orography), t1 and t2 are any date;
  821. ! use the tday stored in mf structure for the orography time:
  822. tmid = mf%tday
  823. else
  824. ! in oasis3 always begin of interval:
  825. tmid = t1
  826. end if
  827. ! convert from tm5 time structure to prism time structure:
  828. call SetPrismTime( prism_t, tmid, status )
  829. IF_ERROR_RETURN(status=1)
  830. ! *************************** READ FIELD ******************************
  831. PARAM: SELECT CASE ( paramkey )
  832. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  833. ! 3D lat/lon fields
  834. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  835. ! Temperature, humidity, cloud fields, convective fluxes and detrainment rates
  836. ! Cloud details:
  837. ! CLWC liquid water content (kg/kg) (halo=0)
  838. ! CIWC ice water content (kg/kg) (halo=0)
  839. ! CC cloud cover (fraction) (halo=0)
  840. case ( 'T', 'Q', 'CLWC', 'CIWC', 'CC', 'CCO','CCU', 'UDMF', 'DDMF', 'UDDR','DDDR' )
  841. call InqCplVar( paramkey, status, ivar=ivar ) ! inquire field number of coupled field
  842. IF_NOTOK_RETURN(status=1)
  843. gridtype = 'll'
  844. ! intialize lat/lon info:
  845. call Get_DistGrid( dgrid( CplVar(ivar)%region ), lli=lli )
  846. ! allocate arrays if necessary:
  847. call pa_SetShape( sp_ll, CplVar(ivar)%nlon, CplVar(ivar)%nlat )
  848. call pa_SetShape( ll , CplVar(ivar)%nlon, CplVar(ivar)%nlat, CplVar(ivar)%nlev )
  849. ! ~~ SURFACE PRESSURE ~~
  850. ! inquire field number of coupled field:
  851. call InqCplVar( 'sp', status, ivar=ivar )
  852. IF_NOTOK_RETURN(status=1)
  853. ! in cache ?
  854. if ( CplVar(ivar)%cache_tmid == tmid ) then
  855. sp_ll = CplVar(ivar)%cache_data(:,:,1) ! copy from cache
  856. else
  857. ! Are we really ever getting here???? Looks like SP is computed from LNSP
  858. ilev = 1
  859. allocate( ifs_ll(CplVar(ivar)%nlon,CplVar(ivar)%nlat) ) ! temporary storage with correct kind
  860. CALL OASIS_GET( CplVar(ivar)%var_id(ilev), prism_t, ifs_ll, status )
  861. SELECT CASE ( status )
  862. CASE (OASIS_Recvd, OASIS_FromRest, OASIS_Input, OASIS_RecvOut, OASIS_FromRestOut)
  863. CONTINUE
  864. CASE ( OASIS_OK )
  865. TRACEBACK
  866. WRITE (error_message,'("TMM_MF_PRISM: no exchange, while expected!")')
  867. CALL OASIS_ABORT( comp_id, rname, error_message )
  868. CASE DEFAULT
  869. TRACEBACK
  870. WRITE (error_message,'("TMM_MF_PRISM: Error in OASIS_GET:",i6)') status
  871. CALL OASIS_ABORT( comp_id, rname, error_message )
  872. END SELECT
  873. sp_ll = ifs_ll
  874. deallocate( ifs_ll )
  875. CplVar(ivar)%cache_tmid = tmid ! store in cache
  876. CplVar(ivar)%cache_data(:,:,1) = sp_ll
  877. end if
  878. ! ~~ 3D FIELD ~~
  879. call InqCplVar( paramkey, status, ivar=ivar ) ! inquire field number of coupled field
  880. IF_NOTOK_RETURN(status=1)
  881. ALLOCATE( ifs_ll(CplVar(ivar)%nlon,CplVar(ivar)%nlat) ) ! temporary storage with correct kind
  882. DO ilev = 1, CplVar(ivar)%nlev
  883. CALL OASIS_GET( CplVar(ivar)%var_id(ilev), prism_t, ifs_ll, status )
  884. SELECT CASE ( status )
  885. CASE (OASIS_Recvd, OASIS_FromRest, OASIS_Input, OASIS_RecvOut, OASIS_FromRestOut)
  886. CONTINUE
  887. CASE ( OASIS_OK )
  888. TRACEBACK
  889. WRITE (error_message,'("TMM_MF_PRISM: no exchange, while expected!")')
  890. CALL OASIS_ABORT( comp_id, rname, error_message )
  891. CASE DEFAULT
  892. TRACEBACK
  893. WRITE (error_message,'("TMM_MF_PRISM: Error in OASIS_GET:",i6)') status
  894. CALL OASIS_ABORT( comp_id, rname, error_message )
  895. END SELECT
  896. ll(:,:,CplVar(ivar)%nlev+1-ilev) = ifs_ll ! store; reverse layer order
  897. ENDDO
  898. DEALLOCATE( ifs_ll )
  899. ! convert ...
  900. select case ( paramkey )
  901. case ( 'Q' ) ; ll = min( max( 0.0, ll ), 1.0 ) ! [0-1]
  902. case ( 'CLWC' ) ; ll = min( max( 0.0, ll ), 1.0 ) ! [0-1]
  903. case ( 'CIWC' ) ; ll = min( max( 0.0, ll ), 1.0 ) ! [0-1]
  904. case ( 'CC' ) ; ll = min( max( 0.0, ll ), 1.0 ) ! [0-1]
  905. case ( 'CCO' ) ; ll = min( max( 0.0, ll ), 1.0 ) ! [0-1]
  906. case ( 'CCU' ) ; ll = min( max( 0.0, ll ), 1.0 ) ! [0-1]
  907. end select
  908. ! evaluate CCO / CCU
  909. select case ( paramkey )
  910. case ( 'CCO' )
  911. ! --- overhead cloud cover:
  912. lme = CplVar(ivar)%nlev
  913. allocate( cc_col(lme) )
  914. allocate( cco_col(lme) )
  915. ! !$OMP PARALLEL
  916. do j = 1, CplVar(ivar)%nlat
  917. do i = 1, CplVar(ivar)%nlon
  918. ! cf_overhead requires CC in the reversed vertical order of IFS
  919. do l = 1, lme
  920. cc_col(l) = ll(i,j,lme+1-l)
  921. enddo
  922. call cf_overhead ( lme, cc_col, cco_col )
  923. ! cf_overhead delivers CCO at layer base in the reversed vertical order of IFS
  924. do l = 1, lme
  925. ll(i,j,l)=cco_col(lme+1-l)
  926. enddo
  927. end do
  928. end do
  929. ! !$OMP END PARALLEL
  930. deallocate( cc_col)
  931. deallocate( cco_col)
  932. case ( 'CCU' )
  933. ! --- underfeet cloud cover:
  934. lme = CplVar(ivar)%nlev
  935. allocate( cc_rev(lme) )
  936. allocate( ccu_rev(lme) )
  937. ! !$OMP PARALLEL
  938. do j = 1, CplVar(ivar)%nlat
  939. do i = 1, CplVar(ivar)%nlon
  940. ! for calculating CCU cf_overhead requires CC in the vertical order of TM5
  941. cc_rev = ll(i,j,:)
  942. call cf_overhead( lme, cc_rev, ccu_rev )
  943. ! cf_overhead delivers CCU at layer top in the vertical order of TM5
  944. ll(i,j,:)=ccu_rev
  945. end do
  946. end do
  947. ! !$OMP END PARALLEL
  948. deallocate( cc_rev)
  949. deallocate( ccu_rev)
  950. end select
  951. ! ~~ levels ~~
  952. call InqCplVar( paramkey, status, ivar=ivar )
  953. IF_NOTOK_RETURN(status=1)
  954. ! level info: field is stored in tm level order after receiving
  955. select case ( CplVar(ivar)%nlev )
  956. case ( 19 )
  957. call Init( levi, 'tm19', status )
  958. IF_NOTOK_RETURN(status=1)
  959. case ( 31 )
  960. call Init( levi, 'tm31', status )
  961. IF_NOTOK_RETURN(status=1)
  962. case ( 34 )
  963. call Init( levi, 'tm34', status )
  964. IF_NOTOK_RETURN(status=1)
  965. case ( 40 )
  966. call Init( levi, 'tm40', status )
  967. IF_NOTOK_RETURN(status=1)
  968. case ( 60 )
  969. call Init( levi, 'tm60', status )
  970. IF_NOTOK_RETURN(status=1)
  971. case ( 62 )
  972. call Init( levi, 'tm62', status )
  973. IF_NOTOK_RETURN(status=1)
  974. case ( 91 )
  975. call Init( levi, 'tm91', status )
  976. IF_NOTOK_RETURN(status=1)
  977. case default
  978. write (gol,'("unsupported ifs nlev : ",i4)') CplVar(ivar)%nlev; call goErr
  979. write (gol,'("in ",a)') rname; call goErr; status=1; return
  980. end select
  981. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  982. ! 2D surface fields
  983. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  984. case ( 'sshf', 'slhf', 'ewss', 'nsss', 'oro', 'lsm', &
  985. 'albedo', 'sr', 'ci', 'sst', 'cp', 'lsp', 'sf', &
  986. 'u10m', 'v10m', 'd2m', 't2m', 'ssr', 'skt', 'src', 'sd', 'swvl1', &
  987. 'tv01', 'tv02', 'tv03', 'tv04', 'tv05', 'tv06', 'tv07', 'tv09', &
  988. 'tv10', 'tv11', 'tv13', 'tv16', 'tv17', 'tv18', 'tv19', 'cvl', 'cvh' )
  989. call InqCplVar( paramkey, status, ivar=ivar )
  990. IF_NOTOK_RETURN(status=1)
  991. gridtype = 'll'
  992. ! intialize lat/lon info:
  993. call Get_DistGrid( dgrid( CplVar(ivar)%region ), lli=lli )
  994. ! allocate arrays if necessary:
  995. call pa_SetShape( ll, CplVar(ivar)%nlon, CplVar(ivar)%nlat, 1 )
  996. allocate( ifs_ll(CplVar(ivar)%nlon,CplVar(ivar)%nlat) )
  997. ilev = 1
  998. CALL OASIS_GET( CplVar(ivar)%var_id(ilev), prism_t, ifs_ll, status )
  999. SELECT CASE ( status )
  1000. CASE (OASIS_Recvd, OASIS_FromRest, OASIS_Input, OASIS_RecvOut, OASIS_FromRestOut)
  1001. CONTINUE
  1002. CASE ( OASIS_OK )
  1003. TRACEBACK
  1004. WRITE (error_message,'("TMM_MF_PRISM: no exchange, while expected!")')
  1005. CALL OASIS_ABORT( comp_id, rname, error_message )
  1006. CASE DEFAULT
  1007. TRACEBACK
  1008. WRITE (error_message,'("TMM_MF_PRISM: Error in OASIS_GET:",i6)') status
  1009. CALL OASIS_ABORT( comp_id, rname, error_message )
  1010. END SELECT
  1011. ll(:,:,1) = ifs_ll
  1012. deallocate( ifs_ll )
  1013. ! CONVERT
  1014. select case ( paramkey )
  1015. !case ( 'oro' ) ; ll = ll/grav ! m m/s2 -> m <-- oro is in m*m/s2
  1016. case ( 'lsm' ) ; ll = min( max( 0.0, ll * 100.0 ), 100.0 ) ! 0-1 -> %
  1017. case ( 'albedo', 'ci', 'swvl1', 'cvl', 'cvh' ) ; ll = min( max( 0.0, ll ), 1.0 ) ! [0-1]
  1018. case ( 'lsp', 'cp' ) ; ll = max( 0.0, ll / 1000.0 ) ! mm/s -> m/s
  1019. ! Snow depth is received as kg/m3,
  1020. ! and should be converted to height in m of water equivalent.
  1021. ! The water density is here set to 1000. kg/m3.
  1022. case ( 'sd', 'src' ) ; ll = max( 0.0, ll / 1000.0 ) ! mm -> m
  1023. case ( 'sr', 'sf', 'ssr' ) ; ll = max( 0.0, ll)
  1024. case ( 'tv01', 'tv02', 'tv03', 'tv04', 'tv05', 'tv06', 'tv07', 'tv09', &
  1025. 'tv10', 'tv11', 'tv13', 'tv16', 'tv17', 'tv18', 'tv19' )
  1026. ll = min( max( 0.0, ll ), 100.0 ) ! %
  1027. end select
  1028. ! * level info (dummy levels)
  1029. call Init( levi, 1, (/0.0,0.0/), (/1.0,0.0/), status )
  1030. IF_NOTOK_RETURN(status=1)
  1031. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1032. ! 2D spectral fields
  1033. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1034. case ( 'LNSP' )
  1035. call InqCplVar( 'spinf2d', status, ivar=ivar )
  1036. IF_NOTOK_RETURN(status=1)
  1037. gridtype = 'sh'
  1038. ! intialize spherical harmonic field info:
  1039. call Init( shi, CplVar(ivar)%shT, status )
  1040. IF_NOTOK_RETURN(status=1)
  1041. ! allocate array if necessary:
  1042. call pa_SetShape( sh, CplVar(ivar)%shn, 1 )
  1043. ! raw spectral field from coupler:
  1044. allocate( sh_raw(CplVar(ivar)%shn_recv*2,1,1) )
  1045. allocate( sh_zcl(2,CplVar(ivar)%shn,1) )
  1046. ! * SPINF2D
  1047. ! setup remapping if not done yet
  1048. if ( shRemap2d%t /= tmid ) then ! receive info field every time step
  1049. call InqCplVar( 'spinf2d', status, ivar=ivar )
  1050. IF_NOTOK_RETURN(status=1)
  1051. allocate( ifs_sp(CplVar(ivar)%shn_recv*2) )
  1052. ifs_sp = spinf_nan ! fill with nan
  1053. ilev = 1
  1054. call OASIS_Get( CplVar(ivar)%var_id(ilev), prism_t, ifs_sp, status )
  1055. SELECT CASE ( status )
  1056. CASE (OASIS_Recvd, OASIS_FromRest, OASIS_Input, OASIS_RecvOut, OASIS_FromRestOut)
  1057. CONTINUE
  1058. CASE ( OASIS_OK )
  1059. TRACEBACK
  1060. WRITE (error_message,'("TMM_MF_PRISM: no exchange, while expected!")')
  1061. CALL OASIS_ABORT( comp_id, rname, error_message )
  1062. CASE DEFAULT
  1063. TRACEBACK
  1064. WRITE (error_message,'("TMM_MF_PRISM: Error in OASIS_GET:",i6)') status
  1065. CALL OASIS_ABORT( comp_id, rname, error_message )
  1066. END SELECT
  1067. sh_raw(:,1,1) = ifs_sp
  1068. deallocate( ifs_sp )
  1069. if ( .not. associated(spinf2d_sh_raw) ) allocate( spinf2d_sh_raw(CplVar(ivar)%shn_recv*2,1,1) )
  1070. spinf2d_sh_raw = sh_raw
  1071. call Setup( shRemap2d, sh_raw, spinf_nan, status ) ! setup remapping
  1072. IF_NOTOK_RETURN(status=1)
  1073. shRemap2d%t = tmid ! store time
  1074. end if
  1075. ! * LNSP
  1076. call InqCplVar( 'LNSP', status, ivar=ivar )
  1077. IF_NOTOK_RETURN(status=1)
  1078. if ( CplVar(ivar)%cache_tmid == tmid ) then ! in cache?
  1079. sh_zcl = CplVar(ivar)%cache_data
  1080. else
  1081. allocate( ifs_sp(CplVar(ivar)%shn_recv*2) )
  1082. ifs_sp = spinf_nan
  1083. ilev = 1
  1084. call OASIS_Get( CplVar(ivar)%var_id(ilev), prism_t, ifs_sp, status )
  1085. SELECT CASE ( status )
  1086. CASE (OASIS_Recvd, OASIS_FromRest, OASIS_Input, OASIS_RecvOut, OASIS_FromRestOut)
  1087. CONTINUE
  1088. CASE ( OASIS_OK )
  1089. TRACEBACK
  1090. WRITE (error_message,'("TMM_MF_PRISM: no exchange, while expected!")')
  1091. CALL OASIS_ABORT( comp_id, rname, error_message )
  1092. CASE DEFAULT
  1093. TRACEBACK
  1094. WRITE (error_message,'("TMM_MF_PRISM: Error in OASIS_GET:",i6)') status
  1095. CALL OASIS_ABORT( comp_id, rname, error_message )
  1096. END SELECT
  1097. sh_raw(:,1,1) = ifs_sp
  1098. deallocate( ifs_sp )
  1099. call Remap( shRemap2d, sh_raw, shi, sh_zcl, status )
  1100. IF_NOTOK_RETURN(status=1)
  1101. CplVar(ivar)%cache_tmid = tmid
  1102. CplVar(ivar)%cache_data = sh_zcl
  1103. end if
  1104. sh = cmplx(sh_zcl(1,:,:),sh_zcl(2,:,:)) ! convert to complex
  1105. deallocate( sh_raw )
  1106. deallocate( sh_zcl )
  1107. ! * level info (dummy levels)
  1108. call Init( levi, 1, (/0.0,0.0/), (/1.0,0.0/), status )
  1109. IF_NOTOK_RETURN(status=1)
  1110. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1111. ! 3D spectral fields
  1112. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1113. case ( 'VO', 'D' )
  1114. call InqCplVar( paramkey, status, ivar=ivar )
  1115. IF_NOTOK_RETURN(status=1)
  1116. gridtype = 'sh'
  1117. ! intialize spherical harmonic field info:
  1118. call Init( shi, CplVar(ivar)%shT, status )
  1119. IF_NOTOK_RETURN(status=1)
  1120. ! allocate arrays if necessary:
  1121. call pa_SetShape( sh , CplVar(ivar)%shn, CplVar(ivar)%nlev )
  1122. call pa_SetShape( lnsp_sh, CplVar(ivar)%shn )
  1123. ! raw spectral field from coupler:
  1124. allocate( sh_raw(CplVar(ivar)%shn_recv*2,CplVar(ivar)%nlev,1) )
  1125. allocate( sh_zcl(2,CplVar(ivar)%shn,CplVar(ivar)%nlev) )
  1126. ! * SPINF3D
  1127. ! setup remapping if not done yet
  1128. if ( shRemap3d%t /= tmid ) then
  1129. sh_raw = spinf_nan
  1130. ! use save field:
  1131. do ilev = 1, CplVar(ivar)%nlev
  1132. do k = 1, CplVar(ivar)%shn_recv*2
  1133. if ( spinf2d_sh_raw(k,1,1) /= spinf_nan ) then
  1134. sh_raw(k,ilev,1) = spinf2d_sh_raw(k,1,1) + sign(ilev*0.01,spinf2d_sh_raw(k,1,1))
  1135. end if
  1136. end do
  1137. end do
  1138. call Setup( shRemap3d, sh_raw, spinf_nan, status )
  1139. IF_NOTOK_RETURN(status=1)
  1140. shRemap3d%t = tmid
  1141. end if
  1142. ! * 3D SPECTRAL FIELD
  1143. call InqCplVar( paramkey, status, ivar=ivar )
  1144. IF_NOTOK_RETURN(status=1)
  1145. if ( CplVar(ivar)%cache_tmid == tmid ) then ! in cache ?
  1146. sh_zcl = CplVar(ivar)%cache_data
  1147. else
  1148. allocate( ifs_sp(CplVar(ivar)%shn_recv*2) )
  1149. ifs_sp = spinf_nan
  1150. do ilev = 1, CplVar(ivar)%nlev
  1151. CALL OASIS_GET( CplVar(ivar)%var_id(ilev), prism_t, ifs_sp, status )
  1152. SELECT CASE ( status )
  1153. CASE (OASIS_Recvd, OASIS_FromRest, OASIS_Input, OASIS_RecvOut, OASIS_FromRestOut)
  1154. CONTINUE
  1155. CASE ( OASIS_OK )
  1156. TRACEBACK
  1157. WRITE (error_message,'("TMM_MF_PRISM: no exchange, while expected!")')
  1158. CALL OASIS_ABORT( comp_id, rname, error_message )
  1159. CASE DEFAULT
  1160. TRACEBACK
  1161. WRITE (error_message,'("TMM_MF_PRISM: Error in OASIS_GET:",i6)') status
  1162. CALL OASIS_ABORT( comp_id, rname, error_message )
  1163. END SELECT
  1164. sh_raw(:,ilev,1) = ifs_sp
  1165. end do
  1166. deallocate( ifs_sp )
  1167. call Remap( shRemap3d, sh_raw, shi, sh_zcl, status )
  1168. IF_NOTOK_RETURN(status=1)
  1169. CplVar(ivar)%cache_tmid = tmid
  1170. CplVar(ivar)%cache_data = sh_zcl
  1171. end if
  1172. ! convert to complex:
  1173. sh = cmplx(sh_zcl(1,:,:),sh_zcl(2,:,:))
  1174. ! * LNSP
  1175. call InqCplVar( 'LNSP', status, ivar=ivar )
  1176. IF_NOTOK_RETURN(status=1)
  1177. ! copy from cache:
  1178. lnsp_sh = cmplx(CplVar(ivar)%cache_data(1,:,1),CplVar(ivar)%cache_data(2,:,1))
  1179. deallocate( sh_raw )
  1180. deallocate( sh_zcl )
  1181. ! * level info
  1182. call InqCplVar( paramkey, status, ivar=ivar )
  1183. IF_NOTOK_RETURN(status=1)
  1184. ! gridless fields are received in original ec order!
  1185. select case ( CplVar(ivar)%nlev )
  1186. case ( 19 )
  1187. call Init( levi, 'ec19', status )
  1188. IF_NOTOK_RETURN(status=1)
  1189. case ( 31 )
  1190. call Init( levi, 'ec31', status )
  1191. IF_NOTOK_RETURN(status=1)
  1192. case ( 34 )
  1193. call Init( levi, 'ec34', status )
  1194. IF_NOTOK_RETURN(status=1)
  1195. case ( 40 )
  1196. call Init( levi, 'ec40', status )
  1197. IF_NOTOK_RETURN(status=1)
  1198. case ( 60 )
  1199. call Init( levi, 'ec60', status )
  1200. IF_NOTOK_RETURN(status=1)
  1201. case ( 62 )
  1202. call Init( levi, 'ec62', status )
  1203. IF_NOTOK_RETURN(status=1)
  1204. case ( 91 )
  1205. call Init( levi, 'ec91', status )
  1206. IF_NOTOK_RETURN(status=1)
  1207. case default
  1208. write (gol,'("unsupported ifs nlev : ",i4)') CplVar(ivar)%nlev; call goErr
  1209. write (gol,'("in ",a)') rname; call goErr; status=1; return
  1210. end select
  1211. case default
  1212. write (gol,'("unsupported paramkey `",a,"`")') trim(paramkey); call goErr
  1213. write (gol,'("in ",a)') rname; status=1; return; call goErr
  1214. END SELECT PARAM
  1215. ! fill some info values
  1216. call Init( tmi, paramkey, 'unkown', status )
  1217. call AddHistory( tmi, 'model==oasis_coupler', status )
  1218. call GO_Timer_End( itim_readrecord, status )
  1219. IF_NOTOK_RETURN(status=1)
  1220. call goLabel()
  1221. status = 0
  1222. end subroutine mf_ReadRecord_parallel
  1223. !--------------------------------------------------------------------------
  1224. ! TM5 !
  1225. !--------------------------------------------------------------------------
  1226. !BOP
  1227. !
  1228. ! !IROUTINE: CF_OVERHEAD
  1229. !
  1230. ! !DESCRIPTION:
  1231. !
  1232. ! Calculate total cloud fraction overhead the base of each layer
  1233. ! based on random/maximum overlap assumptions
  1234. ! Based on code provided by Rob van Dorland
  1235. !
  1236. ! Input:
  1237. ! nlev : number of vertical levels
  1238. ! yclfr : cloud fraction (cc) per cell (0-1)
  1239. !
  1240. ! Output:
  1241. ! wccro: overhead cloud fraction
  1242. !
  1243. ! Optional arguments:
  1244. ! scheme='ecmwf' : 'ecmwf' -> iovln=1
  1245. ! 'other' -> iovln=0
  1246. ! eps=1.0e-4 : cltres
  1247. !
  1248. ! Parameters:
  1249. ! iovln : switch
  1250. ! 1 = ecmwf (maximum random overlap assumption) scheme
  1251. ! 0 = another scheme
  1252. ! cltres : threshold (minimum) cloud fraction used
  1253. ! for numerical stability (division by zero
  1254. ! and to eliminate small unrealistic cloud fractions
  1255. !
  1256. ! Notes:
  1257. ! - Index=1 of arrays (yclfr) corresponds to model top
  1258. ! - The clouds are supposed to be distributed homogeneously
  1259. ! in the vertical in each layer.
  1260. !
  1261. !\\
  1262. !\\
  1263. ! !INTERFACE:
  1264. !
  1265. SUBROUTINE CF_OVERHEAD( nlev, yclfr, wccro, scheme, eps )
  1266. !
  1267. ! !INPUT PARAMETERS:
  1268. !
  1269. integer, intent(in) :: nlev
  1270. real, intent(in) :: yclfr(nlev)
  1271. !
  1272. ! !OUTPUT PARAMETERS:
  1273. !
  1274. real, intent(out) :: wccro(nlev)
  1275. !
  1276. ! !OPTIONAL INPUT PARAMETERS:
  1277. !
  1278. character(len=*), intent(in), optional :: scheme
  1279. real, intent(in), optional :: eps
  1280. !
  1281. ! !REVISION HISTORY:
  1282. ! Peter van Velthoven - 22 nov 2002
  1283. ! Arjo Segers - 25 nov 2002 - Optional arguments
  1284. ! Vincent Huijnen - 27 may 2002 - Applied in TM5-IFS coupled code
  1285. !
  1286. ! !REMARKS:
  1287. !
  1288. !EOP
  1289. !------------------------------------------------------------------------
  1290. !BOC
  1291. real :: clfr0, clfr1, clfr2, ctver
  1292. real :: zclear, zcloud
  1293. integer :: jk
  1294. ! --- settings -----------------------------
  1295. integer :: iovln = 1 ! ecmwf; maximum random overlap
  1296. real :: cltres = 1.0e-4
  1297. ! --- begin -----------------------------
  1298. if ( present(scheme) ) then
  1299. select case ( scheme )
  1300. case ( 'ecmwf' )
  1301. iovln = 1
  1302. case ( 'other' )
  1303. iovln = 0
  1304. case default
  1305. print *, 'Unsupported scheme "'//scheme//'".'
  1306. stop 'FATAL BUG IN cf_overhead'
  1307. end select
  1308. end if
  1309. if ( present(eps) ) cltres = eps
  1310. select case ( iovln )
  1311. case ( 0 )
  1312. !-----------------------------------------
  1313. ! scheme 0: maximum overlap unless there's a
  1314. ! clear sky layer in between?
  1315. !-----------------------------------------
  1316. clfr0 = 0.0
  1317. clfr2 = 0.0
  1318. ctver = 1.0
  1319. do jk = 1, nlev
  1320. clfr1 = yclfr(jk)
  1321. if ( clfr1 < cltres ) then
  1322. !----------------
  1323. ! random overlap
  1324. !----------------
  1325. ctver = ctver * ( 1.0 - clfr2 )
  1326. clfr2 = 0.0
  1327. else
  1328. if ( clfr0 < cltres ) then
  1329. clfr2 = clfr1
  1330. else
  1331. !----------------
  1332. ! maximum overlap
  1333. !----------------
  1334. clfr2 = max( clfr1,clfr2 )
  1335. end if
  1336. end if
  1337. clfr0 = clfr1
  1338. wccro(jk) = 1.0 - ctver * ( 1.0 - clfr2 )
  1339. end do
  1340. !ctver=ctver*(1.-clfr2)
  1341. !wccro=1.-ctver
  1342. case ( 1 )
  1343. !-----------------------------------------
  1344. ! ecmwf scheme
  1345. !-----------------------------------------
  1346. zclear = 1.0
  1347. zcloud = 0.0
  1348. do jk = 1, nlev
  1349. zclear = zclear*(1.0-max(yclfr(jk),zcloud))/(1.0-min(zcloud,1.0-cltres))
  1350. zcloud = yclfr(jk)
  1351. wccro(jk) = 1.0 - zclear
  1352. end do
  1353. case default
  1354. print *, 'unknown switch',IOVLN
  1355. stop 'FATAL BUG IN cf_overhead'
  1356. end select
  1357. END SUBROUTINE CF_OVERHEAD
  1358. !EOC
  1359. END MODULE TMM_MF_PRISM