|
| 1 | +# Advanced usage |
| 2 | + |
| 3 | +## Configuring the transform |
| 4 | + |
| 5 | +The [`SHTnsCfg`](@ref) configuration object takes several keywords allowing the user to tweak the spherical harmonic transform. |
| 6 | + |
| 7 | +The simplest configuration takes only the maximum spherical harmonic degree `lmax` as an argument |
| 8 | +```@example advanced |
| 9 | +using SHTns |
| 10 | +
|
| 11 | +lmax = 100 |
| 12 | +cfg = SHTnsCfg(lmax) |
| 13 | +``` |
| 14 | + |
| 15 | +We can also define the grid resolution (`nlat` and `nphi`) first, and then `lmax`, as well as the maximum azimuthal degree `mmax`, as well as the _resolution_ in ``m`` through `mres`. |
| 16 | +```@example advanced |
| 17 | +nlat = 100 |
| 18 | +nphi = 2nlat+1 |
| 19 | +lmax = 2nlat÷3 |
| 20 | +mmax = 5 |
| 21 | +mres = 1 |
| 22 | +cfg = SHTnsCfg(lmax,mmax,mres,nlat,nphi) |
| 23 | +``` |
| 24 | + |
| 25 | +The transform type [`SHTnsType`](@ref) can be varied through the `shtype` keyword |
| 26 | +```@example advanced |
| 27 | +cfg = SHTnsCfg(lmax; shtype = SHTns.Gauss()) |
| 28 | +``` |
| 29 | + |
| 30 | +See also the documentation of the C library on [shtns_type](https://nschaeff.bitbucket.io/shtns/shtns_8h.html#abdccbb8fbce176dbe189d494c94f0f7b) and [grid layouts](https://nschaeff.bitbucket.io/shtns/spat.html). |
| 31 | + |
| 32 | +We can also change the normalization of the spherical harmonics, for example to the Schmidt semi-normalization without [Condon-Shortley phase](https://mathworld.wolfram.com/Condon-ShortleyPhase.html) (default enabled) |
| 33 | +```@example advanced |
| 34 | +cfg = SHTnsCfg(lmax; norm = SHTns.Schmidt(; cs_phase=false)) |
| 35 | +``` |
| 36 | +See also [Spherical Harmonics storage and normalization](https://nschaeff.bitbucket.io/shtns/spec.html) of the C library. |
| 37 | + |
| 38 | + |
| 39 | +`SHTns` also supports complex to complex transforms (instead of real spatial space to complex spectral space, which is the default). |
| 40 | + |
| 41 | +```@example advanced |
| 42 | +cfg = SHTnsCfg(lmax; transform=Complex) |
| 43 | +``` |
| 44 | + |
| 45 | +## GPU |
| 46 | + |
| 47 | +Using `SHTns` on a CUDA-enabled GPU is straightforward. |
| 48 | +Simply install and import [`CUDA.jl`](https://github.com/JuliaGPU/CUDA.jl): |
| 49 | + |
| 50 | +```julia |
| 51 | +import Pkg; Pkg.add("CUDA") |
| 52 | +using CUDA |
| 53 | +``` |
| 54 | + |
| 55 | +Then, configure your [`SHTnsCfg`](@ref) using an [`SHTnsType`](@ref) with the keyword `gpu=true`. |
| 56 | +```julia |
| 57 | +cfg_gpu = SHTnsCfg(64; shtype=SHTns.QuickInit(;gpu=true)) |
| 58 | +``` |
| 59 | + |
| 60 | +The rest remains almost identical to the CPU transform |
| 61 | +```julia |
| 62 | +θ,ϕ = SHTns.grid(cfg) #get (co-)latitude and longitude |
| 63 | +d = @. 0.3*sin(ϕ') * sin(θ) #create some spatial data (0.3 Y₁¹) - on CPU! |
| 64 | + |
| 65 | +d_gpu = CuArray(d) #send spatial data to GPU |
| 66 | + |
| 67 | +q_gpu = SHTns.analys(cfg_gpu,d_gpu) #transform to spectral space |
| 68 | + |
| 69 | +#scalar indexing not allowed on GPU arrays, therefore call Array(q_gpu) to send back to CPU |
| 70 | +y11_coeff = Array(q_gpu)[SHTns.LM(cfg, 1,1)] |
| 71 | +y11_coeff ≈ 0.3*sqrt(2π/3)*im #true |
| 72 | + |
| 73 | +d2_gpu = SHTns.synth(cfg_gpu,q_gpu) #transform backto spatial space |
| 74 | +d2_gpu ≈ d_gpu #true |
| 75 | +``` |
| 76 | + |
| 77 | + |
| 78 | +> [!NOTE] |
| 79 | +> ROCm GPUs may be supported in future releases of SHTns.jl (already available in the C library). |
| 80 | +
|
| 81 | +## Batched transform |
| 82 | + |
| 83 | +`SHTns` supports batched transforms, i.e. multiple spherical harmonic transforms together. For example transforms on spherical surfaces at different radii at the same time. |
| 84 | + |
| 85 | +One can exploit this feature using the keyword `howmany`, to give the configuration the number of transforms to be performed. |
| 86 | + |
| 87 | +```@example advanced |
| 88 | +howmany = 10 |
| 89 | +cfg = SHTnsCfg(lmax; howmany) |
| 90 | +
|
| 91 | +θ,ϕ = SHTns.grid(cfg) |
| 92 | +
|
| 93 | +# create spatial array (nlat_padded x nphi x howmany) |
| 94 | +d = zeros(cfg.nlat_padded, cfg.nphi, howmany) |
| 95 | +d1 = @. 0.3*sin(ϕ') * sin(θ) |
| 96 | +for i=1:howmany |
| 97 | + @. d[:,:,i] = i*d1 |
| 98 | +end |
| 99 | +
|
| 100 | +q = SHTns.analys(cfg,d) |
| 101 | +d2 = SHTns.synth(cfg,q) |
| 102 | +d2 ≈ d #true |
| 103 | +``` |
| 104 | + |
| 105 | +> [!NOTE] |
| 106 | +> Complex to complex transforms are currently not supported in the batched transform. |
| 107 | +
|
| 108 | + |
0 commit comments