tm5.F90 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291
  1. !#################################################################
  2. !
  3. ! TM5 as a library ...
  4. !
  5. !### macro's #####################################################
  6. !
  7. #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
  8. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  9. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  10. !
  11. #include "tm5.inc"
  12. !
  13. !#################################################################
  14. module TM5
  15. use GO, only : gol, goPr, goErr
  16. use GO, only : GO_Timer_Init, GO_Timer_Done, GO_Timer_Def, GO_Timer_Start, GO_Timer_End
  17. #ifdef with_prism
  18. use TM5_Prism, only : comp_name, comp_id
  19. #endif
  20. implicit none
  21. private
  22. public :: TM5_Comm_Init, TM5_Comm_Done, TM5_Comm_Abort
  23. public :: TM5_Messages_Init, TM5_Messages_Done
  24. public :: TM5_Model_Init, TM5_Model_Run, TM5_Model_Done
  25. #ifdef with_prism
  26. public :: comp_name, comp_id
  27. #endif
  28. ! --- const --------------------------------------
  29. character(len=*), parameter :: mname = 'TM5'
  30. ! --- var ----------------------------------------
  31. integer :: itim_init, itim_done
  32. integer :: itim_run_init, itim_run_step, itim_run_done
  33. integer :: itim_run_init_cfl, itim_run_init_setmass, itim_run_init_setothers, itim_run_init_pup, itim_run_init_ssup
  34. integer :: itim_run_init_write_restart, itim_start, itim_output
  35. ! Henk Eskes
  36. integer :: itim_run_assim
  37. contains
  38. ! ===================================================================
  39. ! ===
  40. ! === communication
  41. ! ===
  42. ! ===================================================================
  43. !
  44. ! Setup communication:
  45. ! o MPI_Init
  46. ! o fill npes and myid
  47. !
  48. subroutine TM5_Comm_Init( status, comm )
  49. use ParTools, only : TM5_MPI_Init
  50. use OMP_ParTools, only : TM5_OMP_Init
  51. ! --- in/out ----------------------------------
  52. integer, intent(out) :: status
  53. integer, intent(in), optional :: comm
  54. ! --- const ------------------------------
  55. character(len=*), parameter :: rname = mname//'/TM5_Comm_Init'
  56. ! --- begin -----------------------------------
  57. ! setup mpi stuff if necessary:
  58. call TM5_MPI_Init( status, comm )
  59. IF_NOTOK_RETURN(status=1)
  60. ! setup OpenMP stuff if necessary:
  61. call TM5_OMP_Init( status )
  62. IF_NOTOK_RETURN(status=1)
  63. ! ok
  64. status = 0
  65. end subroutine TM5_Comm_Init
  66. !
  67. ! Stop communication:
  68. ! o MPI_Finalize
  69. !
  70. subroutine TM5_Comm_Done( status, comm )
  71. use ParTools, only : TM5_MPI_Done
  72. ! --- in/out ----------------------------------
  73. integer, intent(out) :: status
  74. integer, intent(in), optional :: comm
  75. ! --- const ------------------------------
  76. character(len=*), parameter :: rname = mname//'/TM5_Comm_Done'
  77. ! --- begin -----------------------------------
  78. ! finalize mpi stuff if necessary:
  79. call TM5_MPI_Done( status, comm )
  80. IF_NOTOK_RETURN(status=1)
  81. ! ok
  82. status = 0
  83. end subroutine TM5_Comm_Done
  84. !
  85. ! Abort communication:
  86. ! o MPI_Abort
  87. !
  88. subroutine TM5_Comm_Abort( errorcode, status )
  89. use ParTools, only : TM5_MPI_Abort
  90. ! --- in/out ----------------------------------
  91. integer, intent(in) :: errorcode
  92. integer, intent(out) :: status
  93. ! --- const ------------------------------
  94. character(len=*), parameter :: rname = mname//'/TM5_Comm_Abort'
  95. ! --- begin -----------------------------------
  96. ! finalize mpi stuff if necessary:
  97. call TM5_MPI_Abort( errorcode, status )
  98. IF_NOTOK_RETURN(status=1)
  99. ! ok
  100. status = 0
  101. end subroutine TM5_Comm_Abort
  102. ! ===================================================================
  103. ! ===
  104. ! === arguments
  105. ! ===
  106. ! ===================================================================
  107. subroutine TM5_Arguments( status )
  108. use GO , only : goArgCount, goGetArg
  109. use global_data, only : rcfile
  110. use partools , only : isRoot, root, Par_Broadcast_Status, Par_Broadcast
  111. ! --- in/out ----------------------------------
  112. integer, intent(out) :: status
  113. ! --- const ----------------------------------
  114. character(len=*), parameter :: rname = mname//'/TM5_Arguments'
  115. ! --- local -----------------------------------
  116. integer :: narg
  117. integer :: iarg
  118. character(len=1024) :: line
  119. ! --- begin -----------------------------------
  120. ! on root only, since some mpirun version do not parse
  121. ! all arguments to each executable:
  122. ! number of arguments:
  123. if (isRoot) call goArgCount( narg, status )
  124. call Par_Broadcast_Status(status, root)
  125. IF_NOTOK_RETURN(status=1)
  126. call Par_Broadcast( narg, status )
  127. IF_NOTOK_RETURN(status=1)
  128. ! check ...
  129. if ( narg == 0 ) then
  130. write (gol,'("no arguments found ...")'); call goErr
  131. TRACEBACK; status=1; return
  132. end if
  133. ! defaults:
  134. rcfile = 'None'
  135. ! loop over arguments:
  136. iarg = 0
  137. do
  138. ! next:
  139. iarg = iarg + 1
  140. ! get argument:
  141. if (isRoot) call goGetArg( iarg, line, status )
  142. call Par_Broadcast_Status(status, root)
  143. IF_NOTOK_RETURN(status=1)
  144. call Par_Broadcast( line, status )
  145. IF_NOTOK_RETURN(status=1)
  146. ! specials ...
  147. select case ( trim(line) )
  148. ! arguments added by MPICH/mpirun :
  149. case ( '-p4pg', '-p4wd' )
  150. ! skip next argument:
  151. iarg = iarg + 1
  152. ! other ...
  153. case default
  154. ! not filled yet ?
  155. if ( trim(rcfile) == 'None' ) then
  156. rcfile = trim(line)
  157. else
  158. write (gol,'("unsupported argument : ",a)') trim(line); call goErr
  159. TRACEBACK; status=1; return
  160. end if
  161. end select
  162. ! last one is processed now ?
  163. if ( iarg == narg ) exit
  164. end do
  165. ! ok
  166. status = 0
  167. end subroutine TM5_Arguments
  168. ! ***
  169. subroutine TM5_Print_Usage( status )
  170. ! --- in/out ---------------------------------
  171. integer, intent(out) :: status
  172. ! --- begin ----------------------------------
  173. ! display usage line:
  174. write (*,'("Usage: tm5.x <rcfile>")')
  175. ! ok
  176. status = 0
  177. end subroutine TM5_Print_Usage
  178. ! ===================================================================
  179. ! ===
  180. ! === messages init/done
  181. ! ===
  182. ! ===================================================================
  183. subroutine TM5_Messages_Init( status )
  184. use GO , only : GO_Print_Init, gol, goPr
  185. use GO , only : TrcFile, Init, Done, ReadRc
  186. use partools , only : npes, myid, root
  187. use global_data, only : rcfile
  188. ! --- in/out ----------------------------------
  189. integer, intent(out) :: status
  190. ! --- const ----------------------------------
  191. character(len=*), parameter :: rname = mname//'/TM5_Messages_Init'
  192. ! --- local -----------------------------------
  193. type(TrcFile) :: rcF
  194. logical :: go_print_all
  195. logical :: go_print_apply
  196. logical :: go_print_trace
  197. logical :: go_print_prompt_pe
  198. logical :: go_print_file
  199. character(len=256) :: go_print_file_base, fname
  200. ! --- begin -----------------------------------
  201. ! read settings:
  202. call Init( rcF, rcfile, status )
  203. IF_NOTOK_RETURN(status=1)
  204. call ReadRc( rcF, 'go.print.all', go_print_all, status, default=.false. )
  205. IF_ERROR_RETURN(status=1)
  206. call ReadRc( rcF, 'go.print.prompt.pe', go_print_prompt_pe, status, default=npes>1 )
  207. IF_ERROR_RETURN(status=1)
  208. call ReadRc( rcF, 'go.print.trace', go_print_trace, status, default=.false. )
  209. IF_ERROR_RETURN(status=1)
  210. call ReadRc( rcF, 'go.print.file', go_print_file, status, default=.false. )
  211. IF_ERROR_RETURN(status=1)
  212. call ReadRc( rcF, 'go.print.file.base', go_print_file_base, status, default='go.out' )
  213. IF_ERROR_RETURN(status=1)
  214. call Done( rcF, status )
  215. IF_NOTOK_RETURN(status=1)
  216. ! standard output by root only:
  217. go_print_apply = go_print_all .or. (myid==root)
  218. ! write to file ?
  219. if ( go_print_file ) then
  220. if ( myid < 10 ) then
  221. write (fname,'(a,".",i1.1)') trim(go_print_file_base), myid
  222. else if ( myid < 100 ) then
  223. write (fname,'(a,".",i2.2)') trim(go_print_file_base), myid
  224. else if ( myid < 1000 ) then
  225. write (fname,'(a,".",i3.3)') trim(go_print_file_base), myid
  226. else
  227. write (fname,'(a,".",i6.6)') trim(go_print_file_base), myid
  228. end if
  229. else
  230. fname = 'stdout'
  231. end if
  232. ! setup standard output processing:
  233. call GO_Print_Init( status, &
  234. apply=go_print_apply, trace=go_print_trace, &
  235. prompt_pe=go_print_prompt_pe, pe=myid, &
  236. file=go_print_file, file_name=fname )
  237. IF_NOTOK_RETURN(status=1)
  238. ! intro message ...
  239. write (gol,'(" ")'); call goPr
  240. write (gol,'("*************************************************************")'); call goPr
  241. write (gol,'("*** ***")'); call goPr
  242. write (gol,'("*** Global Atmospheric Tracer Model TM5 ***")'); call goPr
  243. write (gol,'("*** ***")'); call goPr
  244. write (gol,'("*************************************************************")'); call goPr
  245. write (gol,'(" ")'); call goPr
  246. ! ok
  247. status = 0
  248. end subroutine TM5_Messages_Init
  249. ! ***
  250. subroutine TM5_Messages_Done( status )
  251. use GO, only : GO_Print_Done
  252. ! --- in/out ----------------------------------
  253. integer, intent(out) :: status
  254. ! --- const ------------------------------
  255. character(len=*), parameter :: rname = mname//'/TM5_Messages_Done'
  256. ! --- begin -----------------------------------
  257. ! final message ...
  258. write (gol,'(" ")'); call goPr
  259. write (gol,'("*************************************************************")'); call goPr
  260. write (gol,'("*** ***")'); call goPr
  261. write (gol,'("*** end message log ***")'); call goPr
  262. write (gol,'("*** ***")'); call goPr
  263. write (gol,'("*************************************************************")'); call goPr
  264. write (gol,'(" ")'); call goPr
  265. call GO_Print_Done( status )
  266. IF_NOTOK_RETURN(status=1)
  267. ! ok
  268. status = 0
  269. end subroutine TM5_Messages_Done
  270. ! ====================================================================
  271. ! ===
  272. ! === Timing
  273. ! ===
  274. ! ====================================================================
  275. subroutine TM5_Timing_Init( status )
  276. use GO, only : GO_Timer_Init, GO_Timer_Def
  277. ! --- in/out ---------------------------------
  278. integer, intent(inout) :: status
  279. ! --- const ----------------------------------
  280. character(len=*), parameter :: rname = mname//'/TM5_Timing_Init'
  281. ! --- local ----------------------------------
  282. ! --- begin ----------------------------------
  283. call GO_Timer_Init( status )
  284. IF_NOTOK_RETURN(status=1)
  285. ! define ...
  286. call GO_Timer_Def( itim_init, 'init', status ) ! MODEL_INIT
  287. IF_NOTOK_RETURN(status=1)
  288. ! MODEL_RUN
  289. call GO_Timer_Def( itim_start, 'step start', status )
  290. IF_NOTOK_RETURN(status=1)
  291. call GO_Timer_Def( itim_run_init, 'step init', status )
  292. IF_NOTOK_RETURN(status=1)
  293. call GO_Timer_Def( itim_run_init_cfl, 'step init check cfl', status )
  294. IF_NOTOK_RETURN(status=1)
  295. call GO_Timer_Def( itim_run_init_setmass, 'step init set mass', status )
  296. IF_NOTOK_RETURN(status=1)
  297. call GO_Timer_Def( itim_run_init_setothers, 'step init set others', status )
  298. IF_NOTOK_RETURN(status=1)
  299. call GO_Timer_Def( itim_run_init_pup, 'step init proc update', status )
  300. IF_NOTOK_RETURN(status=1)
  301. call GO_Timer_Def( itim_run_init_ssup, 'step init sources update', status )
  302. IF_NOTOK_RETURN(status=1)
  303. call GO_Timer_Def( itim_run_init_write_restart, 'step init write restart', status )
  304. IF_NOTOK_RETURN(status=1)
  305. call GO_Timer_Def( itim_run_step, 'step run' , status )
  306. IF_NOTOK_RETURN(status=1)
  307. ! Henk Eskes, add step assim
  308. call GO_Timer_Def( itim_run_assim, 'step assim' , status )
  309. IF_NOTOK_RETURN(status=1)
  310. call GO_Timer_Def( itim_run_done, 'step done', status )
  311. IF_NOTOK_RETURN(status=1)
  312. call GO_Timer_Def( itim_output, 'step output', status )
  313. IF_NOTOK_RETURN(status=1)
  314. call GO_Timer_Def( itim_done, 'done', status ) ! MODEL_DONE
  315. IF_NOTOK_RETURN(status=1)
  316. ! ok
  317. status = 0
  318. end subroutine TM5_Timing_Init
  319. ! ***
  320. !--------------------------------------------------------------------------
  321. ! TM5 !
  322. !--------------------------------------------------------------------------
  323. !BOP
  324. !
  325. ! !IROUTINE: TM5_Timing_Done
  326. !
  327. ! !DESCRIPTION: Interface to write profiling output. Get filename and call
  328. ! timer (profiler).
  329. !\\
  330. !\\
  331. ! !INTERFACE:
  332. !
  333. subroutine TM5_Timing_Done( status )
  334. !
  335. ! !USES:
  336. !
  337. use GO, only : pathsep
  338. use GO, only : TrcFile, Init, Done, ReadRc
  339. use GO, only : GO_Timer_Done
  340. use Global_Data, only : rcfile
  341. use Partools, only : myid
  342. !
  343. ! !INPUT/OUTPUT PARAMETERS:
  344. !
  345. integer, intent(inout) :: status
  346. !
  347. ! !REVISION HISTORY:
  348. ! 21 Sep 2010 - P. Le Sager - uses output.dir instead of outputdir
  349. ! (to follow pycasso std)
  350. !
  351. ! !REMARKS:
  352. !
  353. !EOP
  354. !------------------------------------------------------------------------
  355. !BOC
  356. ! --- const ----------------------------------
  357. character(len=*), parameter :: rname = mname//'/TM5_Timing_Done'
  358. ! --- local ----------------------------------
  359. integer :: l
  360. character(len=1024) :: outdir
  361. character(len=256) :: subdir
  362. character(len=1024) :: timing_file
  363. type(TrcFile) :: rcF
  364. logical :: putout
  365. ! --- begin ----------------------------------
  366. ! first open rcfile:
  367. call Init( rcF, rcfile, status )
  368. IF_NOTOK_RETURN(status=1)
  369. ! read flag; by default false to avoid problems with uncreated directories etc:
  370. call ReadRc( rcF, 'timing.output', putout, status, default=.false. )
  371. IF_ERROR_RETURN(status=1)
  372. ! putout ?
  373. if ( putout ) then
  374. ! output directory:
  375. call ReadRc( rcF, 'output.dir', outdir, status )
  376. IF_NOTOK_RETURN(status=1)
  377. ! timing subdirectory:
  378. call ReadRc( rcF, 'timing.output.subdir', subdir, status, default='' )
  379. IF_ERROR_RETURN(status=1)
  380. ! filename to output time profile:
  381. l = len_trim(rcfile)
  382. write (timing_file,'(5a,"_",i4.4,".prf")') &
  383. trim(outdir), pathsep, trim(subdir), pathsep, &
  384. rcfile(1:l-3), myid
  385. ! done with timers; write profile to standard output and file:
  386. call GO_Timer_Done( status, file=trim(timing_file) )
  387. IF_NOTOK_RETURN(status=1)
  388. end if ! putout
  389. ! close:
  390. call Done( rcF, status )
  391. IF_ERROR_RETURN(status=1)
  392. ! ok
  393. status = 0
  394. end subroutine TM5_Timing_Done
  395. !EOC
  396. ! ===================================================================
  397. ! ===
  398. ! === ok file
  399. ! ===
  400. ! ===================================================================
  401. ! Write dummy file 'tm5.ok'.
  402. ! Existence of this file is used by the scripts to check
  403. ! if a run ended properly.
  404. ! Checking exit status would be better, but this does
  405. ! not trap 'stop' statements and other obscure endings.
  406. subroutine TM5_Write_OkFile( status )
  407. use GO, only : goGetFU
  408. ! --- in/out ----------------------------------
  409. integer, intent(out) :: status
  410. ! --- const ------------------------------
  411. character(len=*), parameter :: rname = mname//'/TM5_Write_OkFile'
  412. ! --- local ----------------------------------
  413. integer :: fu
  414. ! --- begin -----------------------------------
  415. ! get free file unit:
  416. call goGetFU( fu, status )
  417. IF_NOTOK_RETURN(status=1)
  418. ! open file:
  419. open( unit=fu, file='tm5.ok', form='formatted', status='unknown', iostat=status )
  420. if ( status/=0 ) then
  421. write (gol,'("from opening okfile")'); call goErr
  422. else
  423. ! write happy message:
  424. write (fu,'("Program terminated normally")',iostat=status)
  425. if ( status/=0 ) then
  426. write (gol,'("from writing to okfile")'); call goErr
  427. else
  428. ! close:
  429. close( fu, iostat=status )
  430. if ( status/=0 ) then
  431. write (gol,'("from closing okfile")'); call goErr
  432. end if
  433. end if
  434. end if
  435. ! ok
  436. status = 0
  437. end subroutine TM5_Write_OkFile
  438. ! ===================================================================
  439. ! ===
  440. ! === model init/done
  441. ! ===
  442. ! ===================================================================
  443. subroutine TM5_Model_Init( status )
  444. use GO, only : TDate, NewDate
  445. use GO, only : TrcFile, Init, Done, ReadRc
  446. use MDF, only : MDF_Init
  447. use geometry, only : calc_dxy, GeomtryH
  448. use dims, only : nregions, dxy11, nlat180, okdebug
  449. use global_data, only : rcfile, declare_fields, region_dat
  450. use tracer_data, only : tracer_print
  451. use ModelIntegration, only : Proces_Init
  452. use Meteo, only : Meteo_Init, Meteo_Init_Grids
  453. use tm5_distgrid, only : tm5_dgrid_init
  454. use redgridZoom, only : RedGrid_Init
  455. #ifdef with_prism
  456. use dims , only : nregions_all,iglbsfc!,iglbsfc_prism
  457. use MeteoData , only : global_lli, levi
  458. use TM5_Prism , only : TM5_Prism_Init, TM5_Prism_Init2
  459. use TM5_Prism , only : ifs_nlev
  460. #endif
  461. #ifdef with_tendencies
  462. use tracer_data, only : PLC_Init
  463. #endif
  464. use initexit, only : control_init
  465. use restart, only : Restart_Init
  466. ! --- in/out ----------------------------------
  467. integer, intent(out) :: status
  468. ! --- const ------------------------------
  469. character(len=*), parameter :: rname = mname//'/TM5_Model_Init'
  470. ! --- local ----------------------------------
  471. type(TrcFile) :: rcF
  472. integer :: region
  473. ! --- begin -----------------------------------
  474. ! extract arguments:
  475. call TM5_Arguments( status )
  476. if (status/=0) then
  477. call TM5_Print_Usage( status )
  478. status=1; return
  479. end if
  480. ! setup messages
  481. call TM5_Messages_Init( status )
  482. IF_NOTOK_RETURN(status=1)
  483. write (gol,'(a,": init model (read control param, init calendar/time) ...")') rname; call goPr
  484. ! Fisrt, read control parameters, since several are required by many inits
  485. CALL CONTROL_INIT( status )
  486. IF_NOTOK_RETURN(status=1)
  487. ! init parallelisation
  488. write (gol,'(a,": init distributed grid ...")') rname; call goPr
  489. call tm5_DGRID_Init( rcfile, status )
  490. IF_NOTOK_RETURN(status=1)
  491. ! init timers:
  492. write (gol,'(a,": init timers ...")') rname; call goPr
  493. call TM5_Timing_Init( status )
  494. IF_NOTOK_RETURN(status=1)
  495. ! start timing ...
  496. call GO_Timer_Start( itim_init, status )
  497. IF_NOTOK_RETURN(status=1)
  498. ! init MDF interface to HDF/NetCDF:
  499. call MDF_Init( status )
  500. IF_NOTOK_RETURN(status=1)
  501. #ifdef with_prism
  502. ! init prism coupler: read coupling parameter from rc file
  503. write (gol,'(a,": init prism ...")') rname; call goPr
  504. call TM5_Prism_Init( rcfile, status )
  505. IF_NOTOK_RETURN(status=1)
  506. #endif
  507. ! setup restart:
  508. write (gol,'(a,": init restart ...")') rname; call goPr
  509. call Restart_Init( status )
  510. IF_NOTOK_RETURN(status=1)
  511. ! setup meteo input:
  512. write (gol,'(a,": init grids ...")') rname; call goPr
  513. call Meteo_Init_Grids( status )
  514. IF_NOTOK_RETURN(status=1)
  515. #ifdef with_prism
  516. ! init prism coupler: grids, partition, coupled variables
  517. write (gol,'(a,": init prism 2 ...")') rname; call goPr
  518. call TM5_Prism_Init2( nregions_all, nregions, iglbsfc, global_lli(1:nregions_all), levi, status )
  519. IF_NOTOK_RETURN(status=1)
  520. #endif
  521. #ifdef with_tendencies
  522. ! init concentration, production, loss rates:
  523. write (gol,'(a,": init production/loss/chemistry ...")') rname; call goPr
  524. call PLC_Init( rcfile, status )
  525. IF_NOTOK_RETURN(status=1)
  526. #endif
  527. ! setup meteo input:
  528. write (gol,'(a,": init meteo (be patient) ...")') rname; call goPr
  529. call Meteo_Init( status )
  530. IF_NOTOK_RETURN(status=1)
  531. ! Allocate tracers and "global data" for this run; fill tracers with 0.
  532. call declare_fields
  533. ! Fill horizontal geometry variables
  534. write (gol,'(a,": horizontal geometry ...")') rname; call goPr
  535. call calc_dxy(dxy11, nlat180) ! grid cell area in 1x1 grid
  536. do region = 1, nregions
  537. call GeomtryH( region ) ! grid definition (set dims:areag(1) and globa_data:region_dat%dxyp)
  538. end do
  539. region_dat(1)%zoomed = 1 ! remains from zooming capabilities
  540. region_dat(1)%edge = 0
  541. ! More geometry and extra data if needed: REDuced GRID
  542. write (gol,'(a,": init reduced grid ...")') rname; call goPr
  543. call redgrid_init( 1, status )
  544. IF_NOTOK_RETURN(status=1)
  545. ! Now we can init processes
  546. write (gol,'(a,": init processes ...")') rname; call goPr
  547. call Proces_Init( status )
  548. IF_NOTOK_RETURN(status=1)
  549. ! Note: this is the earliest that can be called since meteo fields have to be allocated
  550. if ( okdebug ) then
  551. call tracer_print(1, "process init", status)
  552. IF_NOTOK_RETURN(status=1)
  553. end if
  554. write (gol,'(a,": done")') rname; call goPr
  555. write (gol,'(" ")') ; call goPr
  556. ! end timing ...
  557. call GO_Timer_End( itim_init, status )
  558. IF_NOTOK_RETURN(status=1)
  559. ! ok
  560. status = 0
  561. end subroutine TM5_Model_Init
  562. ! ***
  563. subroutine TM5_Model_Done( status )
  564. use MDF , only : MDF_Done
  565. use ModelIntegration, only : Proces_Done
  566. use Meteo , only : Meteo_Done, Meteo_Done_Grids
  567. use tm5_distgrid , only : tm5_dgrid_done
  568. #ifdef with_prism
  569. use TM5_Prism , only : TM5_Prism_Done
  570. #endif
  571. #ifdef with_tendencies
  572. use tracer_data , only : PLC_Done
  573. #endif
  574. use restart , only : Restart_Done
  575. use redgridZoom, only : RedGrid_Done
  576. ! --- in/out ----------------------------------
  577. integer, intent(out) :: status
  578. ! --- const ------------------------------
  579. character(len=*), parameter :: rname = mname//'/TM5_Model_Done'
  580. ! --- local -----------------------------------
  581. integer :: errstat
  582. ! --- begin -----------------------------------
  583. write (gol,'(a,": start")') rname; call goPr
  584. ! start timing ...
  585. call GO_Timer_Start( itim_done, status )
  586. IF_NOTOK_RETURN(status=1)
  587. ! done with restart:
  588. call Restart_Done( status )
  589. IF_NOTOK_RETURN(status=1)
  590. #ifdef with_tendencies
  591. ! done with production/loss rates
  592. call PLC_Done( status )
  593. IF_NOTOK_RETURN(status=1)
  594. #endif
  595. #ifdef with_prism
  596. ! done with prism coupler
  597. call TM5_Prism_Done( status )
  598. IF_NOTOK_RETURN(status=1)
  599. #endif
  600. ! do not break on error from the following routines,
  601. ! to rescue what could be rescued;
  602. ! by default, return status is ok:
  603. errstat = 0
  604. ! done processes
  605. call Proces_Done( status )
  606. if (status/=0) then; TRACEBACK; errstat=1; end if
  607. ! close meteo files etc
  608. call Meteo_Done( status )
  609. if (status/=0) then; TRACEBACK; errstat=1; end if
  610. ! close meteo files etc
  611. call Meteo_Done_Grids( status )
  612. if (status/=0) then; TRACEBACK; errstat=1; end if
  613. ! done with MDF interface to HDF/NetCDF:
  614. call MDF_Done( status )
  615. if (status/=0) then; TRACEBACK; errstat=1; end if
  616. ! end timing ...
  617. call GO_Timer_End( itim_done, status )
  618. if (status/=0) then; TRACEBACK; errstat=1; end if
  619. ! done with timing ...
  620. call TM5_Timing_Done( status )
  621. if (status/=0) then; TRACEBACK; errstat=1; end if
  622. ! done parallelisation
  623. call tm5_dgrid_Done( status )
  624. if (status/=0) then; TRACEBACK; errstat=1; end if
  625. ! done with standard output:
  626. call TM5_Messages_Done( status )
  627. if (status/=0) then; TRACEBACK; errstat=1; end if
  628. call RedGrid_Done( status )
  629. if (status/=0) then; TRACEBACK; errstat=1; end if
  630. ! write dummy file to indicate proper end:
  631. if ( errstat == 0 ) then
  632. call TM5_Write_OkFile( status )
  633. if (status/=0) then; TRACEBACK; errstat=1; end if
  634. end if
  635. write (gol,'(a,": end")') rname; call goPr
  636. write(gol,'(" ")') ; call goPr
  637. ! return with error status if some routines failed:
  638. status = errstat
  639. end subroutine TM5_Model_Done
  640. ! ===================================================================
  641. ! ===
  642. ! === model run
  643. ! ===
  644. ! ===================================================================
  645. subroutine TM5_Model_Run( status )
  646. use GO, only : TrcFile, Init, Done, ReadRc
  647. use GO, only : TDate, NewDate, IncrDate, wrtgol
  648. use GO, only : rTotal, operator(+), operator(-), operator(>), operator(==)
  649. use dims, only : nregions, okdebug
  650. use dims, only : region_status => status
  651. use dims, only : nread
  652. use dims, only : idate, idatee, idatei
  653. use dims, only : itau, itaue, itaur
  654. use dims, only : ndyn_max
  655. use dims, only : nread, ndyn, nconv, nsrce, nchem
  656. use dims, only : revert
  657. use dims, only : newsrun, newmonth
  658. use dims, only : nread, idate
  659. use global_data, only : rcfile
  660. use ParTools, only : Par_Barrier, myid
  661. use datetime, only : inctime
  662. use Meteo, only : Meteo_Setup_Other
  663. use Meteo, only : Meteo_Setup_Mass
  664. #ifndef without_advection
  665. use AdvectM_CFL, only : Check_CFL, Setup_MassFlow
  666. #endif
  667. use ModelIntegration, only : Proces_Update, Proces_Region
  668. use InitExit, only : Start
  669. use InitExit, only : Exitus
  670. use sources_sinks, only : ss_monthly_update
  671. use user_output, only : user_output_done, user_output_mean
  672. #ifdef with_prism
  673. use prism_putget , only : TM5_Prism_Puts!, TM5_Prism_Gets
  674. #endif
  675. #ifdef with_ecearth_optics
  676. use ecearth_optics , only : ECEarth_Optics_Step
  677. use TM5_Prism , only : exchange_period
  678. #endif
  679. #ifdef with_tendencies
  680. use tracer_data, only : plc_reset_period
  681. use tm5_tendency_eval, only : apply_tendency, reset_tendency
  682. #endif
  683. use restart, only : Restart_Save
  684. use datetime, only : tau2date,date2tau
  685. ! Henk Eskes: perform an NO2 retrieval + assimilation step
  686. use assim_interf_mod, only : AssimNO2_interface, AssimNO2_interface_init, AssimNO2_interface_done
  687. ! --- in/out ----------------------------------
  688. integer, intent(out) :: status
  689. ! --- const ----------------------------------
  690. character(len=*), parameter :: rname = mname//'/TM5_Model_Run'
  691. ! --- local ----------------------------------
  692. type(TrcFile) :: rcF
  693. type(TDate) :: tread1, tread2
  694. type(TDate) :: tdyn, tend, tr(2)
  695. logical :: isfirst
  696. integer :: nhalf
  697. logical :: this_is_the_end
  698. logical :: check_pressure
  699. integer :: region
  700. integer :: n
  701. ! CarbonTracker-specific restart quantities; not used unless
  702. ! the rcfile contains a "jobstep.step" key.
  703. integer,dimension(6) :: ct_restart_special = (/0,0,0,0,0,0/)
  704. integer :: ct_itau,jobstep_step
  705. ! --- begin -----------------------------------
  706. ! ~~~ rc file settings ~~~
  707. call GO_Timer_Start( itim_start, status )
  708. IF_NOTOK_RETURN(status=1)
  709. write (gol,'(a,": read settings ...")') rname; call goPr
  710. ! open rcfile:
  711. call Init( rcF, rcfile, status )
  712. IF_NOTOK_RETURN(status=1)
  713. ! ensure that every 'nread' seconds is at the end of a dynamic time step:
  714. call ReadRc( rcF, 'time.ntimestep', nread, status )
  715. IF_NOTOK_RETURN(status=1)
  716. ! a CarbonTracker-specific setting; no error if is it missing
  717. call ReadRc( rcF, 'jobstep.step' ,jobstep_step, status ,default=0)
  718. IF_ERROR_RETURN(status=1)
  719. ! close rcfile:
  720. call Done( rcF, status )
  721. IF_NOTOK_RETURN(status=1)
  722. ! ~~~~~~~~~~~~~~~~~~~~~~~~
  723. write (gol,'(a,": call start ..")') rname; call goPr
  724. ! set-up and read user input;
  725. ! return time interval for which meteo was read:
  726. call Start( tread1, tread2, status )
  727. IF_NOTOK_RETURN(status=1)
  728. write (gol,'(a,": setup times ..")') rname; call goPr
  729. ! current time (begin of dynamics step)
  730. tdyn = NewDate( time6=idate )
  731. tend = NewDate( time6=idatee )
  732. !synchronize time-count regions....
  733. itaur(:) = itau
  734. write (gol,'(a,": start time loop ...")') rname; call goPr
  735. write (gol,'(" ")'); call goPr
  736. ! first step in time loop ?
  737. isfirst = .true.
  738. nhalf = 0
  739. if(jobstep_step .gt. 0) then
  740. call date2tau(idatei,ct_itau)
  741. ct_itau=ct_itau + 86400*jobstep_step
  742. call tau2date(ct_itau,ct_restart_special)
  743. end if
  744. call GO_Timer_End( itim_start, status )
  745. IF_NOTOK_RETURN(status=1)
  746. ! Henk Eskes: Initialise assimilation
  747. call AssimNO2_interface_init ( rcFile )
  748. ! time loop over steps ndyn/2 (!)
  749. do
  750. !*************************************************************************
  751. ! *** INIT STEP ***
  752. !*************************************************************************
  753. call GO_Timer_Start( itim_run_init, status )
  754. IF_NOTOK_RETURN(status=1)
  755. ! is this the end time ?
  756. this_is_the_end = (revert*itau) >= (revert*itaue)
  757. ! next half step
  758. nhalf = modulo(nhalf,2) + 1
  759. !
  760. ! *** write restart ***
  761. !
  762. if ( nhalf == 1 ) then
  763. call GO_Timer_Start( itim_run_init_write_restart, status )
  764. IF_NOTOK_RETURN(status=1)
  765. ! eventually save extra restart file, or final save file:
  766. if (all((ct_restart_special - idate) .eq. 0)) then
  767. write (gol,'(a,": Writing restart files for CarbonTracker jobstep.step.")') rname; call goPr
  768. call Restart_Save( status, extra=.false., isfirst=isfirst )
  769. else
  770. ! restart file gets written when extra is .false.
  771. call Restart_Save( status, extra=(.not. this_is_the_end ), isfirst=isfirst )
  772. endif
  773. IF_NOTOK_RETURN(status=1)
  774. call GO_Timer_End( itim_run_init_write_restart, status )
  775. IF_NOTOK_RETURN(status=1)
  776. end if
  777. !
  778. ! *** new time interval ? ***
  779. !
  780. if ( this_is_the_end ) then
  781. call GO_Timer_End( itim_run_init, status )
  782. IF_NOTOK_RETURN(status=1)
  783. exit
  784. endif
  785. !
  786. ! *** Perform assimilation with "ndyn_max" model time step *** (Henk Eskes)
  787. !
  788. if ( mod(itau,ndyn_max) == 0 ) then
  789. call GO_Timer_Start( itim_run_assim, status )
  790. IF_NOTOK_RETURN(status=1)
  791. call wrtgol( '>>> NO2 retrieval-assimilation step for : ', tdyn ); call goPr
  792. call assimNO2_interface( rcFile, ndyn_max, status )
  793. IF_NOTOK_RETURN(status=1)
  794. call GO_Timer_End( itim_run_assim, status )
  795. IF_NOTOK_RETURN(status=1)
  796. end if
  797. if ( nhalf == 1 ) then
  798. call wrtgol( '>>> dynamics step from : ', tdyn ); call goPr
  799. end if
  800. !
  801. ! *** setup data ***
  802. !
  803. ! New meteo (if reached end of time interval for which meteo is valid)
  804. if ( tdyn == tread2 ) then
  805. ! reset possible reduced timestep due to CFL:
  806. ndyn = ndyn_max
  807. nsrce = ndyn_max
  808. nconv = ndyn_max
  809. nchem = ndyn_max
  810. ! setup meteo data for next interval;
  811. ! nread is the length (in seconds) of the interval in which
  812. ! surface pressure is interpolated (and mass fluxes are constant)
  813. tread1 = tdyn
  814. tread2 = tdyn + IncrDate(sec=nread)
  815. if ( tread2 > tend ) tread2 = tend
  816. ! n is the number of dynamic intervals within the
  817. ! time interval for which the meteo has been setup:
  818. n = ceiling( rTotal(tread2-tread1,'sec') / real(ndyn) )
  819. ndyn = nint( rTotal(tread2-tread1,'sec') / n )
  820. ! setup mass and mass fluxes:
  821. ! o skip first time; already called in 'initexit/start'
  822. ! o check pressure implied by advection if advection is applied
  823. #ifdef without_advection
  824. check_pressure = .false.
  825. #else
  826. check_pressure = .true.
  827. #endif
  828. call GO_Timer_Start( itim_run_init_setmass, status )
  829. IF_NOTOK_RETURN(status=1)
  830. call Meteo_Setup_Mass( tread1, tread2, status, check_pressure=check_pressure )
  831. IF_NOTOK_RETURN(status=1)
  832. call GO_Timer_End( itim_run_init_setmass, status )
  833. IF_NOTOK_RETURN(status=1)
  834. #ifndef without_advection
  835. call GO_Timer_Start( itim_run_init_cfl, status )
  836. IF_NOTOK_RETURN(status=1)
  837. ! determine dynamic timestep ndyn for this interval [tread1,tread2] ;
  838. ! the initial number of time steps n is increased until no cfl
  839. ! violations occure
  840. call Check_CFL( tread1, tread2, n, status )
  841. IF_NOTOK_RETURN(status=1)
  842. call GO_Timer_End( itim_run_init_cfl, status )
  843. IF_NOTOK_RETURN(status=1)
  844. #endif
  845. end if
  846. ! Setup meteo for dynamic step tdyn+[0,ndyn]
  847. if ( nhalf == 1 ) then
  848. ! time range of dynamic step:
  849. tr(1) = tdyn
  850. tr(2) = tdyn + IncrDate( sec=ndyn )
  851. call GO_Timer_Start( itim_run_init_setothers, status )
  852. IF_NOTOK_RETURN(status=1)
  853. #ifndef without_advection
  854. ! convert pu/pv to am/bm/cm, eventually time interpolated
  855. call Setup_MassFlow( tr, status )
  856. IF_NOTOK_RETURN(status=1)
  857. #endif
  858. ! setup (interpolate?) other meteo:
  859. call Meteo_Setup_Other( tr(1), tr(2), status )
  860. IF_NOTOK_RETURN(status=1)
  861. call GO_Timer_End( itim_run_init_setothers, status )
  862. IF_NOTOK_RETURN(status=1)
  863. ! Sources and sinks update (must be done after meteo setup [because of the NOx emissions
  864. ! vertical remapping], and before the Proces_Update [because of the getDMS call down the
  865. ! line]). Note that we assume that 'newmonth' is always at nhalf==1
  866. call GO_Timer_Start( itim_run_init_ssup, status )
  867. IF_NOTOK_RETURN(status=1)
  868. if ( newmonth ) then
  869. call ss_monthly_update( status )
  870. IF_NOTOK_RETURN(status=1)
  871. end if
  872. call GO_Timer_End( itim_run_init_ssup, status )
  873. IF_NOTOK_RETURN(status=1)
  874. call GO_Timer_Start( itim_run_init_pup, status )
  875. IF_NOTOK_RETURN(status=1)
  876. ! recalculate proces dependend fields if necessary
  877. call Proces_Update( status )
  878. IF_NOTOK_RETURN(status=1)
  879. call GO_Timer_End( itim_run_init_pup, status )
  880. IF_NOTOK_RETURN(status=1)
  881. end if
  882. #ifdef with_ecearth_optics
  883. if ( (modulo(tdyn%hour,exchange_period)==0) .and. all((/tdyn%min,tdyn%sec,tdyn%mili/)==0) ) then
  884. call wrtgol( 'Calculating aerosol radiative properties for EC-Earth at ', tdyn ); call goPr
  885. call ECEarth_Optics_Step ( status )
  886. IF_NOTOK_RETURN(status=1)
  887. endif
  888. #endif
  889. #ifdef with_prism
  890. ! put concentrations to IFS:
  891. call TM5_Prism_Puts( tdyn, status )
  892. IF_NOTOK_RETURN(status=1)
  893. #endif
  894. call GO_Timer_End( itim_run_init, status )
  895. IF_NOTOK_RETURN(status=1)
  896. !*************************************************************************
  897. ! *** RUN STEP (processes) ***
  898. !*************************************************************************
  899. call GO_Timer_Start( itim_run_step, status )
  900. IF_NOTOK_RETURN(status=1)
  901. if ( ndyn > 0 ) then
  902. ! reset the process status counters:
  903. if ( nhalf == 1 ) region_status(1:nregions) = 0
  904. tr(1) = tdyn
  905. tr(2) = tdyn + IncrDate(sec=ndyn/2)
  906. ! info
  907. if ( okdebug ) then
  908. if ( nhalf == 1 ) then
  909. call wrtgol( '--> first half : ', tr(1), ' - ', tr(2) ); call goPr
  910. end if
  911. ! This was needed for LiNox budget computation script, when LiNOx was not written to budget file
  912. if ( nhalf == 2 ) then
  913. call wrtgol( '--> second half : ', tr(1), ' - ', tr(2) ); call goPr
  914. end if
  915. endif
  916. itaur(:) = itau ! synchronize time-count regions
  917. call Proces_Region( 1, tr, status ) ! start recursive process for the main region = 1
  918. IF_NOTOK_RETURN(status=1)
  919. end if
  920. call GO_Timer_End( itim_run_step, status )
  921. IF_NOTOK_RETURN(status=1)
  922. !*************************************************************************
  923. ! *** DONE STEP (next) ***
  924. !*************************************************************************
  925. !
  926. call GO_Timer_Start( itim_run_done, status )
  927. IF_NOTOK_RETURN(status=1)
  928. ! advance the model time with ndyn/2 seconds:
  929. call inctime
  930. tdyn = tdyn + IncrDate( sec=nint(ndyn/2.0) )
  931. ! update mean outputs:
  932. if ( mod(itau,ndyn_max) == 0) then
  933. call user_output_mean( status )
  934. IF_NOTOK_RETURN(status=1)
  935. end if
  936. call GO_Timer_End( itim_run_done, status )
  937. IF_NOTOK_RETURN(status=1)
  938. ! end first time loop
  939. isfirst = .false.
  940. END DO ! MAIN LOOP
  941. ! Finalise assimilation (Henk Eskes)
  942. call AssimNO2_interface_done()
  943. call GO_Timer_Start( itim_output, status )
  944. IF_NOTOK_RETURN(status=1)
  945. ! complete user-specified output:
  946. call user_output_done( status )
  947. IF_NOTOK_RETURN(status=1)
  948. ! store save file etc
  949. call exitus( status )
  950. IF_NOTOK_RETURN(status=1)
  951. call GO_Timer_End( itim_output, status )
  952. IF_NOTOK_RETURN(status=1)
  953. write (gol,'(a,": end")') rname; call goPr
  954. write(gol,'(" ")') ; call goPr
  955. ! ok
  956. status = 0
  957. end subroutine TM5_Model_Run
  958. end module TM5