-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Subdomain extraction #86
Conversation
src/osyris/spatial/spatial.py
Outdated
return R | ||
|
||
|
||
def spherical_to_cartesian(r, theta, phi): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate you wanting to make a start on this earlier rather than later, but as I've said before I think it's worth taking our time to think properly about how we want to implement this.
We have to ask ourselves what is the goal here.
If we want to be able to e.g. easily compute a radius, and make a radial profile, then these functions would definitely be useful.
If we wish to make maps that depend on theta and phi (which was your original motivation), we also need to consider how this would then be used to make the maps. Maybe this approach does work, I am not sure, I have not thought enough about it.
Another approach could have been to give the Array additional properties, such as .r
, .theta
, and .phi
, which would compute the radius and angles on-the-fly. I am thinking that the coordinates are inherently cartesian, because they are as such inside Ramses. So they should be loaded as such, and am therefore not sure that converting from spherical back to cartesian would be something that is ever needed?
In addition, as you pointed out when you first suggested this idea, velocity or B field vectors could also have radial, theta and phi components (and those calculations would be a little different from that of the positions), which would certainly be useful.
This last point, combined with the slicing inconsistency of vectors in the other PR, is making me wonder whether we want a slightly different class for vector arrays (that would inherit from Array).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another approach could have been to give the Array additional properties, such as .r, .theta, and .phi, which would compute the radius and angles on-the-fly.
In addition, as you pointed out when you first suggested this idea, velocity or B field vectors could also have radial, theta and phi components (and those calculations would be a little different from that of the positions), which would certainly be useful.
Maybe we can group these into .get_spherical_components()
& .get_cylindrical_components()
methods? These shouldn't be automatically computed by osyris upon loading the dataset because otherwise it comes with an extra RAM burden, but they can provide a quick and easy way to gather all components.
This last point, combined with the slicing inconsistency of vectors in the other PR, is making me wonder whether we want a slightly different class for vector arrays (that would inherit from Array).
Instead of having a different class for vectors, I would rather have the type be an attribute of the Array class (eg. a .vector boolean attribute
).
src/osyris/spatial/spatial.py
Outdated
return Array(values=np.transpose(xyz).values, unit=r.unit, name="position") | ||
|
||
|
||
def cartesian_to_spherical(position, origin=[0, 0, 0]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In your original suggestion, you also had vector bases as part of the arguments. I think these would still be needed here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, I just wanted to keep it simple and generic for now, but expressing your coordinates in a new basis requires you to simply rotate them (which is the purpose of the rotation_matrix
function).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe thinking about how one would use this in a notebook would be a good way to figure out the API.
You have a disk somewhere in your simulation. You want to basically rotate everything so that the z axis is aligned with the angular momentum (is that all you need to do?)
You could have the following steps:
- find angular momentum vector
- rotate all coords and vectors into a new basis (still in cartesian coords)
- then access the radial or angular components of your vectors (this could be done via the
.r
and.theta
properties?
The problem with just having .r
property on a vector is that it works for position vectors, but not for other vectors such as velocity. If you want the radial velocity, you need to take the scalar product of the velocity vector with the position vector, so the conversion needs both position vectors and velocity vectors as inputs.
Maybe that is an argument for having functions that turn a whole Datagroup
into spherical or cylindrical components?
Something like
spherical_hydro = osyris.spatial.get_spherical_components(data['hydro'])
Which would return a new Datagroup (i think it might be safer to return a new group rather than doing operations in-place).
But then the get_spherical_components
also needs the data['amr']['position']
array...
Not sure if sending the entire Dataset to be converted is good, because you may be doubling your RAM usage.
Maybe the function should just accept a single Array, and an optional positions
argument, which could just be None
for computing the spherical components of the cell positions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have a disk somewhere in your simulation. You want to basically rotate everything so that the z axis is aligned with the angular momentum (is that all you need to do?)
Yes, that's all there is to it.
The problem with just having .r property on a vector is that it works for position vectors, but not for other vectors such as velocity. If you want the radial velocity, you need to take the scalar product of the velocity vector with the position vector, so the conversion needs both position vectors and velocity vectors as inputs.
Yeah that's what's been causing me a bit of a headache. It's difficult to come up with a clean API for something like this.
Not sure if sending the entire Dataset to be converted is good, because you may be doubling your RAM usage.
That is why in #52 I suggested that we make the coordinate system an attribute of the Dataset. That way with data.transform(system="spherical", basis="top")
, you do not return a new dataset, but simply convert all components in it to spherical and keep the old basis stored somewhere so that the user can revert his changes. However, this solution is going to be quite costly in development time.
What I suggest is to have a get_spherical_components
function that takes a Dataset as the argument but also a dictionary containing all the groups and arrays that the user would like to convert. Something like:
osyris.spatial.get_spherical_components(data, {"amr":"position", "hydro": ["velocity", "B_field"]})
It should be easier in this case to make a few checks on the user's request (eg. if they request spherical velocity components, we can access the position array since the whole dataset has been passed as an argument).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot to say that this suggestion would return a new Dataset containing all the converted coordinates and .r
, .theta
and .phi
components for each array.
Eg. :
spherical_coords = osyris.spatial.get_spherical_components(data, {"amr":"position", "hydro": ["velocity", "B_field"]})
spherical_coords["amr"]["position"].r # radius
spherical_coords["amr"]["position"].theta # colatitude
spherical_coords["amr"]["position"].phi # azimuth
spherical_coords[“hydro"]["velocity"].r # radial velocity
spherical_coords[“hydro"]["velocity"].phi # azimuthal velocity
etc...
And spherical_coords["amr"]["position"].x
returns an attribute error.
Trying to get this going again: After doing some more thinking about this, about how it would be used, I think what you would want is to be able to
That's probably what it boils down to (I think?). I suggest the following:
We could try this as a first step, see how usable it is, and make wrapper functions that convert an entire |
PR is indeed trying to do two things, but this keeps things simpler for us to review the code together. Checklist:
|
Current workflow looks like this:
Basis can be changed with |
This is however messing up in slices. I never had this problem in my own simulations, presumably because they're much higher resolution, but I'm getting some weird effects as can be seen here:
I'm still trying to track the issue down, but I'm certain from the spherical components that things are working as intended. Maybe there's something I've misunderstood with slices. |
The effect on maps is indeed weird. You can actually see the little squares from the cells that are rotated (around the edges). |
Have a look at the changes in #102 , maybe if we get that merged it might make some things easier/more compact here? |
It should reduce the number of |
Thanks for all your comments. I'll work on this again and push the changes sometime this week. |
PR now simply extracts subdomains. Ordinary coordinate transforms will be added after this PR is merged. |
Co-authored-by: Neil Vaytet <[email protected]>
Co-authored-by: Neil Vaytet <[email protected]>
Co-authored-by: Neil Vaytet <[email protected]>
This PR is linked to #52 and is in anticipation of an upcoming PR that will handle cartopy projections of surfaces (#53).
A spatial.py file containing common coordinate transforms alongside matrix rotations has been added. I am still open for discussion on how these transformations should be handled/called, but for the moment the current routines are generic enough for us to easily modify in the future.
Git should handle the diff if #81 and #85 are merged.