Backward trajectories#

Backward trajectories answer “where did this water come from?”. Fortran TRACMASS runs backward with nff = -1, which steps through the GCM fields in reverse and flips the sign of the fluxes (swap_sign). In TRACMASS-JAX the direction follows from the dates: dtm_end earlier than dtm_start means a backward run. No separate flag is needed.

import tracmass
from tracmass import gcm, seed

grid, lazy = tracmass.new_flux(
    gcm.theoretical.fluxes,
    dtm_start="2007-06-01",
    dtm_end="2007-05-27",       # earlier than dtm_start -> backward
)
print(grid.reverse, grid.timestep, lazy.n_windows)   # True 1:00:00 120

state = seed.ijk(40, 60, 30, 50, 5, 5, grid=grid)
result = tracmass.time_dependent(state, grid, lazy)

From settings, use a negative runtime or an earlier dtm_end:

[myrun_back]
dtm_start = "2010-12-31"
runtime = "-180D"            # or: dtm_end = "2010-07-04"

What changes in a backward run#

  • grid.reverse is True. grid.timestep stays positive: it is the GCM output interval, whatever the direction.

  • new_flux and update_flux step backward through the snapshots: the second slot is dtm - timestep, and each update_flux moves one more timestep into the past.

  • uflux, vflux and wflux are negated, lazily, inside new_flux/update_flux. The kernel then runs forward in “particle time” through a reversed flow, which is the same as running backward in physical time. The adapters always return forward fluxes. Passing a reverse= argument to an adapter is a leftover from an older API and raises a TypeError.

  • Particle time tt still increases, and dtm in the output decreases.

  • Output files get reverse instead of forward in their name, and "direction": "reverse" in their metadata.

Reusing a grid#

A grid built for one direction can be reused for more flux buffers. new_flux(grid, fluxes, ...) checks that the dtm_end you pass agrees with grid.reverse and raises ValueError if it does not:

grid = tracmass.new_grid("glorys", dtm_start="2010-12-31", dtm_end="2010-07-04")
lazy = tracmass.new_flux(grid, "glorys", dtm_start="2010-12-31",
                         dtm_end="2010-07-04")             # OK
tracmass.new_flux(grid, "glorys", dtm_start="2010-12-31",
                  dtm_end="2011-06-01")                    # ValueError

Loading backward output#

df = tracmass.load(env="myrun_back", dtm="2010-12-31", reverse=True)

reverse=None, the default, accepts either direction, but raises if one date matches both a forward and a backward file.