Device#
This section introduces the modeling of power system devices. Here the term
"model" refers to the descriptive model of a device, which is used to
hold the device-level data and variables, such as Bus, Line, and PQ.
AMS employs a similar model organization manner as ANDES, where the class
model is used to hold the device-level parameters and variables.
Note
One major difference here is, in ANDES, two classes, ModelData and
Model, are used to hold the device-level parameters and equations.
Parameters#
Parameter is an atom element in building a power system model. Most parameters are read from an input file, and other parameters are calculated from the existing parameters.
AMS leverages the parameter definition in ANDES, where four classes,
DataParam, IdxParam, NumParam, and ExtParam are used.
More details can be found in ANDES documentation
Development - Parameters.
Variables#
In AMS, the definition of variables Algeb is simplified from ANDES. The
Algeb class is used to define algebraic variables in the model level, which are used to
exchange data with dynamic simulator.
- class ams.core.var.Algeb(name: str | None = None, tex_name: str | None = None, info: str | None = None, unit: str | None = None)[source]
Algebraic variable class.
Simplified from andes.core.var.Algeb.
Note
The Algeb class here is not directly used for optimization purpose, we will discuss
its role further in the Routine section.
Model#
Encapsulating the parameters and variables, the Model class is used to define the
device model.
- class ams.core.model.Model(system=None, config=None)[source]
Base class for power system scheduling models.
This class is revised from
andes.core.model.Model.
Examples#
The following two examples demonstrate how to define a device model in AMS.
PV model#
In this example, we define a PV generator model PV in three steps, data
definition, model definition, and manufacturing.
First, we need to define the parameters needed in a PV.
not included in ANDES PVData. In this example, we hold the parameters in
a separate class GenParam.
from andes.core.param import NumParam, ExtParam
class GenParam:
def __init__(self) -> None:
self.ctrl = NumParam(default=1,
info="generator controllability",
tex_name=r'c_{trl}',)
self.Pc1 = NumParam(default=0.0,
info="lower real power output of PQ capability curve",
tex_name=r'P_{c1}',
unit='p.u.')
self.Pc2 = NumParam(default=0.0,
info="upper real power output of PQ capability curve",
tex_name=r'P_{c2}',
unit='p.u.')
......
self.pg0 = NumParam(default=0.0,
info='real power start point',
tex_name=r'p_{g0}',
unit='p.u.',
)
Second, we define the PVModel model with two algebraic variables and an external parameter.
from ams.core.model import Model
from ams.core.var import Algeb
class PVModel(Model):
def __init__(self, system=None, config=None):
super().__init__(system, config)
self.group = 'StaticGen'
self.zone = ExtParam(model='Bus', src='zone', indexer=self.bus, export=False,
info='Retrieved zone idx', vtype=str, default=None,
)
self.p = Algeb(info='actual active power generation',
unit='p.u.',
tex_name='p',
name='p',
)
self.q = Algeb(info='actual reactive power generation',
unit='p.u.',
tex_name='q',
name='q',
)
Note
The external parameter zone is added here to enable the zonal reserve dispatch,
but it is not included in ANDES PV.
Third, we manufacture these classes together as the PV model.
from andes.models.static.pv import PVData # NOQA
class PV(PVData, GenParam, PVModel):
"""
PV generator model.
"""
def __init__(self, system, config):
PVData.__init__(self)
GenParam.__init__(self)
PVModel.__init__(self, system, config)
Lastly, we need to finalize the model by adding the PV model to the model list in
$HOME/ams/ams/models/__init__.py, where 'static' is the file name, and 'PV' is the
model name.
ams_file_classes = list([
('info', ['Summary']),
('bus', ['Bus']),
('static', ['PQ', 'PV', 'Slack']),
... ...
])
Note
The device-level model development procedures is similar to ANDES. The only difference is that a device-level model for dispatch is much simpler than that for dynamic simulation. In AMS, we only defines the data and small amount of variables. In contrast, ANDES defines the data, variables, and equations for dynamic simulation. Mode details for device-level model development can be found in ANDES documentation Development - Examples.
Line model#
In this example, we define a Line model, where the data is extended from existing
ANDES LineData by including two extra parameters amin and amax.
from andes.models.line.line import LineData
from andes.core.param import NumParam
from andes.shared import deg2rad
from ams.core.model import Model
class Line(LineData, Model):
"""
AC transmission line model.
The model is also used for two-winding transformer. Transformers can set the
tap ratio in ``tap`` and/or phase shift angle ``phi``.
Notes
-----
There is a known issue that adding Algeb ``ud`` will cause Line.algebs run into
AttributeError: 'NoneType' object has no attribute 'n'. Not figured out why yet.
"""
def __init__(self, system=None, config=None) -> None:
LineData.__init__(self)
Model.__init__(self, system, config)
self.group = 'ACLine'
self.amin = NumParam(default=-360 * deg2rad,
info="minimum angle difference, from bus - to bus",
unit='rad',
tex_name=r'a_{min}',
)
self.amax = NumParam(default=360 * deg2rad,
info="maximum angle difference, from bus - to bus",
unit='rad',
tex_name=r'a_{max}',
)