xref: /petsc/src/binding/petsc4py/demo/legacy/ode/fastslowsplit.py (revision d027ae8252c8433bd30a9744018d99f45e0735bd)
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