tm5.F90 38 KB

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