tm5_prism.F90 64 KB

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