1d027ae82SHong Zhang# \begin{eqnarray} 2d027ae82SHong 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}\\ 3d027ae82SHong 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}\\ 4d027ae82SHong Zhang# \end{eqnarray} 5d027ae82SHong Zhang 6d027ae82SHong 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. 7d027ae82SHong 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. 8d027ae82SHong Zhang 9*69777137SStefano Zampiniimport sys 10*69777137SStefano Zampiniimport petsc4py 11*69777137SStefano Zampini 12d027ae82SHong Zhangpetsc4py.init(sys.argv) 13d027ae82SHong Zhang 14d027ae82SHong Zhangfrom petsc4py import PETSc 15d027ae82SHong Zhangimport numpy as np 16d027ae82SHong Zhang 17*69777137SStefano Zampini 18*69777137SStefano Zampiniclass FSS: 19d027ae82SHong Zhang n = 2 20d027ae82SHong Zhang comm = PETSc.COMM_SELF 21*69777137SStefano Zampini 22d027ae82SHong Zhang def __init__(self): 23d027ae82SHong Zhang pass 24*69777137SStefano Zampini 25d027ae82SHong Zhang def initialCondition(self, u): 26d027ae82SHong Zhang u[0] = np.sqrt(2.0) 27d027ae82SHong Zhang u[1] = np.sqrt(3.0) 28d027ae82SHong Zhang u.assemble() 29*69777137SStefano Zampini 30d027ae82SHong Zhang def evalRHSFunction(self, ts, t, u, f): 31*69777137SStefano Zampini f[0] = ( 32*69777137SStefano Zampini -2.0 * (-1.0 + u[0] * u[0] - np.cos(t)) / (2.0 * u[0]) 33*69777137SStefano Zampini + 0.05 * (-2.0 + u[1] * u[1] - np.cos(5.0 * t)) / (2.0 * u[1]) 34*69777137SStefano Zampini - np.sin(t) / (2.0 * u[0]) 35*69777137SStefano Zampini ) 36*69777137SStefano Zampini f[1] = ( 37*69777137SStefano Zampini 0.05 * (-1.0 + u[0] * u[0] - np.cos(t)) / (2.0 * u[0]) 38*69777137SStefano Zampini - (-2.0 + u[1] * u[1] - np.cos(5.0 * t)) / (2.0 * u[1]) 39*69777137SStefano Zampini - 5.0 * np.sin(5.0 * t) / (2.0 * u[1]) 40*69777137SStefano Zampini ) 41*69777137SStefano Zampini f.assemble() 42*69777137SStefano Zampini 43d027ae82SHong Zhang def evalRHSFunctionSlow(self, ts, t, u, f): 44*69777137SStefano Zampini f[0] = ( 45*69777137SStefano Zampini -2.0 * (-1.0 + u[0] * u[0] - np.cos(t)) / (2.0 * u[0]) 46*69777137SStefano Zampini + 0.05 * (-2.0 + u[1] * u[1] - np.cos(5.0 * t)) / (2.0 * u[1]) 47*69777137SStefano Zampini - np.sin(t) / (2.0 * u[0]) 48*69777137SStefano Zampini ) 49d027ae82SHong Zhang f.assemble() 50*69777137SStefano Zampini 51d027ae82SHong Zhang def evalRHSFunctionFast(self, ts, t, u, f): 52*69777137SStefano Zampini f[0] = 0.05 * (-1.0 + u[0] * u[0] - np.cos(t)) / (2.0 * u[0]) - 5.0 * np.sin( 53*69777137SStefano Zampini 5.0 * t 54*69777137SStefano Zampini ) / (2.0 * u[1]) 55d027ae82SHong Zhang f.assemble() 56*69777137SStefano Zampini 57d027ae82SHong Zhang def evalIFunctionFast(self, ts, t, u, udot, f): 58*69777137SStefano Zampini f[0] = udot[0] + (-2.0 + u[1] * u[1] - np.cos(5.0 * t)) / (2.0 * u[1]) 59d027ae82SHong Zhang f.assemble() 60*69777137SStefano Zampini 61d027ae82SHong Zhang def evalIJacobianFast(self, ts, t, u, udot, a, A, B): 62d027ae82SHong Zhang A[0, 0] = a + (2.0 + np.cos(5.0 * t)) / (2.0 * u[1] * u[1]) + 0.5 63d027ae82SHong Zhang A.assemble() 64*69777137SStefano Zampini if A != B: 65*69777137SStefano Zampini B.assemble() 66*69777137SStefano Zampini 67d027ae82SHong Zhang 68d027ae82SHong ZhangOptDB = PETSc.Options() 69d027ae82SHong Zhangexplicitform_ = OptDB.getBool('explicitform', False) 70d027ae82SHong Zhang 71d027ae82SHong Zhangode = FSS() 72d027ae82SHong Zhang 73d027ae82SHong ZhangJim = PETSc.Mat().createDense([1, 1], comm=ode.comm) 74d027ae82SHong ZhangJim.setUp() 75d027ae82SHong Zhang 76d027ae82SHong Zhangu = PETSc.Vec().createSeq(ode.n, comm=ode.comm) 77d027ae82SHong Zhang 78d027ae82SHong Zhangts = PETSc.TS().create(comm=ode.comm) 79d027ae82SHong Zhangts.setProblemType(ts.ProblemType.NONLINEAR) 80d027ae82SHong Zhang 81d027ae82SHong Zhangif not explicitform_: 82d027ae82SHong Zhang iss = PETSc.IS().createGeneral([0], comm=ode.comm) 83d027ae82SHong Zhang isf = PETSc.IS().createGeneral([1], comm=ode.comm) 84d027ae82SHong Zhang ts.setType(ts.Type.ARKIMEX) 85d027ae82SHong Zhang ts.setARKIMEXFastSlowSplit(True) 86*69777137SStefano Zampini ts.setRHSSplitIS('slow', iss) 87*69777137SStefano Zampini ts.setRHSSplitIS('fast', isf) 88*69777137SStefano Zampini ts.setRHSSplitRHSFunction('slow', ode.evalRHSFunctionSlow, None) 89*69777137SStefano Zampini ts.setRHSSplitRHSFunction('fast', ode.evalRHSFunctionFast, None) 90*69777137SStefano Zampini ts.setRHSSplitIFunction('fast', ode.evalIFunctionFast, None) 91*69777137SStefano Zampini ts.setRHSSplitIJacobian('fast', ode.evalIJacobianFast, Jim, Jim) 92d027ae82SHong Zhangelse: 93d027ae82SHong Zhang f = u.duplicate() 94d027ae82SHong Zhang ts.setType(ts.Type.RK) 95d027ae82SHong Zhang ts.setRHSFunction(ode.evalRHSFunction, f) 96d027ae82SHong Zhang 97d027ae82SHong Zhangts.setTimeStep(0.01) 98d027ae82SHong Zhangts.setMaxTime(0.3) 99d027ae82SHong Zhangts.setExactFinalTime(PETSc.TS.ExactFinalTime.MATCHSTEP) 100d027ae82SHong Zhang 101d027ae82SHong Zhangts.setFromOptions() 102d027ae82SHong Zhangode.initialCondition(u) 103d027ae82SHong Zhangts.solve(u) 104d027ae82SHong Zhangu.view() 105d027ae82SHong Zhang 106d027ae82SHong Zhangdel ode, Jim, u, ts 107