meteodata.F90 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. !### macro's #####################################################
  2. !
  3. #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
  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. module MeteoData
  11. use GO , only : gol, goErr, goPr
  12. use go , only : TDate
  13. use grid , only : TllGridInfo, TLevelInfo
  14. use tmm , only : TMeteoInfo
  15. use dims , only : nregions_all
  16. implicit none
  17. ! --- const ----------------------------------
  18. ! module name
  19. character(len=*), parameter, private :: mname = 'MeteoData'
  20. ! number of surface types in ECMWF
  21. integer, parameter :: nveg = 20
  22. ! --- types -----------------------------------
  23. ! storage for single meteo field:
  24. type TMeteoData
  25. ! in use ?
  26. logical :: used
  27. ! changed ?
  28. logical :: changed
  29. ! description:
  30. character(len=16) :: name ! field name
  31. character(len=16) :: unit ! kg, K, ...
  32. ! time interpolation:
  33. character(len=10) :: tinterp ! const6, interp3, ...
  34. ! shapes:
  35. integer :: is(2), js(2), ls(2) ! shape w/o halo
  36. integer :: halo
  37. ! target data:
  38. real, pointer :: data(:,:,:)
  39. type(TDate) :: tr(2) ! timerange
  40. type(TMeteoInfo) :: tmi ! history info
  41. ! primary data:
  42. real, pointer :: data1(:,:,:)
  43. logical :: filled1
  44. type(TDate) :: tr1(2) ! timerange
  45. type(TMeteoInfo) :: tmi1 ! history info
  46. ! secondary data:
  47. real, pointer :: data2(:,:,:)
  48. logical :: filled2
  49. type(TDate) :: tr2(2) ! timerange
  50. type(TMeteoInfo) :: tmi2 ! history info
  51. ! input:
  52. character(len=256) :: sourcekey
  53. ! output
  54. logical :: putout
  55. character(len=256) :: destkey
  56. end type TMeteoData
  57. ! --- interfaces -----------------------------------
  58. interface Init
  59. module procedure mdat_Init
  60. end interface
  61. interface Done
  62. module procedure mdat_Done
  63. end interface
  64. interface Set
  65. module procedure mdat_Set
  66. end interface
  67. interface Check
  68. module procedure mdat_Check
  69. end interface
  70. interface Alloc
  71. module procedure mdat_Alloc
  72. end interface
  73. interface TimeInterpolation
  74. module procedure mdat_TimeInterpolation
  75. end interface
  76. interface SetData
  77. module procedure mdat_SetData
  78. end interface
  79. ! --- var ---------------------------------------------
  80. ! horizontal grid definitions
  81. type(TllGridInfo), save :: lli(0:nregions_all) ! local (MPI tile) Lat-Lon grid info
  82. type(TllGridInfo), save :: global_lli(0:nregions_all) ! global Lat-Lon grid info
  83. ! zonal grid definitions:
  84. type(TllGridInfo), save :: lli_z(0:nregions_all) ! global zonal grid info
  85. ! vertical grid definition:
  86. type(TLevelInfo) :: levi
  87. type(TLevelInfo) :: levi_ec
  88. ! meteo fields:
  89. type(TMeteoData), save, target :: sp1_dat(1:nregions_all)
  90. type(TMeteoData), save, target :: sp2_dat(1:nregions_all)
  91. type(TMeteoData), save, target :: sp_dat(1:nregions_all)
  92. type(TMeteoData), save, target :: spm_dat(1:nregions_all)
  93. type(TMeteoData), save, target :: tsp_dat(1:nregions_all)
  94. type(TMeteoData), save, target :: phlb_dat(1:nregions_all)
  95. type(TMeteoData), save, target :: m_dat(1:nregions_all)
  96. type(TMeteoData), save, target :: mfu_dat(1:nregions_all)
  97. type(TMeteoData), save, target :: mfv_dat(1:nregions_all)
  98. type(TMeteoData), save, target :: mfw_dat(1:nregions_all)
  99. type(TMeteoData), save, target :: pu_dat(1:nregions_all)
  100. type(TMeteoData), save, target :: pv_dat(1:nregions_all)
  101. type(TMeteoData), save, target :: pw_dat(1:nregions_all)
  102. type(TMeteoData), save, target :: temper_dat(1:nregions_all)
  103. type(TMeteoData), save, target :: humid_dat(1:nregions_all)
  104. type(TMeteoData), save, target :: gph_dat(1:nregions_all)
  105. type(TMeteoData), save, target :: omega_dat(1:nregions_all)
  106. type(TMeteoData), save, target :: lwc_dat(1:nregions_all)
  107. type(TMeteoData), save, target :: iwc_dat(1:nregions_all)
  108. type(TMeteoData), save, target :: cc_dat(1:nregions_all)
  109. type(TMeteoData), save, target :: cco_dat(1:nregions_all)
  110. type(TMeteoData), save, target :: ccu_dat(1:nregions_all)
  111. type(TMeteoData), save, target :: entu_dat(1:nregions_all)
  112. type(TMeteoData), save, target :: entd_dat(1:nregions_all)
  113. type(TMeteoData), save, target :: detu_dat(1:nregions_all)
  114. type(TMeteoData), save, target :: detd_dat(1:nregions_all)
  115. type(TMeteoData), save, target :: kzz_dat(1:nregions_all)
  116. type(TMeteoData), save, target :: oro_dat(1:nregions_all)
  117. type(TMeteoData), save, target :: lsmask_dat(1:nregions_all)
  118. type(TMeteoData), save, target :: albedo_dat(1:nregions_all)
  119. type(TMeteoData), save, target :: sr_ecm_dat(1:nregions_all)
  120. type(TMeteoData), save, target :: sr_ols_dat(1:nregions_all)
  121. type(TMeteoData), save, target :: ci_dat(1:nregions_all)
  122. type(TMeteoData), save, target :: sst_dat(1:nregions_all)
  123. type(TMeteoData), save, target :: u10m_dat(1:nregions_all)
  124. type(TMeteoData), save, target :: v10m_dat(1:nregions_all)
  125. type(TMeteoData), save, target :: sshf_dat(1:nregions_all)
  126. type(TMeteoData), save, target :: slhf_dat(1:nregions_all)
  127. type(TMeteoData), save, target :: ewss_dat(1:nregions_all)
  128. type(TMeteoData), save, target :: nsss_dat(1:nregions_all)
  129. type(TMeteoData), save, target :: lsp_dat(1:nregions_all)
  130. type(TMeteoData), save, target :: cp_dat(1:nregions_all)
  131. type(TMeteoData), save, target :: sd_dat(1:nregions_all)
  132. type(TMeteoData), save, target :: swvl1_dat(1:nregions_all)
  133. type(TMeteoData), save, target :: src_dat(1:nregions_all)
  134. type(TMeteoData), save, target :: d2m_dat(1:nregions_all)
  135. type(TMeteoData), save, target :: t2m_dat(1:nregions_all)
  136. type(TMeteoData), save, target :: ssr_dat(1:nregions_all)
  137. type(TMeteoData), save, target :: ssrd_dat(1:nregions_all)
  138. type(TMeteoData), save, target :: str_dat(1:nregions_all)
  139. type(TMeteoData), save, target :: strd_dat(1:nregions_all)
  140. type(TMeteoData), save, target :: skt_dat(1:nregions_all)
  141. type(TMeteoData), save, target :: tv_dat(1:nregions_all,nveg)
  142. type(TMeteoData), save, target :: cvl_dat(1:nregions_all)
  143. type(TMeteoData), save, target :: cvh_dat(1:nregions_all)
  144. type(TMeteoData), save, target :: blh_dat(1:nregions_all)
  145. type(TMeteoData), save, target :: sf_dat(1:nregions_all)
  146. type(TMeteoData), save, target :: g10m_dat(1:nregions_all)
  147. type(TMeteoData), save, target :: ch4fire_dat(1:nregions_all)
  148. contains
  149. ! ==========================================================
  150. subroutine mdat_Init( md, name, unit, tinterp, is, js, halo, ls, &
  151. sourcekey, putout, destkey, status )
  152. ! --- in/out -----------------------------------
  153. type(TMeteoData), intent(out) :: md
  154. character(len=*), intent(in) :: name, unit
  155. character(len=*), intent(in) :: tinterp
  156. integer, intent(in) :: is(2), js(2)
  157. integer, intent(in) :: halo
  158. integer, intent(in) :: ls(2)
  159. character(len=*), intent(in) :: sourcekey
  160. logical, intent(in) :: putout
  161. character(len=*), intent(in) :: destkey
  162. integer, intent(out) :: status
  163. ! --- const -------------------------------
  164. character(len=*), parameter :: rname = mname//'/mdat_Init'
  165. ! --- begin --------------------------------
  166. ! not in use:
  167. md%used = .false.
  168. ! not changed yet
  169. md%changed = .false.
  170. ! store description:
  171. md%name = name
  172. md%unit = unit
  173. ! store time info:
  174. md%tinterp = tinterp
  175. ! store data shape:
  176. md%is = is
  177. md%js = js
  178. md%halo = halo
  179. md%ls = ls
  180. ! no data allocated yet:
  181. nullify( md%data )
  182. ! no primary data allocated yet:
  183. nullify( md%data1 )
  184. md%filled1 = .false.
  185. ! no secondary data allocated yet:
  186. nullify( md%data2 )
  187. md%filled2 = .false.
  188. ! store input info:
  189. md%sourcekey = sourcekey
  190. ! store output info:
  191. md%putout = putout
  192. md%destkey = destkey
  193. ! ok
  194. status = 0
  195. end subroutine mdat_Init
  196. ! ***
  197. subroutine mdat_Done( md, status )
  198. ! --- in/out -----------------------------------
  199. type(TMeteoData), intent(inout) :: md
  200. integer, intent(out) :: status
  201. ! --- const -------------------------------
  202. character(len=*), parameter :: rname = mname//'/mdat_Done'
  203. ! --- begin --------------------------------
  204. ! deallocate target data if neccesary:
  205. if ( associated(md%data) ) then
  206. ! target data points to data1 ?
  207. if ( associated(md%data,md%data1) ) then
  208. ! data points to data1 :
  209. nullify( md%data )
  210. else
  211. ! data is allocated; clear:
  212. deallocate( md%data )
  213. end if
  214. end if
  215. ! deallocate primary and seondary data:
  216. if ( associated(md%data1) ) deallocate( md%data1 )
  217. if ( associated(md%data2) ) deallocate( md%data2 )
  218. ! for safety ...
  219. md%used = .false.
  220. md%name = 'none'
  221. md%unit = 'none'
  222. ! ok
  223. status = 0
  224. end subroutine mdat_Done
  225. ! ***
  226. subroutine mdat_Set( md, status, used )
  227. ! --- in/out -----------------------------------
  228. type(TMeteoData), intent(inout) :: md
  229. integer, intent(out) :: status
  230. logical, intent(in), optional :: used
  231. ! --- const -------------------------------
  232. character(len=*), parameter :: rname = mname//'/mdat_Set'
  233. ! --- begin --------------------------------
  234. ! code to quickly find which met field is used in your configuration (useful when developping ecearth)
  235. ! if ( present(used) ) then
  236. ! if (used) then
  237. ! write(gol,*)"USED MET FIELD:",md%name; call goPr
  238. ! endif
  239. ! endif
  240. if ( present(used) ) md%used = used
  241. ! ok
  242. status = 0
  243. end subroutine mdat_Set
  244. ! ***
  245. subroutine mdat_Check( md, status )
  246. ! --- in/out -----------------------------------
  247. type(TMeteoData), intent(inout) :: md
  248. integer, intent(out) :: status
  249. ! --- const -------------------------------
  250. character(len=*), parameter :: rname = mname//'/mdat_Check'
  251. ! --- begin --------------------------------
  252. if ( .not. md%used ) then
  253. write (gol,'("meteo data `",a,"` not in use ...")') trim(md%name); call goErr
  254. TRACEBACK; status=1; return
  255. end if
  256. ! ok
  257. status = 0
  258. end subroutine mdat_Check
  259. ! ***
  260. subroutine mdat_Alloc( md, status )
  261. ! --- in/out -----------------------------------
  262. type(TMeteoData), intent(inout) :: md
  263. integer, intent(out) :: status
  264. ! --- const -------------------------------
  265. character(len=*), parameter :: rname = mname//'/mdat_Alloc'
  266. ! --- begin --------------------------------
  267. ! allocate if field is in use:
  268. if ( md%used ) then
  269. ! allocate target, primary, and/or secondary data array;
  270. ! set all to zero to avoid fpe in halo cells during array operations:
  271. select case ( md%tinterp )
  272. ! computed data is stored in target data array:
  273. case ( 'computed' )
  274. ! allocate target data:
  275. allocate( md%data( md%is(1)-md%halo:md%is(2)+md%halo, &
  276. md%js(1)-md%halo:md%js(2)+md%halo, &
  277. md%ls(1) :md%ls(2) ) )
  278. md%data = 0.0
  279. ! constant data is storred in primary data;
  280. ! target data points to data1 :
  281. case ( 'const', 'month', 'const6', 'const3', 'cpl6', 'cpl3', 'cpl2', 'cpl1' )
  282. ! allocate primary data:
  283. allocate( md%data1( md%is(1)-md%halo:md%is(2)+md%halo, &
  284. md%js(1)-md%halo:md%js(2)+md%halo, &
  285. md%ls(1) :md%ls(2) ) )
  286. md%data1 = 0.0
  287. ! point target data:
  288. md%data => md%data1
  289. case ( 'interp6_3', 'interp6', 'interp3', 'interp2', 'interp1', &
  290. 'aver1', 'aver3', 'aver6', 'aver24', 'aver24_3' )
  291. ! allocate target data:
  292. allocate( md%data( md%is(1)-md%halo:md%is(2)+md%halo, &
  293. md%js(1)-md%halo:md%js(2)+md%halo, &
  294. md%ls(1) :md%ls(2) ) )
  295. md%data = 0.0
  296. ! allocate primary data:
  297. allocate( md%data1( md%is(1)-md%halo:md%is(2)+md%halo, &
  298. md%js(1)-md%halo:md%js(2)+md%halo, &
  299. md%ls(1) :md%ls(2) ) )
  300. md%data1 = 0.0
  301. ! allocate secondary data:
  302. allocate( md%data2( md%is(1)-md%halo:md%is(2)+md%halo, &
  303. md%js(1)-md%halo:md%js(2)+md%halo, &
  304. md%ls(1) :md%ls(2) ) )
  305. md%data2 = 0.0
  306. case default
  307. write (gol,'("unsupported time interpolation:")'); call goErr
  308. write (gol,'(" md%tinterp : ",a)') trim(md%tinterp); call goErr
  309. write (gol,'(" md%name : ",a)') trim(md%name); call goErr
  310. TRACEBACK; status=1; return
  311. end select
  312. end if
  313. ! ok
  314. status = 0
  315. end subroutine mdat_Alloc
  316. ! ***
  317. subroutine mdat_SetData( md, mdin, status )
  318. ! Copy MDIN to MD : only %data and %tr
  319. use GO, only : TDate
  320. ! --- in/out -----------------------------------
  321. type(TMeteoData), intent(inout) :: md
  322. type(TMeteoData), intent(in) :: mdin
  323. integer, intent(out) :: status
  324. ! --- const -------------------------------
  325. character(len=*), parameter :: rname = mname//'/mdat_SetData'
  326. ! --- begin --------------------------------
  327. ! skip rest ?
  328. if ( .not. md%used ) then
  329. write (gol,'("WARNING - destination meteo data not in use ...")'); call goPr
  330. write (*,'("WARNING in ",a)') rname; status=1; return
  331. status=0; return
  332. end if
  333. ! check shapes
  334. if ( any(md%is /=mdin%is ) .or. &
  335. any(md%js /=mdin%js ) .or. &
  336. md%halo/=mdin%halo .or. &
  337. any(md%ls /=mdin%ls ) ) then
  338. write (gol,'("destination and source shapes should be the same:")'); call goErr
  339. write (gol,'(" is : ",2i4," , ",2i4)') md%is , mdin%is; call goErr
  340. write (gol,'(" js : ",2i4," , ",2i4)') md%js , mdin%js; call goErr
  341. write (gol,'(" halo : ", i8," , ", i8)') md%halo, mdin%halo; call goErr
  342. write (gol,'(" ls : ",2i4," , ",2i4)') md%ls , mdin%ls; call goErr
  343. TRACEBACK; status=1; return
  344. end if
  345. ! check source data:
  346. if ( .not. associated(mdin%data) ) then
  347. write (gol,'("source data not allocated ...")'); call goErr
  348. TRACEBACK; status=1; return
  349. end if
  350. !if ( .not. mdin%filled ) then
  351. ! write (gol,'("source data not filled")'); call goErr
  352. ! TRACEBACK; status=1; return
  353. !end if
  354. ! check target data:
  355. if ( md%tinterp /= 'computed' ) then
  356. write (gol,'("destination data has wrong tinterp:")'); call goErr
  357. write (gol,'(" expected : ",a)') 'computed'; call goErr
  358. write (gol,'(" found : ",a)') trim(md%tinterp); call goErr
  359. TRACEBACK; status=1; return
  360. end if
  361. if ( .not. associated(md%data) ) then
  362. write (gol,'("destination data not allocated ...")'); call goErr
  363. TRACEBACK; status=1; return
  364. end if
  365. ! check shapes
  366. if ( any( shape(md%data) /= shape(mdin%data) ) ) then
  367. write (gol,'("shapes are not the same:")'); call goErr
  368. write (gol,'(" md : ",3i5)') shape( md%data); call goErr
  369. write (gol,'(" mdin : ",3i5)') shape(mdin%data); call goErr
  370. TRACEBACK; status=1; return
  371. end if
  372. ! copy data:
  373. md%data = mdin%data
  374. md%tr = mdin%tr
  375. ! ok
  376. status = 0
  377. end subroutine mdat_SetData
  378. ! ***
  379. subroutine mdat_TimeInterpolation( md, tr, status )
  380. use go , only : TDate, NewDate, IncrDate, Get
  381. use go , only : wrtgol, InterpolFractions, rTotal
  382. use go , only : operator(/=), operator(<), operator(<=)
  383. use go , only : operator(+), operator(-), operator(/)
  384. use tmm, only : SetHistory, AddHistory
  385. ! --- in/out ----------------------------------
  386. type(TMeteoData), intent(inout) :: md
  387. type(TDate), intent(in) :: tr(2)
  388. integer, intent(out) :: status
  389. ! --- const ----------------------------------
  390. character(len=*), parameter :: rname = mname//'/mdat_TimeInterpolation'
  391. ! --- local ----------------------------------
  392. integer :: dth, baseh
  393. integer :: year, month, day, hour, minu
  394. type(TDate) :: tmid, tc(2)
  395. real :: alfa1, alfa2
  396. ! --- begin -----------------------------
  397. ! not used ? error
  398. if ( .not. md%used ) then
  399. write (gol,'("meteo data `",a,"` not used")') trim(md%name); call goErr
  400. TRACEBACK; status=1; return
  401. end if
  402. ! different actions based on time interpolation type:
  403. select case ( md%tinterp )
  404. !
  405. ! constant data
  406. !
  407. case ( 'const' )
  408. ! md%data points to md%data1, so nothing to be done
  409. !
  410. ! data constant during interval
  411. !
  412. case ( 'month' )
  413. ! check time: tr should be in md%tr1
  414. if ( (tr(2) < md%tr1(1)) .or. (md%tr1(2) < tr(1)) ) then
  415. write (gol,'("model data does not include requested interval:")'); call goErr
  416. write (gol,'(" md%tinterp : ",a)') trim(md%tinterp); call goErr
  417. call wrtgol( ' md%tr1 : ', md%tr1(1), ' - ', md%tr1(2) ); call goErr
  418. call wrtgol( ' tr : ', tr(1), ' - ', tr(2) ); call goErr
  419. TRACEBACK; status=1; return
  420. end if
  421. ! md%data points to md%data1, so no changes
  422. case ( 'const6', 'const3' )
  423. select case ( md%tinterp )
  424. case ( 'const3' ) ; baseh = 0 ; dth = 3
  425. case ( 'const6' ) ; baseh = 0 ; dth = 6
  426. end select
  427. ! extract time values for begin of current interval:
  428. call Get( tr(1), year, month, day, hour, minu )
  429. ! round hour to 00/06/12/18 or 00/03/06/09/12/15/18/21 or 09
  430. !WP! changed line to NOT use the nint function, instead just use int+0.5 which is the same
  431. !WP! for positive numbers, see http://h21007.www2.hp.com/portal/download/files/unprot/Fortran/docs/lrm/lrm0299.htm
  432. !WP! For negative numbers, the lines below need to be added, this can happen only if baseh!=0
  433. !WP! This fixes a problem on the NOAA machines that cause unpredictable crashes when using nint()
  434. !WP!
  435. !dummy=real(hour+minu/60.0-baseh)/real(dth)
  436. !if(dummy>0.0) hour=dth*int(dummy+0.5)+baseh
  437. !if(dummy<0.0) hour=dth*int(dummy-0.5)+baseh
  438. !endif
  439. !WP!
  440. !WP!
  441. ! ported from cy2, 24 Jan 2008, ARJ
  442. hour = dth * int(real(hour+minu/60.0-baseh)/real(dth)+0.5) + baseh
  443. ! set mid of 3 or 6 hour interval:
  444. tmid = NewDate( year, month, day, hour )
  445. ! interval with constant field
  446. tc(1) = tmid - IncrDate(hour=dth)/2
  447. tc(2) = tmid + IncrDate(hour=dth)/2
  448. ! check interval
  449. if ( (tr(1) < tc(1)) .or. (tc(2) < tr(2)) ) then
  450. write (gol,'("time intervals do not match:")'); call goErr
  451. call wrtgol( ' requested : ', tr(1), ' - ', tr(2) ); call goErr
  452. call wrtgol( ' mdin valid for : ', tc(1), ' - ', tc(2) ) ; call goErr
  453. write (gol,'(" mdin%tinterp : ",a)') trim(md%tinterp); call goErr
  454. TRACEBACK; status=1; return
  455. end if
  456. ! md%data points to md%data1, so no changes
  457. !
  458. ! coupling: get field for t, use it for [t,t+dt]
  459. !
  460. case ( 'cpl6', 'cpl3', 'cpl2', 'cpl1' )
  461. select case ( md%tinterp )
  462. case ( 'cpl6' ) ; baseh = 0 ; dth = 6
  463. case ( 'cpl3' ) ; baseh = 0 ; dth = 3
  464. case ( 'cpl2' ) ; baseh = 0 ; dth = 2
  465. case ( 'cpl1' ) ; baseh = 0 ; dth = 1
  466. end select
  467. ! extract time values for begin of current interval:
  468. call Get( tr(1), year, month, day, hour, minu )
  469. ! round hour to 00/06/12/18 or 00/03/06/09/12/15/18/21
  470. hour = dth * floor(real(hour+minu/60.0-baseh)/real(dth)) + baseh
  471. ! interval with constant field
  472. tc(1) = NewDate( year, month, day, hour )
  473. tc(2) = tc(1) + IncrDate(hour=dth)
  474. ! check interval
  475. if ( (tr(1) < tc(1)) .or. (tc(2) < tr(2)) ) then
  476. write (gol,'("time intervals do not match:")'); call goErr
  477. call wrtgol( ' requested : ', tr(1), ' - ', tr(2) ); call goErr
  478. call wrtgol( ' mdin valid for : ', tc(1), ' - ', tc(2) ) ; call goErr
  479. write (gol,'(" mdin%tinterp : ",a)') trim(md%tinterp); call goErr
  480. TRACEBACK; status=1; return
  481. end if
  482. ! md%data points to md%data1, so no changes
  483. !
  484. ! linear interpolation between instant times
  485. !
  486. case ( 'interp6', 'interp6_3', 'interp3', 'interp2', 'interp1' )
  487. ! not filled ? error
  488. if ( (.not. md%filled1) .or. (.not. md%filled2) ) then
  489. write (gol,'("meteo data not filled:")'); call goErr
  490. write (gol,'(" name : ",a)') trim(md%name); call goErr
  491. write (gol,'(" filled : ",2l2)') md%filled1, md%filled2; call goErr
  492. write (gol,'(" md%tinterp : ",a)') trim(md%tinterp); call goErr
  493. TRACEBACK; status=1; return
  494. end if
  495. ! interpolation between instant times, not between intervals ...
  496. if ( (md%tr1(1) /= md%tr1(2)) .or. (md%tr2(1) /= md%tr2(2)) ) then
  497. write (gol,'("time interpolation not between intervals:")'); call goErr
  498. write (gol,'(" md%tinterp : ",a)') trim(md%tinterp); call goErr
  499. call wrtgol( ' tr1 : ', md%tr1(1), ' - ', md%tr1(2) ); call goErr
  500. call wrtgol( ' tr2 : ', md%tr2(1), ' - ', md%tr2(2) ); call goErr
  501. TRACEBACK; status=1; return
  502. end if
  503. ! interpolate to mid of interval:
  504. tmid = tr(1) + (tr(2)-tr(1))/2
  505. ! deterimine weights to data and data2 :
  506. call InterpolFractions( tmid, md%tr1(1), md%tr2(1), alfa1, alfa2, status )
  507. if (status/=0) then; TRACEBACK; return; end if
  508. !$OMP PARALLEL &
  509. !$OMP default (none) &
  510. !$OMP shared (alfa1, alfa2, md)
  511. md%data = alfa1 * md%data1 + alfa2 * md%data2
  512. !$OMP END PARALLEL
  513. ! data is changed ...
  514. md%changed = .true.
  515. !
  516. ! fractions of time average fields:
  517. ! data1 : [tr1(1),tr1(2)]
  518. ! data2 : [tr1(1),tr1(2)]
  519. ! tr : [tr(1),tr(2)]
  520. !
  521. case ( 'aver1', 'aver3', 'aver6', 'aver24', 'aver24_3' )
  522. ! primary data not filled ? error
  523. if ( .not. md%filled1 ) then
  524. write (gol,'("meteo data1 not filled:")'); call goErr
  525. write (gol,'(" name : ",a)') trim(md%name); call goErr
  526. write (gol,'(" md%tinterp : ",a)') trim(md%tinterp); call goErr
  527. TRACEBACK; status=1; return
  528. end if
  529. ! tr earlier than tr1 ? error ...
  530. if ( tr(1) < md%tr1(1) ) then
  531. write (gol,'("requested time interval earlier than data:")'); call goErr
  532. write (gol,'(" md%tinterp : ",a)') trim(md%tinterp); call goErr
  533. call wrtgol( ' md%tr1 : ', md%tr1(1), ' - ', md%tr1(2) ); call goErr
  534. call wrtgol( ' tr : ', tr(1), ' - ', tr(2) ); call goErr
  535. TRACEBACK; status=1; return
  536. end if
  537. ! tr complete in tr1 ? simple ...
  538. if ( tr(2) <= md%tr1(2) ) then
  539. ! just copy ...
  540. md%data = md%data1
  541. ! data is changed ...
  542. md%changed = .true.
  543. else
  544. ! fractions of data1 and data2
  545. ! secondary data not filled ? error
  546. if ( .not. md%filled2 ) then
  547. write (gol,'("meteo data2 not filled:")'); call goErr
  548. write (gol,'(" name : ",a)') trim(md%name); call goErr
  549. write (gol,'(" md%tinterp : ",a)') trim(md%tinterp); call goErr
  550. TRACEBACK; status=1; return
  551. end if
  552. ! time ranges for data1 and data2 should be connected:
  553. if ( md%tr1(2) /= md%tr2(1) ) then
  554. write (gol,'("time intervals not connected:")'); call goErr
  555. call wrtgol( ' md%tr1 : ', md%tr1(1), ' - ', md%tr1(2) ); call goErr
  556. call wrtgol( ' md%tr2 : ', md%tr2(1), ' - ', md%tr2(2) ); call goErr
  557. write (gol,'(" md%tinterp : ",a)') trim(md%tinterp); call goErr
  558. TRACEBACK; status=1; return
  559. end if
  560. ! check requested time range:
  561. if ( (tr(1) < md%tr1(1)) .or. (md%tr2(2) < tr(2)) ) then
  562. write (gol,'("requested time interval not covered by data :")'); call goErr
  563. call wrtgol( ' md%tr1 : ', md%tr1(1), ' - ', md%tr1(2) ); call goErr
  564. call wrtgol( ' md%tr2 : ', md%tr2(1), ' - ', md%tr2(2) ); call goErr
  565. call wrtgol( ' tr : ', tr(1), ' - ', tr(2) ); call goErr
  566. write (gol,'(" md%tinterp : ",a)') trim(md%tinterp); call goErr
  567. TRACEBACK; status=1; return
  568. end if
  569. ! first fraction:
  570. if ( tr(1) < md%tr1(2) ) then
  571. if ( tr(2) < md%tr1(2) ) then
  572. ! tr complete in tr1 ...
  573. alfa1 = 1.0
  574. else
  575. ! fraction of tr inside tr1 :
  576. alfa1 = rTotal(md%tr1(2)-tr(1),'sec') / rTotal(tr(2)-tr(1),'sec')
  577. end if
  578. else
  579. ! tr later than tr1, thus not covered:
  580. alfa1 = 0.0
  581. end if
  582. ! second fraction:
  583. if ( md%tr2(1) < tr(2) ) then
  584. if ( md%tr2(1) < tr(1) ) then
  585. ! tr complete in tr2 ...
  586. alfa2 = 1.0
  587. else
  588. ! fraction of tr inside tr2 :
  589. alfa2 = rTotal(tr(2)-md%tr2(1),'sec') / rTotal(tr(2)-tr(1),'sec')
  590. end if
  591. else
  592. ! tr before tr2, thus not covered:
  593. alfa2 = 0.0
  594. end if
  595. ! replace data array:
  596. md%data = alfa1 * md%data1 + alfa2 * md%data2
  597. ! data is changed ...
  598. md%changed = .true.
  599. end if
  600. !
  601. ! unknown ...
  602. !
  603. case default
  604. write (gol,'("unsupported time interpolation:")'); call goErr
  605. write (gol,'(" md%tinterp : ",a)') trim(md%tinterp); call goErr
  606. write (gol,'(" md%name : ",a)') trim(md%name); call goErr
  607. TRACEBACK; status=1; return
  608. end select
  609. ! store new time:
  610. md%tr = tr
  611. ! copy history:
  612. call SetHistory( md%tmi, md%tmi1, status )
  613. ! ok
  614. status = 0
  615. end subroutine mdat_TimeInterpolation
  616. end module MeteoData