Renaming scales

80 views
Skip to first unread message

Manohar Teja

unread,
Aug 5, 2022, 7:15:22 AM8/5/22
to dedalu...@googlegroups.com
Hi,

I have moved to Dedalusv3 recently and I noticed that scales of coordinates (x, z) are named differently ('x_hash_90b4bd5251bd0906eb6b915a7934efa62e18bcf7', 'z_hash_5f812b8486509fb9f7cde52d4f5c06de4090b567'). I believe this is being saved as x_hash_<address> which keeps changing every time I run a new simulation. In Dedalus v2 they are saved as 'x', 'z' which is more comfortable to access while plotting. How can I save them just as 'x', 'z'?

Regards.
Manohar Teja Kalluri
CGAFD, Univ of Exeter

Evan Henry Anders

unread,
Aug 5, 2022, 8:13:43 AM8/5/22
to dedalus-users
Hi Manohar,

The short answer is: unfortunately, I don't think this is something you can do in d3. So as users transition we have to adjust this part of our workflow a bit. The good news is that all analysis tasks connect to the information about the bases in a logical way that doesn't require the user to fill in these hashes. I've made this function to get around this problem:

def match_basis(dset, basis):
    """ Returns a 1D numpy array of the requested basis """
    for i in range(len(dset.dims)):
        if dset.dims[i].label == basis:
            return dset.dims[i][0][:].ravel()

example usage:

x = match_basis(file_handler['tasks/u'], 'x')

where here, x will be a 1D numpy array of the x values that the output task 'u' is defined on. Hope this helps!

Best,
Evan 

--
You received this message because you are subscribed to the Google Groups "Dedalus Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dedalus-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dedalus-users/CAGuRpfTWsjAjOPX46S_jGnZsY9dw9UGZhgb7r_M00wRLb%2BwLeg%40mail.gmail.com.

Manohar Teja

unread,
Aug 5, 2022, 9:04:18 AM8/5/22
to dedalu...@googlegroups.com
Thanks Evan. It is very helpful :)

Regards
Manohar
CGAFD, Univ of Exeter


Jeffrey S. Oishi

unread,
Aug 5, 2022, 10:46:10 AM8/5/22
to dedalus-users
Hi Manohar,

I think it might be helpful to explain a bit why d3 does it this way and how you can access things. One of the key improvements in d3 is that a coordinate direction need not be represented by a single basis and fields can be defined on some bases but not others. For example, one could imagine wanting to simulate the atmosphere of a star or planet using a thin, well-resolved spherical shell while at the same time simulating the deep interior using a ball with a different set of equations, using a different set of fields. Both the shell and the ball will have a radial direction. When you want to get the radial grid associated with a field specified only in the shell, you want the shell radius, not the ball radius. So you can see that we can no longer use unique, simple labels in the HDF5 output like "r". The reason those hashes are there is to ensure uniqueness. Of course, it is not human readable, nor is it constant from simulation to simulation. This is because its purpose is not for humans to interact with. Instead, we use the dimension labels attribute in HDF5. This associates another field with each dimension of a given field. You can see an example of this in the last code block in our tutorial notebook 4:

    u = file['tasks']['u']
    t = u.dims[0]['sim_time']
    x = u.dims[1][0]


Here, the code extracts a particular field (u). u is a scalar field in one dimension, so it has dimensions (n_time_outputs, n_x). We then ask for the .dims attribute of our field, which is a list of length 2 in this case: u.dims[0] gives the scales attached to the time dimension, u.dims[1] gives the scales attached to the x direction. Why isn't this the end of the story? Because dedalus allows multiple scales per dimension. This is most useful in the time dimension: you could have the simulation time ('sim_time'), the iteration number ('iteration'), the timestep size ('timestep'), or even the time on the wall when you were running ('wall_time'). There are actually six timescales attached by default in d3; you can see them by doing 

u.dims[0].keys()

One wrinkle is that if instead we had a vector field in 3D, it would have dimensions (n_time_outputs, 3, n_x, n_y, n_z), so the 'x' direction would be u.dims[2], where as for a scalar field f in 3D, it would be f.dims[1], and similarly for all trailing dimensions.
 
The one thing that is not user friendly is the fact that h5py does not support dictionary access to dimensions, so you can't do u.dims['time'], even though the dimension does have a user-readable name. We are planning to raise this issue with their development team. Hopefully in the future it will be even easier. 

We are currently working on some new visualization tools using xarray that should obviate many of these issues, but even now, it is fairly easy to get what you need. I hope understanding how we make use of all of the HDF5 features will help you (and others) understand how to visualize d3 data with ease, despite the vastly increased generality from d2. 

If you have other questions, please don't hesitate to ask!

Jeff

PS: Evan, I'm not sure what the .ravel() in your code is doing. 

Evan Henry Anders

unread,
Aug 5, 2022, 11:15:51 AM8/5/22
to dedalus-users
Hi Jeff,

Thanks for the extra context! And you're right -- the ravel() is unnecessary for tip-d3. I added that in, I think, back when the scales had shapes like (1,128) instead of just (128). 

That said, since using d3, I've been using this match_basis() technique to get the scales while plotting in my d2 projects, and there the ravel() comes in handy!

Best,
Evan

Manohar Teja

unread,
Aug 6, 2022, 3:10:12 AM8/6/22
to dedalu...@googlegroups.com
Thank you very much for the detailed explanation, Dr. Jeff. Very informative.

Regards
Manohar
CGAFD, Univ of Exeter

Reply all
Reply to author
Forward
0 new messages