tm5_prism.F90 68 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042
  1. !
  2. #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
  3. !
  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. #define PRISM_ERR write (gol,'("from call to PRISM routine")'); call goErr
  8. #define IF_PRISM_NOTOK_RETURN(action) if (status/=OASIS_OK) then; PRISM_ERR; TRACEBACK; action; return; end if
  9. !
  10. #include "tm5.inc"
  11. !
  12. !-----------------------------------------------------------------------------
  13. ! TM5 !
  14. !-----------------------------------------------------------------------------
  15. !BOP
  16. !
  17. ! !MODULE: TM5_PRISM
  18. !
  19. ! !DESCRIPTION:
  20. !\\
  21. !\\
  22. ! !INTERFACE:
  23. !
  24. MODULE TM5_PRISM
  25. !
  26. ! !USES:
  27. !
  28. USE MOD_OASIS
  29. USE GO, ONLY : gol, goPr, goErr, TDate
  30. IMPLICIT NONE
  31. PRIVATE
  32. !
  33. ! !PUBLIC MEMBER FUNCTIONS:
  34. !
  35. public :: TM5_Prism_Init ! read control parameters from rc file
  36. public :: TM5_Prism_Init2 ! prism init: grids, partition, coupled variables
  37. public :: TM5_Prism_Done ! deallocate
  38. public :: SetPrismTime ! current time/date into prism format
  39. public :: InqCplVar ! check if a coupled variable exists
  40. public :: Init, Done, Setup, Remap ! methods for TshRemap object
  41. !
  42. ! !PUBLIC DATA MEMBERS:
  43. !
  44. character(len=6), public, parameter :: comp_name = 'ctm5mp'
  45. integer, public :: PRISM_start_date(6) ! prism reference start time
  46. integer, public :: comp_id ! tm5 id for prism
  47. integer, public :: ifs_cpl_freq ! ifs coupling frequency in hours
  48. integer, public :: lpj_cpl_freq ! lpjg coupling frequency in hours
  49. integer, public :: pis_cpl_freq ! pisces coupling frequency in hours
  50. integer, public :: co2_flx_freq ! CO2 (lpj/pis) flux coupling frequency in hours
  51. integer, public :: ifs_cpl_nlev ! number of levels for coupling with IFS
  52. integer, public :: ifs_cpl_nlev_cutoff ! reduced number of levels for coupling with IFS,
  53. ! applied for aerosols
  54. integer, public :: ifs_shT ! ifs spectral fields : resolution
  55. integer, public :: ifs_shn ! ifs spectral fields : number of coeff
  56. !
  57. logical, public :: refine_levels ! do we send/receive all IFS levels? (then we need to "refine them" here)
  58. logical, public :: coupled_to_lpj ! is TM5 coupled to LPJ-Guess?
  59. logical, public :: coupled_to_pis ! is TM5 coupled to PISCES?
  60. real, public, allocatable :: co2_flux_recv(:,:) ! global field to store co2 flux
  61. real, public, allocatable :: co2_flux_appl(:,:) ! global field to store co2 flux
  62. real, public, allocatable :: co2_total_flux_recv(:,:) ! global field to store co2 flux
  63. real, public, allocatable :: co2_total_flux_appl(:,:) ! global field to store co2 flux
  64. !
  65. ! !PRIVATE DATA MEMBERS:
  66. !
  67. character(len=*), parameter :: mname = 'TM5_Prism'
  68. integer, parameter :: len_grid_name = 4 ! oasis3: fixed length for gridname
  69. !
  70. integer :: ifs_npes ! ifs number of procs
  71. integer, parameter :: wp = SELECTED_REAL_KIND(12,307) ! working precision = double
  72. character(len=256) :: error_message
  73. !
  74. ! !PUBLIC TYPES:
  75. !
  76. TYPE, PUBLIC :: TshRemap
  77. !
  78. ! remapping: for each element in received grid, identify target indices:
  79. !
  80. ! remap(:,:,1) : 1 = real part, 2 = imag part
  81. ! remap(:,:,2) : index in triangle : 1=(0,0) 2=(0,1) 3=(0,2) ... np=(m,n)
  82. ! remap(:,:,3) : level
  83. !
  84. ! Info array has values : m*1000 + n + lev/100 and negative for imaginary part
  85. !
  86. ! receive spectral info every timestep to avoid memory growth
  87. type(TDate) :: t ! store time of current info
  88. integer, pointer :: remap(:,:,:) ! remapping indices
  89. integer :: shT ! truncation
  90. END TYPE TshRemap
  91. TYPE, PUBLIC :: TCplVar ! --- TM Coupled Variable ---
  92. character(len=128) :: name ! tm5 internal name
  93. character(len=128) :: cpl_name ! short name used in rcfile
  94. integer, pointer :: var_id(:) ! list of id return by oasis3 (one per level)
  95. character(len=128), pointer :: var_name(:)! list of names used in the namcouple (one per level)
  96. logical :: serial ! serial transfer
  97. character(len=3) :: intent ! in or out
  98. character(len=2) :: grid_type ! spectral or gridpoint
  99. integer :: region !
  100. integer :: nlev !
  101. real :: west_deg, dlon_deg, south_deg, dlat_deg ! lon/lat grids
  102. integer :: nlon, nlat
  103. integer :: shT, shn, shn_recv ! spectral info
  104. integer :: itr ! tracer index if any
  105. logical :: cache ! cache
  106. type(TDate) :: cache_tmid
  107. real, pointer :: cache_data(:,:,:) => null()
  108. END TYPE TCplVar
  109. ! --- var -----------------------------------
  110. integer, parameter :: maxcplvar = 165 ! max nb of coupled fields
  111. type(TCplVar), public, save :: CplVar(maxcplvar) ! array of coupled fields
  112. integer, public :: ncplvar ! actual nb of coupled fields
  113. integer :: region_glb, region_sfc
  114. character(len=1024) :: prism_get_list ! comma seperated lists of coupled fields
  115. character(len=1024) :: prism_put_list
  116. integer, allocatable :: part_id(:)
  117. integer, allocatable :: var_shape(:,:)
  118. integer :: sp_part_id
  119. integer, allocatable :: sp_var_shape(:)
  120. !
  121. ! !INTERFACE:
  122. !
  123. interface Init
  124. module procedure shremap_Init
  125. end interface
  126. interface Done
  127. module procedure shremap_Done
  128. end interface
  129. interface Setup
  130. module procedure shremap_Setup
  131. end interface
  132. interface Remap
  133. module procedure shremap_Remap
  134. end interface
  135. interface SetPrismTime
  136. module procedure SetPrismTime_date
  137. end interface
  138. !
  139. ! !REVISION HISTORY:
  140. ! 10 Sep 2013 - Ph. Le Sager - cleanup, document, remove oasis4 stuff (can
  141. ! always be retrieved with svn if needed)
  142. ! 8 Oct 2013 - Ph. Le Sager - dummy CO2 exchange with LPJ-Guess
  143. !
  144. ! !REMARKS:
  145. !
  146. !EOP
  147. !------------------------------------------------------------------------
  148. CONTAINS
  149. !--------------------------------------------------------------------------
  150. ! TM5 !
  151. !--------------------------------------------------------------------------
  152. !BOP
  153. !
  154. ! !IROUTINE: TM5_PRISM_INIT
  155. !
  156. ! !DESCRIPTION: read coupling information from rc file.
  157. !\\
  158. !\\
  159. ! !INTERFACE:
  160. !
  161. SUBROUTINE TM5_Prism_Init( rcfile, status )
  162. !
  163. ! !USES:
  164. !
  165. use GO, only : TrcFile, Init, Done, ReadRc
  166. !
  167. ! !INPUT PARAMETERS:
  168. !
  169. character(len=*), intent(in) :: rcfile
  170. !
  171. ! !OUTPUT PARAMETERS:
  172. !
  173. integer, intent(out) :: status
  174. !
  175. ! !REMARKS:
  176. !
  177. !EOP
  178. !------------------------------------------------------------------------
  179. !BOC
  180. character(len=*), parameter :: rname = mname//'/TM5_Prism_Init'
  181. type(TrcFile) :: rcF
  182. ! --- begin -----------------------------------
  183. ! * settings from rcfile
  184. call Init( rcF, rcfile, status )
  185. IF_NOTOK_RETURN(status=1)
  186. call ReadRc( rcF, 'ifs.cpl.nlev', ifs_cpl_nlev, status )
  187. IF_NOTOK_RETURN(status=1)
  188. call ReadRc( rcf, 'ifs.cpl.nlev.cutoff', ifs_cpl_nlev_cutoff, status )
  189. IF_NOTOK_RETURN(status=1)
  190. call ReadRc( rcF, 'ifs.shresol', ifs_shT, status )
  191. IF_NOTOK_RETURN(status=1)
  192. call ReadRc( rcF, 'cpl.ifs.period', ifs_cpl_freq, status )
  193. IF_NOTOK_RETURN(status=1)
  194. call ReadRc( rcF, 'cpl.lpj.period', lpj_cpl_freq, status )
  195. IF_NOTOK_RETURN(status=1)
  196. call ReadRc( rcF, 'cpl.pis.period', pis_cpl_freq, status )
  197. IF_NOTOK_RETURN(status=1)
  198. call ReadRc( rcF, 'prism.get', prism_get_list, status )
  199. IF_NOTOK_RETURN(status=1)
  200. call ReadRc( rcF, 'prism.put', prism_put_list, status )
  201. IF_NOTOK_RETURN(status=1)
  202. call ReadRc( rcF, 'coupled_to_lpjguess', coupled_to_lpj, status, default=.false. )
  203. IF_ERROR_RETURN(status=1)
  204. call ReadRc( rcF, 'coupled_to_pisces', coupled_to_pis, status, default=.false. )
  205. IF_ERROR_RETURN(status=1)
  206. ! sanity check that pisces and lpjg coupling frequency is the same,
  207. ! required to properly distribute daily CO2 fluxes over the coupling period
  208. if (coupled_to_lpj .and. coupled_to_pis) then
  209. if ( lpj_cpl_freq /= pis_cpl_freq ) then
  210. write(gol,*) "LPJ-GUESS and PISCES coupling frequency must be the same"; call goErr
  211. status=1
  212. TRACEBACK; return
  213. else
  214. co2_flx_freq = lpj_cpl_freq
  215. end if
  216. else if (coupled_to_lpj) then
  217. co2_flx_freq = lpj_cpl_freq
  218. else if (coupled_to_pis) then
  219. co2_flx_freq = pis_cpl_freq
  220. endif
  221. select case (ifs_cpl_nlev)
  222. case (91,62)
  223. refine_levels=.true.
  224. case(34,31,10,4)
  225. refine_levels=.false.
  226. case default
  227. write(gol,*) " Wrong (sub)set of levels is exchanged between IFS and TM5 " ; call goErr
  228. write(gol,*) " Either (4, 10 or 34 out of) 91, or (31 out of) 62" ; call goErr
  229. status=1
  230. TRACEBACK; return
  231. end select
  232. call Done( rcF, status )
  233. IF_NOTOK_RETURN(status=1)
  234. ! * spectral grids
  235. ifs_shn = (ifs_shT+1)*(ifs_shT+2)/2 ! number of coeff
  236. ! check that compilation was perform as expected with respect to optical feedback
  237. #ifndef with_ecearth_optics
  238. if (index(prism_put_list,'AOD_01') /=0) then
  239. write(gol,*) "Feedback of aerosols optical properties requires 'with_ecearth_optics' cpp"; call goErr
  240. write(gol,*) "You must recompile TM5-MP with cpp defs 'with_ecearth_optics'"; call goErr
  241. write(gol,*) "This can be done in the config-build.xml file with the TM5_MDEFS_FFLAGS key."; call goErr
  242. status=1
  243. TRACEBACK; return
  244. endif
  245. #endif
  246. status = 0
  247. END SUBROUTINE TM5_PRISM_INIT
  248. !EOC
  249. !--------------------------------------------------------------------------
  250. ! TM5 !
  251. !--------------------------------------------------------------------------
  252. !BOP
  253. !
  254. ! !IROUTINE: TM5_PRISM_INIT2
  255. !
  256. ! !DESCRIPTION: prism grid writing, prism partition, init coupled variables
  257. !\\
  258. !\\
  259. ! !INTERFACE:
  260. !
  261. subroutine TM5_Prism_Init2( nreg_all, nreg, ireg_sfc, lli, levi, status )
  262. !
  263. ! !USES:
  264. !
  265. use Grid, only : TllGridInfo, TLevelInfo
  266. use Grid, only : TshGridInfo, Init, Done
  267. #ifdef parallel_cplng
  268. use tm5_distgrid, only : dgrid, Get_DistGrid
  269. #endif
  270. use GO, only : NewDate, goReadFromLine
  271. use dims, only : lm
  272. use chem_param, only : names, io3, ich4, ico2
  273. use partools, only : isRoot
  274. #ifdef with_m7
  275. use chem_param, only : inus_n, iso4nus, iais_n, iso4ais, ibcais, ipomais
  276. use chem_param, only : iacs_n, iso4acs, ibcacs, ipomacs, issacs, iduacs
  277. use chem_param, only : icos_n, iso4cos, ibccos, ipomcos, isscos, iducos
  278. use chem_param, only : iaii_n, ibcaii, ipomaii, iaci_n, iduaci, icoi_n, iducoi
  279. use chem_param, only : ino3_a, imsa
  280. #endif
  281. !
  282. ! !INPUT PARAMETERS:
  283. !
  284. integer, intent(in) :: nreg_all
  285. integer, intent(in) :: nreg
  286. integer, intent(in) :: ireg_sfc
  287. type(TllGridInfo), intent(in) :: lli(1:nreg_all)
  288. type(TLevelInfo), intent(in) :: levi
  289. !
  290. ! !OUTPUT PARAMETERS:
  291. !
  292. integer, intent(out) :: status
  293. !
  294. ! !REVISION HISTORY:
  295. ! 8 Oct 2013 - Ph. Le Sager - coupling with LPJG
  296. !
  297. ! !REMARKS:
  298. !
  299. !EOP
  300. !------------------------------------------------------------------------
  301. !BOC
  302. character(len=*), parameter :: rname = mname//'/TM5_Prism_Init2'
  303. integer :: ireg, region, id, ivar, ilev, i1, j1, i2, j2
  304. integer, parameter :: nc = 4 ! corners
  305. integer :: nx, ny
  306. integer :: i, j, k, m, n, z
  307. character(len=len_grid_name) :: point_name
  308. real(ip_realwp_p), allocatable :: lons(:,:), lats(:,:)
  309. real(ip_realwp_p), allocatable :: clons(:,:,:), clats(:,:,:)
  310. real(ip_realwp_p), allocatable :: area(:,:)
  311. integer, allocatable :: mask(:,:)
  312. character(len=len_grid_name) :: sp_point_name
  313. real(ip_realwp_p), allocatable :: sp_lons(:,:), sp_lats(:,:)
  314. integer, allocatable :: sp_mask(:,:)
  315. real(ip_realwp_p) :: sp_dlon, sp_dlat
  316. #ifdef parallel_cplng
  317. integer :: part_val(1:5)
  318. #else
  319. integer :: part_val(1:3)
  320. #endif
  321. integer :: sp_part_val(1:3)
  322. character(len=128) :: cpl_name
  323. integer :: var_nodims(2)
  324. integer :: var_type
  325. integer(kind=ip_intwp_p) :: var_intent
  326. logical :: write_grid
  327. #ifdef parallel_cplng
  328. type(TllGridInfo) :: local_lli ! local Lat-Lon grid info
  329. #endif
  330. ! --- begin -----------------------------------
  331. write (gol,'("initialize prism coupling:")'); call goPr
  332. write (gol,'(" component : ",a)') trim(comp_name); call goPr
  333. ! store in module variables
  334. region_glb = 1
  335. region_sfc = ireg_sfc
  336. ! storage for variable shape:
  337. allocate( part_id(nreg_all) )
  338. allocate( var_shape(4,nreg_all) )
  339. allocate( sp_var_shape(4) )
  340. ! init to zero on all pe's
  341. part_id = 0
  342. var_shape = 0
  343. sp_part_id = 0
  344. sp_var_shape = 0
  345. ! tmp co2
  346. #ifdef parallel_cplng
  347. region = 1
  348. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2 , J_STRT=j1, J_STOP=j2 )
  349. allocate(co2_flux_recv(i1:i2, j1:j2) )
  350. allocate(co2_flux_appl(i1:i2, j1:j2) )
  351. allocate(co2_total_flux_recv(i1:i2, j1:j2) )
  352. allocate(co2_total_flux_appl(i1:i2, j1:j2) )
  353. #else
  354. allocate(co2_flux_recv(1,1))
  355. allocate(co2_flux_appl(1,1))
  356. allocate(co2_total_flux_recv(1,1))
  357. allocate(co2_total_flux_appl(1,1))
  358. #endif
  359. co2_flux_recv(:,:) = 0.
  360. co2_flux_appl(:,:) = 0.
  361. co2_total_flux_recv(:,:) = 0.
  362. co2_total_flux_appl(:,:) = 0.
  363. ! ============ oasis3 grid writing =================
  364. write_grid=.false. !! HARDCODED !!
  365. ! Define the grids by master proc
  366. if ( isroot .and. write_grid ) then
  367. call oasis_start_grids_writing( status )
  368. ! **** lon/lat grid
  369. do region = 1, nreg_all
  370. ! name of grid points
  371. if ( region == region_glb ) then
  372. ! global region
  373. point_name = 'CTM3'
  374. else if ( region == region_sfc ) then
  375. ! global surface grid:
  376. point_name = 'CTM1'
  377. else
  378. ! global grids only ...
  379. cycle
  380. end if
  381. write (gol,'(" define points ",a," ...")') point_name; call goPr
  382. ! grid size:
  383. nx = lli(region)%nlon
  384. ny = lli(region)%nlat
  385. write (gol,'(" region : ",i6)') region; call goPr
  386. write (gol,'(" size : ",2i6)') nx, ny; call goPr
  387. allocate( lons(nx,ny) )
  388. allocate( lats(nx,ny) )
  389. allocate( clons(nx,ny,nc) )
  390. allocate( clats(nx,ny,nc) )
  391. allocate( area(nx,ny) )
  392. allocate( mask(nx,ny) )
  393. ! set lon/lat grid (grid cell centers):
  394. do i = 1, nx
  395. lons(i,:) = lli(region)%lon_deg(i)
  396. end do
  397. do j = 1, ny
  398. lats(:,j) = lli(region)%lat_deg(j)
  399. end do
  400. call oasis_write_grid( point_name, nx, ny, lons, lats )
  401. ! set corner lon/lat:
  402. ! 3 o o 2
  403. ! 4 o o 1
  404. do i = 1, nx
  405. clons(i,:,1) = lli(region)%blon_deg(i )
  406. clons(i,:,2) = lli(region)%blon_deg(i )
  407. clons(i,:,3) = lli(region)%blon_deg(i-1)
  408. clons(i,:,4) = lli(region)%blon_deg(i-1)
  409. end do
  410. do j = 1, ny
  411. clats(:,j,1) = lli(region)%blat_deg(j-1)
  412. clats(:,j,2) = lli(region)%blat_deg(j )
  413. clats(:,j,3) = lli(region)%blat_deg(j )
  414. clats(:,j,4) = lli(region)%blat_deg(j-1)
  415. end do
  416. write (gol,'(" write corners ...")'); call goPr
  417. call oasis_write_corner( point_name, nx, ny, nc, clons, clats )
  418. ! land/sea mask
  419. mask = 0 ! not masked; gives warnings about 'sea-world' cplout ...
  420. write (gol,'(" write mask ...")'); call goPr
  421. call oasis_write_mask( point_name, nx, ny, mask )
  422. do j = 1, ny
  423. area(:,j) = lli(region)%area_m2(j)
  424. end do
  425. write (gol,'(" write area ...")'); call goPr
  426. call oasis_write_area( point_name, nx, ny, area )
  427. deallocate( lons )
  428. deallocate( lats )
  429. deallocate( clons )
  430. deallocate( clats )
  431. deallocate( area )
  432. deallocate( mask )
  433. end do ! regions
  434. ! *** SPECTRAL GRID
  435. write(sp_point_name, '("C",i3.3)') ifs_shT
  436. write (gol,'(" define points ",a," ...")') trim(sp_point_name); call goPr
  437. allocate( sp_lons(2*ifs_shn,1) )
  438. allocate( sp_lats(2*ifs_shn,1) )
  439. allocate( sp_mask(2*ifs_shn,1) )
  440. ! Triangular storage:
  441. !
  442. ! NSMAX * * .. *
  443. ! :
  444. !
  445. ! 1 * *
  446. ! n 0 *
  447. !
  448. ! 0 1 .. NSMAX
  449. ! m "wavenumber"
  450. !
  451. ! dummy locations : (n*2+z+0.5)*dlon, (m+0.5)*dlat
  452. ! where z=0 is real part and z=1 is imaginary part
  453. ! dummy spacing:
  454. sp_dlon = 0.1 ! degree
  455. sp_dlat = 0.1 ! degree
  456. ! index in coeff array:
  457. k = 0
  458. ! loop over global wavenumbers:
  459. do m = 0, ifs_shT
  460. ! loop over complex coeff:
  461. do n = m, ifs_shT
  462. ! loop over real/complex
  463. do z = 0, 1
  464. ! next coeff:
  465. k = k + 1
  466. ! cell centers:
  467. sp_lons(k,1) = -180.0 + (n*2+z+0.5) * sp_dlon
  468. sp_lats(k,1) = -90.0 + (m +0.5) * sp_dlat
  469. ! no mask:
  470. sp_mask(k,1) = 0 ! not masked
  471. end do ! re,im
  472. end do ! n
  473. end do ! m
  474. call oasis_write_grid( sp_point_name, 2*ifs_shn, 1, sp_lons, sp_lats )
  475. call oasis_write_mask( sp_point_name, 2*ifs_shn, 1, sp_mask )
  476. deallocate( sp_lons )
  477. deallocate( sp_lats )
  478. deallocate( sp_mask )
  479. call oasis_terminate_grids_writing()
  480. else
  481. write (gol,'(" not necessary to write grids (not root) ...")'); call goPr
  482. end if ! root and write_grid
  483. ! ============ Partition =================
  484. write (gol,'(" define partitions ...")'); call goPr
  485. ! *** LAT/LON
  486. reg: do region = 1, nreg_all
  487. if ( (region /= region_glb) .and. (region /= region_sfc) ) cycle ! global grids only
  488. nx = lli(region)%nlon
  489. ny = lli(region)%nlat
  490. #ifdef parallel_cplng
  491. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2 , J_STRT=j1, J_STOP=j2 )
  492. ! store shape:
  493. var_shape(1:2,region) = (/1,i2-i1+1/)
  494. var_shape(3:4,region) = (/1,j2-j1+1/)
  495. part_val(1) = 2
  496. part_val(2) = i1-1+(j1-1)*nx
  497. part_val(3) = i2-i1+1
  498. part_val(4) = j2-j1+1
  499. part_val(5) = nx
  500. #else
  501. ! store shape:
  502. var_shape(1:2,region) = (/1,nx/)
  503. var_shape(3:4,region) = (/1,ny/)
  504. part_val(1) = 0 ! serial partition
  505. part_val(2) = 0
  506. part_val(3) = 0
  507. if ( isroot ) part_val(3) = nx*ny ! total grid size
  508. #endif
  509. status = OASIS_OK ! <-- status was not set by PRISM_Def_Partition_Proto (is it still true in OASIS3-MCT?)
  510. call oasis_def_partition( part_id(region), part_val, status )
  511. if (status/=OASIS_OK) then
  512. write (error_message,'("from OASIS_DEF_PARTITION : ",i6)') status
  513. TRACEBACK
  514. call oasis_abort( comp_id, rname, error_message )
  515. end if
  516. #ifdef parallel_cplng
  517. write (gol,'(" partition : ",i6," ; ",5i6)') part_id(region), part_val; call goPr
  518. #else
  519. write (gol,'(" partition : ",i6," ; ",3i6)') part_id(region), part_val; call goPr
  520. #endif
  521. end do reg
  522. ! *** SPECTRAL
  523. sp_part_val(1) = 0
  524. sp_part_val(2) = 0
  525. sp_part_val(3) = 0
  526. if ( isroot ) sp_part_val(3) = ifs_shn*2 ! total grid size
  527. !status = OASIS_OK ! <-- status was not set by PRISM_Def_Partition_Proto (is it still true in OASIS3-MCT?)
  528. call oasis_def_partition( sp_part_id, sp_part_val, status )
  529. if (status/=OASIS_OK) then
  530. write (error_message,'("from OASIS_DEF_PARTITION : ",i6)') status
  531. TRACEBACK
  532. call oasis_abort( comp_id, rname, error_message )
  533. end if
  534. write (gol,'(" partition : ",i6," ; ",3i6)') sp_part_id, sp_part_val; call goPr
  535. ! -------------------------------------------------------------------------
  536. ! * CONFIGURE COUPLING FIELDS
  537. ! -------------------------------------------------------------------------
  538. !
  539. ! (0) DEFAULT
  540. !
  541. write (gol,'(" init cplvar list ...")'); call goPr
  542. var_nodims(1) = 2 ! rank of coupling field
  543. var_nodims(2) = 1 ! number of bundles in coupling field (always 1)
  544. var_type = OASIS_Real
  545. do ivar = 1, size(CplVar)
  546. CplVar(ivar)%cpl_name = ''
  547. nullify( CplVar(ivar)%var_id )
  548. nullify( CplVar(ivar)%var_name )
  549. CplVar(ivar)%grid_type = 'll' ! lon/lat
  550. CplVar(ivar)%region = -1
  551. CplVar(ivar)%nlev = -1
  552. #ifdef parallel_cplng
  553. CplVar(ivar)%serial = .false.
  554. #else
  555. CplVar(ivar)%serial = .true.
  556. #endif
  557. CplVar(ivar)%intent = 'xxx'
  558. CplVar(ivar)%cache = .false. ! at init, flag means "will use cache"
  559. CplVar(ivar)%cache_tmid = NewDate(year=9999)
  560. nullify( CplVar(ivar)%cache_data )
  561. end do
  562. ! Above init should be same as:
  563. ! CplVar = TCplVar('','',null(),null(),.true.,'xxx','ll',-1,-1,0.,0.,0.,0.,0,0,0,0,0,.false.,NewDate(year=9999),null())
  564. ! We could also just set pointers to => null() in declaration l.117
  565. ncplvar = 0 ! no fields defined yet
  566. !
  567. ! (1) METEO VARIABLES
  568. !
  569. write (gol,'(" set meteo cplvars ...")'); call goPr
  570. write (gol,'(" list : ",a)') trim(prism_get_list); call goPr
  571. ivar = 0
  572. GET: DO
  573. if ( len_trim(prism_get_list) == 0 ) exit ! leave if empty
  574. ! extract next name from list
  575. call goReadFromLine( prism_get_list, cpl_name, status, sep=',' )
  576. IF_NOTOK_RETURN(status=1)
  577. write (gol,'(" extracted ",a," ...")') trim(cpl_name); call goPr
  578. ivar = ivar + 1
  579. if ( ivar > maxcplvar ) then
  580. write (gol,'("ivar exceeds maxcplvar ",i6)') maxcplvar; call goErr
  581. TRACEBACK; status=1; return
  582. end if
  583. CplVar(ivar)%cpl_name = trim(cpl_name)
  584. CplVar(ivar)%intent = 'in'
  585. select case ( trim(cpl_name) )
  586. case ( 'LNSP' )
  587. CplVar(ivar)%name = 'LNSP'
  588. CplVar(ivar)%grid_type = 'sh' ! spherical harmonics
  589. CplVar(ivar)%serial = .true.
  590. CplVar(ivar)%nlev = 1
  591. CplVar(ivar)%cache = .true.
  592. case ( 'VOR' )
  593. CplVar(ivar)%name = 'VO'
  594. CplVar(ivar)%grid_type = 'sh' ! spherical harmonics
  595. CplVar(ivar)%serial = .true.
  596. CplVar(ivar)%nlev = ifs_cpl_nlev
  597. CplVar(ivar)%cache = .true.
  598. case ( 'DIV' )
  599. CplVar(ivar)%name = 'D'
  600. CplVar(ivar)%grid_type = 'sh' ! spherical harmonics
  601. CplVar(ivar)%serial = .true.
  602. CplVar(ivar)%nlev = ifs_cpl_nlev
  603. CplVar(ivar)%cache = .true.
  604. case ( 'SPRES' )
  605. CplVar(ivar)%name = 'sp'
  606. CplVar(ivar)%region = region_glb
  607. CplVar(ivar)%nlev = 1
  608. CplVar(ivar)%cache = .true.
  609. case ( 'TMP' )
  610. CplVar(ivar)%name = 'T'
  611. CplVar(ivar)%region = region_glb
  612. CplVar(ivar)%nlev = ifs_cpl_nlev
  613. case ( 'HUM' )
  614. CplVar(ivar)%name = 'Q'
  615. CplVar(ivar)%region = region_glb
  616. CplVar(ivar)%nlev = ifs_cpl_nlev
  617. case ( 'OROG' )
  618. CplVar(ivar)%name = 'oro'
  619. CplVar(ivar)%region = region_sfc
  620. CplVar(ivar)%nlev = 1
  621. case ( 'CLW' )
  622. CplVar(ivar)%name = 'CLWC'
  623. CplVar(ivar)%region = region_glb
  624. CplVar(ivar)%nlev = ifs_cpl_nlev
  625. case ( 'CIW')
  626. CplVar(ivar)%name = 'CIWC'
  627. CplVar(ivar)%region = region_glb
  628. CplVar(ivar)%nlev = ifs_cpl_nlev
  629. case ( 'CC' )
  630. CplVar(ivar)%name = 'CC'
  631. CplVar(ivar)%region = region_glb
  632. CplVar(ivar)%nlev = ifs_cpl_nlev
  633. case ( 'CCO' )
  634. CplVar(ivar)%name = 'CCO'
  635. CplVar(ivar)%region = region_glb
  636. CplVar(ivar)%nlev = ifs_cpl_nlev
  637. case ( 'CCU' )
  638. CplVar(ivar)%name = 'CCU'
  639. CplVar(ivar)%region = region_glb
  640. CplVar(ivar)%nlev = ifs_cpl_nlev
  641. case ( 'UMF' )
  642. CplVar(ivar)%name = 'UDMF'
  643. CplVar(ivar)%region = region_glb
  644. CplVar(ivar)%nlev = ifs_cpl_nlev
  645. case ( 'DMF' )
  646. CplVar(ivar)%name = 'DDMF'
  647. CplVar(ivar)%region = region_glb
  648. CplVar(ivar)%nlev = ifs_cpl_nlev
  649. case ( 'UDR' )
  650. CplVar(ivar)%name = 'UDDR'
  651. CplVar(ivar)%region = region_glb
  652. CplVar(ivar)%nlev = ifs_cpl_nlev
  653. case ( 'DDR' )
  654. CplVar(ivar)%name = 'DDDR'
  655. CplVar(ivar)%region = region_glb
  656. CplVar(ivar)%nlev = ifs_cpl_nlev
  657. case ( 'LSMSK' )
  658. CplVar(ivar)%name = 'lsm'
  659. CplVar(ivar)%region = region_sfc
  660. CplVar(ivar)%nlev = 1
  661. case ( 'ALB' )
  662. CplVar(ivar)%name = 'albedo'
  663. CplVar(ivar)%region = region_sfc
  664. CplVar(ivar)%nlev = 1
  665. case ( 'SR' )
  666. CplVar(ivar)%name = 'sr'
  667. CplVar(ivar)%region = region_sfc
  668. CplVar(ivar)%nlev = 1
  669. case ( 'CI' )
  670. CplVar(ivar)%name = 'ci'
  671. CplVar(ivar)%region = region_sfc
  672. CplVar(ivar)%nlev = 1
  673. case ( 'SST' )
  674. CplVar(ivar)%name = 'sst'
  675. CplVar(ivar)%region = region_sfc
  676. CplVar(ivar)%nlev = 1
  677. case ( 'U10M' )
  678. CplVar(ivar)%name = 'u10m'
  679. CplVar(ivar)%region = region_sfc
  680. CplVar(ivar)%nlev = 1
  681. case ( 'V10M' )
  682. CplVar(ivar)%name = 'v10m'
  683. CplVar(ivar)%region = region_sfc
  684. CplVar(ivar)%nlev = 1
  685. case ( 'WSPD' )
  686. CplVar(ivar)%name = 'wspd'
  687. CplVar(ivar)%region = region_sfc
  688. CplVar(ivar)%nlev = 1
  689. case ( 'SRC' )
  690. CplVar(ivar)%name = 'src'
  691. CplVar(ivar)%region = region_sfc
  692. CplVar(ivar)%nlev = 1
  693. case ( 'D2M' )
  694. CplVar(ivar)%name = 'd2m'
  695. CplVar(ivar)%region = region_sfc
  696. CplVar(ivar)%nlev = 1
  697. case ( 'T2M' )
  698. CplVar(ivar)%name = 't2m'
  699. CplVar(ivar)%region = region_sfc
  700. CplVar(ivar)%nlev = 1
  701. case ( 'SSHF' )
  702. CplVar(ivar)%name = 'sshf'
  703. CplVar(ivar)%region = region_sfc
  704. CplVar(ivar)%nlev = 1
  705. case ( 'SLHF' )
  706. CplVar(ivar)%name = 'slhf'
  707. CplVar(ivar)%region = region_sfc
  708. CplVar(ivar)%nlev = 1
  709. case ( 'EWSS' )
  710. CplVar(ivar)%name = 'ewss'
  711. CplVar(ivar)%region = region_sfc
  712. CplVar(ivar)%nlev = 1
  713. case ( 'NSSS' )
  714. CplVar(ivar)%name = 'nsss'
  715. CplVar(ivar)%region = region_sfc
  716. CplVar(ivar)%nlev = 1
  717. case ( 'CP' )
  718. CplVar(ivar)%name = 'cp'
  719. CplVar(ivar)%region = region_sfc
  720. CplVar(ivar)%nlev = 1
  721. case ( 'LSP' )
  722. CplVar(ivar)%name = 'lsp'
  723. CplVar(ivar)%region = region_sfc
  724. CplVar(ivar)%nlev = 1
  725. case ( 'SSR' )
  726. CplVar(ivar)%name = 'ssr'
  727. CplVar(ivar)%region = region_sfc
  728. CplVar(ivar)%nlev = 1
  729. case ( 'SKT__')
  730. CplVar(ivar)%name = 'skt'
  731. CplVar(ivar)%region = region_sfc
  732. CplVar(ivar)%nlev = 1
  733. case ( 'SF___' )
  734. CplVar(ivar)%name = 'sf'
  735. CplVar(ivar)%region = region_sfc
  736. CplVar(ivar)%nlev = 1
  737. case ( 'SD' )
  738. CplVar(ivar)%name = 'sd'
  739. CplVar(ivar)%region = region_sfc
  740. CplVar(ivar)%nlev = 1
  741. case ( 'SWVL1' )
  742. CplVar(ivar)%name = 'swvl1'
  743. CplVar(ivar)%region = region_sfc
  744. CplVar(ivar)%nlev = 1
  745. case ( 'TV01' )
  746. CplVar(ivar)%name = 'tv01'
  747. CplVar(ivar)%region = region_sfc
  748. CplVar(ivar)%nlev = 1
  749. case ( 'TV02' )
  750. CplVar(ivar)%name = 'tv02'
  751. CplVar(ivar)%region = region_sfc
  752. CplVar(ivar)%nlev = 1
  753. case ( 'TV03' )
  754. CplVar(ivar)%name = 'tv03'
  755. CplVar(ivar)%region = region_sfc
  756. CplVar(ivar)%nlev = 1
  757. case ( 'TV04' )
  758. CplVar(ivar)%name = 'tv04'
  759. CplVar(ivar)%region = region_sfc
  760. CplVar(ivar)%nlev = 1
  761. case ( 'TV05' )
  762. CplVar(ivar)%name = 'tv05'
  763. CplVar(ivar)%region = region_sfc
  764. CplVar(ivar)%nlev = 1
  765. case ( 'TV06' )
  766. CplVar(ivar)%name = 'tv06'
  767. CplVar(ivar)%region = region_sfc
  768. CplVar(ivar)%nlev = 1
  769. case ( 'TV07' )
  770. CplVar(ivar)%name = 'tv07'
  771. CplVar(ivar)%region = region_sfc
  772. CplVar(ivar)%nlev = 1
  773. case ( 'TV09' )
  774. CplVar(ivar)%name = 'tv09'
  775. CplVar(ivar)%region = region_sfc
  776. CplVar(ivar)%nlev = 1
  777. case ( 'TV10' )
  778. CplVar(ivar)%name = 'tv10'
  779. CplVar(ivar)%region = region_sfc
  780. CplVar(ivar)%nlev = 1
  781. case ( 'TV11' )
  782. CplVar(ivar)%name = 'tv11'
  783. CplVar(ivar)%region = region_sfc
  784. CplVar(ivar)%nlev = 1
  785. case ( 'TV13' )
  786. CplVar(ivar)%name = 'tv13'
  787. CplVar(ivar)%region = region_sfc
  788. CplVar(ivar)%nlev = 1
  789. case ( 'TV16' )
  790. CplVar(ivar)%name = 'tv16'
  791. CplVar(ivar)%region = region_sfc
  792. CplVar(ivar)%nlev = 1
  793. case ( 'TV17' )
  794. CplVar(ivar)%name = 'tv17'
  795. CplVar(ivar)%region = region_sfc
  796. CplVar(ivar)%nlev = 1
  797. case ( 'TV18' )
  798. CplVar(ivar)%name = 'tv18'
  799. CplVar(ivar)%region = region_sfc
  800. CplVar(ivar)%nlev = 1
  801. case ( 'TV19' )
  802. CplVar(ivar)%name = 'tv19'
  803. CplVar(ivar)%region = region_sfc
  804. CplVar(ivar)%nlev = 1
  805. case ( 'CVL' )
  806. CplVar(ivar)%name = 'cvl'
  807. CplVar(ivar)%region = region_sfc
  808. CplVar(ivar)%nlev = 1
  809. case ( 'CVH' )
  810. CplVar(ivar)%name = 'cvh'
  811. CplVar(ivar)%region = region_sfc
  812. CplVar(ivar)%nlev = 1
  813. case default
  814. write (gol,'("unsupported cpl_name : ",a)') trim(cpl_name); call goErr
  815. TRACEBACK; status=1; return
  816. end select
  817. ! check
  818. if ( CplVar(ivar)%nlev < 1 ) then
  819. write (gol,'("found nlev ",i6," in cplvar ",i4," (",a,")")') CplVar(ivar)%nlev, ivar, trim(cpl_name); call goErr
  820. TRACEBACK; status=1; return
  821. end if
  822. ! storage per level
  823. allocate( CplVar(ivar)%var_id (CplVar(ivar)%nlev) )
  824. allocate( CplVar(ivar)%var_name(CplVar(ivar)%nlev) )
  825. ! name used in namcouple
  826. if ( CplVar(ivar)%nlev == 1 ) then
  827. ilev = 1
  828. write (CplVar(ivar)%var_name(ilev),'("C_",a)') trim(CplVar(ivar)%cpl_name)
  829. write (gol,'(" cplvar ",2i4," ",a)') ivar, ilev, trim(CplVar(ivar)%var_name(ilev)); call goPr
  830. else
  831. do ilev = 1, CplVar(ivar)%nlev
  832. write (CplVar(ivar)%var_name(ilev),'("C_",a,".L",i3.3)') trim(CplVar(ivar)%cpl_name), ilev
  833. write (gol,'(" cplvar ",2i4," ",a)') ivar, ilev, trim(CplVar(ivar)%var_name(ilev)); call goPr
  834. end do
  835. end if
  836. ! store latest number:
  837. ncplvar = ivar
  838. END DO GET ! list coupled var to get
  839. !
  840. ! (2) VARIABLES SENT TO IFS
  841. !
  842. write (gol,'(" set concentration/optics coupled vars ...")'); call goPr
  843. write (gol,'(" list : ",a)') trim(prism_put_list); call goPr
  844. ivar = ncplvar
  845. PUT: DO
  846. if ( len_trim(prism_put_list) == 0 ) exit
  847. ! extract next name from list
  848. call goReadFromLine( prism_put_list, cpl_name, status, sep=',' )
  849. IF_NOTOK_RETURN(status=1)
  850. write (gol,'(" extracted ",a," ...")') trim(cpl_name); call goPr
  851. ivar = ivar + 1
  852. if ( ivar > maxcplvar ) then
  853. write (gol,'("ivar exceeds maxcplvar ",i6)') maxcplvar; call goErr
  854. TRACEBACK; status=1; return
  855. end if
  856. CplVar(ivar)%cpl_name = trim(cpl_name)
  857. #ifdef parallel_cplng
  858. CplVar(ivar)%serial = .false.
  859. #else
  860. CplVar(ivar)%serial = .true.
  861. #endif
  862. CplVar(ivar)%intent = 'out'
  863. CplVar(ivar)%region = region_glb
  864. select case ( trim(cpl_name) )
  865. case ( 'O3', 'CH4', 'CO2' )
  866. ! send whole atmosphere for ozone, methane and CO2
  867. if (.not.refine_levels) then ! in both cases this should be ifs_cpl_nlev!
  868. CplVar(ivar)%nlev = lm(region_glb)
  869. else
  870. CplVar(ivar)%nlev = ifs_cpl_nlev
  871. endif
  872. case default
  873. ! for aerosols, do not send all levels in stratosphere
  874. ! this works, for refine_levels true or false
  875. CplVar(ivar)%nlev = ifs_cpl_nlev_cutoff
  876. end select
  877. select case ( trim(cpl_name) )
  878. case ( 'CO2' )
  879. CplVar(ivar)%itr = ico2
  880. case ( 'O3' )
  881. CplVar(ivar)%itr = io3
  882. case ( 'CH4' )
  883. CplVar(ivar)%itr = ich4
  884. #ifdef with_m7
  885. case ( 'N1' )
  886. CplVar(ivar)%itr = inus_n
  887. case ( 'SU1' )
  888. CplVar(ivar)%itr = iso4nus
  889. case ( 'N2' )
  890. CplVar(ivar)%itr = iais_n
  891. case ( 'SU2' )
  892. CplVar(ivar)%itr = iso4ais
  893. case ( 'BC2' )
  894. CplVar(ivar)%itr = ibcais
  895. case ( 'OC2' )
  896. CplVar(ivar)%itr = ipomais
  897. case ( 'N3' )
  898. CplVar(ivar)%itr = iacs_n
  899. case ( 'SU3' )
  900. CplVar(ivar)%itr = iso4acs
  901. case ( 'BC3' )
  902. CplVar(ivar)%itr = ibcacs
  903. case ( 'OC3' )
  904. CplVar(ivar)%itr = ipomacs
  905. case ( 'SS3' )
  906. CplVar(ivar)%itr = issacs
  907. case ( 'DU3' )
  908. CplVar(ivar)%itr = iduacs
  909. case ( 'N4' )
  910. CplVar(ivar)%itr = icos_n
  911. case ( 'SU4' )
  912. CplVar(ivar)%itr = iso4cos
  913. case ( 'BC4' )
  914. CplVar(ivar)%itr = ibccos
  915. case ( 'OC4' )
  916. CplVar(ivar)%itr = ipomcos
  917. case ( 'SS4' )
  918. CplVar(ivar)%itr = isscos
  919. case ( 'DU4' )
  920. CplVar(ivar)%itr = iducos
  921. case ( 'N5' )
  922. CplVar(ivar)%itr = iaii_n
  923. case ( 'BC5' )
  924. CplVar(ivar)%itr = ibcaii
  925. case ( 'OC5' )
  926. CplVar(ivar)%itr = ipomaii
  927. case ( 'N6' )
  928. CplVar(ivar)%itr = iaci_n
  929. case ( 'DU6' )
  930. CplVar(ivar)%itr = iduaci
  931. case ( 'N7' )
  932. CplVar(ivar)%itr = icoi_n
  933. case ( 'DU7' )
  934. CplVar(ivar)%itr = iducoi
  935. case ( 'NO3' )
  936. CplVar(ivar)%itr = ino3_a
  937. case ( 'MSA' )
  938. CplVar(ivar)%itr = imsa
  939. #endif
  940. #ifdef with_ecearth_optics
  941. case ( 'AOD_01', 'AOD_02', 'AOD_03', 'AOD_04', 'AOD_05', 'AOD_06', 'AOD_07', &
  942. 'AOD_08', 'AOD_09', 'AOD_10', 'AOD_11', 'AOD_12', 'AOD_13', 'AOD_14', &
  943. 'SSA_01', 'SSA_02', 'SSA_03', 'SSA_04', 'SSA_05', 'SSA_06', 'SSA_07', &
  944. 'SSA_08', 'SSA_09', 'SSA_10', 'SSA_11', 'SSA_12', 'SSA_13', 'SSA_14', &
  945. 'ASF_01', 'ASF_02', 'ASF_03', 'ASF_04', 'ASF_05', 'ASF_06', 'ASF_07', &
  946. 'ASF_08', 'ASF_09', 'ASF_10', 'ASF_11', 'ASF_12', 'ASF_13', 'ASF_14' )
  947. #endif
  948. case default
  949. write (gol,'("unsupported cpl_name : ",a)') trim(cpl_name); call goErr
  950. TRACEBACK; status=1; return
  951. end select
  952. ! set name:
  953. select case ( trim(cpl_name) )
  954. #ifdef with_ecearth_optics
  955. case ( 'AOD_01', 'AOD_02', 'AOD_03', 'AOD_04', 'AOD_05', 'AOD_06', 'AOD_07', &
  956. 'AOD_08', 'AOD_09', 'AOD_10', 'AOD_11', 'AOD_12', 'AOD_13', 'AOD_14', &
  957. 'SSA_01', 'SSA_02', 'SSA_03', 'SSA_04', 'SSA_05', 'SSA_06', 'SSA_07', &
  958. 'SSA_08', 'SSA_09', 'SSA_10', 'SSA_11', 'SSA_12', 'SSA_13', 'SSA_14', &
  959. 'ASF_01', 'ASF_02', 'ASF_03', 'ASF_04', 'ASF_05', 'ASF_06', 'ASF_07', &
  960. 'ASF_08', 'ASF_09', 'ASF_10', 'ASF_11', 'ASF_12', 'ASF_13', 'ASF_14' )
  961. write(CplVar(ivar)%name,'(a)') trim(cpl_name)
  962. #endif
  963. case default
  964. CplVar(ivar)%name = names(CplVar(ivar)%itr)
  965. end select
  966. ! check ..
  967. if ( CplVar(ivar)%nlev < 1 ) then
  968. write (gol,'("found nlev ",i6," in cplvar ",i4," (",a,")")') CplVar(ivar)%nlev, ivar, trim(cpl_name); call goErr
  969. TRACEBACK; status=1; return
  970. end if
  971. ! storage per level
  972. allocate( CplVar(ivar)%var_id (CplVar(ivar)%nlev) )
  973. allocate( CplVar(ivar)%var_name(CplVar(ivar)%nlev) )
  974. ! name used in namcouple
  975. if ( CplVar(ivar)%nlev == 1 ) then
  976. ilev = 1
  977. write (CplVar(ivar)%var_name(ilev),'(a,"TM5")') trim(CplVar(ivar)%cpl_name)
  978. write (gol,'(" cplvar ",2i4," ",a)') ivar, ilev, trim(CplVar(ivar)%var_name(ilev)); call goPr
  979. else
  980. do ilev = 1, CplVar(ivar)%nlev
  981. write (CplVar(ivar)%var_name(ilev),'("C_",a,".L",i3.3)') trim(CplVar(ivar)%cpl_name), ilev
  982. end do
  983. write (gol,'(" cplvar ",2i4," ",a)') ivar, ilev-1, trim(CplVar(ivar)%var_name(ilev-1)); call goPr
  984. end if
  985. ncplvar = ivar
  986. END DO PUT ! list with coupled names of var to send to IFS
  987. !
  988. ! (3) COUPLING WITH LPJG
  989. !
  990. if (coupled_to_lpj) then
  991. ! Sent to LPJ-Guess
  992. ivar = ncplvar + 1
  993. if ( ivar > maxcplvar ) then
  994. write (gol,'("ivar exceeds maxcplvar ",i6)') maxcplvar; call goErr
  995. TRACEBACK; status=1; return
  996. end if
  997. CplVar(ivar)%cpl_name = 'co2_for_lpjg'
  998. CplVar(ivar)%itr = ico2
  999. CplVar(ivar)%name = 'ppmCO2' ! Reserve names(CplVar(ivar)%itr) for tracer mass
  1000. #ifdef parallel_cplng
  1001. CplVar(ivar)%serial = .false.
  1002. #else
  1003. CplVar(ivar)%serial = .true.
  1004. #endif
  1005. CplVar(ivar)%intent = 'out'
  1006. CplVar(ivar)%region = region_glb
  1007. CplVar(ivar)%nlev = 1
  1008. allocate( CplVar(ivar)%var_id (1) )
  1009. allocate( CplVar(ivar)%var_name(1) )
  1010. CplVar(ivar)%var_name(1) = "LCO2_TM5" ! Land CO2
  1011. write (gol,'(" cplvar ",2i4," ",a)') ivar, ilev, trim(CplVar(ivar)%var_name(1)); call goPr
  1012. ! Received from LPJ-Guess
  1013. ivar = ivar + 1
  1014. if ( ivar > maxcplvar ) then
  1015. write (gol,'("ivar exceeds maxcplvar ",i6)') maxcplvar; call goErr
  1016. TRACEBACK; status=1; return
  1017. end if
  1018. CplVar(ivar)%cpl_name = 'land_c_flux_nat'
  1019. CplVar(ivar)%name = 'land_c_flux_nat'
  1020. #ifdef parallel_cplng
  1021. CplVar(ivar)%serial = .false.
  1022. #else
  1023. CplVar(ivar)%serial = .true.
  1024. #endif
  1025. CplVar(ivar)%intent = 'in'
  1026. CplVar(ivar)%region = region_glb
  1027. CplVar(ivar)%nlev = 1
  1028. CplVar(ivar)%itr = ico2
  1029. allocate( CplVar(ivar)%var_id (1) )
  1030. allocate( CplVar(ivar)%var_name(1) )
  1031. CplVar(ivar)%var_name(1) = "TM5_LandCNAT"
  1032. write (gol,'(" cplvar ",2i4," ",a)') ivar, ilev, trim(CplVar(ivar)%var_name(1)); call goPr
  1033. ivar = ivar + 1
  1034. if ( ivar > maxcplvar ) then
  1035. write (gol,'("ivar exceeds maxcplvar ",i6)') maxcplvar; call goErr
  1036. TRACEBACK; status=1; return
  1037. end if
  1038. CplVar(ivar)%cpl_name = 'land_c_flux_ant'
  1039. CplVar(ivar)%name = 'land_c_flux_ant'
  1040. #ifdef parallel_cplng
  1041. CplVar(ivar)%serial = .false.
  1042. #else
  1043. CplVar(ivar)%serial = .true.
  1044. #endif
  1045. CplVar(ivar)%intent = 'in'
  1046. CplVar(ivar)%region = region_glb
  1047. CplVar(ivar)%nlev = 1
  1048. CplVar(ivar)%itr = ico2
  1049. allocate( CplVar(ivar)%var_id (1) )
  1050. allocate( CplVar(ivar)%var_name(1) )
  1051. CplVar(ivar)%var_name(1) = "TM5_LandCANT"
  1052. write (gol,'(" cplvar ",2i4," ",a)') ivar, ilev, trim(CplVar(ivar)%var_name(1)); call goPr
  1053. ivar = ivar + 1
  1054. if ( ivar > maxcplvar ) then
  1055. write (gol,'("ivar exceeds maxcplvar ",i6)') maxcplvar; call goErr
  1056. TRACEBACK; status=1; return
  1057. end if
  1058. CplVar(ivar)%cpl_name = 'land_c_npp'
  1059. CplVar(ivar)%name = 'land_c_npp'
  1060. #ifdef parallel_cplng
  1061. CplVar(ivar)%serial = .false.
  1062. #else
  1063. CplVar(ivar)%serial = .true.
  1064. #endif
  1065. CplVar(ivar)%intent = 'in'
  1066. CplVar(ivar)%region = region_glb
  1067. CplVar(ivar)%nlev = 1
  1068. CplVar(ivar)%itr = 999
  1069. allocate( CplVar(ivar)%var_id (1) )
  1070. allocate( CplVar(ivar)%var_name(1) )
  1071. CplVar(ivar)%var_name(1) = "TM5_LandCNPP"
  1072. write (gol,'(" cplvar ",2i4," ",a)') ivar, ilev, trim(CplVar(ivar)%var_name(1)); call goPr
  1073. ncplvar = ivar
  1074. end if
  1075. !
  1076. ! (4) COUPLING WITH PISCES
  1077. !
  1078. if (coupled_to_pis) then
  1079. ! Sent to PISCES
  1080. ivar = ncplvar + 1
  1081. if ( ivar > maxcplvar ) then
  1082. write (gol,'("ivar exceeds maxcplvar ",i6)') maxcplvar; call goErr
  1083. TRACEBACK; status=1; return
  1084. end if
  1085. CplVar(ivar)%cpl_name = 'co2_for_pis'
  1086. CplVar(ivar)%itr = ico2
  1087. CplVar(ivar)%name = 'ppmCO2' ! Reserve names(CplVar(ivar)%itr) for tracer mass
  1088. #ifdef parallel_cplng
  1089. CplVar(ivar)%serial = .false.
  1090. #else
  1091. CplVar(ivar)%serial = .true.
  1092. #endif
  1093. CplVar(ivar)%intent = 'out'
  1094. CplVar(ivar)%region = region_glb
  1095. CplVar(ivar)%nlev = 1
  1096. allocate( CplVar(ivar)%var_id (1) )
  1097. allocate( CplVar(ivar)%var_name(1) )
  1098. CplVar(ivar)%var_name(1) = "OCO2_TM5" ! Ocean CO2
  1099. write (gol,'(" cplvar ",2i4," ",a)') ivar, ilev, trim(CplVar(ivar)%var_name(1)); call goPr
  1100. ! Received from PISCES
  1101. ivar = ivar + 1
  1102. if ( ivar > maxcplvar ) then
  1103. write (gol,'("ivar exceeds maxcplvar ",i6)') maxcplvar; call goErr
  1104. TRACEBACK; status=1; return
  1105. end if
  1106. CplVar(ivar)%cpl_name = 'oce_c_flux' ! C fluxes from Ocean
  1107. CplVar(ivar)%name = 'oce_c_flux'
  1108. #ifdef parallel_cplng
  1109. CplVar(ivar)%serial = .false.
  1110. #else
  1111. CplVar(ivar)%serial = .true.
  1112. #endif
  1113. CplVar(ivar)%intent = 'in'
  1114. CplVar(ivar)%region = region_glb
  1115. CplVar(ivar)%nlev = 1
  1116. CplVar(ivar)%itr = 999
  1117. allocate( CplVar(ivar)%var_id (1) )
  1118. allocate( CplVar(ivar)%var_name(1) )
  1119. CplVar(ivar)%var_name(1) = "TM5_OceCFLX"
  1120. write (gol,'(" cplvar ",2i4," ",a)') ivar, ilev, trim(CplVar(ivar)%var_name(1)); call goPr
  1121. ncplvar = ivar
  1122. end if
  1123. !
  1124. ! (5) DEFINE OASIS VARIABLES
  1125. !
  1126. write (gol,'(" define oasis variables ...")'); call goPr
  1127. do ivar = 1, ncplvar
  1128. ireg = CplVar(ivar)%region
  1129. select case ( CplVar(ivar)%intent )
  1130. case ( 'in' )
  1131. var_intent = OASIS_In
  1132. case ( 'out' )
  1133. var_intent = OASIS_Out
  1134. case default
  1135. write (gol,'("unsupported intent : ",a)') trim(CplVar(ivar)%intent); call goErr
  1136. TRACEBACK; status=1; return
  1137. end select
  1138. do ilev = 1, CplVar(ivar)%nlev
  1139. select case ( CplVar(ivar)%grid_type )
  1140. case ( 'sh' )
  1141. !DBG write (gol,'(" ",i4," (",i3,") spectral variable ",a," ...")') ivar, ilev, trim(CplVar(ivar)%var_name(ilev)); call goPr
  1142. !DBG write (gol,'(" region : ",i6)' ) ireg ; call goPr
  1143. !DBG write (gol,'(" partition : ",i6)' ) sp_part_id ; call goPr
  1144. !DBG write (gol,'(" nodims : ",2i6)' ) var_nodims ; call goPr
  1145. !DBG write (gol,'(" shape : ",4i6)' ) sp_var_shape(1:4) ; call goPr
  1146. call oasis_def_var( &
  1147. CplVar(ivar)%var_id(ilev), &
  1148. trim(CplVar(ivar)%var_name(ilev)), &
  1149. sp_part_id, var_nodims, var_intent, &
  1150. sp_var_shape(1:4), var_type, status )
  1151. IF_PRISM_NOTOK_RETURN(status=1)
  1152. case ( 'll' )
  1153. !DBG write (gol,'(" ",i4," (",i3,") gridded variable ",a," ...")') ivar, ilev, trim(CplVar(ivar)%var_name(ilev)); call goPr
  1154. !DBG write (gol,'(" region : ",i6)' ) ireg ; call goPr
  1155. !DBG write (gol,'(" partition : ",i6)' ) part_id(ireg) ; call goPr
  1156. !DBG write (gol,'(" nodims : ",2i6)' ) var_nodims ; call goPr
  1157. !DBG write (gol,'(" shape : ",4i6)' ) var_shape(1:4,ireg) ; call goPr
  1158. call oasis_def_var( &
  1159. CplVar(ivar)%var_id(ilev), &
  1160. trim(CplVar(ivar)%var_name(ilev)), &
  1161. part_id(ireg), var_nodims, var_intent, &
  1162. var_shape(1:4,ireg), var_type, status )
  1163. IF_PRISM_NOTOK_RETURN(status=1)
  1164. case default
  1165. write (gol,'("unsupported grid_type : ",a)') trim(CplVar(ivar)%grid_type); call goErr
  1166. TRACEBACK; status=1; return
  1167. end select
  1168. end do ! levels
  1169. end do ! var
  1170. !
  1171. ! (6) STORE GRID INFO
  1172. !
  1173. write (gol,'("add grid info to cplvars ...")'); call goPr
  1174. do ivar = 1, ncplvar
  1175. do ilev = 1, CplVar(ivar)%nlev
  1176. select case ( CplVar(ivar)%grid_type )
  1177. case ( 'sh' )
  1178. CplVar(ivar)%shT = ifs_shT
  1179. CplVar(ivar)%shn = ifs_shn
  1180. CplVar(ivar)%shn_recv = ifs_shn
  1181. if ( CplVar(ivar)%cache ) allocate( CplVar(ivar)%cache_data(2,CplVar(ivar)%shn,CplVar(ivar)%nlev) )
  1182. case ( 'll' )
  1183. #ifdef parallel_cplng
  1184. call Get_DistGrid( dgrid(CplVar(ivar)%region), lli=local_lli)
  1185. CplVar(ivar)%west_deg = local_lli%lon_deg(1)
  1186. CplVar(ivar)%south_deg = local_lli%lat_deg(1)
  1187. CplVar(ivar)%dlon_deg = local_lli%dlon_deg
  1188. CplVar(ivar)%dlat_deg = local_lli%dlat_deg
  1189. CplVar(ivar)%nlon = local_lli%nlon
  1190. CplVar(ivar)%nlat = local_lli%nlat
  1191. if ( CplVar(ivar)%cache ) &
  1192. allocate( CplVar(ivar)%cache_data(CplVar(ivar)%nlon, CplVar(ivar)%nlat, CplVar(ivar)%nlev) )
  1193. #else
  1194. CplVar(ivar)%west_deg = lli(CplVar(ivar)%region)%lon_deg(1)
  1195. CplVar(ivar)%south_deg = lli(CplVar(ivar)%region)%lat_deg(1)
  1196. CplVar(ivar)%dlon_deg = lli(CplVar(ivar)%region)%dlon_deg
  1197. CplVar(ivar)%dlat_deg = lli(CplVar(ivar)%region)%dlat_deg
  1198. CplVar(ivar)%nlon = lli(CplVar(ivar)%region)%nlon
  1199. CplVar(ivar)%nlat = lli(CplVar(ivar)%region)%nlat
  1200. if ( CplVar(ivar)%cache ) &
  1201. allocate( CplVar(ivar)%cache_data(CplVar(ivar)%nlon,CplVar(ivar)%nlat,CplVar(ivar)%nlev) )
  1202. #endif
  1203. case default
  1204. write (gol,'("unsupported grid_type : ",a)') trim(CplVar(ivar)%grid_type); call goErr
  1205. TRACEBACK; status=1; return
  1206. end select
  1207. end do ! levels
  1208. end do ! var
  1209. !
  1210. ! (7) FINALISE
  1211. !
  1212. call oasis_enddef( status )
  1213. if (status/=OASIS_OK) then
  1214. write (error_message,'("from OASIS_ENDDEF : ",i6)') status
  1215. TRACEBACK
  1216. call oasis_abort( comp_id, rname, error_message )
  1217. end if
  1218. if (isRoot) then
  1219. write (gol,'(" ")' ) ; call goPr
  1220. write (gol,'("initialized oasis coupling:")' ) ; call goPr
  1221. write (gol,'(" component : ",a)' ) trim(comp_name) ; call goPr
  1222. write (gol,'(" real kind : ",i4)' ) wp ; call goPr
  1223. write (gol,'(" ")' ) ; call goPr
  1224. end if
  1225. status = 0
  1226. END SUBROUTINE TM5_PRISM_INIT2
  1227. !EOC
  1228. !--------------------------------------------------------------------------
  1229. ! TM5 !
  1230. !--------------------------------------------------------------------------
  1231. !BOP
  1232. !
  1233. ! !IROUTINE: TM5_PRISM_DONE
  1234. !
  1235. ! !DESCRIPTION: cleanup (ie deallocate).
  1236. !\\
  1237. !\\
  1238. ! !INTERFACE:
  1239. !
  1240. SUBROUTINE TM5_Prism_Done( status )
  1241. USE dims, ONLY : nregions, okdebug, im, jm
  1242. USE TM5_DISTGRID, ONLY : dgrid, Get_DistGrid, scatter, gather, reduce
  1243. USE partools, ONLY : isRoot
  1244. !
  1245. ! !OUTPUT PARAMETERS:
  1246. !
  1247. integer, intent(out) :: status
  1248. !
  1249. ! !REVISION HISTORY:
  1250. ! 10 Sep 2013 - Ph. Le Sager -
  1251. !
  1252. ! !REMARKS:
  1253. !
  1254. !EOP
  1255. !------------------------------------------------------------------------
  1256. !BOC
  1257. character(len=*), parameter :: rname = mname//'/TM5_Prism_Done'
  1258. integer :: ireg
  1259. integer :: ivar
  1260. INTEGER :: region, i1, i2, j1, j2
  1261. REAL, DIMENSION(:,:), ALLOCATABLE :: collect_co2_total_flux_recv, collect_co2_total_flux_appl
  1262. ! --- begin -----------------------------------
  1263. DO region = 1, nregions
  1264. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  1265. if (isRoot) then
  1266. ALLOCATE(collect_co2_total_flux_recv(im(region), jm(region)))
  1267. ALLOCATE(collect_co2_total_flux_appl(im(region), jm(region)))
  1268. else
  1269. ALLOCATE(collect_co2_total_flux_recv(1,1) )
  1270. ALLOCATE(collect_co2_total_flux_appl(1,1) )
  1271. end if
  1272. CALL GATHER( dgrid(region), co2_total_flux_recv, collect_co2_total_flux_recv, 0, status)
  1273. IF_NOTOK_RETURN(status=1)
  1274. CALL GATHER( dgrid(region), co2_total_flux_appl, collect_co2_total_flux_appl, 0, status)
  1275. IF_NOTOK_RETURN(status=1)
  1276. IF ( isRoot ) THEN
  1277. write (gol,'("--------------------------------------------------------")'); call goPr
  1278. write (gol,'(" Budget of tracer CO2 (kg) : ")'); call goPr
  1279. write (gol,'("--------------------------------------------------------")'); call goPr
  1280. write (gol,'(A,E13.6)') 'Total CO2 flux recv : ',sum(collect_co2_total_flux_recv); call goPr
  1281. write (gol,'(A,E13.6)') 'Total CO2 flux appl : ',sum(collect_co2_total_flux_appl); call goPr
  1282. ENDIF
  1283. END DO
  1284. ! --- cleanup ---------------------------------
  1285. deallocate( part_id )
  1286. deallocate( var_shape )
  1287. deallocate( sp_var_shape )
  1288. deallocate(co2_flux_recv)
  1289. deallocate(co2_flux_appl)
  1290. deallocate(co2_total_flux_recv)
  1291. deallocate(co2_total_flux_appl)
  1292. deallocate(collect_co2_total_flux_recv)
  1293. deallocate(collect_co2_total_flux_appl)
  1294. ! clear descriptions:
  1295. do ivar = 1, ncplvar
  1296. deallocate( CplVar(ivar)%var_id )
  1297. deallocate( CplVar(ivar)%var_name )
  1298. if ( associated(CplVar(ivar)%cache_data) ) deallocate( CplVar(ivar)%cache_data )
  1299. end do
  1300. status = 0
  1301. END SUBROUTINE TM5_PRISM_DONE
  1302. !EOC
  1303. !--------------------------------------------------------------------------
  1304. ! TM5 !
  1305. !--------------------------------------------------------------------------
  1306. !BOP
  1307. !
  1308. ! !IROUTINE: InqCplVar
  1309. !
  1310. ! !DESCRIPTION: Inquire if there is a coupled variable with 'name'.
  1311. !\\
  1312. !\\
  1313. ! !INTERFACE:
  1314. !
  1315. SUBROUTINE InqCplVar( name, status, ivar, var_id, var_name, nlev )
  1316. !
  1317. ! !INPUT PARAMETERS:
  1318. !
  1319. character(len=*), intent(in) :: name
  1320. !
  1321. ! !OUTPUT PARAMETERS:
  1322. !
  1323. integer, intent(out) :: status
  1324. integer, intent(out), optional :: ivar
  1325. integer, intent(out), optional :: var_id(:)
  1326. character(len=*), intent(out), optional :: var_name(:)
  1327. integer, intent(out), optional :: nlev
  1328. !
  1329. ! !REVISION HISTORY:
  1330. ! 10 Sep 2013 - Ph. Le Sager -
  1331. !
  1332. ! !REMARKS:
  1333. !
  1334. !EOP
  1335. !------------------------------------------------------------------------
  1336. !BOC
  1337. character(len=*), parameter :: rname = mname//'/InqCplVar'
  1338. integer :: i, iv
  1339. ! --- begin -----------------------------------
  1340. ! loop over defined variables:
  1341. iv = -1
  1342. do i = 1, ncplvar
  1343. ! check name:
  1344. if ( trim(name) == trim(CplVar(i)%name) ) then
  1345. iv = i
  1346. exit
  1347. end if
  1348. end do
  1349. ! not found ?
  1350. if ( iv < 0 ) then
  1351. write (gol,'("name of cplvar not found : ",a)') trim(name) ; call goErr
  1352. write (gol,'(" available names : ")' ) ; call goErr
  1353. do i = 1, ncplvar
  1354. write (gol,'(" ",i4," ",a)') i, trim(CplVar(i)%name) ; call goErr
  1355. end do
  1356. end if
  1357. ! fill requested arguments:
  1358. if ( present(ivar ) ) ivar = iv
  1359. if ( present(var_id ) ) var_id = CplVar(iv)%var_id
  1360. if ( present(var_name) ) var_name = CplVar(iv)%var_name
  1361. if ( present(nlev ) ) nlev = CplVar(iv)%nlev
  1362. ! ok
  1363. status = 0
  1364. END SUBROUTINE InqCplVar
  1365. !EOC
  1366. ! **************************************************************************
  1367. ! ***
  1368. ! *** spectral field remapping routines
  1369. ! ***
  1370. ! **************************************************************************
  1371. !--------------------------------------------------------------------------
  1372. ! TM5 !
  1373. !--------------------------------------------------------------------------
  1374. !BOP
  1375. !
  1376. ! !IROUTINE: SHREMAP_INIT
  1377. !
  1378. ! !DESCRIPTION: Init TshRemap object
  1379. !\\
  1380. !\\
  1381. ! !INTERFACE:
  1382. !
  1383. SUBROUTINE SHREMAP_INIT( shR, status )
  1384. !
  1385. ! !USES:
  1386. !
  1387. use GO, only : NewDate
  1388. !
  1389. ! !OUTPUT PARAMETERS:
  1390. !
  1391. type(TshRemap), intent(out) :: shR
  1392. integer, intent(out) :: status
  1393. !
  1394. ! !REMARKS:
  1395. !
  1396. !EOP
  1397. !------------------------------------------------------------------------
  1398. !BOC
  1399. character(len=*), parameter :: rname = mname//'/shremap_Init'
  1400. ! --- begin ---------------------------------------
  1401. ! no time stored yet:
  1402. shR%t = NewDate(9999,9,9)
  1403. ! safety:
  1404. nullify( shR%remap )
  1405. ! nu truncation determined yet:
  1406. shR%shT = 0
  1407. status = 0
  1408. END SUBROUTINE SHREMAP_INIT
  1409. !EOC
  1410. !--------------------------------------------------------------------------
  1411. ! TM5 !
  1412. !--------------------------------------------------------------------------
  1413. !BOP
  1414. !
  1415. ! !IROUTINE: SHREMAP_DONE
  1416. !
  1417. ! !DESCRIPTION: deallocate var
  1418. !\\
  1419. !\\
  1420. ! !INTERFACE:
  1421. !
  1422. SUBROUTINE SHREMAP_DONE( shR, status )
  1423. !
  1424. ! !INPUT/OUTPUT PARAMETERS:
  1425. !
  1426. type(TshRemap), intent(inout) :: shR
  1427. !
  1428. ! !OUTPUT PARAMETERS:
  1429. !
  1430. integer, intent(out) :: status
  1431. !
  1432. ! !REMARKS:
  1433. !
  1434. !EOP
  1435. !------------------------------------------------------------------------
  1436. !BOC
  1437. character(len=*), parameter :: rname = mname//'/shremap_Done'
  1438. ! --- begin ---------------------------------------
  1439. if ( associated(shR%remap) ) deallocate( shR%remap )
  1440. status = 0
  1441. END SUBROUTINE SHREMAP_DONE
  1442. !EOC
  1443. !--------------------------------------------------------------------------
  1444. ! TM5 !
  1445. !--------------------------------------------------------------------------
  1446. !BOP
  1447. !
  1448. ! !IROUTINE: SHREMAP_SETUP
  1449. !
  1450. ! !DESCRIPTION:
  1451. !\\
  1452. !\\
  1453. ! !INTERFACE:
  1454. !
  1455. SUBROUTINE SHREMAP_SETUP( shR, spinf, spinf_nan, status )
  1456. !
  1457. ! !INPUT/OUTPUT PARAMETERS:
  1458. !
  1459. type(TshRemap), intent(inout) :: shR
  1460. !
  1461. ! !INPUT PARAMETERS:
  1462. !
  1463. real, intent(in) :: spinf(:,:,:) ! spectral info field
  1464. real, intent(in) :: spinf_nan ! not-a-number in spinf
  1465. !
  1466. ! !OUTPUT PARAMETERS:
  1467. !
  1468. integer, intent(out) :: status
  1469. !
  1470. ! !REMARKS:
  1471. !
  1472. !EOP
  1473. !------------------------------------------------------------------------
  1474. !BOC
  1475. character(len=*), parameter :: rname = mname//'/shremap_Setup'
  1476. integer :: nlev
  1477. integer :: sh_tripos(0:ifs_shT,0:ifs_shT)
  1478. integer :: vri, vm, vn, vp, vk
  1479. logical, allocatable :: sh_field(:,:,:)
  1480. integer :: i, j, k
  1481. real :: val
  1482. integer :: nzero, nerr
  1483. ! --- begin ---------------------------------------
  1484. ! number of levels:
  1485. nlev = size(spinf,2)
  1486. ! triangle position:
  1487. sh_tripos = 0
  1488. vp = 0
  1489. do vm = 0, ifs_shT
  1490. do vn = vm, ifs_shT
  1491. vp = vp + 1
  1492. sh_tripos(vm,vn) = vp
  1493. end do
  1494. end do
  1495. ! storage for mapping indices:
  1496. if ( .not. associated(shR%remap) ) then
  1497. allocate( shR%remap(ifs_shn*2,nlev,3) )
  1498. end if
  1499. shR%remap = -1
  1500. ! flags for target values; not filled remains negative:
  1501. allocate( sh_field(2,ifs_shn,nlev) )
  1502. sh_field = .false.
  1503. ! loop over levels:
  1504. do k = 1, nlev
  1505. ! no zero's detected yet ...
  1506. nzero = 0
  1507. ! loop over spectral elements in layer:
  1508. do i = 1, ifs_shn*2
  1509. !if (k==1) then
  1510. !write (gol,'(" k, i, spinf : ",2i6,f16.4)') k, i, spinf(i,k,1); call goPr
  1511. !endif
  1512. ! not a number ? then this is an extra element due to the partitioning
  1513. if ( spinf(i,k,1) == spinf_nan ) cycle
  1514. ! extract m, n, and level:
  1515. !
  1516. ! OLD : mmmnnnkk.0 real part
  1517. ! mmmnnnkk.5 imag part
  1518. !
  1519. !vri = 1 ! real part
  1520. !if ( spinf(i,k,1)-floor(spinf(i,k,1)) == 0.5 ) vri = 2 ! imaginary part
  1521. !vk = modulo( floor(spinf(i,k,1)), 100 ) ! level
  1522. !vn = modulo( floor((spinf(i,k,1)-vk)/100.0), 1000 ) ! n
  1523. !vm = floor(spinf(i,k,1)/100000.0) ! m
  1524. !
  1525. ! NEW : mmmnnn.kk real part
  1526. ! -mmmnnn.kk imag part
  1527. !
  1528. ! Note that real and imag for m=0,n=0 are both 000000.00 for nlev=1;
  1529. ! for nlev > 1, the values are both 000000.01
  1530. !
  1531. val = spinf(i,k,1)
  1532. if ( val > 0.0 ) then
  1533. ! positive value means real part:
  1534. vri = 1
  1535. else if ( val < 0.0 ) then
  1536. ! negative value means imag part:
  1537. vri = 2
  1538. else
  1539. ! zero values for both real and imag part of (0,0)
  1540. nzero = nzero + 1 ! counter for number of zero values found
  1541. !--
  1542. !! test number of zero values:
  1543. !select case ( nzero )
  1544. ! case ( 1 ) ; vri = 1 ! real part of (0,0)
  1545. ! case ( 2 ) ; vri = 2 ! imag part of (0,0)
  1546. ! case default
  1547. ! write (gol,'("found more than 2 zero values in spectral info, ")'); call goErr
  1548. ! write (gol,'("while only expected for real and imag part of (0,0)")'); call goErr
  1549. ! TRACEBACK; status=1; return
  1550. ! cycle ! next value from received array
  1551. !end select
  1552. !--
  1553. ! assume that the extra zero's are the imaginary part for m=0,
  1554. ! which is zero anyway and does not need to be received:
  1555. if ( (nzero == 1) .and. (nlev == 1) ) then
  1556. vri = 1 ! real part of (0,0) in spinf2d
  1557. else
  1558. cycle ! next value from received array
  1559. end if
  1560. end if
  1561. val = abs(val)
  1562. vk = nint( ( val - floor(val) )*100.0 ) ! level is fractional part
  1563. vn = modulo( floor(val), 1000 ) ! last 3 numbers is n
  1564. vm = floor( val/1000.0 ) ! first 3 numbers is m
  1565. ! trap surface level ...
  1566. if ( nlev == 1 ) vk = vk + 1
  1567. ! check ...
  1568. if ( (vri < 1) .or. (vri > 2) .or. &
  1569. (vm < 0) .or. (vm > ifs_shT) .or. (vn < vm) .or. (vn > ifs_shT) .or. &
  1570. ((nlev==1) .and. (vk/=1)) .or. &
  1571. ((nlev>1) .and. ((vk < 1) .or. (vk > nlev))) ) then
  1572. write (gol,'("strange values extracted from spectral info value:")') ; call goErr
  1573. write (gol,'(" spinf : ",f16.4)' ) spinf(i,k,1) ; call goErr
  1574. write (gol,'(" ri : ",i4," (1=real,2=imag)")' ) vri ; call goErr
  1575. write (gol,'(" m : ",i4," (0 .. ",i4,")")' ) vm, ifs_shT ; call goErr
  1576. write (gol,'(" n : ",i4," (m .. ",i4,")")' ) vn, ifs_shT ; call goErr
  1577. write (gol,'(" k : ",i4," (1 .. ",i4,")")' ) vk, nlev ; call goErr
  1578. write (gol,'(" nzero : ",i4)' ) nzero ; call goErr
  1579. TRACEBACK; status=1; return
  1580. end if
  1581. ! position in triangle:
  1582. vp = sh_tripos(vm,vn)
  1583. ! check ...
  1584. if ( (vp < 1) .or. (vp > ifs_shn) ) then
  1585. write (gol,'("strange triangle position:")' ) ; call goErr
  1586. write (gol,'(" ifs T : ",i4)' ) ifs_shT ; call goErr
  1587. write (gol,'(" m : ",i4)' ) vm ; call goErr
  1588. write (gol,'(" n : ",i4)' ) vm ; call goErr
  1589. write (gol,'(" p : ",i8)' ) vp ; call goErr
  1590. TRACEBACK; status=1; return
  1591. end if
  1592. ! store:
  1593. shR%remap(i,k,1) = vri
  1594. shR%remap(i,k,2) = vp
  1595. shR%remap(i,k,3) = vk
  1596. ! maximum truncation:
  1597. shR%shT = max( shR%shT, max( vm, vn ) )
  1598. ! flag ...
  1599. sh_field(shR%remap(i,k,1),shR%remap(i,k,2),shR%remap(i,k,3)) = .true.
  1600. end do ! received coeff i
  1601. end do ! level k
  1602. ! check on missing target values:
  1603. if ( .not. all(sh_field) ) then
  1604. ! error counter:
  1605. nerr = 0
  1606. ! loop over levels:
  1607. do k = 1, nlev
  1608. ! init triangle position counter:
  1609. vp = 0
  1610. ! loop over spectral triangle:
  1611. do vm = 0, ifs_shT
  1612. do vn = vm, ifs_shT
  1613. ! increase triangle position counter:
  1614. vp = vp + 1
  1615. ! negative values at unexpected places ?
  1616. if ( ( (vm==0) .and. (.not. sh_field(1,vp,k) ) ) .or. &
  1617. ( (vm> 0) .and. (.not. all(sh_field(:,vp,k))) ) ) then
  1618. ! increase error counter:
  1619. nerr = nerr + 1
  1620. ! intro message ?
  1621. if ( nerr == 1 ) then
  1622. write (gol,'("not all sh target values filled :")'); call goErr
  1623. write (gol,'(" ifs T : ",i4)') ifs_shT; call goErr
  1624. end if
  1625. ! show error:
  1626. write (gol,'(" (m, n) p, ; k ; real imag : (",2i5,") ",i8," ; ",i4," ; ",2l2)') vm, vn, vp, k, sh_field(:,vp,k); call goErr
  1627. end if ! negatives ?
  1628. end do ! n
  1629. end do ! m
  1630. end do ! level
  1631. ! leave ?
  1632. if (nerr>0) then
  1633. TRACEBACK; status=1; return
  1634. end if
  1635. end if ! some negatives ?
  1636. ! done
  1637. deallocate( sh_field )
  1638. status = 0
  1639. END SUBROUTINE SHREMAP_SETUP
  1640. !EOC
  1641. !--------------------------------------------------------------------------
  1642. ! TM5 !
  1643. !--------------------------------------------------------------------------
  1644. !BOP
  1645. !
  1646. ! !IROUTINE: SHREMAP_REMAP
  1647. !
  1648. ! !DESCRIPTION:
  1649. !\\
  1650. !\\
  1651. ! !INTERFACE:
  1652. !
  1653. SUBROUTINE SHREMAP_REMAP( shR, sh_recv, shi, sh_ri, status )
  1654. !
  1655. ! !USES:
  1656. !
  1657. use grid, only : TshGridInfo
  1658. !
  1659. ! !INPUT/OUTPUT PARAMETERS:
  1660. !
  1661. type(TshRemap), intent(inout) :: shR
  1662. !
  1663. ! !INPUT PARAMETERS:
  1664. !
  1665. real, intent(in) :: sh_recv(:,:,:)
  1666. type(TshGridInfo), intent(in) :: shi
  1667. !
  1668. ! !OUTPUT PARAMETERS:
  1669. !
  1670. real, intent(out) :: sh_ri(:,:,:)
  1671. integer, intent(out) :: status
  1672. !
  1673. ! !REMARKS:
  1674. !
  1675. !EOP
  1676. !------------------------------------------------------------------------
  1677. !BOC
  1678. character(len=*), parameter :: rname = mname//'/shremap_Remap'
  1679. integer :: nlev, i, k
  1680. ! --- begin ---------------------------------------
  1681. ! number of levels:
  1682. nlev = size(sh_recv,2)
  1683. ! check shape of input array ...
  1684. if ( any( shape(sh_recv) /= (/ifs_shn*2,nlev,1/) ) ) then
  1685. write (gol,'("strange input shape :")' ) ; call goErr
  1686. write (gol,'(" sh_recv : ",3i6)' ) shape(sh_recv) ; call goErr
  1687. write (gol,'(" expected : ",3i6)' ) ifs_shn*2,nlev,1 ; call goErr
  1688. TRACEBACK; status=1; return
  1689. end if
  1690. ! check shape of output array ...
  1691. if ( any( shape(sh_ri) /= (/2,ifs_shn,nlev/) ) ) then
  1692. write (gol,'("strange input shape :")' ) ; call goErr
  1693. write (gol,'(" sh : ",3i6)' ) shape(sh_ri) ; call goErr
  1694. write (gol,'(" expected : ",3i6)' ) 2,ifs_shn,nlev ; call goErr
  1695. TRACEBACK; status=1; return
  1696. end if
  1697. ! initial zero:
  1698. sh_ri = 0.0
  1699. ! loop over all elements of received array:
  1700. do k = 1, nlev
  1701. do i = 1, ifs_shn*2
  1702. ! the triplet shR%remap(i,k,:) defines (/ 1=real/2=imag, traingle-position, level /)
  1703. ! all negative ?
  1704. ! o this is a dummy element due to partitioning
  1705. ! o this is the imaginary part for m=0, which should remain zero
  1706. if ( all( shR%remap(i,k,:) < 0 ) ) cycle
  1707. ! any negative ? should not be possible...
  1708. if ( any( shR%remap(i,k,:) < 0 ) ) then
  1709. write (gol,'("found strange mapping:")' ) ; call goErr
  1710. write (gol,'(" triangle point : ",i6)' ) i ; call goErr
  1711. write (gol,'(" level : ",i6)' ) k ; call goErr
  1712. write (gol,'(" mapping : ",3i6)' ) shR%remap(i,k,:) ; call goErr
  1713. end if
  1714. ! copy value from received array into spectral field:
  1715. sh_ri(shR%remap(i,k,1),shR%remap(i,k,2),shR%remap(i,k,3)) = sh_recv(i,k,1)
  1716. end do
  1717. end do
  1718. status = 0
  1719. END SUBROUTINE SHREMAP_REMAP
  1720. !EOC
  1721. !--------------------------------------------------------------------------
  1722. ! TM5 !
  1723. !--------------------------------------------------------------------------
  1724. !BOP
  1725. !
  1726. ! !IROUTINE: SetPrismTime_date
  1727. !
  1728. ! !DESCRIPTION: returns current time/date into prism format (seconds from
  1729. ! prism reference start).
  1730. !\\
  1731. !\\
  1732. ! !INTERFACE:
  1733. !
  1734. subroutine SetPrismTime_date( prism_t, t, status )
  1735. !
  1736. ! !USES:
  1737. !
  1738. use GO, only : TDate, NewDate, iTotal, operator(-)
  1739. !
  1740. ! !OUTPUT PARAMETERS:
  1741. !
  1742. integer, intent(out) :: prism_t ! seconds from start
  1743. !
  1744. ! !INPUT PARAMETERS:
  1745. !
  1746. type(TDate), intent(in) :: t
  1747. integer, intent(out) :: status
  1748. !
  1749. ! !REMARKS:
  1750. !
  1751. !EOP
  1752. !------------------------------------------------------------------------
  1753. !BOC
  1754. character(len=*), parameter :: rname = mname//'/SetPrismTime_date'
  1755. ! --- begin ----------------------------------------
  1756. ! seconds since start
  1757. prism_t = iTotal( t - NewDate(time6=PRISM_start_date), 'sec' )
  1758. status = 0
  1759. end subroutine SetPrismTime_date
  1760. !EOC
  1761. END MODULE TM5_PRISM