Skip to content

Schema Reference

Configuration contract for SimulationConfig. Generated from mp3du-rs/python/mp3du_schema.json.

Auto-generated

This page is generated by scripts/gen_schema_docs.py. Do not edit manually.

Practical Notes

  • velocity_method currently validates only Waterloo in the JSON schema. SSP&A workflows still use the same SimulationConfig contract, so set velocity_method to Waterloo even when the velocity field was fitted with SSP&A outside the config JSON.
  • The capture block controls termination conditions for a particle. Some settings are global limits (max_time, max_steps), while others only matter when the particle encounters specific boundary/capture situations (capture_radius, face_epsilon).

Top-Level Properties

Property Type Required Default Constraints Description
velocity_method string Yes one of: Waterloo Velocity-method selector used by the SimulationConfig schema. Currently only Waterloo is accepted here. SSP&A workflows still use Waterloo in the config because the SSP&A velocity field is fitted outside the JSON config and then tracked through the same runtime interface.
solver string Yes one of: Euler, Rk4StepDoubling, DormandPrince, CashKarp, VernerRobust, VernerEfficient Runge-Kutta solver variant for particle integration. Euler uses a fixed step (non-adaptive). Rk4StepDoubling is a classic RK4 with step-doubling error control. DormandPrince is the recommended default (embedded 4/5 pair). CashKarp is an alternative 4/5 pair. VernerRobust and VernerEfficient are 6/7 pairs for high-accuracy work.
adaptive object Yes Adaptive time-stepping parameters that control how the solver adjusts dt between integration steps. All fields are required even when using the non-adaptive Euler solver.
dispersion object ("None" | "Gsde" | "Ito") Yes Dispersion model configuration. Choose None for pure advection, Gsde for the generalised stochastic differential equation method, or Ito for the Itô-calculus formulation. When dispersion is enabled, each particle run is stochastic — run multiple realisations (Monte Carlo) to build concentration fields.
retardation_enabled boolean Yes When true, the solver multiplies each cell's velocity by 1/R where R is the retardation factor from the cell properties. Requires that retardation factors were provided during hydration. Set to false for conservative (non-sorbing) transport.
capture object Yes
initial_dt number Yes > 0 Starting time step for the first integration step of each particle, in model time units. The adaptive solver will adjust this after the first step. For the Euler solver this is overridden by adaptive.euler_dt.
max_dt number Yes > 0 Upper bound on the time step in model time units. The adaptive solver will never grow dt beyond this value, even if the error estimate would allow it. Prevents particles from jumping over cells in smooth regions.
direction number Yes one of: 1.0, -1.0 Tracking direction. Use 1.0 for forward tracking (particles move downgradient / in the direction of flow) or -1.0 for backward tracking (particles move upgradient / against the flow direction). Must be exactly 1.0 or -1.0 — integer values (1, -1) are rejected by the schema.

adaptive

Property Type Required Default Constraints Description
tolerance number Yes > 0 Local truncation error threshold for step acceptance. The solver compares its embedded-pair error estimate against this value; steps with error ≤ tolerance are accepted. Smaller values produce more accurate trajectories but require more (smaller) steps. Typical starting value: 1e-6.
safety number Yes > 0 Safety factor (S) applied when computing the next step size: h_new = h × S × (tol/err)^alpha. Values < 1 (typically 0.8–0.95) make step-size growth conservative, reducing the chance of immediate rejection on the next step. Recommended: 0.9.
alpha number Yes > 0 Exponent in the step-scaling formula h_new = h × S × (tol/err)^alpha. Derived from the solver order: for a method of order p, the optimal value is 1/(p+1). Use 0.2 for 4th/5th-order pairs (DormandPrince, CashKarp) and ~0.125 for 6th/7th-order pairs (Verner).
min_scale number Yes > 0 Minimum allowed step-size scaling factor. After a rejected step the new dt cannot shrink below min_scale × current dt. Prevents pathological collapse of the step size. Typical value: 0.2 (step can shrink to at most 1/5th).
max_scale number Yes > 0 Maximum allowed step-size scaling factor. After an accepted step the new dt cannot grow beyond max_scale × current dt. Prevents overshooting into a region where the step would be rejected. Typical value: 5.0.
max_rejects integer Yes ≥ 0 Maximum number of consecutive rejected steps before the solver terminates the particle with an error. Increase this (e.g. to 50) if particles encounter sharp velocity gradients that need many successive reductions. Default recommendation: 10.
min_dt number Yes > 0 Absolute minimum time step in model time units. If the adaptive algorithm needs a step smaller than this, the particle terminates with an error. Set small enough to handle tight regions but large enough to prevent the solver from stalling indefinitely. Typical value: 1e-10.
euler_dt number Yes > 0 Fixed time step used exclusively by the Euler solver (which is non-adaptive). Ignored by all other solvers. In model time units.

capture

Property Type Required Default Constraints Description
max_time number Yes > 0 Maximum cumulative tracking time for one particle, in the model's time units (for example days or seconds). The particle terminates once its accumulated travel time reaches or exceeds this value.
max_steps integer Yes ≥ 1 Maximum number of accepted integration steps for one particle. This is unitless and acts as a safety cap on solver work even if the particle has not yet been captured or reached max_time.
stagnation_velocity number Yes ≥ 0 Velocity-magnitude threshold used for stagnation detection, in model length per model time (for example m/day or ft/s). A step is counted as stagnant when the particle velocity magnitude is below this value.
stagnation_limit integer Yes ≥ 1 Number of consecutive stagnant accepted steps required before termination. If velocity rises back above stagnation_velocity, the stagnation counter resets to zero.
capture_radius number No > 0 Distance from the well centre (cell centre) used for internal-well capture. A particle is terminated only after it gets within this radius of the centre. Smaller values delay capture until the particle is very near the centre; larger values make capture occur sooner after entering the well cell.
face_epsilon number No 1e-06 > 0 Tolerance for top/bottom face proximity checks during IFACE-based capture. Particle is considered at the face when z > 1 - face_epsilon (top) or z < face_epsilon (bottom). Increase only if particles leak through top/bottom capture faces; decrease only if they are being captured too far from the face. Default: 1e-6.

Capture Behavior Notes

Capture/termination checks are evaluated in a priority order. A particle stops as soon as the first applicable condition is met:

  1. Outside the model / inactive / model boundary — immediate termination.
  2. Internal well capture — if the cell has an IFACE-0-style internal well, the particle is captured only when it is within capture_radius of the cell centre. Smaller radii delay capture until the particle gets very near the centre; larger radii make capture happen sooner after entering the cell.
  3. Internal sink/source capture — IFACE-based internal boundaries capture immediately on cell entry when the boundary flow direction is consistent with the tracking direction.
  4. Top/bottom face capture — top-face and bottom-face boundaries only capture when the particle is sufficiently close to that face; face_epsilon controls this proximity test.
  5. Water-table top-face termination — in forward tracking, a top-face water-table condition can terminate a particle even when no explicit top-face BC name is present.
  6. Time limitmax_time is compared against the particle's accumulated travel time in model time units; termination occurs when particle time reaches or exceeds that value.
  7. Step limitmax_steps counts accepted integration steps, not physical distance or elapsed wall-clock time.
  8. Stagnation — after each accepted step, if velocity magnitude is below stagnation_velocity, the consecutive stagnation counter increments; otherwise it resets to zero. The particle terminates once that counter reaches stagnation_limit.

Flow sign matters for boundary-driven capture: in forward tracking, sink-like flows capture; in backward tracking, source-like flows capture. max_time uses model time units, stagnation_velocity uses model length per model time, and both max_steps and stagnation_limit are unitless counters.

dispersion

The dispersion property uses one of the following variant schemas:

Variant: "None"

Property Type Required Default Constraints Description
method string Yes must be None Disables dispersion. Particles follow pure advective streamlines.

Variant: "Gsde"

Property Type Required Default Constraints Description
method string Yes must be Gsde Generalised Stochastic Differential Equation dispersion method.
alpha_l number Yes ≥ 0 Longitudinal dispersivity — spreading along the flow direction, in model length units (e.g. metres). Must be ≥ alpha_th ≥ alpha_tv.
alpha_th number Yes ≥ 0 Horizontal transverse dispersivity — spreading perpendicular to flow in the horizontal plane, in model length units.
alpha_tv number Yes ≥ 0 Vertical transverse dispersivity — spreading perpendicular to flow in the vertical direction, in model length units. Typically the smallest of the three.

Variant: "Ito"

Property Type Required Default Constraints Description
method string Yes must be Ito Itô-calculus dispersion formulation.
alpha_l number Yes ≥ 0 Longitudinal dispersivity — spreading along the flow direction, in model length units (e.g. metres). Must be ≥ alpha_th ≥ alpha_tv.
alpha_th number Yes ≥ 0 Horizontal transverse dispersivity — spreading perpendicular to flow in the horizontal plane, in model length units.
alpha_tv number Yes ≥ 0 Vertical transverse dispersivity — spreading perpendicular to flow in the vertical direction, in model length units. Typically the smallest of the three.
Raw JSON Schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "MP3DU SimulationConfig",
  "type": "object",
  "required": [
    "velocity_method",
    "solver",
    "adaptive",
    "dispersion",
    "retardation_enabled",
    "capture",
    "initial_dt",
    "max_dt",
    "direction"
  ],
  "properties": {
    "velocity_method": {
      "type": "string",
      "enum": [
        "Waterloo"
      ],
      "description": "Velocity-method selector used by the SimulationConfig schema. Currently only `Waterloo` is accepted here. SSP&A workflows still use `Waterloo` in the config because the SSP&A velocity field is fitted outside the JSON config and then tracked through the same runtime interface."
    },
    "solver": {
      "type": "string",
      "enum": [
        "Euler",
        "Rk4StepDoubling",
        "DormandPrince",
        "CashKarp",
        "VernerRobust",
        "VernerEfficient"
      ],
      "description": "Runge-Kutta solver variant for particle integration. `Euler` uses a fixed step (non-adaptive). `Rk4StepDoubling` is a classic RK4 with step-doubling error control. `DormandPrince` is the recommended default (embedded 4/5 pair). `CashKarp` is an alternative 4/5 pair. `VernerRobust` and `VernerEfficient` are 6/7 pairs for high-accuracy work."
    },
    "adaptive": {
      "type": "object",
      "description": "Adaptive time-stepping parameters that control how the solver adjusts dt between integration steps. All fields are required even when using the non-adaptive Euler solver.",
      "required": [
        "tolerance",
        "safety",
        "alpha",
        "min_scale",
        "max_scale",
        "max_rejects",
        "min_dt",
        "euler_dt"
      ],
      "properties": {
        "tolerance": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Local truncation error threshold for step acceptance. The solver compares its embedded-pair error estimate against this value; steps with error \u2264 tolerance are accepted. Smaller values produce more accurate trajectories but require more (smaller) steps. Typical starting value: 1e-6."
        },
        "safety": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Safety factor (S) applied when computing the next step size: h_new = h \u00d7 S \u00d7 (tol/err)^alpha. Values < 1 (typically 0.8\u20130.95) make step-size growth conservative, reducing the chance of immediate rejection on the next step. Recommended: 0.9."
        },
        "alpha": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Exponent in the step-scaling formula h_new = h \u00d7 S \u00d7 (tol/err)^alpha. Derived from the solver order: for a method of order p, the optimal value is 1/(p+1). Use 0.2 for 4th/5th-order pairs (DormandPrince, CashKarp) and ~0.125 for 6th/7th-order pairs (Verner)."
        },
        "min_scale": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Minimum allowed step-size scaling factor. After a rejected step the new dt cannot shrink below min_scale \u00d7 current dt. Prevents pathological collapse of the step size. Typical value: 0.2 (step can shrink to at most 1/5th)."
        },
        "max_scale": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Maximum allowed step-size scaling factor. After an accepted step the new dt cannot grow beyond max_scale \u00d7 current dt. Prevents overshooting into a region where the step would be rejected. Typical value: 5.0."
        },
        "max_rejects": {
          "type": "integer",
          "minimum": 0,
          "description": "Maximum number of consecutive rejected steps before the solver terminates the particle with an error. Increase this (e.g. to 50) if particles encounter sharp velocity gradients that need many successive reductions. Default recommendation: 10."
        },
        "min_dt": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Absolute minimum time step in model time units. If the adaptive algorithm needs a step smaller than this, the particle terminates with an error. Set small enough to handle tight regions but large enough to prevent the solver from stalling indefinitely. Typical value: 1e-10."
        },
        "euler_dt": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Fixed time step used exclusively by the Euler solver (which is non-adaptive). Ignored by all other solvers. In model time units."
        }
      },
      "additionalProperties": false
    },
    "dispersion": {
      "description": "Dispersion model configuration. Choose `None` for pure advection, `Gsde` for the generalised stochastic differential equation method, or `Ito` for the It\u00f4-calculus formulation. When dispersion is enabled, each particle run is stochastic \u2014 run multiple realisations (Monte Carlo) to build concentration fields.",
      "oneOf": [
        {
          "type": "object",
          "required": [
            "method"
          ],
          "properties": {
            "method": {
              "const": "None",
              "description": "Disables dispersion. Particles follow pure advective streamlines."
            }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": [
            "method",
            "alpha_l",
            "alpha_th",
            "alpha_tv"
          ],
          "properties": {
            "method": {
              "const": "Gsde",
              "description": "Generalised Stochastic Differential Equation dispersion method."
            },
            "alpha_l": {
              "type": "number",
              "minimum": 0,
              "description": "Longitudinal dispersivity \u2014 spreading along the flow direction, in model length units (e.g. metres). Must be \u2265 alpha_th \u2265 alpha_tv."
            },
            "alpha_th": {
              "type": "number",
              "minimum": 0,
              "description": "Horizontal transverse dispersivity \u2014 spreading perpendicular to flow in the horizontal plane, in model length units."
            },
            "alpha_tv": {
              "type": "number",
              "minimum": 0,
              "description": "Vertical transverse dispersivity \u2014 spreading perpendicular to flow in the vertical direction, in model length units. Typically the smallest of the three."
            }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": [
            "method",
            "alpha_l",
            "alpha_th",
            "alpha_tv"
          ],
          "properties": {
            "method": {
              "const": "Ito",
              "description": "It\u00f4-calculus dispersion formulation."
            },
            "alpha_l": {
              "type": "number",
              "minimum": 0,
              "description": "Longitudinal dispersivity \u2014 spreading along the flow direction, in model length units (e.g. metres). Must be \u2265 alpha_th \u2265 alpha_tv."
            },
            "alpha_th": {
              "type": "number",
              "minimum": 0,
              "description": "Horizontal transverse dispersivity \u2014 spreading perpendicular to flow in the horizontal plane, in model length units."
            },
            "alpha_tv": {
              "type": "number",
              "minimum": 0,
              "description": "Vertical transverse dispersivity \u2014 spreading perpendicular to flow in the vertical direction, in model length units. Typically the smallest of the three."
            }
          },
          "additionalProperties": false
        }
      ]
    },
    "retardation_enabled": {
      "type": "boolean",
      "description": "When true, the solver multiplies each cell's velocity by 1/R where R is the retardation factor from the cell properties. Requires that retardation factors were provided during hydration. Set to false for conservative (non-sorbing) transport."
    },
    "capture": {
      "type": "object",
      "required": [
        "max_time",
        "max_steps",
        "stagnation_velocity",
        "stagnation_limit"
      ],
      "properties": {
        "max_time": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Maximum cumulative tracking time for one particle, in the model's time units (for example days or seconds). The particle terminates once its accumulated travel time reaches or exceeds this value."
        },
        "max_steps": {
          "type": "integer",
          "minimum": 1,
          "description": "Maximum number of accepted integration steps for one particle. This is unitless and acts as a safety cap on solver work even if the particle has not yet been captured or reached max_time."
        },
        "stagnation_velocity": {
          "type": "number",
          "minimum": 0,
          "description": "Velocity-magnitude threshold used for stagnation detection, in model length per model time (for example m/day or ft/s). A step is counted as stagnant when the particle velocity magnitude is below this value."
        },
        "stagnation_limit": {
          "type": "integer",
          "minimum": 1,
          "description": "Number of consecutive stagnant accepted steps required before termination. If velocity rises back above stagnation_velocity, the stagnation counter resets to zero."
        },
        "capture_radius": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Distance from the well centre (cell centre) used for internal-well capture. A particle is terminated only after it gets within this radius of the centre. Smaller values delay capture until the particle is very near the centre; larger values make capture occur sooner after entering the well cell."
        },
        "face_epsilon": {
          "type": "number",
          "exclusiveMinimum": 0,
          "default": 1e-06,
          "description": "Tolerance for top/bottom face proximity checks during IFACE-based capture. Particle is considered at the face when z > 1 - face_epsilon (top) or z < face_epsilon (bottom). Increase only if particles leak through top/bottom capture faces; decrease only if they are being captured too far from the face. Default: 1e-6."
        }
      },
      "additionalProperties": false
    },
    "initial_dt": {
      "type": "number",
      "exclusiveMinimum": 0,
      "description": "Starting time step for the first integration step of each particle, in model time units. The adaptive solver will adjust this after the first step. For the Euler solver this is overridden by adaptive.euler_dt."
    },
    "max_dt": {
      "type": "number",
      "exclusiveMinimum": 0,
      "description": "Upper bound on the time step in model time units. The adaptive solver will never grow dt beyond this value, even if the error estimate would allow it. Prevents particles from jumping over cells in smooth regions."
    },
    "direction": {
      "type": "number",
      "enum": [
        1.0,
        -1.0
      ],
      "description": "Tracking direction. Use 1.0 for forward tracking (particles move downgradient / in the direction of flow) or -1.0 for backward tracking (particles move upgradient / against the flow direction). Must be exactly 1.0 or -1.0 \u2014 integer values (1, -1) are rejected by the schema."
    }
  },
  "additionalProperties": false
}