Skip to main content

fluctifex

Differentiable Earth-system modeling in JAX — assimilate raw observations, forecast, and control.

fluctifex — Latin fluctus (wave, flow) + -fex (maker), by analogy with opifex, artifex. The name points at the physics, not the weather: continuum flow, which is as true of the ocean and the climate as of the atmosphere.

Status: alpha (v0.1.0). APIs are unstable and will change. This is research infrastructure.


The thesis

Most machine-learning weather models are very good correlational forecasters. They train on reanalysis — itself the output of a physical assimilation system — and map one gridded state to the next. That is useful, and it is rung one.

fluctifex is built around a different claim: if the entire pipeline is differentiable, from raw sensor readings through to the predicted field, then estimation and control fall out of the same machinery.

  • Differentiating the model backward through time against past observations is data assimilation (4D-Var) — the adjoint comes free from autodiff instead of being hand-written.
  • Differentiating it forward against a future objective is control (differentiable MPC) — the intervention gradient falls out of the same rollout.

Estimation and control are mirror images: same forward model, opposite directions in time.

   ┌─▶ OBSERVE ............ raw multi-sensor data (satellite, radar, stations, buoys)
   │       ▼
   │   ASSIMILATE .......... optimize the STATE to match PAST obs      [backward · estimation]
   │       ▼
   │   FORECAST ............ roll the differentiable model forward
   │       ▼
   │   DECIDE .............. optimize future ACTIONS to hit an OBJECTIVE [forward · control]
   │       ▼
   │   ACT ................. apply the first action only (receding horizon)
   │       ▼
   └──────── world advances → repeat each cycle ────────

Every arrow is differentiable. The same jax.grad supplies the adjoint going backward and the action gradient going forward.

Why differentiability has to start at the raw data

If the pipeline only becomes differentiable after preprocessing, then assimilation can only ever reach as far back as the preprocessed state — which means you inherit whatever a conventional assimilation system already decided. Beginning at raw, heterogeneous, gappy sensor readings is what makes end-to-end assimilation possible at all. That is why the data layer here is built on datarax, whose pipeline stages are themselves Flax NNX modules.

Architecture

Module Responsibility
fluctifex.data Dense grids + sparse station observations, as a differentiable DAG pipeline
fluctifex.models Forecast backbones (spherical/planar neural operators) and multi-sensor fusion
fluctifex.assimilation Variational (4D-Var) and sequential (Kalman) state estimation
fluctifex.control Differentiable model-predictive control with safety constraints
fluctifex.training Rollout-through-training (a-posteriori) for long-horizon stability
fluctifex.evaluation Latitude-weighted and probabilistic verification (WeatherBench-2 style)

Ecosystem

fluctifex is the Earth-system domain layer of the Avitai stack. It composes rather than reimplements:

  • opifex — neural operators (SFNO, FNO, …), PINNs, UQ, assimilation primitives, differentiable MPC
  • datarax — differentiable, DAG-structured, shardable data pipelines
  • calibrax — metrics, calibration, FLOP/roofline profiling
  • artifex — generative models (diffusion ensembles)

Its sibling cellifex applies the same substrate to cellular dynamics.

Install

pip install fluctifex                 # core (JAX + Flax only)
pip install "fluctifex[avitai]"       # + opifex / datarax / calibrax
pip install "fluctifex[all]"          # everything, incl. diffusion and docs

From source:

git clone https://github.com/avitai/fluctifex.git
cd fluctifex && ./setup.sh && source ./activate.sh
pytest tests/ -v

Quickstart

import jax
from flax import nnx

from fluctifex.models import Forecaster, ForecasterConfig
from fluctifex.training import rollout_loss

model = Forecaster(ForecasterConfig(in_channels=8, out_channels=8), rngs=nnx.Rngs(0))

state = jax.random.normal(jax.random.key(0), (2, 8, 32, 64))   # (B, C, H, W)
next_state = model(state)

# Train through the rollout, not on single steps — a-posteriori stability.
loss = rollout_loss(model, state, targets, steps=4)

Assimilate sparse observations into a state estimate:

from fluctifex.assimilation import four_dvar

analysis = four_dvar(
    model, background=x_b, observations=y, observation_operator=H, num_steps=50
)

Then plan an intervention through the forecast:

from fluctifex.control import DifferentiableMPC, MPCConfig

mpc = DifferentiableMPC(MPCConfig(horizon=8), dynamics=model)
action = mpc.solve(analysis, objective)      # apply only the first step, then re-plan

Design commitments

  1. Differentiable end to end, beginning at raw observations.
  2. Composition over reimplementation — the Avitai siblings do the heavy lifting.
  3. Stability is a first-class result, not a footnote: train through rollouts, report drift.
  4. Uncertainty gates action. A forecast does not drive a recommendation unless its uncertainty is calibrated.
  5. Honest baselines. Persistence, climatology, and matched-cost references, always.

Honest limitations

  • Alpha software; APIs will break between minor versions.
  • No pretrained weights are shipped yet.
  • Single-host SPMD is exercised; multi-host is untested.
  • Physical intervention (control) is a research capability, validated only in simulation. Nothing here is fit for real-world atmospheric intervention, and it should not be represented as such.

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fluctifex-0.1.0.tar.gz (18.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fluctifex-0.1.0-py3-none-any.whl (19.4 kB view details)

Uploaded Python 3

File details

Details for the file fluctifex-0.1.0.tar.gz.

File metadata

  • Download URL: fluctifex-0.1.0.tar.gz
  • Upload date:
  • Size: 18.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.6

File hashes

Hashes for fluctifex-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ff486206c5bd9058f6cbf59b1c94bc1a8c54b3c58a41feba693bd61b20962e60
MD5 b68ed90112e46b8b5fa6ec7ef10707ec
BLAKE2b-256 52405197fb4f9813cf8a7bd3d9f54eccacaecdf665b6d4edb2f3d6c0c3680502

See more details on using hashes here.

File details

Details for the file fluctifex-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: fluctifex-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 19.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.6

File hashes

Hashes for fluctifex-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b2b16d30e12f9e67b3835c6db4de07d0c3eece93708b6ece9653c4fd86b7d5bf
MD5 739a096f559aa7d3f085ad80ebc200b8
BLAKE2b-256 b183f9261f739d9cb373fb0b38409ce51d45886ecca5803ea8e81bfec12ef771

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page