grid_type_sh.F90 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049
  1. ! NAME
  2. ! grid_type_sh - manipulate spherical harmonic field
  3. !
  4. ! may 2002, Arjo Segers
  5. !
  6. module grid_type_sh
  7. implicit none
  8. ! --- in/out ----------------------------
  9. private
  10. public :: TshGridInfo
  11. public :: TshGrid
  12. public :: Init, Done, Check
  13. public :: SpN
  14. public :: Set
  15. public :: Truncate
  16. public :: sh_Pnm
  17. public :: FourrierCoeff
  18. public :: Eval
  19. public :: EvalFast
  20. public :: Eval_Lons
  21. public :: Nabla
  22. public :: vod2uv
  23. ! --- const ------------------------------
  24. character(len=*), parameter :: mname = 'grid_type_sh'
  25. ! --- types -------------------------
  26. ! Coefficients of Associated Legendre Function
  27. ! * Triangular truncation: m=0,..,M=T n=m,..,N=T
  28. ! * Coefficients p(m,n), stored in order:
  29. ! (m,n) = (0,0) (0,1) .. (0,N) (1,1) .. (1,N) ..
  30. ! The storage order is similar to the order used in the EMOS library.
  31. ! Only coefficients for m>=0 are stored, since
  32. ! for real valued ALF the p(-m,n)=conj(p(m,n) .
  33. type TshGridInfo
  34. integer :: T ! triangular truncation
  35. integer :: np ! number of data points
  36. end type TshGridInfo
  37. type TshGrid
  38. integer :: T
  39. complex, pointer :: c(:)
  40. end type TshGrid
  41. ! --- interfaces ----------------------
  42. interface Init
  43. module procedure shi_Init
  44. module procedure shi_Init_copy
  45. module procedure shgrid_Init
  46. module procedure shgrid_Init_T
  47. module procedure shgrid_Init_1
  48. module procedure shgrid_Init_1_T
  49. end interface
  50. interface Done
  51. module procedure shi_Done
  52. module procedure shgrid_Done
  53. module procedure shgrid_Done_1
  54. end interface
  55. interface Check
  56. module procedure shgrid_Check
  57. module procedure shgrid_Check_T_1
  58. module procedure shgrid_Check_T
  59. end interface
  60. interface Set
  61. module procedure shi_Set_T
  62. module procedure shi_Set_shi
  63. module procedure Set_T
  64. module procedure Set_c
  65. module procedure Set_sh
  66. module procedure Set_T_sh
  67. end interface
  68. interface Truncate
  69. module procedure shgrid_Truncate
  70. end interface
  71. interface FourrierCoeff
  72. module procedure shgrid_FourrierCoeff_pnm
  73. module procedure shi_FourrierCoeff_pnm
  74. module procedure shgrid_FourrierCoeff_pnm2
  75. end interface
  76. interface Eval
  77. module procedure shgrid_Eval_Xm_lon
  78. module procedure shgrid_Eval_Pnm_lon
  79. module procedure shgrid_Eval_lat_lon
  80. end interface
  81. interface EvalFast
  82. module procedure shgrid_Eval_Pnm_lon_fast
  83. end interface
  84. interface Eval_Lons
  85. module procedure shi_Eval_Lons_Ulat
  86. module procedure shi_Eval_Lons_UPnm_1
  87. module procedure shgrid_Eval_Lons_Ulat
  88. module procedure shgrid_Eval_Lons_UPnm_1
  89. module procedure shgrid_Eval_Lons_Xm_1
  90. end interface
  91. interface Nabla
  92. module procedure shgrid_Nabla
  93. end interface
  94. interface vod2uv
  95. module procedure sh_vod2uv
  96. module procedure shi_vod2uv
  97. end interface
  98. contains
  99. ! ====================================================================
  100. subroutine shi_Init( shi, T, status )
  101. ! --- in/out ------------------------------------
  102. type(TshGridInfo), intent(out) :: shi
  103. integer, intent(in) :: T
  104. integer, intent(out) :: status
  105. ! --- begin ----------------------------------
  106. ! store triangular trunction:
  107. shi%T = T
  108. ! number of complex data points:
  109. shi%np = SpN( shi%T )
  110. ! ok
  111. status = 0
  112. end subroutine shi_Init
  113. ! ***
  114. subroutine shi_Init_copy( shi, shi2, status )
  115. ! --- in/out ------------------------------------
  116. type(TshGridInfo), intent(out) :: shi
  117. type(TshGridInfo), intent(in) :: shi2
  118. integer, intent(out) :: status
  119. ! --- begin ----------------------------------
  120. call Init( shi, shi2%T, status )
  121. end subroutine shi_Init_copy
  122. ! ***
  123. subroutine shi_Done( shi )
  124. ! --- in/out ------------------------------------
  125. type(TshGridInfo), intent(inout) :: shi
  126. ! --- begin ----------------------------------
  127. ! nothing to be done ...
  128. end subroutine shi_Done
  129. ! ***
  130. subroutine shi_Set_T( shi, T )
  131. ! --- in/out ------------------------------------
  132. type(TshGridInfo), intent(out) :: shi
  133. integer, intent(in) :: T
  134. ! --- begin ----------------------------------
  135. shi%T = T
  136. end subroutine shi_Set_T
  137. ! ***
  138. subroutine shi_Set_shi( shi, shi2 )
  139. ! --- in/out ------------------------------------
  140. type(TshGridInfo), intent(out) :: shi
  141. type(TshGridInfo), intent(in) :: shi2
  142. ! --- begin ----------------------------------
  143. shi%T = shi2%T
  144. end subroutine shi_Set_shi
  145. ! ====================================================================
  146. subroutine shgrid_Init( SH )
  147. ! --- in/out ------------------------------------
  148. type(TshGrid), intent(out) :: SH
  149. ! --- begin ----------------------------------
  150. ! ! check arguments ...
  151. ! if (associated(SH%c)) then
  152. ! print *, 'shgrid_Init : coefficient array already associated ...'
  153. ! stop
  154. ! end if
  155. SH%T = -1
  156. nullify( SH%c )
  157. end subroutine shgrid_Init
  158. ! ***
  159. subroutine shgrid_Init_T( SH, T )
  160. ! --- in/out ------------------------------------
  161. type(TshGrid), intent(out) :: SH
  162. integer, intent(in) :: T
  163. ! --- begin ----------------------------------
  164. ! ! check arguments ...
  165. ! if (associated(SH%c)) then
  166. ! print *, 'shgrid_Init : coefficient array already associated ...'
  167. ! stop
  168. ! end if
  169. ! set Triangular Truncation
  170. if ( T < 0 ) then
  171. print *, 'shgrid_Init : tried to set triangular truncation ', T
  172. stop
  173. end if
  174. SH%T = T
  175. ! allocate ...
  176. allocate( SH%c(SpN(T)) )
  177. ! set to zero:
  178. SH%c = (0.0,0.0)
  179. end subroutine shgrid_Init_T
  180. ! ***
  181. subroutine shgrid_Init_1( SH )
  182. ! --- in/out ------------------------------------
  183. type(TshGrid), intent(out) :: SH(:)
  184. ! --- local ----------------------------------
  185. integer :: l
  186. ! --- begin ----------------------------------
  187. do l = 1, size(SH)
  188. ! ! check arguments ...
  189. ! if ( associated(SH(l)%c) ) then
  190. ! print *, 'shgrid_Init : coefficient array already associated ...'
  191. ! stop
  192. ! end if
  193. SH(l)%T = -1
  194. nullify( SH(l)%c )
  195. end do
  196. end subroutine shgrid_Init_1
  197. ! ***
  198. subroutine shgrid_Init_1_T( SH, T )
  199. ! --- in/out ------------------------------------
  200. type(TshGrid), intent(out) :: SH(:)
  201. integer, intent(in) :: T
  202. ! --- local ----------------------------------
  203. integer :: l
  204. ! --- begin ----------------------------------
  205. do l = 1, size(SH)
  206. ! ! check arguments ...
  207. ! if (associated(SH(l)%c)) then
  208. ! print *, 'shgrid_Init : coefficient array already associated ...'
  209. ! stop
  210. ! end if
  211. ! set Triangular Truncation
  212. if ( T < 0 ) then
  213. print *, 'shgrid_Init : tried to set triangular truncation ', T
  214. stop
  215. end if
  216. SH(l)%T = T
  217. ! allocate ...
  218. allocate( SH(l)%c(SpN(T)) )
  219. ! set to zero:
  220. SH(l)%c = (0.0,0.0)
  221. end do
  222. end subroutine shgrid_Init_1_T
  223. ! ***
  224. subroutine shgrid_Done( SH )
  225. ! --- in/out ------------------------------------
  226. type(TshGrid), intent(out) :: SH
  227. ! --- begin ----------------------------------
  228. ! deallocate if necessary ...
  229. if (associated(SH%c)) deallocate(SH%c)
  230. end subroutine shgrid_Done
  231. ! ***
  232. subroutine shgrid_Done_1( SH )
  233. ! --- in/out ------------------------------------
  234. type(TshGrid), intent(out) :: SH(:)
  235. ! --- local ----------------------------------
  236. integer :: l
  237. ! --- begin ----------------------------------
  238. ! deallocate if necessary ...
  239. do l = 1, size(SH)
  240. if ( associated(SH(l)%c) ) deallocate( SH(l)%c )
  241. end do
  242. end subroutine shgrid_Done_1
  243. ! ====================================================================
  244. ! call Check( SH ) : check wether T and c are consistent
  245. ! call Check( SH, T ) : check wether SH is truncated at T
  246. subroutine shgrid_Check( SH )
  247. ! --- in/out ----------------------------
  248. type(TshGrid), intent(in) :: SH
  249. ! --- begin ----------------------------
  250. if (SH%T<0) then
  251. if (associated(SH%c)) then
  252. print *, 'shgrid_Check : error : coefficient array associated', &
  253. ' while T<0'
  254. stop
  255. end if
  256. else
  257. if (.not.associated(SH%c)) then
  258. print *, 'shgrid_Check : error : coefficient array not associated'
  259. stop
  260. end if
  261. if (size(SH%c) < SpN(SH%T) ) then
  262. print *, 'shgrid_Check : error : coefficient array has size ', size(SH%c), &
  263. 'while triangular truncation ', SH%T, &
  264. 'requires spectral number ', SpN(SH%T)
  265. stop
  266. end if
  267. end if
  268. end subroutine shgrid_Check
  269. ! ===
  270. subroutine shgrid_Check_T( SH, T )
  271. ! --- in/out ----------------------------
  272. type(TshGrid), intent(in) :: SH
  273. integer, intent(in) :: T
  274. ! --- begin ----------------------------
  275. if ( T < 0 ) then
  276. print *, 'shgrid_Check : tried to check for truncation ', T
  277. stop
  278. end if
  279. if ( SH%T /= T ) then
  280. print *, 'shgrid_Check : truncated at ', SH%T, ' instead of ', T
  281. stop
  282. end if
  283. if (.not.associated(SH%c)) then
  284. print *, 'shgrid_Check : error : coefficient array not associated'
  285. stop
  286. end if
  287. if (size(SH%c) < SpN(SH%T) ) then
  288. print *, 'shgrid_Check : error : coefficient array has size ', size(SH%c), &
  289. 'while triangular truncation ', SH%T, &
  290. 'requires spectral number ', SpN(SH%T)
  291. stop
  292. end if
  293. end subroutine shgrid_Check_T
  294. ! ===
  295. subroutine shgrid_Check_T_1( SH, T )
  296. ! --- in/out ----------------------------
  297. type(TshGrid), intent(in) :: SH(:)
  298. integer, intent(in) :: T
  299. ! --- local ---------------------------
  300. integer :: l
  301. ! --- begin ----------------------------
  302. do l = 1, size(SH)
  303. call Check( SH(l), T )
  304. end do
  305. end subroutine shgrid_Check_T_1
  306. ! ====================================================================
  307. ! Spectral number : SN = (T+1)*(T+2)/2
  308. ! (half triangle m=0,..,T , n=m,..,T ;
  309. ! we assume real restult thus only m>=0 required)
  310. integer function SpN( TT )
  311. ! --- in/out -----------------
  312. integer, intent(in) :: TT ! triangular truncation
  313. ! --- begin ------------------
  314. SpN = (TT+1)*(TT+2)/2
  315. end function SpN
  316. ! ====================================================================
  317. subroutine Set_T( SH, TT )
  318. ! --- in/out -------------------------
  319. type(TshGrid), intent(inout) :: SH
  320. integer, intent(in) :: TT
  321. ! --- local ---------------------------
  322. integer :: SN
  323. ! --- in/out -------------------------
  324. call check( SH )
  325. ! -- set triangular truncation
  326. ! check ...
  327. if ( TT < 0 ) then
  328. print *, 'Set : tried to set triangular truncation ', TT
  329. stop
  330. end if
  331. ! set:
  332. SH%T = TT
  333. ! -- set spectral coefficients
  334. ! number of coeff to be set:
  335. SN = SpN(SH%T)
  336. ! (de)allocate coefficient array if necessary ...
  337. if ( associated(SH%c) ) then
  338. if ( size(SH%c)/=SN ) deallocate(SH%c)
  339. end if
  340. if (.not. associated(SH%c) ) allocate(SH%c(SN))
  341. ! fill with zeros
  342. SH%c = (0.0,0.0)
  343. end subroutine Set_T
  344. ! ===
  345. subroutine Set_c( SH, TT, c )
  346. ! --- in/out -------------------------
  347. type(TshGrid), intent(inout) :: SH
  348. integer, intent(in) :: TT
  349. complex, intent(in) :: c(:)
  350. ! --- local ---------------------------
  351. integer :: SN
  352. ! --- in/out -------------------------
  353. ! init with zeros:
  354. call Set( SH, TT )
  355. ! number of coeff to be set:
  356. SN = SpN(SH%T)
  357. ! fill with c
  358. if ( size(c) /= SN ) then
  359. print *, 'Set_c : size of input array is ', size(c), &
  360. ' while triangular truncation ', TT, ' requires ', SN, &
  361. ' spectral coefficients'
  362. stop
  363. end if
  364. SH%c = c
  365. end subroutine Set_c
  366. ! *
  367. subroutine Set_T_sh( SH, TT, sh2 )
  368. ! --- in/out -------------------------
  369. type(TshGrid), intent(inout) :: SH
  370. integer, intent(in) :: TT
  371. type(TshGrid), intent(in) :: sh2
  372. ! --- in/out -------------------------
  373. ! init with full truncation:
  374. call Set( SH, sh2%T, sh2%c )
  375. ! truncate to requested number:
  376. call Truncate( SH, TT )
  377. end subroutine Set_T_sh
  378. ! *
  379. subroutine Set_sh( SH, sh2 )
  380. ! --- in/out -------------------------
  381. type(TshGrid), intent(inout) :: SH
  382. type(TshGrid), intent(in) :: sh2
  383. ! --- in/out -------------------------
  384. ! init with full truncation:
  385. call Set( SH, sh2%T, sh2%c )
  386. end subroutine Set_sh
  387. ! ====================================================================
  388. ! truncates spherical harmonic coeffiecients to lower
  389. ! triangular truncation.
  390. subroutine shgrid_Truncate( SH, T_new )
  391. ! --- in/out ------------------------------
  392. type(TshGrid), intent(inout) :: SH
  393. integer, intent(in) :: T_new
  394. ! --- local ----------------------------
  395. integer :: T, m, n
  396. integer :: k, k_new
  397. complex, allocatable :: c_new(:)
  398. ! ---- begin ----------------------------
  399. ! check arguments ...
  400. call Check( SH )
  401. if (T_new<0) then
  402. print *, 'shgrid_Truncate : error : tried to truncate to T=', T_new
  403. stop
  404. end if
  405. if (T_new > SH%T) then
  406. print *, 'shgrid_Truncate : error : tried to truncate to T=', T_new, &
  407. ' while input spherical harmonics are truncated at ', SH%T
  408. stop
  409. end if
  410. ! shorthands:
  411. T = SH%T
  412. ! truncate only if necessary ...
  413. if ( T_new < T ) then
  414. ! allocate temporary array for truncated coefficients:
  415. allocate( c_new(SpN(T_new)) )
  416. ! loop over original triangle for m <= T_new;
  417. k = 0
  418. k_new = 0
  419. do m = 0, T_new
  420. do n = m, T
  421. k = k + 1
  422. if (n <= T_new) then
  423. k_new = k_new + 1
  424. c_new(k_new) = SH%c(k)
  425. end if
  426. end do
  427. end do
  428. ! fill SH with truncated coefficients:
  429. call Set( SH, T_new, c_new )
  430. ! done
  431. deallocate( c_new )
  432. end if
  433. end subroutine shgrid_Truncate
  434. ! =======================================================
  435. !
  436. ! Evaluate associate Legendre functions at given latitude.
  437. ! Corner (T,T) is set to 0.0 .
  438. !
  439. ! Based on recurent formula:
  440. !
  441. !
  442. ! mu P(mu;m,n-1) = eps(m,n) P(mu;m,n) + eps(m,n-1) P(mu;m,n-2)
  443. !
  444. ! n^2 - m^2
  445. ! mu = sin(lat) , eps(m,n) = sqrt( --------- )
  446. ! 4n^2 - 1
  447. !
  448. ! P(m,n) = ( mu P(m,n-1) - eps(m,n-1) P(m,n-2) ) / eps(m,n)
  449. !
  450. !
  451. ! P(0,0) = 1
  452. !
  453. !
  454. ! P(0,1) = mu / eps(0,1) = mu sqrt(3)
  455. !
  456. !
  457. ! 2m+1 1/2 sqrt(1-mu^2)^m
  458. ! P(m,m) = ( ----- ) -------------- (2m)!
  459. ! (2m)! 2^m m!
  460. !
  461. ! sqrt(1-mu^2)^m
  462. ! = sqrt((2m+1)!) --------------
  463. ! 2^m m!
  464. !
  465. ! sqrt(1-mu^2)sqrt(1-mu^2)^(m-1)
  466. ! = sqrt((2m+1)2m(2(m-1))!) ------------------------------
  467. ! 2 2^(m-1) m (m-1)!
  468. !
  469. ! cos(lat)
  470. ! = P(m-1,m-1) sqrt((2m+1)2m) --------
  471. ! 2m
  472. !
  473. ! = P(m-1,m-1) sqrt((2m+1)) cos(lat) / sqrt(2m)
  474. !
  475. ! P(m,m+1) = mu P(m,m) / eps(m,m+1)
  476. !
  477. !
  478. subroutine sh_Pnm( Pnm, T, lat, status )
  479. ! --- in/out ----------------------------------
  480. real, intent(out) :: Pnm(:)
  481. integer, intent(in) :: T
  482. real, intent(in) :: lat ! rad
  483. integer, intent(out) :: status
  484. ! --- const --------------------------------------
  485. character(len=*), parameter :: rname = mname//'/sh_Pnm'
  486. ! --- local ------------------------------------
  487. integer :: m, n
  488. integer :: k
  489. real :: mu, rmu
  490. real :: fmm, fmmp
  491. real :: eps, eps1
  492. ! --- begin ---------------------------------------
  493. ! Use EMOS library:
  494. !Pnm = 0.0
  495. !call jspleg1( Pnm, lat, T-1 )
  496. !return
  497. if ( size(Pnm) /= SpN(T) ) then
  498. write (*,'("ERROR - wrong size of output array:")')
  499. write (*,'("ERROR - size(Pnm) : ",i6)') size(Pnm)
  500. write (*,'("ERROR - expected : ",i6)') SpN(T)
  501. write (*,'("ERROR - truncation : ",i6)') T
  502. write (*,'("ERROR in ",a)') rname; status=1; return
  503. end if
  504. mu = sin(lat)
  505. rmu = sqrt(1.0-mu*mu) ! cos(lat)
  506. do m = 0, T-1
  507. if ( m == 0 ) then
  508. fmmp = sqrt(3.0)
  509. k = 1; Pnm(k) = 1.0 ! (0,0)
  510. k = 2; Pnm(k) = fmmp*mu ! (0,1)
  511. else
  512. fmm = fmmp * rmu / sqrt( 2.0*m )
  513. fmmp = fmm * sqrt( 2*m + 3.0 )
  514. ! n = m and n = m+1
  515. k = k+1; Pnm(k) = fmm
  516. k = k+1; Pnm(k) = fmmp * mu
  517. endif
  518. ! leave if truncation is reached:
  519. if ( m == T-1 ) exit
  520. eps1 = 1.0 / sqrt( 2*m + 3.0 )
  521. do n = m+2, T
  522. eps = sqrt((n*n*1.0-m*m*1.0)/(4.0*n*n-1.0))
  523. k = k+1; Pnm(k) = ( mu*Pnm(k-1) - eps1*Pnm(k-2) ) / eps
  524. eps1 = eps
  525. end do
  526. end do
  527. ! set corner:
  528. k = k + 1; Pnm(k) = 0.0
  529. ! ok
  530. status = 0
  531. end subroutine sh_Pnm
  532. ! ***
  533. !! same, but without if statements in do loop
  534. !! (faster on some compilers)
  535. !
  536. !subroutine sh_Pnm_fast( Pnm, T, lat, status )
  537. !
  538. ! ! --- in/out ----------------------------------
  539. !
  540. ! real, intent(out) :: Pnm(:)
  541. ! integer, intent(in) :: T
  542. ! real, intent(in) :: lat ! rad
  543. ! integer, intent(out) :: status
  544. !
  545. ! ! --- const --------------------------------------
  546. !
  547. ! character(len=*), parameter :: rname = mname//'/sh_Pnm_fast'
  548. !
  549. ! ! --- local ------------------------------------
  550. !
  551. ! integer :: m, n
  552. ! integer :: k
  553. ! real :: mu, rmu
  554. ! real :: fmm, fmmp
  555. ! real :: eps, eps1
  556. !
  557. ! ! --- begin ---------------------------------------
  558. !
  559. ! ! Use EMOS library:
  560. ! !Pnm = 0.0
  561. ! !call jspleg1( Pnm, lat, T-1 )
  562. ! !return
  563. !
  564. ! if ( size(Pnm) /= SpN(T) ) then
  565. ! write (*,'("ERROR - wrong size of output array:")')
  566. ! write (*,'("ERROR - size(Pnm) : ",i6)') size(Pnm)
  567. ! write (*,'("ERROR - expected : ",i6)') SpN(T)
  568. ! write (*,'("ERROR - truncation : ",i6)') T
  569. ! write (*,'("ERROR in ",a)') rname; status=1; return
  570. ! end if
  571. !
  572. ! mu = sin(lat)
  573. ! rmu = sqrt(1.0-mu*mu) ! cos(lat)
  574. !
  575. ! ! -- first m
  576. !
  577. ! m = 0
  578. !
  579. ! fmmp = sqrt(3.0)
  580. ! k = 1; Pnm(k) = 1.0 ! (0,0)
  581. ! k = 2; Pnm(k) = fmmp*mu ! (0,1)
  582. !
  583. ! eps1 = 1.0 / sqrt( 2*m + 3.0 )
  584. !
  585. ! do n = m+2, T
  586. !
  587. ! eps = sqrt((n*n*1.0-m*m*1.0)/(4.0*n*n-1.0))
  588. ! k = k+1; Pnm(k) = ( mu*Pnm(k-1) - eps1*Pnm(k-2) ) / eps
  589. ! eps1 = eps
  590. !
  591. ! end do
  592. !
  593. ! ! -- 0 < m < T-1
  594. !
  595. ! do m = 1, T-2
  596. !
  597. ! fmm = fmmp * rmu / sqrt( 2.0*m )
  598. ! fmmp = fmm * sqrt( 2*m + 3.0 )
  599. !
  600. ! ! n = m and n = m+1
  601. !
  602. ! k = k+1; Pnm(k) = fmm
  603. ! k = k+1; Pnm(k) = fmmp * mu
  604. !
  605. ! eps1 = 1.0 / sqrt( 2*m + 3.0 )
  606. !
  607. ! do n = m+2, T
  608. !
  609. ! eps = sqrt((n*n*1.0-m*m*1.0)/(4.0*n*n-1.0))
  610. ! k = k+1; Pnm(k) = ( mu*Pnm(k-1) - eps1*Pnm(k-2) ) / eps
  611. ! eps1 = eps
  612. !
  613. ! end do
  614. !
  615. ! end do
  616. !
  617. ! ! -- m = T-1
  618. !
  619. ! m = T-1
  620. !
  621. ! fmm = fmmp * rmu / sqrt( 2.0*m )
  622. ! fmmp = fmm * sqrt( 2*m + 3.0 )
  623. !
  624. ! ! n = m and n = m+1
  625. !
  626. ! k = k+1; Pnm(k) = fmm
  627. ! k = k+1; Pnm(k) = fmmp * mu
  628. !
  629. ! eps1 = 1.0 / sqrt( 2*m + 3.0 )
  630. !
  631. ! do n = m+2, T
  632. !
  633. ! eps = sqrt((n*n*1.0-m*m*1.0)/(4.0*n*n-1.0))
  634. ! k = k+1; Pnm(k) = ( mu*Pnm(k-1) - eps1*Pnm(k-2) ) / eps
  635. ! eps1 = eps
  636. !
  637. ! end do
  638. !
  639. ! ! set corner:
  640. ! k = k + 1; Pnm(k) = 0.0
  641. !
  642. !
  643. !end subroutine sh_Pnm_fast
  644. ! ====================================================================
  645. ! M N i m lon
  646. ! Eval(p,lon,lat) = sum sum p(m,n) P(m,n,sin(lat)) e
  647. ! m=-M n=m
  648. !
  649. ! M
  650. ! = c(0) + sum 2[Re{c(m)}cos(m lon) - Im{c(m)}sin(m lon)] ,
  651. ! m=1
  652. !
  653. ! N
  654. ! c(m) = sum p(m,n) P(m,n,sin(lat))
  655. ! n=m
  656. !
  657. real function shgrid_Eval_Xm_lon( Xm, T, lon )
  658. ! --- in/out -------------------------
  659. integer, intent(in) :: T
  660. complex, intent(in) :: Xm(0:T)
  661. real, intent(in) :: lon
  662. ! --- local --------------------------
  663. integer :: m
  664. ! --- begin --------------------------
  665. ! summation over triangle
  666. shgrid_eval_Xm_lon = Xm(0)
  667. do m = 1, T
  668. shgrid_eval_Xm_lon = shgrid_eval_Xm_lon + 2.0*( real(Xm(m))*cos(m*lon) - aimag(Xm(m))*sin(m*lon) )
  669. end do
  670. end function shgrid_Eval_Xm_lon
  671. ! ***
  672. real function shgrid_Eval_Pnm_lon( SH, Pnm, lon )
  673. ! --- in/out -------------------------
  674. type(TshGrid), intent(in) :: SH
  675. real, intent(in) :: Pnm(:)
  676. real, intent(in) :: lon
  677. ! --- local --------------------------
  678. integer :: T, SN
  679. integer :: m, n, k
  680. complex :: cm
  681. ! --- begin --------------------------
  682. ! shorthands:
  683. T = SH%T
  684. SN = SpN(T)
  685. ! check arguments:
  686. call Check( SH )
  687. if ( size(Pnm) /= SN ) then
  688. print *, 'shgrid_FourrierCoeff_pnm : size(Pnm)=',size(Pnm), &
  689. 'while',SN,'expected for T',T
  690. stop
  691. end if
  692. ! summation over triangle
  693. k = 0
  694. do m = 0, T
  695. cm = (0.0,0.0)
  696. do n = m, T
  697. k = k + 1
  698. cm = cm + SH%c(k) * Pnm(k)
  699. end do
  700. if (m==0) then
  701. shgrid_eval_Pnm_lon = real(cm)
  702. else
  703. shgrid_eval_Pnm_lon = shgrid_eval_Pnm_lon + 2.0*( real(cm)*cos(m*lon) - aimag(cm)*sin(m*lon) )
  704. end if
  705. end do
  706. end function shgrid_Eval_Pnm_lon
  707. ! ***
  708. real function shgrid_Eval_Pnm_lon_fast( SH, Pnm, lon )
  709. ! --- in/out -------------------------
  710. type(TshGrid), intent(in) :: SH
  711. real, intent(in) :: Pnm(:)
  712. real, intent(in) :: lon
  713. ! --- local --------------------------
  714. integer :: T, SN
  715. integer :: m, n, k
  716. complex :: cm
  717. complex :: cp(size(Pnm))
  718. real :: res
  719. ! --- begin --------------------------
  720. ! shorthands:
  721. T = SH%T
  722. SN = SpN(T)
  723. ! check arguments:
  724. call Check( SH )
  725. if ( size(Pnm) /= SN ) then
  726. print *, 'shgrid_FourrierCoeff_pnm : size(Pnm)=',size(Pnm), &
  727. 'while',SN,'expected for T',T
  728. stop
  729. end if
  730. cp = SH%c * Pnm
  731. ! summation over triangle
  732. res = sum( cp(1:T+1) )
  733. k = T+2
  734. do m = 1, T
  735. cm = sum( cp(k:k+T-m) )
  736. k = k + T-m+1
  737. res = res + 2.0*( real(cm)*cos(m*lon) - aimag(cm)*sin(m*lon) )
  738. end do
  739. shgrid_eval_Pnm_lon_fast = res
  740. end function shgrid_Eval_Pnm_lon_fast
  741. ! ***
  742. real function shgrid_Eval_lat_lon( SH, lat, lon, status )
  743. ! --- in/out -------------------------
  744. type(TshGrid), intent(in) :: SH
  745. real, intent(in) :: lon, lat
  746. integer, intent(out) :: status
  747. ! --- const --------------------------------------
  748. character(len=*), parameter :: rname = mname//'/shgrid_Eval_lat_lon'
  749. ! --- local --------------------------
  750. integer :: T
  751. real, allocatable :: Pnm(:)
  752. ! --- begin --------------------------
  753. ! check arguments:
  754. call Check( SH )
  755. ! shorthands:
  756. T = SH%T
  757. ! allocate array for associated Legendre functions:
  758. allocate( Pnm(SpN(T)) )
  759. ! evaluate Legendre functions at given latitude:
  760. call sh_Pnm( Pnm, T, lat, status )
  761. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  762. ! expand summation:
  763. shgrid_Eval_lat_lon = Eval( SH, Pnm, lon )
  764. ! done
  765. deallocate( Pnm )
  766. ! ok
  767. status = 0
  768. end function shgrid_Eval_lat_lon
  769. ! ==============================================
  770. ! compute Fourrier coefficients:
  771. !
  772. ! T
  773. ! X(m;mu) = sum U(m,n) P(m,n;mu) = Xe(m;mu) + Xo(m;mu)
  774. ! n=|m|
  775. !
  776. ! T T
  777. ! = sum U(m,n) P(m,n;mu) + sum U(m,n) P(m,n;mu)
  778. ! n=|m| n=|m|
  779. ! (n-m) even (n-m) odd
  780. !
  781. ! and return coefficients for both +mu and -mu using that
  782. !
  783. ! X(m,1) = X(m;+mu) = Xe(m;mu) + Xo(m;mu) 'north'
  784. !
  785. ! X(m,2) = X(m;-mu) = Xe(m;mu) - Xo(m;mu) 'south'
  786. !
  787. ! (valid for real symmetric Pmn(mu) )
  788. ! subroutine shgrid_FourrierCoeff( Xnm, Pnm, T, X )
  789. !
  790. ! ! --- in/out -----------------------------------
  791. !
  792. ! type(TshGrid), intent(in) :: Xnm, Pnm
  793. ! integer, intent(in) :: T
  794. ! complex, intent(out) :: X(0:T,2)
  795. !
  796. ! ! --- local ---------------------------------
  797. !
  798. ! complex :: Xe, Xo
  799. ! integer :: m, n, k
  800. !
  801. ! ! --- begin ----------------------------------
  802. !
  803. ! ! check input ...
  804. ! call Check( Xnm, T )
  805. ! call Check( Pnm, T )
  806. !
  807. ! ! loop over all coeff:
  808. ! m = 0
  809. ! n = 0
  810. ! Xe = (0.0,0.0)
  811. ! Xo = (0.0,0.0)
  812. ! do k = 1, SpN(T)
  813. ! if ( mod(n+m,2)==0 ) then
  814. ! Xe = Xe + Xnm%c(k)*Pnm%c(k)
  815. ! else
  816. ! Xo = Xo + Xnm%c(k)*Pnm%c(k)
  817. ! end if
  818. ! ! next n
  819. ! n = n + 1
  820. ! ! end of current m ?
  821. ! if ( n > T ) then
  822. ! ! save fourrier coeff for current m :
  823. ! X(m,1) = Xe + Xo
  824. ! X(m,2) = Xe - Xo
  825. ! ! next m
  826. ! m = m + 1
  827. ! n = m
  828. ! Xe = (0.0,0.0)
  829. ! Xo = (0.0,0.0)
  830. ! end if
  831. ! end do
  832. !
  833. ! ! adhoc: ensure that X(0) is real:
  834. ! X(0,:) = real(X(0,:)) * (1.0,0.0)
  835. !
  836. ! end subroutine shgrid_FourrierCoeff
  837. subroutine shgrid_FourrierCoeff_pnm( Xnm, Pnm, T, X )
  838. ! --- in/out -----------------------------------
  839. type(TshGrid), intent(in) :: Xnm
  840. real, intent(in) :: Pnm(:)
  841. integer, intent(in) :: T
  842. complex, intent(out) :: X(0:T)
  843. ! --- local ---------------------------------
  844. complex :: Xe, Xo
  845. integer :: m, n, k
  846. ! --- begin ----------------------------------
  847. ! check input ...
  848. call Check( Xnm, T )
  849. if ( size(Pnm) /= SpN(T) ) then
  850. print *, 'shgrid_FourrierCoeff_pnm : size(Pnm)=',size(Pnm), &
  851. 'while',SpN(T),'expected for T',T
  852. stop
  853. end if
  854. ! loop over all coeff:
  855. k = 0
  856. do m = 0, T
  857. X(m) = (0.0,0.0)
  858. do n = m, T
  859. k = k + 1
  860. X(m) = X(m) + Xnm%c(k) * Pnm(k)
  861. end do
  862. end do
  863. ! adhoc: ensure that X(0) is real:
  864. X(0) = real(X(0)) * (1.0,0.0)
  865. end subroutine shgrid_FourrierCoeff_pnm
  866. ! ***
  867. pure subroutine shi_FourrierCoeff_pnm( shi_in, Xnm, shi, Pnm, X )
  868. ! --- in/out -----------------------------------
  869. type(TshGridInfo), intent(in) :: shi_in
  870. complex, intent(in) :: Xnm(1:shi_in%np)
  871. type(TshGridInfo), intent(in) :: shi
  872. real, intent(in) :: Pnm(1:shi%np)
  873. complex, intent(out) :: X(0:shi%T)
  874. ! --- const --------------------------------------
  875. character(len=*), parameter :: rname = mname//'/shi_FourrierCoeff_pnm'
  876. ! --- local ---------------------------------
  877. integer :: m, n, kx, kp
  878. ! --- begin ----------------------------------
  879. #ifdef check_all
  880. ! check input ...
  881. if ( shi_in%T < shi%T ) then
  882. write (*,'("ERROR - input truncation should not be less than output:")')
  883. write (*,'("ERROR - shi_in%T : ",i6)') shi_in%T
  884. write (*,'("ERROR - shi%T : ",i6)') shi%T
  885. write (*,'("ERROR in ",a)') rname; stop
  886. end if
  887. if ( size(Xnm) /= shi_in%np ) then
  888. write (*,'("ERROR - mismatch between size of Xnm and specified truncation:")')
  889. write (*,'("ERROR - shi_in%T : ",i6)') shi_in%T
  890. write (*,'("ERROR - shi_in%np : ",i6)') shi_in%np
  891. write (*,'("ERROR - Xnm : ",i6)') size(Xnm)
  892. write (*,'("ERROR in ",a)') rname; stop
  893. end if
  894. if ( size(Pnm) /= shi%np ) then
  895. write (*,'("ERROR - mismatch between size of Pnm and specified truncation:")')
  896. write (*,'("ERROR - shi%T : ",i6)') shi%T
  897. write (*,'("ERROR - shi%np : ",i6)') shi%np
  898. write (*,'("ERROR - Pnm : ",i6)') size(Pnm)
  899. write (*,'("ERROR in ",a)') rname; stop
  900. end if
  901. #endif
  902. ! loop over all coeff:
  903. kx = 0
  904. kp = 0
  905. do m = 0, shi%T
  906. X(m) = (0.0,0.0)
  907. do n = m, shi%T
  908. kx = kx + 1
  909. kp = kp + 1
  910. X(m) = X(m) + Xnm(kx) * Pnm(kp)
  911. end do
  912. kx = kx + shi_in%T - shi%T
  913. end do
  914. ! adhoc: ensure that X(0) is real:
  915. X(0) = real(X(0)) * (1.0,0.0)
  916. end subroutine shi_FourrierCoeff_pnm
  917. ! ***
  918. subroutine shgrid_FourrierCoeff_pnm2( Xnm, Pnm, T, X )
  919. ! --- in/out -----------------------------------
  920. type(TshGrid), intent(in) :: Xnm
  921. real, intent(in) :: Pnm(:)
  922. integer, intent(in) :: T
  923. complex, intent(out) :: X(0:T,2)
  924. ! --- local ---------------------------------
  925. complex :: Xe, Xo
  926. integer :: m, n, k
  927. ! --- begin ----------------------------------
  928. ! check input ...
  929. call Check( Xnm, T )
  930. if ( size(Pnm) /= SpN(T) ) then
  931. print *, 'shgrid_FourrierCoeff_pnm : size(Pnm)=',size(Pnm), &
  932. 'while',SpN(T),'expected for T',T
  933. stop
  934. end if
  935. ! loop over all coeff:
  936. m = 0
  937. n = 0
  938. Xe = (0.0,0.0)
  939. Xo = (0.0,0.0)
  940. do k = 1, SpN(T)
  941. if ( mod(n+m,2)==0 ) then
  942. Xe = Xe + Xnm%c(k)*Pnm(k)
  943. else
  944. Xo = Xo + Xnm%c(k)*Pnm(k)
  945. end if
  946. ! next n
  947. n = n + 1
  948. ! end of current m ?
  949. if ( n > T ) then
  950. ! save fourrier coeff for current m :
  951. X(m,1) = Xe + Xo
  952. X(m,2) = Xe - Xo
  953. ! next m
  954. m = m + 1
  955. n = m
  956. Xe = (0.0,0.0)
  957. Xo = (0.0,0.0)
  958. end if
  959. end do
  960. ! adhoc: ensure that X(0) is real:
  961. X(0,:) = real(X(0,:)) * (1.0,0.0)
  962. end subroutine shgrid_FourrierCoeff_pnm2
  963. ! ====
  964. !
  965. ! Evaluate x(lat) and x(-lat) given:
  966. ! Xnm : complex Associated Legendre Func. coefficients
  967. ! Pnm : Associated Legendre Functions evaluated at mu=sin(lat)
  968. ! K : number of lon values on a complete latitude circle;
  969. ! distance between to lon values is thus 2pi/K;
  970. ! lon0 : western boundary of lon grid (rad)
  971. ! Kout : actual number of lon points from lon0 to east .
  972. !
  973. ! Evaluation at oposite latitdues at the same time saves some
  974. ! computation time.
  975. !
  976. ! x(t0+k2pi/K) , k=0,1,..,K0-1
  977. !
  978. ! T i m [t0 + k 2pi/K]
  979. ! = sum X(m) e , k=0,1,..,K0-1
  980. ! m=-T
  981. !
  982. ! L such that KL >= (2T+1)
  983. ! k=(j+1)/L , j=kL-1 , J=KL
  984. !
  985. ! T i m t0 i m (j+1)2pi/KL
  986. ! = sum X(m) e e , j=-1,L-1,2L-1,...,(K0-1)L-1
  987. ! m=-T
  988. !
  989. ! T im[t0+2pi/J] i m j 2pi/J
  990. ! = sum [X(m)e ] e , j=-1,L-1,2L-1,...,(K0-1)L-1
  991. ! m=-T
  992. !
  993. ! _
  994. ! X(m) = X(m) exp(i phi) , phi=m[t0+2pi/J]
  995. ! = (a+ib)(cos(phi)+isin(phi))
  996. ! = [ a cos(phi) - b sin(phi) ] + i [ a sin(phi) + b cos(phi) ]
  997. !
  998. ! FFT99 uses that X(-m) = conjg(X(m)), and thus requires X(m) for m>=0 only;
  999. ! higher fourrier coefficients are zero:
  1000. ! X(0) X(1) ... X(T) 0 0 0 ...
  1001. ! |--- 1+floor(J/2) elements ---|
  1002. !
  1003. ! o o x x x 0 0 ... 0 0 x x
  1004. ! m = 0 1 2 J-2 J-1
  1005. !
  1006. ! Number of K longitudes on complete latitude circle,
  1007. ! while Kout evaluations are required.
  1008. ! Note that Kout might be both smaller and larger than K.
  1009. ! Routine FFT99 returns J+2 evaluations:
  1010. ! x(j=-1) x(j=0) ... x(j=J-1=-1) x(j=J=0)
  1011. ! thus if Kout exceeds K+2 then the result should be taken
  1012. ! cyclic from the output of FFT99.
  1013. !
  1014. ! Evaluate given spherical harmonic coefficients and latitude
  1015. subroutine shi_Eval_Lons_Ulat( shi, Xnm, lat, KK, lon_start, Kout, llgrid, status )
  1016. ! --- in/out -------------------------
  1017. type(TshGridInfo), intent(in) :: shi
  1018. complex, intent(in) :: Xnm(1:shi%np)
  1019. real, intent(in) :: lat
  1020. integer, intent(in) :: KK
  1021. real, intent(in) :: lon_start
  1022. integer, intent(in) :: Kout
  1023. real,intent(out) :: llgrid(Kout)
  1024. integer, intent(out) :: status
  1025. ! --- const --------------------------------------
  1026. character(len=*), parameter :: rname = mname//'/shi_Eval_Lons_Ulat'
  1027. ! --- local --------------------------
  1028. complex :: X(0:shi%T)
  1029. real :: Pnm(1:shi%np)
  1030. ! --- begin --------------------------
  1031. ! evaluate Legendre functions at given latitude:
  1032. call sh_Pnm( Pnm, shi%T, lat, status )
  1033. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1034. ! compute Fourrier coefficients
  1035. ! (latitude is implicit defined in Pnm)
  1036. call FourrierCoeff( shi, Xnm, shi, Pnm, X )
  1037. ! evaluate at longitudes given Fourrier coefficients:
  1038. call Eval_Lons( llgrid, X, shi%T, KK, lon_start, Kout )
  1039. ! ok
  1040. status = 0
  1041. end subroutine shi_Eval_Lons_Ulat
  1042. ! *
  1043. subroutine shgrid_Eval_Lons_Ulat( llgrid, Xnm, lat, KK, lon_start, Kout, status )
  1044. ! --- in/out -------------------------
  1045. type(TshGrid), intent(in) :: Xnm
  1046. real, intent(in) :: lat
  1047. integer, intent(in) :: KK
  1048. real, intent(in) :: lon_start
  1049. integer, intent(in) :: Kout
  1050. real,intent(out) :: llgrid(Kout)
  1051. integer, intent(out) :: status
  1052. ! --- const --------------------------------------
  1053. character(len=*), parameter :: rname = mname//'/shgrid_Eval_Lons_Ulat'
  1054. ! --- local --------------------------
  1055. integer :: T
  1056. complex, allocatable :: X(:,:)
  1057. real, allocatable :: Pnm(:)
  1058. ! --- begin --------------------------
  1059. ! timing:
  1060. ! spleg1 65 %
  1061. ! fourrier 25 %
  1062. ! eval 10 %
  1063. ! extract triangular truncation
  1064. T = Xnm%T
  1065. ! allocate array for associated Legendre functions:
  1066. allocate( Pnm(SpN(T)) )
  1067. ! evaluate Legendre functions at given latitude:
  1068. call sh_Pnm( Pnm, T, lat, status )
  1069. if (status/=0) then; write (*,'("ERROR in ",a)') rname; status=1; return; end if
  1070. ! compute Fourrier coefficients
  1071. ! (latitude is implicit defined in Pnm)
  1072. allocate( X(0:T,2) )
  1073. call FourrierCoeff( Xnm, Pnm, T, X )
  1074. ! evaluate at longitudes given Fourrier coefficients:
  1075. call Eval_Lons( llgrid, X(:,1), T, KK, lon_start, Kout )
  1076. ! done
  1077. deallocate( X )
  1078. deallocate( Pnm )
  1079. ! ok
  1080. status = 0
  1081. end subroutine shgrid_Eval_Lons_Ulat
  1082. ! ***
  1083. ! Evaluate given spherical harmonic coefficients and Legendre functions
  1084. subroutine shgrid_Eval_Lons_UPnm_1( llgrid, Xnm, Pnm, KK, lon_start, Kout, status )
  1085. ! --- in/out -------------------------
  1086. type(TshGrid), intent(in) :: Xnm
  1087. real, intent(in) :: Pnm(:)
  1088. integer, intent(in) :: KK
  1089. real, intent(in) :: lon_start
  1090. integer, intent(in) :: Kout
  1091. real,intent(out) :: llgrid(Kout)
  1092. integer, intent(out) :: status
  1093. ! --- const --------------------------------------
  1094. character(len=*), parameter :: rname = mname//'/shgrid_Eval_Lons_UPnm_1'
  1095. ! --- local --------------------------
  1096. integer :: T
  1097. complex, allocatable :: X(:)
  1098. ! --- begin --------------------------
  1099. T = Xnm%T
  1100. ! compute Fourrier coefficients at oposite latitudes
  1101. ! (latitude is implicit defined in Pnm)
  1102. allocate( X(0:T) )
  1103. call FourrierCoeff( Xnm, Pnm, T, X )
  1104. ! evaluate given Fourrier coefficients:
  1105. call Eval_Lons( llgrid, X, T, KK, lon_start, Kout )
  1106. ! done
  1107. deallocate( X )
  1108. ! ok
  1109. status = 0
  1110. end subroutine shgrid_Eval_Lons_UPnm_1
  1111. ! ***
  1112. ! Evaluate given spherical harmonic coefficients and Legendre functions
  1113. ! o TXnm, Xnm : input truncation and sh coeff
  1114. ! o T, Pnm : target truncation and evaluated Legende functions
  1115. ! o KK : number of longitudes on full circle
  1116. ! o lon_start : first longitude
  1117. ! o Kout : number of output longitudes
  1118. ! o llgrid : output array
  1119. subroutine shi_Eval_Lons_UPnm_1( shi_in, Xnm, shi, Pnm, KK, lon_start, Kout, llgrid, status )
  1120. ! --- in/out -------------------------
  1121. type(TShGridInfo), intent(in) :: shi_in
  1122. complex, intent(in) :: Xnm(shi_in%np)
  1123. type(TShGridInfo), intent(in) :: shi
  1124. real, intent(in) :: Pnm(shi%np)
  1125. integer, intent(in) :: KK
  1126. real, intent(in) :: lon_start
  1127. integer, intent(in) :: Kout
  1128. real,intent(out) :: llgrid(Kout)
  1129. integer, intent(out) :: status
  1130. ! --- const --------------------------------------
  1131. character(len=*), parameter :: rname = mname//'/sh_Eval_Lons_UPnm_1'
  1132. ! --- local --------------------------
  1133. complex :: X(0:shi%T)
  1134. ! --- begin --------------------------
  1135. ! compute Fourrier coefficients at oposite latitudes
  1136. ! (latitude is implicit defined in Pnm)
  1137. call FourrierCoeff( shi_in, Xnm, shi, Pnm, X )
  1138. ! evaluate given Fourrier coefficients:
  1139. call Eval_Lons( llgrid, X, shi%T, KK, lon_start, Kout )
  1140. ! ok
  1141. status = 0
  1142. end subroutine shi_Eval_Lons_UPnm_1
  1143. ! xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  1144. ! Shift to first lon:
  1145. !
  1146. ! x(t0+k2pi/K) , k=0,1,..,KK-1
  1147. !
  1148. ! T i m [t0 + k 2pi/K]
  1149. ! = sum X(m) e , k=0,1,..,K0-1
  1150. ! m=-T
  1151. !
  1152. ! T i m t0 k 2pi/K
  1153. ! = sum [X(m) e ] e , k=0,1,..,K0-1
  1154. ! m=-T
  1155. !
  1156. ! PERFORMANCE
  1157. ! This routine is about 7% slower than with emos fft ...
  1158. !
  1159. ! real(4), external :: etime
  1160. ! real :: tarr(2), t0
  1161. ! t0=etime(tarr)
  1162. ! print *, 'time:',etime(tarr)-t0
  1163. subroutine shgrid_Eval_Lons_Xm_1( llgrid, Xm, T, KK, lon_start, Kout )
  1164. use grid_tools, only : pi
  1165. use grid_singleton, only : fft
  1166. ! --- in/out -------------------------
  1167. integer, intent(in) :: T
  1168. complex, intent(in) :: Xm(0:T)
  1169. integer, intent(in) :: KK
  1170. real, intent(in) :: lon_start
  1171. integer, intent(in) :: Kout
  1172. real,intent(out) :: llgrid(Kout)
  1173. ! --- local --------------------------
  1174. integer :: i, j, k
  1175. integer :: m, n
  1176. complex :: X(0:T)
  1177. integer :: LL, JJ
  1178. complex, allocatable :: C(:), F(:)
  1179. real :: fac
  1180. ! --- begin --------------------------
  1181. ! shift over west most longitude:
  1182. ! X(m) := X(m) exp( i m lon0 )
  1183. do m = 0, T
  1184. X(m) = Xm(m) * exp( (0.0,1.0)*m*lon_start )
  1185. end do
  1186. ! choose L such that JJ=KK*LL >= 2T+1
  1187. LL = 1
  1188. do
  1189. if ( KK*LL >= 2*T+1 ) exit
  1190. LL = LL * 2
  1191. end do
  1192. ! number of longitudes to be evaluated:
  1193. JJ = KK*LL
  1194. ! fft arrays:
  1195. allocate( C(JJ) )
  1196. allocate( F(JJ) )
  1197. ! fill coeff array:
  1198. C = (0.0,0.0)
  1199. C(1) = X(0)
  1200. do m = 1, T
  1201. C(1+m) = X(m)
  1202. C(JJ+1-m) = conjg(X(m))
  1203. end do
  1204. ! Apply fast fourrier transform.
  1205. !
  1206. ! 1 J-1 i m lambda(j)
  1207. ! F(j) = ------- sum C(m) e
  1208. ! sqrt(J) m=0
  1209. !
  1210. ! where
  1211. !
  1212. ! lambda(j) = j 2pi/J = 0, dlon, 2*dlon, ...
  1213. ! ____ ____
  1214. ! C = [ X(0), X(1), .., X(T), 0, ..., 0, X(T), .., X(1) ]
  1215. !
  1216. ! Coeff in C are complex conj, thus imag part of F is zero.returned array is real.
  1217. !
  1218. F = fft( C, inv=.true. )
  1219. fac = sqrt(JJ*1.0)
  1220. ! Extract result.
  1221. ! Since 'only' KK lons are evaluated (covering complete circle),
  1222. ! select values cyclic for k>KK.
  1223. ! Select first each group of LL elements
  1224. do k = 0, Kout-1
  1225. j = mod(k,KK)*LL + 1 ! 1, LL+1, 2*LL+1, ...
  1226. llgrid(k+1) = real(F(j))*fac
  1227. end do
  1228. ! done
  1229. deallocate( C )
  1230. deallocate( F )
  1231. end subroutine shgrid_Eval_Lons_Xm_1
  1232. ! ==============================================
  1233. ! compute associated legendre coeff for
  1234. !
  1235. ! d X 2 d X dX dX
  1236. ! ( -------- , (1-mu ) ---- ) = r cos(theta) ( -- , -- )
  1237. ! d lambda d mu dx dy
  1238. !
  1239. ! given associated legendre coeff of X(lambda,mu)
  1240. !
  1241. subroutine shgrid_Nabla( Xnm, NablaX )
  1242. ! --- in/out -----------------------------
  1243. type(TshGrid), intent(in) :: Xnm
  1244. type(TshGrid), intent(inout) :: NablaX(2)
  1245. ! --- local ------------------------
  1246. integer :: m, n, T
  1247. integer :: k
  1248. ! --- begin ----------------------------
  1249. ! extract triangular truncation
  1250. T = Xnm%T
  1251. ! allocate output arrays
  1252. call Set( NablaX(1), T )
  1253. call Set( NablaX(2), T )
  1254. ! loop over all coeff
  1255. k = 0
  1256. do m = 0, T
  1257. do n = m, T
  1258. k = k + 1
  1259. ! d(ln ps) i m lon
  1260. ! -------- = sum {i m X(m,n)} P(mu;m,n) e
  1261. ! d lon m,n
  1262. NablaX(1)%c(k) = (0.0,1.0) * m * Xnm%c(k)
  1263. ! 2 d(ln ps) ~ i m lon
  1264. ! (1-mu ) -------- = sum X(m,n) P(mu;m,n) e
  1265. ! d mu m,n
  1266. !
  1267. ! ~ = (n+2) eps(m,n+1) X(m,n+1) , m<T, m=n
  1268. ! X(m,n) = (n+2) eps(m,n+1) X(m,n+1) - (n-1) eps(m,n) X(m,n-1) , m<T, m<n<T
  1269. ! = - (n-1) eps(m,n) X(m,n-1) , m<T, n=T
  1270. ! = 0.0 , m=T, n=T
  1271. if ( m < T ) then
  1272. if ( n == m ) then
  1273. NablaX(2)%c(k) = (n+2) * epsilon(m,n+1) * Xnm%c(k+1)
  1274. else if ( n > m .and. n < T ) then
  1275. NablaX(2)%c(k) = (n+2) * epsilon(m,n+1) * Xnm%c(k+1) - &
  1276. (n-1) * epsilon(m,n) * Xnm%c(k-1)
  1277. else ! n == T
  1278. NablaX(2)%c(k) = (n-1) * epsilon(m,n) * Xnm%c(k-1)
  1279. end if
  1280. else
  1281. NablaX(2)%c(k) = 0.0
  1282. end if
  1283. end do
  1284. end do
  1285. contains
  1286. ! n*n - m*m 1/2
  1287. ! epsilon = ( --------- )
  1288. ! 4*n*n - 1
  1289. real function epsilon( m, n )
  1290. ! --- in/out --------------------------------
  1291. integer, intent(in) :: m, n
  1292. ! --- begin --------------------------------
  1293. epsilon = sqrt((n*n-m*m)*1.0/(4*n*n-1.0))
  1294. end function epsilon
  1295. end subroutine shgrid_Nabla
  1296. ! ==================================================================
  1297. !
  1298. ! Compute (U,V) = (u,v) cos(lat) from vorticity VO and divergence D.
  1299. !
  1300. ! Use relations:
  1301. !
  1302. ! U(m,n) = ( + delta(m,n) VO(m,n-1) + i sigma(m,n) D(m,n) - delta(m,n+1) VO(m,n+1) ) R
  1303. !
  1304. ! V(m,n) = ( - delta(m,n) D(m,n-1) + i sigma(m,n) VO(m,n) + delta(m,n+1) D(m,n+1) ) R
  1305. !
  1306. ! where
  1307. !
  1308. ! delta(m,n) = - eps(m,n)/n , eps(m,n) = sqrt( (n^2-m^2)/(4n^2-1) )
  1309. !
  1310. ! sigma(m,n) = - m / (n(n+1))
  1311. !
  1312. ! NOTE: In EMOS library, vor. and div. are assumed to be truncated at T-1;
  1313. ! for consitency, this is used here too ...
  1314. !
  1315. subroutine sh_vod2uv( VO, DI, U, V )
  1316. use Binas, only : R => ae
  1317. ! --- in/out -----------------------------
  1318. type(TshGrid), intent(in) :: VO, DI
  1319. type(TshGrid), intent(inout) :: U, V
  1320. ! --- local ------------------------------
  1321. integer :: m, n, T
  1322. integer :: k
  1323. complex :: z
  1324. ! --- begin ----------------------------
  1325. ! Use EMOS library:
  1326. !call jvod2uv( VO%c, DI%c, VO%T, U%c, V%c, VO%T )
  1327. ! check arguments:
  1328. call Check( VO )
  1329. T = VO%T
  1330. call Check( DI, T )
  1331. call Check( U, T )
  1332. call Check( V, T )
  1333. ! complex i for multiplication:
  1334. z = (0.0, 1.0)
  1335. ! index of coeff in array; initialise:
  1336. k = 0
  1337. ! loop over all m:
  1338. do m = 0, T-1
  1339. ! (m,m)
  1340. n = m
  1341. k = k + 1
  1342. if ( m == 0 ) then
  1343. U%c(k) = ( - delta(m,n+1)*VO%c(k+1) )*R
  1344. V%c(k) = ( delta(m,n+1)*DI%c(k+1) )*R
  1345. else
  1346. U%c(k) = ( z*sigma(m,n)*DI%c(k) - delta(m,n+1)*VO%c(k+1) )*R
  1347. V%c(k) = ( z*sigma(m,n)*VO%c(k) + delta(m,n+1)*DI%c(k+1) )*R
  1348. end if
  1349. ! internal area:
  1350. if ( m <= T-2 ) then
  1351. do n = m+1, T-2
  1352. k = k + 1
  1353. U%c(k) = ( delta(m,n)*VO%c(k-1) + z*sigma(m,n)*DI%c(k) - delta(m,n+1)*VO%c(k+1) )*R
  1354. V%c(k) = ( - delta(m,n)*DI%c(k-1) + z*sigma(m,n)*VO%c(k) + delta(m,n+1)*DI%c(k+1) )*R
  1355. end do
  1356. ! (m,T-1)
  1357. n = T-1
  1358. k = k + 1
  1359. U%c(k) = ( delta(m,n)*VO%c(k-1) + z*sigma(m,n)*DI%c(k))*R
  1360. V%c(k) = ( - delta(m,n)*DI%c(k-1) + z*sigma(m,n)*VO%c(k))*R
  1361. end if
  1362. ! (m,T)
  1363. n = T
  1364. k = k + 1
  1365. U%c(k) = ( delta(m,n)*VO%c(k-1) )*R
  1366. V%c(k) = ( - delta(m,n)*DI%c(k-1) )*R
  1367. end do
  1368. ! (T,T)
  1369. k = k + 1
  1370. U%c(k) = 0.0
  1371. V%c(k) = 0.0
  1372. contains
  1373. real function delta( m, n )
  1374. integer, intent(in) :: m, n
  1375. delta = - sqrt( (n*n-m*m)*1.0/(4.0*n*n-1.0) ) / (n*1.0)
  1376. end function delta
  1377. real function sigma( m, n )
  1378. integer, intent(in) :: m, n
  1379. sigma = - m * 1.0/(n*(n+1.0))
  1380. end function sigma
  1381. end subroutine sh_vod2uv
  1382. ! ***
  1383. pure subroutine shi_vod2uv( shi_in, VO, DI, shi, U, V )
  1384. use Binas, only : R => ae
  1385. ! --- in/out -----------------------------
  1386. type(TShGridInfo), intent(in) :: shi_in
  1387. complex, intent(in) :: VO(shi_in%np), DI(shi_in%np)
  1388. type(TShGridInfo), intent(in) :: shi
  1389. complex, intent(out) :: U(shi%np), V(shi%np)
  1390. ! --- local ------------------------------
  1391. integer :: m, n
  1392. integer :: kin, k
  1393. complex :: z
  1394. ! --- begin ----------------------------
  1395. ! Use EMOS library:
  1396. !call jvod2uv( VO%c, DI%c, VO%T, U%c, V%c, VO%T )
  1397. ! check arguments:
  1398. !call Check( VO )
  1399. !T = VO%T
  1400. !call Check( DI, T )
  1401. !call Check( U, T )
  1402. !call Check( V, T )
  1403. ! complex i for multiplication:
  1404. z = (0.0, 1.0)
  1405. ! index of coeff in array; initialise:
  1406. kin = 0
  1407. k = 0
  1408. ! loop over all m:
  1409. do m = 0, shi%T-1
  1410. ! (m,m)
  1411. n = m
  1412. kin = kin + 1
  1413. k = k + 1
  1414. if ( m == 0 ) then
  1415. U(k) = ( - delta(m,n+1)*VO(kin+1) )*R
  1416. V(k) = ( delta(m,n+1)*DI(kin+1) )*R
  1417. else
  1418. U(k) = ( z*sigma(m,n)*DI(kin) - delta(m,n+1)*VO(kin+1) )*R
  1419. V(k) = ( z*sigma(m,n)*VO(kin) + delta(m,n+1)*DI(kin+1) )*R
  1420. end if
  1421. ! internal area:
  1422. if ( m <= shi%T-2 ) then
  1423. do n = m+1, shi%T-2
  1424. kin = kin + 1
  1425. k = k + 1
  1426. U(k) = ( delta(m,n)*VO(kin-1) + z*sigma(m,n)*DI(kin) - delta(m,n+1)*VO(kin+1) )*R
  1427. V(k) = ( - delta(m,n)*DI(kin-1) + z*sigma(m,n)*VO(kin) + delta(m,n+1)*DI(kin+1) )*R
  1428. end do
  1429. ! (m,T-1)
  1430. n = shi%T-1
  1431. kin = kin + 1
  1432. k = k + 1
  1433. U(k) = ( delta(m,n)*VO(kin-1) + z*sigma(m,n)*DI(kin))*R
  1434. V(k) = ( - delta(m,n)*DI(kin-1) + z*sigma(m,n)*VO(kin))*R
  1435. end if
  1436. ! (m,T)
  1437. n = shi%T
  1438. kin = kin + 1
  1439. k = k + 1
  1440. U(k) = ( delta(m,n)*VO(kin-1) )*R
  1441. V(k) = ( - delta(m,n)*DI(kin-1) )*R
  1442. kin = kin + shi_in%T - shi%T
  1443. end do
  1444. ! (T,T)
  1445. k = k + 1
  1446. U(k) = (0.0,0.0)
  1447. V(k) = (0.0,0.0)
  1448. contains
  1449. pure real function delta( m, n )
  1450. integer, intent(in) :: m, n
  1451. delta = - sqrt( (n*n-m*m)*1.0/(4.0*n*n-1.0) ) / (n*1.0)
  1452. end function delta
  1453. pure real function sigma( m, n )
  1454. integer, intent(in) :: m, n
  1455. sigma = - m * 1.0/(n*(n+1.0))
  1456. end function sigma
  1457. end subroutine shi_vod2uv
  1458. end module grid_type_sh