pyro-kinetics / pyrokinetics

Python library to run and analyse gyrokinetics simulations
https://pyrokinetics.readthedocs.io/en/latest/#
GNU Lesser General Public License v3.0
24 stars 6 forks source link

Demo: Immutable normalisations #363

Open LiamPattinson opened 3 months ago

LiamPattinson commented 3 months ago

This is a demonstration of a possible solution to Issues https://github.com/pyro-kinetics/pyrokinetics/issues/326 and https://github.com/pyro-kinetics/pyrokinetics/issues/337. I don't expect this to ever be merged!


The primary goal here is to develop a Normalisation class that both merges the functionality of SimulationNormalisation and ConventionNormalisation, and forbids the redefinition of units after creation. This would avoid the need to regularly rebuild the pint cache, which is causing significant performance issues, and would guarantee that physical units (e.g. lref_minor_radius_myrun0001) would always remain valid after definition.

There are two new classes that facilitate this:

new_simulation = simulation.with_geometry(my_new_geometry)

In this case, new_simulation will contain a brand new ConstNormalisation, LocalGeometry, LocalSpecies, and Numerics. Editing any of these new instances will not overwrite details of the originals. More complex transformations can be performed by chaining function calls:

new_simulation = simulation.with_geometry(geometry).with_species(species).to_gk_code("GENE")

Crucially, only LocalGKSimulation is responsible for generating new normalisations. Currently, physical units are set up as side effects of several functions throughout the code, and this makes it difficult to track how they evolve through the program.

I'm hoping to move towards a model in which LocalGeometry and LocalSpecies can be created using either simulation units or physical units via standard constructors, and, besides each having a normalise/with_units function that returns new instances, they won't have to worry about managing norms themselves. For now, I've had to make a few temporary edits to these classes just to get things working.

In the final version, LocalGKSimulation would be the object returned by GKInput readers, and the object passed in to write new input files. I'd like to see Pyro act as a manager of LocalGKSimulation instances, which I think would be a lot simpler than its current context-switching design. LocalGKSimulation would also be an input to GKOutput, as its contain all the needed units, geometry details, etc. It would also avoid the need to create deepcopies throughout the project, as PyroScan could make new LocalGKSimulation instances instead.

Examples of how to use this new interface are in the added tests.


A proper implementation would need to be split into several milestones. Issue https://github.com/pyro-kinetics/pyrokinetics/issues/336 would be a good place to start. There are also several other issues I ran into that I'm not sure how to handle: