Skip to content

Commit

Permalink
Fixes to support WECC 240 network solution (#285)
Browse files Browse the repository at this point in the history
Signed-off-by: David P. Chassin <david.chassin@me.com>
  • Loading branch information
dchassin committed Feb 15, 2025
1 parent d8eb126 commit a01e2ce
Show file tree
Hide file tree
Showing 22 changed files with 1,688 additions and 341 deletions.
977 changes: 697 additions & 280 deletions converters/autotest/wecc240.glm

Large diffs are not rendered by default.

77 changes: 74 additions & 3 deletions converters/raw2glm.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from importlib import util
import csv
from math import cos, sin
from collections import namedtuple

if os.path.exists("autotest/wecc240.raw") and len(sys.argv) == 1:
sys.argv.extend(["-i","autotest/wecc240.raw","-o","autotest/wecc240.glm"])
Expand Down Expand Up @@ -228,16 +229,19 @@ def convert(ifile,ofile,options={}):
genndx[genid] = genndx[genid]+1 if genid in genndx else 0
if not row[0] in busndx:
warning(f"gen '{row[0]}' not a valid bus index",ifile,lineno)
# PSSE: I,'ID', PG, QG, QT, QB, VS, IREG, MBASE, ZR, ZX, RT, XT, GTAP,STAT, RMPCT, PT, PB, O1, F1, O2, F2, O3, F3, O4, F4,WMOD, WPF,NREG
# PSSE: I,'ID', PG, QG, QT, QB, VS, IREG, MBASE, ZR, ZX, RT, XT, GTAP, STAT, RMPCT, PT, PB, O1, F1, O2, F2, O3, F3, O4, F4, WMOD, WPF, NREG
print(f"""object pypower.gen
{{
name "{oname}_G_{row[0]}_{genndx[genid]}";
bus {busndx[row[0]]};
Pg {row[2]} MW;
Qg {row[3]} MVAr;
Vg {row[6]} pu*V;
mBase {row[8]} MVA;
status IN_SERVICE;
Pmax {row[16]} MW;
Pmin {row[17]} MW;
Qmax {row[4]} MVAr;
Qmin {row[5]} MVAr;
status {"IN_SERVICE" if row[14] == "1" else "OUT_OF_SERVICE"};
{items(row)}
}}""",file=glm)

Expand Down Expand Up @@ -308,6 +312,73 @@ def convert(ifile,ofile,options={}):
}}""",file=glm)
rowd = []

elif block == "SWITCHED_SHUNT_DATA":

mapping = {
"MODSW": "control_mode",
"ADJM": None,
"ST": "status",
"VSWHI": "voltage_high",
"VSWLO": "voltage_low",
"SWREG": "remote_bus",
"RMPCT": None,
"RMIDNT": None,
"BINIT": "admittance",
"N1": "steps_1",
"B1": "admittance_1",
"N2": "steps_2",
"B2": "admittance_2",
"N3": "steps_3",
"B3": "admittance_3",
"N4": "steps_4",
"B4": "admittance_4",
"N5": "steps_5",
"B5": "admittance_5",
"N6": "steps_6",
"B6": "admittance_6",
"N7": "steps_7",
"B7": "admittance_7",
"N8": "steps_8",
"B8": "admittance_8",
"NREG": None,
}
converters = {
"remote_bus": lambda x: f'"{oname}_N_{x}"',
"control_mode": lambda x: ["FIXED","DISCRETE_V","CONTINUOUS_V","DISCRETE_VAR","DISCRETE_VSC","DISCRETE_Y"][int(x)],
"voltage_high": lambda x: f"{float(x)} pu",
"voltage_low": lambda x: f"{float(x)} pu",
"status": lambda x: ["OFFLINE","ONLINE"][int(x)],
"admittance": lambda x: f"{float(x)} MVAr",
"steps_1" : int,
"admittance_1": lambda x: f"{float(x)} MVAr",
"steps_2" : int,
"admittance_2": lambda x: f"{float(x)} MVAr",
"steps_3" : int,
"admittance_3": lambda x: f"{float(x)} MVAr",
"steps_4" : int,
"admittance_4": lambda x: f"{float(x)} MVAr",
"steps_5" : int,
"admittance_5": lambda x: f"{float(x)} MVAr",
"steps_6" : int,
"admittance_6": lambda x: f"{float(x)} MVAr",
"steps_7" : int,
"admittance_7": lambda x: f"{float(x)} MVAr",
"steps_8" : int,
"admittance_8": lambda x: f"{float(x)} MVAr",
}

print(f"""object shunt {{
name "{oname}_S_{row[0]}";
parent "{oname}_N_{row[0]}";""",file=glm)
for name,value in zip(fields[block][1:],row[1:]):
tag = mapping[name.strip("'")]
if tag in converters:
value = converters[tag](value)
else:
value = f'"{value}"'
print(f""" {tag if tag else "// " + name.strip("'")} {value};""",file=glm)
print(f"""}}""",file=glm)

elif row[0] == "Q":

print(f"""// END OF INPUT FILE {ifile}""",file=glm)
Expand Down
67 changes: 67 additions & 0 deletions docs/GLM/Global/Random.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
[[/GLM/Global/Random.md]] -- Generate a random number

# Synopsis

GLM:

~~~
${RANDOM}
${RANDOM SPEC}
~~~

# Description

If used without the `SPEC`, a random uniform number between 0 and 1 is
generated.

The following is permitted for `SPEC`:

* `N`: generate a `N`-bit unsigned integer where $0 \lt N \le 64$.

* `TYPE(A[,B])`: generate a random number of the specified distriction `TYPE`
given the arguments provided. See [[/GLM/General/Random%20values.md]] for
a list of distributions and their arguments.

* `last`: return the last random number generated.

If no random number has been previously generated and `last` is called, the
value of the global `randomseed` is returned.

# Example

File `test.glm`:

~~~
#set suppress_repeat_messages=FALSE
#print Random uniform.......... ${RANDOM}
#print Random 8-bit integer... ${RANDOM 8}
#print Random 16-bit integer... ${RANDOM 16}
#print Random 32-bit integer... ${RANDOM 32}
#print Random 48-bit integer... ${RANDOM 48}
#print Random 64-bit integer... ${RANDOM 64}
#print Random normal........... ${RANDOM normal(0,1)}
#print Last number generated... ${RANDOM last}
~~~

Run the following:

~~~
gridlabd test.glm
~~~

Output:

~~~
./test.glm(2): Random uniform.......... 0.196869
./test.glm(3): Random 8-bit integer... 156
./test.glm(4): Random 16-bit integer... 238
./test.glm(5): Random 32-bit integer... 996881412
./test.glm(6): Random 48-bit integer... 5506770547858
./test.glm(7): Random 64-bit integer... 8577238717949152431
./test.glm(8): Random normal........... 1.33329
./test.glm(9): Last number generated... 1.33329
~~~

# See Also

* [[/GLM/General/Random%20values.md]]
104 changes: 104 additions & 0 deletions docs/Module/Pypower/Shunt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
[[/Module/Pypower/Shunt.md]] -- Shunt capacitor/reactor

# Synopsis

~~~
class shunt {
enumeration {DISCRETE_V=1, FIXED=0} control_mode; // shunt control mode
enumeration {ONLINE=1, OFFLINE=0} status; // shunt status
double voltage_high[pu]; // controlled voltage upper limit
double voltage_low[pu]; // controlled voltage lower limit
object remote_bus; // remote bus name
double admittance[MVAr]; // shunt admittance at unity voltage
int32 steps_1; // numbers of steps in control block 1
double admittance_1[MVAr]; // control block 1 shunt admittance step at unity voltage
}
~~~

# Description

Shunt objects are used to control voltage of its `parent` bus. Shunt capacitors can raise voltage and shunt reactors can lower voltage. Shunt devices can be controlled by monitoring voltage on a remote bus and stepping the reactive power injections up or down according to the voltage control limits.

Each control block has a number of steps for the admittance steps allowed. Note: at this time, only 1 control block is supported.

# Properties

The following properties determine how a `shunt` device operates.

## `enumeration control_mode`

Determines the shunt device control mode.

### `FIXED`

The shunt device is fixed and does not change the shunt admittance of the parent bus.

### `DISCRETE_V`

The shunt device varies the shunt admittances of the `parent` bus according to the voltage control limits of the `remote_bus`, if specified. If the `remote_bus` is not specified then the `parent` bus is used as the control input.

## `enumeration status`

Shunt device status.

### `ONLINE`

The shunt device is active and will change the admittance of the `parent` bus.

### `OFFLINE`

The shunt device is inactive and will not change the admittance of the `parent` bus.

## `double voltage_high[pu]`

The upper voltage limit at which the shunt device's voltage lowering strategy will be engaged.

## `double voltage_low[pu]`

The lower voltage limit at which the shunt device's voltage raising strategy will be engaged.

## `object remote_bus`

The name of the remote bus from which voltage input is measured. If not specified, the `parent` bus is used as the voltage input.

## `double admittance[MVAr]`

The shunt admittance used when the shunt device is engaged, specified at unity voltage.

## `int32 steps_1`

The number of admittance steps in control block 1.


## `double admittance_1[MVAr]`

The admittance step of control block 1, specified at unity voltage.

# Examples

The following implements a shunt capacitor with 5 steps of 200 MVAr admittance on a test swing bus in `pypower`.

~~~
module pypower;
object pypower.bus
{
name "test_bus";
baseKV 345.0000 kV;
type REF;
}
object shunt {
name "test_shunt";
parent "test_bus";
control_mode DISCRETE_V;
status ONLINE;
voltage_high 1.5 pu;
voltage_low 0.5 pu;
admittance 200.0 MVAr;
steps_1 5;
admittance_1 200.0 MVAr;
}
~~~

# See Also

* [[/Module/Pypower.md]]
5 changes: 5 additions & 0 deletions index
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ docs/GLM/Global/Findfile.md
docs/GLM/Global/Geocode.md
docs/GLM/Global/Now.md
docs/GLM/Global/Python.md
docs/GLM/Global/Random.md
docs/GLM/Global/Range.md
docs/GLM/Global/Shell.md
docs/GLM/Global/Tmpfile.md
Expand Down Expand Up @@ -750,6 +751,7 @@ docs/Module/Pypower/Powerline.md
docs/Module/Pypower/Powerplant.md
docs/Module/Pypower/Relay.md
docs/Module/Pypower/Scada.md
docs/Module/Pypower/Shunt.md
docs/Module/Pypower/Transformer.md
docs/Module/Pypower/Weather.md
docs/Module/Python.md
Expand Down Expand Up @@ -2559,6 +2561,8 @@ module/pypower/relay.cpp
module/pypower/relay.h
module/pypower/scada.cpp
module/pypower/scada.h
module/pypower/shunt.cpp
module/pypower/shunt.h
module/pypower/transformer.cpp
module/pypower/transformer.h
module/pypower/weather.cpp
Expand Down Expand Up @@ -3369,6 +3373,7 @@ source/autotest/test_quoted_if_test.glm
source/autotest/test_quoted_value.glm
source/autotest/test_random.glm
source/autotest/test_random_correlation.glm
source/autotest/test_random_global.glm
source/autotest/test_range.glm
source/autotest/test_require.glm
source/autotest/test_require_err.glm
Expand Down
1 change: 1 addition & 0 deletions module/pypower/Makefile.mk
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ module_pypower_pypower_la_SOURCES += module/pypower/powerline.cpp module/pypower
module_pypower_pypower_la_SOURCES += module/pypower/powerplant.cpp module/pypower/powerplant.h
module_pypower_pypower_la_SOURCES += module/pypower/relay.cpp module/pypower/relay.h
module_pypower_pypower_la_SOURCES += module/pypower/scada.cpp module/pypower/scada.h
module_pypower_pypower_la_SOURCES += module/pypower/shunt.cpp module/pypower/shunt.h
module_pypower_pypower_la_SOURCES += module/pypower/transformer.cpp module/pypower/transformer.h
module_pypower_pypower_la_SOURCES += module/pypower/weather.cpp module/pypower/weather.h

Expand Down
4 changes: 3 additions & 1 deletion module/pypower/bus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,11 @@ TIMESTAMP bus::precommit(TIMESTAMP t0)

TIMESTAMP bus::presync(TIMESTAMP t0)
{
// reset to base load
// reset to base load/shunt
Pd = S.Re();
Qd = S.Im();
Gs = 0.0;
Bs = 0.0;

return TS_NEVER;
}
Expand Down
Loading

0 comments on commit a01e2ce

Please sign in to comment.