Exemple #1
0
class BaseRoutine:
    """
    Base routine class.

    Provides references to system, config, and solver.
    """

    def __init__(self, system=None, config=None):
        self.system = system
        self.config = Config(self.class_name)

        if config is not None:
            self.config.load(config)

        self.config.add(OrderedDict((('sparselib', 'klu'),
                                     ('linsolve', 0),
                                     )))
        self.config.add_extra("_help",
                              sparselib="linear sparse solver name",
                              linsolve="solve symbolic factorization each step (enable when KLU segfaults)",
                              )
        self.config.add_extra("_alt", sparselib=("klu", "umfpack", "spsolve", "cupy"),
                              linsolve=(0, 1),
                              )

        self.solver = Solver(sparselib=self.config.sparselib)

    @property
    def class_name(self):
        return self.__class__.__name__

    def doc(self, max_width=78, export='plain'):
        """
        Routine documentation interface.
        """
        return self.config.doc(max_width, export)

    def init(self):
        """
        Routine initialization interface.
        """
        pass

    def run(self, **kwargs):
        """
        Routine main entry point.
        """
        raise NotImplementedError

    def summary(self, **kwargs):
        """
        Summary interface
        """
        raise NotImplementedError

    def report(self, **kwargs):
        """
        Report interface.
        """
        raise NotImplementedError
Exemple #2
0
    def __init__(self, system=None, config=None):
        self.system = system
        self.config = Config(self.class_name)

        if config is not None:
            self.config.load(config)

        self.config.add(OrderedDict((('sparselib', 'klu'),
                                     ('linsolve', 0),
                                     )))
        self.config.add_extra("_help",
                              sparselib="linear sparse solver name",
                              linsolve="solve symbolic factorization each step (enable when KLU segfaults)",
                              )
        self.config.add_extra("_alt", sparselib=("klu", "umfpack", "spsolve", "cupy"),
                              linsolve=(0, 1),
                              )

        self.solver = Solver(sparselib=self.config.sparselib)
Exemple #3
0
class System(object):
    """
    System contains models and routines for modeling and simulation.

    System contains a several special `OrderedDict` member attributes for housekeeping.
    These attributes include `models`, `groups`, `routines` and `calls` for loaded models, groups,
    analysis routines, and generated numerical function calls, respectively.

    Notes
    -----
    System stores model and routine instances as attributes.
    Model and routine attribute names are the same as their class names.
    For example, `Bus` is stored at ``system.Bus``, the power flow calculation routine is at
    ``system.PFlow``, and the numerical DAE instance is at ``system.dae``. See attributes for the list of
    attributes.

    Attributes
    ----------
    dae : andes.variables.dae.DAE
        Numerical DAE storage
    files : andes.variables.fileman.FileMan
        File path storage
    config : andes.core.Config
        System config storage
    models : OrderedDict
        model name and instance pairs
    groups : OrderedDict
        group name and instance pairs
    routines : OrderedDict
        routine name and instance pairs
    """
    def __init__(self,
                 case: Optional[str] = None,
                 name: Optional[str] = None,
                 config_path: Optional[str] = None,
                 options: Optional[Dict] = None,
                 **kwargs):
        self.name = name
        self.options = {}
        if options is not None:
            self.options.update(options)
        if kwargs:
            self.options.update(kwargs)
        self.calls = OrderedDict(
        )  # a dictionary with model names (keys) and their ``calls`` instance
        self.models = OrderedDict()  # model names and instances
        self.groups = OrderedDict()  # group names and instances
        self.routines = OrderedDict()  # routine names and instances
        self.switch_times = np.array(
            [])  # an array of ordered event switching times
        self.switch_dict = OrderedDict(
        )  # time: OrderedDict of associated models
        self.n_switches = 0  # number of elements in `self.switch_times`
        self.exit_code = 0  # command-line exit code, 0 - normal, others - error.

        # get and load default config file
        self._config_path = get_config_path()
        if config_path:
            self._config_path = config_path
        self._config_object = self.load_config(self._config_path)
        self.config = Config(self.__class__.__name__)
        self.config.load(self._config_object)

        # custom configuration for system goes after this line
        self.config.add(
            OrderedDict(
                (('freq', 60), ('mva', 100), ('store_z', 0), ('ipadd', 1),
                 ('warn_limits', 1), ('warn_abnormal', 1), ('dime_enabled', 0),
                 ('dime_name', 'andes'), ('dime_protocol', 'ipc'),
                 ('dime_address', '/tmp/dime2'))))

        self.config.add_extra(
            "_help",
            freq='base frequency [Hz]',
            mva='system base MVA',
            store_z='store limiter status in TDS output',
            ipadd='Use spmatrix.ipadd if available',
            warn_limits='warn variables initialized at limits',
            warn_abnormal='warn initialization out of normal values',
        )
        self.config.add_extra(
            "_alt",
            freq="float",
            mva="float",
            store_z=(0, 1),
            ipadd=(0, 1),
            warn_limits=(0, 1),
            warn_abnormal=(0, 1),
        )
        self.config.check()
        self.exist = ExistingModels()

        self.files = FileMan(case=case, **self.options)  # file path manager
        self.dae = DAE(system=self)  # numerical DAE storage

        # dynamic imports of groups, models and routines
        self.import_groups()
        self.import_models()
        self.import_routines()  # routine imports come after models

        self._getters = dict(f=list(), g=list(), x=list(), y=list())
        self._adders = dict(f=list(), g=list(), x=list(), y=list())
        self._setters = dict(f=list(), g=list(), x=list(), y=list())
        self.antiwindups = list()

        # internal flags
        self.is_setup = False  # if system has been setup
Exemple #4
0
class System(object):
    """
    The ANDES power system class.

    This class stores model and routine instances as attributes.
    Model and routine attribute names are the same as their class names.
    For example, the ``Bus`` instance of ``system`` is accessible at ``system.Bus``.
    """
    def __init__(self,
                 case: Optional[str] = None,
                 name: Optional[str] = None,
                 config_path: Optional[str] = None,
                 options: Optional[Dict] = None,
                 **kwargs
                 ):
        self.name = name
        self.options = {}
        if options is not None:
            self.options.update(options)
        if kwargs:
            self.options.update(kwargs)
        self.calls = OrderedDict()         # a dictionary with model names (keys) and their ``calls`` instance
        self.models = OrderedDict()        # model names and instances
        self.groups = OrderedDict()        # group names and instances
        self.routines = OrderedDict()      # routine names and instances
        self.switch_times = np.array([])   # an array of ordered event switching times

        # get and load default config file
        self._config_path = get_config_path()
        if config_path:
            self._config_path = config_path
        self._config_object = self.load_config(self._config_path)
        self.config = Config(self.__class__.__name__)
        self.config.load(self._config_object)

        # custom configuration for system goes after this line
        self.config.add(OrderedDict((('freq', 60),
                                     ('mva', 100),
                                     ('store_z', 0),
                                     ('ipadd', 1),
                                     )))

        self.config.add_extra("_help",
                              freq='base frequency [Hz]',
                              mva='system base MVA',
                              store_z='store limiter status in TDS output',
                              ipadd='Use spmatrix.ipadd if available',
                              )
        self.config.add_extra("_alt",
                              freq="float",
                              mva="float",
                              store_z=(0, 1),
                              ipadd=(0, 1),
                              )
        self.config.check()

        self.files = FileMan(case=case, **self.options)    # file path manager
        self.dae = DAE(system=self)                        # numerical DAE storage

        # dynamic imports of groups, models and routines
        self._group_import()
        self._model_import()
        self._routine_import()  # routine imports come after models

        self._models_flag = {'pflow': self.find_models('pflow'),
                             'tds': self.find_models('tds'),
                             'pflow_tds': self.find_models(('tds', 'pflow')),
                             }

        self._adders = dict(f=list(), g=list(), x=list(), y=list())
        self._setters = dict(f=list(), g=list(), x=list(), y=list())
        self.antiwindups = list()