From bd6a073cfb8d55d960980779a0d48faa3a336231 Mon Sep 17 00:00:00 2001 From: jinningwang Date: Wed, 6 Mar 2024 07:10:29 -0500 Subject: [PATCH] Wording and minor code refactoring on demo_agc --- examples/demonstration/demo_AGC.ipynb | 88 +++++++++++++++------------ 1 file changed, 49 insertions(+), 39 deletions(-) diff --git a/examples/demonstration/demo_AGC.ipynb b/examples/demonstration/demo_AGC.ipynb index b4f6bce8..7e451642 100644 --- a/examples/demonstration/demo_AGC.ipynb +++ b/examples/demonstration/demo_AGC.ipynb @@ -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, @@ -51,6 +58,13 @@ "matplotlib.rcdefaults()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ensure in-line plots." + ] + }, { "cell_type": "code", "execution_count": 3, @@ -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" ] } ], @@ -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" ] } ], @@ -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: , , , , , , \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" ] } ], @@ -313,7 +327,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 12, @@ -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", @@ -509,9 +522,9 @@ "output_type": "stream", "text": [ " reinit OModel due to non-parametric change.\n", - " initialized in 0.0003 seconds.\n", - " solved as optimal in 0.0186 seconds, converged in 12 iterations with ECOS.\n", - " initialized in 0.0028 seconds.\n" + " initialized in 0.0000 seconds.\n", + " solved as optimal in 0.0214 seconds, converged in 12 iterations with ECOS.\n", + " initialized in 0.0027 seconds.\n" ] }, { @@ -526,7 +539,7 @@ "name": "stderr", "output_type": "stream", "text": [ - " solved in 0.3850 seconds, converged in 18 iterations with PYPOWER-PIPS.\n", + " solved in 0.3588 seconds, converged in 18 iterations with PYPOWER-PIPS.\n", " converted to AC.\n" ] }, @@ -552,7 +565,7 @@ "Please update parameters: ['pg0']\n", " reinit OModel due to non-parametric change.\n", " initialized in 0.0000 seconds.\n", - " solved as optimal in 0.0184 seconds, converged in 12 iterations with ECOS.\n" + " solved as optimal in 0.0185 seconds, converged in 12 iterations with ECOS.\n" ] }, { @@ -568,7 +581,7 @@ "name": "stderr", "output_type": "stream", "text": [ - " solved in 0.3569 seconds, converged in 18 iterations with PYPOWER-PIPS.\n", + " solved in 0.3645 seconds, converged in 18 iterations with PYPOWER-PIPS.\n", " converted to AC.\n" ] }, @@ -610,7 +623,7 @@ "name": "stderr", "output_type": "stream", "text": [ - " solved in 0.3499 seconds, converged in 18 iterations with PYPOWER-PIPS.\n", + " solved in 0.3470 seconds, converged in 18 iterations with PYPOWER-PIPS.\n", " converted to AC.\n" ] }, @@ -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", @@ -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", @@ -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",