#! usr/bin/env python3
# -*- coding: utf-8 -*-
"""
**This module defines the production units**
The production_units module defines various kinds of production units with
associated attributes and methods.
It includes :
- ProductionUnit : simple production unit inheriting from EnergyUnit and
with an outer flow direction. The outside co2 emissions, the starting cost,
the operating cost, the minimal operating time, the minimal non-operating
time, the maximal increasing ramp and the maximal decreasing ramp can be
filled.
Objectives are also available :
* minimize starting cost, operating cost, total cost
* minimize production, co2_emissions, time of use
* maximize production
- FixedProductionUnit : Production unit with a fixed production profile.
- VariableProductionUnit : Production unit with a variation of power between
p_min et p_max.
And also :
- SeveralProductionUnit: Production unit based on a fixed production curve
enabling to multiply several times (nb_unit) the same production curve
- SeveralImaginaryProductionUnit: Production unit based on a fixed
production curve enabling to multiply several times (nb_unit) the same
production curve. Be careful, the solution may be imaginary as nb_unit
can be continuous. The accurate number of the production unit should be
calculated later
- SquareProductionUnit: Production unit with a fixed value and fixed
duration.
- ShiftableProductionUnit: Production unit with shiftable production
profile.
..
Copyright 2018 G2Elab / MAGE
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import warnings
from pulp import LpBinary, LpInteger, LpContinuous
from .energy_units import *
del AssemblyUnit
from ...general.optimisation.elements import Constraint, DynamicConstraint, \
ExtDynConstraint
from ...general.optimisation.elements import Objective
from ...general.optimisation.elements import Quantity
__docformat__ = "restructuredtext en"
[docs]class ProductionUnit(EnergyUnit):
"""
**Description**
Simple Production unit
**Attributes**
* co2_out: outside co2 emissions
* starting_cost: the starting cost
* operating_cost: the operating cost
* min_time_on : the minimal operating time
* min_time_off : the minimal non-operating time
* max_ramp_up : the maximal increasing ramp
* max_ramp_down ; the maximal decreasing ramp
"""
def __init__(self, time, name, p=None, p_min=1e-5, p_max=1e+5, e_min=0,
e_max=1e6, co2_out=None, starting_cost=None,
operating_cost=None, min_time_on=None, min_time_off=None,
max_ramp_up=None, max_ramp_down=None, availability_hours=None,
energy_type=None, verbose=True, no_warn=True):
EnergyUnit.__init__(self, time, name, flow_direction='out', p=p,
p_min=p_min, p_max=p_max, e_min=e_min, e_max=e_max,
co2_out=co2_out, starting_cost=starting_cost,
operating_cost=operating_cost,
min_time_on=min_time_on,
min_time_off=min_time_off, max_ramp_up=max_ramp_up,
max_ramp_down=max_ramp_down,
availability_hours=availability_hours,
energy_type=energy_type,
verbose=verbose, no_warn=no_warn)
[docs] def minimize_production(self, weight=1):
"""
:param weight: Weight coefficient for the objective
"""
self.minimize_energy(weight=weight)
self.min_energy.name = 'min_production'
[docs] def maximize_production(self, weight=1):
"""
:param weight: Weight coefficient for the objective
"""
self.minimize_energy(weight=-1 * weight)
self.min_energy.name = 'max_production'
[docs]class FixedProductionUnit(FixedEnergyUnit, ProductionUnit):
"""
**Description**
Production unit with a fixed production profile.
**Attributes**
* p : instantaneous power production known by advance (kW)
* energy_type : type of energy ('Electrical', 'Heat', ...)
"""
def __init__(self, time, name: str, p: list or dict or pd.DataFrame = None,
co2_out=None,
starting_cost=None, operating_cost=None, energy_type=None,
verbose=True):
ProductionUnit.__init__(self, time=time, name=name, verbose=verbose)
FixedEnergyUnit.__init__(self, time, name=name, p=p,
flow_direction='out',
starting_cost=starting_cost,
operating_cost=operating_cost, co2_out=co2_out,
energy_type=energy_type,
verbose=False)
[docs]class VariableProductionUnit(VariableEnergyUnit, ProductionUnit):
"""
**Description**
Production unit with a variation of power between p_min et p_max.
**Attributes**
* p_max : maximal instantaneous power production (kW)
* p_min : minimal instantaneous power production (kW)
* energy_type : type of energy ('Electrical', 'Heat', ...)
"""
def __init__(self, time, name, p_min=1e-5, p_max=1e+5, e_min=0,
e_max=1e6, co2_out=None, starting_cost=None,
operating_cost=None, min_time_on=None, min_time_off=None,
max_ramp_up=None, max_ramp_down=None, energy_type=None,
verbose=True, no_warn=True):
ProductionUnit.__init__(self, time=time, name=name, verbose=verbose)
VariableEnergyUnit.__init__(self, time, name=name,
flow_direction='out', p_min=p_min,
p_max=p_max, e_min=e_min, e_max=e_max,
starting_cost=starting_cost,
operating_cost=operating_cost,
min_time_on=min_time_on,
min_time_off=min_time_off,
max_ramp_up=max_ramp_up,
max_ramp_down=max_ramp_down,
co2_out=co2_out, energy_type=energy_type,
verbose=False,
no_warn=no_warn)
[docs]class SeveralProductionUnit(VariableProductionUnit, SeveralEnergyUnit):
"""
**Description**
Production unit based on a fixed production curve enabling to multiply
several times (nb_unit) the same production curve.
nb_unit is an integer variable.
**Attributes**
* fixed_prod : fixed production curve
"""
def __init__(self, time, name, fixed_prod, p_min=1e-5, p_max=1e+5, e_min=0,
e_max=1e6, nb_unit_min=0, nb_unit_max=None, co2_out=None,
starting_cost=None, operating_cost=None, max_ramp_up=None,
max_ramp_down=None, energy_type=None,
verbose=True, no_warn=True):
VariableProductionUnit.__init__(self, time=time, name=name,
verbose=verbose)
SeveralEnergyUnit.__init__(self, time, name=name,
fixed_power=fixed_prod, p_min=p_min,
p_max=p_max, imaginary=False, e_min=e_min,
e_max=e_max, nb_unit_min=nb_unit_min,
nb_unit_max=nb_unit_max,
flow_direction='out',
starting_cost=starting_cost,
operating_cost=operating_cost,
max_ramp_up=max_ramp_up,
max_ramp_down=max_ramp_down,
co2_out=co2_out, energy_type=energy_type,
verbose=False,
no_warn=no_warn)
[docs]class SeveralImaginaryProductionUnit(VariableProductionUnit, SeveralEnergyUnit):
"""
**Description**
Production unit based on a fixed production curve enabling to multiply
several times (nb_unit) the same production curve.
Be careful, the solution may be imaginary as nb_unit can be
continuous. The accurate number of the production unit should be
calculated later.
**Attributes**
* fixed_prod : fixed production curve
"""
def __init__(self, time, name, fixed_prod, p_min=1e-5, p_max=1e+5, e_min=0,
e_max=1e6, nb_unit_min=0, nb_unit_max=None, co2_out=None,
starting_cost=None, operating_cost=None, max_ramp_up=None,
max_ramp_down=None, energy_type=None,
verbose=True, no_warn=True):
VariableProductionUnit.__init__(self, time=time, name=name,
verbose=verbose)
SeveralEnergyUnit.__init__(self, time, name=name,
fixed_power=fixed_prod, p_min=p_min,
p_max=p_max, imaginary=True, e_min=e_min,
e_max=e_max, nb_unit_min=nb_unit_min,
nb_unit_max=nb_unit_max,
flow_direction='out',
starting_cost=starting_cost,
operating_cost=operating_cost,
max_ramp_up=max_ramp_up,
max_ramp_down=max_ramp_down,
co2_out=co2_out, energy_type=energy_type,
verbose=False,
no_warn=no_warn)
[docs]class SquareProductionUnit(SquareEnergyUnit, VariableProductionUnit):
"""
**Description**
| Production unit with a fixed value and fixed duration.
| Only the time of beginning can be modified.
| Operation can be mandatory or not.
**Attributes**
* p : instantaneous power production (kW)
* duration : duration of the power delivery (hours)
* mandatory : indicates if the power delivery is mandatory or not
* energy_type : type of energy ('Electrical', 'Heat', ...)
"""
def __init__(self, time, name, p_square, duration, n_square,
t_between_sq, co2_out=None, starting_cost=None,
operating_cost=None, energy_type=None,
verbose=True, no_warn=True):
duration /= time.DT
if duration < 1:
raise ValueError('The duration of operation of the '
'SquareProductionUnit should be longer than the '
'time step.')
VariableProductionUnit.__init__(self, time=time, name=name,
verbose=verbose)
SquareEnergyUnit.__init__(self, time, name=name, p_square=p_square,
n_square=n_square, t_square=duration,
t_between_sq=t_between_sq,
flow_direction='out',
starting_cost=starting_cost,
operating_cost=operating_cost,
co2_out=co2_out, energy_type=energy_type,
verbose=False,
no_warn=no_warn)
[docs]class ShiftableProductionUnit(ShiftableEnergyUnit, VariableProductionUnit):
"""
**Description**
Production unit with shiftable production profile.
**Attributes**
* power_values : production profile to shift (kW)
* mandatory : indicates if the production is mandatory : True
or not : False
* starting_cost : cost of the starting of the production
* operating_cost : cost of the operation (€/kW)
* energy_type : type of energy ('Electrical', 'Heat', ...)
"""
def __init__(self, time, name: str, power_values, mandatory=True,
co2_out=None, starting_cost=None, operating_cost=None,
energy_type=None, verbose=True):
VariableProductionUnit.__init__(self, time=time, name=name,
verbose=verbose)
ShiftableEnergyUnit.__init__(self, time, name=name,
flow_direction='out',
power_values=power_values,
mandatory=mandatory, co2_out=co2_out,
starting_cost=starting_cost,
operating_cost=operating_cost,
energy_type=energy_type,
verbose=False)