Skip to content

Commit 2aee5b3

Browse files
committed
Implement handling static concepts in equations
1 parent 8a8c3d3 commit 2aee5b3

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

mira/sources/sympy_ode/__init__.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,17 +149,23 @@ def template_model_from_sympy_odes(odes, concept_data=None, param_data=None):
149149
raise ValueError("Multiple time variables in the ODEs")
150150
time_variable = time_variables.pop()
151151

152-
# Step 2: determine LHS variables
152+
# Step 2: determine LHS variables and handle static concepts
153+
is_static = set()
153154
for ode in odes:
154155
lhs_fun = ode.lhs.args[0]
155156
variable_name = lhs_fun.name
156157
variables.append(variable_name)
158+
if ode.rhs == 0:
159+
is_static.add(variable_name)
157160

158161
# Step 3: Interpret RHS equations and build a hypergraph
159162
parameters = set()
160163
all_terms = []
161164
G = Hypergraph()
162165
for lhs_variable, eq in zip(variables, odes):
166+
# No terms to add for static variables
167+
if lhs_variable in is_static:
168+
continue
163169
# Break up the RHS into a sum of terms
164170
terms = eq.rhs.as_ordered_terms()
165171
for term_idx, term in enumerate(terms):
@@ -205,9 +211,15 @@ def template_model_from_sympy_odes(odes, concept_data=None, param_data=None):
205211
# Remove ambiguous edges
206212
G.remove_ambiguous_edges()
207213

208-
# We first look at unconnected nodes of the graph and construct
209-
# production or degradation templates
210214
templates = []
215+
216+
# We first handle static concepts
217+
for variable in is_static:
218+
concept = make_concept(variable, concept_data)
219+
templates.append(StaticConcept(subject=concept))
220+
221+
# We next look at unconnected nodes of the graph and construct
222+
# production or degradation templates
211223
for node in G.get_unconnected_nodes():
212224
data = G.nodes[node]
213225
term = data['term']

tests/test_sympy_odes.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import sympy
22
from sympy import Function, symbols, Eq, Symbol
33

4+
from mira.metamodel import StaticConcept
45
from mira.sources.sympy_ode import template_model_from_sympy_odes
56

67

@@ -279,3 +280,24 @@ def test_large_model():
279280
tm = template_model_from_sympy_odes(equations)
280281

281282
assert len(tm.templates) == 67
283+
284+
285+
def test_extract_static():
286+
# Define time variable
287+
t = sympy.symbols("t")
288+
289+
# Define variables with time derivative to be time-dependent functions
290+
DP, TE, EV, PS, ASI = sympy.symbols("DP TE EV PS ASI", cls=sympy.Function)
291+
292+
# Define the equations without time-derivative on the left hand side
293+
equation_output = [
294+
sympy.Eq(DP(t).diff(t), 0),
295+
sympy.Eq(TE(t).diff(t), 0),
296+
sympy.Eq(EV(t).diff(t), 0),
297+
sympy.Eq(PS(t).diff(t), 0),
298+
sympy.Eq(ASI(t).diff(t), 0),
299+
]
300+
301+
tm = template_model_from_sympy_odes(equation_output)
302+
303+
assert all(isinstance(t, StaticConcept) for t in tm.templates)

0 commit comments

Comments
 (0)