1*d027ae82SHong Zhang# \begin{eqnarray} 2*d027ae82SHong Zhang# ys' = -2.0*\frac{-1.0+ys^2.0-\cos(t)}{2.0*ys}+0.05*\frac{-2.0+yf^2-\cos(5.0*t)}{2.0*yf}-\frac{\sin(t)}{2.0*ys}\\ 3*d027ae82SHong Zhang# yf' = 0.05*\frac{-1.0+ys^2-\cos(t)}{2.0*ys}-\frac{-2.0+yf^2-\cos(5.0*t)}{2.0*yf}-5.0*\frac{\sin(5.0*t)}{2.0*yf}\\ 4*d027ae82SHong Zhang# \end{eqnarray} 5*d027ae82SHong Zhang 6*d027ae82SHong Zhang# This example demonstrates how to use ARKIMEX for solving a fast-slow system. The system is partitioned additively and component-wise at the same time. 7*d027ae82SHong Zhang# ys stands for the slow component and yf stands for the fast component. On the RHS for yf, only the term -\frac{-2.0+yf^2-\cos(5.0*t)}{2.0*yf} is treated implicitly while the rest is treated explicitly. 8*d027ae82SHong Zhang 9*d027ae82SHong Zhangimport sys, petsc4py 10*d027ae82SHong Zhangpetsc4py.init(sys.argv) 11*d027ae82SHong Zhang 12*d027ae82SHong Zhangfrom petsc4py import PETSc 13*d027ae82SHong Zhangimport numpy as np 14*d027ae82SHong Zhang 15*d027ae82SHong Zhangclass FSS(object): 16*d027ae82SHong Zhang n = 2 17*d027ae82SHong Zhang comm = PETSc.COMM_SELF 18*d027ae82SHong Zhang def __init__(self): 19*d027ae82SHong Zhang pass 20*d027ae82SHong Zhang def initialCondition(self, u): 21*d027ae82SHong Zhang u[0] = np.sqrt(2.0) 22*d027ae82SHong Zhang u[1] = np.sqrt(3.0) 23*d027ae82SHong Zhang u.assemble() 24*d027ae82SHong Zhang def evalRHSFunction(self, ts, t, u, f): 25*d027ae82SHong Zhang f[0] = -2.0 * (-1.0 + u[0] * u[0] - np.cos(t)) / (2.0 * u[0]) + 0.05 * (-2.0 + u[1] * u[1] - np.cos(5.0 * t)) / (2.0 * u[1]) - np.sin(t) / (2.0 * u[0]) 26*d027ae82SHong Zhang f[1] = 0.05 * (-1.0 + u[0] * u[0] - np.cos(t)) / (2.0 * u[0]) - (-2.0 + u[1] * u[1] - np.cos(5.0 * t)) / (2.0 * u[1]) - 5.0 * np.sin(5.0 * t) / (2.0 * u[1]) 27*d027ae82SHong Zhang f.assemble 28*d027ae82SHong Zhang def evalRHSFunctionSlow(self, ts, t, u, f): 29*d027ae82SHong Zhang f[0] = -2.0 * (-1.0 + u[0] * u[0] - np.cos(t)) / (2.0 * u[0]) + 0.05 * (-2.0 + u[1] * u[1] - np.cos(5.0 * t)) / (2.0 * u[1]) - np.sin(t) / (2.0 * u[0]); 30*d027ae82SHong Zhang f.assemble() 31*d027ae82SHong Zhang def evalRHSFunctionFast(self, ts, t, u, f): 32*d027ae82SHong Zhang f[0] = 0.05 * (-1.0 + u[0] * u[0] - np.cos(t)) / (2.0 * u[0]) - 5.0 * np.sin(5.0 * t) / (2.0 * u[1]) 33*d027ae82SHong Zhang f.assemble() 34*d027ae82SHong Zhang def evalIFunctionFast(self, ts, t, u, udot, f): 35*d027ae82SHong Zhang f[0] = udot[0] + (-2.0 + u[1] * u[1] - np.cos(5.0 * t)) / (2.0 * u[1]); 36*d027ae82SHong Zhang f.assemble() 37*d027ae82SHong Zhang def evalIJacobianFast(self, ts, t, u, udot, a, A, B): 38*d027ae82SHong Zhang A[0,0] = a + (2.0 + np.cos(5.0 * t)) / (2.0 * u[1] * u[1]) + 0.5 39*d027ae82SHong Zhang A.assemble() 40*d027ae82SHong Zhang if A != B: B.assemble() 41*d027ae82SHong Zhang return True # same nonzero pattern 42*d027ae82SHong Zhang 43*d027ae82SHong ZhangOptDB = PETSc.Options() 44*d027ae82SHong Zhangexplicitform_ = OptDB.getBool('explicitform', False) 45*d027ae82SHong Zhang 46*d027ae82SHong Zhangode = FSS() 47*d027ae82SHong Zhang 48*d027ae82SHong ZhangJim = PETSc.Mat().createDense([1,1], comm=ode.comm) 49*d027ae82SHong ZhangJim.setUp() 50*d027ae82SHong Zhang 51*d027ae82SHong Zhangu = PETSc.Vec().createSeq(ode.n, comm=ode.comm) 52*d027ae82SHong Zhang 53*d027ae82SHong Zhangts = PETSc.TS().create(comm=ode.comm) 54*d027ae82SHong Zhangts.setProblemType(ts.ProblemType.NONLINEAR) 55*d027ae82SHong Zhang 56*d027ae82SHong Zhangif not explicitform_: 57*d027ae82SHong Zhang iss = PETSc.IS().createGeneral([0], comm=ode.comm) 58*d027ae82SHong Zhang isf = PETSc.IS().createGeneral([1], comm=ode.comm) 59*d027ae82SHong Zhang ts.setType(ts.Type.ARKIMEX) 60*d027ae82SHong Zhang ts.setARKIMEXFastSlowSplit(True) 61*d027ae82SHong Zhang ts.setRHSSplitIS("slow",iss) 62*d027ae82SHong Zhang ts.setRHSSplitIS("fast",isf) 63*d027ae82SHong Zhang ts.setRHSSplitRHSFunction("slow", ode.evalRHSFunctionSlow, None) 64*d027ae82SHong Zhang ts.setRHSSplitRHSFunction("fast", ode.evalRHSFunctionFast, None) 65*d027ae82SHong Zhang ts.setRHSSplitIFunction("fast", ode.evalIFunctionFast, None) 66*d027ae82SHong Zhang ts.setRHSSplitIJacobian("fast", ode.evalIJacobianFast, Jim, Jim) 67*d027ae82SHong Zhangelse: 68*d027ae82SHong Zhang f = u.duplicate() 69*d027ae82SHong Zhang ts.setType(ts.Type.RK) 70*d027ae82SHong Zhang ts.setRHSFunction(ode.evalRHSFunction, f) 71*d027ae82SHong Zhang 72*d027ae82SHong Zhangts.setTimeStep(0.01) 73*d027ae82SHong Zhangts.setMaxTime(0.3) 74*d027ae82SHong Zhangts.setExactFinalTime(PETSc.TS.ExactFinalTime.MATCHSTEP) 75*d027ae82SHong Zhang 76*d027ae82SHong Zhangts.setFromOptions() 77*d027ae82SHong Zhangode.initialCondition(u) 78*d027ae82SHong Zhangts.solve(u) 79*d027ae82SHong Zhangu.view() 80*d027ae82SHong Zhang 81*d027ae82SHong Zhangdel ode, Jim, u, ts 82