def shed(self, time, scenario=None, evaluate=False): Pused = self.power(time, scenario=scenario) Pavail = self.power_available(time, scenario=scenario) if evaluate: Pused = value(Pused) Pavail = value(Pavail) return Pavail - Pused
def visualization(self, filename=None): '''power flow visualization''' if not do_plotting: return try: import networkx as nx except ImportError: logging.warning("Could'nt import networkx -- skipping plotting.") return buses, lines, t = self.buses, self.lines, self.times[0] G = nx.DiGraph() for bus in buses: Pinj = value(bus.Pgen(t)) - value(bus.Pload(t)) G.add_node(bus.name, Pinj=Pinj) for line in lines: P = value(line.power(t)) if P >= 0: G.add_edge(line.frombus, line.tobus, P=P, Plim=line.pmax) else: G.add_edge(line.tobus, line.frombus, P=-P, Plim=-line.pmin) pos = nx.spectral_layout(G) Pinj = [ ndata['Pinj'] for bus, ndata in G.nodes(data=True) if 'Pinj' in ndata ] nx.draw(G, node_color=Pinj, pos=pos, node_size=1500, alpha=.7, cmap=plot.cm.get_cmap('RdYlBu'), fontsize=30) # TODO: get colorbar label working again # ax = plot.gca() # cb = plot.colorbar(ax=ax, shrink=.8) # cb.set_label('injected power [MW]', fontsize=15) Plines = [ edata['P'] for _, t, edata in G.edges(data=True) if 'P' in edata ] atLimLines = [(f, t) for f, t, edata in G.edges(data=True) if within(edata['P'], val=edata['Plim'], eps=1e-3)] nx.draw_networkx_edges(G, edge_color='0.6', pos=pos, width=Plines, alpha=0.5) nx.draw_networkx_edges(G, edgelist=atLimLines, edge_color='r', pos=pos, width=Plines, alpha=0.5) self.savevisualization(full_filename('powerflow.png'))
def output_incremental(self, input_var): input_val = value(input_var) if self.is_pwl: for A, B in pairwise(self.bid_points): if A[0] <= input_val <= B[0]: return get_line_slope(A, B) else: return polynomial_incremental_value(self.polynomial, value(input_var))
def get_values(self, items, method='power', time=None, evaluate=False): '''Get the attributes of all objects of a certain kind at a given time.''' if time: if evaluate: out = [value(getattr( obj, method)(time, evaluate=True)) for obj in items] else: out = [value(getattr(obj, method)(time)) for obj in items] else: out = [value(getattr(obj, method)) for obj in items] return out
def gen_time_df(self, method, scenario, non_overlap=True, evaluate=False, generators=None): if generators is None: generators = self.generators if evaluate: getval = lambda gen, t: value( getattr(gen, method)(t, scenario, evaluate=True)) else: getval = lambda gen, t: value(getattr(gen, method)(t, scenario)) times = self.times_non_overlap if non_overlap else self.times return gen_time_dataframe(generators, times, [[getval(gen, t) for t in times] for gen in generators])
def cost_shutdown(self, time, scenario=None, evaluate=False): if self.shutdowncost == 0 or not self.commitment_problem: return 0 else: c = self.get_variable( 'shutdowncost', time, scenario=scenario, indexed=True) return c if not evaluate else value(c)
def _get_problem_info(self): self.solve_time = self.power_system.solution_time self.objective = float(value(self.power_system.objective)) try: self.mipgap = self.power_system.mipgap except AttributeError: self.mipgap = None
def power(self, time, scenario=None, evaluate=False): if self.shedding_mode: power = self.get_variable("power", time, scenario=scenario, indexed=True) if evaluate: power = value(power) return power else: return self.get_scheduled_output(time)
def power(self, time, scenario=None, evaluate=False): if self.shedding_mode: power = self.get_variable('power', time, scenario=scenario, indexed=True) if evaluate: power = value(power) return power else: return self.get_scheduled_output(time)
def get_line_value(A, B, x): ''' take a pair of points and make a linear function get the value of the function at x see http://bit.ly/Pd4z4l ''' xA, yA = A slope = get_line_slope(A, B) return slope * (value(x) - xA) + yA
def visualization(self, filename=None): '''power flow visualization''' if not do_plotting: return try: import networkx as nx except ImportError: logging.warning("Could'nt import networkx -- skipping plotting.") return buses, lines, t = self.buses, self.lines, self.times[0] G = nx.DiGraph() for bus in buses: Pinj = value(bus.Pgen(t)) - value(bus.Pload(t)) G.add_node(bus.name, Pinj=Pinj) for line in lines: P = value(line.power(t)) if P >= 0: G.add_edge(line.frombus, line.tobus, P=P, Plim=line.pmax) else: G.add_edge(line.tobus, line.frombus, P=-P, Plim=-line.pmin) pos = nx.spectral_layout(G) Pinj = [ndata['Pinj'] for bus, ndata in G.nodes(data=True) if 'Pinj' in ndata] nx.draw(G, node_color=Pinj, pos=pos, node_size=1500, alpha=.7, cmap=plot.cm.get_cmap('RdYlBu'), fontsize=30) # TODO: get colorbar label working again # ax = plot.gca() # cb = plot.colorbar(ax=ax, shrink=.8) # cb.set_label('injected power [MW]', fontsize=15) Plines = [edata['P'] for _, t, edata in G.edges(data=True) if 'P' in edata] atLimLines = [(f, t) for f, t, edata in G.edges( data=True) if within(edata['P'], val=edata['Plim'], eps=1e-3)] nx.draw_networkx_edges( G, edge_color='0.6', pos=pos, width=Plines, alpha=0.5) nx.draw_networkx_edges(G, edgelist=atLimLines, edge_color='r', pos=pos, width=Plines, alpha=0.5) self.savevisualization(full_filename('powerflow.png'))
def output(self, time=None, scenario=None, evaluate=False): status = self.status_variable(time, scenario) power = self.input_variable(time, scenario) if evaluate: status = value(status) power = value(power) if self.is_linear: out = self.polynomial[1] * power else: out = self.get_variable('cost', time=time, scenario=scenario, indexed=True) if evaluate: out = value(out) if self.constant_term != 0: out += status * self.constant_term return out
def stg_panel(self, method, generators=None, no_overlap=True, evaluate=False): if generators is None: generators = self.generators times = self.times_non_overlap if no_overlap else self.times if evaluate: getval = lambda s, gen, t: value( getattr(gen, method)(t, s, evaluate=True)) else: getval = lambda s, gen, t: value(getattr(gen, method)(t, s)) return pd.Panel( [[[getval(s, gen, t) for gen in generators] for t in times] for s in self.scenarios], items=[s for s in self.scenarios], major_axis=times.strings.index, minor_axis=[str(g) for g in generators])
def output_true(self, input_var, force_linear=False): '''true output value of bid''' input_val = value(input_var) if (self.is_pwl or force_linear) and not self.is_linear: if not self.is_pwl and self.bid_points is None: # construct the bid points bid_pt_outputs = map(lambda pt: polynomial_value( self.polynomial, pt), self.discrete_input_points) self.bid_points = zip( self.discrete_input_points, bid_pt_outputs) for A, B in pairwise(self.bid_points.values.tolist()): if A[0] <= input_val <= B[0]: return get_line_value(A, B, input_val) + self.constant_term else: return polynomial_value(self.polynomial, input_val)
def visualization(self, show_cost_also=False): ''' economic dispatch visualization of linearized incremental cost''' if not do_plotting: return t = self.times[0] price = self.lmps[str(t)][0] generators = self.generators loads = self.loads plotted_gens, names_gens, plotted_loads, names_loads = [], [], [], [] minGen = min(getattrL(generators, 'pmin')) maxGen = max(getattrL(generators, 'pmax')) # save a plot of the price space - illustrating equal IC ax = plot.axes() for gen in generators: if gen.status(t): in_range, out_range = gen.bids.output_incremental_range() if gen.bids.is_pwl: line, = plot.step( in_range, out_range, where='pre', linestyle='-') else: line, = plot.plot(in_range, out_range, linestyle='-', ) plotted_gens.append(line) P = value(gen.power(t)) IC = gen.incrementalcost(t) plot.plot(P, IC, '.', c=line.get_color( ), markersize=8, linewidth=2, alpha=0.7) names_gens.append(gen.name) if price is not None: grayColor = '.75' plot.plot([minGen, maxGen], [price, price], '--k', color=grayColor) plot.text(maxGen, price, '{p:0.2f} $/MWh'.format( p=price), color=grayColor, horizontalalignment='right') plot.xlabel('P [MWh]') if plotted_loads: plot.ylabel('Marginal Cost-Benifit [$/MWh]') else: plot.ylabel('Marginal Cost [$/MWh]') prettify_axes(ax) # plot.xlim(xmin=0,xmax=) ymin, _ = plot.ylim() if ymin < 0: plot.ylim(ymin=0) legendGens = plot.legend(plotted_gens, names_gens, fancybox=True, title='Generators:', loc='best') if plotted_loads: plot.legend(plotted_loads, names_loads, fancybox=True, title='Loads:', loc='best') # add first legend to the axes manually bcs multiple legends get overwritten plot.gca().add_artist(legendGens) self.savevisualization(filename=full_filename('dispatch.png')) if show_cost_also: # show a plot of the cost space, illustrating the linearization plot.figure() gensPlotted_price = plotted_gens plotted_gens, names_gens, plotted_loads, names_loads = [ ], [], [], [] for g, gen in enumerate(generators): if gen.status(t): plotted_gens.append(gen.cost_model.plot( P=value(gen.power(t)), linestyle='-', color=gensPlotted_price[g].get_color() )) names_gens.append(gen.name) for load in loads: if load.kind == 'bidding': plotted_loads.append(load.bid( t).plot(P=value(load.power(t)), linestyle=':')) names_loads.append(load.name) plot.xlabel('P [MWh]') if plotted_loads: plot.ylabel('Cost-Benifit [$/h]') else: plot.ylabel('Cost [$/h]') legendGens = plot.legend(plotted_gens, names_gens, fancybox=True, title='Generators:', loc='best') if plotted_loads: plot.legend(plotted_loads, names_loads, fancybox=True, title='Loads:', loc='best') plot.gca().add_artist(legendGens) # add first legend to the axes manually bcs multiple legends get overwritten self.savevisualization(filename=full_filename('dispatch-cost.png'))
def getstatus(self, tend, times, status): return dict( status=value(self.status(tend)), power=value(self.power(tend)), hoursinstatus=self.gethrsinstatus(times, status))
def incrementalcost(self, time, scenario=None): '''change in cost with change in power at time (based on exact bid polynomial).''' return self.bids.output_incremental(self.power(time, scenario)) if value(self.status(time, scenario)) else None
def getstatus(self, tend, times, status): return dict(status=value(self.status(tend)), power=value(self.power(tend)), hoursinstatus=self.gethrsinstatus(times, status))
def truecost(self, time, scenario=None): '''exact cost of real power production at time (based on exact bid polynomial).''' return value(self.status(time, scenario)) * self.bids.output_true( self.power(time, scenario))
def Pload(self, t, evaluate=False): if evaluate: return sum(value(ld.power(t)) for ld in self.loads) else: return sum(ld.power(t) for ld in self.loads)
def truecost(self, time, scenario=None): '''exact cost of real power production at time (based on exact bid polynomial).''' return value(self.status(time, scenario)) * self.bids.output_true(self.power(time, scenario))
def Pgen(self, t, evaluate=False): if evaluate: return sum(value(gen.power(t)) for gen in self.generators) else: return sum(gen.power(t) for gen in self.generators)
def incrementalcost(self, time, scenario=None): '''change in cost with change in power at time (based on exact bid polynomial).''' return self.bids.output_incremental(self.power( time, scenario)) if value(self.status(time, scenario)) else None