cpl.f90 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002
  1. module cplmod
  2. use resmod
  3. !
  4. parameter(nxa=NLAT_ATM + NLAT_ATM)
  5. parameter(nya=NLAT_ATM)
  6. !parameter(nxa=64,nya=32) !T42
  7. !parameter(nxa=128,nya=64) !T42
  8. parameter(nxo=72,nyot=76,nyo=nyot-4)
  9. parameter(radea=6.371E6)
  10. parameter(nud=6) ! output unit
  11. !
  12. character(len=30) :: version='cplmod 20/06/08'
  13. !
  14. real :: xa(nxa,nya) ! atm. longitudes
  15. real :: xa1(nxa,nya) ! atm. longitudes western boundary
  16. real :: xa2(nxa,nya) ! atm. longitudes eastern boundary
  17. real :: ya(nxa,nya) ! atm. latitudes
  18. real :: ya1(nxa,nya) ! atm. latitudes boundary 1
  19. real :: ya2(nxa,nya) ! atm. latitudes boundary 2
  20. real :: xos(nxo,nyo) ! oce. longitudes (scalar)
  21. real :: xos1(nxo,nyo) ! oce. longitudes western boundary (scalar)
  22. real :: xos2(nxo,nyo) ! oce. longitudes eastern boundary (scalar)
  23. real :: xov(nxo,nyo) ! oce. longitudes (vector)
  24. real :: xov1(nxo,nyo) ! oce. longitudes western boundary (vector)
  25. real :: xov2(nxo,nyo) ! oce. longitudes eastern boundary (vector)
  26. real :: yo(nxo,nyo) ! oce. latitudes
  27. real :: yo1(nxo,nyo) ! oce. latitudes boundary 1
  28. real :: yo2(nxo,nyo) ! oce. latitudes boundary 2
  29. !
  30. real :: agw(nxa,nya) ! atm. area weights
  31. real :: ogw(nxo,nyo) ! oce. area weights
  32. !
  33. real :: aslm(nxa,nya) = 0. ! atm. land(0)-see(1)-mask
  34. real :: oslms(nxo,nyo) = 0. ! oce. land(0)-see(1)-mask (scalar)
  35. real :: oslmv(nxo,nyo) = 0. ! oce. land(0)-see(1)-mask (vector)
  36. real :: asst(nxa,nya) = 0. ! atm. sst
  37. real :: aiced(nxa,nya) = 0. ! atm. ice thickness
  38. real :: apme(nxa,nya) = 0. ! atm. fresh water flux
  39. real :: ataux(nxa,nya) = 0. ! atm. u-stress
  40. real :: atauy(nxa,nya) = 0. ! atm. v-stress
  41. real :: ahfl(nxa,nya) = 0. ! atm. heat flux
  42. !
  43. real :: osst(nxo,nyo) = 0. ! oce. sst
  44. real :: oiced(nxo,nyo) = 0. ! oce. ice thickness
  45. real :: opme(nxo,nyo) = 0. ! oce. fresh water flux
  46. real :: otaux(nxo,nyo) = 0. ! oce. u-stress
  47. real :: otauy(nxo,nyo) = 0. ! oce. v-stress
  48. real :: ohfl(nxo,nyo) = 0. ! oce. heat flux
  49. !
  50. real :: assta(nxa,nya) = 0. ! atm. sst (accumulated)
  51. real :: aiceda(nxa,nya) = 0. ! atm. ice thickness (accumulated)
  52. real :: apmea(nxa,nya) = 0. ! atm. frsh water flux (accumulated)
  53. real :: atauxa(nxa,nya) = 0. ! atm. u-stress (accumulated)
  54. real :: atauya(nxa,nya) = 0. ! atm. v-stress (accumulated)
  55. real :: ahfla(nxa,nya) = 0. ! atm. heat flux (accumulated)
  56. !
  57. real :: ossta(nxo,nyo) = 0. ! oce. sst (accumulated)
  58. real :: oiceda(nxo,nyo) = 0. ! oce. ice thickness(accumulated)
  59. real :: opmea(nxo,nyo) = 0. ! oce. fresh water flux (accumulated)
  60. real :: otauxa(nxo,nyo) = 0. ! oce. u-stress (accumulated)
  61. real :: otauya(nxo,nyo) = 0. ! oce. v-stress (accumulated)
  62. real :: ohfla(nxo,nyo) = 0. ! oce. heat flux (accumulated)
  63. !
  64. real :: flukosst(nxo,nyot,12) = 0. ! sst flux correction
  65. real :: flukotaux(nxo,nyot,12) = 0. ! u-stress flux correction
  66. real :: flukotauy(nxo,nyot,12) = 0. ! v-stress flux correction
  67. real :: flukofresh(nxo,nyot,12)= 0. ! frsh water flux flux correction
  68. real :: flukoice(nxo,nyot,12) = 0. ! ice flux correction
  69. real :: flukooheat(nxo,nyot,12)= 0. ! heat flux flux correction
  70. !
  71. integer :: iroffi(nxa,nya) = 0 ! runoff mask input (nroffc=2,3)
  72. integer :: iroffo(nxa,nya) = 0 ! runoff mask output (nroffc=3)
  73. !
  74. integer :: ncoupling = 1 ! switch for coupling method
  75. integer :: nfluko = 0 ! switch for flux correction
  76. integer :: ngui = 0 ! switch for gui
  77. integer :: nroffc = 0 ! switch for runoff correction
  78. !
  79. integer :: nssta = 0 ! counter for atm. sst accumulation
  80. integer :: nicea = 0 ! counter for atm. ice accumulation
  81. integer :: npmea = 0 ! counter for atm. fresh water flux accumulation
  82. integer :: ntaua = 0 ! counter for atm. stress accumulation
  83. integer :: nhfla = 0 ! counter for atm. heat flux accumulation
  84. integer :: nssto = 0 ! counter for oce. sst accumulation
  85. integer :: niceo = 0 ! counter for oce. ice accumulation
  86. integer :: npmeo = 0 ! counter for oce. fresh water flux accumulation
  87. integer :: ntauo = 0 ! counter for oce. stress accumulation
  88. integer :: nhflo = 0 ! counter for oce. heat flux accumulation
  89. !
  90. integer :: naomod = 0 ! atm-oce coupling interval
  91. !
  92. integer :: ndatim(7) = 0 ! array containing time/date information
  93. integer :: nyear = 0 ! actual year
  94. integer :: nmonth = 0 ! actual month
  95. integer :: nday = 0 ! actual day
  96. integer :: nhour = 0 ! actual hour
  97. integer :: nmin = 0 ! actual minute
  98. integer :: nwday = 0 ! actual day of the week
  99. !
  100. ! namelist parameter
  101. !
  102. integer :: nprint = 0 ! extended diagnostics
  103. integer :: ndbox = 1 ! ocean diagnostic gp (i)
  104. integer :: ndboy = 1 ! ocean diagnostic gp (j)
  105. integer :: nflsst = 0 ! sst fluko
  106. integer :: nfltau = 0 ! stress fluko
  107. integer :: nflice = 0 ! ice fluko
  108. integer :: nflfresh = 0 ! pme fluko
  109. integer :: nfloheat = 0 ! heat flux (deep ocean) fluko
  110. integer :: nissta = 0 ! choise for ssta interpolation
  111. integer :: niicea = 0 ! choise for icea interpolation
  112. integer :: nipmea = 0 ! choise for pmea interpolation
  113. integer :: nitaua = 0 ! choise for taua interpolation
  114. integer :: nihfla = 0 ! choise for hfla interpolation
  115. integer :: nissto = 1 ! choise for ssto interpolation
  116. integer :: nihflo = 1 ! choise for hflo interpolation
  117. integer :: ncssta = 3 ! choise for ssta correction
  118. integer :: ncicea = 1 ! choise for icea correction
  119. integer :: ncpmea = 3 ! choise for pmea correction
  120. integer :: nctaua = 3 ! choise for taua correction
  121. integer :: nchfla = 3 ! choise for hfla correction
  122. integer :: ncssto = 3 ! choise for ssto correction
  123. integer :: nchflo = 3 ! choise for hflo correction
  124. !
  125. real :: cfacsst = 1. ! coupling factor sst
  126. real :: cfactau = 1. ! coupling factor stress
  127. real :: cfacice = 1. ! coupling factor ice
  128. real :: cfacfresh = 1. ! coupling factor fresh water
  129. !
  130. character(len=80) :: flukofile='fluko_data.txt'! file for flux corrction
  131. character(len=80) :: runoffmap='runoffmap.txt' ! file for runoff map
  132. !
  133. end module cplmod
  134. !
  135. ! ==================
  136. ! subroutine CLSGINI
  137. ! ==================
  138. !
  139. subroutine clsgini(kdatim,ktspd,kaomod,kcpl,kgui,pslm,kxa,kya)
  140. use cplmod
  141. !
  142. real :: pslm(nxa,nya)
  143. integer :: kdatim(7)
  144. integer :: ktspd
  145. integer :: kaomod
  146. integer :: kcpl
  147. integer :: kxa,kya
  148. logical :: lopen
  149. character(len=10) :: chform
  150. !
  151. ! dbug
  152. !
  153. real :: zduma(nxa,nya) = 1
  154. real :: zdumo(nxo,nyo) = 1
  155. real :: zslmaos(nxo,nyo)
  156. real :: zslmaov(nxo,nyo)
  157. real :: zslmoa(nxa,nya)
  158. !
  159. character(len=8) :: cform
  160. !
  161. namelist/cplpar/ndbox,ndboy,nprint,nissta,niicea,nipmea,nitaua &
  162. & ,nihfla,nissto,nihflo,nflsst,nfltau,nflice,nflfresh&
  163. & ,nfloheat,ncssta,ncicea,ncpmea,nctaua,nchflo,ncssto&
  164. & ,cfacsst,cfacice,cfactau,cfacfresh,nroffc &
  165. & ,flukofile,runoffmap
  166. !
  167. ! check atm dimensions
  168. !
  169. if(kxa /= nxa .or. kya /= nya) then
  170. write(nud,*)'!ERROR! wrong Plasim dimensions in cplmod'
  171. stop
  172. endif
  173. !
  174. ! read namelist
  175. !
  176. do jt=30,99
  177. ntape=jt
  178. inquire(unit=ntape,opened=lopen)
  179. if(.not. lopen) exit
  180. enddo
  181. open(ntape,file='cpl_namelist',form='formatted')
  182. read(ntape,cplpar)
  183. write(nud,'(/," ****************************************")')
  184. write(nud,'(" * CPLMOD ",a30," *")') trim(version)
  185. write(nud,'(" ******************************************")')
  186. write(nud,'(" * Namelist CPLPAR from <cpl_namelist> *")')
  187. write(nud,'(" ******************************************")')
  188. write(nud,cplpar)
  189. close(ntape)
  190. !
  191. ! initialize coupling method from kcpl (= nlsg in oceanmod)
  192. ! ncoupling=1 (atmospheric sst and oceanic hfl)
  193. ! ncoupling=2 (atmospheric hfl and oceanic sst)
  194. !
  195. ncoupling=kcpl
  196. ngui=kgui
  197. !
  198. ! initialize flux correction
  199. !
  200. nfluko=nflsst+nfltau+nflice+nflfresh+nfloheat
  201. if(nfluko > 0) then
  202. call cflukoini
  203. else
  204. write(nud,*) ' '
  205. write(nud,*) 'No flux correction chosen in CLSGINI'
  206. write(nud,*) ' '
  207. endif
  208. !
  209. ! initialize runoff correction
  210. !
  211. if(nroffc > 1) then
  212. write(chform,'(A1,I6.6,A3)') '(',nxa,'I1)'
  213. open(ntape,file=trim(runoffmap),form='formatted')
  214. read(ntape,chform,end=9000) iroffi(:,:)
  215. if(nroffc == 3) then
  216. read(ntape,*,end=9000)
  217. read(ntape,chform,end=9000) iroffo(:,:)
  218. endif
  219. close(ntape)
  220. endif
  221. !
  222. ! make plasim and lsg grids
  223. !
  224. call cinigrids
  225. !
  226. ! put atm land sea mask to common
  227. !
  228. call cputlsma(pslm,nxa,nya)
  229. !
  230. ! put atm time to common
  231. !
  232. call cputtime(kdatim)
  233. !
  234. ! initialize LSG
  235. !
  236. naomod=kaomod
  237. ndcoup=kaomod/ktspd
  238. call lsgini(ndcoup,ncoupling,ndbox,ndboy)
  239. if(ngui > 0) call do_lsg_visual
  240. !
  241. ! dbug print out
  242. !
  243. if(nprint > 0) then
  244. zgr=180./(2.*asin(1.))
  245. write(nud,*) ' '
  246. write(nud,*) 'End of CLSGINI: '
  247. write(cform,'(A1,I2.2,A3)') '(',nxa,'I1)'
  248. write(nud,*) 'Atmosphere Mask'
  249. write(nud,cform) nint(aslm)
  250. write(cform,'(A1,I2.2,A3)') '(',nxo,'I1)'
  251. write(nud,*) 'Ocean Scalar Mask'
  252. write(nud,cform) nint(oslms)
  253. write(nud,*) 'Ocean Vector MasK'
  254. write(nud,cform) nint(oslmv)
  255. write(nud,*) ' '
  256. call cglm(aslm,zduma,zgs,zgm,zgw,agw,nxa,nya)
  257. write(nud,*) 'Atm. ocean area (sum/mean) + global area : ' &
  258. & ,zgs*radea,zgm,zgw*radea
  259. call cglm(oslms,zdumo,zgs,zgm,zgw,ogw,nxo,nyo)
  260. write(nud,*) 'Oce. ocean area scalar (sum/mean) + global area : ' &
  261. & ,zgs*radea,zgm,zgw*radea
  262. call cglm(oslmv,zdumo,zgs,zgm,zgw,ogw,nxo,nyo)
  263. write(nud,*) 'Oce. ocean area vector (sum/mean) + global area : ' &
  264. & ,zgs*radea,zgm,zgw*radea
  265. !
  266. ! check mask overlaps:
  267. !
  268. write(nud,*) 'Check mask overlaps for area interpolation'
  269. write(nud,*) ' '
  270. call cinter(aslm,zduma,zslmaos,zdumo,agw,ogw,xa1,xa2,xos1,xos2 &
  271. & ,ya1,ya2,yo1,yo2,nxa,nxo,nya,nyo,0,nprint)
  272. kmiss=0
  273. do j=1,nyo
  274. do i=1,nxo
  275. zdumo(i,j)=0.
  276. if(zslmaos(i,j) < 1.E-9 .and. oslms(i,j) > 0.5) then
  277. kmiss=kmiss+1
  278. zdumo(i,j)=1.
  279. endif
  280. enddo
  281. enddo
  282. write(nud,*) kmiss &
  283. & ,' Oce Scalar points must be extrapolated'
  284. if(kmiss > 0) then
  285. write(nud,*) 'These points are:'
  286. do j=1,nyo
  287. do i=1,nxo
  288. if(zdumo(i,j) > 0.5) then
  289. write(nud,*) 'i,j= ',i,j,' Lon,Lat= ',xos(i,j)*zgr,yo(i,j)*zgr
  290. endif
  291. enddo
  292. enddo
  293. write(nud,*) 'Map of missed points'
  294. write(cform,'(A1,I2.2,A3)') '(',nxo,'I1)'
  295. write(nud,cform) nint(zdumo)
  296. endif
  297. zdumo=1.
  298. call cinter(aslm,zduma,zslmaov,zdumo,agw,ogw,xa1,xa2,xov1,xov2 &
  299. & ,ya1,ya2,yo1,yo2,nxa,nxo,nya,nyo,0,nprint)
  300. kmiss=0
  301. do j=1,nyo
  302. do i=1,nxo
  303. zdumo(i,j)=0.
  304. if(zslmaov(i,j) < 1.E-9 .and. oslmv(i,j) > 0.5) then
  305. kmiss=kmiss+1
  306. zdumo(i,j)=1.
  307. endif
  308. enddo
  309. enddo
  310. write(nud,*) kmiss &
  311. & ,' Oce Vector points must be extrapolated:'
  312. if(kmiss > 0) then
  313. write(nud,*) 'These points are:'
  314. do j=1,nyo
  315. do i=1,nxo
  316. if(zdumo(i,j) > 0.5) then
  317. write(nud,*) 'i,j= ',i,j,' Lon,Lat= ',xov(i,j)*zgr,yo(i,j)*zgr
  318. endif
  319. enddo
  320. enddo
  321. write(nud,*) 'Map of missed points'
  322. write(cform,'(A1,I2.2,A3)') '(',nxo,'I1)'
  323. write(nud,cform) nint(zdumo)
  324. endif
  325. zdumo=1.
  326. call cinter(oslms,zdumo,zslmoa,zduma,ogw,agw,xos1,xos2,xa1,xa2 &
  327. & ,yo1,yo2,ya1,ya2,nxo,nxa,nyo,nya,0,nprint)
  328. kmiss=0
  329. do j=1,nya
  330. do i=1,nxa
  331. zduma(i,j)=0.
  332. if(zslmoa(i,j) < 1.E-9 .and. aslm(i,j) > 0.5) then
  333. kmiss=kmiss+1
  334. zduma(i,j)=1.
  335. endif
  336. enddo
  337. enddo
  338. write(nud,*) kmiss &
  339. & ,' Atm points must be extrapolated:'
  340. if(kmiss > 0) then
  341. write(nud,*) 'These points are:'
  342. do j=1,nya
  343. do i=1,nxa
  344. if(zduma(i,j) > 0.5) then
  345. write(nud,*) 'i,j= ',i,j,' Lon,Lat= ',xa(i,j)*zgr,ya(i,j)*zgr
  346. endif
  347. enddo
  348. enddo
  349. write(nud,*) 'Map of missed points'
  350. write(cform,'(A1,I2.2,A3)') '(',nxa,'I1)'
  351. write(nud,cform) nint(zduma)
  352. endif
  353. write(nud,*)
  354. !
  355. ! check mask overlaps for bi-linear interpolation:
  356. !
  357. write(nud,*) 'Check for bi-linear interpolation'
  358. write(nud,*)
  359. zduma=1.
  360. zdumo=1.
  361. call cinter2(aslm,zduma,zslmaos,zdumo,agw,ogw,xa,xos &
  362. & ,ya,yo,nxa,nxo,nya,nyo,0,nprint)
  363. kmiss=0
  364. do j=1,nyo
  365. do i=1,nxo
  366. zdumo(i,j)=0.
  367. if(zslmaos(i,j) < 1.E-9 .and. oslms(i,j) > 0.5) then
  368. kmiss=kmiss+1
  369. zdumo(i,j)=1.
  370. endif
  371. enddo
  372. enddo
  373. write(nud,*) kmiss &
  374. & ,' Oce Scalar points must be extrapolated'
  375. if(kmiss > 0) then
  376. write(nud,*) 'These points are:'
  377. do j=1,nyo
  378. do i=1,nxo
  379. if(zdumo(i,j) > 0.5) then
  380. write(nud,*) 'i,j= ',i,j,' Lon,Lat= ',xos(i,j)*zgr,yo(i,j)*zgr
  381. endif
  382. enddo
  383. enddo
  384. write(nud,*) 'Map of missed points'
  385. write(cform,'(A1,I2.2,A3)') '(',nxo,'I1)'
  386. write(nud,cform) nint(zdumo)
  387. endif
  388. zdumo=1.
  389. call cinter2(aslm,zduma,zslmaov,zdumo,agw,ogw,xa,xov &
  390. & ,ya,yo,nxa,nxo,nya,nyo,0,nprint)
  391. kmiss=0
  392. do j=1,nyo
  393. do i=1,nxo
  394. zdumo(i,j)=0.
  395. if(zslmaov(i,j) < 1.E-9 .and. oslmv(i,j) > 0.5) then
  396. kmiss=kmiss+1
  397. zdumo(i,j)=1.
  398. endif
  399. enddo
  400. enddo
  401. write(nud,*) kmiss &
  402. & ,' Oce Vector points must be extrapolated:'
  403. if(kmiss > 0) then
  404. write(nud,*) 'These points are:'
  405. do j=1,nyo
  406. do i=1,nxo
  407. if(zdumo(i,j) > 0.5) then
  408. write(nud,*) 'i,j= ',i,j,' Lon,Lat= ',xov(i,j)*zgr,yo(i,j)*zgr
  409. endif
  410. enddo
  411. enddo
  412. write(nud,*) 'Map of missed points'
  413. write(cform,'(A1,I2.2,A3)') '(',nxo,'I1)'
  414. write(nud,cform) nint(zdumo)
  415. endif
  416. zdumo=1.
  417. call cinter2(oslms,zdumo,zslmoa,zduma,ogw,agw,xos,xa &
  418. & ,yo,ya,nxo,nxa,nyo,nya,0,nprint)
  419. kmiss=0
  420. do j=1,nya
  421. do i=1,nxa
  422. zduma(i,j)=0.
  423. if(zslmoa(i,j) < 1.E-9 .and. aslm(i,j) > 0.5) then
  424. kmiss=kmiss+1
  425. zduma(i,j)=1.
  426. endif
  427. enddo
  428. enddo
  429. write(nud,*) kmiss &
  430. & ,' Atm points must be extrapolated:'
  431. if(kmiss > 0) then
  432. write(nud,*) 'These points are:'
  433. do j=1,nya
  434. do i=1,nxa
  435. if(zduma(i,j) > 0.5) then
  436. write(nud,*) 'i,j= ',i,j,' Lon,Lat= ',xa(i,j)*zgr,ya(i,j)*zgr
  437. endif
  438. enddo
  439. enddo
  440. write(nud,*) 'Map of missed points'
  441. write(cform,'(A1,I2.2,A3)') '(',nxa,'I1)'
  442. write(nud,cform) nint(zduma)
  443. endif
  444. write(nud,*)
  445. endif
  446. !
  447. return
  448. !
  449. 9000 continue
  450. write(nud,*) 'ERROR: nroffc set to ',nroffc,' but file ' &
  451. & ,trim(runoffmap) &
  452. & ,'not correctly given!'
  453. stop
  454. !
  455. end subroutine clsgini
  456. !
  457. ! ===================
  458. ! subroutine CLSGSTEP
  459. ! ===================
  460. !
  461. subroutine clsgstep(kdatim,kstep,psst,ptaux,ptauy,ppme,proff,pice &
  462. & ,pheat,pfldo)
  463. use cplmod
  464. !
  465. real :: psst(nxa,nya) ! atm sst (input)
  466. real :: ptaux(nxa,nya) ! atm u-stress (input)
  467. real :: ptauy(nxa,nya) ! atm v-stress (input)
  468. real :: ppme(nxa,nya) ! atm p-e (input)
  469. real :: proff(nxa,nya) ! atm runoff (input)
  470. real :: pice(nxa,nya) ! atm ice thickness (incl. snow) (input)
  471. real :: pheat(nxa,nya) ! atm heat flux (input; not used yet)
  472. real :: pfldo(nxa,nya) ! atm deep ocan heat flux (output)
  473. !
  474. real :: zfresh(nxa,nya) ! atm fresh water flux (p-e+runoff)
  475. !
  476. integer :: kdatim(7) ! date and time
  477. integer :: kstep ! current atm time step
  478. !
  479. ! put all atm input to common (+ accumulate)
  480. !
  481. if(nroffc > 0) call croffc(proff)
  482. !
  483. zfresh(:,:)=ppme(:,:)+proff(:,:)
  484. call cputtime(kdatim)
  485. call cputtaua(ptaux,ptauy)
  486. call cputpmea(zfresh)
  487. if(ncoupling == 2) call cputhfla(pheat)
  488. !
  489. ! run lsg if its time
  490. !
  491. if (mod(kstep,naomod) == naomod-1) then
  492. !
  493. if(nprint > 0) then
  494. write(nud,*) 'in cpl: make lsg step'
  495. endif
  496. !
  497. if(ncoupling == 1) then
  498. call cputssta(psst)
  499. endif
  500. call cputicea(pice)
  501. call lsgstep
  502. if(ngui > 0) call do_lsg_visual
  503. !
  504. ! get the new deep ocean heat flux
  505. !
  506. if(ncoupling == 1) then
  507. call cgethfla(pfldo)
  508. elseif(ncoupling == 2) then
  509. call cgetssta(psst)
  510. endif
  511. endif
  512. !
  513. return
  514. end subroutine clsgstep
  515. !
  516. ! ===================
  517. ! subroutine CLSGSTOP
  518. ! ===================
  519. !
  520. subroutine clsgstop
  521. use cplmod
  522. !
  523. ! finalize lsg
  524. !
  525. call lsgstop
  526. !
  527. return
  528. end subroutine clsgstop
  529. !
  530. ! ====================
  531. ! subroutine CINIGRIDS
  532. ! ====================
  533. !
  534. subroutine cinigrids
  535. use cplmod
  536. !
  537. real (kind=8) :: zsi(nya),zgw(nya)
  538. !
  539. zpi=2.*asin(1.)
  540. !
  541. ! atmospheric grid
  542. !
  543. call inigau(nya,zsi,zgw)
  544. zdxa=2.*zpi/real(nxa)
  545. do i=1,nxa
  546. do j=1,nya
  547. xa(i,j)=zdxa*(i-1)
  548. ya(i,j)=asin(zsi(j))
  549. enddo
  550. enddo
  551. do i=2,nxa
  552. xa1(i,:)=0.5*(xa(i,:)+xa(i-1,:))
  553. enddo
  554. xa1(1,:)=xa1(2,:)-zdxa
  555. do i=1,nxa-1
  556. xa2(i,:)=0.5*(xa(i,:)+xa(i+1,:))
  557. enddo
  558. xa2(nxa,:)=xa2(nxa-1,:)+zdxa
  559. zgw(:)=2.*zgw(:)/sum(zgw(:))
  560. zsinm=sin(zpi*0.5)
  561. ya1(:,1)=asin(zsinm)
  562. do j=2,nya
  563. zsin=zsinm-zgw(j-1)
  564. ya1(:,j)=asin(zsin)
  565. ya2(:,j-1)=asin(zsin)
  566. zsinm=zsin
  567. enddo
  568. ya2(:,nya)=-zpi*0.5
  569. !
  570. ! oceanic grid
  571. !
  572. call cmklonlate(xos,yo,nxo,nyo)
  573. xov(:,:)=xos(:,:)+zpi/real(nxo)
  574. where(xos(:,:) < 0.) xos(:,:)=xos(:,:)+2.*zpi
  575. where(xov(:,:) < 0.) xov(:,:)=xov(:,:)+2.*zpi
  576. zdxo=2.*zpi/real(nxo)
  577. xos1(:,:)=xos(:,:)-0.5*zdxo
  578. xos2(:,:)=xos(:,:)+0.5*zdxo
  579. xov1(:,:)=xov(:,:)-0.5*zdxo
  580. xov2(:,:)=xov(:,:)+0.5*zdxo
  581. zdyo=zpi/real(nyo)
  582. yo1(:,:)=yo(:,:)-zdyo*0.5
  583. yo2(:,:)=yo(:,:)+zdyo*0.5
  584. !
  585. ! weights
  586. !
  587. do j=1,nya
  588. do i=1,nxa
  589. agw(i,j)=zdxa*abs(sin(ya1(i,j))-sin(ya2(i,j)))
  590. enddo
  591. enddo
  592. do j=1,nxo
  593. do i=1,nyo
  594. ogw(i,j)=zdxo*abs(sin(yo1(i,j))-sin(yo2(i,j)))
  595. enddo
  596. enddo
  597. !
  598. return
  599. end
  600. !
  601. ! =====================
  602. ! subroutine CMKLONLATE
  603. ! =====================
  604. !
  605. subroutine cmklonlate(x,y,nlon,nlat)
  606. parameter(radea=6.371E6)
  607. real :: x(nlon,nlat)
  608. real :: y(nlon,nlat)
  609. real :: rlat(nlat)
  610. !
  611. delta=360./real(nlon)
  612. !
  613. pi=2.*asin(1.)
  614. !
  615. ! lon und lat berechnen(umrechnung vom E Gitter in geog. koord.)
  616. !
  617. do j=1,nlat
  618. y(:,j)=90./real(nlat)-180.*real(j-nlat/2)/real(nlat)
  619. enddo
  620. !
  621. rlonlimit=180.-delta/100. ! lower the limit for lon with respect to delta
  622. do j=1,nlat
  623. do i=1,nlon
  624. x(i,j)=(((i-(j/2.))/(nlon/2.))*180.)-delta
  625. !
  626. ! lonlimit zur Vermeidung von Fehlern durch Ungenauigkeiten
  627. !
  628. if(x(i,j).gt.rlonlimit) x(i,j)=-(360.-x(i,j))
  629. if(x(i,j).lt.-rlonlimit) x(i,j)=-x(i,j)
  630. enddo
  631. enddo
  632. x(:,:)=x(:,:)*pi/180.
  633. y(:,:)=y(:,:)*pi/180.
  634. !
  635. return
  636. end
  637. !
  638. ! ===================
  639. ! subroutine CPUTTIME
  640. ! ===================
  641. !
  642. subroutine cputtime(kdatim)
  643. use cplmod
  644. !
  645. ! put time to common
  646. !
  647. integer :: kdatim(7)
  648. !
  649. ndatim(:)=kdatim(:)
  650. nyear=ndatim(1)
  651. nmonth=ndatim(2)
  652. nday=ndatim(3)
  653. nhour=ndatim(4)
  654. nmin=ndatim(5)
  655. nwday=ndatim(6)
  656. !
  657. return
  658. end
  659. !
  660. ! ===================
  661. ! subroutine CGETTIME
  662. ! ===================
  663. !
  664. subroutine cgettime(kdatim)
  665. use cplmod
  666. !
  667. ! get time from common
  668. !
  669. integer :: kdatim(7)
  670. !
  671. kdatim(:)=ndatim(:)
  672. !
  673. if(nprint > 0) then
  674. write(nud,*) ' '
  675. write(nud,*) 'In CGETTIME, datim= ',ndatim(:)
  676. write(nud,*) ' '
  677. endif
  678. !
  679. return
  680. end
  681. !
  682. ! ===================
  683. ! subroutine CPUTLSMA
  684. ! ===================
  685. !
  686. subroutine cputlsma(plsm,kx,ky)
  687. use cplmod
  688. !
  689. ! put atm land see mask to common
  690. !
  691. real :: plsm(nxa,nya) ! land see mask (input)
  692. !
  693. ! check dimensions
  694. !
  695. if(nxa /= kx .or. nya /= ky) then
  696. write(nud,*) '!ERROR! inconsistent atm. dimensions in cpl'
  697. stop
  698. endif
  699. !
  700. ! copy land see mask and convert 0/1 to 1/0
  701. !
  702. aslm(:,:)=real(nint(1.-plsm(:,:)))
  703. !
  704. return
  705. end
  706. !
  707. ! ===================
  708. ! subroutine CPUTLSMO
  709. ! ===================
  710. !
  711. subroutine cputlsmo(plsms,plsmv,kx,ky)
  712. use cplmod
  713. !
  714. ! put oce land see mask to common
  715. !
  716. real :: plsms(nxo,nyot) ! land see mask scalar (input)
  717. real :: plsmv(nxo,nyot) ! land see mask vector (input)
  718. !
  719. ! check dimensions
  720. !
  721. if(nxo /= kx .or. nyot /= ky) then
  722. write(nud,*) '!ERROR! inconsistent oce. dimensions in cpl'
  723. stop
  724. endif
  725. !
  726. ! copy land see mask and convert 0/1 to 1/0
  727. !
  728. oslms(1:nxo,1:nyo)=real(nint(plsms(1:nxo,3:nyot-2)))
  729. oslmv(1:nxo,1:nyo)=real(nint(plsmv(1:nxo,3:nyot-2)))
  730. !
  731. return
  732. end
  733. !
  734. ! ===================
  735. ! subroutine CPUTSSTA
  736. ! ===================
  737. !
  738. subroutine cputssta(psst)
  739. use cplmod
  740. !
  741. ! put atm sst to common (accumulated)
  742. !
  743. real :: psst(nxa,nya) ! sst (input)
  744. !
  745. ! accumulate
  746. !
  747. assta(:,:)=assta(:,:)+psst(:,:)
  748. nssta=nssta+1
  749. !
  750. return
  751. end
  752. !
  753. ! ===================
  754. ! subroutine CPUTICEA
  755. ! ===================
  756. !
  757. subroutine cputicea(piced)
  758. use cplmod
  759. !
  760. ! put atm ice to common (accumulated)
  761. !
  762. real :: piced(nxa,nya) ! ice thickness (input)
  763. !
  764. ! accumulate
  765. !
  766. aiceda(:,:)=aiceda(:,:)+piced(:,:)
  767. nicea=nicea+1
  768. !
  769. return
  770. end
  771. !
  772. ! ===================
  773. ! subroutine CPUTPMEA
  774. ! ===================
  775. !
  776. subroutine cputpmea(ppme)
  777. use cplmod
  778. !
  779. ! put atm fresh water flux to common (accumulated)
  780. !
  781. real :: ppme(nxa,nya) ! fresh water flux (input)
  782. !
  783. ! accumulate
  784. !
  785. apmea(:,:)=apmea(:,:)+ppme(:,:)
  786. npmea=npmea+1
  787. !
  788. return
  789. end
  790. !
  791. ! ===================
  792. ! subroutine CPUTTAUA
  793. ! ===================
  794. !
  795. subroutine cputtaua(ptaux,ptauy)
  796. use cplmod
  797. !
  798. ! put atm wind stress to common (accumulated)
  799. !
  800. real :: ptaux(nxa,nya) ! u-stress (input)
  801. real :: ptauy(nxa,nya) ! v-stress (input)
  802. !
  803. ! accumulate
  804. !
  805. atauxa(:,:)=atauxa(:,:)+ptaux(:,:)
  806. atauya(:,:)=atauya(:,:)+ptauy(:,:)
  807. ntaua=ntaua+1
  808. !
  809. return
  810. end
  811. !
  812. ! ===================
  813. ! subroutine CPUTHFLA
  814. ! ===================
  815. !
  816. subroutine cputhfla(phfl)
  817. use cplmod
  818. !
  819. ! put atm heat flux to common (accumulated)
  820. !
  821. real :: phfl(nxa,nya) ! heat flux (input)
  822. !
  823. ! accumulate
  824. !
  825. ahfla(:,:)=ahfla(:,:)+phfl(:,:)
  826. nhfla=nhfla+1
  827. !
  828. return
  829. end
  830. !
  831. ! ===================
  832. ! subroutine CPUTHFLO
  833. ! ===================
  834. !
  835. subroutine cputhflo(phfl)
  836. use cplmod
  837. !
  838. ! put oce heat flux to common (accumulated)
  839. !
  840. real :: phfl(nxo,nyot) ! heat flux (input)
  841. !
  842. ! accumulate
  843. !
  844. ohfla(:,:)=ohfla(:,:)+phfl(1:nxo,3:nyot-2)
  845. nhflo=nhflo+1
  846. !
  847. return
  848. end
  849. !
  850. ! ===================
  851. ! subroutine CPUTSSTO
  852. ! ===================
  853. !
  854. subroutine cputssto(psst)
  855. use cplmod
  856. !
  857. ! put oce sst to common (accumulated)
  858. !
  859. real :: psst(nxo,nyot) ! heat flux (input)
  860. !
  861. ! accumulate
  862. !
  863. ossta(:,:)=ossta(:,:)+psst(1:nxo,3:nyot-2)
  864. nssto=nssto+1
  865. !
  866. return
  867. end
  868. !
  869. ! ===================
  870. ! subroutine CGETSSTO
  871. ! ===================
  872. !
  873. subroutine cgetssto(psst)
  874. use cplmod
  875. parameter(rkelvin=273.16)
  876. !
  877. ! get interpolated sst from common
  878. !
  879. real :: psst(nxo,nyot) ! sst (output)
  880. !
  881. ! get accumulated atm sst
  882. !
  883. if(nssta == 0) then
  884. write(nud,*) '!ERROR! no accumulated atm sst found'
  885. stop
  886. endif
  887. asst(:,:)=assta(:,:)/real(nssta)
  888. !
  889. ! interpolate
  890. !
  891. if(nissta== 1) then
  892. call cinter(asst,aslm,osst,oslms,agw,ogw,xa1,xa2,xos1,xos2 &
  893. & ,ya1,ya2,yo1,yo2,nxa,nxo,nya,nyo,ncssta,nprint)
  894. else
  895. call cinter2(asst,aslm,osst,oslms,agw,ogw,xa,xos &
  896. & ,ya,yo,nxa,nxo,nya,nyo,ncssta,nprint)
  897. endif
  898. !
  899. ! copy to output (convert into C)
  900. !
  901. psst(1:nxo,3:nyot-2)=osst(:,:)-rkelvin
  902. !
  903. ! dbug printout
  904. !
  905. if(nprint > 0) then
  906. write(nud,*) ' '
  907. write(nud,*) 'In CGETSSTO: '
  908. write(nud,*) 'sst from ',nssta,' accumulated values'
  909. call cglm(asst,aslm,zgs,zgm,zgw,agw,nxa,nya)
  910. write(nud,*) 'Atm (sum,mean,max,min): ' &
  911. & ,zgs,zgm,MAXVAL(asst,MASK=(aslm > 0.5)) &
  912. & ,MINVAL(asst,MASK=(aslm > 0.5))
  913. call cglm(osst,oslms,zgs,zgm,zgw,ogw,nxo,nyo)
  914. write(nud,*) 'Oce (sum,mean,max,min): ' &
  915. & ,zgs,zgm,MAXVAL(osst,MASK=(oslms > 0.5)) &
  916. & ,MINVAL(osst,MASK=(oslms > 0.5))
  917. write(nud,*) ' '
  918. endif
  919. !
  920. ! reset accumulated field
  921. !
  922. assta(:,:)=0.
  923. nssta=0
  924. !
  925. return
  926. end
  927. !
  928. ! ===================
  929. ! subroutine CGETICEO
  930. ! ===================
  931. !
  932. subroutine cgeticeo(piced)
  933. use cplmod
  934. parameter(rhoi=1000.)
  935. parameter(rho0=1030.)
  936. real :: zpiced(nxo,nyot-4)
  937. !
  938. ! get interpolated ice from common
  939. !
  940. real :: piced(nxo,nyot) ! ice thickness (output)
  941. !
  942. ! get accumulated atm ice
  943. !
  944. if(nicea == 0) then
  945. write(nud,*) '!ERROR! no accumulated atm ice found'
  946. stop
  947. endif
  948. aiced(:,:)=aiceda(:,:)/real(nicea)
  949. !
  950. ! interpolate
  951. !
  952. if(niicea == 1) then
  953. call cinter(aiced,aslm,oiced,oslms,agw,ogw,xa1,xa2,xos1,xos2 &
  954. & ,ya1,ya2,yo1,yo2,nxa,nxo,nya,nyo,ncicea,nprint)
  955. else
  956. call cinter2(aiced,aslm,oiced,oslms,agw,ogw,xa,xos &
  957. & ,ya,yo,nxa,nxo,nya,nyo,ncicea,nprint)
  958. endif
  959. !
  960. ! copy to output
  961. !
  962. piced(1:nxo,3:nyot-2)=oiced(:,:)*rhoi/rho0
  963. !
  964. ! dbug printout
  965. !
  966. if(nprint > 0) then
  967. write(nud,*) ' '
  968. write(nud,*) 'In CGETICEO: '
  969. write(nud,*) 'ice from ',nicea,' accumulated values'
  970. call cglm(aiced,aslm,zgs,zgm,zgw,agw,nxa,nya)
  971. write(nud,*) 'Atm (sum,mean,max,min): ' &
  972. & ,zgs,zgm,MAXVAL(aiced,MASK=(aslm > 0.5)) &
  973. & ,MINVAL(aiced,MASK=(aslm > 0.5))
  974. call cglm(oiced,oslms,zgs,zgm,zgw,ogw,nxo,nyo)
  975. write(nud,*) 'Oce uncorrected (sum,mean,max,min): ' &
  976. & ,zgs,zgm,MAXVAL(oiced,MASK=(oslms > 0.5)) &
  977. & ,MINVAL(oiced,MASK=(oslms > 0.5))
  978. zpiced(:,:) = piced(:,3:nyot-2)
  979. call cglm(zpiced,oslms,zgs,zgm,zgw,ogw,nxo,nyo)
  980. write(nud,*) 'Oce corrected (sum,mean,max,min): ' &
  981. & ,zgs,zgm,MAXVAL(zpiced(:,:),MASK=(oslms > 0.5)) &
  982. & ,MINVAL(zpiced(:,:),MASK=(oslms > 0.5))
  983. write(nud,*) ' '
  984. endif
  985. !
  986. ! reset accumulated field
  987. !
  988. aiceda(:,:)=0.
  989. nicea=0
  990. !
  991. return
  992. end
  993. !
  994. ! ===================
  995. ! subroutine CGETPMEO
  996. ! ===================
  997. !
  998. subroutine cgetpmeo(ppme)
  999. use cplmod
  1000. parameter(rhop=1000.)
  1001. parameter(rho0=1030.)
  1002. !
  1003. ! get interpolated pme from common
  1004. !
  1005. real :: ppme(nxo,nyot) ! pme (output)
  1006. !
  1007. ! get accumulated atm pme
  1008. !
  1009. if(npmea == 0) then
  1010. write(nud,*) '!ERROR! no accumulated atm pme found'
  1011. stop
  1012. endif
  1013. apme(:,:)=apmea(:,:)/real(npmea)
  1014. !
  1015. ! interpolate
  1016. !
  1017. if(nipmea == 1) then
  1018. call cinter(apme,aslm,opme,oslms,agw,ogw,xa1,xa2,xos1,xos2 &
  1019. & ,ya1,ya2,yo1,yo2,nxa,nxo,nya,nyo,ncpmea,nprint)
  1020. else
  1021. call cinter2(apme,aslm,opme,oslms,agw,ogw,xa,xos &
  1022. & ,ya,yo,nxa,nxo,nya,nyo,ncpmea,nprint)
  1023. endif
  1024. !
  1025. ! copy to output and correct for density differences
  1026. !
  1027. ppme(1:nxo,3:nyot-2)=opme(:,:)*rhop/rho0
  1028. !
  1029. ! dbug printout
  1030. !
  1031. if(nprint > 0) then
  1032. write(nud,*) ' '
  1033. write(nud,*) 'In CGETPMEO: '
  1034. write(nud,*) 'pme from ',npmea,' accumulated values'
  1035. call cglm(apme,aslm,zgs,zgm,zgw,agw,nxa,nya)
  1036. write(nud,*) 'Atm (sum,mean,max,min): ' &
  1037. & ,zgs,zgm,MAXVAL(apme,MASK=(aslm > 0.5)) &
  1038. & ,MINVAL(apme,MASK=(aslm > 0.5))
  1039. call cglm(opme,oslms,zgs,zgm,zgw,ogw,nxo,nyo)
  1040. write(nud,*) 'Oce (sum,mean,max,min): ' &
  1041. & ,zgs,zgm,MAXVAL(opme,MASK=(oslms > 0.5)) &
  1042. & ,MINVAL(opme,MASK=(oslms > 0.5))
  1043. write(nud,*) ' '
  1044. endif
  1045. !
  1046. ! reset accumulated field
  1047. !
  1048. apmea(:,:)=0.
  1049. npmea=0
  1050. !
  1051. return
  1052. end
  1053. !
  1054. ! ===================
  1055. ! subroutine CGETTAUO
  1056. ! ===================
  1057. !
  1058. subroutine cgettauo(ptaux,ptauy)
  1059. use cplmod
  1060. !
  1061. ! get interpolated stress from common
  1062. !
  1063. real :: ptaux(nxo,nyot) ! u-stress (output)
  1064. real :: ptauy(nxo,nyot) ! v-stress (output)
  1065. !
  1066. ! get accumulated atm stress
  1067. !
  1068. if(ntaua == 0) then
  1069. write(nud,*) '!ERROR! no accumulated atm stress found'
  1070. stop
  1071. endif
  1072. ataux(:,:)=atauxa(:,:)/real(ntaua)
  1073. atauy(:,:)=atauya(:,:)/real(ntaua)
  1074. !
  1075. ! interpolate
  1076. !
  1077. if(nitaua == 1) then
  1078. call cinter(ataux,aslm,otaux,oslmv,agw,ogw,xa1,xa2,xov1,xov2 &
  1079. & ,ya1,ya2,yo1,yo2,nxa,nxo,nya,nyo,nctaua,nprint)
  1080. call cinter(atauy,aslm,otauy,oslmv,agw,ogw,xa1,xa2,xov1,xov2 &
  1081. & ,ya1,ya2,yo1,yo2,nxa,nxo,nya,nyo,nctaua,nprint)
  1082. else
  1083. call cinter2(ataux,aslm,otaux,oslmv,agw,ogw,xa,xov &
  1084. & ,ya,yo,nxa,nxo,nya,nyo,nctaua,nprint)
  1085. call cinter2(atauy,aslm,otauy,oslmv,agw,ogw,xa,xov &
  1086. & ,ya,yo,nxa,nxo,nya,nyo,nctaua,nprint)
  1087. endif
  1088. !
  1089. ! copy to output
  1090. !
  1091. ptaux(1:nxo,3:nyot-2)=otaux(:,:)
  1092. ptauy(1:nxo,3:nyot-2)=otauy(:,:)
  1093. !
  1094. ! dbug printout
  1095. !
  1096. if(nprint > 0) then
  1097. write(nud,*) ' '
  1098. write(nud,*) 'In CGETTAUO: '
  1099. write(nud,*) 'stress from ',ntaua,' accumulated values'
  1100. call cglm(ataux,aslm,zgs,zgm,zgw,agw,nxa,nya)
  1101. write(nud,*) 'Atm u (sum,mean,max,min): ' &
  1102. & ,zgs,zgm,MAXVAL(ataux,MASK=(aslm > 0.5)) &
  1103. & ,MINVAL(ataux,MASK=(aslm > 0.5))
  1104. call cglm(atauy,aslm,zgs,zgm,zgw,agw,nxa,nya)
  1105. write(nud,*) 'Atm v (sum,mean,max,min): ' &
  1106. & ,zgs,zgm,MAXVAL(atauy,MASK=(aslm > 0.5)) &
  1107. & ,MINVAL(atauy,MASK=(aslm > 0.5))
  1108. call cglm(otaux,oslmv,zgs,zgm,zgw,ogw,nxo,nyo)
  1109. write(nud,*) 'Oce u (sum,mean,max,min): ' &
  1110. & ,zgs,zgm,MAXVAL(otaux,MASK=(oslmv > 0.5)) &
  1111. & ,MINVAL(otaux,MASK=(oslmv > 0.5))
  1112. call cglm(otauy,oslmv,zgs,zgm,zgw,ogw,nxo,nyo)
  1113. write(nud,*) 'Oce v (sum,mean,max,min): ' &
  1114. & ,zgs,zgm,MAXVAL(otauy,MASK=(oslmv > 0.5)) &
  1115. & ,MINVAL(otauy,MASK=(oslmv > 0.5))
  1116. write(nud,*) ' '
  1117. endif
  1118. !
  1119. ! reset accumulated field
  1120. !
  1121. atauxa(:,:)=0.
  1122. atauya(:,:)=0.
  1123. ntaua=0
  1124. !
  1125. return
  1126. end
  1127. !
  1128. ! ===================
  1129. ! subroutine CGETHFLO
  1130. ! ===================
  1131. !
  1132. subroutine cgethflo(phfl)
  1133. use cplmod
  1134. !
  1135. ! get interpolated atm hfl from common
  1136. !
  1137. real :: phfl(nxo,nyot) ! hfl (output)
  1138. !
  1139. ! get accumulated atm hfl
  1140. !
  1141. if(nhfla == 0) then
  1142. write(nud,*) '!ERROR! no accumulated atm hfl found'
  1143. stop
  1144. endif
  1145. ahfl(:,:)=ahfla(:,:)/real(nhfla)
  1146. !
  1147. ! interpolate
  1148. !
  1149. if(nihfla == 1) then
  1150. call cinter(ahfl,aslm,ohfl,oslms,agw,ogw,xa1,xa2,xos1,xos2 &
  1151. & ,ya1,ya2,yo1,yo2,nxa,nxo,nya,nyo,nchfla,nprint)
  1152. else
  1153. call cinter2(ahfl,aslm,ohfl,oslms,agw,ogw,xa,xos &
  1154. & ,ya,yo,nxa,nxo,nya,nyo,nchfla,nprint)
  1155. endif
  1156. !
  1157. ! copy to output
  1158. !
  1159. phfl(1:nxo,3:nyot-2)=ohfl(:,:)
  1160. !
  1161. ! dbug printout
  1162. !
  1163. if(nprint > 0) then
  1164. write(nud,*) ' '
  1165. write(nud,*) 'In CGETHFLO: '
  1166. write(nud,*) 'hfl from ',nhfla,' accumulated values'
  1167. call cglm(ahfl,aslm,zgs,zgm,zgw,agw,nxa,nya)
  1168. write(nud,*) 'Atm (sum,mean,max,min): ' &
  1169. & ,zgs,zgm,MAXVAL(ahfl,MASK=(aslm > 0.5)) &
  1170. & ,MINVAL(ahfl,MASK=(aslm > 0.5))
  1171. call cglm(ohfl,oslms,zgs,zgm,zgw,ogw,nxo,nyo)
  1172. write(nud,*) 'Oce (sum,mean,max,min): ' &
  1173. & ,zgs,zgm,MAXVAL(ohfl,MASK=(oslms > 0.5)) &
  1174. & ,MINVAL(ohfl,MASK=(oslms > 0.5))
  1175. write(nud,*) ' '
  1176. endif
  1177. !
  1178. ! reset accumulated field
  1179. !
  1180. ahfla(:,:)=0.
  1181. nhfla=0
  1182. !
  1183. return
  1184. end
  1185. !
  1186. ! ===================
  1187. ! subroutine CGETHFLA
  1188. ! ===================
  1189. !
  1190. subroutine cgethfla(phfl)
  1191. use cplmod
  1192. !
  1193. ! get interpolated oce hfl from common
  1194. !
  1195. real :: phfl(nxa,nya) ! hfl (output)
  1196. !
  1197. ! get accumulated oce hfl
  1198. !
  1199. if(nhflo == 0) then
  1200. write(nud,*) '!ERROR! no accumulated oce hfl found'
  1201. stop
  1202. endif
  1203. ohfl(:,:)=ohfla(:,:)/real(nhflo)
  1204. !
  1205. ! interpolate
  1206. !
  1207. if(nihflo == 1) then
  1208. call cinter(ohfl,oslms,ahfl,aslm,ogw,agw,xos1,xos2,xa1,xa2 &
  1209. & ,yo1,yo2,ya1,ya2,nxo,nxa,nyo,nya,nchflo,nprint)
  1210. else
  1211. call cinter2(ohfl,oslms,ahfl,aslm,ogw,agw,xos,xa &
  1212. & ,yo,ya,nxo,nxa,nyo,nya,nchflo,nprint)
  1213. endif
  1214. !
  1215. ! copy to output
  1216. !
  1217. phfl(:,:)=ahfl(:,:)
  1218. !
  1219. ! dbug printout
  1220. !
  1221. if(nprint > 0) then
  1222. write(nud,*) ' '
  1223. write(nud,*) 'In CGETHFLA: '
  1224. write(nud,*) 'hfl from ',nhflo,' accumulated values'
  1225. call cglm(ohfl,oslms,zgs,zgm,zgw,ogw,nxo,nyo)
  1226. write(nud,*) 'Oce (sum,mean,max,min): ' &
  1227. & ,zgs,zgm,MAXVAL(ohfl,MASK=(oslms > 0.5)) &
  1228. & ,MINVAL(ohfl,MASK=(oslms > 0.5))
  1229. call cglm(ahfl,aslm,zgs,zgm,zgw,agw,nxa,nya)
  1230. write(nud,*) 'Atm (sum,mean,max,min): ' &
  1231. & ,zgs,zgm,MAXVAL(ahfl,MASK=(aslm > 0.5)) &
  1232. & ,MINVAL(ahfl,MASK=(aslm > 0.5))
  1233. write(nud,*) ' '
  1234. endif
  1235. !
  1236. ! reset accumulated field
  1237. !
  1238. ohfla(:,:)=0.
  1239. nhflo=0
  1240. !
  1241. return
  1242. end
  1243. !
  1244. ! ===================
  1245. ! subroutine CGETSSTA
  1246. ! ===================
  1247. !
  1248. subroutine cgetssta(psst)
  1249. use cplmod
  1250. parameter(tfreeze=271.25)
  1251. parameter(rkelvin=273.16)
  1252. !
  1253. ! get interpolated oce sst from common
  1254. !
  1255. real :: psst(nxa,nya) ! sst (output)
  1256. !
  1257. ! get accumulated oce sst
  1258. !
  1259. if(nssto == 0) then
  1260. write(nud,*) '!ERROR! no accumulated oce sst found'
  1261. stop
  1262. endif
  1263. osst(:,:)=ossta(:,:)/real(nssto)+rkelvin
  1264. !
  1265. ! interpolate
  1266. !
  1267. if (nissto == 1) then
  1268. call cinter(osst,oslms,asst,aslm,ogw,agw,xos1,xos2,xa1,xa2 &
  1269. & ,yo1,yo2,ya1,ya2,nxo,nxa,nyo,nya,ncssto,nprint)
  1270. else
  1271. call cinter2(osst,oslms,asst,aslm,ogw,agw,xos,xa &
  1272. & ,yo,ya,nxo,nxa,nyo,nya,ncssto,nprint)
  1273. endif
  1274. !
  1275. ! copy to output
  1276. !
  1277. psst(:,:)=asst(:,:)
  1278. !
  1279. ! dbug printout
  1280. !
  1281. if(nprint > 0) then
  1282. write(nud,*) ' '
  1283. write(nud,*) 'In CGETSSTA: '
  1284. write(nud,*) 'sst from ',nssto,' accumulated values'
  1285. call cglm(osst,oslms,zgs,zgm,zgw,ogw,nxo,nyo)
  1286. write(nud,*) 'Oce (sum,mean,max,min): ' &
  1287. & ,zgs,zgm,MAXVAL(osst,MASK=(oslms > 0.5)) &
  1288. & ,MINVAL(osst,MASK=(oslms > 0.5))
  1289. call cglm(asst,aslm,zgs,zgm,zgw,agw,nxa,nya)
  1290. write(nud,*) 'Atm (sum,mean,max,min): ' &
  1291. & ,zgs,zgm,MAXVAL(asst,MASK=(aslm > 0.5)) &
  1292. & ,MINVAL(asst,MASK=(aslm > 0.5))
  1293. write(nud,*) ' '
  1294. endif
  1295. !
  1296. ! reset accumulated field
  1297. !
  1298. ossta(:,:)=0.
  1299. nssto=0
  1300. !
  1301. return
  1302. end
  1303. !
  1304. ! =================
  1305. ! subroutine CINTER
  1306. ! =================
  1307. !
  1308. subroutine cinter(pfi,pslmi,pfo,pslmo,pgwi,pgwo,pxi1,pxi2,pxo1 &
  1309. & ,pxo2,pyi1,pyi2,pyo1,pyo2,nxi,nxo,nyi,nyo,nc,npr)
  1310. !
  1311. parameter(zerr=-9.E09)
  1312. !
  1313. real :: fi(nxi,nyi) ! input field
  1314. real :: slmi(nxi,nyi) ! input mask (0/1)
  1315. real :: fo(nxo,nyo) ! output field
  1316. real :: slmo(nxo,nyo) ! output mask (0/1)
  1317. real :: xi1(nxi,nyi) ! left x's for input
  1318. real :: xi2(nxi,nyi) ! right x's for input
  1319. real :: xo1(nxo,nyo) ! left x's for output
  1320. real :: xo2(nxo,nyo) ! right x's for output
  1321. real :: yi1(nxi,nyi) ! southern y's for input
  1322. real :: yi2(nxi,nyi) ! northern y's for input
  1323. real :: yo1(nxo,nyo) ! southern y's for output
  1324. real :: yo2(nxo,nyo) ! northern y's for output
  1325. !
  1326. real :: pfi(nxi,nyi)
  1327. real :: pslmi(nxi,nyi)
  1328. real :: pfo(nxo,nyo)
  1329. real :: pslmo(nxo,nyo)
  1330. real :: pxi1(nxi,nyi)
  1331. real :: pxi2(nxi,nyi)
  1332. real :: pxo1(nxo,nyo)
  1333. real :: pxo2(nxo,nyo)
  1334. real :: pyi1(nxi,nyi)
  1335. real :: pyi2(nxi,nyi)
  1336. real :: pyo1(nxo,nyo)
  1337. real :: pyo2(nxo,nyo)
  1338. real :: pgwi(nxi,nyi)
  1339. real :: pgwo(nxo,nyo)
  1340. !
  1341. pi=2.*asin(1.)
  1342. !
  1343. fi(:,:)=pfi(:,:)
  1344. slmi(:,:)=pslmi(:,:)
  1345. if(pyi1(1,1) < pyi2(1,1)) then
  1346. yi1(:,:)=pyi1(:,:)
  1347. yi2(:,:)=pyi2(:,:)
  1348. else
  1349. yi1(:,:)=pyi2(:,:)
  1350. yi2(:,:)=pyi1(:,:)
  1351. endif
  1352. xi1(:,:)=pxi1(:,:)
  1353. xi2(:,:)=pxi2(:,:)
  1354. if (pyo1(1,1) < pyo2(1,1)) then
  1355. yo1(:,:)=pyo1(:,:)
  1356. yo2(:,:)=pyo2(:,:)
  1357. else
  1358. yo1(:,:)=pyo2(:,:)
  1359. yo2(:,:)=pyo1(:,:)
  1360. endif
  1361. xo1(:,:)=pxo1(:,:)
  1362. xo2(:,:)=pxo2(:,:)
  1363. slmo(:,:)=pslmo(:,:)
  1364. kmiss=0
  1365. do jo=1,nyo
  1366. do io=1,nxo
  1367. zgw=0.
  1368. zf=0.
  1369. fo(io,jo)=zerr
  1370. do ji=1,nyi
  1371. do ii=1,nxi
  1372. xol=xo1(io,jo)
  1373. xor=xo2(io,jo)
  1374. xil=xi1(ii,ji)
  1375. xir=xi2(ii,ji)
  1376. if(ABS(xol-xil) > pi) then
  1377. if(xol > xil) then
  1378. xor=xor-2.*pi
  1379. xol=xol-2.*pi
  1380. else
  1381. xir=xir-2.*pi
  1382. xil=xil-2.*pi
  1383. endif
  1384. endif
  1385. !
  1386. if((xol <= xil .and. xor > xil) &
  1387. & .and. (yo1(io,jo) <= yi1(ii,ji) .and. yo2(io,jo) > yi1(ii,ji))) &
  1388. & then
  1389. zweight=(MIN(xor,xir)-xil) &
  1390. & *ABS(sin(MIN(yo2(io,jo),yi2(ii,ji)))-sin(yi1(ii,ji)))
  1391. zf=zf+zweight*fi(ii,ji)*slmi(ii,ji)
  1392. zgw=zgw+zweight*slmi(ii,ji)
  1393. endif
  1394. !
  1395. if((xol > xil .and. xol < xir) &
  1396. & .and. (yo1(io,jo) <= yi1(ii,ji) .and. yo2(io,jo) > yi1(ii,ji))) &
  1397. & then
  1398. zweight=(MIN(xor,xir)-xol) &
  1399. & *ABS(sin(MIN(yo2(io,jo),yi2(ii,ji)))-sin(yi1(ii,ji)))
  1400. zf=zf+zweight*fi(ii,ji)*slmi(ii,ji)
  1401. zgw=zgw+zweight*slmi(ii,ji)
  1402. endif
  1403. !
  1404. if((xol <= xil .and. xor > xil) &
  1405. & .and. (yo1(io,jo) > yi1(ii,ji) .and. yo1(io,jo) < yi2(ii,ji))) &
  1406. & then
  1407. zweight=(MIN(xor,xir)-xil) &
  1408. & *ABS(sin(MIN(yo2(io,jo),yi2(ii,ji)))-sin(yo1(io,jo)))
  1409. zf=zf+zweight*fi(ii,ji)*slmi(ii,ji)
  1410. zgw=zgw+zweight*slmi(ii,ji)
  1411. endif
  1412. !
  1413. if((xol > xil .and. xol < xir) &
  1414. & .and. (yo1(io,jo) > yi1(ii,ji) .and. yo1(io,jo) < yi2(ii,ji))) &
  1415. & then
  1416. zweight=(MIN(xor,xir)-xol) &
  1417. & *ABS(sin(MIN(yo2(io,jo),yi2(ii,ji)))-sin(yo1(io,jo)))
  1418. zf=zf+zweight*fi(ii,ji)*slmi(ii,ji)
  1419. zgw=zgw+zweight*slmi(ii,ji)
  1420. endif
  1421. enddo
  1422. enddo
  1423. if(zgw > 0.) fo(io,jo)=zf/zgw
  1424. if(fo(io,jo) == zerr .and. slmo(io,jo) > 0.) then
  1425. kmiss=kmiss+1
  1426. else
  1427. fo(io,jo)=fo(io,jo)*slmo(io,jo)
  1428. endif
  1429. enddo
  1430. enddo
  1431. !
  1432. if(npr > 0) then
  1433. write(nud,*) ' '
  1434. write(nud,*) 'In CINTER: ',kmiss,' points to be extrapolated'
  1435. endif
  1436. !
  1437. if(kmiss > 0) call cfill(fo,slmo,nxo,nyo,zerr,npr)
  1438. !
  1439. if(nc > 0) then
  1440. call conserve(fi,fo,slmi,slmo,pgwi,pgwo,nxi,nxo,nyi,nyo,nc,npr)
  1441. endif
  1442. !
  1443. pfo(:,:)=fo(:,:)
  1444. !
  1445. return
  1446. end subroutine cinter
  1447. !
  1448. ! ==================
  1449. ! subroutine CINTER2
  1450. ! ==================
  1451. !
  1452. subroutine cinter2(pfi,pslmi,pfo,pslmo,pgwi,pgwo,pxi,pxo &
  1453. & ,pyi,pyo,nxi,nxo,nyi,nyo,nc,npr)
  1454. !
  1455. parameter(zerr=-9.E09)
  1456. !
  1457. real :: fi(0:nxi,0:nyi+1) ! input field
  1458. real :: zzfi(nxi,nyi)
  1459. real :: slmi(0:nxi,0:nyi+1) ! input mask (0/1)
  1460. real :: zzslmi(nxi,nyi)
  1461. real :: fo(nxo,nyo) ! output field
  1462. real :: slmo(nxo,nyo) ! output mask (0/1)
  1463. real :: xi(0:nxi,0:nyi+1) ! x's for input
  1464. real :: xo(nxo,nyo) ! x's for output
  1465. real :: yi(0:nxi,0:nyi+1) ! y's for input
  1466. real :: yo(nxo,nyo) ! y's for output
  1467. real :: gwi(0:nxi,0:nyi+1) ! input weights
  1468. !
  1469. real :: pfi(nxi,nyi)
  1470. real :: pslmi(nxi,nyi)
  1471. real :: pfo(nxo,nyo)
  1472. real :: pslmo(nxo,nyo)
  1473. real :: pxi(nxi,nyi)
  1474. real :: pxo(nxo,nyo)
  1475. real :: pyi(nxi,nyi)
  1476. real :: pyo(nxo,nyo)
  1477. real :: pgwi(nxi,nyi)
  1478. real :: pgwo(nxo,nyo)
  1479. !
  1480. pi=2.*asin(1.)
  1481. !
  1482. fi(1:nxi,1:nyi)=pfi(:,:)
  1483. fi(0,1:nyi)=pfi(nxi,:)
  1484. fi(:,0)=fi(:,1)
  1485. fi(:,nyi+1)=fi(:,nyi)
  1486. slmi(1:nxi,1:nyi)=pslmi(:,:)
  1487. slmi(0,1:nyi)=pslmi(nxi,:)
  1488. slmi(:,0)=slmi(:,1)
  1489. slmi(:,nyi+1)=slmi(:,nyi)
  1490. gwi(1:nxi,1:nyi)=pgwi(:,:)
  1491. gwi(0,1:nyi)=pgwi(nxi,:)
  1492. gwi(:,0)=gwi(:,1)
  1493. gwi(:,nyi+1)=gwi(:,nyi)
  1494. yi(1:nxi,1:nyi)=pyi(:,:)
  1495. yi(0,1:nyi)=pyi(nxi,:)
  1496. if(pyi(1,1) < pyi(1,nyi)) then
  1497. yi(:,0)=-pi*0.5
  1498. yi(:,nyi+1)=pi*0.5
  1499. else
  1500. yi(:,0)=pi*0.5
  1501. yi(:,nyi+1)=-pi*0.5
  1502. endif
  1503. xi(1:nxi,1:nyi)=pxi(:,:)
  1504. xi(0,1:nyi)=pxi(nxi,:)-2.*pi
  1505. xi(:,0)=xi(:,1)
  1506. xi(:,nyi+1)=xi(:,nyi)
  1507. yo(:,:)=pyo(:,:)
  1508. xo(:,:)=pxo(:,:)
  1509. xo(:,:)=pxo(:,:)
  1510. slmo(:,:)=pslmo(:,:)
  1511. !
  1512. kmiss=0
  1513. do jo=1,nyo
  1514. do io=1,nxo
  1515. zgw=0.
  1516. zf=0.
  1517. zxo=xo(io,jo)
  1518. zyo=yo(io,jo)
  1519. fo(io,jo)=zerr
  1520. do ji=1,nyi+1
  1521. do ii=1,nxi
  1522. zxi=xi(ii,ji)
  1523. zxil=xi(ii-1,ji)
  1524. if(zxil > zxi) zxil=zxil-2.*pi
  1525. if(ABS(zxil-zxi) > pi) then
  1526. if(zxil > zxi) then
  1527. zxil=zxil-2.*pi
  1528. else
  1529. zxi=zxi-2.*pi
  1530. endif
  1531. endif
  1532. if(ABS(zxo-zxi) > pi) then
  1533. if(zxo > zxi) then
  1534. zxo=zxo-2.*pi
  1535. else
  1536. zxi=zxi-2.*pi
  1537. zxil=zxil-2.*pi
  1538. endif
  1539. endif
  1540. if(((zyo <= yi(ii,ji) .and. zyo > yi(ii,ji-1)) &
  1541. & .or.(zyo > yi(ii,ji) .and. zyo <= yi(ii,ji-1))) &
  1542. & .and.(zxo <= zxi .and. zxo > zxil)) then
  1543. zgwx1=abs(zxo-zxi)*slmi(ii-1,ji)
  1544. zgwx2=abs(zxo-zxil)*slmi(ii,ji)
  1545. zgwx=zgwx1+zgwx2
  1546. if(zgwx > 0.) then
  1547. zf1=(zgwx1*fi(ii-1,ji)+zgwx2*fi(ii,ji))/zgwx
  1548. zgwy1=abs(zyo-yi(ii,ji-1)) &
  1549. & *(gwi(ii,ji)*slmi(ii,ji)+gwi(ii-1,ji)*slmi(ii-1,ji))
  1550. else
  1551. zf1=0.
  1552. zgwy1=0.
  1553. endif
  1554. zxi=xi(ii,ji-1)
  1555. zxil=xi(ii-1,ji-1)
  1556. if(zxil > zxi) zxil=zxil-2.*pi
  1557. if(ABS(zxil-zxi) > pi) then
  1558. if(zxil > zxi) then
  1559. zxil=zxil-2.*pi
  1560. else
  1561. zxi=zxi-2.*pi
  1562. endif
  1563. endif
  1564. if(ABS(zxo-zxi) > pi) then
  1565. if(zxo > zxi) then
  1566. zxo=zxo-2.*pi
  1567. else
  1568. zxi=zxi-2.*pi
  1569. zxil=zxil-2.*pi
  1570. endif
  1571. endif
  1572. zgwx1=abs(zxo-zxi)*slmi(ii-1,ji-1)
  1573. zgwx2=abs(zxo-zxil)*slmi(ii,ji-1)
  1574. zgwx=zgwx1+zgwx2
  1575. if(zgwx > 0.) then
  1576. zf2=(zgwx1*fi(ii-1,ji-1)+zgwx2*fi(ii,ji-1))/zgwx
  1577. zgwy2=abs(zyo-yi(ii,ji)) &
  1578. & *(gwi(ii,ji-1)*slmi(ii,ji-1) &
  1579. & +gwi(ii-1,ji-1)*slmi(ii-1,ji-1))
  1580. else
  1581. zf2=0.
  1582. zgwy2=0.
  1583. endif
  1584. zgwy=zgwy1+zgwy2
  1585. if(zgwy > 0.) fo(io,jo)=(zf1*zgwy1+zf2*zgwy2)/zgwy
  1586. endif
  1587. enddo
  1588. enddo
  1589. if(fo(io,jo) == zerr .and. slmo(io,jo) > 0.) then
  1590. kmiss=kmiss+1
  1591. else
  1592. fo(io,jo)=fo(io,jo)*slmo(io,jo)
  1593. endif
  1594. enddo
  1595. enddo
  1596. !
  1597. if(npr > 0) then
  1598. write(nud,*) ' '
  1599. write(nud,*) 'In CINTER2: ',kmiss,' points to be extrapolated'
  1600. endif
  1601. !
  1602. if(kmiss > 0) call cfill(fo,slmo,nxo,nyo,zerr,npr)
  1603. !
  1604. if(nc > 0) then
  1605. zzfi(:,:) = fi(1:nxi,1:nyi)
  1606. zzslmi(:,:) = slmi(1:nxi,1:nyi)
  1607. call conserve(zzfi,fo,zzslmi,slmo,pgwi,pgwo,nxi,nxo,nyi,nyo,nc &
  1608. & ,npr)
  1609. endif
  1610. !
  1611. pfo(:,:)=fo(:,:)
  1612. !
  1613. return
  1614. end subroutine cinter2
  1615. !
  1616. ! ================
  1617. ! subroutine CFILL
  1618. ! ================
  1619. !
  1620. subroutine cfill(pf,pm,nx,ny,perr,npr)
  1621. !
  1622. ! complete the field by a simple extrapolation
  1623. !
  1624. real :: pf(nx,ny),pm(nx,ny)
  1625. real :: ppf(0:nx+1,0:ny+1),ppm(0:nx+1,0:ny+1)
  1626. !
  1627. ppf(1:nx,1:ny)=pf(:,:)
  1628. ppf(0,1:ny)=pf(nx,:)
  1629. ppf(nx+1,1:ny)=pf(1,:)
  1630. ppf(:,0)=ppf(:,1)
  1631. ppf(:,ny+1)=ppf(:,ny)
  1632. ppm(1:nx,1:ny)=pm(:,:)
  1633. ppm(0,1:ny)=pm(nx,:)
  1634. ppm(nx+1,1:ny)=pm(1,:)
  1635. ppm(:,0)=ppm(:,1)
  1636. ppm(:,ny+1)=ppm(:,ny)
  1637. !
  1638. kmiss=1
  1639. do while(kmiss > 0)
  1640. kmiss=0
  1641. do j=1,ny
  1642. do i=1,nx
  1643. if(ppf(i,j) == perr .or. ppm(i,j) < 0.5) then
  1644. zf=0.
  1645. zgw=0.
  1646. if(ppf(i-1,j) /= perr) then
  1647. zf=zf+ppf(i-1,j)*ppm(i-1,j)
  1648. zgw=zgw+ppm(i-1,j)
  1649. endif
  1650. if(ppf(i+1,j) /= perr) then
  1651. zf=zf+ppf(i+1,j)*ppm(i+1,j)
  1652. zgw=zgw+ppm(i+1,j)
  1653. endif
  1654. if(ppf(i,j-1) /= perr) then
  1655. zf=zf+ppf(i,j-1)*ppm(i,j-1)
  1656. zgw=zgw+ppm(i,j-1)
  1657. endif
  1658. if(ppf(i,j+1) /= perr) then
  1659. zf=zf+ppf(i,j+1)*ppm(i,j+1)
  1660. zgw=zgw+ppm(i,j+1)
  1661. endif
  1662. if(zgw > 0.) then
  1663. ppf(i,j)=zf/zgw
  1664. ppm(i,j)=1.
  1665. endif
  1666. if(i==1) ppf(nx+1,j)=ppf(i,j)
  1667. if(i==nx) ppf(0,j)=ppf(i,j)
  1668. if(j==1) ppf(i,0)=ppf(i,j)
  1669. if(j==ny) ppf(i,ny+1)=ppf(i,j)
  1670. endif
  1671. if(ppf(i,j) == perr) kmiss=kmiss+1
  1672. enddo
  1673. enddo
  1674. if(npr > 0) then
  1675. write(nud,*) 'In CFILL: ',kmiss,' points still missed'
  1676. endif
  1677. enddo
  1678. !
  1679. pf(:,:)=ppf(1:nx,1:ny)
  1680. !
  1681. return
  1682. end
  1683. !
  1684. ! ===================
  1685. ! subroutine CONSERVE
  1686. ! ===================
  1687. !
  1688. subroutine conserve(pfi,pfo,pmi,pmo,pgwi,pgwo &
  1689. & ,nxi,nxo,nyi,nyo,nc,npr)
  1690. !
  1691. ! correct global mean (multiplicative or additive depending on nc)
  1692. !
  1693. ! nc=1 : multiply f to give sum(fi*gwi)=sum(fon*gwo) with fon=f*fo
  1694. ! nc=2 : multiply f to give sum(fi*gwi)/sum(gwi)=sum(fon*gwo)/sum(gwo)
  1695. ! nc=3 : add a to give sum(fi*gwi)=sum(fon*gwo) with fon=fo+a
  1696. ! nc=4 : add a to give sum(fi*gwi)/sum(gwi)=sum(fon*gwo)/sum(gwo)
  1697. !
  1698. real :: pfi(nxi,nyi)
  1699. real :: pfo(nxo,nyo)
  1700. real :: pmi(nxi,nyi)
  1701. real :: pmo(nxo,nyo)
  1702. real :: pgwi(nxi,nyi)
  1703. real :: pgwo(nxo,nyo)
  1704. !
  1705. zgwi=0.
  1706. zfi=0.
  1707. do j=1,nyi
  1708. do i=1,nxi
  1709. zgw=pgwi(i,j)*pmi(i,j)
  1710. zfi=zfi+pfi(i,j)*zgw
  1711. zgwi=zgwi+zgw
  1712. enddo
  1713. enddo
  1714. zgwo=0.
  1715. zfo=0.
  1716. do j=1,nyo
  1717. do i=1,nxo
  1718. zgw=pgwo(i,j)*pmo(i,j)
  1719. zfo=zfo+pfo(i,j)*zgw
  1720. zgwo=zgwo+zgw
  1721. enddo
  1722. enddo
  1723. !
  1724. if(nc < 3) then
  1725. if(zfo == 0.) then
  1726. if(zfi /= 0.) write(nud,*) 'WARNING (CPL): No Conservation (zfo=0.)'
  1727. zfac1=1.
  1728. zfac2=1.
  1729. else
  1730. zfac1=zfi/zfo
  1731. zfac2=zfi/zfo*zgwo/zgwi
  1732. endif
  1733. endif
  1734. zadd1=(zfi-zfo)/zgwo
  1735. zadd2=zfi/zgwi-zfo/zgwo
  1736. !
  1737. if(nc==1) pfo(:,:)=pfo(:,:)*zfac1
  1738. if(nc==2) pfo(:,:)=pfo(:,:)*zfac2
  1739. if(nc==3) pfo(:,:)=pfo(:,:)+zadd1*pmo(:,:)
  1740. if(nc==4) pfo(:,:)=pfo(:,:)+zadd2*pmo(:,:)
  1741. !
  1742. if(npr > 0) then
  1743. if(nc==1) write(nud,*) 'In CONSERVE: nc= ',nc,' Fac= ',zfac1
  1744. if(nc==2) write(nud,*) 'In CONSERVE: nc= ',nc,' Fac= ',zfac2
  1745. if(nc==3) write(nud,*) 'In CONSERVE: nc= ',nc,' Add= ',zadd1
  1746. if(nc==4) write(nud,*) 'In CONSERVE: nc= ',nc,' Add= ',zadd2
  1747. endif
  1748. !
  1749. return
  1750. end
  1751. !
  1752. ! ===============
  1753. ! subroutine CGLM
  1754. ! ===============
  1755. !
  1756. subroutine cglm(pf,pm,pgs,pgm,pgw,pgwi,nx,ny)
  1757. !
  1758. ! compute global means
  1759. !
  1760. real :: pf(nx,ny)
  1761. real :: pm(nx,ny)
  1762. real :: pgwi(nx,ny)
  1763. !
  1764. real :: zgwd,zgsd,zgw
  1765. !
  1766. zgwd=0.
  1767. zgsd=0.
  1768. do j=1,ny
  1769. do i=1,nx
  1770. zgw=pgwi(i,j)*pm(i,j)
  1771. zgsd=zgsd+pf(i,j)*zgw
  1772. zgwd=zgwd+zgw
  1773. enddo
  1774. enddo
  1775. if(zgwd > 0.) then
  1776. pgm=zgsd/zgwd
  1777. else
  1778. write(nud,*)'!WARNING! no sea points found in cglm2'
  1779. endif
  1780. pgs=zgsd
  1781. pgw=zgwd
  1782. !
  1783. return
  1784. end subroutine cglm
  1785. !
  1786. ! ====================
  1787. ! subroutine CFLUKOINI
  1788. ! ====================
  1789. !
  1790. subroutine cflukoini
  1791. use cplmod
  1792. !
  1793. integer ih(8)
  1794. real :: zin(nxo,nyot) = 0.
  1795. logical lopen
  1796. character (len=20) :: yformat = "(8E12.6)"
  1797. !
  1798. do jt=30,99
  1799. ntape=jt
  1800. inquire(unit=ntape,opened=lopen)
  1801. if(.not. lopen) exit
  1802. enddo
  1803. !
  1804. open(ntape,file=trim(flukofile),form='formatted')
  1805. jflfresh=0
  1806. jflsst=0
  1807. jfltaux=0
  1808. jfltauy=0
  1809. jflice=0
  1810. jfloheat=0
  1811. do
  1812. read(ntape,'(8I10)',end=1001) ih
  1813. read(ntape,yformat) zin(:,3:74)
  1814. jmon=ih(3)
  1815. if(jmon >= 100) jmon=(jmon-(jmon/10000)*10000)/100 ! oroginal service
  1816. if(ih(1)==75 .or. ih(1)== -82) then
  1817. flukofresh(:,:,jmon)=zin(:,:)
  1818. jflfresh=jflfresh+1
  1819. elseif(ih(1)==73 .or. ih(1)== -83) then
  1820. flukotaux(:,:,jmon)=zin(:,:)
  1821. jfltaux=jfltaux+1
  1822. elseif(ih(1)==74 .or. ih(1)== -84) then
  1823. flukotauy(:,:,jmon)=zin(:,:)
  1824. jfltauy=jfltauy+1
  1825. elseif(ih(1)==72 .or. ih(1)== -80) then
  1826. flukosst(:,:,jmon)=zin(:,:)
  1827. jflsst=jflsst+1
  1828. elseif(ih(1)==78) then
  1829. flukooheat(:,:,jmon)=zin(:,:)
  1830. jfloheat=jfloheat+1
  1831. elseif(ih(1)==79 .or. ih(1)== -81) then
  1832. flukoice(:,:,jmon)=zin(:,:)
  1833. jflice=jflice+1
  1834. endif
  1835. enddo
  1836. 1001 continue
  1837. close(ntape)
  1838. !
  1839. write(nud,*)' '
  1840. write(nud,*)'Reading Flux corrections'
  1841. write(nud,*)jflsst,' months sst correction found in ',trim(flukofile)
  1842. write(nud,*)jfltaux,' months taux correction found in ',trim(flukofile)
  1843. write(nud,*)jfltauy,' months tauy correction found in ',trim(flukofile)
  1844. write(nud,*)jflice,' months ice correction found in ',trim(flukofile)
  1845. write(nud,*)jflfresh,' months pme correction found in ',trim(flukofile)
  1846. write(nud,*)jfloheat,' months heat correction found in ',trim(flukofile)
  1847. write(nud,*)' '
  1848. !
  1849. return
  1850. !
  1851. end subroutine cflukoini
  1852. !
  1853. ! ==================
  1854. ! subroutine CFLUKOA
  1855. ! ==================
  1856. !
  1857. subroutine cflukoa(psst,ptaux,ptauy,pice,pfresh)
  1858. use cplmod
  1859. !
  1860. real :: psst(nxo,nyot),ptaux(nxo,nyot),ptauy(nxo,nyot)
  1861. real :: pice(nxo,nyot),pfresh(nxo,nyot)
  1862. !
  1863. jmon=ndatim(2)
  1864. !
  1865. if(nflsst==1) then
  1866. psst(:,:)=psst(:,:)+flukosst(:,:,jmon)
  1867. endif
  1868. !
  1869. if(nflice==1) then
  1870. pice(:,:)=pice(:,:)+flukoice(:,:,jmon)
  1871. endif
  1872. !
  1873. if(nfltau==1) then
  1874. ptaux(:,:)=ptaux(:,:)+flukotaux(:,:,jmon)
  1875. ptauy(:,:)=ptauy(:,:)+flukotauy(:,:,jmon)
  1876. endif
  1877. !
  1878. if(nflfresh==1) then
  1879. pfresh(:,:)=pfresh(:,:)+flukofresh(:,:,jmon)
  1880. endif
  1881. !
  1882. return
  1883. end subroutine cflukoa
  1884. !
  1885. ! ==================
  1886. ! subroutine CFLUKOB
  1887. ! ==================
  1888. !
  1889. subroutine cflukob(poheat)
  1890. use cplmod
  1891. !
  1892. real :: poheat(nxo,nyot)
  1893. !
  1894. jmon=ndatim(2)
  1895. !
  1896. if(nfloheat==1) then
  1897. poheat(:,:)=poheat(:,:)+flukooheat(:,:,jmon)
  1898. endif
  1899. !
  1900. return
  1901. end subroutine cflukob
  1902. !
  1903. ! ================
  1904. ! subroutine CPFAC
  1905. ! ================
  1906. !
  1907. subroutine cpfac(pfsst,pftau,pffresh,pfice)
  1908. use cplmod
  1909. !
  1910. real :: pfsst,pftau,pffresh,pfice
  1911. !
  1912. pfsst=cfacsst
  1913. pftau=cfactau
  1914. pffresh=cfacfresh
  1915. pfice=cfacice
  1916. !
  1917. return
  1918. end subroutine cpfac
  1919. !
  1920. ! =================
  1921. ! subroutine CROFFC
  1922. ! =================
  1923. !
  1924. subroutine croffc(proff)
  1925. use cplmod
  1926. !
  1927. real :: proff(nxa,nya)
  1928. real :: zroff(nxa,nya)
  1929. !
  1930. if(nroffc == 1) then
  1931. !
  1932. ! substitute lokal runoff by global mean
  1933. !
  1934. call cglm(proff,aslm,zgs,zgm,zgw,agw,nxa,nya)
  1935. proff(:,:)=zgm*aslm(:,:)
  1936. endif
  1937. !
  1938. if(nroffc == 2) then
  1939. !
  1940. ! substitute lokal runoff by area averages
  1941. ! where iroffi==0 local runoff is kept
  1942. !
  1943. !! kroff=0
  1944. nroffa=maxval(iroffi(:,:))
  1945. do ja=1,nroffa
  1946. zroffa=SUM(proff(:,:)*agw(:,:)*aslm(:,:) &
  1947. & ,mask=(ja == iroffi(:,:)))
  1948. zgwa=SUM(agw(:,:)*aslm(:,:),mask=(ja == iroffi(:,:)))
  1949. !! kroff=kroff+SUM(nint(aslm(:,:)),mask=(ja == iroffi(:,:)))
  1950. if(zgwa <= 0.) then
  1951. zgwa=-1.
  1952. zroffa=0.
  1953. endif
  1954. where(ja == iroffi(:,:))
  1955. proff(:,:)=zroffa/zgwa*aslm(:,:)
  1956. endwhere
  1957. enddo
  1958. !! klsm=SUM(nint(aslm(:,:)))
  1959. !! if(kroff /= klsm) then
  1960. !! write(nud,*)'WARNING: runoff corrected only for ',kroff,' from ' &
  1961. !! & ,klsm,' gridpoints!'
  1962. !! endif
  1963. elseif(nroffc == 3) then
  1964. zroff(:,:)=0.
  1965. !
  1966. ! redistribute lokal runoff using area averages
  1967. ! where iroffi==0 local runoff + area average is used
  1968. !
  1969. where(iroffi(:,:) == 0)
  1970. zroff(:,:)=proff(:,:)
  1971. endwhere
  1972. nroffa=maxval(iroffi(:,:))
  1973. !! kroffi=0
  1974. do ja=1,nroffa
  1975. zroffa=SUM(proff(:,:)*agw(:,:)*aslm(:,:) &
  1976. & ,mask=(ja == iroffi(:,:)))
  1977. zgwa=SUM(agw(:,:)*aslm(:,:),mask=(ja == iroffo(:,:)))
  1978. !! kroffi=kroffi+SUM(nint(aslm(:,:)),mask=(ja == iroffi(:,:)))
  1979. if(zgwa <= 0. .and. zroffa > 0.) then
  1980. write(nud,*)'ERROR: zero area for runoff output no ',ja
  1981. stop
  1982. endif
  1983. if(zgwa > 0.) then
  1984. where(ja == iroffo(:,:))
  1985. zroff(:,:)=zroffa/zgwa*aslm(:,:)+zroff(:,:)
  1986. endwhere
  1987. endif
  1988. enddo
  1989. !! klsm=SUM(nint(aslm(:,:)))
  1990. !! if(kroffi /= klsm) then
  1991. !! write(nud,*)'ERROR: not all runoff redistributed!',klsm,kroffi,nroffa
  1992. !! stop
  1993. !! endif
  1994. proff(:,:)=zroff(:,:)
  1995. endif
  1996. !
  1997. return
  1998. end subroutine croffc