def capacity_factor(results, model_data, systemwide=False): """ Returns a DataArray with capacity factor for the given results. The results are either indexed by loc_tech_carriers_prod and timesteps, or by techs and carriers if systemwide results are being calculated. The weight of timesteps is considered when computing systemwide capacity factors, such that higher-weighted timesteps have a stronger influence on the resulting system-wide time-averaged capacity factor. """ # In operate mode, energy_cap is an input parameter if "energy_cap" not in results.keys(): energy_cap = model_data.energy_cap else: energy_cap = results.energy_cap _prod = split_loc_techs(results["carrier_prod"]) _cap = split_loc_techs(energy_cap) if systemwide: # Aggregated/clustered days are represented `timestep_weights` times prod_sum = (_prod * model_data.timestep_weights).sum( ["timesteps", "locs"]) cap_sum = _cap.sum(dim="locs") time_sum = (model_data.timestep_resolution * model_data.timestep_weights).sum() capacity_factors = prod_sum / (cap_sum * time_sum) else: extra_dims = { i: model_data[i].to_index() for i in _prod.dims if i not in _cap.dims } capacity_factors = ((_prod / _cap.expand_dims(extra_dims)).fillna(0).stack({ "loc_tech_carriers_prod": ["locs", "techs", "carriers"] })) new_idx = concat_iterable( capacity_factors.loc_tech_carriers_prod.values, ["::", "::"]) capacity_factors = capacity_factors.assign_coords({ "loc_tech_carriers_prod": new_idx }).reindex({"loc_tech_carriers_prod": results.loc_tech_carriers_prod}) return capacity_factors
def generate_constraint_sets(model_run): """ Generate loc-tech sets for a given pre-processed ``model_run`` Parameters ---------- model_run : AttrDict """ sets = model_run.sets ## From here on, everything is a `key=value` pair within a dictionary constraint_sets = dict() # energy_balance.py constraint_sets[ "loc_carriers_system_balance_constraint"] = sets.loc_carriers constraint_sets[ "loc_techs_balance_supply_constraint"] = sets.loc_techs_finite_resource_supply constraint_sets[ "loc_techs_balance_demand_constraint"] = sets.loc_techs_finite_resource_demand constraint_sets[ "loc_techs_resource_availability_supply_plus_constraint"] = sets.loc_techs_finite_resource_supply_plus constraint_sets[ "loc_techs_balance_transmission_constraint"] = sets.loc_techs_transmission constraint_sets[ "loc_techs_balance_supply_plus_constraint"] = sets.loc_techs_supply_plus constraint_sets[ "loc_techs_balance_storage_constraint"] = sets.loc_techs_storage if model_run.run.cyclic_storage is True: constraint_sets["loc_techs_storage_initial_constraint"] = [ i for i in sets.loc_techs_store if constraint_exists( model_run, i, "constraints.storage_initial") is not None ] constraint_sets["loc_techs_storage_discharge_depth"] = [ i for i in sets.loc_techs_store if constraint_exists( model_run, i, "constraints.storage_discharge_depth") ] constraint_sets["carriers_reserve_margin_constraint"] = [ i for i in sets.carriers if i in model_run.model.get_key("reserve_margin", {}).keys() ] # clustering-specific balance constraints if model_run.model.get_key( "time.function", None) == "apply_clustering" and model_run.model.get_key( "time.function_options.storage_inter_cluster", True): set_name = "loc_techs_balance_storage_inter_cluster_constraint" constraint_sets[set_name] = sets.loc_techs_store # costs.py constraint_sets["loc_techs_cost_constraint"] = sets.loc_techs_cost constraint_sets[ "loc_techs_cost_investment_constraint"] = sets.loc_techs_investment_cost constraint_sets["loc_techs_cost_var_constraint"] = [ i for i in sets.loc_techs_om_cost if i not in sets.loc_techs_conversion_plus + sets.loc_techs_conversion ] # export.py constraint_sets["loc_carriers_update_system_balance_constraint"] = [ i for i in sets.loc_carriers if sets.loc_techs_export and any([ "{0}::{2}".format(*j.split("::")) == i for j in sets.loc_tech_carriers_export ]) ] constraint_sets[ "loc_tech_carriers_export_balance_constraint"] = sets.loc_tech_carriers_export constraint_sets["loc_techs_update_costs_var_constraint"] = [ i for i in sets.loc_techs_om_cost if i in sets.loc_techs_export ] constraint_sets["loc_tech_carriers_export_max_constraint"] = [ i for i in sets.loc_tech_carriers_export if constraint_exists( model_run, i.rsplit("::", 1)[0], "constraints.export_cap") is not None ] # capacity.py constraint_sets["loc_techs_storage_capacity_constraint"] = [ i for i in sets.loc_techs_store if i not in sets.loc_techs_milp ] constraint_sets["loc_techs_energy_capacity_storage_constraint_old"] = [ i for i in sets.loc_techs_store if constraint_exists(model_run, i, "constraints.charge_rate") ] constraint_sets["loc_techs_energy_capacity_storage_equals_constraint"] = [ i for i in sets.loc_techs_store if constraint_exists( model_run, i, "constraints.energy_cap_per_storage_cap_equals") ] constraint_sets["loc_techs_energy_capacity_storage_min_constraint"] = [ i for i in sets.loc_techs_store if constraint_exists( model_run, i, "constraints.energy_cap_per_storage_cap_min") and not constraint_exists( model_run, i, "constraints.energy_cap_per_storage_cap_equals") ] constraint_sets["loc_techs_energy_capacity_storage_max_constraint"] = [ i for i in sets.loc_techs_store if constraint_exists( model_run, i, "constraints.energy_cap_per_storage_cap_max") and not constraint_exists( model_run, i, "constraints.energy_cap_per_storage_cap_equals") ] constraint_sets["loc_techs_resource_capacity_constraint"] = [ i for i in sets.loc_techs_finite_resource_supply_plus if any([ constraint_exists(model_run, i, "constraints.resource_cap_equals"), constraint_exists(model_run, i, "constraints.resource_cap_max"), constraint_exists(model_run, i, "constraints.resource_cap_min"), ]) ] constraint_sets[ "loc_techs_resource_capacity_equals_energy_capacity_constraint"] = [ i for i in sets.loc_techs_finite_resource_supply_plus if constraint_exists(model_run, i, "constraints.resource_cap_equals_energy_cap") ] constraint_sets["loc_techs_resource_area_constraint"] = sets.loc_techs_area constraint_sets[ "loc_techs_resource_area_per_energy_capacity_constraint"] = [ i for i in sets.loc_techs_area if constraint_exists( model_run, i, "constraints.resource_area_per_energy_cap") is not None ] constraint_sets["locs_resource_area_capacity_per_loc_constraint"] = [ i for i in sets.locs if model_run.locations[i].get_key("available_area", None) is not None and sets.loc_techs_area ] constraint_sets["loc_techs_energy_capacity_constraint"] = [ i for i in sets.loc_techs if i not in sets.loc_techs_milp + sets.loc_techs_purchase ] constraint_sets["techs_energy_capacity_systemwide_constraint"] = [ i for i in sets.techs if model_run.get_key( "techs.{}.constraints.energy_cap_max_systemwide".format(i), None) or model_run.get_key( "techs.{}.constraints.energy_cap_equals_systemwide".format(i), None) ] # dispatch.py constraint_sets["loc_tech_carriers_carrier_production_max_constraint"] = [ i for i in sets.loc_tech_carriers_prod if i not in sets.loc_tech_carriers_conversion_plus and i.rsplit("::", 1)[0] not in sets.loc_techs_milp ] constraint_sets["loc_tech_carriers_carrier_production_min_constraint"] = [ i for i in sets.loc_tech_carriers_prod if i not in sets.loc_tech_carriers_conversion_plus and constraint_exists( model_run, i.rsplit("::", 1)[0], "constraints.energy_cap_min_use") and i.rsplit("::", 1)[0] not in sets.loc_techs_milp ] constraint_sets["loc_tech_carriers_carrier_consumption_max_constraint"] = [ i for i in sets.loc_tech_carriers_con if i.rsplit("::", 1)[0] in sets.loc_techs_demand + sets.loc_techs_storage + sets.loc_techs_transmission and i.rsplit("::", 1)[0] not in sets.loc_techs_milp ] constraint_sets[ "loc_techs_resource_max_constraint"] = sets.loc_techs_supply_plus constraint_sets["loc_tech_carriers_ramping_constraint"] = [ i for i in sets.loc_tech_carriers_prod if i.rsplit("::", 1)[0] in sets.loc_techs_ramping ] # clustering-specific dispatch constraints if model_run.model.get_key( "time.function", None) == "apply_clustering" and model_run.model.get_key( "time.function_options.storage_inter_cluster", True): constraint_sets[ "loc_techs_storage_intra_max_constraint"] = sets.loc_techs_store constraint_sets[ "loc_techs_storage_intra_min_constraint"] = sets.loc_techs_store constraint_sets[ "loc_techs_storage_inter_max_constraint"] = sets.loc_techs_store constraint_sets[ "loc_techs_storage_inter_min_constraint"] = sets.loc_techs_store else: constraint_sets[ "loc_techs_storage_max_constraint"] = sets.loc_techs_store # milp.py constraint_sets[ "loc_techs_unit_commitment_milp_constraint"] = sets.loc_techs_milp constraint_sets[ "loc_techs_unit_capacity_milp_constraint"] = sets.loc_techs_milp constraint_sets[ "loc_tech_carriers_carrier_production_max_milp_constraint"] = [ i for i in sets.loc_tech_carriers_prod if i not in sets.loc_tech_carriers_conversion_plus and i.rsplit("::", 1)[0] in sets.loc_techs_milp ] constraint_sets[ "loc_techs_carrier_production_max_conversion_plus_milp_constraint"] = [ i for i in sets.loc_techs_conversion_plus if i in sets.loc_techs_milp ] constraint_sets[ "loc_tech_carriers_carrier_production_min_milp_constraint"] = [ i for i in sets.loc_tech_carriers_prod if i not in sets.loc_tech_carriers_conversion_plus and constraint_exists(model_run, i.rsplit("::", 1)[0], "constraints.energy_cap_min_use") and i.rsplit("::", 1)[0] in sets.loc_techs_milp ] constraint_sets[ "loc_techs_carrier_production_min_conversion_plus_milp_constraint"] = [ i for i in sets.loc_techs_conversion_plus if constraint_exists(model_run, i, "constraints.energy_cap_min_use" ) and i in sets.loc_techs_milp ] constraint_sets[ "loc_tech_carriers_carrier_consumption_max_milp_constraint"] = [ i for i in sets.loc_tech_carriers_con if i.rsplit("::", 1)[0] in sets.loc_techs_demand + sets.loc_techs_storage + sets.loc_techs_transmission and i.rsplit("::", 1)[0] in sets.loc_techs_milp ] constraint_sets["loc_techs_energy_capacity_units_milp_constraint"] = [ i for i in sets.loc_techs_milp if constraint_exists( model_run, i, "constraints.energy_cap_per_unit") is not None ] constraint_sets["loc_techs_storage_capacity_units_milp_constraint"] = [ i for i in sets.loc_techs_milp if i in sets.loc_techs_store ] constraint_sets[ "loc_techs_energy_capacity_max_purchase_milp_constraint"] = [ i for i in sets.loc_techs_purchase if (constraint_exists( model_run, i, "constraints.energy_cap_equals") is not None or (constraint_exists(model_run, i, "constraints.energy_cap_max") is not None and constraint_exists( model_run, i, "constraints.energy_cap_max") != np.inf)) ] constraint_sets[ "loc_techs_energy_capacity_min_purchase_milp_constraint"] = [ i for i in sets.loc_techs_purchase if (not constraint_exists(model_run, i, "constraints.energy_cap_equals") and constraint_exists(model_run, i, "constraints.energy_cap_min")) ] constraint_sets[ "loc_techs_storage_capacity_max_purchase_milp_constraint"] = [ i for i in set(sets.loc_techs_purchase).intersection( sets.loc_techs_store) if (constraint_exists( model_run, i, "constraints.storage_cap_equals") is not None or (constraint_exists(model_run, i, "constraints.storage_cap_max") is not None and constraint_exists( model_run, i, "constraints.storage_cap_max") != np.inf)) ] constraint_sets[ "loc_techs_storage_capacity_min_purchase_milp_constraint"] = [ i for i in set(sets.loc_techs_purchase).intersection( sets.loc_techs_store) if (not constraint_exists(model_run, i, "constraints.storage_cap_equals") and constraint_exists(model_run, i, "constraints.storage_cap_min")) ] constraint_sets[ "loc_techs_update_costs_investment_units_milp_constraint"] = [ i for i in sets.loc_techs_milp if i in sets.loc_techs_investment_cost and any( constraint_exists(model_run, i, "costs.{}.purchase".format(j)) for j in model_run.sets.costs) ] # loc_techs_purchase technologies only exist because they have defined a purchase cost constraint_sets[ "loc_techs_update_costs_investment_purchase_milp_constraint"] = sets.loc_techs_purchase constraint_sets["techs_unit_capacity_systemwide_milp_constraint"] = [ i for i in sets.techs if model_run.get_key( "techs.{}.constraints.units_max_systemwide".format(i), None) or model_run.get_key( "techs.{}.constraints.units_equals_systemwide".format(i), None) ] constraint_sets[ "loc_techs_asynchronous_prod_con_milp_constraint"] = sets.loc_techs_asynchronous_prod_con # conversion.py constraint_sets[ "loc_techs_balance_conversion_constraint"] = sets.loc_techs_conversion constraint_sets[ "loc_techs_cost_var_conversion_constraint"] = sets.loc_techs_om_cost_conversion # conversion_plus.py constraint_sets[ "loc_techs_balance_conversion_plus_primary_constraint"] = sets.loc_techs_conversion_plus constraint_sets[ "loc_techs_carrier_production_max_conversion_plus_constraint"] = [ i for i in sets.loc_techs_conversion_plus if i not in sets.loc_techs_milp ] constraint_sets[ "loc_techs_carrier_production_min_conversion_plus_constraint"] = [ i for i in sets.loc_techs_conversion_plus if constraint_exists(model_run, i, "constraints.energy_cap_min_use" ) and i not in sets.loc_techs_milp ] constraint_sets[ "loc_techs_cost_var_conversion_plus_constraint"] = sets.loc_techs_om_cost_conversion_plus constraint_sets[ "loc_techs_balance_conversion_plus_in_2_constraint"] = sets.loc_techs_in_2 constraint_sets[ "loc_techs_balance_conversion_plus_in_3_constraint"] = sets.loc_techs_in_3 constraint_sets[ "loc_techs_balance_conversion_plus_out_2_constraint"] = sets.loc_techs_out_2 constraint_sets[ "loc_techs_balance_conversion_plus_out_3_constraint"] = sets.loc_techs_out_3 # network.py constraint_sets[ "loc_techs_symmetric_transmission_constraint"] = sets.loc_techs_transmission # policy.py for sense in ["min", "max", "equals"]: constraint_sets[ f"techlists_group_share_energy_cap_{sense}_constraint"] = [ i for i in sets.techlists if f"energy_cap_{sense}" in model_run.model.get_key( "group_share.{}".format(i), {}).keys() ] constraint_sets[ f"techlists_carrier_group_share_carrier_prod_{sense}_constraint"] = [ i + "::" + carrier for i in sets.techlists if f"carrier_prod_{sense}" in model_run.model.get_key( "group_share.{}".format(i), {}).keys() for carrier in sets.carriers if carrier in model_run.model.get_key( f"group_share.{i}.carrier_prod_{sense}", {}).keys() ] # group.py group_constraints = { name: data for name, data in model_run["group_constraints"].items() if data.get("exists", True) } constraint_sets["constraint_groups"] = list(group_constraints.keys()) for group_constraint_name, group_constraint in group_constraints.items(): tech_groups = [[ k for k, v in checks.DEFAULTS.tech_groups.items() if i in v["allowed_group_constraints"] ] for i in group_constraint.keys() if i not in ["techs", "locs", "exists"]] allowed_tech_groups = set(tech_groups[0]).intersection(*tech_groups) allowed_techs = sum( [sets["techs_{}".format(i)] for i in allowed_tech_groups], []) techs = group_constraint.get("techs", allowed_techs) locs = group_constraint.get("locs", sets["locs"]) # If there are transmission techs, keep only those that link to allowed locations techs = [ i for i in techs if ":" not in techs or i.split(":")[-1] in locs ] trans_techs = set(techs).intersection(sets["techs_transmission_names"]) for i in trans_techs: techs += [i + ":" + j for j in locs] techs.remove(i) # If the group constraint defines its own techs, remove those that are # not allowed (there is a warning for this in checks.py) techs = list(set(techs).intersection(allowed_techs)) # All possible loc_techs for this constraint loc_techs_all = list( set( concat_iterable([(l, t) for l, t in product(locs, techs)], ["::"]))) # Some loc_techs may not actually exist in the actual model, # so we must filter with actually exising loc_techs loc_techs = [i for i in loc_techs_all if i in sets.loc_techs] constraint_sets["group_constraint_loc_techs_{}".format( group_constraint_name)] = loc_techs return constraint_sets
def location_specific_to_dataset(model_run): """ Extract location specific information from the processed dictionary (model.model_run) and return an xarray Dataset with DataArray variables describing distance, coordinate and available area information. Parameters ---------- model_run : AttrDict processed Calliope model_run dict Returns ------- data_dict : dict conforming to xarray conventions """ # for every transmission technology, we extract distance information, if it # is available data_dict = dict() data_dict["distance"] = dict( dims="loc_techs_transmission", data=[ model_run.get_key( "locations.{loc_from}.links.{loc_to}.techs.{tech}.distance". format(**split_loc_techs_transmission(loc_tech)), np.nan, ) for loc_tech in model_run.sets["loc_techs_transmission"] ], ) # If there is no distance information stored, distance array is deleted if data_dict["distance"]["data"].count(np.nan) == len( data_dict["distance"]["data"]): del data_dict["distance"] data_dict["lookup_remotes"] = dict( dims="loc_techs_transmission", data=concat_iterable( [(k["loc_to"], k["tech"], k["loc_from"]) for k in [ split_loc_techs_transmission(loc_tech) for loc_tech in model_run.sets["loc_techs_transmission"] ]], ["::", ":"], ), ) # If there are no remote locations stored, lookup_remotes array is deleted if data_dict["lookup_remotes"]["data"].count(np.nan) == len( data_dict["lookup_remotes"]["data"]): del data_dict["lookup_remotes"] data_dict["available_area"] = dict( dims="locs", data=[ model_run.locations[loc].get("available_area", np.nan) for loc in model_run.sets["locs"] ], ) # remove this dictionary element if nothing is defined in it if set(data_dict["available_area"]["data"]) == {np.nan}: del data_dict["available_area"] # Coordinates are defined per location, but may not be defined at all for # the model if "coordinates" in model_run.sets: data_dict["loc_coordinates"] = dict(dims=["locs", "coordinates"], data=[]) for loc in model_run.sets["locs"]: data_dict["loc_coordinates"]["data"].append([ model_run.locations[loc].coordinates[coordinate] for coordinate in model_run.sets.coordinates ]) return data_dict
def generate_loc_tech_sets(model_run, simple_sets): """ Generate loc-tech sets for a given pre-processed ``model_run`` Parameters ---------- model_run : AttrDict simple_sets : AttrDict Simple sets returned by ``generate_simple_sets(model_run)``. """ sets = AttrDict() ## # First deal with transmission techs, which can show up only in # loc_techs_transmission, loc_techs_milp, and loc_techs_purchase ## # All `tech:loc` expanded transmission technologies sets.loc_techs_transmission = set( concat_iterable( [ (i, u, j) for i, j, u in product( # (loc, loc, tech) product simple_sets.locs, simple_sets.locs, simple_sets.techs_transmission_names, ) if model_run.get_key( "locations.{}.links.{}.techs.{}".format(i, j, u), None) ], ["::", ":"], )) # A dict of transmission tech config objects # to make parsing for set membership easier loc_techs_transmission_config = { k: model_run.get_key( "locations.{loc_from}.links.{loc_to}.techs.{tech}".format( **split_loc_techs_transmission(k))) for k in sets.loc_techs_transmission } ## # Now deal with the rest of the techs and other sets ## # Only loc-tech combinations that actually exist sets.loc_techs_non_transmission = set( concat_iterable( [(l, t) for l, t in product(simple_sets.locs, simple_sets.techs_non_transmission) if model_run.get_key("locations.{}.techs.{}".format(l, t), None)], ["::"], )) sets.loc_techs = sets.loc_techs_non_transmission | sets.loc_techs_transmission # A dict of non-transmission tech config objects # to make parsing for set membership easier loc_techs_config = { k: model_run.get_key("locations.{}.techs.{}".format(*k.split("::"))) for k in sets.loc_techs_non_transmission } loc_techs_all_config = { **loc_techs_config, **loc_techs_transmission_config } ## # Sets based on membership in abstract base technology groups ## for group in [ "storage", "demand", "supply", "supply_plus", "conversion", "conversion_plus", ]: tech_set = set( k for k in sets.loc_techs_non_transmission if model_run.techs[k.split("::")[1]].inheritance[-1] == group) sets["loc_techs_{}".format(group)] = tech_set sets.loc_techs_non_conversion = (set( k for k in sets.loc_techs_non_transmission if k not in sets.loc_techs_conversion and k not in sets.loc_techs_conversion_plus) | sets.loc_techs_transmission) # Techs that introduce energy into the system sets.loc_techs_supply_all = sets.loc_techs_supply | sets.loc_techs_supply_plus # Techs that change the energy carrier in the system sets.loc_techs_conversion_all = (sets.loc_techs_conversion | sets.loc_techs_conversion_plus) # All techs that can be used to generate a carrier (not just store or move it) sets.loc_techs_supply_conversion_all = (sets.loc_techs_supply_all | sets.loc_techs_conversion_all) ## # Sets based on specific constraints being active ## # Technologies that specify resource_area constraints sets.loc_techs_area = set( k for k in sets.loc_techs_non_transmission if (any( "resource_area" in i for i in loc_techs_config[k].keys_nested()) or loc_techs_config[k]. constraints.get("resource_unit", "energy") == "energy_per_area")) # Technologies that define storage, which can include `supply_plus` # and `storage` groups. sets.loc_techs_store = (set(k for k in sets.loc_techs_supply_plus if any( "storage_" in i for i in loc_techs_config[k].constraints.keys_nested())) | sets.loc_techs_storage) # technologies that specify a finite resource sets.loc_techs_finite_resource = set( k for k in sets.loc_techs_non_transmission if loc_techs_config[k].constraints.get("resource") and not ( loc_techs_config[k].constraints.get("resource") in ["inf", np.inf]) ) # `supply` technologies that specify a finite resource sets.loc_techs_finite_resource_supply = sets.loc_techs_finite_resource.intersection( sets.loc_techs_supply) # `demand` technologies that specify a finite resource sets.loc_techs_finite_resource_demand = sets.loc_techs_finite_resource.intersection( sets.loc_techs_demand) # `supply_plus` technologies that specify a finite resource sets.loc_techs_finite_resource_supply_plus = sets.loc_techs_finite_resource.intersection( sets.loc_techs_supply_plus) # Technologies that define ramping constraints sets.loc_techs_ramping = set( k for k in sets.loc_techs_non_transmission if "energy_ramping" in loc_techs_config[k].constraints) # Technologies that allow export sets.loc_techs_export = set( k for k in sets.loc_techs_non_transmission if "export_carrier" in loc_techs_config[k].constraints) # Technologies that allow purchasing discrete units # NB: includes transmission techs! loc_techs_purchase = set(k for k in sets.loc_techs_non_transmission if any( ".purchase" in i for i in loc_techs_config[k].get("costs", AttrDict()).keys_nested( )) and not any("units_" in i for i in loc_techs_config[k].get( "constraints", AttrDict()).keys_nested())) transmission_purchase = set( k for k in sets.loc_techs_transmission if any(".purchase" in i for i in loc_techs_transmission_config[k].get( "costs", AttrDict()).keys_nested()) and not any( "units_" in i for i in loc_techs_transmission_config[k].get( "constraints", AttrDict()).keys_nested())) sets.loc_techs_purchase = loc_techs_purchase | transmission_purchase # Technologies with MILP constraints loc_techs_milp = set(k for k in sets.loc_techs_non_transmission if any( "units_" in i for i in loc_techs_config[k].constraints.keys_nested())) transmission_milp = set(k for k in sets.loc_techs_transmission if any( "units_" in i for i in loc_techs_transmission_config[k].constraints.keys_nested())) sets.loc_techs_milp = loc_techs_milp | transmission_milp # Technologies with forced asynchronous production/consumption of energy loc_techs_storage_asynchronous_prod_con = set( k for k in sets.loc_techs_store if "force_asynchronous_prod_con" in loc_techs_config[k].constraints.keys_nested()) loc_techs_transmission_asynchronous_prod_con = set( k for k in sets.loc_techs_transmission if "force_asynchronous_prod_con" in loc_techs_transmission_config[k].constraints.keys_nested()) sets.loc_techs_asynchronous_prod_con = ( loc_techs_storage_asynchronous_prod_con | loc_techs_transmission_asynchronous_prod_con) ## # Sets based on specific costs being active # NB includes transmission techs ## loc_techs_costs = set(k for k in sets.loc_techs_non_transmission if any( "costs" in i for i in loc_techs_config[k].keys())) loc_techs_transmission_costs = set( k for k in sets.loc_techs_transmission if any("costs" in i for i in loc_techs_transmission_config[k].keys())) # Any capacity or fixed annual costs loc_techs_investment_costs = set(k for k in loc_techs_costs if any( "_cap" in i or ".purchase" in i or "_area" in i for i in loc_techs_config[k].costs.keys_nested())) loc_techs_transmission_investment_costs = set( k for k in loc_techs_transmission_costs if any("_cap" in i or ".purchase" in i or "_area" in i for i in loc_techs_transmission_config[k].costs.keys_nested())) # Any operation and maintenance loc_techs_om_costs = set(k for k in loc_techs_costs if any( "om_" in i or "export" in i for i in loc_techs_config[k].costs.keys_nested())) loc_techs_transmission_om_costs = set( k for k in loc_techs_transmission_costs if any("om_" in i for i in loc_techs_transmission_config[k].costs.keys_nested())) # Any export costs sets.loc_techs_costs_export = set(k for k in loc_techs_costs if any( "export" in i for i in loc_techs_config[k].costs.keys_nested())) sets.loc_techs_cost = loc_techs_costs | loc_techs_transmission_costs sets.loc_techs_investment_cost = (loc_techs_investment_costs | loc_techs_transmission_investment_costs) sets.loc_techs_om_cost = loc_techs_om_costs | loc_techs_transmission_om_costs ## # Subsets of costs for different abstract base technologies ## sets.loc_techs_om_cost_conversion = loc_techs_om_costs.intersection( sets.loc_techs_conversion) sets.loc_techs_om_cost_conversion_plus = loc_techs_om_costs.intersection( sets.loc_techs_conversion_plus) sets.loc_techs_om_cost_supply = loc_techs_om_costs.intersection( sets.loc_techs_supply) sets.loc_techs_om_cost_supply_plus = loc_techs_om_costs.intersection( sets.loc_techs_supply_plus) ## # Subsets of `conversion_plus` technologies ## # `conversion_plus` technologies with secondary carrier(s) out sets.loc_techs_out_2 = set(k for k in sets.loc_techs_conversion_plus if "carrier_out_2" in model_run.techs[k.split( "::")[1].split(":")[0]].essentials) # `conversion_plus` technologies with tertiary carrier(s) out sets.loc_techs_out_3 = set(k for k in sets.loc_techs_conversion_plus if "carrier_out_3" in model_run.techs[k.split( "::")[1].split(":")[0]].essentials) # `conversion_plus` technologies with secondary carrier(s) in sets.loc_techs_in_2 = set(k for k in sets.loc_techs_conversion_plus if "carrier_in_2" in model_run.techs[k.split( "::")[1].split(":")[0]].essentials) # `conversion_plus` technologies with tertiary carrier(s) in sets.loc_techs_in_3 = set(k for k in sets.loc_techs_conversion_plus if "carrier_in_3" in model_run.techs[k.split( "::")[1].split(":")[0]].essentials) ## # `loc_tech_carrier` sets ## # loc_tech_carriers for all technologies that have energy_prod=True sets.loc_tech_carriers_prod = set( "{}::{}".format(k, carrier) for k in sets.loc_techs if loc_techs_all_config[k].constraints.get_key("energy_prod", False) for carrier in get_all_carriers(model_run.techs[k.split("::")[1].split( ":")[0]].essentials, direction="out")) # loc_tech_carriers for all technologies that have energy_con=True sets.loc_tech_carriers_con = set( "{}::{}".format(k, carrier) for k in sets.loc_techs if loc_techs_all_config[k].constraints.get_key("energy_con", False) for carrier in get_all_carriers(model_run.techs[k.split("::")[1].split( ":")[0]].essentials, direction="in")) # loc_tech_carriers for all supply technologies sets.loc_tech_carriers_supply_all = set( "{}::{}".format(k, carrier) for k in sets.loc_techs_supply_all for carrier in get_all_carriers(model_run.techs[k.split("::")[1].split( ":")[0]].essentials, direction="out")) # loc_tech_carriers for all conversion technologies sets.loc_tech_carriers_conversion_all = set( "{}::{}".format(k, carrier) for k in sets.loc_techs_conversion_all for carrier in get_all_carriers(model_run.techs[k.split("::")[1].split( ":")[0]].essentials, direction="out")) # loc_tech_carriers for all supply and conversion technologies sets.loc_tech_carriers_supply_conversion_all = ( sets.loc_tech_carriers_supply_all | sets.loc_tech_carriers_conversion_all) # loc_tech_carriers for all demand technologies sets.loc_tech_carriers_demand = set( "{}::{}".format(k, carrier) for k in sets.loc_techs_demand for carrier in get_all_carriers(model_run.techs[k.split("::")[1].split( ":")[0]].essentials, direction="in")) # loc_tech_carriers for all technologies that have export sets.loc_tech_carriers_export = set( "{}::{}".format(k, loc_techs_all_config[k].constraints.export_carrier) for k in sets.loc_techs if loc_techs_all_config[k].constraints.get_key( "export_carrier", False)) # loc_tech_carriers for `conversion_plus` technologies sets.loc_tech_carriers_conversion_plus = set( k for k in sets.loc_tech_carriers_con | sets.loc_tech_carriers_prod if k.rsplit("::", 1)[0] in sets.loc_techs_conversion_plus) # loc_carrier combinations that exist with either a con or prod tech sets.loc_carriers = set("{0}::{2}".format(*k.split("::")) for k in sets.loc_tech_carriers_prod | sets.loc_tech_carriers_con) return sets