Skip to content

Native odesys ignores provided parameters if it is based on SymbolicSys created by chempy #105

@niklastoe

Description

@niklastoe

I tried your example on native odesys. Providing different parameters leads to different concentrations as it should.

Now I noticed that if I construct the odesys using chempy, the results stay the same even if I change the parameters:

from chempy import ReactionSystem  # The rate constants below are arbitrary
from chempy.kinetics.ode import get_odesys
from collections import defaultdict
import numpy as np

from pyodesys.native import native_sys

rsys = ReactionSystem.from_string("""2 Fe+2 + H2O2 -> 2 Fe+3 + 2 OH-; 42
    2 Fe+3 + H2O2 -> 2 Fe+2 + O2 + 2 H+; 17
    H+ + OH- -> H2O; 1e10
    H2O -> H+ + OH-; 1e-4""")  # "[H2O]" = 1.0 (actually 55.4 at RT)
chempy_odesys, extra = get_odesys(rsys)

tout = sorted(np.concatenate((np.linspace(0, 23), np.logspace(-8, 1))))
c0 = defaultdict(float, {'Fe+2': 0.05, 'H2O2': 0.1, 'H2O': 1.0, 'H+': 1e-2, 'OH-': 1e-12})

print('Results from symbolic odesys')
result = chempy_odesys.integrate(tout, c0, atol=1e-12, rtol=1e-14)
np.array(result.at(tout))[-1,0]

chempy_native = native_sys['cvode'].from_other(chempy_odesys)

print('Results from native odesys without providing parameters')
result_chempy_native = chempy_native.integrate(tout, c0)
np.array(result_chempy_native.at(tout))[-1,0]

chempy_org_params = rsys.params()

print('Results from native odesys providing old parameters: ' + str(chempy_org_params))
result_chempy_native_org_params = chempy_native.integrate(tout, c0, chempy_org_params)
np.array(result_chempy_native_org_params.at(tout))[-1,0]

chempy_new_params = [4.2, 1.7, 1e5, 1e-2]
print('Results from native odesys providing new parameters: ' + str(chempy_new_params))
result_chempy_native_new_params = chempy_native.integrate(tout, c0, chempy_new_params)
np.array(result_chempy_native_new_params.at(tout))[-1,0]

print(chempy_org_params)
print(chempy_new_params)
print(np.array(chempy_org_params) / np.array(chempy_new_params))

The output:

Results from symbolic odesys

array([1.94487014e-02, 3.05512986e-02, 7.38097945e-12, 1.05023516e+00,
       4.44891879e-02, 2.01175814e-02, 2.05512986e-02])

Results from native odesys without providing parameters

INFO:pyodesys.native._base:In "/tmp/tmpGbkXsw_pycodeexport_pyodesys_NativeCvodeCode", executing:
"/usr/bin/g++ -c -std=c++11 -Wall -Wextra -fPIC -O2 -ffast-math -funroll-loops -fopenmp -o ./odesys_anyode.o -I/home/niklas/anaconda2/lib/python2.7/site-packages/numpy/core/include -I/home/niklas/anaconda2/lib/python2.7/site-packages/pyodesys/native/sources -I/home/niklas/anaconda2/lib/python2.7/site-packages/pycvodes/include odesys_anyode.cpp"
INFO:pyodesys.native._base:In "/tmp/tmpGbkXsw_pycodeexport_pyodesys_NativeCvodeCode", executing:
"/usr/bin/g++ -pthread -shared -std=c++11 -Wall -Wextra -fPIC -O2 -ffast-math -funroll-loops -fopenmp -o /tmp/tmpGbkXsw_pycodeexport_pyodesys_NativeCvodeCode/_cvode_wrapper.so -I/home/niklas/anaconda2/lib/python2.7/site-packages/numpy/core/include -I/home/niklas/anaconda2/lib/python2.7/site-packages/pyodesys/native/sources -I/home/niklas/anaconda2/lib/python2.7/site-packages/pycvodes/include odesys_anyode.o _cvode_wrapper.o -lsundials_cvodes -lsundials_nvecserial -lsundials_sunlinsollapackdense -lsundials_sunlinsollapackband -lopenblas -lpython2.7"

array([ 1.94486898e-02,  3.05513102e-02, -2.05513102e-02,  1.07078646e+00,
        4.44891934e-02,  2.01175757e-02, -7.42631650e-12])

Results from native odesys providing old parameters: [42, 17, 10000000000.0, 0.0001]

array([ 1.94486898e-02,  3.05513102e-02, -2.05513102e-02,  1.07078646e+00,
        4.44891934e-02,  2.01175757e-02, -7.42631650e-12])

Results from native odesys providing new parameters: [4.2, 1.7, 100000.0, 0.01]

array([ 1.94486898e-02,  3.05513102e-02, -2.05513102e-02,  1.07078646e+00,
        4.44891934e-02,  2.01175757e-02, -7.42631650e-12])

[42, 17, 10000000000.0, 0.0001]
[4.2, 1.7, 100000.0, 0.01]
[1.e+01 1.e+01 1.e+05 1.e-02]

There are minor numerical differences between the results from the symbolic odesys and the native one. In the latter, the ordering of species is slightly different and there are some negative concentrations, though. Can their absolute values be safely used or this there something wrong with them?
The provided parameters change nothing, though. Is there a way to make this work? Thanks in advance!

chempy 0.6.15
pyodesys 0.11.17
python 2.7.15

same behaviour with
chempy 0.7.6
pyodesys 0.12.4

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions