Skip to content

Commit

Permalink
Merge pull request #92 from cuihantao/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
cuihantao committed Oct 11, 2020
2 parents 3c7548d + 775880a commit 5d0885a
Show file tree
Hide file tree
Showing 31 changed files with 724 additions and 192 deletions.
592 changes: 592 additions & 0 deletions .pylintrc

Large diffs are not rendered by default.

Binary file modified andes/cases/kundur/kundur_reg.xlsx
Binary file not shown.
20 changes: 10 additions & 10 deletions andes/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@ def create_parser():

parser.add_argument(
'-v', '--verbose',
help='Program logging level in 10-DEBUG, 20-INFO, 30-WARNING, '
'40-ERROR or 50-CRITICAL.',
type=int, default=20, choices=(1, 10, 20, 30, 40, 50))
help='Verbosity level in 10-DEBUG, 20-INFO, 30-WARNING, '
'or 40-ERROR.',
type=int, default=20, choices=(1, 10, 20, 30, 40))

sub_parsers = parser.add_subparsers(dest='command', help='[run] run simulation routine; '
'[plot] plot simulation results; '
'[plot] plot results; '
'[doc] quick documentation; '
'[prepare] run the symbolic-to-numeric preparation; '
'[misc] miscellaneous functions.'
'[misc] misc. functions; '
'[prepare] prepare the numerical code; '
'[selftest] run self test.'
)

run = sub_parsers.add_parser('run')
Expand All @@ -44,8 +45,8 @@ def create_parser():
run.add_argument('-o', '--output-path', help='Output path prefix', type=str, default='')
run.add_argument('-n', '--no-output', help='Force no output of any kind', action='store_true')
run.add_argument('--ncpu', help='Number of parallel processes', type=int, default=os.cpu_count())
run.add_argument('--dime-address', help='Specify DiME streaming server address and port', type=str)
run.add_argument('--dime-protocol', help='Specify DiME streaming protocol', type=str)
run.add_argument('--dime-address', help='DiME streaming server address and port', type=str)
run.add_argument('--dime-protocol', help='DiME streaming protocol', type=str)
run.add_argument('--tf', help='End time of time-domain simulation', type=float)
run.add_argument('--qrt', help='Enable quasi-real-time stepping', action='store_true')
run.add_argument('--kqrt', help='Scaling factor for quasi-real-time; e.g., kqrt=2 means the wall-clock time '
Expand Down Expand Up @@ -102,8 +103,7 @@ def create_parser():
plot.add_argument('--vline1', help='dashed vertical line 1', type=float)
plot.add_argument('--vline2', help='dashed vertical line 2', type=float)


doc = sub_parsers.add_parser('doc') # NOQA
doc = sub_parsers.add_parser('doc')
doc.add_argument('attribute', help='System attribute name to get documentation', nargs='?')
doc.add_argument('--config', '-c', help='Config help')
doc.add_argument('--list', '-l', help='List supported models and groups', action='store_true',
Expand Down
2 changes: 1 addition & 1 deletion andes/core/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import numpy as np


class Block(object):
class Block:
r"""
Base class for control blocks.
Expand Down
8 changes: 4 additions & 4 deletions andes/core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
logger = logging.getLogger(__name__)


class ModelFlags(object):
class ModelFlags:
"""
Model flags.
Expand Down Expand Up @@ -72,7 +72,7 @@ def __repr__(self):
return pprint.pformat(self.__dict__)


class DummyValue(object):
class DummyValue:
"""
Class for converting a scalar value to a dummy parameter with `name` and `tex_name` fields.
Expand Down Expand Up @@ -111,7 +111,7 @@ def dummify(param):
return param


class JacTriplet(object):
class JacTriplet:
"""
Storage class for Jacobian triplet lists.
"""
Expand Down Expand Up @@ -173,7 +173,7 @@ def merge(self, triplet):
self.vjac[jname + jtype] += triplet.vjac[jname + jtype]


class Config(object):
class Config:
"""
A class for storing system, model and routine configurations.
"""
Expand Down
2 changes: 1 addition & 1 deletion andes/core/discrete.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
logger = logging.getLogger(__name__)


class Discrete(object):
class Discrete:
"""
Base discrete class.
Expand Down
91 changes: 47 additions & 44 deletions andes/core/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
np.seterr(divide='raise')


class Cache(object):
class Cache:
"""
Class for caching the return value of callback functions.
"""
Expand All @@ -55,9 +55,6 @@ def __getattr__(self, item):

return self.__getattribute__(item)

def __setattr__(self, key, value):
super(Cache, self).__setattr__(key, value)

def add_callback(self, name: str, callback):
"""
Add a cache attribute and a callback function for updating the attribute.
Expand Down Expand Up @@ -111,7 +108,7 @@ def _call(self, name):
return self._callbacks[name]


class ModelData(object):
class ModelData:
r"""
Class for holding parameter data for a model.
Expand Down Expand Up @@ -374,7 +371,7 @@ def find_idx(self, keys, values, allow_none=False, default=False):
return idxes


class ModelCall(object):
class ModelCall:
"""
Class for storing generated function calls and Jacobians.
"""
Expand All @@ -394,7 +391,7 @@ def __init__(self):
self.j_args = dict()
self.s_args = OrderedDict()

self.init_lambdify = OrderedDict()
self.init = OrderedDict()

self.ijac = defaultdict(list)
self.jjac = defaultdict(list)
Expand Down Expand Up @@ -428,7 +425,7 @@ def zip_ijv(self, j_full_name):
self.vjac[j_full_name])


class Model(object):
class Model:
r"""
Base class for power system DAE models.
Expand Down Expand Up @@ -684,7 +681,7 @@ def _check_attribute(self, key, value):
if not value.tex_name:
value.tex_name = key
if key in self.__dict__:
logger.warning(f"{self.class_name}: redefinition of member <{key}>")
logger.warning(f"{self.class_name}: redefinition of member <{key}>. Likely a modeling error.")

def __setattr__(self, key, value):
self._check_attribute(key, value)
Expand Down Expand Up @@ -1171,7 +1168,7 @@ def init(self, routine):
d.check_var()

kwargs = self.get_inputs(refresh=True)
init_fun = self.calls.init_lambdify[name]
init_fun = self.calls.init[name]

if callable(init_fun):
try:
Expand Down Expand Up @@ -1218,12 +1215,13 @@ def f_update(self):
Non-inplace equations: in-place set to internal array to
overwrite old values (and avoid clearing).
"""
f_ret = self.calls.f(*self.f_args)
for i, var in enumerate(self.cache.states_and_ext.values()):
if var.e_inplace:
var.e += f_ret[i]
else:
var.e[:] = f_ret[i]
if callable(self.calls.f):
f_ret = self.calls.f(*self.f_args)
for i, var in enumerate(self.cache.states_and_ext.values()):
if var.e_inplace:
var.e += f_ret[i]
else:
var.e[:] = f_ret[i]

kwargs = self.get_inputs()
# user-defined numerical calls defined in the model
Expand All @@ -1239,12 +1237,13 @@ def g_update(self):
"""
Evaluate algebraic equations.
"""
g_ret = self.calls.g(*self.g_args)
for i, var in enumerate(self.cache.algebs_and_ext.values()):
if var.e_inplace:
var.e += g_ret[i]
else:
var.e[:] = g_ret[i]
if callable(self.calls.g):
g_ret = self.calls.g(*self.g_args)
for i, var in enumerate(self.cache.algebs_and_ext.values()):
if var.e_inplace:
var.e += g_ret[i]
else:
var.e[:] = g_ret[i]

kwargs = self.get_inputs()
# numerical calls defined in the model
Expand Down Expand Up @@ -1639,7 +1638,7 @@ def numba_jitify(self, parallel=False, cache=False):
self.flags.jited = True


class SymProcessor(object):
class SymProcessor:
"""
A helper class for symbolic processing and code generation.
Expand Down Expand Up @@ -1694,7 +1693,7 @@ def __init__(self, parent):
self.cache = parent.cache
self.config = parent.config
self.class_name = parent.class_name
self.tex_names = parent.tex_names
self.tex_names = OrderedDict()

def generate_init(self):
"""
Expand Down Expand Up @@ -1735,7 +1734,7 @@ def generate_init(self):
if len(self.init_std) > 0:
self.init_dstd = self.init_std.jacobian(list(self.vars_dict.values()))

self.calls.init_lambdify = init_lambda_list
self.calls.init = init_lambda_list
self.calls.init_latex = init_latex
self.calls.init_std = lambdify((list(self.iters_dict), list(self.non_iters_dict)),
self.init_std,
Expand Down Expand Up @@ -1769,8 +1768,8 @@ def generate_symbols(self):

# process tex_names defined in model
# -----------------------------------------------------------
for key in self.tex_names.keys():
self.tex_names[key] = Symbol(self.tex_names[key])
for key in self.parent.tex_names.keys():
self.tex_names[key] = Symbol(self.parent.tex_names[key])
for instance in self.parent.discrete.values():
for name, tex_name in zip(instance.get_names(), instance.get_tex_names()):
self.tex_names[name] = tex_name
Expand Down Expand Up @@ -1832,17 +1831,17 @@ def generate_equations(self):
self.calls.f_args = list()
self.calls.g_args = list()

iter_list = [self.cache.states_and_ext, self.cache.algebs_and_ext]
dest_list = [self.f_list, self.g_list]
vars_list = [self.cache.states_and_ext, self.cache.algebs_and_ext]
expr_list = [self.f_list, self.g_list]

dest_eqn = ['f', 'g']
dest_args = [self.calls.f_args, self.calls.g_args]
eqn_names = ['f', 'g']
eqn_args = [self.calls.f_args, self.calls.g_args]

for it, dest, eqn, dargs in zip(iter_list, dest_list, dest_eqn, dest_args):
eq_args = list()
for name, instance in it.items():
for vlist, elist, ename, eargs in zip(vars_list, expr_list, eqn_names, eqn_args):
sym_args = list()
for name, instance in vlist.items():
if instance.e_str is None:
dest.append(0)
elist.append(0)
else:
try:
expr = sympify(instance.e_str, locals=self.inputs_dict)
Expand All @@ -1853,13 +1852,15 @@ def generate_equations(self):
free_syms = self._check_expr_symbols(expr)

for s in free_syms:
if s not in eq_args:
eq_args.append(s)
dargs.append(str(s))
if s not in sym_args:
sym_args.append(s)
eargs.append(str(s))

dest.append(expr)

self.calls.__dict__[eqn] = lambdify(eq_args, tuple(dest), 'numpy')
elist.append(expr)
if len(elist) == 0 or not any(elist): # `any`, not `all`
self.calls.__dict__[ename] = None
else:
self.calls.__dict__[ename] = lambdify(sym_args, tuple(elist), 'numpy')

# convert to SymPy matrices
self.f_matrix = Matrix(self.f_list)
Expand Down Expand Up @@ -1954,11 +1955,13 @@ def generate_jacobians(self):
self.calls.append_ijv(jname, e_idx, v_idx, 0)

free_syms = self._check_expr_symbols(e_symbolic)
j_args[jname].extend(free_syms)
for fs in free_syms:
if fs not in j_args[jname]:
j_args[jname].append(fs)
# j_args[jname].extend(free_syms)
j_calls[jname].append(e_symbolic)

for jname in j_calls:
j_args[jname] = list(set(j_args[jname]))
self.calls.j_args[jname] = [str(i) for i in j_args[jname]]
self.calls.j[jname] = lambdify(j_args[jname], tuple(j_calls[jname]), 'numpy')

Expand Down Expand Up @@ -2068,7 +2071,7 @@ def _rename_func(self, func, func_name):
return src


class Documenter(object):
class Documenter:
"""
Helper class for documenting models.
Expand Down
2 changes: 1 addition & 1 deletion andes/core/param.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
logger = logging.getLogger(__name__)


class BaseParam(object):
class BaseParam:
"""
The base parameter class.
Expand Down
2 changes: 1 addition & 1 deletion andes/core/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
logger = logging.getLogger(__name__)


class BaseService(object):
class BaseService:
"""
Base class for Service.
Expand Down
7 changes: 3 additions & 4 deletions andes/core/solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
logger = logging.getLogger(__name__)


class Solver(object):
class Solver:
"""
Sparse matrix solver class.
Expand All @@ -21,7 +21,6 @@ def __init__(self, sparselib='umfpack'):

# check if `sparselib` library has been successfully imported
if (sparselib not in globals()) or globals()[sparselib] is None:
logger.warning(f"Sparse solver {sparselib} not available. Using UMFPACK.")
self.sparselib = 'umfpack'

# solvers
Expand Down Expand Up @@ -75,7 +74,7 @@ def clear(self):
self.worker.clear()


class SuiteSparseSolver(object):
class SuiteSparseSolver:
"""
Base SuiteSparse solver interface.
Expand Down Expand Up @@ -280,7 +279,7 @@ def linsolve(self, A, b):
return np.ravel(b)


class SciPySolver(object):
class SciPySolver:
"""
Base class for scipy family solvers.
"""
Expand Down
2 changes: 1 addition & 1 deletion andes/core/var.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from andes.shared import np, ndarray


class BaseVar(object):
class BaseVar:
"""
Base variable class.
Expand Down
4 changes: 2 additions & 2 deletions andes/io/psse.py
Original file line number Diff line number Diff line change
Expand Up @@ -618,10 +618,10 @@ def sort_psse_models(dyr_yaml):
"""
Sort supported models so that model names are ordered by dependency.
"""
from andes.models import non_jit
from andes.models import file_classes
from andes.utils.func import list_flatten

andes_models = list_flatten(list(non_jit.values()))
andes_models = list_flatten(list(file_classes.values()))
number = dict()

for psse_model in dyr_yaml:
Expand Down
Loading

0 comments on commit 5d0885a

Please sign in to comment.