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
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)
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
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()