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

Some type hierarchy suggestions #3

Open
adamslc opened this issue Nov 16, 2024 · 11 comments
Open

Some type hierarchy suggestions #3

adamslc opened this issue Nov 16, 2024 · 11 comments

Comments

@adamslc
Copy link
Member

adamslc commented Nov 16, 2024

Hi @Beforerr, I wanted to offer a few suggestions for the type hierarchy that this package implements. This would help me to incorporate this into the JuliaPlasma/ParticleInCell.jl.

At it's core, I suggest making the type hierarchy something like:

AbstractParticle{M,Z}
└─ Particle{M,Z}

This will allow for dispatch based on the mass number and charge state of the particle. Additionally, I wonder if it would be worth supporting a field in the Particle struct to specify the exact mass of the particle:

struct Particle{M,Z,T} <: AbstractParticle{M,Z,T}
    symbol::Symbol
    mass::T
end

If storing this information is not desired, the T=Nothing.

Aside: I suggest renaming ChargedParticleImpl to Particle regardless. In my (very) humble opinion, this is a more Julian way to name the type. You could also consider ChargedParticle, but since Z=0 is allowed, I don`t think it makes as much sense.

Regardless of if you accept my suggestions, thanks for the great package!

@Beforerr
Copy link
Member

Hi Adam @adamslc , thank you for the suggestion. Actually, in my initial implementation, I include the mass field. However, it's a little bit redundant and confusing if one supply both mass number and mass (and do we need to verify they are equal?).

Also, I would say the symbol is more fundamental than the mass number. For example electron and muon, they both have zero mass number, but they have different mass, we need something like symbol to differentiate them. But this is something we can discuss.

Actually, I'm leaning towards the way of how plasmapy implement it. They have both physical particles and costume particles class. And for costume particles, we can have mass and charge as their fields.

struct CustomParticle
    mass
    charge_number
    symbol::Symbol = nothing
end

@Beforerr
Copy link
Member

Yes, I agree with you that ChargedParticleImpl is not a good name (it is so rusty 🫠:) . But I think it would be nice to keep it separate from Particle. As if we add CostumeParticle struct , it would be nice to make Particle be able to create both physical particles and costume particles.

@Beforerr
Copy link
Member

Thank you for all the suggestions. Yes it would be wonderful to incorporate into the ParticleInCell.jl.

@adamslc
Copy link
Member Author

adamslc commented Nov 16, 2024

I personally would find it very counterintuitive to call Particle(...) and get back something that is not of type Particle. In general, the Julia convention is that functions with a capital letter are constructors for a struct of the same name.

You make a good point that the symbol (encoding the actual type of the particle) is the more fundamental quantity. However, I would still like to see type parameters so that I can dispatch on the type of particle. Perhaps Particle{S,Z,M} where S is the particle symbol, Z is the charge state, and M is the mass number. I ordered them in this way because it seems most likely that I would want to dispatch on species first, charge second, and least commonly dispatch on mass number, but this is definitely biased by my plasma background.

@Beforerr
Copy link
Member

Beforerr commented Nov 16, 2024

How about

struct Particle <: AbstractParticle
symbol::Symbol
charge_number::Int
mass_number::Int
end

@kwdef struct CustomParticle <: AbstractParticle
charge_number::Int
mass::Mass
symbol::Symbol = nothing
end

@Beforerr
Copy link
Member

Hi @adamslc please see #4 . For PIC simulation maybe CustomParticle is more relevant? since real mass is not always used?

@adamslc
Copy link
Member Author

adamslc commented Nov 17, 2024

I've been thinking about this some more, and I'd really like to be able to use type interface to interact with and select particles. What do you think about a much more exhaustive type hierarchy:

AbstractChargedParticle{Z}
└─ AbstractLepton{Z}
   └─ Electron{Z}
   ⋮
└─ AbstractQuark{Z}
   └─ Up{Z}
   ⋮
⋮
└─ Particle{Z,P,M}
└─ CustomParticle{Z}

This way the non-ion particles are easily distinguished by their type, and for ions, they can still be dispatched on by proton number (P) and mass number (M). I don't personally have a need for quark, gauge boson, or Higgs types, but it seems nice to include them for completeness.

Thus I propose:

struct Particle{Z,P,M} <: AbstractParticle{Z}
    symbol::Symbol
end
@kwdef struct CustomParticle{Z} <: AbstractParticle{Z}
    mass::Mass
    symbol::Symbol = nothing
end

The symbol can be kept for printing convenience, although I'm not sure it is needed. Maybe it should be a string instead of a symbol?

@Beforerr
Copy link
Member

Hi @adamslc . Exhaustive type hierarchy in my opinion is definitely better.

My concern is that charge state only makes sense for ions. For particles like electron i feel it is more like internal thing. (I don't know too much about particle Physics, so i may be wrong)

Something else to consider is in that Type hierarchy 'Particle' is not a good name anymore, we may need something like 'particle' function as an united interface to créate Particle.

@adamslc
Copy link
Member Author

adamslc commented Nov 18, 2024

Yes, I agree that AbstractChargedParticle shouldnt have a Ztype parameter, onlyParticleandCustomParticle`.

And having a particlefunction that parses a string to return the correct representation sounds great! It will be type-unstable but that should be ok because the parsing should only happen in performance-insensitive parts of code.

@Beforerr
Copy link
Member

Implemented now in #4 with suggested type hierarchy

@Beforerr Beforerr reopened this Nov 19, 2024
@Beforerr
Copy link
Member

Beforerr commented Nov 20, 2024

The two options here (option 1 with concrete fields, option 2 with type parameters) both have their merits, and the best choice depends on specific use case:

  • Option 1 offers simplicity, suitable for most general applications and for cases where particle properties are dynamic or numerous or are determined at runtime (when charge state may change and mass number could change) and is not limited to atomic ions

  • Option 3 provides performance benefits through type-level optimizations where particle properties are known beforehand but introduces type proliferation and additional complexity.

struct Particle <: AbstractChargeParticle
    symbol::Symbol
    charge_number::Int
    mass_number::Int
end
struct Particle{Z, P, M} <: AbstractChargeParticle end

I think maybe we could incorporate both concrete field-based and type-parameterized Particle structures within the same Julia package. And allow users to select the most appropriate representation based on their specific needs, whether they prioritize flexibility or performance.

What do you think? @adamslc

For the option 2, maybe we could name it ParamParticle or StaticParticle or just SParticle like SVector.

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

No branches or pull requests

2 participants