Skip to content

Implement first order non-conservative processes between nodes#17

Open
AlexLipp wants to merge 13 commits intomainfrom
downstreamdistance
Open

Implement first order non-conservative processes between nodes#17
AlexLipp wants to merge 13 commits intomainfrom
downstreamdistance

Conversation

@AlexLipp
Copy link
Owner

This PR adds the ability for funmixer to simulate first order decay processes modifying tracer concentrations between sample sites on a drainage network. If we consider that the hydrographical (i.e., along flow-path) distance between two nodes on the sample network is $x$, and assuming that some tracer is removed as a function of distance according to: $\frac{dC}{dx} = -k$ then the contribution from the upstream node to the downstream node is best described by: $C_0 \exp(-kx)$, where $C_0$ is the contribution from the upstream node.

This PR implements this by making the following changes:

  • Extracting the hydrographical distance between nodes from the D8 raster and sample sites, and storing this as an edge length on the networkx sample network (see d8_processing.py, flow_acc_cfuncs.pyx)
  • Modifying the primary terms of the optimisation (and forward model) to include an exponential decay term
  • Implementing this within the test functions which now solves random optimisation problems with and without conservative behaviour for (uniform) decay constants $0 < k < 3$.

To consider non-conservative processes, the user simply has to provide a dictionary mapping sample names onto a rate constant. These rate constants apply to the edge downstream of that node. Different rate constants can be set across the entire study area. If rate_constants is not supplied, default values of $k=0$ are assumed, which recovers the initial non-conservative behaviour.

Notes

  • Because $C_0 \exp(-kx)$ is not-affine with respect to $k$, the optimisation problem cannot be made DPP compliant. As a result, unlike other parameters (e.g., export rates), the rate constants must be set when the problem is first built, and cannot be subsequently modified. $k$ for each node is therefore not a CVXPY parameter, rather a float
  • The units of $k$ are reciprocal distance $[L]^{-1}$ where the length unit is inherited from that of the D8 raster. As a consequence, to convert rate constants which have units $[T]^{-1}$ (e.g., $\mathrm{s}^{-1}$), some estimate of the material velocity ($v$) must be used!

CoPilot Summary

This pull request introduces support for first-order (exponential decay) rate constants in the sample network unmixing workflow, enabling modeling of non-conservative tracer behavior along drainage networks. It also improves the handling of spatial information in the D8 flow direction raster, including accurate calculation of distances between nodes and sub-basin areas. The most important changes are grouped below:

Support for First-Order Rate Constants in Network Unmixer:

  • Added a my_rate_constant attribute to the SampleNode class and corresponding handling in the SampleNetworkUnmixer, allowing each sub-basin/reach to have an associated decay rate constant. The rate constants are now used to weight tracer fluxes between nodes using the exponential decay law.
  • Added a _set_rate_constants method to SampleNetworkUnmixer to initialize and manage rate constants for each site, with validation and support for user input. The constructor and solve_montecarlo now accept rate_constants as an argument.

Improvements to D8 Raster Handling and Sample Graph Construction:

  • Modified the Cython backend (flow_acc_cfuncs.pyx) and Python interface to pass cell sizes (dx, dy) and the D8 flow direction array to the sample graph builder. This enables accurate calculation of distances between nodes and sub-basin areas in physical units.
  • Updated the sample graph construction to record the distance between each sample site and its downstream neighbor, storing this as distance_downstream and using it as edge metadata in the network.
  • Changed area calculations to use physical cell area (dx * dy) instead of pixel counts, and added validation to ensure the total upstream area matches expectations.

Documentation and Type Improvements:

  • Expanded the docstring for SampleNode to clarify all attributes, including new ones related to rate constants and distances.
  • Added the RateConstantData type alias for clarity.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request implements support for first-order non-conservative tracer decay processes between nodes in drainage networks. The PR introduces exponential decay modeling using the formula C₀ exp(-kx), where k is a rate constant and x is the hydrographical distance between nodes.

Changes:

  • Extracts and stores hydrographical distances between nodes as edge metadata from D8 raster processing
  • Modifies optimization and forward model to include exponential decay terms based on user-provided rate constants
  • Updates test suite to verify both conservative (k=0) and non-conservative (0 < k < 3) behavior

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.

File Description
tests/random_networks_test.py Adds rate constant parameters to test functions and generates test networks with edge lengths
funmixer/network_unmixer.py Implements rate constant handling in unmixer, forward model, and supporting functions with exponential decay weighting
funmixer/flow_acc_cfuncs.pyx Adds distance calculation between nodes using D8 directions and updates area calculations to use physical units
funmixer/d8processing.py Adds properties for cell sizes and passes D8 array with cell dimensions to graph builder

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

AlexLipp and others added 7 commits January 16, 2026 16:40
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
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.

1 participant