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