user_output_flight.F90 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  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. ! TM5 !
  11. !-----------------------------------------------------------------------------
  12. !BOP
  13. !
  14. ! !MODULE: USER_OUTPUT_FLIGHT
  15. !
  16. ! !DESCRIPTION:
  17. !\\
  18. !\\
  19. ! !INTERFACE:
  20. !
  21. MODULE USER_OUTPUT_FLIGHT
  22. !
  23. ! !USES:
  24. !
  25. use dims, only : lm, dx, xref, dy, yref, xbeg, xend, ybeg, yend
  26. use dims, only : nregions, region_name!, meteodir
  27. use chem_param, only : fscale
  28. use PARTOOLS, only : isRoot, PAR_REDUCE_ELEMENT, PAR_BROADCAST
  29. use GO, only : GOL, goErr
  30. implicit none
  31. private
  32. !
  33. ! !PUBLIC MEMBER FUNCTIONS:
  34. !
  35. public :: get_flightdata
  36. !
  37. ! !PRIVATE DATA MEMBERS:
  38. !
  39. character(len=*), parameter, private :: mname='ParTools'
  40. logical :: end_file = .false.
  41. ! filer_open: signal file open for flight input
  42. logical :: filer_open = .false.
  43. ! file_open: signal file open for output
  44. logical,dimension(nregions) :: file_open = .false.
  45. ! funit0: base unit for writing formatted output
  46. integer, parameter :: funit0 = 210
  47. integer,parameter :: nf_trace = 1
  48. real,dimension(nf_trace) :: rmf, rmf_final
  49. ! number of locations to be calculated for 1 model time
  50. integer,parameter :: nsamples = 2
  51. integer,dimension(nf_trace) :: if_trace = (/ 1 /)
  52. integer,dimension(6) :: idate_flight
  53. !
  54. ! !REVISION HISTORY:
  55. ! 10 Jul 2012 - Ph. Le Sager - adapted for lon-lat MPI domain decomposition
  56. !
  57. ! !REMARKS:
  58. !
  59. !EOP
  60. !------------------------------------------------------------------------
  61. CONTAINS
  62. !--------------------------------------------------------------------------
  63. ! TM5 !
  64. !--------------------------------------------------------------------------
  65. !BOP
  66. !
  67. ! !IROUTINE: GET_FLIGHTDATA
  68. !
  69. ! !DESCRIPTION:
  70. !\\
  71. !\\
  72. ! !INTERFACE:
  73. !
  74. SUBROUTINE GET_FLIGHTDATA( region, idate_f, status)
  75. !
  76. ! !USES:
  77. !
  78. use global_data, only : region_dat
  79. use tracer_data, only : mass_dat
  80. use meteodata , only : m_dat, phlb_dat
  81. use global_data, only : outdir
  82. use tm5_distgrid, only : dgrid, get_distgrid, update_halo
  83. !
  84. ! !INPUT/OUTPUT PARAMETERS:
  85. !
  86. integer, intent(in) :: region
  87. integer, intent(in), dimension(6) :: idate_f ! date for which output required
  88. integer, intent(out) :: status
  89. !
  90. ! !REVISION HISTORY:
  91. ! 10 Jul 2012 - Ph. Le Sager - adapted for lon-lat MPI domain decomposition
  92. !
  93. ! !REMARKS:
  94. !
  95. !EOP
  96. !------------------------------------------------------------------------
  97. !BOC
  98. character(len=*), parameter :: rname = mname//'/get_flightdata'
  99. real, dimension(:,:,:), pointer :: m, phlb
  100. real, dimension(:,:,:,:), pointer :: rm, rxm, rym, rzm
  101. real, dimension(0:lm(region)) :: presh
  102. integer :: i,is,js,l,n,isn,jsn,ls,j, i1, i2, j1, j2
  103. real :: flon,flat,fpres,ris,rjs,dxr,dyr,wcx,wcy,rls
  104. ! --- START
  105. if ( end_file ) return
  106. if (isroot) then
  107. if ( .not. filer_open ) then ! open input file...
  108. open( unit=funit0+region, form = 'formatted', &
  109. file = trim(outdir)//'/flight.data', status = 'OLD')
  110. read(funit0+region,*) idate_flight
  111. print *,'get_flightdata: Initial idate_flight read as:',idate_flight
  112. filer_open = .true.
  113. endif
  114. endif
  115. call PAR_BROADCAST(idate_flight, status)
  116. if (isroot) then
  117. if ( .not. file_open(region) ) then ! open output file
  118. open(unit = funit0+region+nregions,form = 'formatted', &
  119. file = trim(outdir)//'/flight_'//region_name(region)//'.out', &
  120. status = 'unknown')
  121. file_open(region) = .true.
  122. write(funit0+region+nregions,'(6i6)') idate_flight
  123. end if
  124. end if
  125. ! bounds on this PE for this region
  126. call get_distgrid( dgrid(region), i_strt=i1, i_stop=i2, j_strt=j1, j_stop=j2)
  127. ! Assume that the halo of phlb_dat has not updated yet
  128. call update_halo( dgrid(region), phlb_dat(region)%data, phlb_dat(region)%halo, status)
  129. ! ---------- Method ----------------
  130. ! 0. Is idate equal to idate_flight
  131. ! 1. Is the flight in the area?--->no, then put -1 in c
  132. ! 2. Determine gridbox
  133. ! 3. Use slopes to determine concentration at the flight.
  134. do i = 1,6
  135. if (idate_flight(i).ne.idate_f(i)) return
  136. enddo
  137. !pointers to global arrays...
  138. m => m_dat(region)%data
  139. phlb => phlb_dat(region)%data
  140. rm => mass_dat(region)%rm
  141. rxm => mass_dat(region)%rxm
  142. rym => mass_dat(region)%rym
  143. rzm => mass_dat(region)%rzm
  144. dyr = dy/yref(region)
  145. dxr = dx/xref(region)
  146. do n = 1,nsamples
  147. if (isroot) then
  148. read(funit0+region,*) flon,flat,fpres
  149. endif
  150. call PAR_BROADCAST(flon, status)
  151. IF_NOTOK_RETURN(status=1)
  152. call PAR_BROADCAST(flat, status)
  153. IF_NOTOK_RETURN(status=1)
  154. call PAR_BROADCAST(fpres, status)
  155. IF_NOTOK_RETURN(status=1)
  156. rmf=-1.0
  157. ! if in region
  158. if ( (flon .ge. xbeg(region) .and. (flon .le. xend(region)) ) .and. &
  159. (flat .ge. ybeg(region) .and. (flat .le. yend(region)) ) ) then
  160. ris = (flon-float(xbeg(region)))/dxr + 1.0
  161. rjs = (flat-float(ybeg(region)))/dyr + 1.0
  162. !is,js is the box where we want the mixing ratio
  163. is = int(ris)
  164. js = int(rjs)
  165. ! if on current PE
  166. if (is>=i1.and.is<=i2.and.js>=j1.and.js<=j2) then
  167. !fraction from the center of the is-box (-0.5---+0.5)
  168. ris = ris-is-0.5
  169. !idem js
  170. rjs = rjs-js-0.5
  171. if(ris.gt.0) then
  172. isn = is+1 !the neighbour for pressure interpolation
  173. else
  174. isn = is-1
  175. endif
  176. if(rjs.gt.0) then
  177. jsn = js+1 !the neighbour for pressure interpolation
  178. else
  179. jsn = js-1
  180. endif
  181. wcx = (1.-abs(ris))
  182. wcy = (1.-abs(rjs))
  183. ! interpolate the pressure to flight position...
  184. ls = 1 !layer
  185. do l=0,lm(region)
  186. presh(l) = wcx*wcy* phlb(is, js, l+1) + &
  187. (1.-wcx)*wcy* phlb(isn,js, l+1) + &
  188. wcx*(1.-wcy)* phlb(is, jsn,l+1) + &
  189. (1.-wcx)*(1.-wcy)* phlb(isn,jsn,l+1)
  190. enddo
  191. do l=0,lm(region) ! selects layer
  192. if(presh(l).lt.fpres) exit
  193. enddo
  194. select case(l)
  195. case(0)
  196. print*,'get_flightdata: Warning..., flight pressure ',&
  197. 'is below the surface pressure'
  198. ls = 1
  199. rls = -0.5 !surface...
  200. case default
  201. ls = l !the flight layer
  202. ! the off-set from the center of the layer (-0.5--->+0.5)
  203. ! (interpolation is in (m))
  204. rls = (presh(l-1)-fpres)/(presh(l-1)-presh(l)) - 0.5
  205. end select
  206. !from is,js,ls, ris,rjs,rls, determine the mixing ratio ...
  207. do j=1,nf_trace
  208. i = if_trace(j)
  209. ! rm-value is obtained from rm + slopes.
  210. ! slope = rxm = (rm*dX/dx *deltaX/2)
  211. rmf(j) = rm(is,js,ls,i) + 2.0*(ris*rxm(is,js,ls,i) + &
  212. rjs*rym(is,js,ls,i) + &
  213. rls*rzm(is,js,ls,i) )
  214. rmf(j) = rmf(j)/m(is,js,ls) *fscale(i)
  215. enddo
  216. endif
  217. end if
  218. ! Barrier/gather on root
  219. call PAR_REDUCE_ELEMENT(rmf, 'MAX', rmf_final, status)
  220. IF_NOTOK_RETURN(status=1)
  221. if (isroot) then
  222. write(funit0+region+nregions,*) flon,flat,fpres,rmf_final
  223. endif
  224. enddo ! nsamples
  225. nullify(m)
  226. nullify(rm)
  227. nullify(rxm)
  228. nullify(rym)
  229. nullify(rzm)
  230. nullify(phlb)
  231. ! try to read another date in the input file
  232. if (isroot) then
  233. read(funit0+region,*,end=999) idate_flight
  234. write(funit0+region+nregions,'(6i6)') idate_flight
  235. end_file = .false.
  236. goto 1000
  237. 999 close(funit0+region+nregions)
  238. end_file = .true.
  239. 1000 continue
  240. endif
  241. call PAR_BROADCAST(end_file,status)
  242. IF_NOTOK_RETURN(status=1)
  243. status=0
  244. end subroutine get_flightdata
  245. !EOC
  246. END MODULE USER_OUTPUT_FLIGHT