Exemplo n.º 1
0
class System(object):
    """
    New power system class
    """
    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 None else options
        if kwargs:
            self.options.update(kwargs)
        self.calls = OrderedDict()
        self.models = OrderedDict()
        self.groups = OrderedDict()
        self.programs = OrderedDict()
        self.switch_times = np.array([])

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

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

        self.files = FileMan()
        self.files.set(case=case, **self.options)

        self.dae = DAE(system=self)

        # dynamic imports: routine import need to query model flags
        self._group_import()
        self._model_import()
        self._routine_import()

        self._models_with_flag = {
            'pflow': self.get_models_with_flag('pflow'),
            'tds': self.get_models_with_flag('tds'),
            'pflow_and_tds': self.get_models_with_flag(('tds', 'pflow')),
        }

        # ------------------------------
        # FIXME: reduce clutter with defaultdict `adders` and `setters`, each with `x`, `y`, `f`, and `g`
        self.f_adders, self.f_setters = list(), list()
        self.g_adders, self.g_setters = list(), list()

        self.x_adders, self.x_setters = list(), list()
        self.y_adders, self.y_setters = list(), list()
        self.antiwindups = list()
Exemplo n.º 2
0
def edit_conf(edit_config: Optional[Union[str, bool]] = ''):
    """
    Edit the Andes config file which occurs first in the search path.

    Parameters
    ----------
    edit_config : bool
        If ``True``, try to open up an editor and edit the config file. Otherwise returns.

    Returns
    -------
    bool
        ``True`` is a config file is found and an editor is opened. ``False`` if ``edit_config`` is False.
    """
    ret = False

    # no `edit-config` supplied
    if edit_config == '':
        return ret

    conf_path = get_config_path()

    if conf_path is None:
        logger.info('Config file does not exist. Automatically saving.')
        system = System()
        conf_path = system.save_config()

    logger.info('Editing config file "%s"', conf_path)

    editor = ''
    if edit_config is not None:
        # use `edit_config` as default editor
        editor = edit_config
    else:
        # use the following default editors
        if platform.system() == 'Linux':
            editor = os.environ.get('EDITOR', 'vim')
        elif platform.system() == 'Darwin':
            editor = os.environ.get('EDITOR', 'vim')
        elif platform.system() == 'Windows':
            editor = 'notepad.exe'

    editor_cmd = editor.split()
    editor_cmd.append(conf_path)
    call(editor_cmd)
    ret = True
    return ret
Exemplo n.º 3
0
def edit_conf(edit_config: Optional[Union[str, bool]] = ''):
    """
    Edit the Andes config file which occurs first in the search path.

    Parameters
    ----------
    edit_config : bool
        If ``True``, try to open up an editor and edit the config file. Otherwise returns.

    Returns
    -------
    bool
        ``True`` is a config file is found and an editor is opened. ``False`` if ``edit_config`` is False.
    """
    ret = False

    # no `edit-config` supplied
    if edit_config == '':
        return ret

    conf_path = get_config_path()

    if conf_path is not None:
        logger.info('Editing config file {}'.format(conf_path))

        if edit_config is None:
            # use the following default editors
            if platform.system() == 'Linux':
                editor = os.environ.get('EDITOR', 'gedit')
            elif platform.system() == 'Darwin':
                editor = os.environ.get('EDITOR', 'vim')
            elif platform.system() == 'Windows':
                editor = 'notepad.exe'
        else:
            # use `edit_config` as default editor
            editor = edit_config

        call([editor, conf_path])
        ret = True

    else:
        logger.info('Config file does not exist. Save config with \'andes '
                    '--save-config\'')
        ret = True

    return ret
Exemplo n.º 4
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
Exemplo n.º 5
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()