示例#1
0
def get_constraints(
        m: AbstractModel) -> Tuple[Objective, Sequence[GeneralConstraint]]:
    """Equations and constraints for the objective of the optimisation
    (utility specification)

    Necessary variables:
        -

    Returns:
        - Objective
        - list of constraints (any of:
           - GlobalConstraint
           - GlobalInitConstraint
           - RegionalConstraint
           - RegionalInitConstraint
        )
    """
    constraints = []

    m.NPV = Var(m.t)
    m.PRTP = Param()
    constraints.extend([
        GlobalConstraint(
            lambda m, t: m.NPV[t] == m.NPV[t - 1] + m.dt * exp(-m.PRTP * (
                m.year(t) - m.beginyear)) * sum(
                    m.L(m.year(t), r) * m.utility[t, r] for r in m.regions)
            if t > 0 else Constraint.Skip,
            name="NPV",
        ),
        GlobalInitConstraint(lambda m: m.NPV[0] == 0),
    ])

    ## If carbon budget is a soft constraint (not in use now):

    # m.obj = Objective(rule=lambda m: m.NPV[m.tf] * (
    #     soft_switch(m.budget-(
    #         m.cumulative_emissions[m.year2100]
    #         + sum(soft_min(m.global_emissions[t]) for t in m.t if m.year(t) >= 2100)
    #     ), scale=1)
    # ), sense=maximize)

    objective = Objective(rule=lambda m: m.NPV[m.tf], sense=maximize)

    return objective, constraints
示例#2
0
def get_constraints(m: AbstractModel) -> Sequence[GeneralConstraint]:
    """Utility and welfare equations

    Necessary variables:
        m.utility
        m.welfare

    Returns:
        list of constraints (any of:
           - GlobalConstraint
           - GlobalInitConstraint
           - RegionalConstraint
           - RegionalInitConstraint
        )
    """
    constraints = []

    # Parameters
    m.elasmu = Param()
    m.inequal_aversion = Param()

    m.utility = Var(m.t, m.regions, initialize=10)
    m.yearly_welfare = Var(m.t)

    constraints.extend([
        RegionalConstraint(
            lambda m, t, r: m.utility[t, r] == m.consumption[t, r] / m.L(
                m.year(t), r),
            "utility",
        ),
        GlobalConstraint(
            lambda m, t: m.yearly_welfare[t] == sum(
                m.L(m.year(t), r) for r in m.regions) * calc_utility(
                    sum(m.consumption[t, r] for r in m.regions),
                    sum(m.L(m.year(t), r) for r in m.regions),
                    m.elasmu,
                ),
            "yearly_welfare",
        ),
    ])

    return constraints
示例#3
0
def get_constraints(
        m: AbstractModel) -> Tuple[Objective, Sequence[GeneralConstraint]]:
    """Equations and constraints for the objective of the optimisation
    (global costs specification)

    Necessary variables:


    Returns:
        - Objective
        - list of constraints (any of:
           - GlobalConstraint
           - GlobalInitConstraint
           - RegionalConstraint
           - RegionalInitConstraint
        )
    """
    constraints = []

    m.NPV = Var(m.t)
    m.PRTP = Param()
    constraints.extend([
        GlobalConstraint(
            lambda m, t: m.NPV[t] == m.NPV[t - 1] + m.dt * exp(-m.PRTP * (
                m.year(t) - m.beginyear)) *
            (sum(m.abatement_costs[t, r] for r in m.regions) + sum(
                m.damage_costs[t, r] * m.GDP_gross[t, r] for r in m.regions))
            if t > 0 else Constraint.Skip,
            name="NPV",
        ),
        GlobalInitConstraint(lambda m: m.NPV[0] == 0),
    ])

    objective = Objective(rule=lambda m: m.NPV[m.tf], sense=minimize)

    return objective, constraints
示例#4
0
def create_abstract_model(damage_module: str, welfare_module: str,
                          objective_module: str) -> AbstractModel:

    m = AbstractModel()

    ## Constraints
    # Each constraint will be put in this list,
    # then added to the model at the end of this file.
    constraints = []

    ## Time and region
    m.beginyear = Param()
    m.dt = Param()
    m.tf = Param()
    m.t = Set()
    m.year = None  # Initialised with concrete instance
    m.year2100 = Param()

    m.regions = Set(ordered=True)

    ######################
    # Create data functions
    # Will be initialised when creating a concrete instance of the model
    ######################

    m.baseline_emissions = lambda year, region: None
    m.population = lambda year, region: None
    m.TFP = lambda year, region: None
    m.GDP = lambda year, region: None
    m.carbon_intensity = lambda year, region: None

    def baseline_cumulative(year_start, year_end, region):
        years = np.linspace(year_start, year_end, 100)
        return np.trapz(m.baseline_emissions(years, region), x=years)

    m.baseline_cumulative = baseline_cumulative
    m.baseline_cumulative_global = lambda m, year_start, year_end: sum(
        baseline_cumulative(year_start, year_end, r) for r in m.regions)

    ######################
    # Components
    ######################

    # Emissions and temperature equations
    constraints.extend(emissions.get_constraints(m))

    # Sea level rise
    constraints.extend(sealevelrise.get_constraints(m))

    # Damage costs
    if damage_module == "RICE2010":
        constraints.extend(damages.ad_rice2010.get_constraints(m))
    elif damage_module == "WITCH":
        constraints.extend(damages.ad_witch.get_constraints(m))
    elif damage_module == "RICE2012":
        constraints.extend(damages.ad_rice2012.get_constraints(m))
    elif damage_module == "COACCH":
        constraints.extend(damages.coacch.get_constraints(m))
    elif damage_module == "nodamage":
        constraints.extend(damages.nodamage.get_constraints(m))
    else:
        raise NotImplementedError

    # Abatement costs
    constraints.extend(abatement.get_constraints(m))

    # Cobb-Douglas and economics
    constraints.extend(cobbdouglas.get_constraints(m))

    # Utility and welfare
    if welfare_module == "inequal_aversion_elasmu":
        constraints.extend(welfare.inequal_aversion_elasmu.get_constraints(m))
    elif welfare_module == "inequal_aversion_zero":
        constraints.extend(welfare.inequal_aversion_zero.get_constraints(m))
    else:
        raise NotImplementedError(
            f"Welfare module `{welfare_module}` not implemented")

    # Objective of optimisation
    if objective_module == "utility":
        objective_rule, objective_constraints = objective.utility.get_constraints(
            m)
    elif objective_module == "globalcosts":
        objective_rule, objective_constraints = objective.globalcosts.get_constraints(
            m)
    else:
        raise NotImplementedError

    constraints.extend(objective_constraints)

    ######################
    # Add constraints to abstract model
    ######################

    for constraint in constraints:
        add_constraint(m, constraint.to_pyomo_constraint(m), constraint.name)

    m.obj = objective_rule

    return m
示例#5
0
def get_constraints(m: AbstractModel) -> Sequence[GeneralConstraint]:
    """Emissions and temperature equations and constraints

    Necessary variables:
        m.relative_abatement
        m.cumulative_emissions
        m.T0
        m.temperature

    Returns:
        list of constraints (any of:
           - GlobalConstraint
           - GlobalInitConstraint
           - RegionalConstraint
           - RegionalInitConstraint
        )
    """
    constraints = []

    m.regional_emissions = Var(m.t, m.regions)
    m.baseline = Var(m.t, m.regions)
    m.baseline_carbon_intensity = Param()

    m.relative_abatement = Var(m.t, m.regions, initialize=0, bounds=(0, 2))
    m.cumulative_emissions = Var(m.t)
    m.global_emissions = Var(m.t)

    constraints.extend([
        # Baseline emissions based on emissions or carbon intensity
        RegionalConstraint(
            lambda m, t, r: (m.baseline[t, r] == m.carbon_intensity(
                m.year(t), r) * m.GDP_net[t, r])
            if value(m.baseline_carbon_intensity) else
            (m.baseline[t, r] == m.baseline_emissions(m.year(t), r)),
            name="baseline_emissions",
        ),
        # Regional emissions from baseline and relative abatement
        RegionalConstraint(
            lambda m, t, r: m.regional_emissions[t, r] ==
            (1 - m.relative_abatement[t, r]) * m.baseline_emissions(
                m.year(t), r),
            "regional_abatement",
        ),
        RegionalInitConstraint(lambda m, r: m.regional_emissions[0, r] == m.
                               baseline_emissions(m.year(0), r)),
        # Global emissions (sum from regional emissions)
        GlobalConstraint(
            lambda m, t: m.global_emissions[t] == sum(
                m.regional_emissions[t, r] for r in m.regions),
            "global_emissions",
        ),
        GlobalInitConstraint(
            lambda m: m.global_emissions[0] == sum(
                m.baseline_emissions(m.year(0), r) for r in m.regions),
            "global_emissions_init",
        ),
        # Cumulative global emissions
        GlobalConstraint(
            lambda m, t: m.cumulative_emissions[t] == m.cumulative_emissions[
                t - 1] + m.dt * m.global_emissions[t]
            if t > 0 else Constraint.Skip,
            "cumulative_emissions",
        ),
        GlobalInitConstraint(lambda m: m.cumulative_emissions[0] == 0),
    ])

    m.T0 = Param()
    m.temperature = Var(m.t, initialize=lambda m, t: m.T0)
    m.TCRE = Param()
    m.temperature_target = Param()
    constraints.extend([
        GlobalConstraint(
            lambda m, t: m.temperature[t] == m.T0 + m.TCRE * m.
            cumulative_emissions[t],
            "temperature",
        ),
        GlobalInitConstraint(lambda m: m.temperature[0] == m.T0),
        GlobalConstraint(
            lambda m, t: m.temperature[t] <= m.temperature_target
            if (m.year(t) >= 2100 and value(m.temperature_target) is not False)
            else Constraint.Skip,
            name="temperature_target",
        ),
    ])

    m.perc_reversible_damages = Param()

    # m.overshoot = Var(m.t, initialize=0)
    # m.overshootdot = DerivativeVar(m.overshoot, wrt=m.t)
    # m.netnegative_emissions = Var(m.t)
    # global_constraints.extend(
    #     [
    #         lambda m, t: m.netnegative_emissions[t]
    #         == m.global_emissions[t] * (1 - tanh(m.global_emissions[t] * 10)) / 2
    #         if value(m.perc_reversible_damages) < 1
    #         else Constraint.Skip,
    #         lambda m, t: m.overshootdot[t]
    #         == (m.netnegative_emissions[t] if t <= value(m.year2100) and t > 0 else 0)
    #         if value(m.perc_reversible_damages) < 1
    #         else Constraint.Skip,
    #     ]
    # )

    # global_constraints_init.extend([lambda m: m.overshoot[0] == 0])

    # Emission constraints

    m.budget = Param()
    m.inertia_global = Param()
    m.inertia_regional = Param()
    m.global_min_level = Param()
    m.regional_min_level = Param()
    m.no_pos_emissions_after_budget_year = Param()
    constraints.extend([
        # Carbon budget constraints:
        GlobalConstraint(
            lambda m, t: m.cumulative_emissions[t] -
            (m.budget + (m.overshoot[t] * (1 - m.perc_reversible_damages)
                         if value(m.perc_reversible_damages) < 1 else 0)) <= 0
            if (m.year(t) >= 2100 and value(m.budget) is not False
                ) else Constraint.Skip,
            name="carbon_budget",
        ),
        GlobalConstraint(
            lambda m, t: m.global_emissions[t] <= 0 if
            (m.year(t) >= 2100 and value(m.no_pos_emissions_after_budget_year)
             is True and value(m.budget) is not False) else Constraint.Skip,
            name="net_zero_after_2100",
        ),
        GlobalConstraint(lambda m, t: m.cumulative_emissions[t] >= 0),
        # Global and regional inertia constraints:
        GlobalConstraint(
            lambda m, t: m.global_emissions[t] - m.global_emissions[t - 1] >= m
            .dt * m.inertia_global * sum(
                m.baseline_emissions(m.year(0), r) for r in m.regions)
            if value(m.inertia_global
                     ) is not False and t > 0 else Constraint.Skip,
            name="global_inertia",
        ),
        RegionalConstraint(
            lambda m, t, r: m.regional_emissions[t, r] - m.regional_emissions[
                t - 1, r] >= m.dt * m.inertia_regional * m.baseline_emissions(
                    m.year(0), r) if value(m.inertia_regional) is not False and
            t > 0 else Constraint.Skip,
            name="regional_inertia",
        ),
        GlobalConstraint(
            lambda m, t: m.global_emissions[t] >= m.global_min_level
            if value(m.global_min_level) is not False else Constraint.Skip,
            "global_min_level",
        ),
        RegionalConstraint(
            lambda m, t, r: m.regional_emissions[t, r] >= m.regional_min_level
            if value(m.regional_min_level) is not False else Constraint.Skip,
            "regional_min_level",
        ),
    ])

    m.emission_relative_cumulative = Var(m.t, initialize=1)
    constraints.extend([
        GlobalConstraint(
            lambda m, t:
            (m.emission_relative_cumulative[t] == m.cumulative_emissions[t] / m
             .baseline_cumulative_global(m, m.year(0), m.year(t)))
            if t > 0 else Constraint.Skip,
            name="relative_cumulative_emissions",
        ),
        GlobalInitConstraint(lambda m: m.emission_relative_cumulative[0] == 1),
    ])

    return constraints
示例#6
0
def get_constraints(m: AbstractModel) -> Sequence[GeneralConstraint]:
    """Damage and adaptation costs equations and constraints
    (RICE specification)

    Necessary variables:
        m.damage_costs (sum of residual damages and adaptation costs, as % of GDP)

    Returns:
        list of constraints (any of:
           - GlobalConstraint
           - GlobalInitConstraint
           - RegionalConstraint
           - RegionalInitConstraint
        )
    """
    constraints = []

    m.damage_costs = Var(m.t, m.regions)
    m.smoothed_factor = Var(m.t, bounds=(0, 1))
    m.gross_damages = Var(m.t, m.regions)
    m.resid_damages = Var(m.t, m.regions)
    m.adapt_costs = Var(m.t, m.regions)
    m.adapt_level = Var(m.t, m.regions, bounds=(0, 1))

    m.damage_a1 = Param(m.regions)
    m.damage_a2 = Param(m.regions)
    m.damage_a3 = Param(m.regions)
    m.damage_scale_factor = Param()
    m.adapt_g1 = Param(m.regions)
    m.adapt_g2 = Param(m.regions)
    m.adapt_curr_level = Param()
    m.fixed_adaptation = Param()

    constraints.extend(
        [
            # Smoothing factor for partially reversible damages
            GlobalConstraint(
                lambda m, t: m.smoothed_factor[t]
                == smoothed_factor(t, m.temperature, m.dt, m.perc_reversible_damages),
                name="smoothed_factor",
            ),
            # Gross damages
            RegionalConstraint(
                lambda m, t, r: m.gross_damages[t, r]
                == calc_gross_damages(m, t, r, m.perc_reversible_damages),
                name="gross_damages",
            ),
            RegionalConstraint(lambda m, t, r: m.gross_damages[t, r] >= 0),
            RegionalInitConstraint(lambda m, r: m.gross_damages[0, r] == 0),
        ]
    )

    # Adaptation
    constraints.extend(
        [
            RegionalConstraint(
                lambda m, t, r: m.adapt_level[t, r]
                == (
                    m.adapt_curr_level
                    if value(m.fixed_adaptation)
                    else optimal_adapt_level(m.gross_damages[t, r], m, r)
                ),
                name="adapt_level",
            ),
            RegionalConstraint(
                lambda m, t, r: m.resid_damages[t, r]
                == m.gross_damages[t, r] * (1 - m.adapt_level[t, r]),
                "resid_damages",
            ),
            RegionalConstraint(
                lambda m, t, r: m.adapt_costs[t, r]
                == adaptation_costs(m.adapt_level[t, r], m, r),
                "adapt_costs",
            ),
            RegionalConstraint(
                lambda m, t, r: m.damage_costs[t, r]
                == m.resid_damages[t, r] + m.adapt_costs[t, r],
                "damage_costs",
            ),
        ]
    )

    return constraints
示例#7
0
def get_constraints(m: AbstractModel) -> Sequence[GeneralConstraint]:
    """Damage and adaptation costs equations and constraints
    (RICE specification)

    Necessary variables:
        m.damage_costs (sum of residual damages and adaptation costs multiplied by gross GDP)

    Returns:
        list of constraints (any of:
           - GlobalConstraint
           - GlobalInitConstraint
           - RegionalConstraint
           - RegionalInitConstraint
        )
    """
    constraints = []

    m.damage_costs = Var(m.t, m.regions)
    m.gross_damages = Var(m.t, m.regions)
    m.resid_damages = Var(m.t, m.regions)

    m.damage_a1 = Param(m.regions)
    m.damage_a2 = Param(m.regions)
    m.damage_a3 = Param(m.regions)
    m.damage_scale_factor = Param()

    m.adapt_level = Var(m.t, m.regions, within=NonNegativeReals)
    m.adapt_costs = Var(m.t, m.regions)
    m.adapt_FAD = Var(m.t, m.regions, bounds=(0, 0.15), initialize=0)
    m.adapt_IAD = Var(m.t, m.regions, bounds=(0, 0.15), initialize=0)
    m.adap1 = Param(m.regions)
    m.adap2 = Param(m.regions)
    m.adap3 = Param(m.regions)
    m.adapt_rho = Param()
    m.fixed_adaptation = Param()

    m.adapt_SAD = Var(m.t, m.regions, initialize=0.01, within=NonNegativeReals)

    # SLR damages
    m.SLRdam1 = Param(m.regions)
    m.SLRdam2 = Param(m.regions)
    m.SLR_damages = Var(m.t, m.regions)

    constraints.extend(
        [
            RegionalConstraint(
                lambda m, t, r: m.SLR_damages[t, r]
                == slr_damages(
                    m.total_SLR[t],
                    m.GDP_gross[t, r],
                    m.GDP_gross[0, r],
                    m.SLRdam1[r],
                    m.SLRdam2[r],
                ),
                "SLR_damages",
            ),
        ]
    )

    # Gross damages and adaptation levels
    constraints.extend(
        [
            RegionalConstraint(
                lambda m, t, r: m.gross_damages[t, r]
                == m.damage_scale_factor * damage_fct(m.temperature[t], m.T0, m, r),
                "gross_damages",
            ),
            RegionalConstraint(
                lambda m, t, r: m.resid_damages[t, r]
                == m.gross_damages[t, r] / (1 + m.adapt_level[t, r])
                + m.SLR_damages[t, r],
                "resid_damages",
            ),
            RegionalConstraint(
                lambda m, t, r: m.adapt_SAD[t, r]
                == (1 - m.dk) ** m.dt * m.adapt_SAD[t - 1, r] + m.adapt_IAD[t, r]
                if t > 0
                else Constraint.Skip,
                "adapt_SAD",
            ),
            RegionalInitConstraint(lambda m, r: m.adapt_SAD[0, r] == 0),
            RegionalInitConstraint(lambda m, r: m.adapt_IAD[0, r] == 0),
            RegionalInitConstraint(lambda m, r: m.adapt_FAD[0, r] == 0),
            RegionalConstraint(
                lambda m, t, r: (
                    m.adapt_level[t, r]
                    == m.adap1[r]
                    * (
                        m.adap2[r]
                        * soft_min(m.adapt_FAD[t, r], scale=0.005) ** m.adapt_rho
                        + (1 - m.adap2[r])
                        * soft_min(m.adapt_SAD[t, r], scale=0.005) ** m.adapt_rho
                    )
                    ** (m.adap3[r] / m.adapt_rho)
                )
                if t > 0
                else (m.adapt_level[t, r] == 0),
                name="adapt_level",
            ),
            RegionalConstraint(
                lambda m, t, r: m.adapt_costs[t, r]
                == m.adapt_FAD[t, r] + m.adapt_IAD[t, r],
                "adapt_costs",
            ),
            RegionalConstraint(
                lambda m, t, r: m.damage_costs[t, r]
                == m.resid_damages[t, r] + m.adapt_costs[t, r],
                "damage_costs",
            ),
        ]
    )

    return constraints
示例#8
0
def get_constraints(m: AbstractModel) -> Sequence[GeneralConstraint]:
    """Abatement cost equations and constraints

    Necessary variables:
        m.abatement_costs

    Returns:
        list of constraints (any of:
           - GlobalConstraint
           - GlobalInitConstraint
           - RegionalConstraint
           - RegionalInitConstraint
        )
    """
    constraints = []

    ### Technological learning

    # Learning by doing
    m.LBD_rate = Param()
    m.log_LBD_rate = Param(initialize=log(m.LBD_rate) / log(2))
    m.LBD_scaling = Param()
    m.LBD_factor = Var(m.t)  # , bounds=(0,1), initialize=1)
    constraints.append(
        GlobalConstraint(
            lambda m, t: m.LBD_factor[t]
            == soft_min(
                (
                    m.baseline_cumulative_global(m, m.year(0), m.year(t))
                    - m.cumulative_emissions[t]
                )
                / m.LBD_scaling
                + 1.0
            )
            ** m.log_LBD_rate,
            name="LBD",
        )
    )

    # Learning over time and total learning factor
    m.LOT_rate = Param()
    m.LOT_factor = Var(m.t)
    m.learning_factor = Var(m.t)
    constraints.extend(
        [
            GlobalConstraint(
                lambda m, t: m.LOT_factor[t] == 1 / (1 + m.LOT_rate) ** t, "LOT"
            ),
            GlobalConstraint(
                lambda m, t: m.learning_factor[t]
                == (m.LBD_factor[t] * m.LOT_factor[t]),
                "learning",
            ),
        ]
    )

    # Abatement costs and MAC
    m.abatement_costs = Var(m.t, m.regions, within=NonNegativeReals, initialize=0)
    m.area_under_MAC = Var(m.t, m.regions, within=NonNegativeReals, initialize=0)
    m.rel_abatement_costs = Var(m.t, m.regions, bounds=(0, 0.3))
    m.MAC_gamma = Param()
    m.MAC_beta = Param()
    m.MAC_scaling_factor = Param(m.regions)  # Regional scaling of the MAC
    m.carbonprice = Var(m.t, m.regions, bounds=lambda m: (0, 1.5 * m.MAC_gamma))
    constraints.extend(
        [
            RegionalConstraint(
                lambda m, t, r: (
                    m.area_under_MAC[t, r]
                    if value(m.allow_trade)
                    else m.abatement_costs[t, r]
                )
                == AC(
                    m.relative_abatement[t, r],
                    m.learning_factor[t],
                    m.MAC_gamma,
                    m.MAC_beta,
                    m.MAC_scaling_factor[r],
                )
                * m.baseline[t, r],
                "abatement_costs",
            ),
            RegionalConstraint(
                lambda m, t, r: m.rel_abatement_costs[t, r]
                == m.abatement_costs[t, r] / m.GDP_gross[t, r],
                "rel_abatement_costs",
            ),
            RegionalConstraint(
                lambda m, t, r: m.carbonprice[t, r]
                == MAC(
                    m.relative_abatement[t, r],
                    m.learning_factor[t],
                    m.MAC_gamma,
                    m.MAC_beta,
                    m.MAC_scaling_factor[r],
                ),
                "carbonprice",
            ),
            RegionalInitConstraint(
                lambda m, r: m.carbonprice[0, r] == 0, "init_carbon_price"
            ),
        ]
    )

    # How are mitigation costs distributed over regions?
    m.allow_trade = Param()
    constraints.extend(
        [
            GlobalConstraint(
                lambda m, t: sum(m.abatement_costs[t, r] for r in m.regions)
                == sum(m.area_under_MAC[t, r] for r in m.regions)
                if m.allow_trade
                else Constraint.Skip
            ),
            RegionalConstraint(
                lambda m, t, r: m.abatement_costs[t, r] <= 1.5 * m.area_under_MAC[t, r]
                if m.allow_trade
                else Constraint.Skip
            ),
            # RegionalConstraint(
            #     lambda m, t, r: m.abatement_costs[t, r] >= 0.5 * m.area_under_MAC[t, r]
            #     if m.allow_trade
            #     else Constraint.Skip
            # ),
        ]
    )

    # Keep track of relative global costs
    m.global_rel_abatement_costs = Var(m.t)
    constraints.extend(
        [
            GlobalConstraint(
                lambda m, t: m.global_rel_abatement_costs[t]
                == sum(m.abatement_costs[t, r] for r in m.regions)
                / sum(m.GDP_gross[t, r] for r in m.regions),
                "global_rel_abatement_costs",
            )
        ]
    )

    return constraints
示例#9
0
def get_constraints(m: AbstractModel) -> Sequence[GeneralConstraint]:
    """Emissions and temperature equations and constraints

    Necessary variables:
        m.total_SLR

    Returns:
        list of constraints (any of:
           - GlobalConstraint
           - GlobalInitConstraint
           - RegionalConstraint
           - RegionalInitConstraint
        )
    """

    # Parameters and variables necessary for sea level rise
    m.slr_thermal = Var(m.t)
    m.slr_thermal_equil = Param()
    m.slr_thermal_init = Param()
    m.slr_thermal_adjust_rate = Param()

    m.slr_cumgsic = Var(m.t)
    m.slr_gsic_melt_rate = Param()
    m.slr_gsic_total_ice = Param()
    m.slr_gsic_equil_temp = Param()

    m.slr_cumgis = Var(m.t)
    m.slr_gis_melt_rate_above_thresh = Param()
    m.slr_gis_init_melt_rate = Param()
    m.slr_gis_init_ice_vol = Param()

    m.total_SLR = Var(m.t)

    # Constraints relating to SLR
    constraints = [
        # Thermal expansion
        GlobalConstraint(
            lambda m, t: m.slr_thermal[t] == slr_thermal_expansion(
                m.slr_thermal[t - 1], m.temperature[t - 1], m)
            if t > 0 else Constraint.Skip,
            name="SLR_thermal",
        ),
        GlobalInitConstraint(lambda m: m.slr_thermal[
            0] == m.slr_thermal_init + m.slr_thermal_adjust_rate * (
                m.T0 * m.slr_thermal_equil - m.slr_thermal_init)),
        # GSIC
        GlobalConstraint(
            lambda m, t: m.slr_cumgsic[t] == slr_gsic(m.slr_cumgsic[
                t - 1], m.temperature[t - 1], m) if t > 0 else Constraint.Skip,
            name="SLR_GSIC",
        ),
        GlobalInitConstraint(lambda m: m.slr_cumgsic[0] == 0.015),
        # GIS
        GlobalConstraint(
            lambda m, t: m.slr_cumgis[t] == slr_gis(m.slr_cumgis[
                t - 1], m.temperature[t - 1], m) if t > 0 else Constraint.Skip,
            name="SLR_GIS",
        ),
        GlobalInitConstraint(lambda m: m.slr_cumgis[0] == 0.006),
        # Total SLR is sum of each contributing factors
        GlobalConstraint(
            lambda m, t: m.total_SLR[t] == m.slr_thermal[t] + m.slr_cumgsic[t]
            + m.slr_cumgis[t],
            name="total_SLR",
        ),
    ]

    return constraints
示例#10
0
def get_constraints(m: AbstractModel) -> Sequence[GeneralConstraint]:
    """Economics and Cobb-Douglas equations and constraints

    Necessary variables:
        m.L (equal to m.population)
        m.dk

    Returns:
        list of constraints (any of:
           - GlobalConstraint
           - GlobalInitConstraint
           - RegionalConstraint
           - RegionalInitConstraint
        )
    """
    constraints = []

    m.init_capitalstock_factor = Param(m.regions)
    m.capital_stock = Var(
        m.t,
        m.regions,
        initialize=lambda m, t, r: m.init_capitalstock_factor[r] * m.GDP(
            m.year(t), r),
    )

    # Parameters
    m.alpha = Param()
    m.dk = Param()
    m.sr = Param()

    m.GDP_gross = Var(m.t,
                      m.regions,
                      initialize=lambda m, t, r: m.GDP(m.year(0), r))
    m.GDP_net = Var(m.t, m.regions)
    m.investments = Var(m.t, m.regions)
    m.consumption = Var(m.t, m.regions)

    m.ignore_damages = Param()

    # Cobb-Douglas, GDP, investments, capital and consumption
    constraints.extend([
        RegionalConstraint(
            lambda m, t, r: m.GDP_gross[t, r] == economics.calc_GDP(
                m.TFP(m.year(t), r),
                m.L(m.year(t), r),
                soft_min(m.capital_stock[t, r], scale=10),
                m.alpha,
            ),
            "GDP_gross",
        ),
        RegionalConstraint(
            lambda m, t, r: m.GDP_net[t, r] == m.GDP_gross[t, r] *
            (1 - (m.damage_costs[t, r] if not value(m.ignore_damages) else 0)
             ) - m.abatement_costs[t, r],
            "GDP_net",
        ),
        RegionalConstraint(
            lambda m, t, r: m.investments[t, r] == m.sr * m.GDP_net[t, r],
            "investments",
        ),
        RegionalConstraint(
            lambda m, t, r: m.consumption[t, r] ==
            (1 - m.sr) * m.GDP_net[t, r],
            "consumption",
        ),
        RegionalConstraint(
            lambda m, t, r: (m.capital_stock[t, r] == m.capital_stock[
                t - 1, r] + m.dt * economics.calc_dKdt(m.capital_stock[
                    t, r], m.dk, m.investments[t, r], m.dt))
            if t > 0 else Constraint.Skip,
            "capital_stock",
        ),
        RegionalInitConstraint(lambda m, r: m.capital_stock[
            0, r] == m.init_capitalstock_factor[r] * m.GDP(m.year(0), r)),
    ])

    return constraints
示例#11
0
def get_constraints(m: AbstractModel) -> Sequence[GeneralConstraint]:
    """Damage and adaptation costs equations and constraints
    (WITCH specification)

    Necessary variables:
        m.damage_costs (sum of residual damages and adaptation costs, % of GDP)

    Returns:
        list of constraints (any of:
           - GlobalConstraint
           - GlobalInitConstraint
           - RegionalConstraint
           - RegionalInitConstraint
        )
    """
    constraints = []

    m.damage_costs = Var(m.t, m.regions)

    # Gross and residual damages
    m.gross_damages = Var(m.t, m.regions)
    m.resid_damages = Var(m.t, m.regions)
    m.adapt_Q_ada = Var(m.t, m.regions, initialize=0.1)

    m.damage_omega1_pos = Param(m.regions)
    m.damage_omega1_neg = Param(m.regions)
    m.damage_omega2_pos = Param(m.regions)
    m.damage_omega2_neg = Param(m.regions)
    m.damage_omega3_pos = Param(m.regions)
    m.damage_omega3_neg = Param(m.regions)
    m.damage_omega4_pos = Param(m.regions)
    m.damage_omega4_neg = Param(m.regions)

    m.adapt_eps = Param(m.regions)

    m.damage_scale_factor = Param()

    constraints.extend([
        RegionalConstraint(
            lambda m, t, r: m.gross_damages[t, r] == m.damage_scale_factor *
            damage_fct(m.temperature[t], 0, m.T0, m, r),
            "gross_damages",
        ),
        RegionalConstraint(
            lambda m, t, r: m.resid_damages[t, r] == m.damage_scale_factor *
            damage_fct(
                m.temperature[t],
                pow(m.adapt_Q_ada[t, r], m.adapt_eps[r], True),
                m.T0,
                m,
                r,
            ),
            "resid_damages",
        ),
    ])

    # Adaptation costs (protection costs, PC)
    m.adapt_costs = Var(m.t, m.regions)
    m.adapt_costs_reactive = Var(m.t, m.regions, bounds=(0, 1))  # I_RADA
    # m.adapt_costs_proactive   = Var(m.t, m.regions, bounds=(0,1)) # I_PRADA
    # m.adapt_costs_speccap     = Var(m.t, m.regions) # I_SCAP, specific adaptive capacity
    m.fixed_adaptation = Param()

    constraints.extend([
        RegionalConstraint(
            lambda m, t, r: m.adapt_costs[t, r] == (
                m.adapt_costs_reactive[t, r]  # +
                # m.adapt_costs_proactive[t,r] +
                # m.adapt_costs_speccap[t,r]
            ),
            name="adapt_costs",
        ),
        RegionalInitConstraint(lambda m, r: m.adapt_costs_reactive[0, r] == 0),
    ])

    ## Nested Constant Elasticity of Substitution (CES)

    m.adapt_omega_eff_ada = Param(m.regions)
    m.adapt_omega_act = Param(m.regions)
    m.adapt_omega_eff_act = Param(m.regions)
    m.adapt_omega_rada = Param(m.regions)
    m.adapt_rho_ada = Param(m.regions)
    m.adapt_rho_act = Param(m.regions)

    # Nest 1: adaptation activities vs adaptive capacity
    # m.adapt_Q_act = Var(m.t, m.regions, initialize=0.1)
    m.adapt_Q_cap = Var(m.t, m.regions, initialize=0.1)

    constraints.extend([
        RegionalConstraint(
            lambda m, t, r: m.adapt_Q_ada[t, r] == m.adapt_omega_eff_ada[r] * m
            .adapt_omega_eff_act[r] * m.adapt_costs_reactive[t, r],
            "adapt_Q_ada",
        ),
        # Extra constraint necessary to avoid negative GDP
        RegionalConstraint(lambda m, t, r: m.GDP_net[t, r] >= 0),
    ])

    # regional_constraints.append(lambda m,t,r: m.adapt_Q_ada[t,r] == CES(
    #     m.adapt_costs_reactive[t,r], m.adapt_Q_cap[t,r],
    #     # m.adapt_Q_act[t,r], m.adapt_Q_cap[t,r],
    #     m.adapt_omega_eff_ada[r], m.adapt_omega_act[r], m.adapt_rho_ada[r]
    # ))

    # Nest 2: reactive adaptation vs proactive adaptation
    # m.adapt_K_proactive = Var(m.t, m.regions, initialize=0.1)
    # regional_constraints.append(lambda m,t,r: m.adapt_Q_act[t,r] == CES(
    #     m.adapt_costs_reactive[t,r], m.adapt_K_proactive[t,r],
    #     m.adapt_omega_eff_act[r], m.adapt_omega_rada[r], m.adapt_rho_act[r]
    # ))

    # Nest 3: we don't model R&D and human capital, so we use the description
    # of Bosello et al (2010) [original AD-WITCH] that Q_cap is simple stock variable

    # Stocks of capital
    # m.adapt_Q_capdot        = DerivativeVar(m.adapt_Q_cap, wrt=m.t)
    # m.adapt_K_proactivedot  = DerivativeVar(m.adapt_K_proactive, wrt=m.t)

    # regional_constraints.extend([
    #     lambda m,t,r: m.adapt_Q_capdot[t,r]         == np.log(1-m.dk) * m.adapt_Q_cap[t,r] + m.adapt_costs_speccap[t,r],
    #     # lambda m,t,r: m.adapt_K_proactivedot[t,r]   == np.log(1-m.dk) * m.adapt_K_proactive[t,r] + m.adapt_costs_proactive[t,r],
    # ])

    constraints.extend([
        RegionalConstraint(
            lambda m, t, r: m.damage_costs[t, r] == m.resid_damages[t, r] + m.
            adapt_costs[t, r],
            "damage_costs",
        )
    ])

    return constraints
示例#12
0
def get_constraints(m: AbstractModel) -> Sequence[GeneralConstraint]:
    """Damage and adaptation costs equations and constraints
    (COACCH specification)

    Necessary variables:
        m.damage_costs (sum of residual damages and adaptation costs multiplied by gross GDP)

    Returns:
        list of constraints (any of:
           - GlobalConstraint
           - GlobalInitConstraint
           - RegionalConstraint
           - RegionalInitConstraint
        )
    """
    constraints = []

    m.damage_costs = Var(m.t, m.regions)
    m.damage_scale_factor = Param()

    # Damages not related to SLR (dependent on temperature)
    m.resid_damages = Var(m.t, m.regions)

    m.damage_noslr_form = Param(m.regions,
                                within=Any)  # String for functional form
    m.damage_noslr_b1 = Param(m.regions)
    m.damage_noslr_b2 = Param(m.regions)
    m.damage_noslr_b3 = Param(m.regions)
    # (b2 and b3 are only used for some functional forms)

    m.damage_noslr_a = Param(m.regions)

    # Quadratic damage function for non-SLR damages. Factor `a` represents
    # the damage quantile
    constraints.append(
        RegionalConstraint(
            lambda m, t, r: m.resid_damages[t, r] == damage_fct(
                m.temperature[t], m.T0, m, r, is_slr=False),
            "resid_damages",
        ))

    # SLR damages
    m.SLR_damages = Var(m.t, m.regions)

    m.damage_slr_form = Param(m.regions,
                              within=Any)  # String for functional form
    m.damage_slr_b1 = Param(m.regions)
    m.damage_slr_b2 = Param(m.regions)
    m.damage_slr_b3 = Param(m.regions)
    # (b2 and b3 are only used for some functional forms)

    m.damage_slr_a = Param(m.regions)

    # Linear damage function for SLR damages, including adaptation costs
    constraints.append(
        RegionalConstraint(
            lambda m, t, r: m.SLR_damages[t, r] == damage_fct(
                m.total_SLR[t], None, m, r, is_slr=True),
            "SLR_damages",
        ))

    # Total damages are sum of non-SLR and SLR damages
    constraints.append(
        RegionalConstraint(
            lambda m, t, r: m.damage_costs[t, r] == m.resid_damages[t, r] + m.
            SLR_damages[t, r],
            "damage_costs",
        ), )

    return constraints