tmm_mf_prism.F90 53 KB

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