muse2 2.1.0

A tool for running simulations of energy systems
Documentation
//! Patches to be used in integration tests.
//!
//! This is used to test small variations on existing example models.
use crate::patch::FilePatch;
use anyhow::{Context, Result};
use std::{collections::BTreeMap, sync::LazyLock};

/// Map of patches keyed by name, with the file patches and an optional TOML patch
type PatchMap = BTreeMap<&'static str, (Vec<FilePatch>, Option<&'static str>)>;

/// The patches, keyed by name
static PATCHES: LazyLock<PatchMap> = LazyLock::new(get_all_patches);

/// Get all patches
fn get_all_patches() -> PatchMap {
    [
        // The simple example with gas boiler process made divisible
        (
            "simple_divisible",
            (
                vec![
                    FilePatch::new("processes.csv")
                        .with_deletion("RGASBR,Gas boiler,all,RSHEAT,2020,2040,1.0,")
                        .with_addition("RGASBR,Gas boiler,all,RSHEAT,2020,2040,1.0,1000"),
                ],
                None,
            ),
        ),
        // The simple example with objective type set to NPV for one agent
        (
            "simple_npv",
            (
                vec![
                    FilePatch::new("agent_objectives.csv")
                        .with_deletion("A0_RES,all,lcox,,")
                        .with_addition("A0_RES,all,npv,,"),
                ],
                None,
            ),
        ),
        (
            // The simple example with electricity priced using marginal costs
            "simple_marginal",
            (
                vec![FilePatch::new("commodities.csv").with_replacement(&[
                    "id,description,type,time_slice_level,pricing_strategy,units",
                    "GASPRD,Gas produced,sed,season,shadow,PJ",
                    "GASNAT,Natural gas,sed,season,shadow,PJ",
                    "ELCTRI,Electricity,sed,daynight,marginal,PJ",
                    "RSHEAT,Residential heating,svd,daynight,shadow,PJ",
                    "CO2EMT,CO2 emitted,oth,annual,unpriced,ktCO2",
                ])],
                None,
            ),
        ),
        (
            // The simple example with gas commodities priced using full costs
            "simple_full",
            (
                vec![FilePatch::new("commodities.csv").with_replacement(&[
                    "id,description,type,time_slice_level,pricing_strategy,units",
                    "GASPRD,Gas produced,sed,season,full,PJ",
                    "GASNAT,Natural gas,sed,season,full,PJ",
                    "ELCTRI,Electricity,sed,daynight,shadow,PJ",
                    "RSHEAT,Residential heating,svd,daynight,shadow,PJ",
                    "CO2EMT,CO2 emitted,oth,annual,unpriced,ktCO2",
                ])],
                None,
            ),
        ),
        (
            // The simple example with electricity priced using average marginal costs
            "simple_marginal_average",
            (
                vec![FilePatch::new("commodities.csv").with_replacement(&[
                    "id,description,type,time_slice_level,pricing_strategy,units",
                    "GASPRD,Gas produced,sed,season,shadow,PJ",
                    "GASNAT,Natural gas,sed,season,shadow,PJ",
                    "ELCTRI,Electricity,sed,daynight,marginal_average,PJ",
                    "RSHEAT,Residential heating,svd,daynight,shadow,PJ",
                    "CO2EMT,CO2 emitted,oth,annual,unpriced,ktCO2",
                ])],
                None,
            ),
        ),
        (
            // The simple example with gas commodities priced using average full costs
            "simple_full_average",
            (
                vec![FilePatch::new("commodities.csv").with_replacement(&[
                    "id,description,type,time_slice_level,pricing_strategy,units",
                    "GASPRD,Gas produced,sed,season,full_average,PJ",
                    "GASNAT,Natural gas,sed,season,full_average,PJ",
                    "ELCTRI,Electricity,sed,daynight,shadow,PJ",
                    "RSHEAT,Residential heating,svd,daynight,shadow,PJ",
                    "CO2EMT,CO2 emitted,oth,annual,unpriced,ktCO2",
                ])],
                None,
            ),
        ),
        // The simple example with the ironing-out loop turned on
        (
            "simple_ironing_out",
            (vec![], Some("max_ironing_out_iterations = 10")),
        ),
    ]
    .into_iter()
    .collect()
}

/// Get the names for all the patches
pub fn get_patch_names() -> impl Iterator<Item = &'static str> {
    PATCHES.keys().copied()
}

/// Get patches for the named patched example
pub fn get_patches(name: &str) -> Result<&'static (Vec<FilePatch>, Option<&'static str>)> {
    PATCHES
        .get(name)
        .with_context(|| format!("Patched example '{name}' not found"))
}