From 97e65068dfbdc48ec656f59b9ce4ce22ba8a424a Mon Sep 17 00:00:00 2001 From: jinningwang Date: Fri, 12 Apr 2024 12:24:03 -0400 Subject: [PATCH 1/4] Fix _csv_step to fit selected output file --- andes/routines/tds.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/andes/routines/tds.py b/andes/routines/tds.py index 2c937dd7a..d72131cd7 100644 --- a/andes/routines/tds.py +++ b/andes/routines/tds.py @@ -537,12 +537,23 @@ def itm_step(self): def _csv_step(self): """ Fetch data for the next step from ``data_csv``. + + When `Output` exists, the target variables `x` and `y` are filled with the data, + while the remaining variables are set to zero. """ system = self.system if self.data_csv is not None: - system.dae.x[:] = self.data_csv[self.k_csv, 1:system.dae.n + 1] - system.dae.y[:] = self.data_csv[self.k_csv, system.dae.n + 1:system.dae.n + system.dae.m + 1] + if system.Output.n < 1: + system.dae.x[:] = self.data_csv[self.k_csv, 1:system.dae.n + 1] + system.dae.y[:] = self.data_csv[self.k_csv, system.dae.n + 1:system.dae.n + system.dae.m + 1] + else: + xyidx = system.Output.xidx + [yidx+system.dae.n for yidx in system.Output.yidx] + _xy = np.zeros(system.dae.n + system.dae.m) + _xy[xyidx] = self.data_csv[self.k_csv, 1:] + system.dae.x[:] = _xy[:system.dae.n] + system.dae.y[:] = _xy[system.dae.n:] + system.vars_to_models() self.converged = True @@ -926,8 +937,14 @@ def _load_csv(self, csv_file): if data.shape[0] < 2: logger.warning("CSV data does not contain more than one time step.") if data.shape[1] < (self.system.dae.m + self.system.dae.n): - logger.warning("CSV data contains fewer variables than required.") - logger.warning("Check if the CSV data file is generated from the test case.") + if self.system.Output.n < 1: + logger.warning("CSV data contains fewer variables than required.") + logger.warning("Check if the CSV data file is generated from the test case.") + else: + logger.info("Output selection detected.") + if data.shape[1] - 1 < (len(self.system.Output.xidx + self.system.Output.yidx)): + logger.warning("CSV data contains fewer variables than required.") + logger.warning("Check if the CSV data file is generated with selected output.") # set start and end times from data self.config.t0 = data[0, 0] From 54c94e63271630b1a7ebefad30b7763949f3dcf1 Mon Sep 17 00:00:00 2001 From: jinningwang Date: Fri, 12 Apr 2024 12:36:02 -0400 Subject: [PATCH 2/4] Fix init to fit selected output file --- andes/routines/tds.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/andes/routines/tds.py b/andes/routines/tds.py index d72131cd7..c5ca28f50 100644 --- a/andes/routines/tds.py +++ b/andes/routines/tds.py @@ -237,8 +237,15 @@ def init(self): # discard initialized values and use that from CSV if provided if self.data_csv is not None: - system.dae.x[:] = self.data_csv[0, 1:system.dae.n + 1] - system.dae.y[:] = self.data_csv[0, system.dae.n + 1:system.dae.n + system.dae.m + 1] + if system.Output.n < 1: + system.dae.x[:] = self.data_csv[self.k_csv, 1:system.dae.n + 1] + system.dae.y[:] = self.data_csv[self.k_csv, system.dae.n + 1:system.dae.n + system.dae.m + 1] + else: + xyidx = system.Output.xidx + [yidx+system.dae.n for yidx in system.Output.yidx] + _xy = np.zeros(system.dae.n + system.dae.m) + _xy[xyidx] = self.data_csv[self.k_csv, 1:] + system.dae.x[:] = _xy[:system.dae.n] + system.dae.y[:] = _xy[system.dae.n:] system.vars_to_models() # connect to data streaming server From 66706bac59c7a5592ffabe5d1629160572ea51ba Mon Sep 17 00:00:00 2001 From: jinningwang Date: Fri, 12 Apr 2024 12:36:29 -0400 Subject: [PATCH 3/4] Add test to cover from_csv when Output exists --- tests/test_output.py | 54 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/test_output.py b/tests/test_output.py index fba687663..6fcc302de 100644 --- a/tests/test_output.py +++ b/tests/test_output.py @@ -1,6 +1,7 @@ """ Test output selection. """ +import os import numpy as np import unittest @@ -73,3 +74,56 @@ def test_output_xyname(self): np.testing.assert_equal( ss.dae.ts.get_data(ss.TG2.pout, a=None).shape[1], 0) + + def test_from_csv(self): + """ + Test from_csv when loading selected output from csv file. + """ + case = andes.get_case("5bus/pjm5bus.json") + ss = andes.load(case, + no_output=True, + setup=False, + default_config=True) + + ss.add("Output", {"model": "Bus", "varname": "v"}) + + ss.setup() + + ss.PFlow.run() + ss.TDS.config.tf = 0.1 + ss.TDS.run() + ss.TDS.load_plotter() + + ss.TDS.plt.export_csv("pjm5bus_selec_out.csv") + + # Test assign CSV in TDS.run() + ss2 = andes.load(case, + no_output=True, + setup=False, + default_config=True) + + ss2.add("Output", {"model": "Bus", "varname": "v"}) + + ss2.setup() + + ss2.PFlow.run() + ss2.TDS.run(from_csv="pjm5bus_selec_out.csv") + + self.assertTrue(ss2.TDS.converged) + + # Test assign CSV in andes.load() + ss3 = andes.load(case, + no_output=True, + setup=False, + default_config=True, + from_csv="pjm5bus_selec_out.csv") + ss3.add("Output", {"model": "Bus", "varname": "v"}) + + ss3.setup() + + ss3.PFlow.run() + ss3.TDS.run() + + self.assertTrue(ss3.TDS.converged) + + os.remove("pjm5bus_selec_out.csv") From 35b2a6786dbfcbc3f4dafddbc58f159387d20c7f Mon Sep 17 00:00:00 2001 From: jinningwang Date: Fri, 12 Apr 2024 12:39:03 -0400 Subject: [PATCH 4/4] Update release notes --- docs/source/release-notes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/release-notes.rst b/docs/source/release-notes.rst index ae131afad..b4defd6bc 100644 --- a/docs/source/release-notes.rst +++ b/docs/source/release-notes.rst @@ -14,6 +14,8 @@ v1.9.3 (2024-04-XX) - In symbolic processor, most variables are assumed to be real, except some services that are specified as complex. This will allow generating simplified expressions. +- Adjust `BusFreq.Tw.default` to 0.1. +- Fix `TDS.init()` and `TDS._csv_step()` to fit loading from CSV when `Output` exists. v1.9.2 (2024-03-25) -------------------