Canonical way to apply PETSc matrix to fem.Function vector

I have an explicit time evolution scheme that I would like to iterate by applying a bilinear form to a solution vector (repeatedly). From the elasticity tutorial it appears that one may assemble a PETSc matrix A from a bilinear form a. In that tutorial a PETSc vector b is also created from a linear form L, to which A could then be applied (although in that tutorial they solve the system). Additionally, in the Cahn-Hilliard demo, they directly manipulate the solution vectors via u0.x.array[:] = u.x.array.

I would like to apply a matrix A to a solution vector u0.x.array[:] in order to update the next timestep u. Is this possible to do in Fenics on a distributed system without generating a bunch of copies? Is there some canonical way to do this?

If I understand you correctly, you’re looking to multiply the vector u0 with a matrix A in order to obtain a new vector u? Probably the easiest way to do this is to just stick to using PETSc. The petsc4py Mat class has the function mult, which allows you to do what I assume you are after. You should be able to call that function with your assembled PETSc matrix A.