Run SurEau


source

run_sureau


def run_sureau(
    climate_df:DataFrame, # Daily climate forcing. Required columns: Year, Doy, DATE,
Tair_mean, Tair_max, Tair_min, RHair_mean, RHair_max,
RHair_min, PPT_sum, RG_sum, WS_mean.
    veg_params:SurEauVegetationParams, # Species-specific vegetation parameters. Derived parameters
are computed internally.
    soil_params:SurEauSoilParams, # Soil parameters. Derived parameters are computed internally.
    opts:SurEauModelOptions, # Simulation control options (years, numerical scheme,
adaptive stepping, output resolution).
    deep_water:bool=False, # If True, keep deepest soil layer at field capacity.
Default False.
)->DataFrame: # Simulation results at hourly resolution. One row per
timestep, with columns for all state variables, fluxes,
and diagnostics.

Run the SurEau-Ecos plant hydraulics simulation.

This is the top-level simulation driver that orchestrates the entire SurEau-Ecos model (Ruffault et al. 2022). It loops over years, days, and hours, calling every component function in the correct order to simulate the soil-plant-atmosphere water continuum, predict drought-induced hydraulic failure, and compute fuel moisture content for wildfire risk assessment.

The simulation has three nested time scales:

Yearly: Reset soil water (optional), restart phenological cycle (budburst accumulator, LAI).

Daily: Update phenology, LAI and water storage volumes, capacitances, radiation and ETP, rainfall interception, soil infiltration, and plant conductances.

Hourly (with adaptive sub-stepping): Partition ETP between canopy and soil, evaporate intercepted water, then solve the four-compartment hydraulic ODE system using the selected numerical scheme. An adaptive sub-stepping loop refines the timestep until stomatal regulation (γ) changes by < 5% and PLC changes by < 1% per sub-step.

The simulation ends when the climate data is exhausted or when leaf PLC exceeds the mortality threshold (default 90%).

Parameters:

  • climate_df: pandas DataFrame with daily climate forcing. Must contain columns:

    • Year: Calendar year (int).
    • Doy: Day of year (int, 1–365).
    • DATE: Date string or datetime.
    • Tair_mean, Tair_max, Tair_min: Air temperature (°C).
    • RHair_mean, RHair_max, RHair_min: Relative humidity (%).
    • PPT_sum: Daily precipitation (mm).
    • RG_sum: Daily global radiation (MJ/m²/day or W/m², depending on opts).
    • WS_mean: Daily mean wind speed (m/s).
  • veg_params: SurEauVegetationParams object. Species-specific parameters including: LAI_max, LMA, LDMC (leaf traits); P50_VC_leaf/stem, slope_VC_leaf/stem (vulnerability curves); P12_gs, P88_gs (stomatal regulation); gmin20, TPhase_gmin, Q10_1/2_gmin (cuticular conductance); beta_root_profile or root_Z50/Z95 (root distribution); and many others. Derived parameters (root distribution, conductance partitioning, etc.) are computed internally by sureau_vegetation_params.

  • soil_params: SurEauSoilParams object. Soil parameters including: depth (cumulative layer depths), texture parameters (alpha, n for van Genuchten), theta_sat, theta_res (porosity, residual water), RFC (rock fragment content), and initial water content. Derived parameters (layer thickness, field capacity, etc.) are computed internally by sureau_soil_params.

  • opts: SurEauModelOptions object controlling the simulation:

    • year_start, year_end: Simulation period.
    • print_progress: Whether to print progress to console.
    • comp_options: SurEauComputationOptions with:
      • numerical_scheme: "Implicit" (default), "Semi-Implicit", or "Explicit".
      • n_small_timesteps: List of sub-timestep counts for adaptive stepping, e.g. [1, 2, 4, 8].
      • Lsym, Ssym, CLapo, CTapo: Capacitance scaling flags.
      • Lcav, Scav: Cavitation flux on/off.
      • Eord: Transpiration linearization on/off (Eq. 60).
  • deep_water: If True, keep the deepest soil layer permanently at field capacity, simulating access to a groundwater table. Default False. Useful for isolating atmospheric drought (high VPD) from soil moisture limitation.

Returns:

  • pd.DataFrame: Simulation results at hourly (or sub-hourly) resolution. Each row is one timestep. Columns include:

    Water potentials: psi_LApo, psi_SApo, psi_LSym, psi_SSym, psi_all_soil (MPa).

    Cavitation: PLC_leaf, PLC_stem (%).

    Transpiration: E_lim, E_min, E_min_S (mmol/m²/s); transpiration_mm (mm/timestep).

    Stomatal regulation: regul_fact (γ, 0–1), gs_lim (mmol/m²/s).

    Fuel moisture: LFMC, DFMC, FMC_canopy (%).

    Soil: SWC per layer, psi_soil per layer.

    Diagnostics: leaf_temperature, diag_delta_regul_max, diag_delta_PLC_max, diag_timestep_hours.

Simulation structure:

┌─────────────────────────────────────────────────────────┐
│  INITIALIZATION (once)                                  │
│                                                         │
│  sureau_soil_params     → derived soil properties       │
│  sureau_vegetation_params → root profile (Eq. 19),      │
│                            root length (Eq. 18),        │
│                            conductance split (Eq. 17)   │
│  compute_soil_root_geometry → Gardner-Cowan B_GC (Eq.21)│
│  init_plant, init_soil  → initial state objects         │
└───────────────────────────┬─────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────┐
│  YEARLY LOOP                                            │
│                                                         │
│  Optional: reset soil to field capacity                 │
│  yearly_init_plant → reset phenology accumulators       │
│                                                         │
│  ┌──────────────────────────────────────────────────┐   │
│  │  DAILY LOOP                                      │   │
│  │                                                  │   │
│  │  new_climate_day       → daily climate snapshot  │   │
│  │  compute_pheno         → LAI_pheno (Eqs. A1–A2)  │   │
│  │  update_LAI_and_stocks → LAI, Q_sat (Eqs. 36–40) │   │
│  │  compute_Rn_and_ETP   → net radiation, ETP       │   │
│  │  compute_interception → ppt_soil, intercepted    │   │
│  │  compute_infiltration → soil water update        │   │
│  │  update_kplant        → conductances (Eqs. 13–20)│   │
│  │                                                  │   │
│  │  ┌───────────────────────────────────────────┐   │   │
│  │  │  HOURLY LOOP                              │   │   │
│  │  │                                           │   │   │
│  │  │  ETP partitioning (canopy vs soil)        │   │   │
│  │  │  compute_evapo_intercepted → ETP_r        │   │   │
│  │  │                                           │   │   │
│  │  │  ┌────────────────────────────────────┐   │   │   │
│  │  │  │  ADAPTIVE SUB-STEPPING             │   │   │   │
│  │  │  │                                    │   │   │   │
│  │  │  │  while Δγ > 5% or ΔPLC > 1%:       │   │   │   │
│  │  │  │    deep copy state                 │   │   │   │
│  │  │  │    for each sub-timestep:          │   │   │   │
│  │  │  │      compute_transpiration         │   │   │   │
│  │  │  │                                    │   │   │   │
│  │  │  │      sureau_solver ← THE CORE      │   │   │   │
│  │  │  │                                    │   │   │   │
│  │  │  │      update_kplant                 │   │   │   │
│  │  │  │      update_capacitances           │   │   │   │
│  │  │  │      update_soil_water             │   │   │   │
│  │  │  │    check Δγ, ΔPLC                  │   │   │   │
│  │  │  │    if ok → accept; else refine     │   │   │   │
│  │  │  └────────────────────────────────────┘   │   │   │
│  │  │                                           │   │   │
│  │  │  compute_transpiration                    │   │   │
│  │  │  flux conversions (mmol → mm)             │   │   │
│  │  │  compute_water_storage → LFMC, FMC_canopy │   │   │
│  │  │  mortality check (PLC > threshold?)       │   │   │
│  │  │  collect results → append to list         │   │   │
│  │  │                                           │   │   │
│  │  └───────────────────────────────────────────┘   │   │
│  │                                                  │   │
│  └──────────────────────────────────────────────────┘   │
│                                                         │
└─────────────────────────────────────────────────────────┘
                            │
                            ▼
                  pd.DataFrame(results)

Adaptive sub-stepping strategy:

The solver tries progressively finer sub-timesteps until the solution quality is acceptable:

ts_list = [1, 2, 4, 8]   (example)

Attempt 1: nts=1 → full hour as one timestep
    Solve → check Δγ and ΔPLC
    If Δγ < 5% AND ΔPLC < 1% → accept
    Else → discard, retry with finer resolution

Attempt 2: nts=2 → two 30-min sub-steps
    Deep copy original state → re-solve from scratch
    Solve → check → accept or refine further

Attempt 3: nts=4 → four 15-min sub-steps
    ... and so on until ts_list is exhausted

Each attempt starts from a fresh copy.deepcopy of the original state, ensuring failed attempts leave no trace. The quality criteria are:

  • Δγ < 0.05: Stomatal regulation factor must not change by more than 5% in a single sub-step. This ensures the steep sigmoid transition zone (Eq. 34) is resolved accurately.

  • ΔPLC < 1.0: Percent loss of conductivity must not change by more than 1% in a single sub-step. This ensures the cavitation vulnerability curve (Eq. 15) is resolved.

Soil water balance:

The soil is always solved explicitly. The soil-to-stem flux is computed as:

flux = k_soil_to_stem × (ψ_soil − ψ_SApo)

then converted from per-leaf-area to per-ground-area units via flux_leaf_to_stand (multiply by LAI, convert mmol → mm), and subtracted from the soil water content in update_soil_water.

Mortality criterion:

The simulation checks each hourly timestep whether PLC_leaf >= threshold_mortality (default 90%). If so, the tree is declared dead, the daily and hourly loops break, and the simulation advances to the next year (or ends). This is the hydraulic failure criterion — when 90% of the leaf xylem is embolized, the remaining 10% cannot supply enough water to sustain any physiological function.

Deep water option:

When deep_water=True, the deepest soil layer is refilled to field capacity both at the start of each day and at the end of each hourly timestep. This simulates a shallow water table that the roots can always access, isolating atmospheric drought effects (high VPD, high temperature) from soil drying effects. Useful for sensitivity analysis: “would this tree survive if it had unlimited deep water?”

Key outputs for applications:

Drought mortality prediction:
    PLC_leaf, PLC_stem   → hydraulic damage (irreversible)
    psi_LSym, psi_LApo   → water stress severity
    regul_fact (γ)       → stomatal closure degree

Wildfire risk assessment:
    LFMC                 → live fuel moisture (< 80% = danger)
    DFMC                 → dead fuel moisture
    FMC_canopy           → canopy fuel moisture (live + dead)

Water balance:
    transpiration_mm     → total plant water loss
    flux_soil_to_stem_mm → soil water uptake per layer
    soil.SWC             → soil water content per layer