def optimal_adapt_level(gross_damages, m, r): if value(m.adapt_g1[r]) * value(m.adapt_g2[r]) == 0: return 0 eps = 0.0005 return (soft_min(gross_damages, 0.01) / (m.adapt_g1[r] * m.adapt_g2[r]) + eps) ** ( 1 / (m.adapt_g2[r] - 1) )
def damage_fct(temperature, init_temp, m, r): power_fct = ( lambda temp: m.damage_a1[r] * temp + m.damage_a2[r] * temp ** m.damage_a3[r] ) damage = power_fct(soft_min(temperature)) if init_temp is not None: damage -= power_fct(init_temp) return damage
def calc_utility(consumption, population, elasmu): return (soft_min(consumption / population)** (1 - elasmu) - 1) / (1 - elasmu) - 1
def adaptation_costs(adapt_level, m, r): return m.adapt_g1[r] * soft_min(adapt_level) ** m.adapt_g2[r]
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
def slr_damages(total_slr, gdp_t, gdp_0, dam1, dam2): return ( 4 * (dam1 * total_slr + dam2 * total_slr ** 2) * soft_min(gdp_t / gdp_0) ** 0.25 )
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
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