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
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
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
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])
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])
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')
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
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')
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
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
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
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)
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'))
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)
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)
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'))