def test_ida_tstopfn_stop(self): #test calling sequence. End is reached at a tstop global n n = 0 tspan = np.arange(0, t_end2 + 1, 1.0, np.float) solver = dae('ida', rhs_fn, tstop=T1, ontstop=ontstop_vb, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag == StatusEnumIDA.TSTOP_RETURN, "ERROR: Error occurred" assert allclose( [soln.values.t[-1], soln.values.y[-1, 0], soln.values.y[-1, 1]], [10.0, 509.4995, -98.10], atol=atol, rtol=rtol) assert len(soln.tstop.t) == 1, "ERROR: Did not find all tstop" assert len(soln.values.t) == 11, "ERROR: Did not find all output" assert allclose( [soln.tstop.t[-1], soln.tstop.y[-1, 0], soln.tstop.y[-1, 1]], [10.0, 509.4995, -98.10], atol=atol, rtol=rtol)
def _do_problem(self, problem, integrator, old_api=True, **integrator_params): jac = None if hasattr(problem, 'jac'): jac = problem.jac res = problem.res ig = dae(integrator, res, jacfn=jac, old_api=old_api) ig.set_options(old_api=old_api, **integrator_params) z = empty((1+len(problem.stop_t),alen(problem.z0)), float) zprime = empty((1+len(problem.stop_t),alen(problem.z0)), float) ist = ig.init_step(0., problem.z0, problem.zprime0, z[0], zprime[0]) i=1 for time in problem.stop_t: soln = ig.step(time, z[i], zprime[i]) if old_api: flag, rt = soln else: flag = soln.flag rt = soln.values.t i += 1 if integrator == 'ida': assert flag==0, (problem.info(), flag) else: assert flag > 0, (problem.info(), flag) assert problem.verify(array(z), array(zprime), [0.]+problem.stop_t), \ (problem.info(),)
def test_ida_tstopfn_test(self): #test calling sequence. tsop function continues up to a time global n n = 0 tspan = np.arange(0, t_end2 + 1, 1.0, np.float) solver = dae('ida', rhs_fn, tstop=T1, ontstop=ontstop_vc, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag == StatusEnumIDA.TSTOP_RETURN, "ERROR: Error occurred" assert allclose( [soln.values.t[-1], soln.values.y[-1, 0], soln.values.y[-1, 1]], [30.0, -1452.5024, -294.30], atol=atol, rtol=rtol) assert len(soln.tstop.t) == 3, "ERROR: Did not find all tstop" assert len(soln.values.t) == 31, "ERROR: Did not find all output" assert allclose( [soln.tstop.t[-1], soln.tstop.y[-1, 0], soln.tstop.y[-1, 1]], [30.0, -1452.5024, -294.30], atol=atol, rtol=rtol)
def _do_problem(self, problem, integrator, old_api=True, **integrator_params): jac = None if hasattr(problem, 'jac'): jac = problem.jac res = problem.res ig = dae(integrator, res, jacfn=jac, old_api=old_api) ig.set_options(old_api=old_api, **integrator_params) z = empty((1+len(problem.stop_t),alen(problem.z0)), DTYPE) zprime = empty((1+len(problem.stop_t),alen(problem.z0)), DTYPE) ist = ig.init_step(0., problem.z0, problem.zprime0, z[0], zprime[0]) i=1 for time in problem.stop_t: soln = ig.step(time, z[i], zprime[i]) if old_api: flag, rt = soln else: flag = soln.flag rt = soln.values.t i += 1 if integrator == 'ida': assert flag==0, (problem.info(), flag) else: assert flag > 0, (problem.info(), flag) assert problem.verify(array(z), array(zprime), [0.]+problem.stop_t), \ (problem.info(),)
def test_ida_rootfn(self): #test root finding and stopping: End is reached at a root tspan = np.arange(0, t_end2 + 1, 1.0, DTYPE) solver = dae('ida', rhs_fn, nr_rootfns=1, rootfn=root_fn, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.ROOT_RETURN, "ERROR: Root not found!" assert allclose([soln.roots.t[0], soln.roots.y[0,0], soln.roots.y[0,1]], [14.206856, 10.0000, -139.3693], atol=atol, rtol=rtol)
def test_ida_rootfn(self): #test root finding and stopping: End is reached at a root tspan = np.arange(0, t_end2 + 1, 1.0, np.float) solver = dae('ida', rhs_fn, nr_rootfns=1, rootfn=root_fn, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.ROOT_RETURN, "ERROR: Root not found!" assert allclose([soln.roots.t[0], soln.roots.y[0,0], soln.roots.y[0,1]], [14.206856, 10.0000, -139.3693], atol=atol, rtol=rtol)
def test_ida_rootfn_noroot(self): #test calling sequence. End is reached before root is found tspan = np.arange(0, t_end1 + 1, 1.0, np.float) solver = dae('ida', rhs_fn, nr_rootfns=1, rootfn=root_fn, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.SUCCESS, "ERROR: Error occurred" assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [10.0, 509.4995, -98.10], atol=atol, rtol=rtol)
def test_ida_rootfn_noroot(self): #test calling sequence. End is reached before root is found tspan = np.arange(0, t_end1 + 1, 1.0, DTYPE) solver = dae('ida', rhs_fn, nr_rootfns=1, rootfn=root_fn, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.SUCCESS, "ERROR: Error occurred" assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [10.0, 509.4995, -98.10], atol=atol, rtol=rtol)
def test_ida_tstopfn_notstop(self): #test calling sequence. End is reached before tstop is found global n n = 0 tspan = np.arange(0, t_end1 + 1, 1.0, np.float) solver = dae('ida', rhs_fn, tstop=T1+1, ontstop=ontstop_va, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.SUCCESS, "ERROR: Error occurred" assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [10.0, 509.4995, -98.10], atol=atol, rtol=rtol)
def test_ida_tstopfn_notstop(self): #test calling sequence. End is reached before tstop is found global n n = 0 tspan = np.arange(0, t_end1 + 1, 1.0, DTYPE) solver = dae('ida', rhs_fn, tstop=T1+1, ontstop=ontstop_va, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.SUCCESS, "ERROR: Error occurred" assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [10.0, 509.4995, -98.10], atol=atol, rtol=rtol)
def test_ida_tstopfn(self): #test tstop finding and stopping: End is reached at a tstop global n n = 0 tspan = np.arange(0, t_end2 + 1, 1.0, np.float) solver = dae('ida', rhs_fn, tstop=T1, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.TSTOP_RETURN, "ERROR: Tstop not found!" assert allclose([soln.tstop.t[0], soln.tstop.y[0,0], soln.tstop.y[0,1]], [10.0, 509.4995, -98.10], atol=atol, rtol=rtol) assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [10.0, 509.4995, -98.10], atol=atol, rtol=rtol)
def test_ida_rootfn_end(self): #test root finding with root at endtime tspan = np.arange(0, 30 + 1, 1.0, np.float) solver = dae('ida', rhs_fn, nr_rootfns=1, rootfn=root_fn3, onroot=onroot_vc, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.ROOT_RETURN, "ERROR: Not sufficient root found" assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [30.0, -1452.5024, -294.3000], atol=atol, rtol=rtol) assert len(soln.roots.t) == 3, "ERROR: Did not find all 4 roots" assert allclose([soln.roots.t[-1], soln.roots.y[-1,0], soln.roots.y[-1,1]], [30.0, -1452.5024, -294.3000], atol=atol, rtol=rtol)
def test_ida_rootfn_two(self): #test two root finding tspan = np.arange(0, t_end2 + 1, 1.0, np.float) solver = dae('ida', rhs_fn, nr_rootfns=2, rootfn=root_fn2, onroot=onroot_vc, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.ROOT_RETURN, "ERROR: Not sufficient root found" assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [28.0, 106.4753, -274.6800], atol=atol, rtol=rtol) assert len(soln.roots.t) == 5, "ERROR: Did not find all 4 roots" assert allclose([soln.roots.t[-1], soln.roots.y[-1,0], soln.roots.y[-1,1]], [28.349052, 10.0000, -278.1042], atol=atol, rtol=rtol)
def test_ida_rootfn_test(self): #test root finding and accumilating: End is reached after a number of root tspan = np.arange(0, t_end2 + 1, 1.0, np.float) solver = dae('ida', rhs_fn, nr_rootfns=1, rootfn=root_fn, onroot=onroot_vc, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.ROOT_RETURN, "ERROR: Not sufficient root found" assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [28.0, 124.4724, -274.6800], atol=atol, rtol=rtol) assert len(soln.roots.t) == 4, "ERROR: Did not find all 4 roots" assert allclose([soln.roots.t[-1], soln.roots.y[-1,0], soln.roots.y[-1,1]], [28.413692, 10.0000, -278.7383], atol=atol, rtol=rtol)
def test_ida_rootfnacc(self): #test root finding and accumilating: End is reached normally, roots stored tspan = np.arange(0, t_end2 + 1, 1.0, np.float) solver = dae('ida', rhs_fn, nr_rootfns=1, rootfn=root_fn, onroot=onroot_va, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.SUCCESS, "ERROR: Error occurred" assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [100.0, 459.999, -981.0000], atol=atol, rtol=rtol) assert len(soln.roots.t) == 49, "ERROR: Did not find all 49 roots" assert allclose([soln.roots.t[-1], soln.roots.y[-1,0], soln.roots.y[-1,1]], [99.447910, 10.0000, -975.5840], atol=atol, rtol=rtol)
def test_ida_tstopfn(self): #test tstop finding and stopping: End is reached at a tstop global n n = 0 tspan = np.arange(0, t_end2 + 1, 1.0, DTYPE) solver = dae('ida', rhs_fn, tstop=T1, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.TSTOP_RETURN, "ERROR: Tstop not found!" assert allclose([soln.tstop.t[0], soln.tstop.y[0,0], soln.tstop.y[0,1]], [10.0, 509.4995, -98.10], atol=atol, rtol=rtol) assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [10.0, 509.4995, -98.10], atol=atol, rtol=rtol)
def test_ida_rootfn_end(self): #test root finding with root at endtime tspan = np.arange(0, 30 + 1, 1.0, DTYPE) solver = dae('ida', rhs_fn, nr_rootfns=1, rootfn=root_fn3, onroot=onroot_vc, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.ROOT_RETURN, "ERROR: Not sufficient root found" assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [30.0, -1452.5024, -294.3000], atol=atol, rtol=rtol) assert len(soln.roots.t) == 3, "ERROR: Did not find all 4 roots" assert allclose([soln.roots.t[-1], soln.roots.y[-1,0], soln.roots.y[-1,1]], [30.0, -1452.5024, -294.3000], atol=atol, rtol=rtol)
def test_ida_rootfn_two(self): #test two root finding tspan = np.arange(0, t_end2 + 1, 1.0, DTYPE) solver = dae('ida', rhs_fn, nr_rootfns=2, rootfn=root_fn2, onroot=onroot_vc, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.ROOT_RETURN, "ERROR: Not sufficient root found" assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [28.0, 106.4753, -274.6800], atol=atol, rtol=rtol) assert len(soln.roots.t) == 5, "ERROR: Did not find all 4 roots" assert allclose([soln.roots.t[-1], soln.roots.y[-1,0], soln.roots.y[-1,1]], [28.349052, 10.0000, -278.1042], atol=atol, rtol=rtol)
def test_ida_rootfn_test(self): #test root finding and accumilating: End is reached after a number of root tspan = np.arange(0, t_end2 + 1, 1.0, DTYPE) solver = dae('ida', rhs_fn, nr_rootfns=1, rootfn=root_fn, onroot=onroot_vc, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.ROOT_RETURN, "ERROR: Not sufficient root found" assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [28.0, 124.4724, -274.6800], atol=atol, rtol=rtol) assert len(soln.roots.t) == 4, "ERROR: Did not find all 4 roots" assert allclose([soln.roots.t[-1], soln.roots.y[-1,0], soln.roots.y[-1,1]], [28.413692, 10.0000, -278.7383], atol=atol, rtol=rtol)
def test_ida_rootfnacc(self): #test root finding and accumilating: End is reached normally, roots stored tspan = np.arange(0, t_end2 + 1, 1.0, DTYPE) solver = dae('ida', rhs_fn, nr_rootfns=1, rootfn=root_fn, onroot=onroot_va, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.SUCCESS, "ERROR: Error occurred" assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [100.0, 459.999, -981.0000], atol=atol, rtol=rtol) assert len(soln.roots.t) == 49, "ERROR: Did not find all 49 roots" assert allclose([soln.roots.t[-1], soln.roots.y[-1,0], soln.roots.y[-1,1]], [99.447910, 10.0000, -975.5840], atol=atol, rtol=rtol)
def test_ida_tstopfnacc(self): #test tstop finding and accumilating: End is reached normally, tstop stored global n n = 0 tspan = np.arange(0, t_end2 + 1, 1.0, DTYPE) solver = dae('ida', rhs_fn, tstop=T1, ontstop=ontstop_va, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.SUCCESS, "ERROR: Error occurred" assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [100.0, -8319.5023, -981.00], atol=atol, rtol=rtol) assert len(soln.tstop.t) == 9, "ERROR: Did not find all tstop" assert allclose([soln.tstop.t[-1], soln.tstop.y[-1,0], soln.tstop.y[-1,1]], [90.0, -7338.5023, -882.90], atol=atol, rtol=rtol)
def test_ida_tstopfnacc(self): #test tstop finding and accumilating: End is reached normally, tstop stored global n n = 0 tspan = np.arange(0, t_end2 + 1, 1.0, np.float) solver = dae('ida', rhs_fn, tstop=T1, ontstop=ontstop_va, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.SUCCESS, "ERROR: Error occurred" assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [100.0, -8319.5023, -981.00], atol=atol, rtol=rtol) assert len(soln.tstop.t) == 9, "ERROR: Did not find all tstop" assert allclose([soln.tstop.t[-1], soln.tstop.y[-1,0], soln.tstop.y[-1,1]], [90.0, -7338.5023, -882.90], atol=atol, rtol=rtol)
def test_ida_tstopfn_test(self): #test calling sequence. tsop function continues up to a time global n n = 0 tspan = np.arange(0, t_end2 + 1, 1.0, np.float) solver = dae('ida', rhs_fn, tstop=T1, ontstop=ontstop_vc, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.TSTOP_RETURN, "ERROR: Error occurred" assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [30.0, -1452.5024, -294.30], atol=atol, rtol=rtol) assert len(soln.tstop.t) == 3, "ERROR: Did not find all tstop" assert len(soln.values.t) == 31, "ERROR: Did not find all output" assert allclose([soln.tstop.t[-1], soln.tstop.y[-1,0], soln.tstop.y[-1,1]], [30.0, -1452.5024, -294.30], atol=atol, rtol=rtol)
def test_ida_tstopfn_stop(self): #test calling sequence. End is reached at a tstop global n n = 0 tspan = np.arange(0, t_end2 + 1, 1.0, np.float) solver = dae('ida', rhs_fn, tstop=T1, ontstop=ontstop_vb, old_api=False) soln = solver.solve(tspan, y0, yp0) assert soln.flag==StatusEnumIDA.TSTOP_RETURN, "ERROR: Error occurred" assert allclose([soln.values.t[-1], soln.values.y[-1,0], soln.values.y[-1,1]], [10.0, 509.4995, -98.10], atol=atol, rtol=rtol) assert len(soln.tstop.t) == 1, "ERROR: Did not find all tstop" assert len(soln.values.t) == 11, "ERROR: Did not find all output" assert allclose([soln.tstop.t[-1], soln.tstop.y[-1,0], soln.tstop.y[-1,1]], [10.0, 509.4995, -98.10], atol=atol, rtol=rtol)
def _do_problem(self, problem, integrator, **integrator_params): jac = None if hasattr(problem, 'jac'): jac = problem.jac res = problem.res ig = dae(integrator, res, jacfn=jac) ig.set_options(**integrator_params) z = empty((1 + len(problem.stop_t), alen(problem.z0)), float) zprime = empty((1 + len(problem.stop_t), alen(problem.z0)), float) ig.init_step(0., problem.z0, problem.zprime0, z[0], zprime[0]) i = 1 for time in problem.stop_t: flag, rt = ig.step(time, z[i], zprime[i]) i += 1 if integrator == 'ida': assert flag == 0, (problem.info(), flag) else: assert flag > 0, (problem.info(), flag) assert problem.verify(array(z), array(zprime), [0.]+problem.stop_t), \ (problem.info(),)
def main(): """ The main program: instantiate a problem, then use odes package to solve it """ uinput = input("Solve as\n 1 = index 2 problem\n 2 = index 1 problem\n" " 3 = index 1 problem with jacobian\n 4 = info\n\n" "Answer (1,2,3 or 4) : ") jac = None if uinput == '1': problem = Doublependulum(type='index2') res = resindex2() elif uinput == '2': problem = Doublependulum(type='index1') res = resindex1() elif uinput == '3': problem = Doublependulum(type='index1_jac') res = resindex1() jac = jacindex1() else: print(__doc__) return z = [0]*(1+len(problem.stop_t)); zprime = [0]*(1+len(problem.stop_t)) res.set_dblpend(problem) jfac = 1. if jac: jac.set_dblpend(problem) jfac = JACFAC solver = ida.IDA(res, compute_initcond='yp0', first_step_size=1e-18, atol=ATOL*jfac, rtol=RTOL*jfac, max_steps=1500, jacfn=jac, algebraic_vars_idx=problem.algvar_idx, exclude_algvar_from_error=problem.exclalg_err, ) z[0] = np.empty(problem.neq, float) zprime[0] = np.empty(problem.neq, float) (flag, t0_init) = solver.init_step(0., problem.z0, problem.zprime0, z[0], zprime[0]) realtime = [t0_init] #flag, rt = solver.step(t0_init, z[0], zprime[0]) i=1 error = False for time in problem.stop_t[1:]: #print 'at time', time z[i] = np.empty(problem.neq, float) zprime[i] = np.empty(problem.neq, float) flag, rt = solver.step(time, z[i], zprime[i]) realtime += [rt] #print 'sol at ', time, z[i] i += 1 if flag != 0: error = True print('Error in solver, breaking solution at time %g' % time) break fres = np.empty(problem.neq, float) res.evaluate(problem.stop_t[i-1], z[i-1], zprime[i-1], fres, None) print('last sol has residual: ', fres) nr = i x1t = asarray([z[i][0] for i in range(nr)]) y1t = asarray([z[i][1] for i in range(nr)]) x2t = asarray([z[i][2] for i in range(nr)]) y2t = asarray([z[i][3] for i in range(nr)]) xp1t = asarray([z[i][4] for i in range(nr)]) yp1t = asarray([z[i][5] for i in range(nr)]) xp2t = asarray([z[i][6] for i in range(nr)]) yp2t = asarray([z[i][7] for i in range(nr)]) energy = problem.m1*problem.g*y1t + \ problem.m2*problem.g*y2t + \ .5 *(problem.m1 * (xp1t**2 + yp1t**2) + problem.m2 * (xp2t**2 + yp2t**2) ) initenergy = energy[0] #solve the same with ddaspk if alsoddaspk: ddaspkz = empty((alen(problem.stop_t), problem.neq), float) ddaspkzprime = empty((alen(problem.stop_t), problem.neq), float) problem.set_res(res) ig = dae('ddaspk', problem.ddaspk_res) if jac: problem.set_jac(jac) ig.set_options(jacfn=problem.ddaspk_jac) #first compute the correct initial condition from the values of z0 ig.set_options( algebraic_vars_idx=problem.algvar_idx, compute_initcond='yp0', first_step=1e-18, exclude_algvar_from_error=problem.exclalg_err, atol=ATOL, rtol=RTOL, max_steps=1500) tinit = ig.init_step(0., problem.z0, problem.zprime0, ddaspkz[0], ddaspkzprime[0]) print('ddaspk started from z0 = ', problem.z0) print('ddaspk initial condition calculated, [z,zprime] = [', ddaspkz[0], ddaspkzprime[0], ']') i=1 error = False for time in problem.stop_t[1:]: flag, tout = ig.step(time, ddaspkz[i], ddaspkzprime[i]) i += 1 if flag < 1: error = True break dnr = i ddaspkx1t = asarray([ddaspkz[i][0] for i in range(dnr)]) ddaspky1t = asarray([ddaspkz[i][1] for i in range(dnr)]) ddaspkx2t = asarray([ddaspkz[i][2] for i in range(dnr)]) ddaspky2t = asarray([ddaspkz[i][3] for i in range(dnr)]) ddaspkxp1t = asarray([ddaspkzprime[i][0] for i in range(dnr)]) ddaspkyp1t = asarray([ddaspkzprime[i][1] for i in range(dnr)]) ddaspkxp2t = asarray([ddaspkzprime[i][2] for i in range(dnr)]) ddaspkyp2t = asarray([ddaspkzprime[i][3] for i in range(dnr)]) ddaspkenergy = problem.m1*problem.g*ddaspky1t + \ problem.m2*problem.g*ddaspky2t + \ .5 *(problem.m1 * (ddaspkxp1t**2 + ddaspkyp1t**2) + problem.m2 * (ddaspkxp2t**2 + ddaspkyp2t**2) ) ddaspkrealtime = problem.stop_t[:dnr] pylab.ion() pylab.figure(1) pylab.subplot(211) pylab.title('IDA solution option %s' % uinput) pylab.scatter(x1t, y1t) pylab.scatter(x2t, y2t) pylab.xlim(-10, 10) pylab.ylim(-8, 2) pylab.axis('equal') pylab.subplot(212) pylab.plot(realtime, energy, 'b') pylab.title('Energy Invariant Violation for a Double Pendulum') pylab.xlabel('Time (s)') pylab.ylabel('Total Energy') pylab.axis() pylab.show() if alsoddaspk: pylab.ion() pylab.figure(2) pylab.subplot(211) pylab.title('DDASPK solution option %s' % uinput) pylab.scatter(ddaspkx1t, ddaspky1t) pylab.scatter(ddaspkx2t, ddaspky2t) pylab.xlim(-10, 10) pylab.ylim(-8, 2) pylab.axis('equal') pylab.subplot(212) pylab.plot(ddaspkrealtime, ddaspkenergy, 'b') pylab.title('Energy Invariant Violation for a Double Pendulum') pylab.xlabel('Time (s)') pylab.ylabel('Total Energy DDASPK solution') pylab.axis() pylab.show() def circle(ax, x, y, r, color='r'): count = 20 ax.fill([x + r * cos(2.* i * pi/count) for i in range(count+1)], [y + r * sin(2.* i * pi/count) for i in range(count+1)], color) def line(ax, x1, y1, x2, y2, color='black'): norm = sqrt((y2-y1)**2 + (x2-x1)**2) normal = [(y2-y1)/norm, -(x2-x1)/norm] ax.fill( [x1-0.01*normal[0],x1+0.01*normal[0],x2+0.01*normal[0],x2-0.01*normal[0]], [y1-0.01*normal[1],y1+0.01*normal[1],y2+0.01*normal[1],y2-0.01*normal[1]], color) def draw(ax, nr): sol = z[nr] line(ax, 0., 0., sol[0], sol[1]) line(ax, sol[0], sol[1], sol[2], sol[3]) circle(ax, sol[0], sol[1], 0.5) circle(ax, sol[2], sol[3], 0.5) def drawonesol(nr, sizex, sizey, ext=None): pylab.clf() a = pylab.axes() draw(a, nr) pylab.axis('scaled') pylab.xlim(-sizex, sizex) pylab.ylim(-sizey, sizey) if ext is None: ext = nr pylab.savefig('figsdoublependulum' + os.sep + 'outsol%08i.png' % ext) def open_file_with_default_application( file_path ): """ Launch a program to open an arbitrary file. The file will be opened using whatever program is configured on the host as the default program for that type of file. """ norm_path = os.path.normpath( file_path ) if not os.path.exists(norm_path): print("%s does not exist" % file_path) return if os.sys.platform == 'win32': try: os.startfile(norm_path) except WindowsError as msg: print("Error Opening File. " + str(msg)) else: search = os.environ['PATH'].split(':') for path in search: prog = os.path.join(path, 'xdg-open') if os.path.isfile(prog): os.spawnvpe(os.P_NOWAIT, prog, [prog, norm_path], os.environ) return def create_animation(sizex, sizey, ext): """ The calculation step is 1e-2, so output every 5 solutions or 0.05, means a frame rate of 20 frames per second """ import shutil fps = 20 if os.path.isdir('figsdoublependulum'): shutil.rmtree('figsdoublependulum') os.mkdir('figsdoublependulum') if not os.path.isdir('anidoublependulum'): os.mkdir('anidoublependulum') pylab.figure(2) secs = 0 frame = 0 print('Generating output ...\n') for solnr in range(0,nr,5): drawonesol(solnr, sizex, sizey, frame) frame += 1 if solnr // 500 != secs : secs = solnr // 500 print(' ... at %i seconds ' % (secs * 5 )) print('Creating movie using ffmpeg with output ... \n') import subprocess subprocess.call(['ffmpeg', '-r', '20', '-i', 'figsdoublependulum' + os.sep + 'outsol%8d.png', '-f', 'avi', '-vcodec', 'mpeg2video', '-y', 'anidoublependulum' + os.sep + 'doublependulum'+ext+'.mpg']) #remove unused pictures shutil.rmtree('figsdoublependulum') #opening movie with default player print('Opening user with default application ... \n') open_file_with_default_application('anidoublependulum' + os.sep + 'doublependulum'+ext+'.mpg') uinput2 = input('Create animation of the solution? (y/n): ') print('\n') if (uinput2 == 'y' or uinput2 == 'yes'): extend = problem.radius1 + problem.radius2 + 1 create_animation(extend, extend, uinput)
residual[5] = ydot[5] - inlet_massFlow residual[6] = ydot[6] - outlet_massFlow residual[7] = y[7] - gasMass residual[8] = y[8] - liquidMass rtol = 1e-4 atol = 1e-4 algebraic_vars_idx = [2, 3, 4, 7, 8] solver = dae( 'ida', computeResidual, compute_initcond="yp0", exclude_algvar_from_error=False, algebraic_vars_idx=algebraic_vars_idx, atol=atol, rtol=rtol, max_steps=500000, ) times = np.linspace(0, 50, 100) solution = solver.solve(times, initialState, initialDerivatives) print(solution.message) with open('/data/tankFilling.npy', 'wb') as f: t = np.array(solution.values.t) y = np.array(solution.values.y) np.save(f, t) np.save(f, y)
ux0 = 1 b_par0 = -L0 / (omega * kx) * ux0 u_perp0 = -1j * kx * nabla_perp0 / (L0 + nabla_perp0**2) * ux0 # ux_r0 = np.real(ux_exact(x_min, z)) # ux_i0 = np.imag(ux_exact(x_min, z)) # b_par_r0 = np.real(b_par_exact(x_min, z)) # b_par_i0 = np.imag(b_par_exact(x_min, z)) # U0 = np.concatenate((ux_r0, ux_i0, b_par_r0, b_par_i0)) # sol = solve_ivp(dUdx, [x_min, x_max], U0, t_eval=x, method='Radau') # ux_r = sol.y[0:nz] # fig = plt.figure() # ax = fig.add_subplot(111, projection='3d') # surf = ax.plot_surface(X, Z, np.real(ux_r)) # ax.set_xlabel('x') # ax.set_ylabel('z') ux_r0 = np.real(ux_exact(x_min, z)) ux_i0 = np.imag(ux_exact(x_min, z)) b_par_r0 = np.real(b_par_exact(x_min, z)) b_par_i0 = np.imag(b_par_exact(x_min, z)) U0 = np.concatenate((ux_r0, ux_i0, b_par_r0, b_par_i0)) dux_r0 = np.real(1j * kx * ux_exact(x_min, z)) dux_i0 = np.imag(1j * kx * ux_exact(x_min, z)) db_par_r0 = np.real(1j * kx * b_par_exact(x_min, z)) db_par_i0 = np.imag(1j * kx * b_par_exact(x_min, z)) dU0 = np.concatenate((dux_r0, dux_i0, db_par_r0, db_par_i0)) solver = dae('ddaspk', reseqn) result = solver.solve(x, U0, dU0)
result[1] = x[3]-xdot[1] result[2] = -xdot[2]+x[4]*x[0]/m result[3] = -xdot[3]+x[4]*x[1]/m-g result[4] = x[2]**2 + x[3]**2 \ + (x[0]**2 + x[1]**2)/m*x[4] - x[1] * g abs_resid = np.sum(np.abs(result)) if t > 2.1: resid_t.append(t) resid_vals.append(abs_resid) solver = dae('ida', residual, compute_initcond='yp0', first_step_size=1e-18, atol=1e-6, rtol=1e-6, algebraic_vars_idx=[4], compute_initcond_t0=60, old_api=False) solution = solver.solve([0., 1., 2.], z0, zp0) print('\n t Solution') print('----------------------') for t, u in zip(solution.values.t, solution.values.y): print('{0:>4.0f} {1:15.6g} '.format(t, u[0])) # Solve over the next hour by continuation times = np.linspace(0, 3600, 61) times[0] = solution.values.t[-1]
This is = rhs(t,y) - a(t,y) * dy/dt """ result[0] = -m*xdot[1] - k*x[0] result[1] = -xdot[0] + x[1] def adda(t, y, ml, mu, p, nrowp): """ adda function for lsodi. matrix a is the matrix in the problem formulation you multiply wity dy/dt, and this method must add it with p """ p[0,1] += m p[1,0] += 1.0 return p from scikits.odes import dae solver = dae('lsodi', reseqn, adda_func=adda, rtol=([1e-4, 1e-4]), atol=([1e-6, 1e-10])) #obtain solution at a required time result = solver.solve([0., 1., 2.], initx, initxp) print('\n t Solution Exact') print('------------------------------------') for t, u in zip(result[1], result[2]): print('%4.2f %15.6g %15.6g' % (t, u[0], initx[0]*cos(sqrt(k/m)*t)+initx[1]*sin(sqrt(k/m)*t)/sqrt(k/m))) #continue the solver result = solver.solve([result[1][-1], result[1][-1]+1], result[2][-1], result[3][-1]) print('Continuation of the solution') print('\n t Solution Exact') for t, u in zip(result[1], result[2]): print ('%4.2f %15.6g %15.6g' % (t, u[0], initx[0]*cos(sqrt(k/m)*t)+initx[1]*sin(sqrt(k/m)*t)/sqrt(k/m)))
mdot0 = 3 * 1.66667e-5 * gas_in.density '''Test PFR with simplified kinetics expression''' #Initial conditions vector y0 = gas_in.Y #Initialize simple PFR r = PFR_simple(gas=gas, surf=surf, diam=0.01520, rate_eff=1e-03) #Algebraic equations index algidx = np.array([5, 6, 7]) solver = dae('ida', r.eval_reactor_dae, compute_initcond='yp0', atol=1e-14, rtol=1e-07, max_steps=5000, algebraic_vars_idx=algidx, old_api=False) #Reactor axial coordinates [m] zcoord = np.linspace(0.0, 0.01, 250) #Coverages values at the inlet cov_data_mean = cov_data[:, 0, :] #Species index idx_ni = surf.species_index('NI(S)') idx_h = surf.species_index('H(S)') idx_co = surf.species_index('CO(S)')
result[0] = x[0] / self.params["R1"] - x[1] / self.params["R1"] - x[2] result[1] = -x[0] / self.params["R1"] + x[1] / self.params[ "R1"] + self.params["C1"] * xdot[1] result[2] = -x[0] - self.source(t) self.t_var = t z0 = [0, 0, 0] zp0 = [0, 0, 0] for i in [1e-3]: #, 1e-4, 1e-5]: sol_fs = solve_functions(params={"R1": 10, "C1": i}) solver = dae('ida', sol_fs.residual, compute_initcond='yp0', first_step_size=1e-18, atol=1e-6, rtol=1e-6, algebraic_vars_idx=[0, 2], compute_initcond_t0=60, old_api=False) solution = solver.solve(np.linspace(0, 2, 100), z0, zp0) plt.plot(solution.values.t, solution.values.y[:, 2], label=i) def strictly_increasing(L): return all(x < y for x, y in zip(L, L[1:])) def non_decreasing(L): return all(x <= y for x, y in zip(L, L[1:]))
def solver( sys, y0, fromTime, toTime, outputTimestep, events = None, useDae = False, rtol = None, atol = None ): times = np.arange(fromTime, toTime, outputTimestep) options.currentlySolvingWithDAE = useDae # sys is of the form def system(t, y) if useDae: from scikits.odes import dae yp0 = sys(fromTime, y0) yp0 = yp0[0,:] def addafunc(t, y, ml, mu, p, nrowp): return p - np.eye(nrowp) nfev = 0 njev = None nlu = None N = np.size(y0) def residual(t, y, ydot, result): nonlocal nfev nfev += 1 try: derivative = sys(t, y[0:N]) except Exception: return 1 gamma = derivative[0, 10] volume = derivative[0, 11] dgamma_dt = ydot[10] dvolume_dt = ydot[11] pressure = y[7] derivative[0, 7] += pressure / (volume - 1) * dgamma_dt derivative[0, 7] += pressure * gamma / volume * dvolume_dt for i in range(N): result[i] = ydot[i] - derivative[0, i] # DAE part... not pretty but yes, for now, it works if options.solveTankVolumeContraintWithDAE: tankVolume = derivative[0, 4] result[4] = tankVolume else: result[4] = y[4] result[10] = ydot[10] result[11] = ydot[11] result[N] = y[N] - derivative[0, 10] result[N+1] = y[N+1] - derivative[0, 11] return 0 extra_vars = 2 if extra_vars > 0: y0 = np.concatenate((y0, np.zeros(extra_vars))) yp0 = np.concatenate((yp0, np.zeros(extra_vars))) y0[10] = 0 yp0[10] = 0 y0[11] = 0 yp0[11] = 0 y0[N] = yp0[10] yp0[N] = 0 y0[N+1] = yp0[11] yp0[N+1] = 0 algebraic_vars_idx = [4, 7, 10, 11, N, N+1] def root_fn(t, y, yp, result): for i in range(len(events)): if hasattr(events[i], "disabled") and events[i].disabled: result[i] = 1 continue result[i] = events[i](t, y[0:N]) # print(t, result) solver = dae('ida', residual, compute_initcond="yp0", exclude_algvar_from_error=False, algebraic_vars_idx=algebraic_vars_idx, atol=atol, rtol=rtol, max_steps=500000, rootfn=root_fn, nr_rootfns=len(events) ) allTimes = np.zeros((0)) allY = np.zeros((N,0)) currentTime = 0 currentY0 = y0 currentYP0 = yp0 while True: computeTimes = np.concatenate(([currentTime], times[times > currentTime])) if len(computeTimes) == 0: break print("Running solution from {:.4f} to {:.4f} with DAE (IDA) solver".format(np.min(computeTimes), np.max(computeTimes))) solution = solver.solve(computeTimes, currentY0, currentYP0) # 0 is done # 2 is that it hit root if not (solution.flag == 0 or solution.flag == 2): raise Exception("Flag is not 0 or 2 (it is " + str(solution.flag) + ")") t = np.array(solution.values.t) v = np.array(solution.values.y) allTimes = np.concatenate((allTimes, np.transpose(t))) allY = np.concatenate((allY, np.transpose(v[:,0:N])), axis=1) if solution.flag == 2: root = solution.roots result = np.zeros(len(events)) root_fn(root.t[0], root.y[0], root.ydot[0], result) result = np.abs(result) argmin = np.argmin(result) event = events[argmin] event.disabled = True currentTime = root.t[0] currentY0 = root.y[0] currentYP0 = root.ydot[0] print("Root '{:}' hit at {:.4f}".format(event.__name__, currentTime)) if hasattr(event, "terminal"): if event.terminal: break # stop! return allTimes, allY, allTimes[-1], nfev, njev, nlu print("Running solution from {:.2f} to {:.2f} with ODE (LSODA) solver".format(fromTime, toTime)) sol = solve_ivp( sys, [fromTime, toTime], y0, 'LSODA', t_eval=times, dense_output=False, events=events, atol=atol, rtol=rtol ) for i in range(len(sol.t_events)): if(len(sol.t_events[i]) == 0): continue sol.t = np.concatenate((sol.t, sol.t_events[i]), axis=0) sol.y = np.concatenate((sol.y, np.transpose(sol.y_events[i])), axis=1) # sol.t = np.concatenate(sol.t, sol.t_events[i]) # sol.y = np.concatenate(sol.y, sol.y_events[i]) # # sort_indices = np.argsort(sol.t, axis=0) # sol.t = sol.t[sort_indices] # sol.y = sol.y[sort_indices] indices = np.argsort(sol.t) sol.t = sol.t[indices] sol.y = sol.y[:,indices] return sol.t, sol.y, sol.t[-1], sol.nfev, sol.njev, sol.nlu
#data k = 4.0 m = 1.0 #initial data on t=0, x[0] = u, x[1] = \dot{u}, xp = \dot{x} initx = [1, 0.1] initxp = [initx[1], -k/m*initx[0]] #define function for the residual equations which has specific signature def reseqn(t, x, xdot, result): """ we create residual equations for the problem""" result[0] = m*xdot[1] + k*x[0] result[1] = xdot[0] - x[1] #instantiate the solver from scikits.odes import dae solver = dae('ida', reseqn) #obtain solution at a required time result = solver.solve([0., 1., 2.], initx, initxp) print('\n t Solution Exact') print('------------------------------------') for t, u in zip(result[1], result[2]): print('%4.2f %15.6g %15.6g' % (t, u[0], initx[0]*cos(sqrt(k/m)*t)+initx[1]*sin(sqrt(k/m)*t)/sqrt(k/m))) #continue the solver result = solver.solve([result[1][-1], result[1][-1]+1], result[2][-1], result[3][-1]) print('------------------------------------') print(' ...continuation of the solution') print('------------------------------------')
def calculateSolution(timeData, designData): jac = None prob = Collector(timeData, designData) res = resindex() res.set_drysim(prob) jfac = 1. solver = ida.IDA(res, compute_initcond='yp0', first_step_size=1e-18, atol=ATOL*jfac, rtol=RTOL*jfac, max_steps=1500, jacfn=jac, algebraic_vars_idx=prob.algvar_idx, exclude_algvar_from_error=prob.exclalg_err, ) # Solution vectors y = [0]*(1+len(prob.stop_t)); yp = [0]*(1+len(prob.stop_t)) y[0] = empty(prob.neq, float); yp[0] = empty(prob.neq, float) flag, t, y = solver.solve(prob.stop_t, prob.y0, prob.yp0)[:3] prob.setSolution(y, 'ida') # (flag, t0_init) = solver.init_step(0., prob.y0, prob.yp0, y[0], yp[0]) # realtime = [t0_init] # # i=1 # error = False # for time in prob.stop_t[1:]: # #print 'at time', time # y[i] = empty(prob.neq, float) # yp[i] = empty(prob.neq, float) # flag, rt = solver.step(time, y[i], yp[i]) # realtime += [rt] # print(time, y[i]) # # i += 1 # if flag != 0: # error = True # print('Error in solver, breaking solution at time %g' % time) # break if alsoddaspk: ddaspkz = empty((alen(prob.stop_t), prob.neq), float) ddaspkzprime = empty((alen(prob.stop_t), prob.neq), float) prob.set_res(res) ig = dae('ddaspk', prob.ddaspk_res) if jac: prob.set_jac(jac) ig.set_options(jacfn=prob.ddaspk_jac) #first compute the correct initial condition from the values of z0 ig.set_options( algebraic_vars_idx=prob.algvar_idx, compute_initcond='yp0', first_step=1e-18, exclude_algvar_from_error=prob.exclalg_err, atol=ATOL, rtol=RTOL, max_steps=1500) tinit = ig.init_step(0., prob.y0, prob.yp0, ddaspkz[0], ddaspkzprime[0]) # print('ddaspk started from y0 = ', prob.y0) # print('ddaspk initial condition calculated, [z,zprime] = [', ddaspkz[0], # ddaspkzprime[0], ']') i=1 error = False for time in prob.stop_t[1:]: flag, tout = ig.step(time, ddaspkz[i], ddaspkzprime[i]) i += 1 if flag < 1: error = True break prob.setSolution(ddaspkz, 'ddaspk') return prob
#initial data on t=0, x[0] = u, x[1] = \dot{u}, xp = \dot{x} initx = [1, 0.1] initxp = [initx[1], -k/m*initx[0]] #define function for the residual equations which has specific signature def reseqn(t, x, xdot, result): """ we create residual equations for the problem""" result[0] = m*xdot[1] + k*x[0] result[1] = xdot[0] - x[1] return 0 #instantiate the solver from scikits.odes import dae print ("Using the old api:") solver = dae('ida', reseqn, old_api=True) #obtain solution at a required time result = solver.solve([0., 1., 2.], initx, initxp) print('\n t Solution Exact') print('------------------------------------') for t, u in zip(result[1], result[2]): print('%4.2f %15.6g %15.6g' % (t, u[0], initx[0]*cos(sqrt(k/m)*t)+initx[1]*sin(sqrt(k/m)*t)/sqrt(k/m))) #continue the solver result = solver.solve([result[1][-1], result[1][-1]+1], result[2][-1], result[3][-1]) print('------------------------------------') print(' ...continuation of the solution') print('------------------------------------') for t, u in zip(result[1], result[2]):
def _do_problem(self, problem, integrator, old_api=True, **integrator_params): jac = None if hasattr(problem, 'jac'): jac = problem.jac res = problem.res class UserData: def __init__(self): self.J = None my_userdata = UserData() jac_times_vec = None jac_times_vec2 = None jac_times_setupfn = None # restrict to 'ida' method since jacobian function below # follows the ida interface if jac is not None and integrator in ['ida', 'idas']: def jac_times_vec(tt, yy, yp, rr, v, Jv, cj): J = zeros((len(yy), len(yy)), DTYPE) jac(tt, yy, yp, rr, cj, J) Js = sparse.csr_matrix(J) Jv[:] = Js * v return 0 def jac_times_vec2(tt, yy, yp, rr, v, Jv, cj, userdata): Jv[:] = userdata.J * v return 0 def jac_times_setupfn(tt, yy, yp, rr, cj, userdata): J = zeros((len(yy), len(yy)), DTYPE) jac(tt, yy, yp, rr, cj, J) userdata.J = sparse.csr_matrix(J) return 0 igs = [dae(integrator, res, jacfn=jac, old_api=old_api)] # if testing 'ida' then try the iterative linsolvers as well if integrator in ['ida', 'idas']: igs.append( dae(integrator, res, linsolver='spgmr', jac_times_vecfn=jac_times_vec, old_api=old_api)) igs.append( dae(integrator, res, linsolver='spgmr', jac_times_vecfn=jac_times_vec2, jac_times_setupfn=jac_times_setupfn, old_api=old_api, user_data=my_userdata)) for ig in igs: ig.set_options(old_api=old_api, **integrator_params) z = empty((1 + len(problem.stop_t), alen(problem.z0)), DTYPE) zprime = empty((1 + len(problem.stop_t), alen(problem.z0)), DTYPE) ist = ig.init_step(0., problem.z0, problem.zprime0, z[0], zprime[0]) i = 1 for time in problem.stop_t: soln = ig.step(time, z[i], zprime[i]) if old_api: flag, rt = soln else: flag = soln.flag rt = soln.values.t i += 1 if integrator in ['ida', 'idas']: assert flag == 0, (problem.info(), flag) else: assert flag > 0, (problem.info(), flag) assert problem.verify(array(z), array(zprime), [0.]+problem.stop_t), \ (problem.info(),)
def my_residual(t, y, ydot, result): # Residual F(t, y, y_dot) = 0 result[:] = (np.dot(M, ydot) - my_rhs(t, y)) # Calculate Jacobian of RHS J = jacobian(my_rhs, 1) def my_jac(self, t, y, ydot, cj, jac): # Need to write function to approximate jacobian of nonlinear part jac[:][:] = -J(t, y) + cj * M # TO DO: Get consistant initial conditions ------------------------------------ y_dot_0 = np.zeros(np.size(y_0)) # Solve IVP ------------------------------------------------------------------- print("Solving ODE.") ODE_start = mesh.t[0] solver = dae("ida", my_residual, jacfn=my_jac, atol=1e-4, rtol=1e-4, old_api=False) soln = solver.solve(mesh.t, y_0, y_dot_0) ODE_finish = mesh.t[-1] t_out = soln.values.t y_out = np.transpose(soln.values.y)
return self.dt*convolv/(Q*gamma(alpha)) z0=[0,0,0, 0] zp0=[0,0,0, 0] sol_fs=solve_functions(params={"R1":10, "C1":1e-3, "Q1":1, "alpha1":0.5}) dt=1e-9 sol_fs.dt=dt times=np.arange(0, dt*1000, dt) charge_array=np.zeros(len(times)) interval_potential=[sol_fs.source(t) for t in times] solver = dae('ida', sol_fs.residual, first_step_size=dt, atol=1e-6, rtol=1e-6, algebraic_vars_idx=[0, 2, 3], one_step_compute=True, old_api=False) solver.init_step(t0=0, y0=z0, yp0=zp0) times=np.arange(0, dt*2, dt) y_retn=np.zeros(len(times)) for i in range(1, len(times)): solver.step(times[i]) """for i in [1e-3]:#, 1e-4, 1e-5]: sol_fs=solve_functions(params={"R1":10, "C1":i, "Q1":1, "alpha1":0.5}) solver = dae('ida', sol_fs.residual, compute_initcond='yp0', first_step_size=1e-18, atol=1e-6, rtol=1e-6,
m = 1.0 #initial data on t=0, x[0] = u, x[1] = \dot{u}, xp = \dot{x} initx = [1, 0.1] initxp = [initx[1], -k/m*initx[0]] #define function for the residual equations which has specific signature def reseqn(t, x, xdot, result): """ we create residual equations for the problem""" result[0] = m*xdot[1] + k*x[0] result[1] = xdot[0] - x[1] #instantiate the solver #from scikits.odes.sundials import ida #solver = ida.IDA(reseqn) from scikits.odes import dae solver = dae('ddaspk', reseqn) #obtain solution at a required time result = solver.solve([0., 1., 2.], initx, initxp) print('\n t Solution Exact') print('------------------------------------') for t, u in zip(result[1], result[2]): print('%4.2f %15.6g %15.6g' % (t, u[0], initx[0]*cos(sqrt(k/m)*t)+initx[1]*sin(sqrt(k/m)*t)/sqrt(k/m))) #continue the solver result = solver.solve([result[1][-1], result[1][-1]+1], result[2][-1], result[3][-1]) print('Continuation of the solution') print('\n t Solution Exact') for t, u in zip(result[1], result[2]): print ('%4.2f %15.6g %15.6g' % (t, u[0], initx[0]*cos(sqrt(k/m)*t)+initx[1]*sin(sqrt(k/m)*t)/sqrt(k/m)))
def adda(t, y, ml, mu, p, nrowp): """ adda function for lsodi. matrix a is the matrix in the problem formulation you multiply wity dy/dt, and this method must add it with p """ p[0, 1] += m p[1, 0] += 1.0 return p from scikits.odes import dae solver = dae('lsodi', reseqn, adda_func=adda, rtol=([1e-4, 1e-4]), atol=([1e-6, 1e-10])) #obtain solution at a required time result = solver.solve([0., 1., 2.], initx, initxp) print('\n t Solution Exact') print('------------------------------------') for t, u in zip(result[1], result[2]): print('%4.2f %15.6g %15.6g' % (t, u[0], initx[0] * cos(sqrt(k / m) * t) + initx[1] * sin(sqrt(k / m) * t) / sqrt(k / m))) #continue the solver result = solver.solve([result[1][-1], result[1][-1] + 1], result[2][-1], result[3][-1])
initxp = [initx[1], -k / m * initx[0]] #define function for the residual equations which has specific signature def reseqn(t, x, xdot, result): """ we create residual equations for the problem""" result[0] = m * xdot[1] + k * x[0] result[1] = xdot[0] - x[1] return 0 #instantiate the solver from scikits.odes import dae print("Using the old api:") solver = dae('ida', reseqn, old_api=True) #obtain solution at a required time result = solver.solve([0., 1., 2.], initx, initxp) print('\n t Solution Exact') print('------------------------------------') for t, u in zip(result[1], result[2]): print('%4.2f %15.6g %15.6g' % (t, u[0], initx[0] * cos(sqrt(k / m) * t) + initx[1] * sin(sqrt(k / m) * t) / sqrt(k / m))) #continue the solver result = solver.solve([result[1][-1], result[1][-1] + 1], result[2][-1], result[3][-1]) print('------------------------------------') print(' ...continuation of the solution')
g=1 tmp[0]=x[2]-xdot[0] tmp[1]=x[3]-xdot[1] tmp[2]=-xdot[2]-x[4]*x[0] tmp[3]=-xdot[3]-x[4]*x[1]-g #tmp[4]=x[0]*x[0]+x[1]*x[1]-1 #tmp[4]=x[0]*x[2]+x[1]*x[3] tmp[4] = x[2]**2 + x[3]**2 \ - (x[0]**2 + x[1]**2)*x[4] - x[1] * PlanarPendulum.g problem = PlanarPendulum() z = empty((1+len(problem.stop_t), alen(problem.z0)), float) zprime = empty((1+len(problem.stop_t), alen(problem.z0)), float) algvar = -1 ig = dae('ddaspk', problem.res) #first compute the correct initial condition from the values of z0 ig.set_options(algebraic_vars_idx=[4], compute_initcond='y0', first_step=1e-9, atol=1e-6, rtol=1e-6) #initialize solver and obtain correct values of initial condition tinit = ig.init_step(.0, problem.z0, problem.zprime0, z[0], zprime[0]) error = False i = 1 for time in problem.stop_t: flag, tout = ig.step(time, z[i], zprime[i] ) i += 1 #print 'sol at ', time, z[i]
def main(): """ The main program: instantiate a problem, then use odes package to solve it """ uinput = input("Solve as\n 1 = index 2 problem \n 2 = index 1 problem (Not working!)\n" " \n 4 = info\n\n" "Answer (1,2 or 4) : ") if uinput == '1': problem = Slidingpendulum(type='index2') elif uinput == '2': problem = Slidingpendulum(type='index1') else: print(__doc__) return input1 = input("Solve with\n 1 = ida\n 2 = ddaspk\n\n" "Answer (1 or 2) : ").strip() if input1 not in ["1", "2"]: print("Invalid solution method given") return if input1 == '1': ig = dae('ida', problem.res, atol=1e-5,rtol=1e-4, max_conv_fails=200) elif input1 == '2': ig = dae('ddaspk', problem.res, atol=1e-5,rtol=1e-4) #for ddaspk, scale2 must not be that big problem.scale2 = 1. ig.set_options(jacfn=problem.jac, algebraic_vars_idx=problem.algvaridx, compute_initcond='yp0', exclude_algvar_from_error=problem.exclalg_err, max_steps = 15000, first_step_size=1e-9) #Solve it result= ig.solve(problem.stop_t, problem.z0, problem.zprime0) time = result[1] z = result[2] zprime = result[3] #some user output print('started from z0 = ', problem.z0) print('initial condition calculated, [z,zprime] = [', z[0], zprime[0], ']') print('last sol at time', time[-1]) print(' has solution ', z[-1], zprime[-1]) res = empty(problem.neq, float) problem.res(problem.stop_t[-1], z[-1], zprime[-1], res) print(' has residual: ', res) xt = z[:,0] yt = z[:,1] thetat = z[:,2] nr = len(xt) pylab.ion() pylab.figure(1) pylab.subplot(111) pylab.scatter(xt, yt) pylab.scatter(xt + problem.l*sin(thetat), yt - problem.l*cos(thetat)) pylab.axis('equal') pylab.axis() pylab.show() def circle(ax, x, y, r, color='r'): count = 20 ax.fill([x + r * cos(2.* i * pi/count) for i in range(count+1)], [y + r * sin(2.* i * pi/count) for i in range(count+1)], color) def line(ax, x1, y1, x2, y2, color='black'): norm = sqrt((y2-y1)**2 + (x2-x1)**2) normal = [(y2-y1)/norm, -(x2-x1)/norm] ax.fill( [x1-0.01*normal[0],x1+0.01*normal[0],x2+0.01*normal[0],x2-0.01*normal[0]], [y1-0.01*normal[1],y1+0.01*normal[1],y2+0.01*normal[1],y2-0.01*normal[1]], color) def draw(ax, nr): sol = z[nr] x2 = sol[0]+problem.l*sin(sol[2]) y2 = sol[1]-problem.l*cos(sol[2]) line(ax, sol[0], sol[1], x2, y2) circle(ax, x2, y2, 0.1) def drawonesol(nr, sizex, sizey, ext=None): pylab.clf() a = pylab.axes() draw(a, nr) pylab.axis('scaled') pylab.xlim(-sizex, sizex) pylab.ylim(-sizey, sizey) if ext is None: ext = nr pylab.savefig('figsslidingpendulum' + os.sep + 'outsol%08i.png' % ext) def open_file_with_default_application( file_path ): """ Launch a program to open an arbitrary file. The file will be opened using whatever program is configured on the host as the default program for that type of file. """ norm_path = os.path.normpath( file_path ) if not os.path.exists(norm_path): print("%s does not exist" % file_path) return if os.sys.platform == 'win32': try: os.startfile(norm_path) except WindowsError as msg: print("Error Opening File. " + str(msg)) else: search = os.environ['PATH'].split(':') for path in search: prog = os.path.join(path, 'xdg-open') if os.path.isfile(prog): os.spawnvpe(os.P_NOWAIT, prog, [prog, norm_path], os.environ) return def create_animation(sizex, sizey, ext): """ The calculation step is 1e-2, so output every 5 solutions or 0.05, means a frame rate of 20 frames per second """ import shutil fps = 20 if os.path.isdir('figsslidingpendulum'): shutil.rmtree('figsslidingpendulum') os.mkdir('figsslidingpendulum') if not os.path.isdir('anislidingpendulum'): os.mkdir('anislidingpendulum') pylab.figure(2) secs = 0 frame = 0 print('Generating output ...\n') for solnr in range(0,nr,5): drawonesol(solnr, sizex, sizey, frame) frame += 1 if solnr // 500 != secs : secs = solnr // 500 print(' ... at %i seconds ' % (secs * 5 )) print('Creating movie using ffmpeg with output ... \n') import subprocess subprocess.call(['ffmpeg', '-r', '20', '-i', 'figsslidingpendulum' + os.sep + 'outsol%8d.png', '-f', 'avi', '-y', 'anislidingpendulum' + os.sep + 'slidingpendulum'+ext+'.mpg']) #remove unused pictures shutil.rmtree('figsslidingpendulum') #opening movie with default player print('Opening user with default application ... \n') open_file_with_default_application('anislidingpendulum' + os.sep + 'slidingpendulum'+ext+'.mpg') input2 = input('Create animation of the solution? (y/n): ') print('\n') if (input2 == 'y' or input2 == 'yes'): create_animation(1.+problem.l, 1+problem.l, '0')
def main(): """ The main program: instantiate a problem, then use odes package to solve it """ uinput = input( "Solve as\n 1 = index 2 problem \n 2 = index 1 problem (Not working!)\n" " \n 4 = info\n\n" "Answer (1,2 or 4) : " ) if uinput == "1": problem = Slidingpendulum(type="index2") elif uinput == "2": problem = Slidingpendulum(type="index1") else: print(__doc__) return input1 = input("Solve with\n 1 = ida\n 2 = ddaspk\n\n" "Answer (1 or 2) : ").strip() if input1 not in ["1", "2"]: print("Invalid solution method given") return if input1 == "1": ig = dae("ida", problem.res, atol=1e-5, rtol=1e-4, max_conv_fails=200) elif input1 == "2": ig = dae("ddaspk", problem.res, atol=1e-5, rtol=1e-4) # for ddaspk, scale2 must not be that big problem.scale2 = 1.0 ig.set_options( jacfn=problem.jac, algebraic_vars_idx=problem.algvaridx, compute_initcond="yp0", exclude_algvar_from_error=problem.exclalg_err, max_steps=15000, first_step_size=1e-9, ) # Solve it result = ig.solve(problem.stop_t, problem.z0, problem.zprime0) time = result[1] z = result[2] zprime = result[3] # some user output print("started from z0 = ", problem.z0) print("initial condition calculated, [z,zprime] = [", z[0], zprime[0], "]") print("last sol at time", time[-1]) print(" has solution ", z[-1], zprime[-1]) res = empty(problem.neq, float) problem.res(problem.stop_t[-1], z[-1], zprime[-1], res) print(" has residual: ", res) xt = z[:, 0] yt = z[:, 1] thetat = z[:, 2] nr = len(xt) pylab.ion() pylab.figure(1) pylab.subplot(111) pylab.scatter(xt, yt) pylab.scatter(xt + problem.l * sin(thetat), yt - problem.l * cos(thetat)) pylab.axis("equal") pylab.axis() pylab.show() def circle(ax, x, y, r, color="r"): count = 20 ax.fill( [x + r * cos(2.0 * i * pi / count) for i in range(count + 1)], [y + r * sin(2.0 * i * pi / count) for i in range(count + 1)], color, ) def line(ax, x1, y1, x2, y2, color="black"): norm = sqrt((y2 - y1) ** 2 + (x2 - x1) ** 2) normal = [(y2 - y1) / norm, -(x2 - x1) / norm] ax.fill( [x1 - 0.01 * normal[0], x1 + 0.01 * normal[0], x2 + 0.01 * normal[0], x2 - 0.01 * normal[0]], [y1 - 0.01 * normal[1], y1 + 0.01 * normal[1], y2 + 0.01 * normal[1], y2 - 0.01 * normal[1]], color, ) def draw(ax, nr): sol = z[nr] x2 = sol[0] + problem.l * sin(sol[2]) y2 = sol[1] - problem.l * cos(sol[2]) line(ax, sol[0], sol[1], x2, y2) circle(ax, x2, y2, 0.1) def drawonesol(nr, sizex, sizey, ext=None): pylab.clf() a = pylab.axes() draw(a, nr) pylab.axis("scaled") pylab.xlim(-sizex, sizex) pylab.ylim(-sizey, sizey) if ext is None: ext = nr pylab.savefig("figsslidingpendulum" + os.sep + "outsol%08i.png" % ext) def open_file_with_default_application(file_path): """ Launch a program to open an arbitrary file. The file will be opened using whatever program is configured on the host as the default program for that type of file. """ norm_path = os.path.normpath(file_path) if not os.path.exists(norm_path): print("%s does not exist" % file_path) return if os.sys.platform == "win32": try: os.startfile(norm_path) except WindowsError as msg: print("Error Opening File. " + str(msg)) else: search = os.environ["PATH"].split(":") for path in search: prog = os.path.join(path, "xdg-open") if os.path.isfile(prog): os.spawnvpe(os.P_NOWAIT, prog, [prog, norm_path], os.environ) return def create_animation(sizex, sizey, ext): """ The calculation step is 1e-2, so output every 5 solutions or 0.05, means a frame rate of 20 frames per second """ import shutil fps = 20 if os.path.isdir("figsslidingpendulum"): shutil.rmtree("figsslidingpendulum") os.mkdir("figsslidingpendulum") if not os.path.isdir("anislidingpendulum"): os.mkdir("anislidingpendulum") pylab.figure(2) secs = 0 frame = 0 print("Generating output ...\n") for solnr in range(0, nr, 5): drawonesol(solnr, sizex, sizey, frame) frame += 1 if solnr // 500 != secs: secs = solnr // 500 print(" ... at %i seconds " % (secs * 5)) print("Creating movie using ffmpeg with output ... \n") import subprocess subprocess.call( [ "ffmpeg", "-r", "20", "-i", "figsslidingpendulum" + os.sep + "outsol%8d.png", "-f", "avi", "-y", "anislidingpendulum" + os.sep + "slidingpendulum" + ext + ".mpg", ] ) # remove unused pictures shutil.rmtree("figsslidingpendulum") # opening movie with default player print("Opening user with default application ... \n") open_file_with_default_application("anislidingpendulum" + os.sep + "slidingpendulum" + ext + ".mpg") input2 = input("Create animation of the solution? (y/n): ") print("\n") if input2 == "y" or input2 == "yes": create_animation(1.0 + problem.l, 1 + problem.l, "0")
m = 1.0 #initial data on t=0, x[0] = u, x[1] = \dot{u}, xp = \dot{x} initx = [1, 0.1] initxp = [initx[1], -k / m * initx[0]] #define function for the residual equations which has specific signature def reseqn(t, x, xdot, result): """ we create residual equations for the problem""" result[0] = m * xdot[1] + k * x[0] result[1] = xdot[0] - x[1] #instantiate the solver from scikits.odes import dae solver = dae('ida', reseqn) #obtain solution at a required time result = solver.solve([0., 1., 2.], initx, initxp) print('\n t Solution Exact') print('------------------------------------') for t, u in zip(result[1], result[2]): print('%4.2f %15.6g %15.6g' % (t, u[0], initx[0] * cos(sqrt(k / m) * t) + initx[1] * sin(sqrt(k / m) * t) / sqrt(k / m))) #continue the solver result = solver.solve([result[1][-1], result[1][-1] + 1], result[2][-1], result[3][-1]) print('------------------------------------')