Skip to content

Commit

Permalink
Merge pull request #64 from cuihantao/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
cuihantao committed Apr 29, 2020
2 parents 8e93f61 + 9a1701b commit 0d2a613
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 11 deletions.
6 changes: 6 additions & 0 deletions andes/core/block.py
Expand Up @@ -90,6 +90,11 @@ def __init__(self, name: Optional[str] = None, tex_name: Optional[str] = None, i
self.owner = None
self.vars: Dict[str, Union[Algeb, State, Discrete]] = dict()
self.triplets = JacTriplet()
self.flags = dict(
f_num=False, # True if the block defines `f_numeric`
g_num=False, # True if the block defines `g_numeric`
j_num=False, # True if the block defines `j_numeric`
)

def __setattr__(self, key, value):
# handle sub-blocks by prepending self.name
Expand Down Expand Up @@ -297,6 +302,7 @@ def __init__(self, u, ref, kp, ki, name=None, info=None):
self.y = Algeb(info="Output value")

self.vars = {'xi': self.xi, 'y': self.y}
self.flags.update({'f_num': True, 'g_num': True, 'j_num': True})

def g_numeric(self, **kwargs):
self.y.e = self.kp.v * (self.ref.v - self.u.v) + self.xi.v
Expand Down
38 changes: 27 additions & 11 deletions andes/core/model.py
Expand Up @@ -118,6 +118,10 @@ class ModelData(object):
cache
A cache instance for different views of the internal data.
flags : dict
Flags to control the routine and functions that get called. If the model is using user-defined
numerical calls, set `f_num`, `g_num` and `j_num` properly.
Notes
-----
Two default parameters, `u` (connection status of type :py:class:`andes.core.param.NumParam`),
Expand Down Expand Up @@ -550,6 +554,9 @@ def __init__(self, system=None, config=None):
tds=False, # True if called during tds; if is False, ``dae_t`` cannot be used
series=False, # True if is series device
nr_iter=False, # True if require iterative initialization
f_num=False, # True if the model defines `f_numeric`
g_num=False, # True if the model defines `g_numeric`
j_num=False, # True if the model defines `j_numeric`
sys_base=False, # True if is parameters have been converted to system base
address=False, # True if address is assigned
initialized=False, # True if variables have been initialized
Expand Down Expand Up @@ -1244,11 +1251,14 @@ def store_sparse_pattern(self):
return

# store model-level user-defined Jacobians
self.j_numeric()
if self.flags['j_num'] is True:
self.j_numeric()

# store and merge user-defined Jacobians in blocks
for instance in self.blocks.values():
instance.j_numeric()
self.triplets.merge(instance.triplets)
if instance.flags['j_num'] is True:
instance.j_numeric()
self.triplets.merge(instance.triplets)

var_names_list = list(self.cache.all_vars.keys())
eq_names = {'f': var_names_list[:len(self.cache.states_and_ext)],
Expand Down Expand Up @@ -1332,18 +1342,21 @@ def f_update(self):
if (self.n == 0) or (not self.in_use):
return
kwargs = self.get_inputs()
args = kwargs.values()

# call lambda functions in self.call
ret = self.calls.f_lambdify(**kwargs)
ret = self.calls.f_lambdify(*args)
for idx, instance in enumerate(self.cache.states_and_ext.values()):
instance.e += ret[idx][0]

# numerical calls defined in the model
self.f_numeric(**kwargs)
# user-defined numerical calls defined in the model
if self.flags['f_num'] is True:
self.f_numeric(**kwargs)

# numerical calls in blocks
# user-defined numerical calls in blocks
for instance in self.blocks.values():
instance.f_numeric(**kwargs)
if instance.flags['f_num'] is True:
instance.f_numeric(**kwargs)

def g_update(self):
"""
Expand All @@ -1353,18 +1366,21 @@ def g_update(self):
if (self.n == 0) or (not self.in_use):
return
kwargs = self.get_inputs()
args = kwargs.values()

# call lambda functions stored in `self.calls`
ret = self.calls.g_lambdify(**kwargs)
ret = self.calls.g_lambdify(*args)
for idx, instance in enumerate(self.cache.algebs_and_ext.values()):
instance.e += ret[idx][0]

# numerical calls defined in the model
self.g_numeric(**kwargs)
if self.flags['g_num'] is True:
self.g_numeric(**kwargs)

# numerical calls in blocks
for instance in self.blocks.values():
instance.g_numeric(**kwargs)
if instance.flags['g_num'] is True:
instance.g_numeric(**kwargs)

def j_update(self):
"""
Expand Down
11 changes: 11 additions & 0 deletions docs/source/release-notes.rst
Expand Up @@ -4,6 +4,17 @@ Release Notes

The APIs before v1.0.0 are in beta and may change without prior notice.

v0.8.8 (2020-04-28)
-------------------
This update contains a quick but significant fix to boost the simulation speed by avoiding
calls to empty user-defined numerical calls.

- In `Model.flags` and `Block.flags`, added `f_num`, `g_num` and `j_num` to indicate
if user-defined numerical calls exist.
- In `Model.f_update`, `Model.g_update` and `Model.j_update`, check the above flags
to avoid unnecessary calls to empty numeric functions.
- For the `kundur_pss.xlsx` case, simulation time was reduced from 3.5s to 2.7s.

v0.8.7 (2020-04-28)
-------------------
- Changed `RefParam` to a service type called `BackRef`.
Expand Down

0 comments on commit 0d2a613

Please sign in to comment.