예제 #1
0
def test_events_code_generating(tmpfile):
    dsargs, _ = vanDerPol()
    dsargs['nobuild'] = True
    ev_args = {
        'name': 'monitor',
        'eventtol': 1e-4,
        'eventdelay': 1e-5,
        'starttime': 0,
        'active': True,
        'term': False,
        'precise': True
    }
    ev = Events.makeZeroCrossEvent('y', 0, ev_args, ['y'], targetlang='c')
    dsargs['events'] = [ev]

    ode = Radau_ODEsystem(dsargs)
    ode.makeLibSource(fname=tmpfile)

    with open(tmpfile) as g:
        code = g.read()
        assert 'double monitor(unsigned n_, double t, double *Y_, double *p_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_);' in code
        assert 'int N_EVENTS = 1;' in code
        assert 'void assignEvents(EvFunType *events){\n events[0] = &monitor;\n\n}' in code
        assert '\n'.join([
        'double monitor(unsigned n_, double t, double *Y_, double *p_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_) {',
        'return  y; ',
        '}']) in code
예제 #2
0
def test_events_code_generating(tmpfile):
    dsargs, _ = vanDerPol()
    dsargs['nobuild'] = True
    ev_args = {
        'name': 'monitor',
        'eventtol': 1e-4,
        'eventdelay': 1e-5,
        'starttime': 0,
        'active': True,
        'term': False,
        'precise': True
    }
    ev = Events.makeZeroCrossEvent('y', 0, ev_args, ['y'], targetlang='c')
    dsargs['events'] = [ev]

    ode = Radau_ODEsystem(dsargs)
    ode.makeLibSource(fname=tmpfile)

    with open(tmpfile) as g:
        code = g.read()
        assert 'double monitor(unsigned n_, double t, double *Y_, double *p_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_);' in code
        assert 'int N_EVENTS = 1;' in code
        assert 'void assignEvents(EvFunType *events){\n events[0] = &monitor;\n\n}' in code
        assert '\n'.join([
            'double monitor(unsigned n_, double t, double *Y_, double *p_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_) {',
            'return  y; ', '}'
        ]) in code
예제 #3
0
def test_explicitfngen():
    """Test of Explicit and Implicit Function generators, global time, and deletion"""

    ev_args = {'name': 'threshold',
               'eventtol': 1e-4,
               'eventdelay': 1e-5,
               'starttime': 0,
               'active': True,
               'term': True,
               'precise': True}
    thresh_ev = Events.makePythonStateZeroCrossEvent('t', 20, 1, ev_args)

    DSargs = {'tdomain': [-50, 50],
            'pars': {'speed': 1},
            'xdomain': {'s': [-1., 1.]},
            'name': 'sine',
            'globalt0': 0.4,
            'pdomain': {'speed': [0, 200]},
            'varspecs': {'s': "sin(globalindepvar(t)*speed)"},
            'events': thresh_ev}
    sin_gen = ExplicitFnGen(DSargs)
    sintraj1 = sin_gen.compute('sine1')
    assert sintraj1.globalt0 == 0.4
    assert sintraj1(0) == sin(0.4)

    sin_gen.set(pars={'speed': 2})
    sintraj2 = sin_gen.compute('sine2')

    # sintraj2 independent variable domain truncated at terminal event
    assert allclose(sin_gen.getEventTimes()['threshold'], 20+sintraj1.globalt0)
    assert sintraj2.indepdomain[0] == -50
    assert abs(sintraj2.indepdomain[1] - 20) < 1e-4
예제 #4
0
def test_ode_system(tb_args):
    fvarspecs = {
        "w": "k*w + a*itable + sin(t) + myauxfn1(t)*myauxfn2(w)",
        'aux_wdouble': 'w*2 + globalindepvar(t)',
        'aux_other': 'myauxfn1(2*t) + initcond(w)'
    }
    fnspecs = {'myauxfn1': (['t'], '2.5*cos(3*t)'), 'myauxfn2': (['w'], 'w/2')}
    DSargs = {
        'tdomain': [0.1, 2.1],
        'pars': {
            'k': 2,
            'a': -0.5
        },
        'inputs': {
            'itable': InterpolateTable(tb_args).variables['x1']
        },
        'auxvars': ['aux_wdouble', 'aux_other'],
        'algparams': {
            'init_step': 0.01,
            'strict': False
        },
        'checklevel': 2,
        'name': 'ODEtest',
        'fnspecs': fnspecs,
        'varspecs': fvarspecs
    }
    testODE = Vode_ODEsystem(DSargs)
    assert testODE.pars == DSargs['pars']
    assert (not testODE.defined)
    testODE.set(ics={'w': 3.0}, tdata=[0.11, 2.1])
    testtraj = testODE.compute('test1')
    assert testODE.defined
    assert_almost_equal(testtraj(0.5, 'w'), 6.05867901304, 3)
    assert_almost_equal(testtraj(0.2, 'aux_other'), 3.90581993688, 3)
    assert testODE.indepvariable.depdomain == Interval('t', float64,
                                                       [0.11, 2.1])
    assert testODE.diagnostics.hasWarnings()
    assert testODE.diagnostics.findWarnings(21) != []

    # Now adding a terminating co-ordinate threshold event...
    ev_args = {
        'name': 'threshold',
        'eventtol': 1e-4,
        'eventdelay': 1e-5,
        'starttime': 0,
        'active': True,  # = default
        'term': True,
        'precise': True  # = default
    }
    thresh_ev = Events.makePythonStateZeroCrossEvent('w', 20, 1, ev_args)
    testODE.eventstruct.add(thresh_ev)
    traj2 = testODE.compute('test2')
    assert testODE.diagnostics.hasWarnings()
    assert testODE.diagnostics.findWarnings(10) != []
    print(testODE.diagnostics.showWarnings())
    assert_almost_equal(traj2.getEventTimes()['threshold'][0], 1.51449456, 3)
    assert testODE.indepvariable.depdomain == Interval('t', float64,
                                                       [0.11, 2.1])
예제 #5
0
def test_ode_system(tb_args):
    fvarspecs = {
        "w": "k*w + a*itable + sin(t) + myauxfn1(t)*myauxfn2(w)",
        'aux_wdouble': 'w*2 + globalindepvar(t)',
        'aux_other': 'myauxfn1(2*t) + initcond(w)'
    }
    fnspecs = {
        'myauxfn1': (['t'], '2.5*cos(3*t)'),
        'myauxfn2': (['w'], 'w/2')
    }
    DSargs = {
        'tdomain': [0.1, 2.1],
        'pars': {'k': 2, 'a': -0.5},
        'inputs': {'itable': InterpolateTable(tb_args).variables['x1']},
        'auxvars': ['aux_wdouble', 'aux_other'],
        'algparams': {'init_step': 0.01, 'strict': False},
        'checklevel': 2,
        'name': 'ODEtest',
        'fnspecs': fnspecs,
        'varspecs': fvarspecs
    }
    testODE = Vode_ODEsystem(DSargs)
    assert testODE.pars == DSargs['pars']
    assert (not testODE.defined)
    testODE.set(
        ics={'w': 3.0},
        tdata=[0.11, 2.1]
    )
    testtraj = testODE.compute('test1')
    assert testODE.defined
    assert_almost_equal(testtraj(0.5, 'w'), 6.05867901304, 3)
    assert_almost_equal(testtraj(0.2, 'aux_other'), 3.90581993688, 3)
    assert testODE.indepvariable.depdomain == Interval(
        't', float64, [0.11, 2.1])
    assert testODE.diagnostics.hasWarnings()
    assert testODE.diagnostics.findWarnings(21) != []

    # Now adding a terminating co-ordinate threshold event...
    ev_args = {
        'name': 'threshold',
        'eventtol': 1e-4,
        'eventdelay': 1e-5,
        'starttime': 0,
        'active': True,  # = default
        'term': True,
        'precise': True  # = default
    }
    thresh_ev = Events.makePythonStateZeroCrossEvent('w', 20, 1, ev_args)
    testODE.eventstruct.add(thresh_ev)
    traj2 = testODE.compute('test2')
    assert testODE.diagnostics.hasWarnings()
    assert testODE.diagnostics.findWarnings(10) != []
    print(testODE.diagnostics.showWarnings())
    assert_almost_equal(traj2.getEventTimes()['threshold'][0], 1.51449456, 3)
    assert testODE.indepvariable.depdomain == Interval(
        't', float64, [0.11, 2.1])
예제 #6
0
def test_saveload_vode_odesystem(interptable):
    """Test pickling for saving and loading 'Vode_ODEsystem' Generator"""

    # Vode object with event and external input trajectory (defined earlier)
    fvarspecs = {
        "w": "k*w + a*itable + sin(t) + myauxfn1(t)*myauxfn2(w)",
        'aux_wdouble': 'w*2 + globalindepvar(t)',
        'aux_other': 'myauxfn1(2*t) + initcond(w)'
    }
    fnspecs = {'myauxfn1': (['t'], '2.5*cos(3*t)'), 'myauxfn2': (['w'], 'w/2')}
    ev_args = {
        'name': 'threshold',
        'eventtol': 1e-4,
        'eventdelay': 1e-5,
        'starttime': 0,
        'term': True,
    }
    thresh_ev = Events.makePythonStateZeroCrossEvent('w', 20, 1, ev_args)
    DSargs = {
        'tdomain': [0.1, 2.1],
        'tdata': [0.11, 2.1],
        'ics': {
            'w': 3.0
        },
        'pars': {
            'k': 2,
            'a': -0.5
        },
        'inputs': {
            'itable': interptable.variables['x1']
        },
        'auxvars': ['aux_wdouble', 'aux_other'],
        'algparams': {
            'init_step': 0.01,
            'strict': False
        },
        'events': thresh_ev,
        'checklevel': 2,
        'name': 'ODEtest',
        'fnspecs': fnspecs,
        'varspecs': fvarspecs
    }
    testODE = Vode_ODEsystem(DSargs)
    odetraj = testODE.compute('testode')
    saveObjects([odetraj, testODE], 'temp_objects.pkl', True)
    objs_ode = loadObjects('temp_objects.pkl')
    objs_ode[1].diagnostics.clearWarnings()
    assert len(objs_ode[1].diagnostics.warnings) == 0
    odetraj2 = objs_ode[1].compute('testode2')
    assert odetraj2(0.6) == odetraj(0.6)
    assert len(objs_ode[1].diagnostics.warnings) == 1
    os.remove('temp_objects.pkl')
예제 #7
0
def test_explicitfngen():
    """Test of Explicit and Implicit Function generators, global time, and deletion"""

    ev_args = {
        'name': 'threshold',
        'eventtol': 1e-4,
        'eventdelay': 1e-5,
        'starttime': 0,
        'active': True,
        'term': True,
        'precise': True
    }
    thresh_ev = Events.makePythonStateZeroCrossEvent('t', 20, 1, ev_args)

    DSargs = {
        'tdomain': [-50, 50],
        'pars': {
            'speed': 1
        },
        'xdomain': {
            's': [-1., 1.]
        },
        'name': 'sine',
        'globalt0': 0.4,
        'pdomain': {
            'speed': [0, 200]
        },
        'varspecs': {
            's': "sin(globalindepvar(t)*speed)"
        },
        'events': thresh_ev
    }
    sin_gen = ExplicitFnGen(DSargs)
    sintraj1 = sin_gen.compute('sine1')
    assert sintraj1.globalt0 == 0.4
    assert sintraj1(0) == sin(0.4)

    sin_gen.set(pars={'speed': 2})
    sintraj2 = sin_gen.compute('sine2')

    # sintraj2 independent variable domain truncated at terminal event
    assert allclose(sin_gen.getEventTimes()['threshold'],
                    20 + sintraj1.globalt0)
    assert sintraj2.indepdomain[0] == -50
    assert abs(sintraj2.indepdomain[1] - 20) < 1e-4
예제 #8
0
def test_saveload_vode_odesystem(interptable):
    """Test pickling for saving and loading 'Vode_ODEsystem' Generator"""

    # Vode object with event and external input trajectory (defined earlier)
    fvarspecs = {
        "w": "k*w + a*itable + sin(t) + myauxfn1(t)*myauxfn2(w)",
        'aux_wdouble': 'w*2 + globalindepvar(t)',
        'aux_other': 'myauxfn1(2*t) + initcond(w)'
    }
    fnspecs = {
        'myauxfn1': (['t'], '2.5*cos(3*t)'),
        'myauxfn2': (['w'], 'w/2')
    }
    ev_args = {
        'name': 'threshold',
        'eventtol': 1e-4,
        'eventdelay': 1e-5,
        'starttime': 0,
        'term': True,
    }
    thresh_ev = Events.makePythonStateZeroCrossEvent('w', 20, 1, ev_args)
    DSargs = {
        'tdomain': [0.1, 2.1],
        'tdata': [0.11, 2.1],
        'ics': {'w': 3.0},
        'pars': {'k': 2, 'a': -0.5},
        'inputs': {'itable': interptable.variables['x1']},
        'auxvars': ['aux_wdouble', 'aux_other'],
        'algparams': {'init_step': 0.01, 'strict': False},
        'events': thresh_ev,
        'checklevel': 2,
        'name': 'ODEtest',
        'fnspecs': fnspecs,
        'varspecs': fvarspecs
    }
    testODE = Vode_ODEsystem(DSargs)
    odetraj = testODE.compute('testode')
    saveObjects([odetraj, testODE], 'temp_objects.pkl', True)
    objs_ode = loadObjects('temp_objects.pkl')
    objs_ode[1].diagnostics.clearWarnings()
    assert len(objs_ode[1].diagnostics.warnings) == 0
    odetraj2 = objs_ode[1].compute('testode2')
    assert odetraj2(0.6) == odetraj(0.6)
    assert len(objs_ode[1].diagnostics.warnings) == 1
    os.remove('temp_objects.pkl')
예제 #9
0
def test_vode_events_with_external_input(my_input):
    """
        Test Vode_ODEsystem with events involving external inputs.
        Robert Clewley, September 2006.
    """
    xs = ['x1', 'x2', 'x3']
    ys = [0, 0.5, 1]
    fvarspecs = {"w": "k*w  + pcwfn(sin(t)) + myauxfn1(t)*myauxfn2(w)",
                 'aux_wdouble': 'w*2 + globalindepvar(t)',
                 'aux_other': 'myauxfn1(2*t) + initcond(w)'}
    fnspecs = {'myauxfn1': (['t'], '2.5*cos(3*t)'),
               'myauxfn2': (['w'], 'w/2'),
               'pcwfn': makeMultilinearRegrFn('x', xs, ys)}
    # targetlang is optional if the default python target is desired
    DSargs = args(fnspecs=fnspecs, name='ODEtest')
    DSargs.varspecs = fvarspecs
    DSargs.tdomain = [0.1, 2.1]
    DSargs.pars = {'k': 2, 'a': -0.5, 'x1': -3, 'x2': 0.5, 'x3': 1.5}
    DSargs.vars = 'w'
    DSargs.inputs = {'in': my_input.variables['example_input']}
    DSargs.algparams = {'init_step': 0.01}
    DSargs.checklevel = 2
    testODE = Vode_ODEsystem(DSargs)
    assert not testODE.defined
    testODE.set(ics={'w': 3.0},
                tdata=[0.11, 2.1])
    traj1 = testODE.compute('traj1')
    assert testODE.defined
    assert_almost_equal(traj1(0.5, 'w'), 8.9771499, 5)
    assert not testODE.diagnostics.hasWarnings()
    assert_almost_equal(traj1(0.2, ['aux_other']), 3.905819936, 5)
    print("\nNow adding a terminating co-ordinate threshold event")
    print(" and non-terminating timer event")
    # Show off the general-purpose, language-independent event creator:
    #  'makeZeroCrossEvent'
    ev_args_nonterm = {'name': 'monitor',
                       'eventtol': 1e-4,
                       'eventdelay': 1e-5,
                       'starttime': 0,
                       'active': True,
                       'term': False,
                       'precise': True}
    thresh_ev_nonterm = Events.makeZeroCrossEvent('in', 0,
                                                  ev_args_nonterm, inputnames=['in'])
    # Now show use of the python-target specific creator:
    #  'makePythonStateZeroCrossEvent', which is also only
    #  able to make events for state variable threshold crossings
    ev_args_term = {'name': 'threshold',
                    'eventtol': 1e-4,
                    'eventdelay': 1e-5,
                    'starttime': 0,
                    'active': True,
                    'term': True,
                    'precise': True}
    thresh_ev_term = Events.makePythonStateZeroCrossEvent('w',
                                                          20, 1, ev_args_term)
    testODE.eventstruct.add([thresh_ev_nonterm, thresh_ev_term])
    print("Recomputing trajectory:")
    print("traj2 = testODE.compute('traj2')")
    traj2 = testODE.compute('traj2')
    print("\ntestODE.diagnostics.showWarnings() => ")
    testODE.diagnostics.showWarnings()
    print("\ntraj2.indepdomain.get() => ", traj2.indepdomain.get())
    indep1 = traj2.indepdomain[1]
    assert indep1 < 1.17 and indep1 > 1.16
    mon_evs_found = testODE.getEvents('monitor')
    assert len(mon_evs_found) == 1
예제 #10
0
def dsargs():
    timeData = linspace(0, 10, 20)
    sindata = sin(20 * timeData)
    xData = {'in': sindata}
    my_input = InterpolateTable({
        'tdata': timeData,
        'ics': xData,
        'name': 'interp1d',
        'method': 'linear',
        'checklevel': 1,
        'abseps': 1e-5
    }).compute('interp')

    fvarspecs = {
        "w": "k*w  + sin(t) + myauxfn1(t)*myauxfn2(w)",
        'aux_wdouble': 'w*2 + globalindepvar(t)',
        'aux_other': 'myauxfn1(2*t) + initcond(w)'
    }
    fnspecs = {'myauxfn1': (['t'], '2.5*cos(3*t)'), 'myauxfn2': (['w'], 'w/2')}
    # targetlang is optional if the default python target is desired
    DSargs = args(fnspecs=fnspecs, name='event_test')
    DSargs.varspecs = fvarspecs
    DSargs.tdomain = [0.1, 2.1]
    DSargs.pars = {'k': 2, 'a': -0.5}
    DSargs.vars = 'w'
    DSargs.ics = {'w': 3}
    DSargs.inputs = {'in': my_input.variables['in']}
    DSargs.algparams = {'init_step': 0.01}
    DSargs.checklevel = 2
    ev_args_nonterm = {
        'name': 'monitor',
        'eventtol': 1e-4,
        'eventdelay': 1e-5,
        'starttime': 0,
        'active': True,
        'term': False,
        'precise': True
    }
    thresh_ev_nonterm = Events.makeZeroCrossEvent('in',
                                                  0,
                                                  ev_args_nonterm,
                                                  inputnames=['in'],
                                                  targetlang='c')

    ev_args_term = {
        'name': 'threshold',
        'eventtol': 1e-4,
        'eventdelay': 1e-5,
        'starttime': 0,
        'active': True,
        'term': True,
        'precise': True
    }

    thresh_ev_term = Events.makeZeroCrossEvent('w-20',
                                               1,
                                               ev_args_term, ['w'],
                                               targetlang='c')
    DSargs.events = [thresh_ev_nonterm, thresh_ev_term]

    return DSargs
예제 #11
0
파일: test_events.py 프로젝트: F-A/pydstool
def dsargs():
    timeData = linspace(0, 10, 20)
    sindata = sin(20 * timeData)
    xData = {'in': sindata}
    my_input = InterpolateTable({
        'tdata': timeData,
        'ics': xData,
        'name': 'interp1d',
        'method': 'linear',
        'checklevel': 1,
        'abseps': 1e-5
    }).compute('interp')

    fvarspecs = {
        "w": "k*w  + sin(t) + myauxfn1(t)*myauxfn2(w)",
        'aux_wdouble': 'w*2 + globalindepvar(t)',
        'aux_other': 'myauxfn1(2*t) + initcond(w)'
    }
    fnspecs = {
        'myauxfn1': (['t'], '2.5*cos(3*t)'),
        'myauxfn2': (['w'], 'w/2')
    }
    # targetlang is optional if the default python target is desired
    DSargs = args(fnspecs=fnspecs, name='event_test')
    DSargs.varspecs = fvarspecs
    DSargs.tdomain = [0.1, 2.1]
    DSargs.pars = {'k': 2, 'a': -0.5}
    DSargs.vars = 'w'
    DSargs.ics = {'w': 3}
    DSargs.inputs = {'in': my_input.variables['in']}
    DSargs.algparams = {'init_step': 0.01}
    DSargs.checklevel = 2
    ev_args_nonterm = {
        'name': 'monitor',
        'eventtol': 1e-4,
        'eventdelay': 1e-5,
        'starttime': 0,
        'active': True,
        'term': False,
        'precise': True
    }
    thresh_ev_nonterm = Events.makeZeroCrossEvent(
        'in',
        0,
        ev_args_nonterm,
        inputnames=['in'],
        targetlang='c'
    )

    ev_args_term = {
        'name': 'threshold',
        'eventtol': 1e-4,
        'eventdelay': 1e-5,
        'starttime': 0,
        'active': True,
        'term': True,
        'precise': True
    }

    thresh_ev_term = Events.makeZeroCrossEvent(
        'w-20',
        1,
        ev_args_term,
        ['w'],
        targetlang='c'
    )
    DSargs.events = [thresh_ev_nonterm, thresh_ev_term]

    return DSargs
예제 #12
0
def test_vode_events_compare_with_euler():
    """
        Test terminal and non-terminal event testing with VODE integrator,
        including some comparisons and tests of Euler integrator too.
    """
    DSargs = args(varspecs={'w': 'k*sin(2*t) - w'}, name='ODEtest')
    DSargs.tdomain = [0, 10]
    DSargs.pars = {'k': 1, 'p_thresh': -0.25}
    DSargs.algparams = {'init_step': 0.001, 'atol': 1e-12, 'rtol': 1e-13}
    DSargs.checklevel = 2
    DSargs.ics = {'w': -1.0}
    DSargs.tdata = [0, 10]
    ev_args_nonterm = {'name': 'monitor',
                       'eventtol': 1e-4,
                       'eventdelay': 1e-5,
                       'starttime': 0,
                       'active': True,
                       'term': False,
                       'precise': True}
    thresh_ev_nonterm = Events.makeZeroCrossEvent('w', 0,
                                                  ev_args_nonterm, varnames=['w'])
    ev_args_term = {'name': 'threshold',
                    'eventtol': 1e-4,
                    'eventdelay': 1e-5,
                    'starttime': 0,
                    'active': True,
                    'term': True,
                    'precise': True}
    thresh_ev_term = Events.makeZeroCrossEvent('w-p_thresh',
                                               -1, ev_args_term, varnames=['w'], parnames=['p_thresh'])
    DSargs.events = [thresh_ev_nonterm, thresh_ev_term]
    testODE = Vode_ODEsystem(DSargs)
    # diagnostics and other possible user-defined python functions
    # for python solvers only (currently only Euler)
    # def before_func(euler):
    # print(euler.algparams['init_step'])
    #
    # def after_func(euler):
    # print(euler._solver.y)
    #
    ##DSargs.user_func_beforestep = before_func
    ##DSargs.user_func_afterstep = after_func
    testODE_Euler = Euler_ODEsystem(DSargs)
    traj = testODE.compute('traj')
    traj2 = testODE_Euler.compute('traj')
    pts = traj.sample()
    testODE.diagnostics.showWarnings()
    mon_evs_found = testODE.getEvents('monitor')
    term_evs_found = testODE.getEvents('threshold')
    # test Euler
    assert allclose(array(testODE.getEventTimes('monitor')),
                    array(traj2.getEventTimes('monitor')), atol=1e-3)
    assert all(traj.getEvents('monitor') == mon_evs_found)
    assert all(traj.getEventTimes('threshold')
               == testODE.getEventTimes('threshold'))
    term_evs_found.info()
    # Alternative way to extract events: they are labelled in the
    # pointset! These return dictionaries indexing into the pointset.
    mon_evs_dict = pts.labels.by_label['Event:monitor']
    mon_ev_points = pts[sort(list(mon_evs_dict.keys()))]
    assert len(mon_evs_found) == len(mon_ev_points) == 2
    assert all(mon_evs_found == mon_ev_points)
예제 #13
0
def test_vode_events_with_external_input(my_input):
    """
        Test Vode_ODEsystem with events involving external inputs.
        Robert Clewley, September 2006.
    """
    xs = ['x1', 'x2', 'x3']
    ys = [0, 0.5, 1]
    fvarspecs = {"w": "k*w  + pcwfn(sin(t)) + myauxfn1(t)*myauxfn2(w)",
                 'aux_wdouble': 'w*2 + globalindepvar(t)',
                 'aux_other': 'myauxfn1(2*t) + initcond(w)'}
    fnspecs = {'myauxfn1': (['t'], '2.5*cos(3*t)'),
               'myauxfn2': (['w'], 'w/2'),
               'pcwfn': makeMultilinearRegrFn('x', xs, ys)}
    # targetlang is optional if the default python target is desired
    DSargs = args(fnspecs=fnspecs, name='ODEtest')
    DSargs.varspecs = fvarspecs
    DSargs.tdomain = [0.1, 2.1]
    DSargs.pars = {'k': 2, 'a': -0.5, 'x1': -3, 'x2': 0.5, 'x3': 1.5}
    DSargs.vars = 'w'
    DSargs.inputs = {'in': my_input.variables['example_input']}
    DSargs.algparams = {'init_step': 0.01}
    DSargs.checklevel = 2
    testODE = Vode_ODEsystem(DSargs)
    assert not testODE.defined
    testODE.set(ics={'w': 3.0},
                tdata=[0.11, 2.1])
    traj1 = testODE.compute('traj1')
    assert testODE.defined
    assert_almost_equal(traj1(0.5, 'w'), 8.9771499, 5)
    assert not testODE.diagnostics.hasWarnings()
    assert_almost_equal(traj1(0.2, ['aux_other']), 3.905819936, 5)
    print("\nNow adding a terminating co-ordinate threshold event")
    print(" and non-terminating timer event")
    # Show off the general-purpose, language-independent event creator:
    #  'makeZeroCrossEvent'
    ev_args_nonterm = {'name': 'monitor',
                       'eventtol': 1e-4,
                       'eventdelay': 1e-5,
                       'starttime': 0,
                       'active': True,
                       'term': False,
                       'precise': True}
    thresh_ev_nonterm = Events.makeZeroCrossEvent('in', 0,
                                                  ev_args_nonterm, inputnames=['in'])
    # Now show use of the python-target specific creator:
    #  'makePythonStateZeroCrossEvent', which is also only
    #  able to make events for state variable threshold crossings
    ev_args_term = {'name': 'threshold',
                    'eventtol': 1e-4,
                    'eventdelay': 1e-5,
                    'starttime': 0,
                    'active': True,
                    'term': True,
                    'precise': True}
    thresh_ev_term = Events.makePythonStateZeroCrossEvent('w',
                                                          20, 1, ev_args_term)
    testODE.eventstruct.add([thresh_ev_nonterm, thresh_ev_term])
    print("Recomputing trajectory:")
    print("traj2 = testODE.compute('traj2')")
    traj2 = testODE.compute('traj2')
    print("\ntestODE.diagnostics.showWarnings() => ")
    testODE.diagnostics.showWarnings()
    print("\ntraj2.indepdomain.get() => ", traj2.indepdomain.get())
    indep1 = traj2.indepdomain[1]
    assert indep1 < 1.17 and indep1 > 1.16
    mon_evs_found = testODE.getEvents('monitor')
    assert len(mon_evs_found) == 1
예제 #14
0
def test_mapsystem():

    # datafn provides an external input to the map system -- this could have
    # been from an experimentally measured signal
    datafn = Generator.InterpolateTable(
        {'name': 'datafunction',
         'tdata': [-30., 0., 5., 10., 30., 100., 180., 400.],
         'ics': {'x': [4., 1., 0., 1., 2., 3., 4., 8.]}
         }
    )

    fvarspecs = {
        "w": "15-a*w + 2*x",
        "v": "1+k*w/10",
        'aux_wdouble': 'w*2 + globalindepvar(t)',
        'aux_other': 'myauxfn(2*t) + initcond(w)'
    }
    fnspecs = {
        'myauxfn': (['t'], '.5*cos(3*t)'),
    }

    # targetlang is optional if default=python is OK
    DSargs = args(name='maptest', fnspecs=fnspecs)
    DSargs.varspecs = fvarspecs
    DSargs.tdomain = [0, 400]
    DSargs.pars = {'k': 2.1, 'a': -0.5}
    DSargs.vars = ['w', 'v']
    DSargs.ttype = int  # force independent variable type to be integer
    DSargs.checklevel = 2
    DSargs.inputs = datafn.variables
    testmap = MapSystem(DSargs)
    assert testmap.pars == DSargs.pars
    assert not testmap.defined
    assert_array_almost_equal([0, 400], testmap.tdata)
    testmap.set(
        ics={'w': 3.0, 'v': 2.},
        tdata=[10, 400])
    assert_array_almost_equal([10, 400], testmap.tdata)
    assert_almost_equal(3.0, testmap.initialconditions['w'])
    assert_almost_equal(2.0, testmap.initialconditions['v'])

    traj1 = testmap.compute('traj1')
    assert testmap.defined
    p = Point({'coorddict': {
        'aux_other': 3.34962540324,
        'aux_wdouble': 98.1981323242,
        'v': 8.64360778809,
        'w': 36.5990661621,
    }})
    assert_almost_equal(p.toarray(), traj1(25).toarray())
    assert testmap.diagnostics.hasWarnings()
    assert_array_almost_equal(testmap.tdata, traj1.indepdomain.get())
    assert_almost_equal(2.70076996547, traj1(30, 'aux_other'))
    ps = traj1(range(10, 40))
    assert isinstance(ps, Pointset)
    assert ps._parameterized

    ev_args = {'name': 'threshold',
               'eventtol': 1e-4,
               'eventdelay': 1e-5,
               'starttime': 0,
               'active': True,
               'term': True,
               'precise': False}
    thresh_ev = Events.makePythonStateZeroCrossEvent('w', 58, 1, ev_args)
    testmap.eventstruct.add(thresh_ev)
    traj2 = testmap.compute('traj2')
    assert testmap.getEventTimes()['threshold'] == [347.]
    assert_array_almost_equal([10, 347], traj2.indepdomain.get())

    assert testmap.diagnostics.hasWarnings()
    assert testmap.diagnostics.findWarnings(10) != []
    assert_almost_equal(58.0, traj2(traj2.indepdomain[1], 'w'))
예제 #15
0
def test_vode_events_compare_with_euler():
    """
        Test terminal and non-terminal event testing with VODE integrator,
        including some comparisons and tests of Euler integrator too.
    """
    DSargs = args(varspecs={'w': 'k*sin(2*t) - w'}, name='ODEtest')
    DSargs.tdomain = [0, 10]
    DSargs.pars = {'k': 1, 'p_thresh': -0.25}
    DSargs.algparams = {'init_step': 0.001, 'atol': 1e-12, 'rtol': 1e-13}
    DSargs.checklevel = 2
    DSargs.ics = {'w': -1.0}
    DSargs.tdata = [0, 10]
    ev_args_nonterm = {'name': 'monitor',
                       'eventtol': 1e-4,
                       'eventdelay': 1e-5,
                       'starttime': 0,
                       'active': True,
                       'term': False,
                       'precise': True}
    thresh_ev_nonterm = Events.makeZeroCrossEvent('w', 0,
                                                  ev_args_nonterm, varnames=['w'])
    ev_args_term = {'name': 'threshold',
                    'eventtol': 1e-4,
                    'eventdelay': 1e-5,
                    'starttime': 0,
                    'active': True,
                    'term': True,
                    'precise': True}
    thresh_ev_term = Events.makeZeroCrossEvent('w-p_thresh',
                                               -1, ev_args_term, varnames=['w'], parnames=['p_thresh'])
    DSargs.events = [thresh_ev_nonterm, thresh_ev_term]
    testODE = Vode_ODEsystem(DSargs)
    # diagnostics and other possible user-defined python functions
    # for python solvers only (currently only Euler)
    # def before_func(euler):
    # print(euler.algparams['init_step'])
    #
    # def after_func(euler):
    # print(euler._solver.y)
    #
    ##DSargs.user_func_beforestep = before_func
    ##DSargs.user_func_afterstep = after_func
    testODE_Euler = Euler_ODEsystem(DSargs)
    traj = testODE.compute('traj')
    traj2 = testODE_Euler.compute('traj')
    pts = traj.sample()
    testODE.diagnostics.showWarnings()
    mon_evs_found = testODE.getEvents('monitor')
    term_evs_found = testODE.getEvents('threshold')
    # test Euler
    assert allclose(array(testODE.getEventTimes('monitor')),
                    array(traj2.getEventTimes('monitor')), atol=1e-3)
    assert all(traj.getEvents('monitor') == mon_evs_found)
    assert all(traj.getEventTimes('threshold')
               == testODE.getEventTimes('threshold'))
    term_evs_found.info()
    # Alternative way to extract events: they are labelled in the
    # pointset! These return dictionaries indexing into the pointset.
    mon_evs_dict = pts.labels.by_label['Event:monitor']
    mon_ev_points = pts[sort(mon_evs_dict.keys())]
    assert len(mon_evs_found) == len(mon_ev_points) == 2
    assert all(mon_evs_found == mon_ev_points)
예제 #16
0
 def _makeBoundsEvents(self,
                       precise=True,
                       eventtol=1e-6,
                       activatedbounds=None):
     events = []
     # pars + vars (pars used only by PyCont during continuation)
     alldoms = copy(self._pdomain)
     alldoms.update(self._xdomain)
     allnames = self.funcspec.vars + self.funcspec.pars
     if activatedbounds is None:
         activatedbounds = {}.fromkeys(allnames, (True, True))
     for xname, xdom in alldoms.iteritems():
         if xname not in allnames:
             # don't make bound constraints for non-state variables
             continue
         xdlo = xdom[0]
         xdhi = xdom[1]
         evname = xname + "_domlo"
         evargs = {
             'term': True,
             'precise': precise,
             'name': evname,
             'eventtol': eventtol,
             'eventdelay': eventtol * 10,
             'eventinterval': eventtol * 20,
             'xdomain': self._xdomain,
             'pdomain': self._pdomain
         }
         try:
             evargs['active'] = activatedbounds[xname][0] and isfinite(xdlo)
         except KeyError:
             evargs['active'] = False
         evstr = xname + '-' + 'getbound("%s", 0)' % xname
         ev = Events.makeZeroCrossEvent(evstr,
                                        -1,
                                        evargs, [xname],
                                        targetlang=self.funcspec.targetlang,
                                        reuseterms=self.funcspec.reuseterms)
         events.append(ev)
         evname = xname + "_domhi"
         evargs = {
             'term': True,
             'precise': precise,
             'name': evname,
             'eventtol': eventtol,
             'eventdelay': eventtol * 10,
             'eventinterval': eventtol * 20,
             'xdomain': self._xdomain,
             'pdomain': self._pdomain
         }
         try:
             evargs['active'] = activatedbounds[xname][1] and isfinite(xdhi)
         except KeyError:
             evargs['active'] = False
         evstr = xname + '-' + 'getbound("%s", 1)' % xname
         ev = Events.makeZeroCrossEvent(evstr,
                                        1,
                                        evargs, [xname],
                                        targetlang=self.funcspec.targetlang,
                                        reuseterms=self.funcspec.reuseterms)
         events.append(ev)
     if events != []:
         self._addEvents(events)
예제 #17
0
def test_mapsystem():

    # datafn provides an external input to the map system -- this could have
    # been from an experimentally measured signal
    datafn = Generator.InterpolateTable({
        'name':
        'datafunction',
        'tdata': [-30., 0., 5., 10., 30., 100., 180., 400.],
        'ics': {
            'x': [4., 1., 0., 1., 2., 3., 4., 8.]
        }
    })

    fvarspecs = {
        "w": "15-a*w + 2*x",
        "v": "1+k*w/10",
        'aux_wdouble': 'w*2 + globalindepvar(t)',
        'aux_other': 'myauxfn(2*t) + initcond(w)'
    }
    fnspecs = {
        'myauxfn': (['t'], '.5*cos(3*t)'),
    }

    # targetlang is optional if default=python is OK
    DSargs = args(name='maptest', fnspecs=fnspecs)
    DSargs.varspecs = fvarspecs
    DSargs.tdomain = [0, 400]
    DSargs.pars = {'k': 2.1, 'a': -0.5}
    DSargs.vars = ['w', 'v']
    DSargs.ttype = int  # force independent variable type to be integer
    DSargs.checklevel = 2
    DSargs.inputs = datafn.variables
    testmap = MapSystem(DSargs)
    assert testmap.pars == DSargs.pars
    assert not testmap.defined
    assert_array_almost_equal([0, 400], testmap.tdata)
    testmap.set(ics={'w': 3.0, 'v': 2.}, tdata=[10, 400])
    assert_array_almost_equal([10, 400], testmap.tdata)
    assert_almost_equal(3.0, testmap.initialconditions['w'])
    assert_almost_equal(2.0, testmap.initialconditions['v'])

    traj1 = testmap.compute('traj1')
    assert testmap.defined
    p = Point({
        'coorddict': {
            'aux_other': 3.34962540324,
            'aux_wdouble': 98.1981323242,
            'v': 8.64360778809,
            'w': 36.5990661621,
        }
    })
    assert_almost_equal(p.toarray(), traj1(25).toarray())
    assert testmap.diagnostics.hasWarnings()
    assert_array_almost_equal(testmap.tdata, traj1.indepdomain.get())
    assert_almost_equal(2.70076996547, traj1(30, 'aux_other'))
    ps = traj1(list(range(10, 40)))
    assert isinstance(ps, Pointset)
    assert ps._parameterized

    ev_args = {
        'name': 'threshold',
        'eventtol': 1e-4,
        'eventdelay': 1e-5,
        'starttime': 0,
        'active': True,
        'term': True,
        'precise': False
    }
    thresh_ev = Events.makePythonStateZeroCrossEvent('w', 58, 1, ev_args)
    testmap.eventstruct.add(thresh_ev)
    traj2 = testmap.compute('traj2')
    assert testmap.getEventTimes()['threshold'] == [347.]
    assert_array_almost_equal([10, 347], traj2.indepdomain.get())

    assert testmap.diagnostics.hasWarnings()
    assert testmap.diagnostics.findWarnings(10) != []
    assert_almost_equal(58.0, traj2(traj2.indepdomain[1], 'w'))