コード例 #1
0
    def add_variable(self,
                     name,
                     time=None,
                     fixed_value=None,
                     index=None,
                     **kwargs):
        '''
        Create a new variable and add it to the object's variables and the model's variables.
        :param name: name of optimization variable.
        :param kind: type of variable, specified by string. {Continuous or Binary/Boolean}
        :param low: low limit of variable
        :param high: high limit of variable
        :param fixed_value: a fixed value for a variable (making it a parameter)
        :param time: a single time for a variable
        :param index: a :class:`pyomo.Set` over which a variable is created
        '''
        def map_args(kind='Continuous', low=None, high=None):
            return dict(bounds=(low, high), domain=variable_kinds[kind])

        orig_name = name
        if index is None:
            name = self._t_id(name, time)
            if fixed_value is None:
                var = pyomo.Var(name=name, **map_args(**kwargs))
                self._parent_problem().add_component_to_problem(var)
            else:
                var = pyomo.Param(name=name, default=fixed_value)
                # add var
                self._parent_problem().add_component_to_problem(var)
                # and set value
                var = self.get_variable(orig_name, time)
                var[None] = fixed_value
        else:
            name = self._id(name)

            if fixed_value is None:
                var = pyomo.Var(index, name=name, **map_args(**kwargs))
                self._parent_problem().add_component_to_problem(var)
            else:
                var = pyomo.Param(index, name=name, default=fixed_value)
                self._parent_problem().add_component_to_problem(var)
                var = self._parent_problem().get_component(name)
                for i in index:
                    var[i] = fixed_value
コード例 #2
0
 def add_parameter(self,
                   name,
                   index=None,
                   values=None,
                   mutable=True,
                   default=None,
                   **kwargs):
     name = self._id(name)
     self._parent_problem().add_component_to_problem(
         pyomo.Param(index,
                     name=name,
                     default=default,
                     mutable=mutable,
                     **kwargs))
     if values is not None:
         if pd.Series(values).count() != len(values):
             raise ValueError('a parameter value cannot be NaN')
         var = self._parent_problem().get_component(name)
         for i in index:
             var[i] = values[i]
コード例 #3
0
from __future__ import division
from coopr import pyomo

# define an abstract model
model = pyomo.AbstractModel()

# add number of linear constraints as attribute 
model.m = pyomo.Param(within=pyomo.NonNegativeIntegers)
model.n = pyomo.Param(within=pyomo.NonNegativeIntegers)

# although not required, it is convenient to define index sets
model.I = pyomo.RangeSet(1, model.m)
model.J = pyomo.RangeSet(1, model.n)

# now we define the coefficients (which are themselves defined over index sets!)
model.a = pyomo.Param(model.I, model.J)
model.b = pyomo.Param(model.I)
model.c = pyomo.Param(model.J)

# the next line declares a variable indexed by the set J
model.x = pyomo.Var(model.J, domain=pyomo.NonNegativeReals)

def objective(model):
    """Abstract representation of our model objective.""" 
    obj = pyomo.summation(model.c, model.x)
    return obj

# add the objective function to the model object as an attribute (OBJ can be arbitrary!)
model.OBJ = pyomo.Objective(rule=objective)

def constraints(model, i):
コード例 #4
0
from __future__ import division
from coopr import pyomo

# define an abstract life-cycle savings model
model = pyomo.AbstractModel()

##### Define model parameters #####

# time horizon
model.T = pyomo.Param(doc="time horizon", within=pyomo.NonNegativeIntegers)
model.periods = pyomo.RangeSet(0, model.T)

# retirement age
model.R = pyomo.Param(doc="retirement age", within=pyomo.NonNegativeIntegers)

# net interest rate
model.r = pyomo.Param(doc='interest rate', within=pyomo.NonNegativeReals)

# wages
model.w0 = pyomo.Param(doc='initial real wage', within=pyomo.NonNegativeReals)
model.g = pyomo.Param(doc='growth rate of real wages',
                      within=pyomo.NonNegativeReals)


def wage_schedule(model, t):
    """Defines the path of wages. This should really go in the .dat file!"""
    # extract parameters
    w0 = model.w0
    g = model.g

    if t < model.R:
コード例 #5
0
from __future__ import division
from coopr import pyomo

# define an abstract life-cycle savings model
model = pyomo.AbstractModel()

##### Define model parameters #####

# time horizon
model.T = pyomo.Param(doc="time horizon", within=pyomo.NonNegativeIntegers)
model.periods = pyomo.RangeSet(0, model.T)

# retirement age
model.R = pyomo.Param(doc="retirement age", within=pyomo.NonNegativeIntegers)

# net interest rate
model.r = pyomo.Param(doc='interest rate', within=pyomo.NonNegativeReals)


# wages
def wage_schedule(model, t):
    """Defines the path of wages. This should really go in the .dat file!"""
    if t < model.R:
        wage = t / model.R
    else:
        wage = 0.0
    return wage


model.w = pyomo.Param(model.periods,
                      doc='real wages',
コード例 #6
0
from __future__ import division
from coopr import pyomo

# define an abstract life-cycle savings model
model = pyomo.AbstractModel()

##### Define model parameters #####

# time horizon
model.T = pyomo.Param(doc="time horizon", within=pyomo.NonNegativeIntegers)
model.periods = pyomo.RangeSet(0, model.T)

# retirement age
model.R = pyomo.Param(doc="retirement age", within=pyomo.NonNegativeIntegers)

# net interest rate
model.r = pyomo.Param(doc='interest rate', within=pyomo.NonNegativeReals)

# wages
model.w0 = pyomo.Param(doc='initial real wage', within=pyomo.NonNegativeReals)
model.g = pyomo.Param(doc='growth rate of real wages',
                      within=pyomo.NonNegativeReals)


def wage_schedule(model, t):
    """Defines the path of wages. This should really go in the .dat file!"""
    # extract parameters
    w0 = model.w0
    g = model.g

    if t < model.R:
コード例 #7
0
def create_model(data, timesteps):
    """ Create a VICUS model object from input data.
    
    Creates and returns a Pyomo ConcreteModel object, given a model
    input file (supported formats: Excel spreadsheet [planned: SQLite DB])
    
    Args:
        data: input dict with fields for Commodities, Processes, 
            Storage and timeseries for Demand and SupIm
        timesteps: numpy array of timestep labels, matching the ones 
            used in the Demand and SupIm timeseries
            
    Returns:
        A coopr.pyomo ConcreteModel object, ready to be instantiated and
        solved.
                  
    """
    m = pyomo.ConcreteModel()
    m.name = 'VICUS'
    m.created = datetime.now().strftime('%Y%m%dT%H%M%S', )

    # Preparations
    # ============
    # Data import. Syntax to access a value within equation definitions looks
    # like this:
    #
    #     m.process.loc[sit, pro, coin, cout][attribute]
    #
    get_inputs = itemgetter("commodity", "process", "storage", "demand",
                            "supim")
    (m.commodity, m.process, m.storage, m.demand, m.supim) = get_inputs(data)

    # Sets
    # ====
    # Syntax: m.{name} = Set({domain}, initialize={values})
    # where name: set name
    #       domain: set domain for tuple sets, a cartesian set product
    #       values: set values, a list or array of element tuples
    m.t = pyomo.Set(ordered=True, initialize=timesteps)
    m.tm = pyomo.Set(within=m.t, initialize=timesteps[1:])
    m.co = pyomo.Set(initialize=m.commodity.index.levels[0])
    m.coin = pyomo.Set(within=m.co, initialize=m.process.index.levels[1])
    m.cout = pyomo.Set(within=m.co, initialize=m.process.index.levels[2])
    m.co_type = pyomo.Set(initialize=m.commodity.index.levels[1])
    m.pro = pyomo.Set(initialize=m.process.index.levels[0])
    m.sto = pyomo.Set(initialize=m.storage.index.levels[0])
    m.cost_type = pyomo.Set(initialize=['Inv', 'Fix', 'Var', 'Fuel'])

    # sets of existing tuples:
    # co_tuples = [('Coal', 'Stock'), ('Wind', 'SupIm'), ('ElecAC', 'Demand')...]
    # pro_tuples = [('pp', 'Coal', 'ElecAC'), ('wt', 'Wind', 'ElecAC')...]
    # sto_tuples = [('bat', 'ElecDC'), ('pst', 'ElecAC')...]
    m.co_tuples = pyomo.Set(within=m.co * m.co_type,
                            initialize=m.commodity.index)
    m.pro_tuples = pyomo.Set(within=m.pro * m.coin * m.cout,
                             initialize=m.process.index)
    m.sto_tuples = pyomo.Set(within=m.sto * m.co, initialize=m.storage.index)

    # subsets of commodities by type
    # for shorter equations that apply to only one commodity type
    m.co_supim = pyomo.Set(within=m.co,
                           initialize=(c[0] for c in m.co_tuples
                                       if c[1] == 'SupIm'))
    m.co_stock = pyomo.Set(within=m.co,
                           initialize=(c[0] for c in m.co_tuples
                                       if c[1] == 'Stock'))
    m.co_demand = pyomo.Set(within=m.co,
                            initialize=(c[0] for c in m.co_tuples
                                        if c[1] == 'Demand'))

    # Parameters
    # ==========
    # for model entities (commodity, process, storage) no Pyomo params
    # are needed, just use the DataFrames m.commodity, m.process and
    # m.storage directly.
    # Syntax: m.{name} = Param({domain}, initialize={values})
    # where name: param name
    #       domain: one or multiple model sets; empty for scalar parameters
    #       values: dict of values, addressed by elements of domain sets
    m.weight = pyomo.Param(initialize=float(8760) / len(m.t))

    # Variables
    # =========
    # listed alphabetically
    # Syntax: m.{name} = Var({domain}, within={range})
    # where name: variable name
    #       domain: variable domain, consisting of one or multiple sets
    #       range: variable values, like Binary, Integer, NonNegativeReals
    m.cap_pro = pyomo.Var(m.pro_tuples,
                          within=pyomo.NonNegativeReals,
                          doc='Total process capacity (kW)')
    m.cap_pro_new = pyomo.Var(m.pro_tuples,
                              within=pyomo.NonNegativeReals,
                              doc='New process capacity (kW)')
    m.cap_sto_c = pyomo.Var(m.sto_tuples,
                            within=pyomo.NonNegativeReals,
                            doc='Total storage size (kWh)')
    m.cap_sto_c_new = pyomo.Var(m.sto_tuples,
                                within=pyomo.NonNegativeReals,
                                doc='New storage capacity (kWh)')
    m.cap_sto_p = pyomo.Var(m.sto_tuples,
                            within=pyomo.NonNegativeReals,
                            doc='Total storage power (kW)')
    m.cap_sto_p_new = pyomo.Var(m.sto_tuples,
                                within=pyomo.NonNegativeReals,
                                doc='New storage power (kW)')
    m.co2_pro_out = pyomo.Var(
        m.tm,
        m.pro_tuples,
        within=pyomo.NonNegativeReals,
        doc='CO2 emissions from processes (kg) per timestep')
    m.costs = pyomo.Var(m.cost_type,
                        within=pyomo.NonNegativeReals,
                        doc='Costs by type (EUR/a)')
    m.e_co_stock = pyomo.Var(
        m.tm,
        m.co_stock,
        within=pyomo.NonNegativeReals,
        doc='Source power flow from stock commodities (kW) per timestep')
    m.e_pro_in = pyomo.Var(m.tm,
                           m.pro_tuples,
                           within=pyomo.NonNegativeReals,
                           doc='Power flow into process (kW) per timestep')
    m.e_pro_out = pyomo.Var(m.tm,
                            m.pro_tuples,
                            within=pyomo.NonNegativeReals,
                            doc='Power flow out of process (kW) per timestep')
    m.e_sto_in = pyomo.Var(m.tm,
                           m.sto_tuples,
                           within=pyomo.NonNegativeReals,
                           doc='Power flow into storage (kW) per timestep')
    m.e_sto_out = pyomo.Var(m.tm,
                            m.sto_tuples,
                            within=pyomo.NonNegativeReals,
                            doc='Power flow out of storage (kW) per timestep')
    m.e_sto_con = pyomo.Var(m.t,
                            m.sto_tuples,
                            within=pyomo.NonNegativeReals,
                            doc='Energy content of storage (kWh) in timestep')

    # Equation definition
    # ===================
    # listed by topic. All equations except the Objective function are
    # of type Constraint, although there are two semantics for those,
    # indicated by the name prefix (def, res).
    #  - def: definition, usually equations, defining variable values
    #  - res: restriction, usually inequalities, limiting variable values
    # topics
    #  - commodity
    #  - process
    #  - storage
    #  - emissions
    #  - costs

    # commodity
    def res_demand_rule(m, tm, co, co_type):
        if co not in m.co_demand:
            return pyomo.Constraint.Skip
        else:
            provided_energy = -commodity_balance(m, tm, co)
            return provided_energy >= \
                   m.demand.loc[tm][co] * \
                   m.commodity.loc[co, co_type]['peak']

    def def_e_co_stock_rule(m, tm, co, co_type):
        if co not in m.co_stock:
            return pyomo.Constraint.Skip
        else:
            return m.e_co_stock[tm, co] == commodity_balance(m, tm, co)

    def res_stock_hour_rule(m, tm, co, co_type):
        if co not in m.co_stock:
            return pyomo.Constraint.Skip
        else:
            return m.e_co_stock[tm, co] <= \
                   m.commodity.loc[co, co_type]['maxperhour']

    def res_stock_total_rule(m, co, co_type):
        if co not in m.co_stock:
            return pyomo.Constraint.Skip
        else:
            # calculate total consumption of commodity co
            total_consumption = 0
            for tm in m.tm:
                total_consumption += m.e_co_stock[tm, co] * m.weight
            return total_consumption <= m.commodity.loc[co, co_type]['max']

    # process
    def def_process_capacity_rule(m, tm, pro, coin, cout):
        return m.cap_pro[pro,coin,cout] == \
               m.cap_pro_new[pro,coin,cout] + \
               m.process.loc[pro,coin,cout]['inst-cap']

    def def_process_output_rule(m, tm, pro, coin, cout):
        return m.e_pro_out[tm, pro, coin, cout] == \
               m.e_pro_in[tm, pro, coin, cout] * \
               m.process.loc[pro, coin, cout]['eff']

    def def_intermittent_supply_rule(m, tm, pro, coin, cout):
        if coin in m.co_supim:
            return m.e_pro_in[tm, pro, coin, cout] == \
                   m.cap_pro[pro, coin, cout] * m.supim.loc[tm][coin]
        else:
            return pyomo.Constraint.Skip

    def def_co2_emissions_rule(m, tm, pro, coin, cout):
        return m.co2_pro_out[tm, pro, coin, cout] == \
               m.e_pro_in[tm, pro, coin, cout] * \
               m.process.loc[pro, coin, cout]['co2'] * \
               m.weight

    def res_process_output_by_capacity_rule(m, tm, pro, coin, cout):
        return m.e_pro_out[tm, pro, coin, cout] <= m.cap_pro[pro, coin, cout]

    def res_process_capacity_rule(m, pro, coin, cout):
        return (m.process.loc[pro, coin, cout]['cap-lo'],
                m.cap_pro[pro, coin, cout], m.process.loc[pro, coin,
                                                          cout]['cap-up'])

    # storage
    def def_storage_state_rule(m, t, sto, co):
        return m.e_sto_con[t, sto, co] == \
               m.e_sto_con[t-1, sto, co] + \
               m.e_sto_in[t, sto, co] * m.storage.loc[sto, co]['eff-in'] - \
               m.e_sto_out[t, sto, co] / m.storage.loc[sto, co]['eff-out']

    def def_storage_power_rule(m, sto, co):
        return m.cap_sto_p[sto, co] == \
               m.cap_sto_p_new[sto, co] + \
               m.storage.loc[sto, co]['inst-cap-p']

    def def_storage_capacity_rule(m, sto, co):
        return m.cap_sto_c[sto, co] == \
               m.cap_sto_c_new[sto, co] + \
               m.storage.loc[sto, co]['inst-cap-p']

    def res_storage_input_by_power_rule(m, t, sto, co):
        return m.e_sto_in[t, sto, co] <= m.cap_sto_p[sto, co]

    def res_storage_output_by_power_rule(m, t, sto, co):
        return m.e_sto_out[t, sto, co] <= m.cap_sto_p[sto, co]

    def res_storage_state_by_capacity_rule(m, t, sto, co):
        return m.e_sto_con[t, sto, co] <= m.cap_sto_c[sto, co]

    def res_storage_power_rule(m, sto, co):
        return (m.storage.loc[sto, co]['cap-lo-p'], m.cap_sto_p[sto, co],
                m.storage.loc[sto, co]['cap-up-p'])

    def res_storage_capacity_rule(m, sto, co):
        return (m.storage.loc[sto, co]['cap-lo-c'], m.cap_sto_c[sto, co],
                m.storage.loc[sto, co]['cap-up-c'])

    def res_initial_and_final_storage_state_rule(m, t, sto, co):
        if t == m.t[1]:  # first timestep (Pyomo uses 1-based indexing)
            return m.e_sto_con[t, sto, co] == \
                   m.cap_sto_c[sto, co] * \
                   m.storage.loc[sto, co]['init']
        elif t == m.t[-1]:  # last timestep
            return m.e_sto_con[t, sto, co] >= \
                   m.cap_sto_c[sto, co] * \
                   m.storage.loc[sto, co]['init']
        else:
            return pyomo.Constraint.Skip

    # emissions
    def res_co2_emission_rule(m):
        return pyomo.summation(m.co2_pro_out) <= \
               m.commodity.loc['CO2','Env']['max']

    # costs
    def def_costs_rule(m, cost_type):
        """ Calculate total costs by cost type.
        
        Sums up process activity and capacity expansions
        and sums them in the cost types that are specified in the set
        m.cost_type. To change or add cost types, add/change entries 
        there and modify the if/elif cases in this function accordingly.
        
        Cost types are
          - Investment costs for process power, storage power and 
            storage capacity, annualized.
          - Fixed costs for process & storage power, storage capacity.
          - Variable costs for process and storage activity.
          - Fuel costs for purchased stock commodities.
        """
        if cost_type == 'Inv':
            return m.costs['Inv'] == \
                sum(m.cap_pro_new[p] *
                    m.process.loc[p]['inv-cost'] *
                    m.process.loc[p]['annuity_factor']
                    for p in m.pro_tuples) + \
                sum(m.cap_sto_p_new[s] *
                    m.storage.loc[s]['inv-cost-p'] *
                    m.storage.loc[s]['annuity_factor'] +
                    m.cap_sto_c_new[s] *
                    m.storage.loc[s]['inv-cost-c'] *
                    m.storage.loc[s]['annuity_factor']
                    for s in m.sto_tuples)

        elif cost_type == 'Fix':
            return m.costs['Fix'] == \
                sum(m.cap_pro[p] * m.process.loc[p]['fix-cost']
                    for p in m.pro_tuples) + \
                sum(m.cap_sto_p[s] * m.storage.loc[s]['fix-cost-p'] +
                    m.cap_sto_c[s] * m.storage.loc[s]['fix-cost-c']
                    for s in m.sto_tuples)

        elif cost_type == 'Var':
            return m.costs['Var'] == \
                sum(m.e_pro_out[(tm,) + p] *
                    m.process.loc[p]['var-cost'] *
                    m.weight
                    for tm in m.tm for p in m.pro_tuples) + \
                sum(m.e_sto_con[(tm,) + s] *
                    m.storage.loc[s]['var-cost-c'] * m.weight +
                    (m.e_sto_in[(tm,) + s] + m.e_sto_out[(tm,) + s]) *
                    m.storage.loc[s]['var-cost-p'] * m.weight
                    for tm in m.tm for s in m.sto_tuples)

        elif cost_type == 'Fuel':
            return m.costs['Fuel'] == \
                sum(m.e_co_stock[(tm,c[0])] *
                    m.commodity.loc[c]['price'] *
                    m.weight
                    for tm in m.tm for c in m.co_tuples
                    if c[0] in m.co_stock)

        else:
            raise NotImplementedError("Unknown cost type!")

    def obj_rule(m):
        """ Return sum of total costs over all cost types.
        
        Simply calculates the sum of m.costs over all m.cost_types.
        """
        return pyomo.summation(m.costs)

    # Equation declaration
    # ====================
    # declarations connect rule functions to the model, specifying
    # the model sets for which the constraints are enforced.

    # commodity
    m.res_demand = pyomo.Constraint(m.tm,
                                    m.co_tuples,
                                    doc='storage + process balance >= demand')
    m.def_e_co_stock = pyomo.Constraint(
        m.tm,
        m.co_tuples,
        doc='commodity source term = hourly commodity consumption')
    m.res_stock_hour = pyomo.Constraint(
        m.tm,
        m.co_tuples,
        doc='hourly commodity source term <= commodity.maxperhour')
    m.res_stock_total = pyomo.Constraint(
        m.co_tuples, doc='total commodity source term <= commodity.max')

    # process
    m.def_process_capacity = pyomo.Constraint(
        m.tm,
        m.pro_tuples,
        doc='total process capacity = inst-cap + new capacity')
    m.def_process_output = pyomo.Constraint(
        m.tm, m.pro_tuples, doc='process output = process input * efficiency')
    m.def_intermittent_supply = pyomo.Constraint(
        m.tm,
        m.pro_tuples,
        doc='process output = process capacity * supim timeseries')
    m.def_co2_emissions = pyomo.Constraint(
        m.tm,
        m.pro_tuples,
        doc='process co2 output = process input * process.co2 * weight')
    m.res_process_output_by_capacity = pyomo.Constraint(
        m.tm, m.pro_tuples, doc='process output <= process capacity')
    m.res_process_capacity = pyomo.Constraint(
        m.pro_tuples,
        doc='process.cap-lo <= process capacity <= process.cap-up')

    # storage
    m.def_storage_state = pyomo.Constraint(
        m.tm, m.sto_tuples, doc='storage[t] = storage[t-1] + input - output')
    m.def_storage_power = pyomo.Constraint(
        m.sto_tuples, doc='storage power = inst-cap + new power')
    m.def_storage_capacity = pyomo.Constraint(
        m.sto_tuples, doc='storage capacity = inst-cap + new capacity')
    m.res_storage_input_by_power = pyomo.Constraint(
        m.tm, m.sto_tuples, doc='storage input <= storage power')
    m.res_storage_output_by_power = pyomo.Constraint(
        m.tm, m.sto_tuples, doc='storage output <= storage power')
    m.res_storage_state_by_capacity = pyomo.Constraint(
        m.t, m.sto_tuples, doc='storage content <= storage capacity')
    m.res_storage_power = pyomo.Constraint(
        m.sto_tuples, doc='storage.cap-lo <= storage power <= storage.cap-up')
    m.res_storage_capacity = pyomo.Constraint(
        m.sto_tuples,
        doc='storage.cap-lo <= storage capacity <= storage.cap-up')
    m.res_initial_and_final_storage_state = pyomo.Constraint(
        m.t,
        m.sto_tuples,
        doc='storage content initial == and final >= storage.init * capacity')

    # emissions
    m.res_co2_emission = pyomo.Constraint(
        doc='total co2 emissions <= commodity.co2.max')

    # costs
    m.def_costs = pyomo.Constraint(m.cost_type,
                                   doc='main cost function by cost type')
    m.obj = pyomo.Objective(sense=pyomo.minimize,
                            doc='cost = sum of all cost types')

    return m