1*69777137SStefano Zampiniimport sys 2*69777137SStefano Zampiniimport petsc4py 3*69777137SStefano Zampini 455a74a43SLisandro Dalcinpetsc4py.init(sys.argv) 555a74a43SLisandro Dalcin 655a74a43SLisandro Dalcinfrom petsc4py import PETSc 755a74a43SLisandro Dalcin 8*69777137SStefano Zampini 9*69777137SStefano Zampiniclass BouncingBall: 1055a74a43SLisandro Dalcin n = 2 1155a74a43SLisandro Dalcin comm = PETSc.COMM_SELF 1255a74a43SLisandro Dalcin 1355a74a43SLisandro Dalcin def __init__(self): 1455a74a43SLisandro Dalcin pass 1555a74a43SLisandro Dalcin 1655a74a43SLisandro Dalcin def initialCondition(self, u): 1755a74a43SLisandro Dalcin u[0] = 0.0 1855a74a43SLisandro Dalcin u[1] = 20.0 1955a74a43SLisandro Dalcin u.assemble() 2055a74a43SLisandro Dalcin 2155a74a43SLisandro Dalcin def evalRHSFunction(self, ts, t, u, f): 2255a74a43SLisandro Dalcin f[0] = u[1] 2355a74a43SLisandro Dalcin f[1] = -9.8 2455a74a43SLisandro Dalcin f.assemble() 2555a74a43SLisandro Dalcin 2655a74a43SLisandro Dalcin def evalRHSJacobian(self, ts, t, u, A, B): 2755a74a43SLisandro Dalcin J = A 2855a74a43SLisandro Dalcin J[0, 0] = 0.0 2955a74a43SLisandro Dalcin J[1, 0] = 0.0 3055a74a43SLisandro Dalcin J[0, 1] = 1.0 3155a74a43SLisandro Dalcin J[1, 1] = 0.0 3255a74a43SLisandro Dalcin J.assemble() 33*69777137SStefano Zampini if A != B: 34*69777137SStefano Zampini B.assemble() 3555a74a43SLisandro Dalcin 3655a74a43SLisandro Dalcin 37*69777137SStefano Zampiniclass Monitor: 3855a74a43SLisandro Dalcin def __init__(self): 3955a74a43SLisandro Dalcin pass 4055a74a43SLisandro Dalcin 4155a74a43SLisandro Dalcin def __call__(self, ts, k, t, x): 42*69777137SStefano Zampini PETSc.Sys.Print(f'Position at time {t}: {x[0]}') 43*69777137SStefano Zampini 4455a74a43SLisandro Dalcin 4555a74a43SLisandro Dalcinode = BouncingBall() 4655a74a43SLisandro Dalcin 4755a74a43SLisandro DalcinJ = PETSc.Mat().create() 4855a74a43SLisandro DalcinJ.setSizes([ode.n, ode.n]) 4955a74a43SLisandro DalcinJ.setType('aij') 5055a74a43SLisandro DalcinJ.setUp() 5155a74a43SLisandro DalcinJ.assemble() 5255a74a43SLisandro Dalcin 5355a74a43SLisandro Dalcinu = PETSc.Vec().createSeq(ode.n, comm=ode.comm) 5455a74a43SLisandro Dalcinf = u.duplicate() 5555a74a43SLisandro Dalcin 5655a74a43SLisandro Dalcints = PETSc.TS().create(comm=ode.comm) 5755a74a43SLisandro Dalcints.setProblemType(ts.ProblemType.NONLINEAR) 5855a74a43SLisandro Dalcin 5955a74a43SLisandro Dalcints.setType(ts.Type.BEULER) 6055a74a43SLisandro Dalcints.setRHSFunction(ode.evalRHSFunction, f) 6155a74a43SLisandro Dalcints.setRHSJacobian(ode.evalRHSJacobian, J) 6255a74a43SLisandro Dalcin 6355a74a43SLisandro Dalcin# ts.setSaveTrajectory() 6455a74a43SLisandro Dalcints.setTime(0.0) 6555a74a43SLisandro Dalcints.setTimeStep(0.01) 6655a74a43SLisandro Dalcints.setMaxTime(15.0) 6755a74a43SLisandro Dalcin# ts.setMaxSteps(1000) 6855a74a43SLisandro Dalcints.setExactFinalTime(PETSc.TS.ExactFinalTime.MATCHSTEP) 6955a74a43SLisandro Dalcin# ts.setMonitor(Monitor()) 7055a74a43SLisandro Dalcin 7155a74a43SLisandro Dalcindirection = [-1] 7255a74a43SLisandro Dalcinterminate = [False] 7355a74a43SLisandro Dalcin 74*69777137SStefano Zampini 7555a74a43SLisandro Dalcindef event(ts, t, X, fvalue): 7655a74a43SLisandro Dalcin fvalue[0] = X[0] 7755a74a43SLisandro Dalcin 78*69777137SStefano Zampini 7955a74a43SLisandro Dalcindef postevent(ts, events, t, X, forward): 8055a74a43SLisandro Dalcin X[0] = 0.0 8155a74a43SLisandro Dalcin X[1] = -0.9 * X[1] 8255a74a43SLisandro Dalcin X.assemble() 8355a74a43SLisandro Dalcin 84*69777137SStefano Zampini 8555a74a43SLisandro Dalcints.setEventHandler(direction, terminate, event, postevent) 8655a74a43SLisandro Dalcints.setEventTolerances(1e-6, vtol=[1e-9]) 8755a74a43SLisandro Dalcin 8855a74a43SLisandro Dalcints.setFromOptions() 8955a74a43SLisandro Dalcin 9055a74a43SLisandro Dalcinode.initialCondition(u) 9155a74a43SLisandro Dalcints.solve(u) 92