Groups#

A group is a collection of similar functional models with common variables and parameters. It is mandatory to enforce the common variables and parameters when developing new models. The common variables and parameters are typically the interface when connecting different group models.

Background#

For example, the Group RenGen has variables Pe and Qe, which are active power output and reactive power output. Such common variables can be retrieved by other models, such as one in the Group RenExciter for further calculation.

In such a way, the same variable interface is realized so that all models in the same group can carry out similar functions. This enables:

  1. Common interface: All generators have bus, Sn, Vn

  2. Polymorphism: Exciters work with any synchronous generator model

  3. Backward references: Find all devices connected to a bus

  4. Model substitution: Replace GENCLS with GENROU without changing case files

GroupBase#

GroupBase()

Base class for groups.

class andes.models.group.GroupBase[source]

Base class for groups.

add(idx, model)[source]

Register an idx from model_name to the group

Parameters:
idx: Union[str, float, int]

Register an element to a model

model: Model

instance of the model

Returns:
add_model(name: str, instance)[source]

Add a Model instance to group.

Parameters:
namestr

Model name

instanceModel

Model instance

Returns:
None
alter(src, idx, value, attr='v')[source]

Alter values of input parameters or constant service for a group of models.

Deprecated since version Use: set() with base='device' instead.

Parameters:
srcstr

The parameter name to alter

idxstr, float, int

The unique identifier for the device to alter

valuefloat

The desired value

attrstr, optional

The attribute to alter. Default is 'v'.

as_df(vin=False)[source]

Export group common parameters as a pandas.DataFrame object.

Note

New in version 1.9.3.

Parameters:
vinbool

If True, export all parameters from original input (vin).

Returns:
DataFrame

A dataframe containing all model data. An uid column is added.

as_dict(vin=False)[source]

Export group common parameters as a dictionary.

Note

New in version 1.9.3.

This method returns a dictionary where the keys are the ModelData parameter names and the values are array-like structures containing the data in the order they were added. Unlike ModelData.as_dict(), this dictionary does not include the uid field.

Parameters:
vinbool, optional

If True, includes the vin attribute in the dictionary. Default is False.

Returns:
dict

A dictionary of common parameters.

doc(export='plain')[source]

Return the documentation of the group in a string.

doc_all(export='plain')[source]

Return documentation of the group and its models.

Parameters:
export'plain' or 'rest'

Export format, plain-text or RestructuredText

Returns:
str
find_idx(keys, values, allow_none=False, default=None, allow_all=False)[source]

Find indices of devices that satisfy the given key=value condition.

This method iterates over all models in this group.

Parameters:
keysstr, array-like, Sized

A string or an array-like of strings containing the names of parameters for the search criteria.

valuesarray, array of arrays, Sized

Values for the corresponding key to search for. If keys is a str, values should be an array of elements. If keys is a list, values should be an array of arrays, each corresponding to the key.

allow_nonebool, optional

Allow key, value to be not found. Used by groups. Default is False.

defaultbool, optional

Default idx to return if not found (missing). Default is None.

allow_allbool, optional

Return all matches if set to True. Default is False.

Returns:
list

Indices of devices.

get(src: str, idx, attr: str = 'v', allow_none=False, default=0.0)[source]

Based on the indexer, get the attr field of the src parameter or variable.

Parameters:
srcstr

param or var name

idxarray-like

device idx

attr

The attribute of the param or var to retrieve

allow_nonebool

True to allow None values in the indexer

defaultfloat

If allow_none is true, the default value to use for None indexer.

Returns:
The requested param or variable attribute. If idx is a list, return a list of values.
If idx is a single element, return a single value.
get_all_idxes()[source]

Return all the devices idx in this group.

Note

New in version 1.9.3.

Returns:
list

List of indices.

Notes

The default models sequence depends on the order of the models in the group, which comes from OrderedDict file_classes in models.__init__.py.

Examples

>>> ss = andes.load(andes.get_case('ieee14/ieee14_pvd1.xlsx'))
>>> ss.DG.get_all_idxes()
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> ss.StaticGen.get_all_idxes()
[2, 3, 4, 5, 6, 1]
get_field(src: str, idx, field: str)[source]

Helper function for retrieving an attribute of a member variable shared by models in this group.

Returns:
list

A list with the length equal to len(idx).

get_next_idx(idx=None, model_name=None)[source]

Get a no-conflict idx for a new device. Use the provided idx if no conflict. Generate a new one otherwise.

Parameters:
idxstr or None

Proposed idx. If None, assign a new one.

model_namestr or None

Model name. If not, prepend the group name.

Returns:
str

New device name.

get_setpoint(system, idx, name)[source]

Get the current setpoint value by resolving the controller chain.

See set_setpoint() for notes on the physical meaning of setpoint values.

Parameters:
systemSystem

The system instance.

idxstr, int, float

Device idx in this group.

namestr

Setpoint key (e.g., 'pref', 'vref', 'qref').

Returns:
float

Current value of the setpoint (system-base per-unit).

get_status(idx)[source]

Get the effective online status of a device.

Parameters:
idxstr, int, float

Device idx.

Returns:
float

Effective status value (0 or 1).

idx2model(idx, allow_none=False)[source]

Find model name for the given idx.

Parameters:
idxfloat, int, str, array-like

idx or idx-es of devices.

allow_nonebool

If True, return None at the positions where idx is not found.

Returns:
If idx is a list, return a list of model instances.
If idx is a single element, return a model instance.
idx2uid(idx)[source]

Convert idx to the 0-indexed unique index.

Parameters:
idxarray-like, numbers, or str

idx of devices

Returns:
list

A list containing the unique indices of the devices

property n

Total number of devices.

set(src: str, idx, *args, value=<object object>, attr='v', base=None)[source]

Set the value of a group property, dispatching to the correct model.

Delegates to each model's Model.set(). See its docstring for details on base and attr.

Parameters:
srcstr

Name of property.

idxstr, int, float, array-like

Indices of devices.

valuefloat or array-like

New values to be set. Can be passed as the third positional argument or as a keyword.

attrstr, optional

Attribute to write (default 'v'). Ignored when base='device'.

baseNone or 'device', optional

None (default): system-base direct write. 'device': device/input-base with per-unit conversion.

Returns:
bool

True when successful.

set_backref(name, from_idx, to_idx)[source]

Set idxes to BackRef, and set them to models.

set_setpoint(system, idx, name, value)[source]

Set a setpoint value by resolving the controller chain.

Searches for a connected controller (e.g., TurbineGov for 'pref', Exciter for 'vref') and writes there. Falls back to the device itself with a warning.

Note

The physical meaning of a setpoint depends on the specific controller model that owns it. For example, 'vref' writes to the exciter's voltage reference input, which may include compensation terms (e.g., EXAC4 initializes vref0 = v + vf0/KA). It is not necessarily the exact terminal voltage. Similarly, 'pref' is the governor's power reference in system-base per-unit. Use get_setpoint() to read the current value before applying incremental changes.

Parameters:
systemSystem

The system instance.

idxstr, int, float

Device idx in this group.

namestr

Setpoint key (e.g., 'pref', 'vref', 'qref').

valuefloat

Value to write (absolute, in system-base per-unit).

set_status(idx, value)[source]

Set the online status of a device and propagate to dependents.

Delegates to the concrete model's set_status() which calls System.set_status() for propagation.

Parameters:
idxstr, int, float

Device idx.

valueint or float

New status value (0 or 1).

Standard Groups#

Group

Models

Common Parameters

StaticGen

PV, Slack

bus, p0, q0, Sn

SynGen

GENCLS, GENROU, GENSAL

bus, gen, Sn, Vn

Exciter

ESST1A, ESDC2, SEXS

syn

TurbineGov

TGOV1, IEEEG1, HYGOV

syn

PSS

IEEEST, ST2CUT

avr

StaticLoad

PQ, ZIP

bus, Vn

Motor

MotorThree, MotorFive

bus

RenGen

REGCA1, REECA1

bus, gen

Defining Groups#

Groups are defined in andes/models/group.py:

from andes.core.model import GroupBase

class Exciter(GroupBase):
    """Exciter group base class."""

    def __init__(self):
        super().__init__()
        # Common parameters for all exciters
        self.common_params = ['syn']
        self.common_vars = []

Model Group Registration#

Models declare their group in the constructor:

class ESST1A(ExciterData, Model):
    def __init__(self, system, config):
        ExciterData.__init__(self)
        Model.__init__(self, system, config)

        self.group = 'Exciter'  # Register with Exciter group

Using Groups for References#

External Parameters#

Get parameters from any model in a group:

class TurbineGov(Model):
    def __init__(self):
        # Reference generator - can be any SynGen model
        self.syn = IdxParam(model='SynGen', mandatory=True)

        # Get inertia from the generator (works for GENCLS or GENROU)
        self.M = ExtParam(src='M', model='SynGen', indexer=self.syn)

External Variables#

Access variables from any group member:

class Exciter(Model):
    def __init__(self):
        self.syn = IdxParam(model='SynGen')

        # Access generator terminal voltage
        self.vd = ExtAlgeb(src='vd', model='SynGen', indexer=self.syn)
        self.vq = ExtAlgeb(src='vq', model='SynGen', indexer=self.syn)

BackRef for Connections#

Groups enable backward references:

class Bus(Model):
    def __init__(self):
        # Collect all PQ loads connected to this bus
        self.PQ = BackRef()

        # Collect all generators
        self.SynGen = BackRef()

Usage:

# Get list of PQ indices on bus 1
pq_indices = ss.Bus.PQ.v[0]  # List of PQ idx connected to first bus

Group Substitution#

Replace models without changing input files:

# Original case uses GENCLS
# To use GENROU instead, load with model map
ss = andes.load('case.xlsx', model_map={'GENCLS': 'GENROU'})

Since both are in SynGen group, references work automatically.

Common Group Patterns#

Generator Groups#

StaticGen (base)
    ├── PV
    └── Slack

SynGen (dynamic generators)
    ├── GENCLS (classical)
    ├── GENROU (round-rotor)
    └── GENSAL (salient-pole)

Controller Groups#

Exciter
    ├── ESST1A
    ├── ESDC2
    ├── SEXS
    └── ...

TurbineGov
    ├── TGOV1
    ├── IEEEG1
    ├── HYGOV
    └── ...

Group Requirements#

When creating models for a group:

  1. Inherit group data class: Use ExciterData, TGOVData, etc.

  2. Set group name: self.group = 'Exciter'

  3. Provide required parameters: Match common_params

  4. Match interface: Variables and equations must be compatible

Creating New Groups#

# In andes/models/group.py
class MyGroup(GroupBase):
    def __init__(self):
        super().__init__()
        self.common_params = ['bus', 'Sn']
        self.common_vars = ['P', 'Q']

Register in the models import file to make it available.

See Also#