calliope-project / calliope

A multi-scale energy systems modelling framework
https://www.callio.pe
Apache License 2.0
299 stars 94 forks source link

conversion_plus creating non output carrier? related to the carrier_out name #60

Closed arnaud-leroy closed 7 years ago

arnaud-leroy commented 7 years ago

Hello,

I am testing conversion_plus technology after seeing some strange behavior while using it.

I created a model with a power demand, a power supply and a conversion plus technology consuming power to release another carrier.

techs:
    supply_power:
        name: 'Electricity import'
        parent: supply
        carrier: power
        constraints:
            r: inf
            e_cap.max: 100
        costs:
            monetary:
                e_cap: 1
                om_fuel: 50

    conv_tech:
        name: 'conversion tech consuming power'
        parent: conversion_plus
        carrier_in: power    
        carrier_out:   
            name_carrier_out: 0.01
        primary_carrier: name_carrier_out

    demand_power:
        name: 'Electrical demand'
        parent: demand
        carrier: power

    unmet_demand_power:
        name: 'Unmet electrical demand'
        parent: unmet_demand
        carrier: power

In fact the name of the carrier_out has an influence on the result of the model:

I also changed the primary_carrier every time to match the carrier_out name.

arnaud-leroy commented 7 years ago

In another model, I use the 2 carriers "heat" and "district_heat". This "large_Gas_Boiler" is providing "heat" instead of "district_heat":

  large_Gas_Boiler:
    carrier_in: gas
    carrier_out:
      district_heat: 0.9
    constraints:
      e_cap.max: .inf
    costs:
      monetary:
        e_cap: 6100000.0
        om_fixed: 109800.0
    depreciation:
      plant_life: 21.0
    name: Gas Boiler
    parent: conversion_plus
    primary_carrier: district_heat
brynpickering commented 7 years ago

Thanks for this Arnaud. It was being caused by a in constraint generation:

carriers_out = model.get_carrier(y, 'out', all_carriers=True)
            if c not in carriers_out:
                return c_prod == 0
            if c in carriers_out and model._locations.at[x, y] == 0:
                return c_prod == 0

In the examples you give, with only one carrier out, model.get_carrier returns a string e.g. district_heat. So the carrier heat would be flagged as being "in" district_heat. If there were multiple output carriers, e.g. district_heat and power, model.get_carrier would return a tuple (power, district_heat), and heat would not be flagged as "in" this.

Conversion plus has quite a few quirks, I'll see if this can be resolved easily and then aim to fix it. If it causes issues downstream then it could take me a bit longer to sort.

brynpickering commented 7 years ago

Fixed in commit cc9536c