File: bouncing_ball.py

package info (click to toggle)
petsc4py 3.23.1-1exp2
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 3,448 kB
  • sloc: python: 12,503; ansic: 1,697; makefile: 343; f90: 313; sh: 14
file content (91 lines) | stat: -rw-r--r-- 1,659 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import sys
import petsc4py

petsc4py.init(sys.argv)

from petsc4py import PETSc


class BouncingBall:
    n = 2
    comm = PETSc.COMM_SELF

    def __init__(self):
        pass

    def initialCondition(self, u):
        u[0] = 0.0
        u[1] = 20.0
        u.assemble()

    def evalRHSFunction(self, ts, t, u, f):
        f[0] = u[1]
        f[1] = -9.8
        f.assemble()

    def evalRHSJacobian(self, ts, t, u, A, B):
        J = A
        J[0, 0] = 0.0
        J[1, 0] = 0.0
        J[0, 1] = 1.0
        J[1, 1] = 0.0
        J.assemble()
        if A != B:
            B.assemble()


class Monitor:
    def __init__(self):
        pass

    def __call__(self, ts, k, t, x):
        PETSc.Sys.Print(f'Position at time {t}: {x[0]}')


ode = BouncingBall()

J = PETSc.Mat().create()
J.setSizes([ode.n, ode.n])
J.setType('aij')
J.setUp()
J.assemble()

u = PETSc.Vec().createSeq(ode.n, comm=ode.comm)
f = u.duplicate()

ts = PETSc.TS().create(comm=ode.comm)
ts.setProblemType(ts.ProblemType.NONLINEAR)

ts.setType(ts.Type.BEULER)
ts.setRHSFunction(ode.evalRHSFunction, f)
ts.setRHSJacobian(ode.evalRHSJacobian, J)

# ts.setSaveTrajectory()
ts.setTime(0.0)
ts.setTimeStep(0.01)
ts.setMaxTime(15.0)
# ts.setMaxSteps(1000)
ts.setExactFinalTime(PETSc.TS.ExactFinalTime.MATCHSTEP)
# ts.setMonitor(Monitor())

direction = [-1]
terminate = [False]


def event(ts, t, X, fvalue):
    fvalue[0] = X[0]


def postevent(ts, events, t, X, forward):
    X[0] = 0.0
    X[1] = -0.9 * X[1]
    X.assemble()


ts.setEventHandler(direction, terminate, event, postevent)
ts.setEventTolerances(1e-6, vtol=[1e-9])

ts.setFromOptions()

ode.initialCondition(u)
ts.solve(u)