class MultistageStandalone(Solution_UC_multistage): def __init__(self, power_system, stage_times, store): self.power_system = power_system self.is_stochastic = power_system.is_stochastic self._resolved = self.is_stochastic or \ user_config.deterministic_solve or user_config.perfect_solve times = pd.concat( [times.non_overlap().strings for times in stage_times]).index self.times = TimeIndex(times) self.times.set_initial(stage_times[0].initialTime) self.expected_cost = self.totalcost_generation = store['expected_cost'] if self._resolved: self.observed_cost = self.totalcost_generation = \ store['observed_cost'] self.generators_power = store['power'] self.generators_status = store['status'] self.load_shed_timeseries = store['load_shed'] self.gen_shed_timeseries = store['gen_shed'] self.load_shed = store['load_shed'].sum() self.gen_shed = store['gen_shed'].sum() self.solve_time = store['solve_time'].sum()
class Solution_UC_multistage(Solution_UC): ''' Muti-stage unit commitment. Each stage represents one optimization problem. Each element of the list :param:stage_solutions is a :class:`~results.Solution_UC` object. ''' def __init__(self, power_system, stage_times, stage_solutions): update_attributes(self, locals(), exclude=['stage_solutions', 'stage_times']) self._resolved = power_system.is_stochastic \ or user_config.deterministic_solve or user_config.perfect_solve self.is_stochastic = any(sln.is_stochastic for sln in stage_solutions) times = pd.concat( [times.non_overlap().strings for times in stage_times]).index self.times = TimeIndex(times) self.times.set_initial(stage_times[0].initialTime) self.objective = self._sum_over('objective', stage_solutions) self.solve_time = self._sum_over('solve_time', stage_solutions) self.mipgaps = pd.Series([sln.mipgap for sln in stage_solutions]) self._get_outputs(stage_solutions) self._get_costs(stage_solutions) self._get_prices(stage_solutions) def _sum_over(self, attrib, stage_solutions): return sum(getattr(sln, attrib) for sln in stage_solutions) def _concat(self, attrib, slns): return pd.concat([getattr(sln, attrib) for sln in slns]) def _get_outputs(self, slns): '''the outputs under observed wind''' self.generators_power = self._concat('generators_power', slns) self.generators_status = self._concat('generators_status', slns) if self._resolved: self.expected_power = self._concat('expected_power', slns) self.expected_status = self._concat('expected_status', slns) def _get_costs(self, slns): self.expected_cost = self.totalcost_generation = \ self._concat('expected_totalcost' if self._resolved else 'totalcost_generation', slns) self.load_shed_timeseries = self._concat('load_shed_timeseries', slns) self.gen_shed_timeseries = self._concat('gen_shed_timeseries', slns) self.load_shed = self.load_shed_timeseries.sum() self.gen_shed = self.gen_shed_timeseries.sum() if self._resolved: self.observed_cost = self.totalcost_generation = \ self._concat('observed_totalcost', slns) def info_cost(self): resolved = self._resolved expected = 'expected ' if resolved else '' observed = 'observed ' if resolved else '' out = [] out.append('total {}generation cost = {}'.format( expected, self.expected_cost.sum().sum())) if resolved: out.append('total {}generation cost = {}'.format( observed, self.observed_cost.sum().sum())) return out def _get_prices(self, stage_solutions): self.lmps = {} try: for stage in stage_solutions: self.lmps.update(stage.lmps) except: # no lmps in stochastic solutions right now pass def show(self): out = [] out.extend(self.info_status()) out.extend(self.info_cost()) out.extend(self.info_shedding()) print '\n'.join(out) def info_generators(self): return [] def info_loads(self): return [] def info_status(self): return ['solved multistage problem in a total solver time ' + 'of {time:0.4f} sec'.format(time=self.solve_time)] def info_shedding(self): return [ 'total load shed={}MW'.format(self.load_shed) if self.load_shed > 0.01 else '', 'total gen shed={}MW'.format(self.gen_shed) if self.gen_shed > 0.01 else '', ]