Skip to content

Commit

Permalink
Wording and minor code refactoring on demo_agc
Browse files Browse the repository at this point in the history
  • Loading branch information
jinningwang committed Mar 6, 2024
1 parent ff153af commit bd6a073
Showing 1 changed file with 49 additions and 39 deletions.
88 changes: 49 additions & 39 deletions examples/demonstration/demo_AGC.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Reset matplotlib style to default."
]
},
{
"cell_type": "code",
"execution_count": 2,
Expand All @@ -51,6 +58,13 @@
"matplotlib.rcdefaults()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ensure in-line plots."
]
},
{
"cell_type": "code",
"execution_count": 3,
Expand All @@ -69,9 +83,9 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Last run time: 2024-03-05 21:24:59\n",
"Last run time: 2024-03-06 07:09:26\n",
"andes:1.9.1\n",
"ams:0.9.2.post8+g285882c\n"
"ams:0.9.2.post11.dev0+gff153af\n"
]
}
],
Expand Down Expand Up @@ -119,10 +133,10 @@
"output_type": "stream",
"text": [
"Parsing input file \"/Users/jinningwang/Documents/work/ams/ams/cases/ieee39/ieee39_uced.xlsx\"...\n",
"Input file parsed in 0.2186 seconds.\n",
"Input file parsed in 0.2026 seconds.\n",
"Zero line rates detacted in rate_a, rate_b, rate_c, adjusted to 999.\n",
"If expect a line outage, please set 'u' to 0.\n",
"System set up in 0.0065 seconds.\n"
"System set up in 0.0022 seconds.\n"
]
}
],
Expand Down Expand Up @@ -202,9 +216,9 @@
"text": [
"Parsing additional file \"/Users/jinningwang/Documents/work/mambaforge/envs/ams/lib/python3.9/site-packages/andes/cases/ieee39/ieee39_full.xlsx\"...\n",
"Following PFlow models in addfile will be overwritten: <Bus>, <PQ>, <PV>, <Slack>, <Shunt>, <Line>, <Area>\n",
"Addfile parsed in 0.0748 seconds.\n",
"System converted to ANDES in 0.1898 seconds.\n",
"AMS system 0x1606db880 is linked to the ANDES system 0x16cfc3820.\n"
"Addfile parsed in 0.0724 seconds.\n",
"System converted to ANDES in 0.1613 seconds.\n",
"AMS system 0x162a49910 is linked to the ANDES system 0x162a5d760.\n"
]
}
],
Expand Down Expand Up @@ -313,7 +327,7 @@
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x16de3aa30>"
"<matplotlib.legend.Legend at 0x177d79fd0>"
]
},
"execution_count": 12,
Expand Down Expand Up @@ -472,13 +486,12 @@
"pq_idx = sp.PQ.idx.v # PQ index\n",
"\n",
"# get a copy of link table\n",
"maptab = sp.dyn.link.copy()\n",
"maptab.fillna(False, inplace=True)\n",
"maptab = sp.dyn.link.copy().fillna(False)\n",
"\n",
"# existence of each type of generator\n",
"maptab['has_gov'] = maptab['gov_idx'].fillna(0, inplace=False).astype(bool).astype(int)\n",
"maptab['has_dg'] = maptab['dg_idx'].fillna(0, inplace=False).astype(bool).astype(int)\n",
"maptab['has_rg'] = maptab['rg_idx'].fillna(0, inplace=False).astype(bool).astype(int)\n",
"maptab['has_gov'] = maptab['gov_idx'].notna().astype(int)\n",
"maptab['has_dg'] = maptab['dg_idx'].notna().astype(int)\n",
"maptab['has_rg'] = maptab['rg_idx'].notna().astype(int)\n",
"\n",
"# initialize columns for power output\n",
"# pg: StaticGen power; pru: RegUp power; prd: RegDn power\n",
Expand Down Expand Up @@ -509,9 +522,9 @@
"output_type": "stream",
"text": [
"<RTED> reinit OModel due to non-parametric change.\n",
"<RTED> initialized in 0.0003 seconds.\n",
"<RTED> solved as optimal in 0.0186 seconds, converged in 12 iterations with ECOS.\n",
"<ACOPF> initialized in 0.0028 seconds.\n"
"<RTED> initialized in 0.0000 seconds.\n",
"<RTED> solved as optimal in 0.0214 seconds, converged in 12 iterations with ECOS.\n",
"<ACOPF> initialized in 0.0027 seconds.\n"
]
},
{
Expand All @@ -526,7 +539,7 @@
"name": "stderr",
"output_type": "stream",
"text": [
"<ACOPF> solved in 0.3850 seconds, converged in 18 iterations with PYPOWER-PIPS.\n",
"<ACOPF> solved in 0.3588 seconds, converged in 18 iterations with PYPOWER-PIPS.\n",
"<RTED> converted to AC.\n"
]
},
Expand All @@ -552,7 +565,7 @@
"Please update <RTED> parameters: ['pg0']\n",
"<RTED> reinit OModel due to non-parametric change.\n",
"<RTED> initialized in 0.0000 seconds.\n",
"<RTED> solved as optimal in 0.0184 seconds, converged in 12 iterations with ECOS.\n"
"<RTED> solved as optimal in 0.0185 seconds, converged in 12 iterations with ECOS.\n"
]
},
{
Expand All @@ -568,7 +581,7 @@
"name": "stderr",
"output_type": "stream",
"text": [
"<ACOPF> solved in 0.3569 seconds, converged in 18 iterations with PYPOWER-PIPS.\n",
"<ACOPF> solved in 0.3645 seconds, converged in 18 iterations with PYPOWER-PIPS.\n",
"<RTED> converted to AC.\n"
]
},
Expand Down Expand Up @@ -610,7 +623,7 @@
"name": "stderr",
"output_type": "stream",
"text": [
"<ACOPF> solved in 0.3499 seconds, converged in 18 iterations with PYPOWER-PIPS.\n",
"<ACOPF> solved in 0.3470 seconds, converged in 18 iterations with PYPOWER-PIPS.\n",
"<RTED> converted to AC.\n"
]
},
Expand Down Expand Up @@ -684,22 +697,22 @@
" # set into governor, Exclude NaN values for governor index\n",
" gov_to_set = {gov: pgov for gov, pgov in zip(maptab['gov_idx'], maptab['pgov']) if bool(gov)}\n",
" sa.TurbineGov.set(src='pref0', attr='v',\n",
" idx=list(gov_to_set.keys()),\n",
" value=list(gov_to_set.values()))\n",
" idx=list(gov_to_set.keys()),\n",
" value=list(gov_to_set.values()))\n",
" print(f\"--ANDES: update TurbineGov reference.\")\n",
"\n",
" # set into dg, Exclude NaN values for dg index\n",
" dg_to_set = { dg: pdg for dg, pdg in zip(maptab['dg_idx'], maptab['pdg']) if bool(dg)}\n",
" dg_to_set = {dg: pdg for dg, pdg in zip(maptab['dg_idx'], maptab['pdg']) if bool(dg)}\n",
" sa.DG.set(src='pref0', attr='v',\n",
" idx=list(dg_to_set.keys()),\n",
" value=list(dg_to_set.values()))\n",
" idx=list(dg_to_set.keys()),\n",
" value=list(dg_to_set.values()))\n",
" print(f\"--ANDES: update DG reference.\")\n",
"\n",
" # set into rg, Exclude NaN values for rg index\n",
" rg_to_set = {rg: prg for rg, prg in zip(maptab['rg_idx'], maptab['prg']) if bool(rg)}\n",
" sa.RenGen.set(src='Pref', attr='v',\n",
" idx=list(rg_to_set.keys()),\n",
" value=list(rg_to_set.values()))\n",
" idx=list(rg_to_set.keys()),\n",
" value=list(rg_to_set.values()))\n",
" print(f\"--ANDES: update RenGen reference.\")\n",
" else:\n",
" print(f\"ERROR! {sp.recent.class_name} failed: {sp.RTED.om.prob.status}\")\n",
Expand Down Expand Up @@ -734,7 +747,8 @@
" value=list(adg_to_set.values()))\n",
"\n",
" # set into rg, Exclude NaN values for rg index\n",
" arg_to_set = {rg: arg + prg for rg, arg, prg in zip(maptab['rg_idx'], maptab['arg'], maptab['prg']) if bool(rg)}\n",
" arg_to_set = {rg: arg + prg for rg, arg,\n",
" prg in zip(maptab['rg_idx'], maptab['arg'], maptab['prg']) if bool(rg)}\n",
" sa.RenGen.set(src='Pref', attr='v',\n",
" idx=list(arg_to_set.keys()),\n",
" value=list(arg_to_set.values()))\n",
Expand Down Expand Up @@ -873,22 +887,18 @@
"source": [
"## Settings to Improve Performance\n",
"\n",
"Long-term dynamic simualtion can be memory-consuming, as time-series data is updated by default.\n",
"To reduce the memory burden, we can set the TDS config `save_every=0`, to discard all data immediately after each simulation step.\n",
"As the trade-off, a separate output array is used to store the data, with resolution of co-sim time step.\n",
"Long-term dynamic simulation can be memory-consuming, as time-series data is updated by default. To reduce the memory burden, we can configure the TDS with `save_every=0`, discarding all data immediately after each simulation step. As a trade-off, a separate output array is utilized to store the data, with a resolution matching the co-simulation time step.\n",
"More details about ANDES settings can be found in the [ANDES Release notes - v1.7.0](https://docs.andes.app/en/latest/release-notes.html#v1-7-0-2022-05-22).\n",
"\n",
"The case is tested with complete 3600s. However, to save CI resources, the simualted time is cut for demonstration.\n",
"The case has been tested with a complete 3600s duration. However, for demonstration purposes and to conserve CI resources, the simulated time is truncated.\n",
"\n",
"## Limitations\n",
"\n",
"1. Although the code is designed to be generalized, the demo is implemented on IEEE 39-bus case with generators to be synchronous machine and the application to other cases is not fully tested.\n",
"1. In ANDES, ``SynGen.ra`` is set to zero to ignore the power loss in the generator.\n",
"The load curve is synthetic by experience.\n",
"1. The equation-based PI controller is updated every co-sim time step.\n",
"1. In intra-interval, generator setpoints are updated one time, where smooth action is not considered.\n",
"1. In ANDES, some dynamic parameters are revised to unclog the co-sim while ignoring the actual physical meaning.\n",
"1. The case used contains synchronous generators only, where further adaptation is needed for including renewable energy sources.\n",
"1. Although the code is designed for generalization, the demo is implemented on the IEEE 39-bus case with generators set to synchronous machines, and its application to other cases is not fully tested.\n",
"1. The load curve is synthetic, based on experience.\n",
"1. Within each interval, generator setpoints are updated only once, without considering smooth action.\n",
"1. In ANDES, certain dynamic parameters are adjusted to facilitate co-simulation, disregarding their actual physical implications.\n",
"1. The used case comprises synchronous generators exclusively, necessitating further adaptation for the inclusion of renewable energy sources.\n",
"\n",
"## FAQ\n",
"\n",
Expand Down

0 comments on commit bd6a073

Please sign in to comment.