def add_diffeq(self, name, eq, unit, global_namespace={}, local_namespace={}, nonzero=True): ''' unit may contain "(event-driven)" ''' pattern = re.compile("(\w+)\s*\(event\-driven\)\s*") result = pattern.match(unit) # event-driven if result: unit, = result.groups() # We treat as a diff eq to get the correct namespaces Equations.add_diffeq(self, name, eq, unit, global_namespace, local_namespace, nonzero=False) if isinstance(unit, Quantity): unit = scalar_representation(unit) self._string[name] = '0*' + unit + '/second' self._namespace[name]['second'] = second # then add it to the list of event-driven variables self._eventdriven[name] = eq else: Equations.add_diffeq(self, name, eq, unit, global_namespace, local_namespace, nonzero)
def separate_equations(eqs, additional_dependencies=[]): eqs.prepare() all_vars = eqs._string.keys() # Construct a list of dependency sets, where each variable in each # dependency set induces a dependency on each other variable in each # dependency set depsets = [] for var in all_vars: ids = set(get_identifiers(eqs._string[var])) ids = ids.intersection(all_vars) ids.add(var) depsets.append(ids) for expr in additional_dependencies: ids = set(get_identifiers(expr)) ids = ids.intersection(all_vars) depsets.append(ids) # Construct a graph deps which indicates what variable depends on which # other variables (or is depended on by other variables). deps = defaultdict(set) for ids in depsets: for id1 in ids: for id2 in ids: deps[id1].add(id2) # Extract all the independent subgraphs ind_graphs = [] while len(deps): ind_graphs.append(set(next_independent_subgraph(deps).keys())) if len(ind_graphs) == 1: return [eqs] # Finally, we construct an Equations object for each of the subgraphs ind_eqs = [] for G in ind_graphs: neweqs = Equations() for var in G: if var in eqs._eq_names: neweqs.add_eq(var, eqs._string[var], eqs._units[var], local_namespace=eqs._namespace[var]) elif var in eqs._diffeq_names: nonzero = var in eqs._diffeq_names_nonzero neweqs.add_diffeq(var, eqs._string[var], eqs._units[var], local_namespace=eqs._namespace[var], nonzero=nonzero) elif var in eqs._alias.keys(): neweqs.add_alias(var, eqs._string[var].strip()) else: assert False ind_eqs.append(neweqs) return ind_eqs
def add_diffeq(self, name, eq, unit, global_namespace={}, local_namespace={}, nonzero=True): ''' unit may contain "(event-driven)" ''' pattern=re.compile("(\w+)\s*\(event\-driven\)\s*") result=pattern.match(unit) # event-driven if result: unit, = result.groups() # We treat as a diff eq to get the correct namespaces Equations.add_diffeq(self,name, eq, unit, global_namespace, local_namespace, nonzero=False) if isinstance(unit, Quantity): unit = scalar_representation(unit) self._string[name]='0*' + unit + '/second' self._namespace[name]['second']=second # then add it to the list of event-driven variables self._eventdriven[name]=eq else: Equations.add_diffeq(self,name, eq, unit, global_namespace, local_namespace, nonzero)