grid_interpol.F90 113 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824
  1. !
  2. ! NAME
  3. ! grid_interpol - from sh/gg/ll to gg/ll
  4. !
  5. ! HISTORY
  6. ! v1.?
  7. ! Original
  8. ! v1.1
  9. ! Bug fixed: southpole in gg -> ll
  10. !
  11. module Grid_Interpol
  12. implicit none
  13. ! --- in/out ------------------------------
  14. private
  15. public :: Interpol
  16. public :: NewInterpol
  17. public :: InterpolMask
  18. public :: Aver
  19. public :: IntArea
  20. public :: IntLat, IntLon
  21. !public :: ShTruncation, ShRefinement
  22. public :: Tgg2llFracs, Tll2ggFracs, Init, Done, FracSum
  23. ! --- const ----------------------------------
  24. character(len=*), parameter :: mname = 'grid_interpol'
  25. ! --- types -------------------------------
  26. type Tgg2llFracs
  27. integer :: nlon, nlat, np
  28. integer, pointer :: ncov(:,:)
  29. integer, pointer :: indx(:,:,:)
  30. real, pointer :: frac(:,:,:)
  31. real, pointer :: A_gg(:) ! m2
  32. real, pointer :: A_ll(:,:) ! m2
  33. end type Tgg2llFracs
  34. type Tll2ggFracs
  35. integer :: nlon, nlat, np
  36. integer, pointer :: ncov(:) ! (1:np)
  37. integer, pointer :: ii(:,:) ! (1:np,1:max(ncov(k)))
  38. integer, pointer :: jj(:,:) ! (1:np,1:max(ncov(k)))
  39. real, pointer :: ff(:,:) ! (1:np,1:max(ncov(k)))
  40. real, pointer :: A_gg(:) ! m2
  41. real, pointer :: A_ll(:,:) ! m2
  42. end type Tll2ggFracs
  43. ! --- interfaces --------------------------
  44. interface Init
  45. module procedure gg2ll_Init
  46. module procedure ll2gg_Init
  47. end interface
  48. interface Done
  49. module procedure gg2ll_Done
  50. module procedure ll2gg_Done
  51. end interface
  52. interface FracSum
  53. module procedure gg2ll_FracSum
  54. module procedure ll2gg_FracSum
  55. end interface
  56. interface Interpol
  57. module procedure Interpol_sh_gg
  58. module procedure Interpol_shi_gg
  59. module procedure Interpol_sh_ll
  60. module procedure Interpol_shi_ll
  61. module procedure Interpol_gg_ll
  62. module procedure Interpol_ll_gg
  63. end interface
  64. interface NewInterpol
  65. module procedure NewInterpol_shi_gg
  66. end interface
  67. interface Aver
  68. module procedure Aver_gg_ll
  69. module procedure Aver_sh_ll
  70. end interface
  71. interface IntArea
  72. module procedure IntArea_sh_ll_f
  73. module procedure IntArea_shi_ll_f
  74. module procedure IntArea_sh_ll_fgh
  75. module procedure IntArea_shi_ll_fgh
  76. module procedure IntArea_sh_ll_fh
  77. module procedure IntArea_shi_ll_fh
  78. end interface
  79. interface IntLat
  80. module procedure IntLat_sh_ll
  81. module procedure IntLat_shi_ll
  82. end interface
  83. interface IntLon
  84. module procedure IntLon_sh_ll
  85. module procedure IntLon_shi_ll
  86. end interface
  87. contains
  88. ! =========================================================
  89. ! ===
  90. ! === evaluate spectral fields
  91. ! ===
  92. ! =========================================================
  93. ! from spectral to reduced gausian grid
  94. subroutine Interpol_sh_gg( sh, ggi, gg, status )
  95. use Grid_Type_sh, only : TshGrid, Eval_Lons, Check
  96. use Grid_Type_gg, only : TggGridInfo, Check
  97. ! --- in/out ----------------------------------
  98. type(TshGrid), intent(in) :: sh
  99. type(TggGridInfo), intent(in) :: ggi
  100. real, intent(out) :: gg(ggi%np)
  101. integer, intent(out) :: status
  102. ! --- const --------------------------------
  103. character(len=*), parameter :: rname = mname//'/Interpol_sh_gg'
  104. ! --- local -----------------------------------
  105. !real, allocatable :: llgrid(:,:)
  106. real, allocatable :: llgrid(:)
  107. integer :: nlon
  108. integer :: jn !, js
  109. ! --- begin -----------------------------------
  110. call Check( sh )
  111. call Check( ggi, gg )
  112. !allocate( llgrid(maxval(ggi%nlon),2) )
  113. allocate( llgrid(maxval(ggi%nlon)) )
  114. ! northern rows:
  115. !do jn = 1, ggi%nlat/2
  116. do jn = 1, ggi%nlat
  117. ! southern row:
  118. !js = ggi%nlat + 1 - jn
  119. ! only if one of the rows is marked:
  120. !if ( ggi%latflag(jn) .or. ggi%latflag(js) ) then
  121. if ( ggi%latflag(jn) ) then
  122. nlon = ggi%nlon(jn)
  123. !call Eval_Lons( llgrid(1:nlon,1:2), sh, ggi%lat(jn), nlon, 0.0, nlon )
  124. !gg(ggi%i1(jn):ggi%im(jn)) = llgrid(1:nlon,1)
  125. !gg(ggi%i1(js):ggi%im(js)) = llgrid(1:nlon,2)
  126. call Eval_Lons( llgrid(1:nlon), sh, ggi%lat(jn), nlon, 0.0, nlon, status )
  127. gg(ggi%i1(jn):ggi%im(jn)) = llgrid(1:nlon)
  128. end if
  129. end do
  130. deallocate( llgrid )
  131. end subroutine Interpol_sh_gg
  132. ! *
  133. subroutine NewInterpol_shi_gg( shi, shc, ggi, gg, status )
  134. use Grid_Type_sh, only : TshGridInfo, Check, Eval_Lons
  135. use Grid_Type_sh, only : TshGrid, Init, Done, Set
  136. use Grid_Type_gg, only : TggGridInfo, Check
  137. ! --- in/out ----------------------------------
  138. type(TshGridInfo), intent(in) :: shi
  139. complex, intent(in) :: shc(shi%np)
  140. type(TggGridInfo), intent(in) :: ggi
  141. real, intent(out) :: gg(ggi%np)
  142. integer, intent(out) :: status
  143. ! --- const --------------------------------
  144. character(len=*), parameter :: rname = mname//'/NewInterpol_shi_gg'
  145. ! --- local -----------------------------------
  146. real, pointer :: llgrid(:)
  147. integer :: nlon
  148. integer :: jn !, js
  149. ! --- begin -----------------------------------
  150. allocate( llgrid(maxval(ggi%nlon)) )
  151. ! northern rows:
  152. !do jn = 1, ggi%nlat/2
  153. do jn = 1, ggi%nlat
  154. ! southern row:
  155. !js = ggi%nlat + 1 - jn
  156. ! only if one of the rows is marked:
  157. !if ( ggi%latflag(jn) .or. ggi%latflag(js) ) then
  158. if ( ggi%latflag(jn) ) then
  159. nlon = ggi%nlon(jn)
  160. !call Eval_Lons( llgrid(1:nlon,1:2), sh, ggi%lat(jn), nlon, 0.0, nlon )
  161. !gg(ggi%i1(jn):ggi%im(jn)) = llgrid(1:nlon,1)
  162. !gg(ggi%i1(js):ggi%im(js)) = llgrid(1:nlon,2)
  163. call Eval_Lons( shi, shc, ggi%lat(jn), nlon, 0.0, nlon, llgrid(1:nlon), status )
  164. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  165. gg(ggi%i1(jn):ggi%im(jn)) = llgrid(1:nlon)
  166. end if
  167. end do
  168. ! done
  169. deallocate( llgrid )
  170. ! ok
  171. status = 0
  172. end subroutine NewInterpol_shi_gg
  173. ! *
  174. subroutine Interpol_shi_gg( shi, shc, ggi, gg, status )
  175. use Grid_Type_sh, only : TshGridInfo, Check, Eval_Lons
  176. use Grid_Type_sh, only : TshGrid, Init, Done, Set
  177. use Grid_Type_gg, only : TggGridInfo, Check
  178. ! --- in/out ----------------------------------
  179. type(TshGridInfo), intent(in) :: shi
  180. complex, intent(in) :: shc(shi%np)
  181. type(TggGridInfo), intent(in) :: ggi
  182. real, intent(out) :: gg(ggi%np)
  183. integer, intent(out) :: status
  184. ! --- const --------------------------------
  185. character(len=*), parameter :: rname = mname//'/Interpol_shi_gg'
  186. ! --- local -----------------------------------
  187. type(TshGrid) :: sh
  188. !real, allocatable :: llgrid(:,:)
  189. real, allocatable :: llgrid(:)
  190. integer :: nlon
  191. integer :: jn !, js
  192. ! --- begin -----------------------------------
  193. ! store input in old type grid:
  194. call Init( sh )
  195. call Set( sh, shi%T, shc )
  196. !allocate( llgrid(maxval(ggi%nlon),2) )
  197. allocate( llgrid(maxval(ggi%nlon)) )
  198. ! northern rows:
  199. !do jn = 1, ggi%nlat/2
  200. do jn = 1, ggi%nlat
  201. ! southern row:
  202. !js = ggi%nlat + 1 - jn
  203. ! only if one of the rows is marked:
  204. !if ( ggi%latflag(jn) .or. ggi%latflag(js) ) then
  205. if ( ggi%latflag(jn) ) then
  206. nlon = ggi%nlon(jn)
  207. !call Eval_Lons( llgrid(1:nlon,1:2), sh, ggi%lat(jn), nlon, 0.0, nlon )
  208. !gg(ggi%i1(jn):ggi%im(jn)) = llgrid(1:nlon,1)
  209. !gg(ggi%i1(js):ggi%im(js)) = llgrid(1:nlon,2)
  210. call Eval_Lons( llgrid(1:nlon), sh, ggi%lat(jn), nlon, 0.0, nlon, status )
  211. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  212. gg(ggi%i1(jn):ggi%im(jn)) = llgrid(1:nlon)
  213. end if
  214. end do
  215. ! done
  216. deallocate( llgrid )
  217. call Done( sh )
  218. ! ok
  219. status = 0
  220. end subroutine Interpol_shi_gg
  221. ! ===
  222. ! from sh to ll
  223. subroutine Interpol_sh_ll( sh, lli, ll, status )
  224. use Grid_Type_sh, only : TshGrid, Eval_Lons, Check
  225. use Grid_Type_ll, only : TllGridInfo, Check
  226. ! --- in/out -------------------------------
  227. type(TshGrid), intent(in) :: sh
  228. type(TllGridInfo), intent(in) :: lli
  229. real, intent(out) :: ll(lli%im,lli%jm)
  230. integer, intent(out) :: status
  231. ! --- const --------------------------------
  232. character(len=*), parameter :: rname = mname//'/Interpol_sh_ll'
  233. ! --- local --------------------------------
  234. integer :: j
  235. ! --- begin --------------------------------
  236. call Check( sh )
  237. call Check( lli, 'n', ll, status )
  238. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  239. ! loop over latitudes
  240. do j = 1, lli%jm
  241. ! evaluate at oposite latidutes:
  242. call Eval_Lons( ll(:,j), sh, lli%lat(j), int(360.0/lli%dlon_deg), &
  243. lli%lon(1), lli%im, status )
  244. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  245. end do
  246. ! ok
  247. status = 0
  248. end subroutine Interpol_sh_ll
  249. ! *
  250. ! from shi/sh to ll
  251. subroutine Interpol_shi_ll( shi, shc, lli, ll, status )
  252. use Grid_Type_sh, only : TshGridInfo, Check, Eval_Lons
  253. use Grid_Type_sh, only : TshGrid, Init, Done, Set
  254. use Grid_Type_ll, only : TllGridInfo, Check
  255. ! --- in/out -------------------------------
  256. type(TshGridInfo), intent(in) :: shi
  257. complex, intent(in) :: shc(shi%np)
  258. type(TllGridInfo), intent(in) :: lli
  259. real, intent(out) :: ll(lli%im,lli%jm)
  260. integer, intent(out) :: status
  261. ! --- const --------------------------------
  262. character(len=*), parameter :: rname = mname//'/Interpol_shi_ll'
  263. ! --- local --------------------------------
  264. type(TshGrid) :: sh
  265. integer :: j
  266. ! --- begin --------------------------------
  267. ! store input in old type grid:
  268. call Init( sh )
  269. call Set( sh, shi%T, shc )
  270. ! check lat/lon arguments:
  271. call Check( lli, 'n', ll, status )
  272. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  273. ! loop over latitudes
  274. do j = 1, lli%jm
  275. ! evaluate spectral field:
  276. call Eval_Lons( ll(:,j), sh, lli%lat(j), int(360.0/lli%dlon_deg), &
  277. lli%lon(1), lli%im, status )
  278. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  279. end do
  280. ! done
  281. call Done( sh )
  282. ! ok
  283. status = 0
  284. end subroutine Interpol_shi_ll
  285. ! =========================================================
  286. ! ===
  287. ! === interpolate from gg
  288. ! ===
  289. ! =========================================================
  290. ! Return a logical array with size gg;
  291. ! true if a point is required for interpolation from gg to ll
  292. !
  293. ! Include 'depth' extra rows.
  294. !
  295. ! Also set flags in ggi for each row.
  296. !
  297. subroutine InterpolMask( ggi, gg, lli, depth )
  298. use Grid_Type_gg, only : TggGridInfo, Check
  299. use Grid_Type_ll, only : TllGridInfo, Check
  300. ! --- in/out -------------------------------
  301. type(TggGridInfo), intent(inout) :: ggi
  302. logical, intent(out) :: gg(ggi%np)
  303. type(TllGridInfo), intent(in) :: lli
  304. integer, intent(in) :: depth
  305. ! --- local --------------------------------
  306. integer :: j, jn, js
  307. ! --- begin ------------------------------
  308. ! note: gg lats from north to south!
  309. !print *, 'llilat:',lli%blat_deg(0), lli%blat_deg(lli%nlat)
  310. ! search south most gg lat outside lli
  311. js = 1
  312. do
  313. if ( js == ggi%nlat ) exit
  314. if ( ggi%lat(js) < lli%blat(0) ) exit
  315. js = js + 1
  316. end do
  317. js = min( ggi%nlat, js+depth )
  318. ! search north-most gg lat row outside lli
  319. jn = ggi%nlat
  320. do
  321. if ( jn == 1 ) exit
  322. if ( ggi%lat(jn) > lli%blat(lli%nlat) ) exit
  323. jn = jn - 1
  324. end do
  325. jn = max( 1, jn-depth )
  326. ! set all rows between js and jn to true:
  327. gg = .false.
  328. ggi%latflag = .false.
  329. do j = jn, js
  330. ggi%latflag(j) = .true.
  331. gg(ggi%i1(j):ggi%im(j)) = .true.
  332. end do
  333. end subroutine InterpolMask
  334. ! *************************************************************
  335. !
  336. ! Determine fraction of gg cell that covers a ll cell.
  337. !
  338. ! Returns three arrays:
  339. !
  340. ! integer :: ncov(im,jm)
  341. ! integer :: indx(im,jm,max_nconv)
  342. ! real :: frac(im,jm,max_nconv)
  343. !
  344. ! For an ll cell (i,j), 'ncov' gives the number of gg cells covering it.
  345. ! Their gg indices are stored in : indx(i,j,1:ncov(i,j)),
  346. ! corresponding fractions are in : frac(i,j,1:ncov(i,j)) .
  347. !
  348. subroutine gg2ll_Init( gg2ll, ggi, lli, status )
  349. use num, only : Interval
  350. use grid_tools, only : pi, ll_area_frac
  351. use grid_type_gg, only : TggGridInfo, AreaOper
  352. use grid_type_ll, only : TllGridInfo, AreaOper
  353. ! --- in/out ---------------------------
  354. type(Tgg2llFracs), intent(out) :: gg2ll
  355. type(TggGridInfo), intent(in) :: ggi
  356. type(TllGridInfo), intent(in) :: lli
  357. integer, intent(out) :: status
  358. ! --- const ---------------------------------
  359. character(len=*), parameter :: rname = mname//'/gg2ll_Init'
  360. ! --- local ----------------------------
  361. integer :: max_ncov_lon, max_ncov_lat, max_ncov
  362. integer :: i, j
  363. integer :: iflag
  364. integer :: gi, gi1, gi2
  365. integer :: gj, gj1, gj2
  366. integer :: nlon
  367. real :: gblon(0:ggi%nlon_reg)
  368. real :: west1, east1, south1, north1
  369. real :: west2, east2, south2, north2
  370. real :: frac
  371. integer :: ncov
  372. ! --- begin ----------------------------
  373. ! save dimension
  374. gg2ll%nlon = lli%nlon
  375. gg2ll%nlat = lli%nlat
  376. gg2ll%np = ggi%np
  377. ! estimate maximum number of gg cells covering an ll cell:
  378. max_ncov_lon = ceiling(lli%dlon/minval(ggi%dlon))
  379. max_ncov_lat = ceiling(lli%dlat/minval(ggi%dlat))
  380. max_ncov = (max_ncov_lon+1) * (max_ncov_lat+1)
  381. ! allocate arrays
  382. allocate( gg2ll%ncov(lli%nlon,lli%nlat) )
  383. allocate( gg2ll%indx(lli%nlon,lli%nlat,max_ncov) )
  384. allocate( gg2ll%frac(lli%nlon,lli%nlat,max_ncov) )
  385. ! zero by default:
  386. gg2ll%ncov = 0
  387. gg2ll%indx = 0
  388. gg2ll%frac = 0.0
  389. gj1 = 0
  390. gj2 = 0
  391. ! loop over ll cells from north to south (gg direction):
  392. do j = lli%nlat, 1, -1
  393. do i = 1, lli%nlon
  394. ! extract boundaries of ll cell:
  395. west2 = lli%blon(i-1)
  396. east2 = lli%blon(i)
  397. if ( east2 < 0.0 ) then
  398. west2 = west2 + 2*pi ! (0,2pi)
  399. east2 = east2 + 2*pi ! (0,2pi)
  400. end if
  401. south2 = lli%blat(j-1)
  402. north2 = lli%blat(j)
  403. ! search gg rows including north and south ll lat;
  404. ! negative lats to get increasing values ...
  405. call Interval( -ggi%blat, -north2 , gj1, iflag )
  406. if ( iflag /= 0 ) stop 'BUG IN gg2ll_Init : wrong iflag gj1'
  407. call Interval( -ggi%blat, -south2, gj2, iflag )
  408. if ( iflag /= 0 ) stop 'BUG IN gg2ll_Init : wrong iflag gj2'
  409. gi1 = 0
  410. gi2 = 0
  411. ! loop over gg lat rows:
  412. do gj = gj1, gj2
  413. ! boundary lons
  414. nlon = ggi%nlon(gj)
  415. do gi = 0, nlon
  416. gblon(gi) = (gi-0.5)*ggi%dlon(gj)
  417. end do
  418. ! search cells including west and east bound of ll cell
  419. if ( west2 < gblon(0) ) then
  420. call Interval( gblon(0:nlon), west2+2*pi, gi1, iflag )
  421. else if ( west2 > gblon(nlon) ) then
  422. call Interval( gblon(0:nlon), west2-2*pi, gi1, iflag )
  423. else
  424. call Interval( gblon(0:nlon), west2 , gi1, iflag )
  425. end if
  426. if ( iflag /= 0 ) then
  427. print *, 'gblon=', gblon(0:nlon)
  428. print *, 'west2=',west2
  429. print *, 'iflag=',iflag
  430. stop 'BUG IN gg2ll_Init : wrong iflag gi1'
  431. end if
  432. if ( east2 < gblon(0) ) then
  433. call Interval( gblon(0:nlon), east2+2*pi, gi2, iflag )
  434. else if ( east2 > gblon(nlon) ) then
  435. call Interval( gblon(0:nlon), east2-2*pi, gi2, iflag )
  436. else
  437. call Interval( gblon(0:nlon), east2 , gi2, iflag )
  438. end if
  439. if ( iflag /= 0 ) then
  440. print *, 'gblon=', gblon(0:nlon)
  441. print *, 'east2=',east2
  442. stop 'BUG IN gg2ll_Init : wrong iflag gi2'
  443. end if
  444. ! loop over all gg cells in current row:
  445. gi = gi1
  446. do
  447. ! extract boundaries of gg cell:
  448. west1 = (gi-1.5)*ggi%dlon(gj) ! (0,2pi)
  449. east1 = (gi-0.5)*ggi%dlon(gj) ! (0,2pi)
  450. south1 = ggi%blat(gj)
  451. north1 = ggi%blat(gj-1)
  452. ! shift if gg cell is right from [0,2pi]
  453. if ( west1 > east2 ) then
  454. west1 = west1 - 2*pi ! (0,2pi)
  455. east1 = east1 - 2*pi ! (0,2pi)
  456. end if
  457. ! determine covarage fraction:
  458. frac = ll_area_frac( west1, east1, south1, north1, &
  459. west2, east2, south2, north2 )
  460. ! fill fraction:
  461. if ( frac > 0.0 .and. frac <= 1.0 ) then
  462. ncov = gg2ll%ncov(i,j) + 1
  463. gg2ll%ncov(i,j) = ncov
  464. gg2ll%indx(i,j,ncov) = ggi%i1(gj)-1 + gi
  465. gg2ll%frac(i,j,ncov) = frac
  466. else if ( abs(frac) < 1.0e-4 ) then
  467. ! almost no coverage ...
  468. else if ( abs(frac-1.0) < 1.0e-4 ) then
  469. !print *, 'WARNING in module grid_interpol, gg2ll_Init'
  470. !print *, 'frac=',frac
  471. !print *, ' 1:', west1, east1, south1, north1
  472. !print *, ' 2:', west2, east2, south2, north2
  473. ncov = gg2ll%ncov(i,j) + 1
  474. gg2ll%ncov(i,j) = ncov
  475. gg2ll%indx(i,j,ncov) = ggi%i1(gj)-1 + gi
  476. gg2ll%frac(i,j,ncov) = 1.0
  477. else
  478. print *, 'ERROR in module grid_interpol, gg2ll_Init'
  479. print *, 'frac=',frac
  480. print *, ' 1:', west1, east1, south1, north1
  481. print *, ' 2:', west2, east2, south2, north2
  482. stop
  483. end if
  484. if ( gi == gi2 ) exit
  485. gi = gi + 1
  486. if ( gi == nlon+1 ) gi = 1
  487. end do
  488. end do
  489. end do
  490. end do
  491. ! store cell area's
  492. allocate( gg2ll%A_gg(ggi%np) )
  493. call AreaOper( ggi, gg2ll%A_gg, '=', 'm2' )
  494. allocate( gg2ll%A_ll(lli%nlon,lli%nlat) )
  495. call AreaOper( lli, gg2ll%A_ll, '=', 'm2', status )
  496. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  497. ! ok
  498. status = 0
  499. end subroutine gg2ll_Init
  500. ! ***
  501. subroutine gg2ll_Done( gg2ll )
  502. ! --- in/out ---------------------------
  503. type(Tgg2llFracs), intent(inout) :: gg2ll
  504. ! --- begin ----------------------------
  505. ! deallocate arrays
  506. deallocate( gg2ll%ncov )
  507. deallocate( gg2ll%indx )
  508. deallocate( gg2ll%frac )
  509. deallocate( gg2ll%A_gg )
  510. deallocate( gg2ll%A_ll )
  511. end subroutine gg2ll_Done
  512. ! ***
  513. !
  514. ! ncov(i,j)
  515. ! ll(i,j) = sum gg(indx(i,j,k)) * frac(i,j,k)
  516. ! k=1
  517. !
  518. subroutine gg2ll_FracSum( gg2ll, gg, ll, status, key )
  519. ! --- in/out ---------------------------
  520. type(Tgg2llFracs), intent(in) :: gg2ll
  521. real, intent(in) :: gg(:)
  522. real, intent(out) :: ll(:,:)
  523. integer, intent(out) :: status
  524. character(len=*), intent(in), optional :: key
  525. ! --- const ----------------------------------
  526. character(len=*), parameter :: rname = mname//'/gg2ll_FracSum'
  527. ! --- local ----------------------------
  528. character(len=10) :: the_key
  529. integer :: i, j, k
  530. integer :: ncov, indx
  531. real :: fac
  532. ! --- begin ----------------------------
  533. the_key = 'none'
  534. if ( present(key) ) the_key = key
  535. if ( any(shape(gg2ll%ncov)/=shape(ll)) ) then
  536. write (*,'("ERROR - shapes of ll and gg2ll do not match:")')
  537. write (*,'("ERROR - ll : ",2i4)') shape(ll)
  538. write (*,'("ERROR - gg2ll : ",2i4)') shape(gg2ll%ncov)
  539. write (*,'("ERROR in ",a)') rname; status=1; return
  540. end if
  541. if ( minval(gg2ll%indx)<0 .or. maxval(gg2ll%indx)>size(gg) ) then
  542. write (*,'("ERROR - indices of gg array in gg2ll out of range:")')
  543. write (*,'("ERROR - gg : 1 - ",i4)') size(gg)
  544. write (*,'("ERROR - gg2ll : ",i4," - ",i4)') minval(gg2ll%indx), maxval(gg2ll%indx)
  545. write (*,'("ERROR in ",a)') rname; status=1; return
  546. end if
  547. if ( minval(gg2ll%frac)<0.0 .or. maxval(gg2ll%frac)>1.0 ) then
  548. write (*,'("ERROR - fraction in gg2ll out of range:")')
  549. write (*,'("ERROR - gg2ll: ",i4," - ",i4)') minval(gg2ll%frac), maxval(gg2ll%frac)
  550. write (*,'("ERROR in ",a)') rname; status=1; return
  551. end if
  552. ll = 0.0
  553. do j = 1, gg2ll%nlat
  554. do i = 1, gg2ll%nlon
  555. ncov = gg2ll%ncov(i,j)
  556. if ( ncov > 0 ) then
  557. do k = 1, ncov
  558. indx = gg2ll%indx(i,j,k)
  559. select case ( the_key )
  560. case ( 'none' )
  561. fac = 1.0
  562. case ( 'area-aver', 'area-sum' )
  563. fac = gg2ll%A_gg(indx)
  564. case default
  565. write (*,'("ERROR - key `",a,"` not supported")') trim(the_key)
  566. write (*,'("ERROR in ",a)') rname; status=1; return
  567. end select
  568. ll(i,j) = ll(i,j) + gg(indx) * fac * gg2ll%frac(i,j,k)
  569. end do
  570. end if
  571. select case ( the_key )
  572. case ( 'none', 'area-sum' )
  573. ! nothing to be done
  574. case ( 'area-aver' )
  575. ll(i,j) = ll(i,j) / gg2ll%A_ll(i,j)
  576. case default
  577. write (*,'("ERROR - key `",a,"` not supported")') trim(the_key)
  578. write (*,'("ERROR in ",a)') rname; status=1; return
  579. end select
  580. end do
  581. end do
  582. ! ok
  583. status = 0
  584. end subroutine gg2ll_FracSum
  585. ! *************************************************************
  586. !
  587. ! Determine fraction of gg cell that covers a ll cell.
  588. !
  589. ! Returns three arrays:
  590. !
  591. ! integer :: ncov(im,jm)
  592. ! integer :: indx(im,jm,max_nconv)
  593. ! real :: frac(im,jm,max_nconv)
  594. !
  595. ! For a gg cell 'k', 'ncov(k)' gives the number of ll cells covering it.
  596. ! Their ll indices are stored in : ii(k,1:ncov(k)), jj(k,1:ncov(k)) ;
  597. ! corresponding fractions are in : frac(k,1:ncov(k)) .
  598. !
  599. subroutine ll2gg_Init( ll2gg, lli, ggi, status )
  600. use num, only : Interval
  601. use grid_tools, only : pi, ll_area_frac
  602. use grid_type_gg, only : TggGridInfo, AreaOper
  603. use grid_type_ll, only : TllGridInfo, AreaOper
  604. ! --- in/out ---------------------------
  605. type(Tll2ggFracs), intent(out) :: ll2gg
  606. type(TllGridInfo), intent(in) :: lli
  607. type(TggGridInfo), intent(in) :: ggi
  608. integer, intent(out) :: status
  609. ! --- const ------------------------------------
  610. character(len=*), parameter :: rname = mname//'/ll2gg_Init'
  611. ! --- local ----------------------------
  612. integer :: max_ncov_lon, max_ncov_lat, max_ncov
  613. integer :: gi, gi1, gi2
  614. integer :: gj, gj1, gj2
  615. integer :: li, li1, li2
  616. integer :: lj, lj1, lj2
  617. real :: west2, east2, south2, north2
  618. real :: west1, east1, south1, north1
  619. integer :: iflag
  620. integer :: gp
  621. real :: frac
  622. integer :: ncov
  623. ! --- begin ----------------------------
  624. ! save dimension
  625. ll2gg%nlon = lli%nlon
  626. ll2gg%nlat = lli%nlat
  627. ll2gg%np = ggi%np
  628. ! estimate maximum number of ll cells covering a gg cell:
  629. max_ncov_lon = ceiling(maxval(ggi%dlon)/lli%dlon)
  630. max_ncov_lat = ceiling(maxval(ggi%dlat)/lli%dlat)
  631. max_ncov = (max_ncov_lon+1) * (max_ncov_lat+1)
  632. ! allocate arrays
  633. allocate( ll2gg%ncov(ggi%np) )
  634. allocate( ll2gg%ii(ggi%np,max_ncov) )
  635. allocate( ll2gg%jj(ggi%np,max_ncov) )
  636. allocate( ll2gg%ff(ggi%np,max_ncov) )
  637. ! zero by default:
  638. ll2gg%ncov = 0
  639. ll2gg%ii = 0
  640. ll2gg%jj = 0
  641. ll2gg%ff = 0.0
  642. ! index in gg arrays:
  643. gp = 0
  644. ! row range in ll grid:
  645. lj1 = 0
  646. lj2 = 0
  647. ! loop over gg rows:
  648. do gj = 1, ggi%nlat
  649. ! extract north/south boundaries of gg cell:
  650. north2 = ggi%blat(gj-1) ! [-pi,pi]
  651. south2 = ggi%blat(gj) ! [-pi,pi]
  652. ! search ll rows including north and south gg lat;
  653. call Interval( lli%blat, south2, lj1, iflag )
  654. if ( iflag /= 0 ) stop 'BUG IN ll2gg_Init : wrong iflag lj1'
  655. call Interval( lli%blat, north2, lj2, iflag )
  656. if ( iflag /= 0 ) stop 'BUG IN ll2gg_Init : wrong iflag lj2'
  657. ! loop over cells in row:
  658. do gi = 1, ggi%nlon(gj)
  659. ! next index in 1d row ...
  660. gp = gp + 1
  661. ! set east/west boundaries of gg cell:
  662. west2 = (gi-1.5) * ggi%dlon(gj) ! [0,2pi]
  663. east2 = (gi-0.5) * ggi%dlon(gj) ! [0,2pi]
  664. ! loop over ll lat rows:
  665. do lj = lj1, lj2
  666. ! search ll cells including west and east bound of gg cell
  667. if ( west2 > lli%blon(lli%nlon) ) then
  668. call Interval( lli%blon, west2-2*pi, li1, iflag )
  669. else
  670. call Interval( lli%blon, west2 , li1, iflag )
  671. end if
  672. if ( iflag /= 0 ) then
  673. print *, 'lli%blon=', lli%blon
  674. print *, 'west2=',west2
  675. print *, 'iflag=',iflag
  676. stop 'BUG IN ll2gg_Init : wrong iflag li1'
  677. end if
  678. if ( east2 > lli%blon(lli%nlon) ) then
  679. call Interval( lli%blon, east2-2*pi, li2, iflag )
  680. else
  681. call Interval( lli%blon, east2 , li2, iflag )
  682. end if
  683. if ( iflag /= 0 ) then
  684. print *, 'lli%blon=', lli%blon
  685. print *, 'east2=',east2
  686. print *, 'east2-2pi=',east2-2*pi
  687. stop 'BUG IN ll2gg_Init : wrong iflag li2'
  688. end if
  689. ! loop over ll lon cels:
  690. li = li1
  691. do
  692. ! extract boundaries of ll cell:
  693. west1 = lli%blon(li-1) ! [-pi,pi]
  694. east1 = lli%blon(li ) ! [-pi,pi]
  695. south1 = lli%blat(lj-1) ! [-pi,pi]
  696. north1 = lli%blat(lj ) ! [-pi,pi]
  697. ! shift if completely left from gg cell:
  698. if ( east1 < west2 ) then
  699. west1 = west1 + 2*pi
  700. east1 = east1 + 2*pi
  701. end if
  702. ! determine covarage fraction:
  703. frac = ll_area_frac( west1, east1, south1, north1, &
  704. west2, east2, south2, north2 )
  705. ! fill fraction:
  706. if ( frac > 0.0 .and. frac <= 1.0 ) then
  707. ncov = ll2gg%ncov(gp) + 1
  708. ll2gg%ncov(gp) = ncov
  709. ll2gg%ii(gp,ncov) = li
  710. ll2gg%jj(gp,ncov) = lj
  711. ll2gg%ff(gp,ncov) = frac
  712. else if ( abs(frac) < 1.0e-4 ) then
  713. ! almost no coverage ...
  714. else if ( abs(frac-1.0) < 1.0e-4 ) then
  715. !print *, 'WARNING in module grid_interpol, ll2gg_Init'
  716. !print *, 'frac=',frac
  717. !print *, ' 1:', west1, east1, south1, north1
  718. !print *, ' 2:', west2, east2, south2, north2
  719. ncov = ll2gg%ncov(gp) + 1
  720. ll2gg%ncov(gp) = ncov
  721. ll2gg%ii(gp,ncov) = li
  722. ll2gg%jj(gp,ncov) = lj
  723. ll2gg%ff(gp,ncov) = 1.0
  724. else
  725. print *, 'ERROR in module grid_interpol, ll2gg_Init'
  726. print *, 'frac=',frac
  727. print *, ' 1:', west1, east1, south1, north1
  728. print *, ' 2:', west2, east2, south2, north2
  729. stop
  730. end if
  731. if ( li == li2 ) exit
  732. li = li + 1
  733. if ( li == lli%nlon+1 ) li = 1
  734. end do ! ll i
  735. end do ! ll j
  736. end do ! gg i
  737. end do ! gg j
  738. ! store cell area's
  739. allocate( ll2gg%A_gg(ggi%np) )
  740. call AreaOper( ggi, ll2gg%A_gg, '=', 'm2' )
  741. !
  742. allocate( ll2gg%A_ll(lli%nlon,lli%nlat) )
  743. call AreaOper( lli, ll2gg%A_ll, '=', 'm2', status )
  744. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  745. ! ok
  746. status = 0
  747. end subroutine ll2gg_Init
  748. ! ***
  749. subroutine ll2gg_Done( ll2gg )
  750. ! --- in/out ---------------------------
  751. type(Tll2ggFracs), intent(inout) :: ll2gg
  752. ! --- begin ----------------------------
  753. ! deallocate arrays
  754. deallocate( ll2gg%ncov )
  755. deallocate( ll2gg%ii )
  756. deallocate( ll2gg%jj )
  757. deallocate( ll2gg%ff )
  758. deallocate( ll2gg%A_gg )
  759. deallocate( ll2gg%A_ll )
  760. end subroutine ll2gg_Done
  761. ! ***
  762. !
  763. ! ncov(p)
  764. ! gg(p) = sum ll(ii(p,k),jj(p,k)) * ff(p,k)
  765. ! k=1
  766. !
  767. subroutine ll2gg_FracSum( ll2gg, ll, gg, key )
  768. ! --- in/out ---------------------------
  769. type(Tll2ggFracs), intent(in) :: ll2gg
  770. real, intent(in) :: ll(:,:)
  771. real, intent(out) :: gg(:)
  772. character(len=*), intent(in), optional :: key
  773. ! --- local ----------------------------
  774. character(len=10) :: the_key
  775. integer :: gp, i, j, k
  776. integer :: ncov
  777. real :: fac
  778. ! --- begin ----------------------------
  779. the_key = 'none'
  780. if ( present(key) ) the_key = key
  781. if ( size(ll2gg%ncov) /= size(gg) ) then
  782. print *, 'shapes of gg and ll2gg do not match:'
  783. print *, ' ll : ', size(gg)
  784. print *, ' ll2gg: ', size(ll2gg%ncov)
  785. stop 'FATAL ERROR IN ll2gg_FracSum'
  786. end if
  787. if ( minval(ll2gg%ii)<0 .or. maxval(ll2gg%ii)>size(ll,1) ) then
  788. print *, 'indices of ll array in ll2gg out of range:'
  789. print *, ' ll i : 1 - ', size(ll,1)
  790. print *, ' ll2gg: ', minval(ll2gg%ii),'-',maxval(ll2gg%ii)
  791. stop 'FATAL ERROR IN ll2gg_FracSum'
  792. end if
  793. if ( minval(ll2gg%jj)<0 .or. maxval(ll2gg%jj)>size(ll,2) ) then
  794. print *, 'indices of ll array in ll2gg out of range:'
  795. print *, ' ll j : 1 - ', size(ll,2)
  796. print *, ' ll2gg: ', minval(ll2gg%jj),'-',maxval(ll2gg%jj)
  797. stop 'FATAL ERROR IN ll2gg_FracSum'
  798. end if
  799. if ( minval(ll2gg%ff)<0.0 .or. maxval(ll2gg%ff)>1.0 ) then
  800. print *, 'fraction in ll2gg out of range:'
  801. print *, ' ll2gg: ', minval(ll2gg%ff),'-',maxval(ll2gg%ff)
  802. stop 'FATAL ERROR IN ll2gg_FracSum'
  803. end if
  804. ! init to zero:
  805. gg = 0.0
  806. ! loop over gg
  807. do gp = 1, ll2gg%np
  808. ncov = ll2gg%ncov(gp)
  809. if ( ncov > 0 ) then
  810. do k = 1, ncov
  811. i = ll2gg%ii(gp,k)
  812. j = ll2gg%jj(gp,k)
  813. select case ( the_key )
  814. case ( 'none' )
  815. fac = 1.0
  816. case ( 'area-aver', 'area-sum' )
  817. fac = ll2gg%A_ll(i,j)
  818. case default
  819. print *, 'Sorry, key "'//trim(the_key)//'" not supported.'
  820. stop 'BUG IN ll2gg_FracSum'
  821. end select
  822. !if (abs(ll(i,j))>0.0) then
  823. !print *, gp,':',gg(gp) ,'+', ll(i,j) ,'*', fac ,'*', ll2gg%ff(gp,k),'=',gg(gp) + ll(i,j) * fac * ll2gg%ff(gp,k)
  824. !endif
  825. gg(gp) = gg(gp) + ll(i,j) * fac * ll2gg%ff(gp,k)
  826. end do
  827. end if
  828. select case ( the_key )
  829. case ( 'none', 'area-sum' )
  830. ! nothing to be done
  831. !if (abs(gg(gp))>0.0) then
  832. !print *, ' '
  833. !endif
  834. case ( 'area-aver' )
  835. gg(gp) = gg(gp) / ll2gg%A_gg(gp)
  836. !if (abs(gg(gp))>0.0) then
  837. !print *, gp,':',gg(gp),'/',ll2gg%A_gg(gp),'=',gg(gp) / ll2gg%A_gg(gp)
  838. !print *, ' '
  839. !endif
  840. case default
  841. print *, 'Sorry, key "'//trim(the_key)//'" not supported.'
  842. stop 'BUG IN ll2gg_FracSum'
  843. end select
  844. end do ! gg cells
  845. end subroutine ll2gg_FracSum
  846. ! *************************************************************
  847. ! gg to ll
  848. subroutine Interpol_gg_ll( ggi, gg, lli, ll, status )
  849. use Binas, only : deg2rad
  850. use Num, only : Interp_Lin, CircInterp_Lin
  851. use Grid_Type_gg, only : TggGridInfo, Check
  852. use Grid_Type_ll, only : TllGridInfo, Check
  853. ! --- in/out -------------------------------
  854. type(TggGridInfo), intent(in) :: ggi
  855. real, intent(in) :: gg(ggi%np)
  856. type(TllGridInfo), intent(in) :: lli
  857. real, intent(out) :: ll(lli%im,lli%jm)
  858. integer, intent(out) :: status
  859. ! --- const ----------------------------------
  860. character(len=*), parameter :: rname = mname//'/Interpol_gg_ll'
  861. ! --- local --------------------------------
  862. integer :: nlon, nlon_max
  863. integer :: nlat
  864. integer :: i1, im
  865. real, allocatable :: lons(:)
  866. real, allocatable :: row(:)
  867. real, allocatable :: gl(:,:)
  868. real, allocatable :: gl_lat(:)
  869. integer :: i, j
  870. integer :: j1, jm
  871. integer :: ilast
  872. ! --- begin --------------------------------
  873. call Check( ggi, gg )
  874. call Check( lli, 'n', ll, status )
  875. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  876. nlat = ggi%nlat
  877. nlon_max = maxval(ggi%nlon)
  878. ! ll in lon, gg in lat
  879. allocate( gl(size(ll,1),0:nlat+1) ); gl = 0.0
  880. ! latitudes from south->north
  881. allocate( gl_lat(0:nlat+1) )
  882. gl_lat(0) = -90.0 * deg2rad ! south pole (rad)
  883. do j = 1, nlat
  884. gl_lat(nlat+1-j) = ggi%lat(j) ! rad
  885. end do
  886. gl_lat(nlat+1) = 90.0 * deg2rad ! north pole (rad)
  887. ! row in gg grid; doubled from -360.0 to 360.0
  888. allocate( lons(nlon_max) ); lons = 0.0
  889. allocate( row(nlon_max) ) ; row = 0.0
  890. ! select first and last Gaussian lat:
  891. j1 = nlat
  892. do
  893. if ( (j1 == 1) .or. (ggi%lat(j1) > maxval(lli%lat)) ) exit
  894. j1 = j1 - 1
  895. end do
  896. jm = 1
  897. do
  898. if ( (jm == nlat) .or. (ggi%lat(jm) < minval(lli%lat)) ) exit
  899. jm = jm + 1
  900. end do
  901. ! loop over Gaussian latitudes, from north to south!
  902. do j = j1, jm
  903. ! number of lon points at this latitude:
  904. nlon = ggi%nlon(j)
  905. ! start and end indices in grid point array
  906. i1 = ggi%i1(j)
  907. im = ggi%im(j)
  908. ! lons in [0,2pi)
  909. do i = 1, nlon
  910. lons(i) = (i-1)*360.0/nlon
  911. end do
  912. lons(1:nlon) = lons(1:nlon) * deg2rad
  913. ! grid values (doubled)
  914. row(1:nlon) = gg(i1:im)
  915. ! set north pole (j=1 in gg, j=nlat+1 in gl)
  916. if ( j == 1 ) then
  917. gl(:,nlat+1) = sum(row(1:nlon))/nlon
  918. end if
  919. ! set south pole
  920. if ( j == nlat ) then
  921. gl(:,0) = sum(row(1:nlon))/nlon
  922. end if
  923. ! Interpolate over lon (circular arrays);
  924. ! swap lats to ensure south -> north:
  925. ilast = 1
  926. do i = 1, lli%im
  927. call CircInterp_Lin( lons(1:nlon), 360.0*deg2rad, row(1:nlon), &
  928. lli%lon(i), gl(i,nlat+1-j), ilast, status )
  929. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  930. end do
  931. end do
  932. ! Linear interpolation over lat:
  933. ilast = 1
  934. do j = 1, lli%jm
  935. do i = 1, lli%im
  936. call Interp_Lin( gl_lat, gl(i,:), lli%lat(j), ll(i,j), ilast, status )
  937. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  938. end do
  939. end do
  940. ! free memory
  941. deallocate( gl )
  942. deallocate( gl_lat )
  943. deallocate( lons )
  944. deallocate( row )
  945. ! ok
  946. status = 0
  947. end subroutine Interpol_gg_ll
  948. ! =========================================================
  949. ! ===
  950. ! === interpolate from ll
  951. ! ===
  952. ! =========================================================
  953. ! ll to gg
  954. !
  955. ! First interpol in lat direction to Gaussian lats,
  956. ! then interpolate in lon direction.
  957. ! NOTE: MIPSpro compiler gives errors if argument names are the
  958. ! same as used for Interpol_gg_ll ...
  959. subroutine Interpol_ll_gg( lli, ll, xggi, xgg, status )
  960. use Binas, only : deg2rad
  961. use Num, only : Interp_Lin, CircInterp_Lin
  962. use Grid_Type_gg, only : TggGridInfo, Check
  963. use Grid_Type_ll, only : TllGridInfo, Check
  964. ! --- in/out -------------------------------
  965. type(TllGridInfo), intent(in) :: lli
  966. real, intent(in) :: ll(lli%im,lli%jm)
  967. type(TggGridInfo), intent(in) :: xggi
  968. real, intent(out) :: xgg(1:xggi%np)
  969. integer, intent(out) :: status
  970. ! --- const ----------------------------------
  971. character(len=*), parameter :: rname = mname//'/Interpol_ll_gg'
  972. ! --- local --------------------------------
  973. integer :: nlon
  974. integer :: nlat
  975. integer :: i, j
  976. integer :: i0
  977. integer :: ilast
  978. real :: dlon_deg
  979. real :: glat, glon
  980. real :: period
  981. real, allocatable :: row(:)
  982. ! --- begin --------------------------------
  983. call Check( xggi, xgg )
  984. call Check( lli, 'n', ll, status )
  985. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  986. nlat = xggi%nlat
  987. ! ll grid interpolated to gaussian lat:
  988. allocate( row(1:lli%im) )
  989. ! loop over Gaussian latitudes:
  990. do j = 1, nlat
  991. ! number of lon points at this latitude:
  992. nlon = xggi%nlon(j)
  993. ! current Gaussian lat
  994. glat = xggi%lat(j)
  995. !! error if ll grid does not cover this gaussian lat
  996. !if ( glat < minval(lli%lat) .or. glat > maxval(lli%lat) ) then
  997. ! write (*,'("ERROR - ll grid does not cover current gg latitude:")')
  998. ! write (*,'("ERROR - ll lat range : ",2f12.4)') minval(lli%lat), maxval(lli%lat)
  999. ! write (*,'("ERROR - gg latitude : ",f12.4)') glat
  1000. ! write (*,'("ERROR in ",a)') rname; status=1
  1001. !end if
  1002. ! * interpolate ll grid to this gaussian lat:
  1003. ! check for direction of ll lats:
  1004. if ( lli%lat(1) < lli%lat(lli%jm) ) then
  1005. ! 'normal' : grid stored from south to north
  1006. ilast = 1
  1007. do i = 1, lli%im
  1008. call Interp_Lin( lli%lat, ll(i,:), glat, row(i), ilast, status )
  1009. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1010. end do
  1011. else
  1012. ! grid stored from north to south; fake with negative lats:
  1013. ilast = 1
  1014. do i = 1, lli%im
  1015. call Interp_Lin( -lli%lat, ll(i,:), -glat, row(i), ilast, status )
  1016. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1017. end do
  1018. end if
  1019. ! base index of current row in xgg array:
  1020. i0 = xggi%i1(j)-1
  1021. ! interpolate from ll lons to lons in this xgg row:
  1022. period = 360.0*deg2rad
  1023. ilast = 1
  1024. do i = 1, nlon
  1025. ! curren lon in xgg grid:
  1026. glon = (i-1)*xggi%dlon(j)
  1027. ! periodic interpolation:
  1028. call CircInterp_Lin( lli%lon, period, row, glon, xgg(i0+i), ilast, status )
  1029. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1030. end do
  1031. end do
  1032. ! free memory
  1033. deallocate( row )
  1034. ! ok
  1035. status = 0
  1036. end subroutine Interpol_ll_gg
  1037. ! =========================================================
  1038. ! ===
  1039. ! === area average gg
  1040. ! ===
  1041. ! =========================================================
  1042. subroutine Aver_gg_ll( ggi, gg, lli, ll )
  1043. use Binas, only : deg2rad
  1044. use Num, only : IntervalQuad_Lin, IntervalQuad_Cos_Lin
  1045. use Grid_Type_gg, only : TggGridInfo, Check
  1046. use Grid_Type_ll, only : TllGridInfo, Check
  1047. ! --- in/out -------------------------------
  1048. type(TggGridInfo), intent(in) :: ggi
  1049. real, intent(in) :: gg(ggi%np)
  1050. type(TllGridInfo), intent(in) :: lli
  1051. real, intent(out) :: ll(lli%im,lli%jm)
  1052. integer :: status
  1053. ! --- const ----------------------------------
  1054. character(len=*), parameter :: rname = mname//'/ Aver_gg_ll'
  1055. ! --- local --------------------------------
  1056. integer :: nlon, nlon_max
  1057. integer :: nlat
  1058. integer :: i1, im
  1059. real, allocatable :: lons(:)
  1060. real, allocatable :: row(:)
  1061. real, allocatable :: gl(:,:)
  1062. real, allocatable :: gl_lat(:)
  1063. real, allocatable :: gl_dim2(:)
  1064. integer :: i, j
  1065. integer :: ilast
  1066. ! --- begin --------------------------------
  1067. call Check( ggi, gg )
  1068. call Check( lli, 'n', ll, status )
  1069. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; stop; end if
  1070. nlat = ggi%nlat
  1071. nlon_max = maxval(ggi%nlon)
  1072. ! ll in lon, gg in lat
  1073. allocate( gl(size(ll,1),0:nlat+1) )
  1074. allocate( gl_dim2(0:nlat+1) )
  1075. ! latitudes from south->north
  1076. allocate( gl_lat(0:nlat+1) )
  1077. ! row in gg grid; doubled from -360.0 to 360.0
  1078. allocate( lons(2*nlon_max) )
  1079. allocate( row(2*nlon_max) )
  1080. ! loop over Gaussian latitudes, from north to south!
  1081. do j = 1, nlat
  1082. ! number of lon points at this latitude:
  1083. nlon = ggi%nlon(j)
  1084. ! start and end indices in grid point array
  1085. i1 = ggi%i1(j)
  1086. im = ggi%im(j)
  1087. ! lons from -360 to 360
  1088. do i = 1, nlon
  1089. lons(i) = -360.0 + (i-1)*360.0/nlon
  1090. lons(nlon+i) = (i-1)*360.0/nlon
  1091. end do
  1092. lons(1:2*nlon) = lons(1:2*nlon) * deg2rad
  1093. ! grid values (doubled)
  1094. row(1:2*nlon) = (/ gg(i1:im), gg(i1:im) /)
  1095. ! integrate over dlon assuming linear interpolation;
  1096. ! swap lats to ensure south -> north;
  1097. ! result in [g] rad
  1098. ilast = 1
  1099. do i = 1, lli%im
  1100. call IntervalQuad_Lin( lons(1:2*nlon), row(1:2*nlon), &
  1101. lli%blon(i-1), lli%blon(i), gl(i,nlat+1-j), &
  1102. ilast, status )
  1103. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; stop; end if
  1104. end do
  1105. gl_lat(nlat+1-j) = ggi%lat(j) ! rad
  1106. ! take care of poles (reverse lats);
  1107. ! set polar value to average of surrounding points:
  1108. if ( j == 1 ) then
  1109. ! north pole
  1110. gl_lat(nlat+1) = 90.0 * deg2rad
  1111. gl(:,nlat+1) = lli%dlon * sum(gg(i1:im))/(im-i1+1)
  1112. end if
  1113. if ( j == nlat ) then
  1114. ! south pole
  1115. gl_lat(0) = -90.0 * deg2rad
  1116. gl(:,0) = lli%dlon * sum(gg(i1:im))/(im-i1+1)
  1117. end if
  1118. end do
  1119. ! integrate over dlat assuming linear interpolation;
  1120. ! weight with cos(lat) to account for smaller cells near the poles,
  1121. ! result in [g] rad^2
  1122. ilast = 1
  1123. do j = 1, lli%jm
  1124. do i = 1, lli%im
  1125. !>>> bsf15k bug fix >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  1126. !call IntervalQuad_Cos_Lin( gl_lat, gl(i,:), lli%blat(j-1), lli%blat(j), ll(i,j), ilast )
  1127. gl_dim2 = gl(i,:)
  1128. call IntervalQuad_Cos_Lin( gl_lat, gl_dim2, lli%blat(j-1), lli%blat(j), &
  1129. ll(i,j), ilast, status )
  1130. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; stop; end if
  1131. !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1132. end do
  1133. end do
  1134. ! area average; lli%area(j) for cells in row j in rad^2
  1135. do j = 1, lli%jm
  1136. ll(:,j) = ll(:,j) / lli%area(j)
  1137. end do
  1138. ! free memory
  1139. deallocate( gl )
  1140. deallocate( gl_dim2 )
  1141. deallocate( gl_lat )
  1142. deallocate( lons )
  1143. deallocate( row )
  1144. end subroutine Aver_gg_ll
  1145. ! =========================================================
  1146. ! ===
  1147. ! === area average sh
  1148. ! ===
  1149. ! =========================================================
  1150. ! Deterimine spectral truncation for area integration.
  1151. integer function ShTruncation( T, dlon, dlat )
  1152. ! --- in/out --------------------------
  1153. integer, intent(in) :: T
  1154. real, intent(in) :: dlon, dlat ! deg
  1155. ! --- begin --------------------------
  1156. !print *, 'WARNING - spectral fields are not truncated ...'
  1157. ! o no truncation:
  1158. ShTruncation = T
  1159. ! o choose minium T based on grid resolution:
  1160. !ShTruncation = min( T, ceiling( (360.0/min(dlon,dlat))/2 - 1 ) )
  1161. !print *, 'WARNING - adhoc truncation of spectral fields for testing ...'
  1162. !ShTruncation = 21
  1163. end function ShTruncation
  1164. ! Deterimine refinement for averaging spectral fields
  1165. ! over distance 'cellspacing' in degrees.
  1166. ! Cell is divided in number of intervals returned by this function.
  1167. integer function ShRefinement( T, cellspacing )
  1168. ! --- in/out ----------------------------------------
  1169. integer, intent(in) :: T
  1170. real, intent(in) :: cellspacing
  1171. ! --- local -----------------------------------------
  1172. real :: shres
  1173. integer :: nstep
  1174. ! --- beging -----------------------------------------
  1175. ! o fixec number of intervals per cell
  1176. !ShRefinement = 20
  1177. !ShRefinement = 1
  1178. !ShRefinement = nint( cellspacing * 2 )
  1179. !write (*,'(" WARNING: ShRefinement = ",i4)') ShRefinement
  1180. ! o resultion specified by spectral truncation
  1181. ! truncation T <--> resolution 360.0/(2(T+1))
  1182. ! nstep points within resolution implied by T
  1183. shres = 360.0 / (2*(T+1))
  1184. nstep = 2
  1185. ShRefinement = max( 1, ceiling(nstep*cellspacing/shres) )
  1186. end function ShRefinement
  1187. ! ***********************************
  1188. subroutine Aver_sh_ll( sh, lli, ll, status )
  1189. use grid_tools, only : deg2rad, pi
  1190. use Num, only : IntervalQuad_Lin, IntervalQuad_Cos_Lin
  1191. use Grid_Type_sh, only : TshGrid, Check, Eval_Lons
  1192. use Grid_Type_ll, only : TllGridInfo, Check
  1193. ! --- in/out -------------------------------
  1194. type(TshGrid), intent(in) :: sh
  1195. type(TllGridInfo), intent(in) :: lli
  1196. real, intent(out) :: ll(lli%im,lli%jm)
  1197. integer, intent(out) :: status
  1198. ! --- const ----------------------------------
  1199. character(len=*), parameter :: rname = mname//'/Aver_sh_ll'
  1200. ! --- local --------------------------------
  1201. integer :: i, j, jf
  1202. integer :: ilast
  1203. integer :: nlon_fine
  1204. integer :: T
  1205. integer :: refinement_i, refinement_j
  1206. real, allocatable :: llgrid(:)
  1207. real, allocatable :: lons_fine(:), row_fine(:)
  1208. real, allocatable :: llf(:,:), lat(:)
  1209. ! --- begin --------------------------------
  1210. call Check( sh )
  1211. T = sh%T
  1212. call Check( lli, 'n', ll, status )
  1213. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; stop; end if
  1214. ! determine refinement (5 points per sh resolution)
  1215. refinement_i = ShRefinement( T, lli%dlon_deg )
  1216. refinement_j = ShRefinement( T, lli%dlon_deg )
  1217. ! number of lons in fine grid on complete circle:
  1218. nlon_fine = 360.0/lli%dlon_deg * refinement_i
  1219. ! store evaluation of spectral field:
  1220. allocate( llgrid(nlon_fine) )
  1221. ! lons on complete circle from westb+[0,2pi)
  1222. allocate( row_fine(0:nlon_fine) )
  1223. allocate( lons_fine(0:nlon_fine) )
  1224. do i = 0, nlon_fine
  1225. lons_fine(i) = i*2*pi/nlon_fine
  1226. end do
  1227. lons_fine = lli%blon(0) + lons_fine
  1228. ! ll in lon, fine in lat
  1229. allocate( llf(lli%im,0:refinement_j) )
  1230. allocate( lat(0:refinement_j) )
  1231. ! loop over latitudes in ll grid:
  1232. do j = 1, lli%jm
  1233. ! loop over latitudes in fine grid:
  1234. do jf = 0, refinement_j
  1235. ! latitude in fine grid:
  1236. lat(jf) = lli%blat(j-1) + jf*lli%dlat/refinement_j
  1237. ! evaluate row:
  1238. ! (oposite latitudes, but use only one)
  1239. call Eval_Lons( llgrid, sh, lat(jf), &
  1240. nlon_fine, lons_fine(0), nlon_fine, status )
  1241. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1242. ! copy result, cyclic:
  1243. row_fine = (/ llgrid(:), llgrid(1) /)
  1244. ! integral in lon direction assuming linear interpolation,
  1245. ! result in [sh] rad
  1246. ilast = 1
  1247. do i = 1, lli%im
  1248. call IntervalQuad_Lin( lons_fine, row_fine, lli%blon(i-1), lli%blon(i), llf(i,jf), ilast, status )
  1249. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1250. end do
  1251. end do
  1252. ! integral in lat direction;
  1253. ! weight with cos(lat) to account for smaller cells near the poles,
  1254. ! result in [sh] rad^2
  1255. do i = 1, lli%im
  1256. ilast = 1
  1257. call IntervalQuad_Cos_Lin( lat, llf(i,:), lli%blat(j-1), lli%blat(j), ll(i,j), ilast, status )
  1258. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1259. end do
  1260. ! area average; lli%area(j) for cells in row j in rad^2
  1261. ll(:,j) = ll(:,j) / lli%area(j)
  1262. end do
  1263. ! free memory
  1264. deallocate( llgrid )
  1265. deallocate( lons_fine )
  1266. deallocate( row_fine )
  1267. deallocate( llf )
  1268. deallocate( lat )
  1269. end subroutine Aver_sh_ll
  1270. ! ===========================================================
  1271. !
  1272. ! key == 'aver'
  1273. !
  1274. ! int int F(k) dA / A
  1275. !
  1276. ! key == 'exp,aver'
  1277. !
  1278. ! int int exp(F(k)) dA / A
  1279. !
  1280. subroutine IntArea_shi_ll_f( key, shi, shc, lli, ll, status )
  1281. use grid_tools, only : deg2rad, pi
  1282. use Num, only : IntervalQuad_Lin, IntervalQuad_Cos_Lin
  1283. use Grid_Type_sh, only : TshGrid, TshGridInfo
  1284. use Grid_Type_sh, only : Init, Done, Check, Set, Truncate, SpN
  1285. use Grid_Type_sh, only : sh_Pnm, Eval_Lons
  1286. use Grid_Type_ll, only : TllGridInfo, Check
  1287. ! --- in/out -----------------------------------------
  1288. character(len=*), intent(in) :: key
  1289. type(TshGridInfo), intent(in) :: shi
  1290. complex, intent(in) :: shc(:)
  1291. type(TllGridInfo), intent(in) :: lli
  1292. real, intent(out) :: ll(lli%im,lli%jm)
  1293. integer, intent(out) :: status
  1294. ! --- const ----------------------------------
  1295. character(len=*), parameter :: rname = mname//'/IntArea_shi_ll_f'
  1296. ! --- local ------------------------------------------
  1297. integer :: i, j, jf
  1298. integer :: ilast
  1299. type(TshGrid) :: sh
  1300. integer :: Ttr
  1301. real, allocatable :: Pnm(:)
  1302. integer :: refinement_i, refinement_j
  1303. integer :: nlon_fine_360, nlon_fine
  1304. real, allocatable :: ff(:)
  1305. real, allocatable :: lons_fine(:), row_fine(:)
  1306. real, allocatable :: llf(:,:), lat(:)
  1307. real, allocatable :: llf_dim2(:)
  1308. !logical :: aver_to_prev
  1309. ! --- begin ------------------------------------------
  1310. ! store input in old type grid:
  1311. call Init( sh )
  1312. call Set( sh, shi%T, shc )
  1313. ! use truncation up to grid resolution:
  1314. Ttr = ShTruncation( shi%T, lli%dlon_deg, lli%dlat_deg )
  1315. call Truncate( sh, Ttr )
  1316. ! allocate space for legendre coeff:
  1317. allocate( Pnm(SpN(Ttr)) )
  1318. ! determine refinement (5 points per sh resolution)
  1319. refinement_i = ShRefinement( Ttr, lli%dlon_deg )
  1320. refinement_j = ShRefinement( Ttr, lli%dlat_deg )
  1321. ! number of lons in fine grid on complete circle:
  1322. nlon_fine_360 = 360.0/lli%dlon_deg * refinement_i
  1323. nlon_fine = lli%im * refinement_i
  1324. ! store evaluation of spectral field:
  1325. allocate( ff(0:nlon_fine) )
  1326. ! lons on arc westb+[0,..)
  1327. allocate( row_fine(0:nlon_fine) )
  1328. allocate( lons_fine(0:nlon_fine) )
  1329. do i = 0, nlon_fine
  1330. lons_fine(i) = i*2*pi/nlon_fine_360
  1331. end do
  1332. lons_fine = lli%blon(0) + lons_fine
  1333. ! ll in lon, fine in lat
  1334. allocate( llf(lli%im,0:refinement_j) )
  1335. allocate( llf_dim2(0:refinement_j) )
  1336. allocate( lat(0:refinement_j) )
  1337. ! loop over latitudes in ll grid:
  1338. !aver_to_prev = .false.
  1339. do j = 1, lli%jm
  1340. ! loop over latitudes in fine grid:
  1341. do jf = 0, refinement_j
  1342. ! latitude in fine grid:
  1343. lat(jf) = lli%blat(j-1) + jf*lli%dlat/refinement_j
  1344. !! southpole ?
  1345. !if ( abs(lat(jf) - (-pi/2)) < 1.0e-4 ) then
  1346. ! ! fill with average of next row
  1347. ! aver_to_prev = .true.
  1348. ! cycle
  1349. !end if
  1350. !
  1351. !! northpole ?
  1352. !if ( abs(lat(jf) - (pi/2)) < 1.0e-4 ) then
  1353. ! ! fill with average of previous row:
  1354. ! llf(:,jf) = sum(llf(:,jf-1)) / size(llf,1)
  1355. ! exit
  1356. !end if
  1357. ! evaluate Legendre functions:
  1358. call sh_Pnm( Pnm, Ttr, lat(jf), status )
  1359. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1360. ! evaluate rows:
  1361. call Eval_Lons( ff, sh, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, status )
  1362. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1363. ! combine fields:
  1364. select case ( key )
  1365. !
  1366. ! int int F(k) dA / A
  1367. !
  1368. case ( 'aver' )
  1369. row_fine = ff / lli%area(j)
  1370. !
  1371. ! int int exp(F(k)) dA / A
  1372. !
  1373. case ( 'exp,aver' )
  1374. row_fine = exp(ff) / lli%area(j)
  1375. !
  1376. ! error ...
  1377. !
  1378. case default
  1379. write (*,'("ERROR - unknown key `",a,"`")') trim(key)
  1380. write (*,'("ERROR in ",a)') rname; status=1; return
  1381. end select
  1382. ! integral in lon direction assuming linear interpolation,
  1383. ! result in [sh] rad
  1384. ilast = 1
  1385. do i = 1, lli%im
  1386. call IntervalQuad_Lin( lons_fine, row_fine, lli%blon(i-1), lli%blon(i), llf(i,jf), ilast, status )
  1387. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1388. end do
  1389. !! copy to southpole ..
  1390. !if ( (jf==1) .and. aver_to_prev ) then
  1391. ! llf(:,0) = sum(llf(:,1)) / size(llf,1)
  1392. ! aver_to_prev = .false.
  1393. !end if
  1394. end do ! loop over rows in fine grid
  1395. ! integral in lat direction;
  1396. ! weight with cos(lat) to account for smaller grid cells:
  1397. do i = 1, lli%im
  1398. ilast = 1
  1399. !call IntervalQuad_Cos_Lin( lat, llf(i,:,l), lli%blat(j-1), lli%blat(j), ll(i,j,l), ilast )
  1400. !>>> bsf15k bug fix >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  1401. llf_dim2 = llf(i,:)
  1402. call IntervalQuad_Cos_Lin( lat, llf_dim2, lli%blat(j-1), lli%blat(j), ll(i,j), ilast, status )
  1403. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1404. !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1405. end do
  1406. end do ! loop over rows
  1407. ! free memory
  1408. deallocate( Pnm )
  1409. deallocate( ff )
  1410. deallocate( lons_fine )
  1411. deallocate( row_fine )
  1412. deallocate( llf )
  1413. deallocate( llf_dim2 )
  1414. deallocate( lat )
  1415. call Done( sh )
  1416. end subroutine IntArea_shi_ll_f
  1417. ! ***
  1418. subroutine IntArea_sh_ll_f( key, F, lli, ll, status )
  1419. use grid_tools, only : deg2rad, pi
  1420. use Num, only : IntervalQuad_Lin, IntervalQuad_Cos_Lin
  1421. use Grid_Type_sh, only : TshGrid, Init, Done, SpN, sh_Pnm, Eval_Lons, Set, Check
  1422. use Grid_Type_ll, only : TllGridInfo, Check
  1423. ! --- in/out -----------------------------------------
  1424. character(len=*), intent(in) :: key
  1425. type(TshGrid), intent(in) :: F(:)
  1426. type(TllGridInfo), intent(in) :: lli
  1427. real, intent(out) :: ll(lli%im,lli%jm,size(F))
  1428. integer, intent(out) :: status
  1429. ! --- const --------------------------------
  1430. character(len=*), parameter :: rname = mname//'/IntArea_sh_ll_f'
  1431. ! --- local ------------------------------------------
  1432. integer :: i, j, jf
  1433. integer :: l, lm
  1434. integer :: ilast
  1435. integer :: T
  1436. type(TshGrid) :: sh
  1437. real, allocatable :: Pnm(:)
  1438. integer :: refinement_i, refinement_j
  1439. integer :: nlon_fine_360, nlon_fine
  1440. real, allocatable :: ff(:)
  1441. real, allocatable :: lons_fine(:), row_fine(:)
  1442. real, allocatable :: llf(:,:,:), lat(:)
  1443. real, allocatable :: llf_dim2(:)
  1444. ! --- begin ------------------------------------------
  1445. ! number of levels:
  1446. lm = size(F)
  1447. ! check arguments:
  1448. T = F(1)%T
  1449. do l = 2, lm
  1450. call Check( F(l), T )
  1451. end do
  1452. ! use truncation up to grid resolution:
  1453. T = ShTruncation( T, lli%dlon_deg, lli%dlat_deg )
  1454. call Init( sh, T )
  1455. ! allocate space for legendre coeff:
  1456. allocate( Pnm(SpN(T)) )
  1457. ! determine refinement (5 points per sh resolution)
  1458. refinement_i = ShRefinement( T, lli%dlon_deg )
  1459. refinement_j = ShRefinement( T, lli%dlat_deg )
  1460. ! number of lons in fine grid on complete circle:
  1461. nlon_fine_360 = 360.0/lli%dlon_deg * refinement_i
  1462. nlon_fine = lli%im * refinement_i
  1463. ! store evaluation of spectral field:
  1464. allocate( ff(0:nlon_fine) )
  1465. ! lons on arc westb+[0,..)
  1466. allocate( row_fine(0:nlon_fine) )
  1467. allocate( lons_fine(0:nlon_fine) )
  1468. do i = 0, nlon_fine
  1469. lons_fine(i) = i*2*pi/nlon_fine_360
  1470. end do
  1471. lons_fine = lli%blon(0) + lons_fine
  1472. ! ll in lon, fine in lat
  1473. allocate( llf(lli%im,0:refinement_j,lm) )
  1474. allocate( llf_dim2(0:refinement_j) )
  1475. allocate( lat(0:refinement_j) )
  1476. ! loop over latitudes in ll grid:
  1477. !aver_to_prev = .false.
  1478. do j = 1, lli%jm
  1479. ! loop over latitudes in fine grid:
  1480. do jf = 0, refinement_j
  1481. ! latitude in fine grid:
  1482. lat(jf) = lli%blat(j-1) + jf*lli%dlat/refinement_j
  1483. !! southpole ?
  1484. !if ( abs(lat(jf) - (-pi/2)) < 1.0e-4 ) then
  1485. ! ! fill with average of next row
  1486. ! aver_to_prev = .true.
  1487. ! cycle
  1488. !end if
  1489. !
  1490. !! northpole ?
  1491. !if ( abs(lat(jf) - (pi/2)) < 1.0e-4 ) then
  1492. ! ! fill with average of previous row:
  1493. ! do l = 1, lm
  1494. ! llf(:,jf,l) = sum(llf(:,jf-1,l)) / size(llf,1)
  1495. ! end do
  1496. ! exit
  1497. !end if
  1498. ! evaluate Legendre functions:
  1499. call sh_Pnm( Pnm, T, lat(jf), status )
  1500. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1501. ! evaluate rows:
  1502. do l = 1, lm
  1503. call Set( sh, T, F(l) )
  1504. call Eval_Lons( ff, sh, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, status )
  1505. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1506. ! combine fields:
  1507. select case ( key )
  1508. !
  1509. ! int int F(k) dA / A
  1510. !
  1511. case ( 'aver' )
  1512. row_fine = ff / lli%area(j)
  1513. !
  1514. ! int int exp(F(k)) dA / A
  1515. !
  1516. case ( 'exp,aver' )
  1517. row_fine = exp(ff) / lli%area(j)
  1518. !
  1519. ! error ...
  1520. !
  1521. case default
  1522. write (*,'("ERROR - unsupported integrand key : ",a)') trim(key)
  1523. write (*,'("ERROR in ",a)') rname; status=1; return
  1524. end select
  1525. ! integral in lon direction assuming linear interpolation,
  1526. ! result in [sh] rad
  1527. ilast = 1
  1528. do i = 1, lli%im
  1529. call IntervalQuad_Lin( lons_fine, row_fine, lli%blon(i-1), lli%blon(i), llf(i,jf,l), ilast, status )
  1530. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1531. end do
  1532. end do ! loop over levels
  1533. !! copy to southpole ..
  1534. !if ( (jf==1) .and. aver_to_prev ) then
  1535. ! do l = 1, lm
  1536. ! llf(:,0,l) = sum(llf(:,1,l)) / size(llf,1)
  1537. ! end do
  1538. ! aver_to_prev = .false.
  1539. !end if
  1540. end do ! loop over rows in fine grid
  1541. ! integral in lat direction;
  1542. ! weight with cos(lat) to account for smaller grid cells:
  1543. do l = 1, lm
  1544. do i = 1, lli%im
  1545. ilast = 1
  1546. !call IntervalQuad_Cos_Lin( lat, llf(i,:,l), lli%blat(j-1), lli%blat(j), ll(i,j,l), ilast )
  1547. !>>> bsf15k bug fix >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  1548. llf_dim2 = llf(i,:,l)
  1549. call IntervalQuad_Cos_Lin( lat, llf_dim2, lli%blat(j-1), lli%blat(j), ll(i,j,l), ilast, status )
  1550. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1551. !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1552. end do
  1553. end do
  1554. end do ! loop over rows
  1555. ! free memory
  1556. deallocate( Pnm )
  1557. deallocate( ff )
  1558. deallocate( lons_fine )
  1559. deallocate( row_fine )
  1560. deallocate( llf )
  1561. deallocate( llf_dim2 )
  1562. deallocate( lat )
  1563. call Done( sh )
  1564. ! ok
  1565. status = 0
  1566. end subroutine IntArea_sh_ll_f
  1567. !
  1568. ! key == 'F*(da+db*exp(H))*cos'
  1569. !
  1570. ! int int F(k) (da+db*exp(H)) cos(lat) dA
  1571. !
  1572. ! key == 'F*G*(db*exp(H))/cos'
  1573. !
  1574. ! int int F(k) G db*exp(H) / cos(lat) dA
  1575. !
  1576. ! (for these keys, results are added to ll)
  1577. !
  1578. !
  1579. subroutine IntArea_sh_ll_fgh( key, F, G, H, da, db, lli, ll, status )
  1580. use grid_tools, only : deg2rad, pi
  1581. use Num, only : IntervalQuad_Lin
  1582. use Grid_Type_sh, only : TshGrid, Init, Done, SpN, sh_Pnm, Eval_Lons, Set, Check
  1583. use Grid_Type_ll, only : TllGridInfo, Check
  1584. ! --- in/out -----------------------------------------
  1585. character(len=*), intent(in) :: key
  1586. type(TshGrid), intent(in) :: F(:)
  1587. type(TshGrid), intent(in) :: G, H
  1588. real, intent(in) :: da(size(F)), db(size(F))
  1589. type(TllGridInfo), intent(in) :: lli
  1590. real, intent(inout) :: ll(lli%im,lli%jm,size(F))
  1591. integer, intent(out) :: status
  1592. ! --- const --------------------------------------
  1593. character(len=*), parameter :: rname = mname//'/IntArea_sh_ll_fgh'
  1594. ! --- local ------------------------------------------
  1595. integer :: i, j, jf
  1596. integer :: l, lm
  1597. integer :: ilast
  1598. integer :: T
  1599. type(TshGrid) :: sh
  1600. real, allocatable :: Pnm(:)
  1601. integer :: refinement_i, refinement_j
  1602. integer :: nlon_fine_360, nlon_fine
  1603. real, allocatable :: ff(:)
  1604. real, allocatable :: gg(:)
  1605. real, allocatable :: exp_hh(:)
  1606. real, allocatable :: lons_fine(:), row_fine(:)
  1607. real, allocatable :: llf(:,:,:), lat(:)
  1608. real, allocatable :: llf_dim2(:)
  1609. logical :: aver_to_prev
  1610. real :: res
  1611. ! --- begin ------------------------------------------
  1612. ! number of levels:
  1613. lm = size(F)
  1614. ! check arguments:
  1615. call Check( H )
  1616. T = H%T
  1617. do l = 1, lm
  1618. call Check( F(l), T )
  1619. end do
  1620. call Check( G, T )
  1621. ! use truncation up to grid resolution:
  1622. T = ShTruncation( T, lli%dlon_deg, lli%dlat_deg )
  1623. call Init( sh, T )
  1624. ! allocate space for legendre coeff:
  1625. allocate( Pnm(SpN(T)) )
  1626. ! determine refinement (5 points per sh resolution)
  1627. refinement_i = ShRefinement( T, lli%dlon_deg )
  1628. refinement_j = ShRefinement( T, lli%dlat_deg )
  1629. ! number of lons in fine grid on complete circle:
  1630. nlon_fine_360 = 360.0/lli%dlon_deg * refinement_i
  1631. nlon_fine = lli%im * refinement_i
  1632. ! store evaluation of spectral field:
  1633. allocate( ff(0:nlon_fine) )
  1634. allocate( gg(0:nlon_fine) )
  1635. allocate( exp_hh(0:nlon_fine) )
  1636. ! lons on arc westb+[0,..)
  1637. allocate( row_fine(0:nlon_fine) )
  1638. allocate( lons_fine(0:nlon_fine) )
  1639. do i = 0, nlon_fine
  1640. lons_fine(i) = i*2*pi/nlon_fine_360
  1641. end do
  1642. lons_fine = lli%blon(0) + lons_fine
  1643. ! ll in lon, fine in lat
  1644. allocate( llf(lli%im,0:refinement_j,lm) )
  1645. allocate( lat(0:refinement_j) )
  1646. allocate( llf_dim2(0:refinement_j) )
  1647. ! *** integrals in lon direction
  1648. ! loop over latitudes in ll grid:
  1649. aver_to_prev = .false.
  1650. do j = 1, lli%jm
  1651. ! loop over latitudes in fine grid:
  1652. do jf = 0, refinement_j
  1653. ! latitude in fine grid:
  1654. lat(jf) = lli%blat(j-1) + jf*lli%dlat/refinement_j
  1655. ! southpole ?
  1656. if ( abs(lat(jf) - (-pi/2)) < 1.0e-4 ) then
  1657. ! fill with average of next row
  1658. aver_to_prev = .true.
  1659. cycle
  1660. end if
  1661. ! northpole ?
  1662. if ( abs(lat(jf) - (pi/2)) < 1.0e-4 ) then
  1663. ! fill with average of previous row:
  1664. do l = 1, lm
  1665. llf(:,jf,l) = sum(llf(:,jf-1,l)) / size(llf,1)
  1666. end do
  1667. exit
  1668. end if
  1669. ! evaluate Legendre functions:
  1670. call sh_Pnm( Pnm, T, lat(jf), status )
  1671. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1672. ! evaluate rows:
  1673. call Set( sh, T, G )
  1674. call Eval_Lons( gg, sh, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, status )
  1675. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1676. call Set( sh, T, H )
  1677. call Eval_Lons( exp_hh, sh, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, status )
  1678. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1679. exp_hh = exp(exp_hh)
  1680. do l = 1, lm
  1681. ! combine fields:
  1682. select case ( key )
  1683. !
  1684. ! int int F(k) (da+db*exp(H)) cos(lat) dA
  1685. !
  1686. case ( 'F*(da+db*exp(H))*cos' )
  1687. call Set( sh, T, F(l) )
  1688. call Eval_Lons( ff, sh, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, status )
  1689. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1690. row_fine = ff * ( da(l) + exp_hh*db(l) ) * cos(lat(jf))
  1691. !
  1692. ! int int F(k) G db*exp(H) / cos(lat) dA
  1693. !
  1694. case ( 'F*G*(db*exp(H))/cos' )
  1695. if ( db(l) == 0.0 ) then
  1696. row_fine = 0.0
  1697. else
  1698. call Set( sh, T, F(l) )
  1699. call Eval_Lons( ff, sh, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, status )
  1700. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1701. row_fine = ff * gg * ( exp_hh*db(l) ) / cos(lat(jf))
  1702. end if
  1703. !
  1704. ! error ...
  1705. !
  1706. case default
  1707. print *, 'IntArea_sh_ll_fgh - unknown key "'//trim(key)//'"'
  1708. stop
  1709. end select
  1710. ! integral in lon direction assuming linear interpolation,
  1711. ! result in [sh] rad
  1712. ilast = 1
  1713. do i = 1, lli%im
  1714. call IntervalQuad_Lin( lons_fine, row_fine, lli%blon(i-1), lli%blon(i), llf(i,jf,l), ilast, status )
  1715. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1716. end do
  1717. end do ! loop over levels
  1718. ! copy to southpole ..
  1719. if ( (jf==1) .and. aver_to_prev ) then
  1720. do l = 1, lm
  1721. llf(:,0,l) = sum(llf(:,1,l)) / size(llf,1)
  1722. end do
  1723. aver_to_prev = .false.
  1724. end if
  1725. end do ! loop over rows in fine grid
  1726. ! *** integral in lat direction
  1727. ! 3D field:
  1728. do l = 1, lm
  1729. ilast = 1
  1730. do i = 1, lli%im
  1731. !call lquad( lat, llf(i,:,l), lli%blat(j-1), lli%blat(j), res, ilast )
  1732. !>>> bsf15k bug fix >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  1733. llf_dim2 = llf(i,:,l)
  1734. call IntervalQuad_Lin( lat, llf_dim2, lli%blat(j-1), lli%blat(j), res, ilast, status )
  1735. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1736. !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1737. ! add result
  1738. ll(i,j,l) = ll(i,j,l) + res
  1739. end do
  1740. end do
  1741. end do ! loop over rows
  1742. ! free memory
  1743. deallocate( Pnm )
  1744. deallocate( ff )
  1745. deallocate( gg )
  1746. deallocate( exp_hh )
  1747. deallocate( lons_fine )
  1748. deallocate( row_fine )
  1749. deallocate( llf )
  1750. deallocate( llf_dim2 )
  1751. deallocate( lat )
  1752. call Done( sh )
  1753. ! ok
  1754. status = 0
  1755. end subroutine IntArea_sh_ll_fgh
  1756. ! ***
  1757. subroutine IntArea_shi_ll_fgh( key, shi_in, nlev, F, G, H, da, db, lli, ll, status )
  1758. use grid_tools, only : deg2rad, pi
  1759. use Num, only : IntervalQuad_Lin
  1760. use Grid_Type_sh, only : TshGridInfo, Init, Done, sh_Pnm, Eval_Lons, Set, Check
  1761. use Grid_Type_ll, only : TllGridInfo, Check
  1762. ! --- in/out -----------------------------------------
  1763. character(len=*), intent(in) :: key
  1764. type(TshGridInfo), intent(in) :: shi_in
  1765. integer, intent(in) :: nlev
  1766. complex, intent(in) :: F(shi_in%np,nlev)
  1767. complex, intent(in) :: G(shi_in%np)
  1768. complex, intent(in) :: H(shi_in%np)
  1769. real, intent(in) :: da(nlev), db(nlev)
  1770. type(TllGridInfo), intent(in) :: lli
  1771. real, intent(inout) :: ll(lli%im,lli%jm,nlev)
  1772. integer, intent(out) :: status
  1773. ! --- const --------------------------------------
  1774. character(len=*), parameter :: rname = mname//'/IntArea_sh_ll_fgh'
  1775. ! --- local ------------------------------------------
  1776. integer :: i, j, jf
  1777. integer :: l
  1778. integer :: ilast
  1779. type(TshGridInfo) :: shi
  1780. integer :: T
  1781. real, pointer :: Pnm(:)
  1782. integer :: refinement_i, refinement_j
  1783. integer :: nlon_fine_360, nlon_fine
  1784. real, pointer :: ff(:)
  1785. real, pointer :: gg(:)
  1786. real, pointer :: exp_hh(:)
  1787. real, pointer :: lons_fine(:), row_fine(:)
  1788. real, pointer :: llf(:,:,:), lat(:)
  1789. real, pointer :: llf_dim2(:)
  1790. logical :: aver_to_prev
  1791. real :: res
  1792. ! --- begin ------------------------------------------
  1793. ! use truncation up to grid resolution:
  1794. T = ShTruncation( shi_in%T, lli%dlon_deg, lli%dlat_deg )
  1795. !T = ShTruncation( 159, lli%dlon_deg, lli%dlat_deg )
  1796. ! spectral info:
  1797. call Init( shi, T, status )
  1798. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1799. ! allocate space for legendre coeff:
  1800. allocate( Pnm(shi%np) )
  1801. ! determine refinement (5 points per sh resolution)
  1802. refinement_i = ShRefinement( shi%T, lli%dlon_deg )
  1803. refinement_j = ShRefinement( shi%T, lli%dlat_deg )
  1804. ! number of lons in fine grid on complete circle:
  1805. nlon_fine_360 = 360.0/lli%dlon_deg * refinement_i
  1806. nlon_fine = lli%im * refinement_i
  1807. ! store evaluation of spectral field:
  1808. allocate( ff(0:nlon_fine) )
  1809. allocate( gg(0:nlon_fine) )
  1810. allocate( exp_hh(0:nlon_fine) )
  1811. ! lons on arc westb+[0,..)
  1812. allocate( row_fine(0:nlon_fine) )
  1813. allocate( lons_fine(0:nlon_fine) )
  1814. do i = 0, nlon_fine
  1815. lons_fine(i) = i*2*pi/nlon_fine_360
  1816. end do
  1817. lons_fine = lli%blon(0) + lons_fine
  1818. ! ll in lon, fine in lat
  1819. allocate( llf(lli%im,0:refinement_j,nlev) )
  1820. allocate( lat(0:refinement_j) )
  1821. allocate( llf_dim2(0:refinement_j) )
  1822. ! *** integrals in lon direction
  1823. ! loop over latitudes in ll grid:
  1824. aver_to_prev = .false.
  1825. do j = 1, lli%jm
  1826. ! loop over latitudes in fine grid:
  1827. do jf = 0, refinement_j
  1828. ! latitude in fine grid:
  1829. lat(jf) = lli%blat(j-1) + jf*lli%dlat/refinement_j
  1830. ! southpole ?
  1831. if ( abs(lat(jf) - (-pi/2)) < 1.0e-4 ) then
  1832. ! fill with average of next row
  1833. aver_to_prev = .true.
  1834. cycle
  1835. end if
  1836. ! northpole ?
  1837. if ( abs(lat(jf) - (pi/2)) < 1.0e-4 ) then
  1838. ! fill with average of previous row:
  1839. do l = 1, nlev
  1840. llf(:,jf,l) = sum(llf(:,jf-1,l)) / size(llf,1)
  1841. end do
  1842. exit
  1843. end if
  1844. ! evaluate Legendre functions:
  1845. call sh_Pnm( Pnm, shi%T, lat(jf), status )
  1846. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1847. ! evaluate rows:
  1848. !print *, 'aaa10b shi_in ', shi_in%T, shi_in%np
  1849. !print *, 'aaa10b G size ', size(G)
  1850. !print *, 'aaa10b G val ', G(1:10)
  1851. !print *, 'aaa10b shi ', shi%T, shi%np
  1852. !print *, 'aaa10b Pnm size ', size(Pnm)
  1853. !print *, 'aaa10b Pnm val ', Pnm(1:10)
  1854. call Eval_Lons( shi_in, G, shi, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, gg, status )
  1855. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1856. call Eval_Lons( shi_in, H, shi, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, exp_hh, status )
  1857. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1858. exp_hh = exp(exp_hh)
  1859. ! loop over levels:
  1860. !xOMP PARALLEL &
  1861. !xOMP default ( none ) &
  1862. !xOMP shared ( nlev, key, T, F, Pnm, nlon_fine_360, nlon_fine, lons_fine ) &
  1863. !xOMP shared ( ff, gg, da, exp_hh, db, lat, jf, lli, llf ) &
  1864. !xOMP private ( l, sh, row_fine, ilast, status )
  1865. !xOMP DO
  1866. do l = 1, nlev
  1867. ! combine fields:
  1868. select case ( key )
  1869. !
  1870. ! int int F(k) (da+db*exp(H)) cos(lat) dA
  1871. !
  1872. case ( 'F*(da+db*exp(H))*cos' )
  1873. call Eval_Lons( shi_in, F(:,l), shi, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, ff, status )
  1874. !if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1875. row_fine = ff * ( da(l) + exp_hh*db(l) ) * cos(lat(jf))
  1876. !
  1877. ! int int F(k) G db*exp(H) / cos(lat) dA
  1878. !
  1879. case ( 'F*G*(db*exp(H))/cos' )
  1880. if ( db(l) == 0.0 ) then
  1881. row_fine = 0.0
  1882. else
  1883. call Eval_Lons( shi_in, F(:,l), shi, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, ff, status )
  1884. !if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1885. row_fine = ff * gg * ( exp_hh*db(l) ) / cos(lat(jf))
  1886. end if
  1887. !
  1888. ! error ...
  1889. !
  1890. case default
  1891. print *, 'IntArea_sh_ll_fgh - unknown key "'//trim(key)//'"'
  1892. !stop
  1893. end select
  1894. ! integral in lon direction assuming linear interpolation,
  1895. ! result in [sh] rad
  1896. ilast = 1
  1897. do i = 1, lli%im
  1898. call IntervalQuad_Lin( lons_fine, row_fine, lli%blon(i-1), lli%blon(i), llf(i,jf,l), ilast, status )
  1899. !if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1900. end do
  1901. end do ! levels
  1902. !xOMP END DO
  1903. !xOMP END PARALLEL
  1904. ! copy to southpole ..
  1905. if ( (jf==1) .and. aver_to_prev ) then
  1906. do l = 1, nlev
  1907. llf(:,0,l) = sum(llf(:,1,l)) / size(llf,1)
  1908. end do
  1909. aver_to_prev = .false.
  1910. end if
  1911. end do ! loop over rows in fine grid
  1912. ! *** integral in lat direction
  1913. ! loop over levels:
  1914. !xOMP PARALLEL DO
  1915. do l = 1, nlev
  1916. ilast = 1
  1917. do i = 1, lli%im
  1918. !call lquad( lat, llf(i,:,l), lli%blat(j-1), lli%blat(j), res, ilast )
  1919. !>>> bsf15k bug fix >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  1920. llf_dim2 = llf(i,:,l)
  1921. call IntervalQuad_Lin( lat, llf_dim2, lli%blat(j-1), lli%blat(j), res, ilast, status )
  1922. !if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1923. !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1924. ! add result
  1925. ll(i,j,l) = ll(i,j,l) + res
  1926. end do
  1927. end do
  1928. !xOMP END PARALLEL DO
  1929. end do ! loop over rows
  1930. ! free memory
  1931. deallocate( Pnm )
  1932. deallocate( ff )
  1933. deallocate( gg )
  1934. deallocate( exp_hh )
  1935. deallocate( lons_fine )
  1936. deallocate( row_fine )
  1937. deallocate( llf )
  1938. deallocate( llf_dim2 )
  1939. deallocate( lat )
  1940. call Done( shi )!, status )
  1941. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1942. ! ok
  1943. status = 0
  1944. end subroutine IntArea_shi_ll_fgh
  1945. ! ***
  1946. !
  1947. ! key == '[F*(da+db*exp(H))*cos]/[()*cos]'
  1948. !
  1949. ! int int F(k) (da+db*exp(H)) cos(lat) dA / int int (da+db*exp(H)) cos(lat) dA
  1950. !
  1951. ! Result is put in ll, not added.
  1952. ! Uses cos integration in lat direction.
  1953. !
  1954. subroutine IntArea_sh_ll_fh( key, F, H, da, db, lli, ll, status )
  1955. use grid_tools, only : deg2rad, pi
  1956. use Num, only : IntervalQuad_Lin, IntervalQuad_Cos_Lin
  1957. use Grid_Type_sh, only : TshGrid, Init, Done, SpN, sh_Pnm, Eval_Lons, Set, Check
  1958. use Grid_Type_ll, only : TllGridInfo, Check
  1959. ! --- in/out -----------------------------------------
  1960. character(len=*), intent(in) :: key
  1961. type(TshGrid), intent(in) :: F(:)
  1962. type(TshGrid), intent(in) :: H
  1963. real, intent(in) :: da(size(F)), db(size(F))
  1964. type(TllGridInfo), intent(in) :: lli
  1965. real, intent(inout) :: ll(lli%im,lli%jm,size(F))
  1966. integer, intent(out) :: status
  1967. ! --- const --------------------------------------
  1968. character(len=*), parameter :: rname = mname//'/IntArea_sh_ll_fh'
  1969. ! --- local ------------------------------------------
  1970. integer :: i, j, jf
  1971. integer :: l, lm
  1972. integer :: ilast
  1973. integer :: T
  1974. type(TshGrid) :: sh
  1975. real, allocatable :: Pnm(:)
  1976. integer :: refinement_i, refinement_j
  1977. integer :: nlon_fine_360, nlon_fine
  1978. real, allocatable :: ff(:)
  1979. real, allocatable :: exp_hh(:)
  1980. real, allocatable :: lons_fine(:), row_fine(:)
  1981. real, allocatable :: llf(:,:,:), lat(:)
  1982. real, allocatable :: llf_dim2(:)
  1983. real :: res
  1984. real, allocatable :: llf_expH(:,:)
  1985. ! --- begin ------------------------------------------
  1986. ! number of levels:
  1987. lm = size(F)
  1988. ! check arguments:
  1989. call Check( H )
  1990. T = H%T
  1991. do l = 1, lm
  1992. call Check( F(L), T )
  1993. end do
  1994. T = ShTruncation( T, lli%dlon_deg, lli%dlat_deg )
  1995. call Init( sh, T )
  1996. ! allocate space for legendre coeff:
  1997. allocate( Pnm(SpN(T)) )
  1998. ! determine refinement (5 points per sh resolution)
  1999. refinement_i = ShRefinement( T, lli%dlon_deg )
  2000. refinement_j = ShRefinement( T, lli%dlat_deg )
  2001. ! number of lons in fine grid on complete circle:
  2002. nlon_fine_360 = 360.0/lli%dlon_deg * refinement_i
  2003. nlon_fine = lli%im * refinement_i
  2004. ! store evaluation of spectral field:
  2005. allocate( ff(0:nlon_fine) )
  2006. allocate( exp_hh(0:nlon_fine) )
  2007. ! lons on arc westb+[0,..)
  2008. allocate( row_fine(0:nlon_fine) )
  2009. allocate( lons_fine(0:nlon_fine) )
  2010. do i = 0, nlon_fine
  2011. lons_fine(i) = i*2*pi/nlon_fine_360
  2012. end do
  2013. lons_fine = lli%blon(0) + lons_fine
  2014. ! ll in lon, fine in lat
  2015. allocate( llf(lli%im,0:refinement_j,lm) )
  2016. allocate( llf_expH(lli%im,0:refinement_j) )
  2017. allocate( lat(0:refinement_j) )
  2018. allocate( llf_dim2(0:refinement_j) )
  2019. ! *** integrals in lon direction
  2020. ! loop over latitudes in ll grid:
  2021. do j = 1, lli%jm
  2022. ! loop over latitudes in fine grid:
  2023. do jf = 0, refinement_j
  2024. ! latitude in fine grid:
  2025. lat(jf) = lli%blat(j-1) + jf*lli%dlat/refinement_j
  2026. ! evaluate Legendre functions:
  2027. call sh_Pnm( Pnm, T, lat(jf), status )
  2028. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2029. ! evaluate rows:
  2030. call Set( sh, T, H )
  2031. call Eval_Lons( exp_hh, sh, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, status )
  2032. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2033. ! exponent:
  2034. exp_hh = exp(exp_hh)
  2035. ! compute lon integral over exp(H), as a part of integral over second term
  2036. ! (use linear interpolation):
  2037. ilast = 1
  2038. do i = 1, lli%im
  2039. call IntervalQuad_Lin( lons_fine, exp_hh, lli%blon(i-1), lli%blon(i), llf_expH(i,jf), ilast, status )
  2040. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2041. end do
  2042. do l = 1, lm
  2043. call Set( sh, T, F(l) )
  2044. call Eval_Lons( ff, sh, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, status )
  2045. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2046. ! combine fields:
  2047. select case ( key )
  2048. !
  2049. ! int int F(k) (da+db*exp(H)) cos(lat) dA / int int (da+db*exp(H)) cos(lat) dA
  2050. !
  2051. case ( '[F*(da+db*exp(H))*cos]/[()*cos]' )
  2052. ! lon integral of first term:
  2053. row_fine = ff * ( da(l) + exp_hh*db(l) )
  2054. !
  2055. ! error ...
  2056. !
  2057. case default
  2058. print *, 'IntArea_sh_ll_fh - unknown key "'//trim(key)//'"'
  2059. stop
  2060. end select
  2061. ! integral in lon direction assuming linear interpolation,
  2062. ! result in [sh] rad
  2063. ilast = 1
  2064. do i = 1, lli%im
  2065. call IntervalQuad_Lin( lons_fine, row_fine, lli%blon(i-1), lli%blon(i), llf(i,jf,l), ilast, status )
  2066. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2067. end do
  2068. end do ! loop over levels
  2069. end do ! loop over rows in fine grid
  2070. ! *** integral in lat direction
  2071. ! 3D field:
  2072. do l = 1, lm
  2073. ilast = 1
  2074. do i = 1, lli%im
  2075. !call IntervalQuad_Cos_Lin( lat, llf(i,:,l), lli%blat(j-1), lli%blat(j), res, ilast )
  2076. !>>> bsf15k bug fix >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  2077. llf_dim2 = llf(i,:,l)
  2078. call IntervalQuad_Cos_Lin( lat, llf_dim2, lli%blat(j-1), lli%blat(j), res, ilast, status )
  2079. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2080. !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  2081. ! set result
  2082. ll(i,j,l) = res
  2083. end do
  2084. end do
  2085. ! weight with integral over exp_hh :
  2086. ilast = 1
  2087. do i = 1, lli%im
  2088. !>>> bsf15k bug fix >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  2089. !call IntervalQuad_Cos_Lin( lat, llf_expH(i,:), lli%blat(j-1), lli%blat(j), res, ilast )
  2090. llf_dim2 = llf_expH(i,:)
  2091. call IntervalQuad_Cos_Lin( lat, llf_dim2, lli%blat(j-1), lli%blat(j), res, ilast, status )
  2092. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2093. !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  2094. ! weight with int int (da+db*exp(H))*cos(lat) dA
  2095. do l = 1, lm
  2096. ll(i,j,l) = ll(i,j,l) / (da(l)*lli%area(j) + db(l)*res)
  2097. end do
  2098. end do
  2099. end do ! loop over rows
  2100. ! free memory
  2101. deallocate( Pnm )
  2102. deallocate( ff )
  2103. deallocate( exp_hh )
  2104. deallocate( lons_fine )
  2105. deallocate( row_fine )
  2106. deallocate( llf )
  2107. deallocate( llf_dim2 )
  2108. deallocate( llf_expH )
  2109. deallocate( lat )
  2110. call Done( sh )
  2111. ! ok
  2112. status = 0
  2113. end subroutine IntArea_sh_ll_fh
  2114. ! ***
  2115. subroutine IntArea_shi_ll_fh( key, shi_in, nlev, F, H, da, db, lli, ll, status )
  2116. use grid_tools, only : deg2rad, pi
  2117. use Num, only : IntervalQuad_Lin, IntervalQuad_Cos_Lin
  2118. use Grid_Type_sh, only : TshGrid, Init, Done
  2119. use Grid_Type_sh, only : SpN, sh_Pnm, Eval_Lons, Set, Check, SpN, Truncate
  2120. use Grid_Type_sh, only : TshGridInfo
  2121. use Grid_Type_ll, only : TllGridInfo, Check
  2122. ! --- in/out -----------------------------------------
  2123. character(len=*), intent(in) :: key
  2124. type(TshGridInfo), intent(in) :: shi_in
  2125. integer, intent(in) :: nlev
  2126. complex, intent(in) :: F(shi_in%np,nlev)
  2127. complex, intent(in) :: H(shi_in%np)
  2128. real, intent(in) :: da(nlev), db(nlev)
  2129. type(TllGridInfo), intent(in) :: lli
  2130. real, intent(inout) :: ll(lli%im,lli%jm,nlev)
  2131. integer, intent(out) :: status
  2132. ! --- const ------------------------------------------
  2133. character(len=*), parameter :: rname = mname//'/IntArea_shi_ll_fh'
  2134. ! --- local ------------------------------------------
  2135. integer :: i, j, jf
  2136. integer :: l !, lm
  2137. integer :: ilast
  2138. type(TshGridInfo) :: shi
  2139. ! type(TshGrid) :: sh
  2140. integer :: Ttr
  2141. real, allocatable :: Pnm(:)
  2142. integer :: refinement_i, refinement_j
  2143. integer :: nlon_fine_360, nlon_fine
  2144. real, allocatable :: ff(:)
  2145. real, allocatable :: exp_hh(:)
  2146. real, allocatable :: lons_fine(:), row_fine(:)
  2147. real, allocatable :: llf(:,:,:), lat(:)
  2148. real, allocatable :: llf_dim2(:)
  2149. real :: res
  2150. real, allocatable :: llf_expH(:,:)
  2151. ! --- begin ------------------------------------------
  2152. ! ! number of levels:
  2153. ! lm = size(F,2)
  2154. !
  2155. ! ! check arguments:
  2156. ! if ( (size(F,1) /= shi%np) .or. (size(H) /= shi%np) ) then
  2157. ! write (*,'("ERROR - number of complex coeff does not match with sh grid definition:")')
  2158. ! write (*,'("ERROR - shi%np : ",i6)') shi%np
  2159. ! write (*,'("ERROR - size(F,1) : ",i6)') size(F,1)
  2160. ! write (*,'("ERROR - size(H) : ",i6)') size(H)
  2161. ! write (*,'("ERROR in ",a)') rname; status=1; return
  2162. ! end if
  2163. !
  2164. ! ! input temporary stored in old type grid:
  2165. ! call Init( sh, shi%T )
  2166. ! use truncation up to grid resolution:
  2167. Ttr = ShTruncation( shi_in%T, lli%dlon_deg, lli%dlat_deg )
  2168. ! call Truncate( sh, Ttr )
  2169. call Init( shi, Ttr, status )
  2170. ! allocate space for legendre coeff:
  2171. ! allocate( Pnm(SpN(Ttr)) )
  2172. allocate( Pnm(shi%np) )
  2173. ! determine refinement (5 points per sh resolution)
  2174. refinement_i = ShRefinement( shi%T, lli%dlon_deg )
  2175. refinement_j = ShRefinement( shi%T, lli%dlat_deg )
  2176. ! number of lons in fine grid on complete circle:
  2177. nlon_fine_360 = 360.0/lli%dlon_deg * refinement_i
  2178. nlon_fine = lli%im * refinement_i
  2179. ! store evaluation of spectral field:
  2180. allocate( ff(0:nlon_fine) )
  2181. allocate( exp_hh(0:nlon_fine) )
  2182. ! lons on arc westb+[0,..)
  2183. allocate( row_fine(0:nlon_fine) )
  2184. allocate( lons_fine(0:nlon_fine) )
  2185. do i = 0, nlon_fine
  2186. lons_fine(i) = i*2*pi/nlon_fine_360
  2187. end do
  2188. lons_fine = lli%blon(0) + lons_fine
  2189. ! ll in lon, fine in lat
  2190. !allocate( llf(lli%im,0:refinement_j,lm) )
  2191. allocate( llf(lli%im,0:refinement_j,nlev) )
  2192. allocate( llf_expH(lli%im,0:refinement_j) )
  2193. allocate( lat(0:refinement_j) )
  2194. allocate( llf_dim2(0:refinement_j) )
  2195. ! *** integrals in lon direction
  2196. ! loop over latitudes in ll grid:
  2197. do j = 1, lli%jm
  2198. ! loop over latitudes in fine grid:
  2199. do jf = 0, refinement_j
  2200. ! latitude in fine grid:
  2201. lat(jf) = lli%blat(j-1) + jf*lli%dlat/refinement_j
  2202. ! evaluate Legendre functions:
  2203. !call sh_Pnm( Pnm, Ttr, lat(jf), status )
  2204. call sh_Pnm( Pnm, shi%T, lat(jf), status )
  2205. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2206. ! evaluate rows:
  2207. !call Set( sh, shi%T, H )
  2208. !call Truncate( sh, Ttr )
  2209. !call Eval_Lons( exp_hh, sh, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, status )
  2210. !if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2211. call Eval_Lons( shi_in, H, shi, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, exp_hh, status )
  2212. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2213. exp_hh = exp(exp_hh)
  2214. ! compute lon integral over exp(H), as a part of integral over second term
  2215. ! (use linear interpolation):
  2216. ilast = 1
  2217. do i = 1, lli%im
  2218. call IntervalQuad_Lin( lons_fine, exp_hh, lli%blon(i-1), lli%blon(i), llf_expH(i,jf), ilast, status )
  2219. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2220. end do
  2221. ! combine fields:
  2222. select case ( key )
  2223. !
  2224. ! int int F(k) (da+db*exp(H)) cos(lat) dA / int int (da+db*exp(H)) cos(lat) dA
  2225. !
  2226. case ( '[F*(da+db*exp(H))*cos]/[()*cos]' )
  2227. !$OMP PARALLEL &
  2228. !$OMP default ( none ) &
  2229. !$OMP shared ( shi_in, F, shi, Pnm, nlon_fine_360, lons_fine, nlon_fine, lli, llf ) &
  2230. !$OMP shared ( exp_hh, da, db, jf ) &
  2231. !$OMP shared ( nlev ) &
  2232. !$OMP private ( l, ff, status, row_fine, ilast )
  2233. !$OMP DO
  2234. do l = 1, nlev
  2235. !do l = 1, lm
  2236. !call Set( sh, shi%T, F(:,l) )
  2237. !call Truncate( sh, Ttr )
  2238. call Eval_Lons( shi_in, F(:,l), shi, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, ff, status )
  2239. !if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2240. ! lon integral of first term:
  2241. row_fine = ff * ( da(l) + exp_hh*db(l) )
  2242. ! integral in lon direction assuming linear interpolation,
  2243. ! result in [sh] rad
  2244. ilast = 1
  2245. do i = 1, lli%im
  2246. call IntervalQuad_Lin( lons_fine, row_fine, lli%blon(i-1), lli%blon(i), llf(i,jf,l), ilast, status )
  2247. !if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2248. end do
  2249. end do ! loop over levels
  2250. !$OMP END DO
  2251. !$OMP END PARALLEL
  2252. !
  2253. ! error ...
  2254. !
  2255. case default
  2256. print *, 'IntArea_shi_ll_fh - unknown key "'//trim(key)//'"'
  2257. stop
  2258. end select
  2259. end do ! loop over rows in fine grid
  2260. ! *** integral in lat direction
  2261. ! 3D field:
  2262. do l = 1, nlev
  2263. !do l = 1, lm
  2264. ilast = 1
  2265. do i = 1, lli%im
  2266. !call IntervalQuad_Cos_Lin( lat, llf(i,:,l), lli%blat(j-1), lli%blat(j), res, ilast )
  2267. !>>> bsf15k bug fix >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  2268. llf_dim2 = llf(i,:,l)
  2269. call IntervalQuad_Cos_Lin( lat, llf_dim2, lli%blat(j-1), lli%blat(j), res, ilast, status )
  2270. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2271. !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  2272. ! set result
  2273. ll(i,j,l) = res
  2274. end do
  2275. end do
  2276. ! weight with integral over exp_hh :
  2277. ilast = 1
  2278. do i = 1, lli%im
  2279. !>>> bsf15k bug fix >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  2280. !call IntervalQuad_Cos_Lin( lat, llf_expH(i,:), lli%blat(j-1), lli%blat(j), res, ilast )
  2281. llf_dim2 = llf_expH(i,:)
  2282. call IntervalQuad_Cos_Lin( lat, llf_dim2, lli%blat(j-1), lli%blat(j), res, ilast, status )
  2283. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2284. !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  2285. ! weight with int int (da+db*exp(H))*cos(lat) dA
  2286. do l = 1, nlev
  2287. !do l = 1, lm
  2288. ll(i,j,l) = ll(i,j,l) / (da(l)*lli%area(j) + db(l)*res)
  2289. end do
  2290. end do
  2291. end do ! loop over rows
  2292. ! free memory
  2293. deallocate( Pnm )
  2294. deallocate( ff )
  2295. deallocate( exp_hh )
  2296. deallocate( lons_fine )
  2297. deallocate( row_fine )
  2298. deallocate( llf )
  2299. deallocate( llf_dim2 )
  2300. deallocate( llf_expH )
  2301. deallocate( lat )
  2302. !call Done( sh )
  2303. ! ok
  2304. status = 0
  2305. end subroutine IntArea_shi_ll_fh
  2306. ! ***
  2307. subroutine IntLat_sh_ll( key, F, H, da, db, lli, ll_u, status )
  2308. use grid_tools, only : deg2rad, pi
  2309. use Num, only : IntervalQuad_Lin
  2310. use Grid_Type_sh, only : TshGrid, Init, Done, Set, Check
  2311. use Grid_Type_sh, only : sh_Pnm, Eval_Lons, SpN
  2312. use Grid_Type_ll, only : TllGridInfo, Check
  2313. ! --- in/out -----------------------------------------
  2314. character(len=*), intent(in) :: key
  2315. type(TshGrid), intent(in) :: F(:)
  2316. type(TshGrid), intent(in) :: H
  2317. real, intent(in) :: da(size(F))
  2318. real, intent(in) :: db(size(F))
  2319. type(TllGridInfo), intent(in) :: lli
  2320. real, intent(inout) :: ll_u(0:lli%im,lli%jm,size(F))
  2321. integer, intent(out) :: status
  2322. ! --- const --------------------------------------
  2323. character(len=*), parameter :: rname = mname//'/IntLat_sh_ll'
  2324. ! --- local ------------------------------------------
  2325. integer :: i, j, jf
  2326. integer :: l, lm
  2327. integer :: ilast
  2328. integer :: T
  2329. type(TshGrid) :: sh
  2330. real, allocatable :: Pnm(:)
  2331. integer :: refinement_j
  2332. integer :: nlon_fine_360, nlon_fine
  2333. real, allocatable :: ff(:)
  2334. real, allocatable :: exp_hh(:)
  2335. real, allocatable :: llf(:,:,:), lat(:), llf_row(:)
  2336. logical :: aver_to_prev
  2337. ! --- begin ------------------------------------------
  2338. ! number of levels:
  2339. lm = size(F)
  2340. ! check arguments:
  2341. call Check( H )
  2342. T = H%T
  2343. do l = 1, lm
  2344. call Check( F(l), T )
  2345. end do
  2346. T = ShTruncation( T, lli%dlon_deg, lli%dlat_deg )
  2347. call Init( sh, T )
  2348. ! allocate space for legendre coeff:
  2349. allocate( Pnm(SpN(T)) )
  2350. ! determine refinement based on spectral resolution
  2351. ! and length of required integration interval:
  2352. refinement_j = ShRefinement( T, lli%dlat_deg )
  2353. ! number of lons in fine grid on complete circle:
  2354. nlon_fine_360 = 360.0/lli%dlon_deg
  2355. nlon_fine = lli%im
  2356. ! store evaluation of spectral field:
  2357. allocate( ff(0:nlon_fine) )
  2358. allocate( exp_hh(0:nlon_fine) )
  2359. ! ll in lon, fine in lat
  2360. allocate( llf(0:lli%im,0:refinement_j,lm) )
  2361. allocate( llf_row(0:refinement_j) )
  2362. allocate( lat(0:refinement_j) )
  2363. ! loop over latitudes in ll grid:
  2364. aver_to_prev = .false.
  2365. do j = 1, lli%jm
  2366. ! loop over latitudes in fine grid:
  2367. do jf = 0, refinement_j
  2368. ! latitude in fine grid:
  2369. lat(jf) = lli%blat(j-1) + jf*lli%dlat/refinement_j
  2370. ! southpole ?
  2371. if ( abs(lat(jf) - (-pi/2)) < 1.0e-4 ) then
  2372. ! fill with average of next row
  2373. aver_to_prev = .true.
  2374. cycle
  2375. end if
  2376. ! northpole ?
  2377. if ( abs(lat(jf) - (pi/2)) < 1.0e-4 ) then
  2378. ! fill with average of previous row:
  2379. do l = 1, lm
  2380. llf(:,jf,l) = sum(llf(:,jf-1,l)) / size(llf,1)
  2381. end do
  2382. exit
  2383. end if
  2384. ! evaluate Legendre functions:
  2385. call sh_Pnm( Pnm, T, lat(jf), status )
  2386. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2387. ! evaluate rows:
  2388. call Set( sh, T, H )
  2389. call Eval_Lons( exp_hh, sh, Pnm, nlon_fine_360, lli%blon(0), nlon_fine+1, status )
  2390. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2391. exp_hh = exp(exp_hh)
  2392. do l = 1, lm
  2393. call Set( sh, T, F(l) )
  2394. call Eval_Lons( ff, sh, Pnm, nlon_fine_360, lli%blon(0), nlon_fine+1, status )
  2395. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2396. ! combine fields:
  2397. select case ( key )
  2398. !
  2399. ! [ int exp(H) dlat ] / deltalat
  2400. !
  2401. case ( 'exp(H),aver' )
  2402. llf(:,jf,l) = exp_hh / lli%dlat
  2403. !
  2404. ! int F (da+db*exp(H)) / cos(lat) dlat
  2405. !
  2406. case ( '(da+exp*db)/cos' )
  2407. llf(:,jf,l) = ff * ( da(l) + exp_hh*db(l) ) / cos(lat(jf))
  2408. !
  2409. ! error ...
  2410. !
  2411. case default
  2412. print *, 'IntLat_sh_ll - unknown key "'//trim(key)//'"'
  2413. stop
  2414. end select
  2415. end do ! loop over levels
  2416. ! copy to southpole ..
  2417. if ( (jf==1) .and. aver_to_prev ) then
  2418. do l = 1, lm
  2419. llf(:,0,l) = sum(llf(:,1,l)) / size(llf,1)
  2420. end do
  2421. aver_to_prev = .false.
  2422. end if
  2423. end do ! loop over rows in fine grid
  2424. ! integral in lat direction:
  2425. do l = 1, lm
  2426. do i = 0, lli%im
  2427. ilast = 1
  2428. llf_row = llf(i,:,l)
  2429. call IntervalQuad_Lin( lat, llf_row, lli%blat(j-1), lli%blat(j), ll_u(i,j,l), ilast, status )
  2430. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2431. end do
  2432. end do
  2433. end do ! loop over rows
  2434. ! free memory
  2435. call Done( sh )
  2436. deallocate( Pnm )
  2437. deallocate( ff )
  2438. deallocate( exp_hh )
  2439. deallocate( llf )
  2440. deallocate( llf_row )
  2441. deallocate( lat )
  2442. ! ok
  2443. status = 0
  2444. end subroutine IntLat_sh_ll
  2445. ! ***
  2446. ! ***
  2447. subroutine IntLat_shi_ll( key,shi_in,nlev, F, H, da, db, lli, ll_u, status )
  2448. use grid_tools, only : deg2rad, pi
  2449. use Num, only : IntervalQuad_Lin
  2450. use Grid_Type_sh, only : TshGridInfo, TshGrid, Init, Done, Set, Check
  2451. use Grid_Type_sh, only : sh_Pnm, Eval_Lons, SpN
  2452. use Grid_Type_ll, only : TllGridInfo, Check
  2453. ! --- in/out -----------------------------------------
  2454. character(len=*), intent(in) :: key
  2455. type(TshGridInfo), intent(in) :: shi_in
  2456. integer, intent(in) :: nlev
  2457. complex, intent(in) :: F(shi_in%np,nlev)
  2458. complex, intent(in) :: H(shi_in%np)
  2459. real, intent(in) :: da(nlev)
  2460. real, intent(in) :: db(nlev)
  2461. type(TllGridInfo), intent(in) :: lli
  2462. real, intent(inout) :: ll_u(0:lli%im,lli%jm,nlev)
  2463. integer, intent(out) :: status
  2464. ! --- const --------------------------------------
  2465. character(len=*), parameter :: rname = mname//'/IntLat_shi_ll'
  2466. ! --- local ------------------------------------------
  2467. integer :: i, j, jf
  2468. integer :: l, lm
  2469. integer :: ilast
  2470. type(TshGridInfo) :: shi
  2471. integer :: T
  2472. ! type(TshGrid) :: sh
  2473. real, allocatable :: Pnm(:)
  2474. integer :: refinement_j
  2475. integer :: nlon_fine_360, nlon_fine
  2476. real, allocatable :: ff(:)
  2477. real, allocatable :: exp_hh(:)
  2478. real, allocatable :: llf(:,:,:), lat(:), llf_row(:)
  2479. logical :: aver_to_prev
  2480. ! --- begin ------------------------------------------
  2481. T = ShTruncation( shi_in%T, lli%dlon_deg, lli%dlat_deg )
  2482. ! T = ShTruncation( T, lli%dlon_deg, lli%dlat_deg )
  2483. call Init( shi, T,status )
  2484. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2485. ! allocate space for legendre coeff:
  2486. allocate( Pnm(shi%np) )
  2487. ! determine refinement based on spectral resolution
  2488. ! and length of required integration interval:
  2489. refinement_j = ShRefinement( shi%T, lli%dlat_deg )
  2490. ! number of lons in fine grid on complete circle:
  2491. nlon_fine_360 = 360.0/lli%dlon_deg
  2492. nlon_fine = lli%im
  2493. ! store evaluation of spectral field:
  2494. allocate( ff(0:nlon_fine) )
  2495. allocate( exp_hh(0:nlon_fine) )
  2496. ! ll in lon, fine in lat
  2497. allocate( llf(0:lli%im,0:refinement_j,nlev) )
  2498. allocate( llf_row(0:refinement_j) )
  2499. allocate( lat(0:refinement_j) )
  2500. ! loop over latitudes in ll grid:
  2501. aver_to_prev = .false.
  2502. do j = 1, lli%jm
  2503. ! loop over latitudes in fine grid:
  2504. do jf = 0, refinement_j
  2505. ! latitude in fine grid:
  2506. lat(jf) = lli%blat(j-1) + jf*lli%dlat/refinement_j
  2507. ! southpole ?
  2508. if ( abs(lat(jf) - (-pi/2)) < 1.0e-4 ) then
  2509. ! fill with average of next row
  2510. aver_to_prev = .true.
  2511. cycle
  2512. end if
  2513. ! northpole ?
  2514. if ( abs(lat(jf) - (pi/2)) < 1.0e-4 ) then
  2515. ! fill with average of previous row:
  2516. do l = 1, nlev
  2517. llf(:,jf,l) = sum(llf(:,jf-1,l)) / size(llf,1)
  2518. end do
  2519. exit
  2520. end if
  2521. ! evaluate Legendre functions:
  2522. call sh_Pnm( Pnm, shi%T, lat(jf), status )
  2523. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2524. ! evaluate rows:
  2525. call Eval_Lons( shi_in, H, shi, Pnm, nlon_fine_360, lli%blon(0), nlon_fine+1,exp_hh, status )
  2526. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2527. exp_hh = exp(exp_hh)
  2528. do l = 1, nlev
  2529. call Eval_Lons( shi_in, (/F(:,l)/), shi, Pnm, nlon_fine_360, lli%blon(0), nlon_fine+1,ff, status )
  2530. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2531. ! combine fields:
  2532. select case ( key )
  2533. !
  2534. ! [ int exp(H) dlat ] / deltalat
  2535. !
  2536. case ( 'exp(H),aver' )
  2537. llf(:,jf,l) = exp_hh / lli%dlat
  2538. !
  2539. ! int F (da+db*exp(H)) / cos(lat) dlat
  2540. !
  2541. case ( '(da+exp*db)/cos' )
  2542. llf(:,jf,l) = ff * ( da(l) + exp_hh*db(l) ) / cos(lat(jf))
  2543. !
  2544. ! error ...
  2545. !
  2546. case default
  2547. print *, 'IntLat_sh_ll - unknown key "'//trim(key)//'"'
  2548. stop
  2549. end select
  2550. end do ! loop over levels
  2551. ! copy to southpole ..
  2552. if ( (jf==1) .and. aver_to_prev ) then
  2553. do l = 1, nlev
  2554. llf(:,0,l) = sum(llf(:,1,l)) / size(llf,1)
  2555. end do
  2556. aver_to_prev = .false.
  2557. end if
  2558. end do ! loop over rows in fine grid
  2559. ! integral in lat direction:
  2560. do l = 1, nlev
  2561. do i = 0, lli%im
  2562. ilast = 1
  2563. llf_row = llf(i,:,l)
  2564. call IntervalQuad_Lin( lat, llf_row, lli%blat(j-1), lli%blat(j), ll_u(i,j,l), ilast, status )
  2565. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2566. end do
  2567. end do
  2568. end do ! loop over rows
  2569. ! free memory
  2570. call Done( shi )
  2571. deallocate( Pnm )
  2572. deallocate( ff )
  2573. deallocate( exp_hh )
  2574. deallocate( llf )
  2575. deallocate( llf_row )
  2576. deallocate( lat )
  2577. ! ok
  2578. status = 0
  2579. end subroutine IntLat_shi_ll
  2580. ! ***
  2581. subroutine IntLon_sh_ll( key, F, H, da, db, lli, ll_v, status )
  2582. use grid_tools, only : deg2rad, pi
  2583. use Num, only : IntervalQuad_Lin
  2584. use Grid_Type_sh, only : TshGrid, Init, Done, SpN, Set, Check
  2585. use Grid_Type_sh, only : sh_Pnm, Eval_Lons
  2586. use Grid_Type_ll, only : TllGridInfo, Check
  2587. ! --- in/out -----------------------------------------
  2588. character(len=*), intent(in) :: key
  2589. type(TshGrid), intent(in) :: F(:)
  2590. type(TshGrid), intent(in) :: H
  2591. real, intent(in) :: da(size(F))
  2592. real, intent(in) :: db(size(F))
  2593. type(TllGridInfo), intent(in) :: lli
  2594. real, intent(inout) :: ll_v(lli%im,0:lli%jm,size(F))
  2595. integer, intent(out) :: status
  2596. ! --- const --------------------------------------
  2597. character(len=*), parameter :: rname = mname//'/IntLon_sh_ll'
  2598. ! --- local ------------------------------------------
  2599. integer :: i, j
  2600. integer :: l, lm
  2601. integer :: ilast
  2602. integer :: T
  2603. type(TshGrid) :: sh
  2604. real, allocatable :: Pnm(:)
  2605. integer :: refinement_i
  2606. integer :: nlon_fine_360, nlon_fine
  2607. real, allocatable :: ff(:)
  2608. real, allocatable :: exp_hh(:)
  2609. real, allocatable :: lons_fine(:), row_fine(:)
  2610. logical :: pole
  2611. ! --- begin ------------------------------------------
  2612. ! number of levels:
  2613. lm = size(F)
  2614. ! check arguments:
  2615. call Check( H )
  2616. T = H%T
  2617. do l = 1, lm
  2618. call Check( F(l), T )
  2619. end do
  2620. ! use truncated harmonics ?
  2621. T = ShTruncation( T, lli%dlon_deg, lli%dlat_deg )
  2622. call Init( sh, T )
  2623. ! allocate space for legendre coeff:
  2624. allocate( Pnm(SpN(T)) )
  2625. ! determine refinement based on spectral resolution
  2626. ! and length of required integration interval:
  2627. refinement_i = ShRefinement( T, lli%dlon_deg )
  2628. ! number of lons in fine grid on complete circle:
  2629. nlon_fine_360 = 360.0/lli%dlon_deg * refinement_i
  2630. nlon_fine = lli%im * refinement_i
  2631. ! store evaluation of spectral field:
  2632. allocate( ff(0:nlon_fine) )
  2633. allocate( exp_hh(0:nlon_fine) )
  2634. ! lons on arc westb+[0,..)
  2635. allocate( row_fine(0:nlon_fine) )
  2636. allocate( lons_fine(0:nlon_fine) )
  2637. do i = 0, nlon_fine
  2638. lons_fine(i) = i*2*pi/nlon_fine_360
  2639. end do
  2640. lons_fine = lli%blon(0) + lons_fine
  2641. ! loop over boundary latitudes in ll grid:
  2642. do j = 0, lli%jm
  2643. ! pole ? then int f(x) dx = f
  2644. pole = ( abs(lli%blat(j) - (-pi/2)) < 1.0e-4 ) .or. &
  2645. ( abs(lli%blat(j) - ( pi/2)) < 1.0e-4 )
  2646. ! evaluate Legendre functions:
  2647. call sh_Pnm( Pnm, T, lli%blat(j), status )
  2648. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2649. ! evaluate rows:
  2650. call Set( sh, T, H )
  2651. call Eval_Lons( exp_hh, sh, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, status )
  2652. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2653. exp_hh = exp(exp_hh)
  2654. ! loop over levels
  2655. do l = 1, lm
  2656. call Set( sh, T, F(l) )
  2657. call Eval_Lons( ff, sh, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, status )
  2658. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2659. ! combine fields:
  2660. select case ( key )
  2661. !
  2662. ! [ int exp(H) dlon ] / deltalon
  2663. !
  2664. case ( 'exp(H),aver' )
  2665. if ( pole ) then
  2666. row_fine = exp_hh
  2667. else
  2668. row_fine = exp_hh / lli%dlon
  2669. end if
  2670. !
  2671. ! int F (da+db*exp(H)) dlon
  2672. !
  2673. case ( '(da+exp*db)' )
  2674. if ( pole ) then
  2675. row_fine = 0.0
  2676. else
  2677. row_fine = ff * ( da(l) + exp_hh*db(l) )
  2678. end if
  2679. !
  2680. ! error ...
  2681. !
  2682. case default
  2683. print *, 'IntLon_sh_ll - unknown key "'//trim(key)//'"'
  2684. stop
  2685. end select
  2686. ! special treatment of poles:
  2687. if ( pole ) then
  2688. ! same value at al 'longitudes', thus for example the average ...
  2689. ll_v(:,j,l) = sum(row_fine)/size(row_fine)
  2690. else
  2691. ! integral in lon direction assuming linear interpolation,
  2692. ! result in [sh] rad
  2693. ilast = 1
  2694. do i = 1, lli%im
  2695. call IntervalQuad_Lin( lons_fine, row_fine, lli%blon(i-1), lli%blon(i), ll_v(i,j,l), ilast, status )
  2696. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2697. end do
  2698. end if
  2699. end do ! loop over levels
  2700. end do ! loop over rows
  2701. ! free memory
  2702. call Done( sh )
  2703. deallocate( Pnm )
  2704. deallocate( ff )
  2705. deallocate( exp_hh )
  2706. deallocate( lons_fine )
  2707. deallocate( row_fine )
  2708. ! ok
  2709. status = 0
  2710. end subroutine IntLon_sh_ll
  2711. ! ***
  2712. subroutine IntLon_shi_ll( key, shi_in,nlev, F, H, da, db, lli, ll_v, status )
  2713. use grid_tools, only : deg2rad, pi
  2714. use Num, only : IntervalQuad_Lin
  2715. use Grid_Type_sh, only : TshGridInfo, TshGrid, Init, Done, SpN, Set, Check
  2716. use Grid_Type_sh, only : sh_Pnm, Eval_Lons
  2717. use Grid_Type_ll, only : TllGridInfo, Check
  2718. ! --- in/out -----------------------------------------
  2719. character(len=*), intent(in) :: key
  2720. type(TshGridInfo), intent(in) :: shi_in
  2721. integer, intent(in) :: nlev
  2722. complex, intent(in) :: F(shi_in%np,nlev)
  2723. complex, intent(in) :: H(shi_in%np)
  2724. real, intent(in) :: da(nlev)
  2725. real, intent(in) :: db(nlev)
  2726. type(TllGridInfo), intent(in) :: lli
  2727. real, intent(inout) :: ll_v(lli%im,0:lli%jm,nlev)
  2728. integer, intent(out) :: status
  2729. ! --- const --------------------------------------
  2730. character(len=*), parameter :: rname = mname//'/IntLon_shi_ll'
  2731. ! --- local ------------------------------------------
  2732. integer :: i, j
  2733. integer :: l
  2734. integer :: ilast
  2735. type(TshGridInfo) :: shi
  2736. integer :: T
  2737. ! type(TshGrid) :: sh
  2738. real, allocatable :: Pnm(:)
  2739. integer :: refinement_i
  2740. integer :: nlon_fine_360, nlon_fine
  2741. real, allocatable :: ff(:)
  2742. real, allocatable :: exp_hh(:)
  2743. real, allocatable :: lons_fine(:), row_fine(:)
  2744. logical :: pole
  2745. ! --- begin ------------------------------------------
  2746. ! use truncated harmonics ?
  2747. T = ShTruncation( shi_in%T, lli%dlon_deg, lli%dlat_deg )
  2748. ! T = ShTruncation( T, lli%dlon_deg, lli%dlat_deg )
  2749. call Init( shi, T ,status)
  2750. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2751. ! allocate space for legendre coeff:
  2752. allocate( Pnm(shi%np) )
  2753. ! determine refinement based on spectral resolution
  2754. ! and length of required integration interval:
  2755. refinement_i = ShRefinement( shi%T, lli%dlon_deg )
  2756. ! number of lons in fine grid on complete circle:
  2757. nlon_fine_360 = 360.0/lli%dlon_deg * refinement_i
  2758. nlon_fine = lli%im * refinement_i
  2759. ! store evaluation of spectral field:
  2760. allocate( ff(0:nlon_fine) )
  2761. allocate( exp_hh(0:nlon_fine) )
  2762. ! lons on arc westb+[0,..)
  2763. allocate( row_fine(0:nlon_fine) )
  2764. allocate( lons_fine(0:nlon_fine) )
  2765. do i = 0, nlon_fine
  2766. lons_fine(i) = i*2*pi/nlon_fine_360
  2767. end do
  2768. lons_fine = lli%blon(0) + lons_fine
  2769. ! loop over boundary latitudes in ll grid:
  2770. do j = 0, lli%jm
  2771. ! pole ? then int f(x) dx = f
  2772. pole = ( abs(lli%blat(j) - (-pi/2)) < 1.0e-4 ) .or. &
  2773. ( abs(lli%blat(j) - ( pi/2)) < 1.0e-4 )
  2774. ! evaluate Legendre functions:
  2775. call sh_Pnm( Pnm, shi%T, lli%blat(j), status )
  2776. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2777. ! evaluate rows:
  2778. ! call Set( sh, T, H )
  2779. ! call Eval_Lons( exp_hh, sh, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, status )
  2780. call Eval_Lons( shi_in,H,shi,Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1,exp_hh, status )
  2781. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2782. exp_hh = exp(exp_hh)
  2783. ! loop over levels
  2784. do l = 1, nlev
  2785. ! call Set( sh, T, F(l) )
  2786. ! call Eval_Lons( ff, sh, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, status )
  2787. call Eval_Lons( shi_in,F(:,l), shi, Pnm, nlon_fine_360, lons_fine(0), nlon_fine+1, ff,status )
  2788. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2789. ! combine fields:
  2790. select case ( key )
  2791. !
  2792. ! [ int exp(H) dlon ] / deltalon
  2793. !
  2794. case ( 'exp(H),aver' )
  2795. if ( pole ) then
  2796. row_fine = exp_hh
  2797. else
  2798. row_fine = exp_hh / lli%dlon
  2799. end if
  2800. !
  2801. ! int F (da+db*exp(H)) dlon
  2802. !
  2803. case ( '(da+exp*db)' )
  2804. if ( pole ) then
  2805. row_fine = 0.0
  2806. else
  2807. row_fine = ff * ( da(l) + exp_hh*db(l) )
  2808. end if
  2809. !
  2810. ! error ...
  2811. !
  2812. case default
  2813. print *, 'IntLon_sh_ll - unknown key "'//trim(key)//'"'
  2814. stop
  2815. end select
  2816. ! special treatment of poles:
  2817. if ( pole ) then
  2818. ! same value at al 'longitudes', thus for example the average ...
  2819. ll_v(:,j,l) = sum(row_fine)/size(row_fine)
  2820. else
  2821. ! integral in lon direction assuming linear interpolation,
  2822. ! result in [sh] rad
  2823. ilast = 1
  2824. do i = 1, lli%im
  2825. call IntervalQuad_Lin( lons_fine, row_fine, lli%blon(i-1), lli%blon(i), ll_v(i,j,l), ilast, status )
  2826. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  2827. end do
  2828. end if
  2829. end do ! loop over levels
  2830. end do ! loop over rows
  2831. ! free memory
  2832. call Done( shi )
  2833. deallocate( Pnm )
  2834. deallocate( ff )
  2835. deallocate( exp_hh )
  2836. deallocate( lons_fine )
  2837. deallocate( row_fine )
  2838. ! ok
  2839. status = 0
  2840. end subroutine IntLon_shi_ll
  2841. end module Grid_Interpol