{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://earthsciml.org/schemas/esm-integrator/0.1.0/tableau.schema.json",
  "title": "EarthSciIntegrator method coefficient table",
  "description": "One method's coefficients, error estimate and controller defaults (spec/methods.md). Generated by tools/tableaus/extract.jl into spec/tableaus/<name>.json; both implementations read these files rather than restating the numbers.",
  "type": "object",
  "required": [
    "schema", "name", "family", "form", "stages", "order", "embedded_order", "error_estimate",
    "controller", "first_same_as_last", "stiffly_accurate", "source"
  ],
  "additionalProperties": false,
  "properties": {
    "schema": {"const": "https://earthsciml.org/schemas/esm-integrator/0.1.0/tableau.schema.json"},
    "name": {"$ref": "run-config.schema.json#/$defs/alg"},
    "family": {"enum": ["explicit_rk", "rosenbrock", "sdirk", "imex", "theta"]},
    "form": {"enum": ["butcher", "shu_osher", "rosenbrock_transformed", "rosenbrock23", "sdirk", "imex_euler", "theta"]},
    "ordinarydiffeq_algorithm": {"type": "string"},
    "stages": {"type": "integer", "minimum": 1},
    "order": {"type": "integer", "minimum": 1},
    "embedded_order": {"oneOf": [{"type": "integer", "minimum": 0}, {"type": "null"}]},
    "error_estimate": {
      "description": "How the step's error estimate is formed (spec/methods.md §3-§5). 'none' means the method has no estimate, so a leaf using it must give dt (D52).",
      "enum": ["none", "embedded", "shu_osher_embedded", "residual_control", "rosenbrock23", "embedded_smoothed", "divided_difference"]
    },
    "first_same_as_last": {"type": "boolean"},
    "stiffly_accurate": {"type": "boolean"},
    "explicit_first_stage": {"type": "boolean"},

    "A": {"$ref": "#/$defs/square"},
    "C": {"$ref": "#/$defs/square"},
    "b": {"$ref": "#/$defs/vector"},
    "btilde": {"$ref": "#/$defs/vector"},
    "c": {"$ref": "#/$defs/vector"},
    "c_ordinarydiffeq": {"$ref": "#/$defs/vector"},
    "d": {
      "description": "Time-derivative coefficients per stage (rosenbrock_transformed), or the single diagonal coefficient of Rosenbrock23.",
      "oneOf": [{"$ref": "#/$defs/vector"}, {"type": "number"}]
    },
    "gamma": {"type": "number"},
    "c32": {"type": "number"},
    "alpha": {"$ref": "#/$defs/triangle"},
    "beta": {"$ref": "#/$defs/triangle"},
    "embedded": {
      "type": "object",
      "required": ["alpha", "beta", "scale"],
      "additionalProperties": false,
      "properties": {
        "alpha": {"$ref": "#/$defs/vector"},
        "beta": {"$ref": "#/$defs/vector"},
        "scale": {"type": "number"}
      }
    },
    "residual_control": {
      "type": "object",
      "required": ["sigma", "scale"],
      "additionalProperties": false,
      "properties": {
        "sigma": {"$ref": "#/$defs/vector"},
        "scale": {"type": "number"}
      }
    },
    "divided_difference": {
      "type": "object",
      "required": ["constant"],
      "additionalProperties": false,
      "properties": {"constant": {"type": "number"}}
    },
    "kpp": {
      "type": "object",
      "required": ["elo", "new_f", "controller"],
      "additionalProperties": false,
      "properties": {
        "elo": {"type": "number"},
        "new_f": {"type": "array", "items": {"type": "boolean"}},
        "controller": {
          "type": "object",
          "required": ["fac_min", "fac_max", "fac_rej", "fac_safe", "source"],
          "additionalProperties": false,
          "properties": {
            "fac_min": {"type": "number"},
            "fac_max": {"type": "number"},
            "fac_rej": {"type": "number"},
            "fac_safe": {"type": "number"},
            "source": {"$ref": "#/$defs/source"}
          }
        }
      }
    },
    "controller": {
      "oneOf": [
        {"type": "null"},
        {
          "type": "object",
          "required": [
            "beta1", "beta2", "gamma", "qmin", "qmax", "qmax_first_step", "qsteady_min",
            "qsteady_max", "failfactor", "qoldinit", "pid_beta3", "pid_accept_safety", "source"
          ],
          "additionalProperties": false,
          "properties": {
            "beta1": {"type": "number"},
            "beta2": {"type": "number"},
            "gamma": {"type": "number"},
            "qmin": {"type": "number"},
            "qmax": {"type": "number"},
            "qmax_first_step": {"type": "number"},
            "qsteady_min": {"type": "number"},
            "qsteady_max": {"type": "number"},
            "failfactor": {"type": "number"},
            "qoldinit": {"type": "number"},
            "pid_beta3": {"type": "number"},
            "pid_accept_safety": {"type": "number"},
            "source": {"$ref": "#/$defs/source"}
          }
        }
      ]
    },
    "source": {
      "oneOf": [
        {"$ref": "#/$defs/source"},
        {"type": "array", "items": {"$ref": "#/$defs/source"}, "minItems": 1}
      ]
    },
    "notes": {"type": "array", "items": {"type": "string"}}
  },

  "allOf": [
    {
      "if": {"properties": {"form": {"const": "butcher"}}},
      "then": {"required": ["A", "b", "c"]}
    },
    {
      "if": {"properties": {"form": {"const": "shu_osher"}}},
      "then": {"required": ["alpha", "beta", "c"]}
    },
    {
      "if": {"properties": {"form": {"const": "rosenbrock_transformed"}}},
      "then": {"required": ["A", "C", "gamma", "c", "d", "b"]}
    },
    {
      "if": {"properties": {"form": {"const": "rosenbrock23"}}},
      "then": {"required": ["d", "c32"]}
    },
    {
      "if": {"properties": {"form": {"const": "sdirk"}}},
      "then": {"required": ["A", "b", "c", "explicit_first_stage"]}
    },
    {
      "if": {"properties": {"error_estimate": {"enum": ["embedded", "embedded_smoothed"]}}},
      "then": {"required": ["btilde"]}
    },
    {
      "if": {"properties": {"error_estimate": {"const": "shu_osher_embedded"}}},
      "then": {"required": ["embedded"]}
    },
    {
      "if": {"properties": {"error_estimate": {"const": "residual_control"}}},
      "then": {"required": ["residual_control"]}
    },
    {
      "if": {"properties": {"error_estimate": {"const": "divided_difference"}}},
      "then": {"required": ["divided_difference"]}
    },
    {
      "if": {"properties": {"error_estimate": {"const": "none"}}},
      "then": {"properties": {"controller": {"type": "null"}, "embedded_order": {"type": "null"}}}
    }
  ],

  "$defs": {
    "vector": {"type": "array", "items": {"type": "number"}, "minItems": 1},
    "square": {"type": "array", "items": {"$ref": "#/$defs/vector"}, "minItems": 1},
    "triangle": {
      "description": "Row i (1-based) has i entries, for j = 0 .. i-1.",
      "type": "array",
      "items": {"$ref": "#/$defs/vector"},
      "minItems": 1
    },
    "source": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "package": {"type": "string"},
        "version": {"type": "string"},
        "file": {"type": "string"},
        "line": {"type": "integer", "minimum": 1},
        "reference": {"type": "string"},
        "note": {"type": "string"}
      },
      "anyOf": [{"required": ["file", "line"]}, {"required": ["reference"]}]
    }
  }
}
