p_EnKF_assemble.F90 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. program EnKF_postprocess
  2. ! KAL -- The new EnKF is MPI-parallelized, and each thread will dump
  3. ! KAL -- to its own file named "analysisXXX_procXXX.[ab]
  4. ! KAL --
  5. ! KAL -- This routine will gather the
  6. ! KAL -- analysis from the separate analyzed files into one complete restart file.
  7. ! KAL -- To do this, a "template" restart file must be specified. This file
  8. ! KAL -- copies non-existing variables in the analyzed fields from the template,
  9. ! KAL -- and into the final analysis. The final files produced by this routine
  10. ! KAL -- are named "analysisXXX.[ab]".
  11. ! KAL -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  12. ! KAL -- Input arguments:
  13. ! KAL -- template restart file
  14. ! KAL -- template ice restart file
  15. ! KAL -- ensemble member
  16. ! KAL -- number of MPI threads used in analysis
  17. ! KAL -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  18. ! KAL --
  19. ! KAL -- NB: This routine will not check or modify the fields. To do that,
  20. ! KAL -- use "consistency" (check) and "fixhycom" (fix)
  21. use mod_raw_io
  22. use m_parse_blkdat
  23. use m_put_mod_fld
  24. implicit none
  25. integer*4, external :: iargc
  26. integer imem ! ensemble member
  27. character(len=80) :: template,icetemplate ! restart template
  28. character(len=80) :: afile
  29. integer :: fnd, rstind, tmpindx, iafile
  30. logical :: ex, allok, nomatch
  31. character(len=8) :: cfld, ctmp
  32. character(len=3) :: cproc,cmem
  33. integer :: tlevel, vlevel, nproc
  34. real :: bmin, bmax, rdummy
  35. integer :: idm,jdm,kdm
  36. real, allocatable:: fld(:,:)
  37. real*8, allocatable, dimension(:,:) :: &
  38. ficem,hicem,hsnwm,ticem,tsrfm
  39. real*4, allocatable:: fldr4(:,:)
  40. real*4 :: spval,amin,amax
  41. real, allocatable, dimension(:,:) :: dpsum
  42. integer,parameter :: numfields=2
  43. integer :: ios,ios2, reclICE,ifld
  44. character(len=8) :: fieldnames(numfields)
  45. integer :: fieldlevels(numfields)
  46. if (iargc()==4) then
  47. call getarg(1,template)
  48. call getarg(2,icetemplate)
  49. call getarg(3,ctmp)
  50. read(ctmp,*) imem
  51. write(cmem,'(i3.3)') imem
  52. call getarg(4,ctmp)
  53. read(ctmp,*) nproc
  54. else
  55. print *,'usage: EnKF_postprocess restart_template ice_template ensemble_member nproc'
  56. call exit(1)
  57. endif
  58. ! Get dimensions from blkdat
  59. call parse_blkdat('idm ','integer',rdummy,idm)
  60. call parse_blkdat('jdm ','integer',rdummy,jdm)
  61. call parse_blkdat('kdm ','integer',rdummy,kdm)
  62. if (idm>0 .and. idm < 1e4 .and. jdm>0 .and. jdm<1e4) then
  63. allocate(fld (idm,jdm))
  64. allocate(fldr4(idm,jdm))
  65. allocate(ficem(idm,jdm))
  66. allocate(hicem(idm,jdm))
  67. allocate(hsnwm(idm,jdm))
  68. allocate(ticem(idm,jdm))
  69. allocate(tsrfm(idm,jdm))
  70. allocate(dpsum(idm,jdm))
  71. else
  72. print *,'fld allocate error'
  73. stop '(EnKF_postprocess)'
  74. end if
  75. ! Remove postfix of template file
  76. fnd=max(index(template,'.a'),index(template,'.b'))
  77. ! Inquire for existence
  78. inquire(exist=ex,file=template(1:fnd-1)//'.b')
  79. if (.not.ex) then
  80. write(*,*) 'Can not find '//template(1:fnd-1)//'.b'
  81. stop '(EnKF_postprocess)'
  82. end if
  83. print *,template(1:fnd-1)//'.b'
  84. ! Loop over restart file
  85. dpsum=0.
  86. rstind=1 ! Restart index
  87. allok=.true.
  88. do while ( allok)
  89. ! Get header info from template
  90. call rst_header_from_index(template(1:fnd-1)//'.b', &
  91. cfld,vlevel,tlevel,rstind,bmin,bmax,.true.)
  92. allok=tlevel/=-1 ! test to see if read was ok
  93. if (allok) then
  94. ! Get actual field - for now we use the READRAW routine (later on we
  95. ! should switch to m_get_mod_fld
  96. call READRAW(fldr4,amin,amax,idm,jdm,.false.,spval,template(1:fnd-1)//'.a',rstind)
  97. fld=fldr4
  98. !print *,cfld,tlevel, vlevel
  99. ! From the template, we have the stuff we need, now we go looking
  100. ! in the EnKF analysis files output for the correct input. Note that
  101. ! all time levels are set equal in the restart. This may introduce
  102. ! imbalances, but the alternative is probably worse.
  103. !
  104. ! KAL -- need list of analysis files here, for now we hardcode
  105. nomatch=.true.
  106. do iafile=1,nproc ! List of procs used in analysis
  107. write(cproc,'(i3.3)') iafile-1
  108. ! Temporary name, will change
  109. afile='analysis'//cmem//'_proc'//cproc
  110. ! NB - time level=1
  111. ! NB2 - the files dumped in the analysis lack a header (last argument
  112. ! is false)
  113. if (trim(cfld)=='ficem') then
  114. ctmp='icec'
  115. elseif (trim(cfld)=='hicem') then
  116. ctmp='hice'
  117. else
  118. ctmp=trim(cfld)
  119. endif
  120. call rst_index_from_header(trim(afile)//'.b',ctmp,vlevel,1, &
  121. tmpindx,bmin,bmax,.false.)
  122. if (tmpindx/=-1) then
  123. !if (tlevel/=1) print *,'--> replacing time level with 1'
  124. print '(a8," -- time, layer:",2i4," match : record, file",i4," ",a)', cfld,tlevel, vlevel,tmpindx,trim(afile)
  125. nomatch=.false.
  126. ! Read field from analysed file
  127. call READRAW(fldr4,amin,amax,idm,jdm,.false.,spval,trim(afile)//'.a',tmpindx)
  128. fld=fldr4
  129. ! Sjekk p at vi har lest rett - samanlign max/min fr filene
  130. if (abs(amin-bmin).gt.abs(bmin)*1.e-4 .or. &
  131. abs(bmax-amax).gt.abs(bmax)*1.e-4 ) then
  132. print *,'Inconsistency between .a and .b files'
  133. print *,'.a : ',amin,amax
  134. print *,'.b : ',bmin,bmax
  135. print *,cfld,vlevel,tlevel
  136. call exit(1)
  137. end if
  138. ! put into final, processed file -- imem is not used, actually
  139. call put_mod_fld('analysis'//cmem,fld,imem,cfld,vlevel,tlevel,rstind,idm,jdm)
  140. exit
  141. end if
  142. end do
  143. if (nomatch) then
  144. print '(a8," -- time, layer:",2i4," - no match - replace with template")',cfld,tlevel,vlevel
  145. ! put template values into final, processed file -- imem is not used, actually
  146. call put_mod_fld('analysis'//cmem,fld,imem,cfld,vlevel,tlevel,rstind,idm,jdm)
  147. end if
  148. rstind=rstind+1
  149. end if ! read of template was ok
  150. end do
  151. #if ! defined (SINGLE_RESTART)
  152. ! ice processing Loop over restart file
  153. print *
  154. print *
  155. print *,'processing ice restart file'
  156. rstind=1 ! Restart index
  157. allok=.true.
  158. ! Temporary solution
  159. fieldnames(1)='icec'
  160. fieldnames(2)='hice'
  161. vlevel=0
  162. ! Copy template record imem to analysysICE.uf
  163. inquire(iolength=reclICE)ficem,hicem,hsnwm,ticem,tsrfm
  164. open(10,file=trim(icetemplate),form='unformatted',access='direct',recl=reclICE,status='old')
  165. read(10,rec=imem,iostat=ios)ficem,hicem,hsnwm,ticem,tsrfm
  166. close(10)
  167. open(11,file='analysisICE.uf',form='unformatted',access='direct',recl=reclICE,status='unknown')
  168. write(11,rec=imem,iostat=ios2)ficem,hicem,hsnwm,ticem,tsrfm
  169. close(11)
  170. do ifld=1,numfields
  171. cfld= fieldnames (ifld)
  172. if (trim(cfld)=='icec' .or. trim(cfld)=='hice') then
  173. nomatch=.true.
  174. do iafile=1,nproc ! List of procs used in analysis
  175. write(cproc,'(i3.3)') iafile-1
  176. ! NB - time level=1
  177. ! NB2 - the files dumped in the analysis lack a header (last argument
  178. ! is false)
  179. call rst_index_from_header(trim(afile)//'.b',cfld,vlevel,1, &
  180. tmpindx,bmin,bmax,.false.)
  181. if (tmpindx/=-1) then
  182. print '(a8," -- layer:",i4," match : record, file",i4," ",a)', cfld, vlevel,tmpindx,trim(afile)
  183. nomatch=.false.
  184. !print *,'Got match for '//cfld
  185. ! Read field from analysed file
  186. call READRAW(fldr4,amin,amax,idm,jdm,.false.,spval,trim(afile)//'.a',tmpindx)
  187. fld=fldr4
  188. ! Sjekk p at vi har lest rett - samanlign max/min fr filene
  189. if (abs(amin-bmin).gt.abs(bmin)*1.e-4 .or. &
  190. abs(bmax-amax).gt.abs(bmax)*1.e-4 ) then
  191. print *,'Inconsistency between .a and .b files'
  192. print *,'.a : ',amin,amax
  193. print *,'.b : ',bmin,bmax
  194. print *,cfld,vlevel,tlevel
  195. call exit(1)
  196. end if
  197. exit
  198. end if
  199. end do
  200. ! Check if we got ice concentration or ice thickness
  201. if (.not.nomatch) then
  202. inquire(iolength=reclICE)ficem,hicem,hsnwm,ticem,tsrfm !,iceU,iceV
  203. open(11,file='analysisICE.uf',form='unformatted',access='direct',recl=reclICE,status='unknown')
  204. if (trim(cfld)=='icec') ficem=fld
  205. if (trim(cfld)=='hice') hicem=fld
  206. write(11,rec=imem,iostat=ios2)ficem,hicem,hsnwm,ticem,tsrfm !,iceU,iceV
  207. close(11)
  208. if (ios/=0 .or.ios2/=0) then
  209. print *,ios
  210. print *,ios2
  211. print *,'Error when writing to ice ens file'
  212. call exit(1)
  213. end if
  214. end if
  215. end if
  216. end do
  217. #endif
  218. print *,'Normal exit of EnKF_postprocess'
  219. print *,'TODO: Process dp inconsistencies'
  220. #if defined(AIX)
  221. call exit_(0)
  222. #else
  223. call exit(0)
  224. #endif
  225. end program