@@ -28,9 +28,9 @@ class RayleighBenard3D(GenericSpectralLinear):
2828
2929 The domain, vertical boundary conditions and pressure gauge are
3030
31- Omega = [0, 8 ) x (-1, 1 )
31+ Omega = [0, Lx ) x [0, Ly] x (0, Lz )
3232 T(z=+1) = 0
33- T(z=-1) = 2
33+ T(z=-1) = Lz
3434 u(z=+-1) = v(z=+-1) = 0
3535 integral over p = 0
3636
@@ -53,16 +53,16 @@ class RayleighBenard3D(GenericSpectralLinear):
5353 def __init__ (
5454 self ,
5555 Prandtl = 1 ,
56- Rayleigh = 2e6 ,
57- nx = 256 ,
58- ny = 256 ,
59- nz = 64 ,
56+ Rayleigh = 1e6 ,
57+ nx = 64 ,
58+ ny = 64 ,
59+ nz = 32 ,
6060 BCs = None ,
6161 dealiasing = 1.5 ,
6262 comm = None ,
6363 Lz = 1 ,
64- Lx = 1 ,
65- Ly = 1 ,
64+ Lx = 4 ,
65+ Ly = 4 ,
6666 useGPU = False ,
6767 ** kwargs ,
6868 ):
@@ -79,7 +79,6 @@ def __init__(
7979 comm (mpi4py.Intracomm): Space communicator
8080 Lx (float): Horizontal length of the domain
8181 """
82- # TODO: documentation
8382 BCs = {} if BCs is None else BCs
8483 BCs = {
8584 'T_top' : 0 ,
@@ -328,7 +327,7 @@ def compute_Nusselt_numbers(self, u):
328327 _me [0 ] = u_pad [iw ] * u_pad [iT ]
329328 wT_hat = self .transform (_me , padding = padding )[0 ]
330329
331- nusselt_hat = wT_hat - DzT_hat
330+ nusselt_hat = ( wT_hat / self . kappa - DzT_hat ) * self . axes [ - 1 ]. L
332331
333332 if not hasattr (self , '_zInt' ):
334333 self ._zInt = zAxis .get_integration_matrix ()
@@ -354,3 +353,70 @@ def compute_Nusselt_numbers(self, u):
354353 't' : Nusselt_t ,
355354 'b' : Nusselt_b ,
356355 }
356+
357+ def get_frequency_spectrum (self , u ):
358+ """
359+ Compute the frequency spectrum of the velocities in x and y direction in the horizontal plane for every point in
360+ z. If the problem is well resolved, the coefficients will decay quickly with the wave number, and the reverse
361+ indicates that the resolution is too low.
362+
363+ The returned spectrum has three dimensions. The first is for component (i.e. u or v), the second is for every
364+ point in z and the third is the energy in every wave number.
365+
366+ Args:
367+ u: The solution you want to compute the spectrum of
368+
369+ Returns:
370+ RayleighBenard3D.xp.ndarray: wave numbers
371+ RayleighBenard3D.xp.ndarray: spectrum
372+ """
373+ xp = self .xp
374+ indices = slice (0 , 2 )
375+
376+ # transform the solution to be in frequency space in x and y, but real space in z
377+ if self .spectral_space :
378+ u_hat = self .itransform (u , axes = (- 1 ,))
379+ else :
380+ u_hat = self .transform (
381+ u ,
382+ axes = (
383+ - 3 ,
384+ - 2 ,
385+ ),
386+ )
387+ u_hat = self .spectral .redistribute (u_hat , axis = 2 , forward_output = False )
388+
389+ # compute "energy density" as absolute square of the velocity modes
390+ energy = (u_hat [indices ] * xp .conjugate (u_hat [indices ])).real / (self .axes [0 ].N ** 2 * self .axes [1 ].N ** 2 )
391+
392+ # prepare wave numbers at which to compute the spectrum
393+ abs_kx = xp .abs (self .Kx [:, :, 0 ])
394+ abs_ky = xp .abs (self .Ky [:, :, 0 ])
395+
396+ unique_k = xp .unique (xp .append (xp .unique (abs_kx ), xp .unique (abs_ky )))
397+ n_k = len (unique_k )
398+
399+ # compute local spectrum
400+ local_spectrum = self .xp .empty (shape = (2 , energy .shape [3 ], n_k ))
401+ for i , k in zip (range (n_k ), unique_k ):
402+ mask = xp .logical_or (abs_kx == k , abs_ky == k )
403+ local_spectrum [..., i ] = xp .sum (energy [indices , mask , :], axis = 1 )
404+
405+ # assemble global spectrum from local spectra
406+ k_all = self .comm .allgather (unique_k )
407+ unique_k_all = []
408+ for k in k_all :
409+ unique_k_all = xp .unique (xp .append (unique_k_all , xp .unique (k )))
410+ n_k_all = len (unique_k_all )
411+
412+ spectra = self .comm .allgather (local_spectrum )
413+ spectrum = self .xp .zeros (shape = (2 , self .axes [2 ].N , n_k_all ))
414+ for ks , _spectrum in zip (k_all , spectra ):
415+ ks = list (ks )
416+ unique_k_all = list (unique_k_all )
417+ for k in ks :
418+ index_global = unique_k_all .index (k )
419+ index_local = ks .index (k )
420+ spectrum [..., index_global ] += _spectrum [..., index_local ]
421+
422+ return xp .array (unique_k_all ), spectrum
0 commit comments