def runopp_map(ssp, link_table, **kwargs): """ Run OPF in pandapower using ``pp.runopp()`` and map results back to ANDES based on the link table. Parameters ---------- ssp : pandapower network The pandapower network link_table : DataFrame The link table of ADNES system Returns ------- DataFrame The DataFrame contains the OPF results with columns ``p_mw``, ``q_mvar``, ``vm_pu`` in p.u., and the corresponding ``idx`` of ``StaticGen``, ``Exciter``, ``TurbineGov`` in ANDES. Notes ----- - The pandapower net and the ANDES system must have same base MVA. - Multiple ``DG`` connected to the same ``StaticGen`` will be converted to one generator. The power is dispatched to each ``DG`` by the power ratio ``gammap`` """ try: pp.runopp(ssp, **kwargs) except Exception: pp.rundcopp(ssp, **kwargs) logger.warning("ACOPF failed, DCOPF is used instead.") # take dispatch results from pp ssp_gen = ssp.gen.rename(columns={'name': 'stg_idx'}) ssp_res = pd.concat( [ssp_gen[['stg_idx']], ssp.res_gen[['p_mw', 'q_mvar', 'vm_pu']]], axis=1) ssp_res = pd.merge(left=ssp_res, right=ssp_gen[['stg_idx', 'controllable']], how='left', on='stg_idx') ssp_res = pd.merge(left=ssp_res, right=link_table, how='left', on='stg_idx') ssp_res['p'] = ssp_res['p_mw'] * ssp_res['gammap'] / ssp.sn_mva ssp_res['q'] = ssp_res['q_mvar'] * ssp_res['gammaq'] / ssp.sn_mva col = [ 'stg_idx', 'p', 'q', 'vm_pu', 'bus_idx', 'controllable', 'dg_idx', 'rg_idx', 'syg_idx', 'gov_idx', 'exc_idx' ] return ssp_res[col]
def _sumPF_ppn(ppn): """Summarize PF results of a pandapower net""" rg = pd.DataFrame() rg['gen'] = ppn.res_gen['p_mw'] rg['bus'] = ppn.gen['bus'] rg = rg.groupby('bus').sum() rg.reset_index(inplace=True) rd = pd.DataFrame() rd['demand'] = ppn.res_load['p_mw'] rd['bus'] = ppn.load['bus'] rd = rd.groupby('bus').sum() rd.reset_index(inplace=True) rp = pd.DataFrame() rp['bus'] = ppn.bus.index rp = pd.merge(rp, rg, how='left', on='bus') rp = pd.merge(rp, rd, how='left', on='bus') rp.fillna(0, inplace=True) rp['ngen'] = rp['gen'] - rp['demand'] return rp
def _to_pp_gen_pre(ssa): """Create generator data in pandapower net""" # build StaticGen df stg_cols = ['idx', 'u', 'bus', 'v0', 'vmax', 'vmin'] stg_calc_cols = ['p0', 'q0', 'pmax', 'pmin', 'qmax', 'qmin'] ssa_stg = build_group_table(ssa, 'StaticGen', stg_cols + stg_calc_cols) ssa_stg['name'] = ssa_stg.idx ssa_stg.rename(inplace=True, columns={ "bus": "bus_idx", "u": "stg_u", "idx": "stg_idx" }) # retrieve Bus idx in pp net ssa_busn = ssa.Bus.as_df().copy().reset_index()[["uid", "idx" ]].rename(columns={ "uid": "pp_bus", "idx": "bus_idx" }) ssa_stg = pd.merge(ssa_stg, ssa_busn, how="left", on="bus_idx") return ssa_stg
def make_link_table(ssa): """ Build the link table for generators and generator controllers in an ADNES System, including ``SynGen`` and ``DG`` for now. Parameters ---------- ssa : andes.system.System The ADNES system to link Returns ------- DataFrame Each column in the output Dataframe contains the ``idx`` of linked ``StaticGen``, ``Bus``, ``DG``, ``SynGen``, ``Exciter``, and ``TurbineGov``, ``gammap``, ``gammaq``. """ # build StaticGen df ssa_stg = build_group_table(ssa, 'StaticGen', ['u', 'name', 'idx', 'bus']) # build TurbineGov df ssa_gov = build_group_table(ssa, 'TurbineGov', ['idx', 'syn']) # build Exciter df ssa_exc = build_group_table(ssa, 'Exciter', ['idx', 'syn']) # build SynGen df ssa_syg = build_group_table(ssa, 'SynGen', ['idx', 'bus', 'gen', 'gammap', 'gammaq'], ['GENCLS', 'GENROU']) # build DG df ssa_dg = build_group_table(ssa, 'DG', ['idx', 'bus', 'gen', 'gammap', 'gammaq']) # output ssa_bus = ssa.Bus.as_df()[['name', 'idx']] ssa_key = pd.merge( left=ssa_stg.rename(columns={ 'name': 'stg_name', 'idx': 'stg_idx', 'bus': 'bus_idx', 'u': 'stg_u' }), right=ssa_bus.rename(columns={ 'name': 'bus_name', 'idx': 'bus_idx' }), how='left', on='bus_idx') ssa_syg = pd.merge(left=ssa_key, how='right', on='stg_idx', right=ssa_syg.rename(columns={ 'idx': 'syg_idx', 'gen': 'stg_idx' })) ssa_dg = pd.merge(left=ssa_key, how='right', on='stg_idx', right=ssa_dg.rename(columns={ 'idx': 'dg_idx', 'gen': 'stg_idx' })) # TODO: Add RenGen ssa_key = pd.concat([ssa_syg, ssa_dg], axis=0) ssa_key = pd.merge(left=ssa_key, right=ssa_exc.rename(columns={ 'idx': 'exc_idx', 'syn': 'syg_idx' }), how='left', on='syg_idx') ssa_key = pd.merge(left=ssa_key, right=ssa_gov.rename(columns={ 'idx': 'gov_idx', 'syn': 'syg_idx' }), how='left', on='syg_idx') cols = [ 'stg_name', 'stg_u', 'stg_idx', 'bus_idx', 'dg_idx', 'syg_idx', 'exc_idx', 'gov_idx', 'bus_name', 'gammap', 'gammaq' ] return ssa_key[cols]
def make_link_table(ssa): """ Build the link table for generators and generator controllers in an ADNES System, including ``SynGen`` and ``DG`` for now. Parameters ---------- ssa : andes.system.System The ADNES system to link Returns ------- DataFrame Each column in the output Dataframe contains the ``idx`` of linked ``StaticGen``, ``Bus``, ``DG``, ``RenGen``, ``RenExciter``, ``SynGen``, ``Exciter``, and ``TurbineGov``, ``gammap``, ``gammaq``. """ # build StaticGen df ssa_stg = build_group_table(ssa, 'StaticGen', ['u', 'name', 'idx', 'bus']) # build TurbineGov df ssa_gov = build_group_table(ssa, 'TurbineGov', ['idx', 'syn']) # build Exciter df ssa_exc = build_group_table(ssa, 'Exciter', ['idx', 'syn']) # build SynGen df ssa_syg = build_group_table(ssa, 'SynGen', ['idx', 'bus', 'gen', 'gammap', 'gammaq'], ['GENCLS', 'GENROU']) # build DG df ssa_dg = build_group_table(ssa, 'DG', ['idx', 'bus', 'gen', 'gammap', 'gammaq']) # build RenGen df ssa_rg = build_group_table(ssa, 'RenGen', ['idx', 'bus', 'gen', 'gammap', 'gammaq']) # build RenExciter df ssa_rexc = build_group_table(ssa, 'RenExciter', ['idx', 'reg']) # output ssa_bus = ssa.Bus.as_df()[['name', 'idx']] ssa_key = pd.merge( left=ssa_stg.rename(columns={ 'name': 'stg_name', 'idx': 'stg_idx', 'bus': 'bus_idx', 'u': 'stg_u' }), right=ssa_bus.rename(columns={ 'name': 'bus_name', 'idx': 'bus_idx' }), how='left', on='bus_idx') ssa_syg = pd.merge(left=ssa_key, how='right', on='stg_idx', right=ssa_syg.rename(columns={ 'idx': 'syg_idx', 'gen': 'stg_idx' })) ssa_dg = pd.merge(left=ssa_key, how='right', on='stg_idx', right=ssa_dg.rename(columns={ 'idx': 'dg_idx', 'gen': 'stg_idx' })) ssa_rg = pd.merge(left=ssa_key, how='right', on='stg_idx', right=ssa_rg.rename(columns={ 'idx': 'rg_idx', 'gen': 'stg_idx' })) ssa_key0 = pd.merge(left=ssa_key, how='left', on='stg_idx', right=ssa_syg[['stg_idx', 'syg_idx']]) ssa_key0 = pd.merge(left=ssa_key0, how='left', on='stg_idx', right=ssa_dg[['stg_idx', 'dg_idx']]) ssa_key0 = pd.merge(left=ssa_key0, how='left', on='stg_idx', right=ssa_rg[['stg_idx', 'rg_idx']]) ssa_key0.fillna(False, inplace=True) ssa_key0['dyr'] = ssa_key0['syg_idx'].astype(bool) + ssa_key0[ 'dg_idx'].astype(bool) + ssa_key0['rg_idx'].astype(bool) ssa_key0['dyr'] = 1 - ssa_key0['dyr'].astype(int) ssa_key0['dyr'] = ssa_key0['dyr'].astype(bool) ssa_dyr0 = ssa_key0[ssa_key0.dyr].drop(['dyr'], axis=1) ssa_dyr0['gammap'] = 1 ssa_dyr0['gammaq'] = 1 ssa_key = pd.concat([ssa_syg, ssa_dg, ssa_rg, ssa_dyr0], axis=0) ssa_key = pd.merge(left=ssa_key, right=ssa_exc.rename(columns={ 'idx': 'exc_idx', 'syn': 'syg_idx' }), how='left', on='syg_idx') ssa_key = pd.merge(left=ssa_key, right=ssa_gov.rename(columns={ 'idx': 'gov_idx', 'syn': 'syg_idx' }), how='left', on='syg_idx') ssa_key = pd.merge(left=ssa_key, how='left', on='rg_idx', right=ssa_rexc.rename(columns={ 'idx': 'rexc_idx', 'reg': 'rg_idx' })) cols = [ 'stg_name', 'stg_u', 'stg_idx', 'bus_idx', 'dg_idx', 'rg_idx', 'rexc_idx', 'syg_idx', 'exc_idx', 'gov_idx', 'bus_name', 'gammap', 'gammaq' ] return ssa_key[cols].reset_index(drop=True)