def __init__(self, COP=None, max_capacity=None, Qmax=None, taxation=None, investment_cost=None, **kwargs): super().__init__(**kwargs) with fs.namespace(self): Q = fs.VariableCollection(lb=0, ub=Qmax, name='Q') inv = fs.Variable(domain=fs.Domain.binary) self.production[Resources.heat] = Q self.consumption[Resources.power] = lambda t: Q(t) / COP #power_cons_tax = taxation('consumption', Resources.power) #Instead of using power_cons_tax in the lambda function I added 10 as a fixed cost self.cost = lambda t: self.consumption[Resources.power](t) * 10 self.state_variables = lambda t: {Q(t)} self.inv = inv if max_capacity: self.max_capacity = max_capacity self.constraints += self.max_production self.investment_cost = inv * investment_cost self.static_variables = {inv} else: self.static_variables = {}
def __init__(self, G=None, T=None, max_capacity=None, capacity=None, taxation=None, running_cost=0, investment_cost=None, **kwargs): super().__init__(**kwargs) self.test = { 'max_capacity': max_capacity, 'capacity': capacity, 'taxation': taxation, 'investment_cost': investment_cost } c1 = -0.0177162 c2 = -0.040289 c3 = -0.004681 c4 = 0.000148 c5 = 0.000169 c6 = 0.000005 Gstc = 1 Tstc = 25 coef_temp_PV = 0.035 if max_capacity: PV_cap = fs.Variable(lb=0, ub=max_capacity, name='PV_cap') self.PV_cap = PV_cap self.investment_cost = PV_cap * investment_cost self.static_variables = {PV_cap} else: PV_cap = capacity self.PV_cap = PV_cap print('!! -- PV PROD IS NOT DEFINED CORRECTLY -- !!') def prod(t): if G[t] == 0: prod = PV_cap * 0 else: G[t] = abs(G[t] / (Gstc * 1000)) T[t] = (T[t] + coef_temp_PV * G[t]) - Tstc prod = PV_cap * 35 #PV_cap* (G[t]*(1 + c1*math.log10(G[t]) + c2*(math.log10(G[t]))**2 + c3*T[t] + c4*T[t]*math.log10(G[t]) + c5*T[t]*(math.log10(G[t]))**2 + c6*(T[t])**2)) return prod self.cost = lambda t: 0 self.production[Resources.power] = lambda t: prod(t) self.state_variables = lambda t: {}
def __init__(self, resource=None, max_flow=0, max_energy=0, loss_factor=0, max_capacity=None, investment_cost=None, t_start='2016-01-01', t_end='2016-01-02', **kwargs): super().__init__(**kwargs) with fs.namespace(self): volume = fs.VariableCollection(lb=0, ub=max_energy, name='Storage') #cap = fs.Variable(lb=0, ub=max_capacity, name='cap') inv = fs.Variable(domain=fs.Domain.binary) self.test = { 'resource': resource, 'max_flow': max_flow, 'max_energy': max_energy, 'loss_factor': loss_factor, 'max_capacity': max_capacity, 'investment_cost': investment_cost } self.t_start = t_start self.t_end = t_end self.max_energy = max_energy self.volume = volume self.resource = resource self.consumption[self.resource] = lambda t: loss_factor * volume(t) self.max_flow = max_flow self.cost = lambda t: 0 self.state_variables = lambda t: {volume(t)} self.accumulation[self.resource] = self.compute_accumulation self.constraints += self.max_change_constraints self.inv = inv if max_capacity: self.max_capacity = max_capacity self.investment_cost = inv * investment_cost self.constraints += self.max_volume self.timeindependent_constraint = fs.Eq(inv, 0) self.static_variables = {inv} else: self.static_variables = {} self.constraints += self.start_end_volume self.constraints += self.start_volume
def __init__(self, fuel=None, alpha=None, eta=None, Fmax=None, taxation=None, investment_cost=None, running_cost=0, max_capacity=None, **kwargs): super().__init__(**kwargs) try: if math.isnan(Fmax): Fmax = max_capacity except TypeError: import pdb pdb.set_trace() with fs.namespace(self): F = fs.VariableCollection(lb=0, ub=Fmax, name='F') inv = fs.Variable(domain=fs.Domain.binary, name='inv_chp') self.test = { 'fuel': fuel, 'alpha': alpha, 'eta': eta, 'Fmax': Fmax, 'max_capacity': max_capacity, 'taxation': taxation, 'investment_cost': investment_cost } self.consumption[fuel] = F self.production[Resources.heat] = lambda t: F(t) * eta / (alpha + 1) self.production[ Resources.power] = lambda t: alpha * F(t) * eta / (alpha + 1) self.cost = lambda t: F( t) * running_cost #_CHP_cost_func(self, taxation, fuel) self.state_variables = lambda t: {F(t)} self.inv = inv if max_capacity: self.max_capacity = max_capacity self.constraints += self.max_production self.investment_cost = inv * investment_cost self.static_variables = {inv} else: self.static_variables = {}
def __init__(self, fuel=None, taxation=None, Fmax=None, eta=None, investment_cost=None, running_cost=0, max_capacity=None, **kwargs): super().__init__(**kwargs) with fs.namespace(self): F = fs.VariableCollection(lb=0, ub=Fmax, name='F') inv = fs.Variable(domain=fs.Domain.binary) self.test = { 'Fmax': Fmax, 'eta': eta, 'running_cost': running_cost, 'max_capacity': max_capacity } self.consumption[fuel] = F self.production[Resources.heat] = lambda t: eta * F(t) self.cost = lambda t: self.consumption[fuel](t) * running_cost self.state_variables = lambda t: {F(t)} self.inv = inv if max_capacity: self.max_capacity = max_capacity self.constraints += self.max_production self.investment_cost = inv * investment_cost self.static_variables = {inv} else: self.static_variables = {}
def test_simple_SOS1(): n = 4 index = 2 sum_val = 3. vs = [fs.Variable(lb=-1, domain=fs.Domain.integer) for i in range(n)] #vs[0] = fs.Variable(lb=-1, domain=fs.Domain.integer) weights = [1 for i in range(n)] weights[index] = 0.5 prob = fs.Problem() prob.add_constraint(fs.SOS1(vs)) prob.add_constraint(Constraint(sum(vs) == sum_val)) #prob.constraints.update(Constraint(v >= 0) for v in vs) prob.objective = fs.Minimize(sum(v * w for v, w in zip(vs, weights))) solution = default_solver.solve(prob) print(solution) for v in vs: v.take_value(solution) for i in range(n): if i == index: assert (approx(vs[i].value, sum_val)) else: assert (approx(vs[i].value, 0))
def make_parts(self, parameters): def make_tax_function(*args, **kwargs): def tax_function(*args, **kwargs): return 0 return tax_function parts = set() taxation = make_tax_function(parameters) heat_history = self.get_heat_history(parameters['time_unit']) power_demand = self.get_power_demand(parameters['time_unit']) heat_history_industry = self.get_heat_history_industry(parameters['time_unit']) for r in pl.Resources: if r not in [pl.Resources.heat, pl.Resources.CO2]: parts.add( pl.Import( resource=r, price=parameters['prices'][r], name='Import({})'.format(r), CO2_factor=parameters['CO2_factor'][r])) # Conversion factor from hour to model time unit: # "hour" is the number of model time steps per hour. # So when capacities/consumption/etc per time step in plants below # are stated like 600 / hour", then think "600 MWh per hour". # Makes sense because larger time unit --> smaller value of "hour" --> # larger max output per time step. hour = pd.Timedelta('1h') / parameters['time_unit'] print('!! -- INCORRECT RENOVATION DATA -- !!') renovation_data_1 = self.get_heat_history(parameters['time_unit'])*0.01 #change to renovation data when available renovation_data_15 =self.get_heat_history(parameters['time_unit'])*0.015 #change to renovation data when available if not 'Trade_off' in scenario: renovation = fs.Node(name = input_data['Renovation']['name']) renovation.consumption[pl.Resources.heat]= lambda t: -renovation_data_1['DH'][t] renovation.state_variables = lambda t: () renovation.cost = lambda t: 0 parts.add(renovation) else: print('!! -- THIS PART NEEDS CLEANING -- !!') renovation = fs.Node(name = input_data['Renovation']['name']) inv_1 = fs.Variable(name= 'inv_1', domain = fs.Domain.binary) inv_0 = fs.Variable(name= 'inv_0', domain = fs.Domain.binary) renovation.test = {'investment_cost' : self.annuity(parameters['interest_rate'],input_data['Renovation']['lifespan'],input_data['Renovation']['investment_cost']), 'renovation level': input_data['Renovation']['capacity']} renovation.state_variables = lambda t: {} renovation.static_variables = {inv_1}#!AK, inv_0} renovation.consumption[pl.Resources.heat]= lambda t: - renovation_data_1['Other'][t]*inv_1 #!AK- 0*inv_0 renovation.investment_cost = self.annuity(parameters['interest_rate'],input_data['Renovation']['lifespan'],input_data['Renovation']['investment_cost']) * inv_1 + 0 * inv_0 renovation.cost = lambda t:0 parts.add(renovation) renovation_15 = fs.Node(name = input_data['Renovation_15']['name']) inv_15 = fs.Variable(name = 'inv_15', domain = fs.Domain.binary) inv_2 = fs.Variable(name = 'inv_2', domain = fs.Domain.binary) renovation_15.test = {'investment_cost' : self.annuity(parameters['interest_rate'],input_data['Renovation_15']['lifespan'],input_data['Renovation_15']['investment_cost']), 'renovation level': input_data['Renovation_15']['capacity']} renovation_15.state_variables = lambda t: {} renovation_15.static_variables ={inv_15}#!AK, inv_2} renovation_15.consumption[pl.Resources.heat]= lambda t: - renovation_data_15['DH'][t]*inv_15 #!AK - 0*inv_2 renovation_15.investment_cost = self.annuity(parameters['interest_rate'],input_data['Renovation_15']['lifespan'],input_data['Renovation_15']['investment_cost']) * inv_15 #!AK+ 0 * inv_2 renovation_15.cost = lambda t:0 parts.add(renovation_15) #renovation_const = fs.Eq(inv_0 + inv_1, 1) #renovation_const_2 = fs.Eq(inv_1 + inv_2 + inv_15, 1) print('!! -- INCORRECT HEAT HISTORY DATA AND NO CHANGE IN MAX_DH -- !!') city = fs.Node(name='City') city.cost = lambda t: 0 city.state_variables = lambda t: {} if scenario in 'Max_DH': city.consumption[pl.Resources.heat] = lambda t: heat_history['DH'][t] else: city.consumption[pl.Resources.heat] = lambda t: heat_history['DH'][t] print('!! -- INCORRECT POWER DEMAND -- !!') city.consumption[pl.Resources.power] = lambda t: 15 #power_demand['Power demand'][t] parts.add(city) Industry = fs.Node(name='Industry') Industry.consumption[pl.Resources.heat] = lambda t: heat_history_industry['DH'][t] Industry.cost = lambda t: 0 Industry.state_variables = lambda t: {} parts.add(Industry) print('!! -- POWER EXPORT WAS DIVIDED BY 10, CHANGED TO 2, WHAT IS CORRECT? -- !!') powerExport = pl.Export(resource = pl.Resources.power, price = parameters['prices'][pl.Resources.power]/2, name='power export') parts.add(powerExport) CO2 = pl.Export(resource = pl.Resources.CO2, price = 0, name = 'CO2_emissions') CO2.time_unit = parameters['time_unit'] parts.add(CO2) "Timeindependent constraint on maximum CO2 emissions during the whole timeperiod" times = CO2.times_between(parameters['t_start'], parameters['t_end']) emissions = fs.Sum(CO2.consumption[pl.Resources.CO2](t) for t in times) CO2_maximum = fs.LessEqual(emissions, 100000000000) #below 24 069 146 limit the CO2 emissions print('!! -- DECREASE HEATING CONSUMPTION AS DH IS EXPANDED -- !!') heating = fs.Node(name='Heating') #se till att heat_history['Other'] minskar när DH byggs ut och blir större heating.consumption[pl.Resources.natural_gas] = lambda t: heat_history['Other'][t]*0.8/0.95 #verkningsgrad gasuppvärmning heating.consumption[pl.Resources.power] = lambda t: 10 #heat_history['Other'][t]*0.2/0.97 #verkningsgrad eluppvärmning heating.cost = lambda t: 0 heating.state_variables = lambda t: {} parts.add(heating) CHP_A = pl.LinearCHP(name='Existing CHP A', eta=0.776, alpha=0.98, Fmax= 4.27 / hour, fuel=pl.Resources.natural_gas, taxation=taxation) # Fmin= 2.33 / hour, start_steps=int(np.round(.5 * hour)), parts.add(CHP_A) CHP_B =pl.LinearCHP(name='Existing CHP B', eta=0.778, alpha=0.98, Fmax= 4.27 /hour, fuel=pl.Resources.natural_gas, taxation=taxation) # Fmin= 2.33 / hour, start_steps=int(np.round(.5 * hour)), parts.add(CHP_B) parts.add(pl.Boiler(name='Existing Boiler A', eta=0.9, Fmax=8.84 / hour, fuel=pl.Resources.natural_gas, taxation=taxation)) parts.add(pl.Boiler(name='Existing Boiler B',eta=0.87, Fmax=8.84 / hour, fuel=pl.Resources.natural_gas, taxation=taxation)) parts.add(pl.Boiler(name='Existing Boiler C', eta=0.89, Fmax=8.84 / hour, fuel=pl.Resources.natural_gas, taxation=taxation)) parts.add(pl.Boiler(name='Existing Boiler D', eta= 0.77, Fmax= 8.84 / hour, fuel=pl.Resources.natural_gas, taxation=taxation)) print('!! -- TRUE CAPACITY IS 45 MW - RUNNING AT 25 MW -- !!') # Running waste incinerator at 25 MW output max according to D4.2 p 32, techincal limit is 45 parts.add( pl.LinearCHP(name='Existing Waste Incinerator', fuel=pl.Resources.waste, alpha=0.46, eta=0.81, Fmax= 25/hour, taxation=taxation) ) parts.add( pl.Accumulator(name='Existing Accumulator', resource=pl.Resources.heat, max_flow=60/hour, max_energy= 220, loss_factor = 0.005, t_start = parameters['t_start'], t_end = parameters['t_end']) ) """ Production alternatives for the scenarios""" solar_data=self.get_solar_data(parameters['time_unit']) print("""!! -- Dividing investment cost LinearCHP by max_capacity so cost is EUR/MW-- !!""") parts.add( pl.LinearCHP( name = input_data['CHP']['name'], eta = input_data['CHP']['eta'], alpha = input_data['CHP']['alpha'], Fmax = input_data['CHP']['capacity'] /hour, fuel = input_data['CHP']['resource'], taxation = input_data['CHP']['taxation'], #ska vara taxation här men fick inte rätt då investment_cost = self.annuity(parameters['interest_rate'], input_data['CHP']['lifespan'], input_data['CHP']['investment_cost']) / (input_data['CHP']['max_capacity'] if input_data['CHP']['max_capacity'] else 1), max_capacity = input_data['CHP']['max_capacity'] ) ) if '2050' in year: if 'Trade_off' in scenario: parts.add( pl.LinearCHP( name = input_data['CHP invest']['name'], eta = input_data['CHP invest']['eta'], alpha = input_data['CHP invest']['alpha'], Fmax = input_data['CHP invest']['capacity'] /hour, max_capacity = input_data['CHP invest']['max_capacity']/hour, fuel = input_data['CHP invest']['resource'], taxation = input_data['CHP invest']['taxation'], #ska vara taxation här men fick inte rätt då investment_cost = self.annuity(parameters['interest_rate'], input_data['CHP invest']['lifespan'], input_data['CHP invest']['investment_cost']))) parts.add( pl.SolarPV( name = input_data['SolarPV']['name'], G = solar_data['Mean Irradiance [W/m2]'], T = solar_data['Mean temperature [C]'], max_capacity = None if input_data['SolarPV']['max_capacity'] is None else float(input_data['SolarPV']['max_capacity']), capacity = input_data['SolarPV']['capacity']/hour, #Eller capacity borde väl inte anges för investment option taxation = input_data['SolarPV']['taxation'], investment_cost = self.annuity(parameters['interest_rate'], input_data['SolarPV']['lifespan'], input_data['SolarPV']['investment_cost']))) if '2050' in year: parts.add( pl.Accumulator( name = input_data['Accumulator']['name'], resource = input_data['Accumulator']['resource'], max_flow = input_data['Accumulator']['max_flow']/hour, max_energy = input_data['Accumulator']['max_energy'], loss_factor = input_data['Accumulator']['loss_factor']/hour, max_capacity = input_data['Accumulator']['max_capacity'], investment_cost = self.annuity(parameters['interest_rate'], input_data['Accumulator']['lifespan'], input_data['Accumulator']['investment_cost']), t_start = parameters['t_start'], t_end = parameters['t_end'])) timeindependent_constraint = [] if 'Trade_off_CO2' in scenario: timeindependent_constraint = [CO2_maximum] #, renovation_const, renovation_const_2] elif 'Trade_off' in scenario: timeindependent_constraint = [] # ,renovation_const, renovation_const_2] #!AK else: timeindependent_constraint = [] return parts, timeindependent_constraint
def __init__(self, start_steps=None, fuel=None, alpha=None, eta=None, capacity=None, Fmin=None, Fmax=None, max_capacity=None, taxation=None, investment_cost=None, **kwargs): super().__init__(**kwargs) mode_names = ('off', 'starting', 'on') with fs.namespace(self): modes = OrderedDict( (n, fs.VariableCollection(name=n, domain=fs.Domain.binary)) for n in mode_names) F_on = fs.VariableCollection(lb=0, name='F_on') # Fuel use if on inv = fs.Variable(domain=fs.Domain.binary) self.test = { 'start_steps': start_steps, 'fuel': fuel, 'alpha': alpha, 'eta': eta, 'capacity': capacity, 'Fmin': Fmin, 'Fmax': Fmax, 'max_capacity': max_capacity, 'taxation': taxation, 'investment_cost': investment_cost } self.inv = inv self.modes = modes if max_capacity: self.max_capacity = max_capacity Fmin = 0.2 * max_capacity * (1 + alpha) / eta Fmax = max_capacity * (1 + alpha) / eta self.investment_cost = inv * investment_cost self.constraints += self.max_production self.static_variables = {inv} elif capacity: Fmin = 0.2 * capacity * (1 + alpha) / eta Fmax = capacity * (1 + alpha) / eta self.static_variables = {} self.investment_cost = investment_cost else: self.static_variables = {} self.investment_cost = investment_cost self.consumption[fuel] = lambda t: F_on(t) + modes['starting'](t ) * Fmin self.production[Resources.heat] = lambda t: F_on(t) * eta / (alpha + 1) self.production[Resources.power] = lambda t: alpha * self.production[ Resources.heat](t) self.cost = lambda t: self.consumption[fuel]( t) * 0 #_CHP_cost_func(self, taxation, fuel) on_or_starting = lambda t: modes['on'](t) + modes['starting'](t) def mode_constraints(t): """ Yields mode constraints, if 'start_steps' is provided as 'n' the unit will have to be 'starting' for 'n' time indices and can be turned to 'on' in the n+1 time index """ yield Constraint(fs.Eq(fs.Sum(m(t) for m in modes.values()), 1), desc='Exactly one mode at a time') if start_steps: recent_sum = fs.Sum( on_or_starting(tau) for tau in self.iter_times(t, -(start_steps), 0)) yield Constraint( modes['on'](t) <= recent_sum / (start_steps), desc= "'on' mode is only allowed after start_steps in 'on' and 'starting'" ) yield Constraint( self.consumption[fuel](t) <= Fmax * modes['on'](t) + Fmin * modes['starting'](t), desc='Max fuel use when on or starting') yield Constraint( self.consumption[fuel](t) >= Fmin * modes['on'](t), desc='Min fuel use when on') self.constraints += mode_constraints self.state_variables = lambda t: {F_on( t)} | {var(t) for var in modes.values()}
def non_callable_constraint(): cl = Cluster(resource=RESOURCE) cl.constraints += fs.Variable() == 3