amusecode / amuse

Astrophysical Multipurpose Software Environment. This is the main repository for AMUSE
http://www.amusecode.org
Apache License 2.0
158 stars 99 forks source link

Bridge support for particle-based hydrodynamics codes #935

Open MJCWilhelm opened 1 year ago

MJCWilhelm commented 1 year ago

Is your feature request related to a problem? Please describe. Currently, of the three SPH codes in AMUSE (Fi, Gadget2, Phantom), only one (Fi) has a get_gravity_at_point function implemented, and as such is the only particle-based hydrodynamics code that can be bridged with.

Additionally, in my personal experience Gadget2 is the best general-purpose galaxy (gravity-only) dynamics code in AMUSE (BHTree and Fi don't have adaptive time-stepping so have trouble with the multiscale nature of galaxies, and Bonsai requires specific hardware), but can't be directly used as e.g. a dynamic galaxy background for clusters. A work-around exists, namely copying all particle data to a tree-based code that does have Bridge support, but this gets very expensive for high-resolution galaxies.

Describe the solution you'd like The functions required for Bridge (get_gravity_at_point, get_potential_at_point) to be implemented in the Gadget2 and Phantom interfaces.

Describe alternatives you've considered For now, this snippet can be used to use the copying-to-another-code method (note that it doesn't handle particles being added/removed):

def add_auxiliary_gravity_code (code, aux_code):
    aux_code.particles.add_particles(code.particles)
    aux_channel = code.particles.new_channel_to(aux_code.particles)

    def get_gravity_from_aux_code (eps, x, y, z):
        aux_channel.copy()
        return aux_code.get_gravity

    code.get_gravity_at_point = get_gravity_from_aux_code
rieder commented 1 year ago

I don't think using the workaround is too expensive in most cases where AMUSE would be used (certainly up to a few million particles it's perfectly fine, and even in high-resolution galaxies there are other factors causing a much bigger slowdown). I've looked into implementing this, but it's not trivial. I'd be happy if someone can/will pick this up, but I'm not doing it myself... Here's a more complete example for an external kicker (similar to how it's implemented in Ekster): https://gist.github.com/rieder/cd00f45409bab3402b95211bd4f33048

rieder commented 1 year ago

(note that adding/removing particles is not needed in this example)