Skip to content
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

Fix Gadget2 read and units #8

Merged
merged 11 commits into from
Oct 29, 2021
Merged

Fix Gadget2 read and units #8

merged 11 commits into from
Oct 29, 2021

Conversation

elehcim
Copy link
Contributor

@elehcim elehcim commented Oct 27, 2021

I added a set of units (the default for Gadget2) which is used when reading/writing files.
I corrected the units of Potential (linked to JuliaAstroSim/PhysicalParticles.jl#18 ).

Also I fixed the usage of StructArray and added some tests.

I'm available this period to contribute on this.

I have a couple of ideas, don't know if you have already thought about that.
For example I'd like to define a getindex method for retrieving only a certain collection from a StructArray of Stars.
I'm not super expert of Julia, but I really want to learn more about it.
Also, there is the need to add Temperature and Energy and star-particle related fields, e.g.: age, chemical composition...
Before going forward, let me know if you have any thought about this. I'll probably open some issues to discuss.

@islent islent self-requested a review October 28, 2021 13:52
src/Gadget.jl Outdated Show resolved Hide resolved
src/Gadget.jl Outdated Show resolved Hide resolved
src/Gadget.jl Outdated Show resolved Hide resolved
src/Gadget.jl Outdated Show resolved Hide resolved
src/Gadget.jl Outdated Show resolved Hide resolved
src/Gadget.jl Outdated Show resolved Hide resolved
@@ -1,3 +1,6 @@
@unit Gadget2Mass "1e10M⊙" Gadget2MassUnit 1e10*u"Msun" false
const uGadget2 = [u"kpc",u"kpc/km*s",u"A",u"K",u"cd",Gadget2Mass,u"mol"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great design!!!

Comment on lines +158 to +160
vx = read(f, Float32) * 1.0 * uVel
vy = read(f, Float32) * 1.0 * uVel
vz = read(f, Float32) * 1.0 * uVel
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are assuming the snapshot velocity unit to be km/s (which is not true in some cases), and there need a unit conversion if uVel is not km/s. So I suggest this to be unchanged:

Suggested change
vx = read(f, Float32) * 1.0 * uVel
vy = read(f, Float32) * 1.0 * uVel
vz = read(f, Float32) * 1.0 * uVel
vx = uconvert(uVel, read(f, Float32) * 1.0 * u"km/s")
vy = uconvert(uVel, read(f, Float32) * 1.0 * u"km/s")
vz = uconvert(uVel, read(f, Float32) * 1.0 * u"km/s") #TODO: user defined snapshot unit

Even better, km/s should be assignable (TODO)

Comment on lines +200 to +204
Mass[i] = read(f, Float32) * uMass
end
else # set using header
for i in start:tail
Mass[i] = header.mass[type] * 1.0e10 * uMass
Mass[i] = header.mass[type] * uMass
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new version only works for uGadget2. I suggest a more general version:

Suggested change
Mass[i] = read(f, Float32) * uMass
end
else # set using header
for i in start:tail
Mass[i] = header.mass[type] * 1.0e10 * uMass
Mass[i] = header.mass[type] * uMass
Mass[i] = uconvert(uMass, read(f, Float32) * 1.0e10 * u"Msun")
end
else # set using header
for i in start:tail
Mass[i] = uconvert(uMass, header.mass[type] * 1.0e10 * u"Msun") #TODO: user defined snapshot unit

@@ -210,7 +234,7 @@ function read_Density!(f::Union{IOStream,Stream{format"Gadget2"}}, data::StructA
temp1 = read(f, Int32)
Density = data.Density
for i in 1:NumGas
Density[i] = read(f, Float32) * 10e10uDensity
Density[i] = read(f, Float32) * 1.0 * uDensity
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Density[i] = read(f, Float32) * 1.0 * uDensity
Density[i] = uconvert(uDensity, read(f, Float32) * 1.0 * u"Msun/kpc^3") #TODO: user defined snapshot unit

@@ -234,7 +258,7 @@ function read_POT!(f::Union{IOStream,Stream{format"Gadget2"}}, data::StructArray
temp1 = read(f, Int32)
Potential = data.Potential
for i in 1:length(data)
Potential[i] = uconvert(uPot, read(f, Float32) * u"km^2/s^2" * data.Mass[i])
Potential[i] = read(f, Float32) * 1.0 * uPot
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Potential[i] = read(f, Float32) * 1.0 * uPot
Potential[i] = uconvert(uPot, read(f, Float32) * u"km^2/s^2" * data.Mass[i]) #TODO: user defined snapshot unit

Comment on lines +273 to +275
accx = read(f, Float32) * 1.0 * uAcc
accy = read(f, Float32) * 1.0 * uAcc
accz = read(f, Float32) * 1.0 * uAcc
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
accx = read(f, Float32) * 1.0 * uAcc
accy = read(f, Float32) * 1.0 * uAcc
accz = read(f, Float32) * 1.0 * uAcc
accx = uconvert(uAcc, read(f, Float32) * 1.0 * u"km^2/kpc/s^2")
accy = uconvert(uAcc, read(f, Float32) * 1.0 * u"km^2/kpc/s^2")
accz = uconvert(uAcc, read(f, Float32) * 1.0 * u"km^2/kpc/s^2") #TODO: user defined snapshot unit

@@ -257,7 +281,7 @@ function read_ACCE!(f::Union{IOStream,Stream{format"Gadget2"}}, data::StructArra
end
end

function read_gadget2_particle(f::Union{IOStream,Stream{format"Gadget2"}}, header::HeaderGadget2, units = uAstro;
function read_gadget2_particle(f::Union{IOStream,Stream{format"Gadget2"}}, header::HeaderGadget2, units = uGadget2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the default unit may cause errors, so I have to add a TODO mark:

Suggested change
function read_gadget2_particle(f::Union{IOStream,Stream{format"Gadget2"}}, header::HeaderGadget2, units = uGadget2;
function read_gadget2_particle(f::Union{IOStream,Stream{format"Gadget2"}}, header::HeaderGadget2, units = uGadget2;
#TODO check uGadget2 unit

@islent
Copy link
Member

islent commented Oct 29, 2021

The error comes from julia 1.3.0 not supporting keyword abbreviation. Ready to merge.

@islent islent merged commit c5e784e into JuliaAstroSim:master Oct 29, 2021
@elehcim
Copy link
Contributor Author

elehcim commented Oct 29, 2021

ok, thanks. I didn't finish to address the units comments. I see the point of them being configurable, I support that idea in general.
In in the manual, in fact, the internal code units are the ones defined in uGadget2. So I'd expect the files to have those units.
Maybe for the moment we can leave them like this.

As a side note: I see these days more and more use of hdf5 as output format for Gadget2 (which is indeed more flexible). This file has units embedded in its header, so configurable units are needed in a while. This is for the (far) future (for now I don't even have example files).

I'm planning to create a Gadget2Particle type inside AstroIO to contain the fields needed by Gadget2 files.
In this way, PhysicalParticles.jl and AstroIO.jl are a bit less interdependent (e.g. a fact that is causing the CI to fail at the moment because the package PhysicalParticles.jl used now in the tests is a bit outdated).

@islent
Copy link
Member

islent commented Oct 29, 2021

I'm planning to create a Gadget2Particle type inside AstroIO to contain the fields needed by Gadget2 files.

This is the reason that I'm using Star or AbstractParticle type while implementing gravity solvers. Other users may prefer particle types like Electron, Photon, etc. Let abstract types to guarantee the most possible reusability.

a fact that is causing the CI to fail at the moment because the package PhysicalParticles.jl used now in the tests is a bit outdated

Yes, local tests succeeded. A little wierd to me though.

@islent
Copy link
Member

islent commented Oct 29, 2021

For reference, these are critical fields for Gadget-like gravity solver:

    Pos::PVector2D{P}
    Vel::PVector2D{V}
    Acc::PVector2D{A}
    Mass::M
    ID::I
    Collection::Collection

    Ti_endstep::I  # Next integer step on the timeline.
    Ti_begstep::I  # Present integer step on the timeline.
    GravCost::I    # For each two-particle interaction, GravCost += 1
    
    Potential::E   # Particle potential in the force field
    OldAcc::A      # Save the normalization of acceleration of last step. Useful in Tree n-body method.

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants