Uncertainty quantification#

A single scenario computation takes about half a second once compiled, and its linearization about the same (see the computational gains). This makes ensemble and sampling studies practical on a laptop, where they would be prohibitive with finite-difference or non-compiled models. Several complementary workflows are available, from the ones used in the paper to full sampling-based UQ.

Discrete sweeps (as in the paper)#

The paper treats deep uncertainty with discrete alternatives, re-optimizing under each:

  • Aircraft technology: technology_index (0/1/2) selects the Lower/Mid/Upper values of every component technology parameter, of the current-fleet efficiency quartiles, and of the fleet lifetimes.

  • Background scenario: global_scenario_name selects the SSP-RCP trajectory for population, GDP, grid emission factor, and resource availability.

  • Resource allocation: preferential_energy switches the fair share between 5.0 % and 8.6 %.

The scripts of the optimization examples sweep these switches; new sweeps are one loop over single_policy_scenario_optimization().

Robust optimization across an ensemble#

MultiScenario vectorizes a TemporalScenario across background scenarios with jax.vmap, evaluating the whole ensemble in one compiled call. The optimization variables are split between a set shared across the ensemble (the aircraft mix) and per-scenario sets (the energy mix), and the objective is the ensemble mean; see the robustness formulation and the robust policy results. To make a policy robust to a different uncertainty source, change the list of global_scenario_names in single_policy_robust_scenario_optimization(), or adjust which variables are fixed versus scenario-specific in multi_scenario_setup.

Sampling uncertain parameters#

Most numeric assumptions are inputs of the assembled GEMSEO discipline: pathway efficiencies and emission indices, price elasticity, discount rate, and fair shares. Uncertainty propagation is therefore a standard GEMSEO DOE over the scenario discipline (the aircraft technology parameters are a special case, treated below). Sketch:

from gemseo import create_design_space
from gemseo import create_scenario

from noads.application.scenario_setup import single_scenario_setup

scenario, _, _, _, _ = single_scenario_setup(
    name="UQ",
    background_scenario_name="SSP2-26",
    start_year=2025.0,
    end_year=2075.0,
    technology_index=1,
)

uncertain_space = create_design_space()
uncertain_space.add_variable(
    "HEFA.direct.CO2_index", lower_bound=50.0, upper_bound=75.0, value=62.75
)
uncertain_space.add_variable(
    "constant.price_elasticity", lower_bound=-0.4, upper_bound=-0.15, value=-0.256
)

doe = create_scenario(
    scenario.discipline,
    formulation_name="DisciplinaryOpt",
    objective_name="cumulative.CO2",
    design_space=uncertain_space,
    scenario_type="DOE",
)
doe.execute(algo_name="OT_MONTE_CARLO", n_samples=200)
dataset = doe.to_dataset()  # samples for statistics or surrogate fitting

Note

Mind the input naming conventions of the assembled discipline: scalar constants are prefixed with constant., time-dependent controls with control., and interpolated inputs with interpolate.; inspect scenario.discipline.input_grammar.names for the exact spelling.

From the same dataset, GEMSEO’s uncertainty package (gemseo.uncertainty) provides distributions, statistics, and sensitivity analyses (Morris, Sobol’), which can rank which assumptions drive cumulative emissions or the demand-aversion burden.

Exposing aircraft technology parameters#

The aircraft technology parameters (battery specific energy, fuel-cell specific power, LH2 tank gravimetric index, …) are handled differently from the other assumptions. Their (2020, 2040, 2060) anchor values are stored on the AircraftTechParameter objects at construction time (from tech_params_lower_mid_upper_2020_2040_2060[technology_index] in noads.application.base_objects), and AircraftDesign closes over them: the design model reads only the aircraft’s entry-into-service year as a discipline input and interpolates the anchor values internally. They are therefore not inputs of the assembled discipline and cannot be sampled the way the sketch above samples HEFA.direct.CO2_index. There are two ways to bring them into a UQ study.

Outer rebuild loop (no code change). Treat the technology assumptions as an outer sampling loop: for each sample, patch the anchor values (or interpolate a continuous “technology index” between the Lower/Mid/Upper triplets) in tech_params_lower_mid_upper_2020_2040_2060, rebuild the scenario with single_policy_scenario_optimization() or single_scenario_setup(), and record the outcome. This is the discrete technology sweep of the paper generalized to a continuous sample; it is simple but pays a JIT recompilation per distinct structure, so it suits a few hundred samples rather than large ensembles.

Refactor into discipline inputs (one compile). To sample them as cheaply as the other parameters, expose the anchor values as named inputs of the design model. In AircraftDesign, add {aircraft}.{param}.value_2020/2040/2060 to the design model’s default_inputs and input_names, and have _gam_design build each AircraftTechParameter (or call its spline) from those inputs instead of from the closed-over attributes. Once they flow through the assembled discipline they behave like any other input: they can be added to the uncertain_space above, sampled in a single compiled vmap DOE, and differentiated in forward mode for the local sensitivities below. This is the same refactor that would let the optimizer trade technology maturity against entry-into-service, rather than fixing it per scenario.

Local sensitivities for free#

Because objective and constraints are differentiated with forward-mode automatic differentiation, the gradient of any output with respect to any input is available at roughly the cost of one extra simulation (scenario.discipline.linearize(...)). Around an optimized policy, these gradients are first-order sensitivities of the outcome to every assumption, a cheap screening before committing to a sampling study.