Questions for Solving time-dependent problem

With the following code in Fenics tutorial for NS equations,

with b1.localForm() as loc_1:
    loc_1.set(0)
    fem.petsc.assemble_vector(b1,L1)
    fem.petsc.apply_lifting(b1,[a1],[bcu])
    b1.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES,mode=PETSc.ScatterMode.REVERSE)
    fem.petsc.set_bc(b1,bcu)
    solver1.solver(b1,u_.vector)
    u_.x.scatter_forward()

I have some questions:
1.What do localForm() and set(0) do?
2.Since we already use apply_lifting() to apply Dirichlet condition for vector b1, why do we still need to use set_bc for b1?And why should we update ghost points?I comment the “b1.ghost…” line but the computation result is the same.Is this corresponding with MPI.COMM_WORLD?

1 Like

petsc4py.PETSc._Vec_LocalForm, i.e. it is a way of accessing the local part of the vector in a context manager, see
27. Context Managers — Python Tips 0.1 documentation for notes regarding general managers.
Set(0) sets the local part of the vector to 0.

Apply lifting changes the vector to b1-= A1 g
where A1 is the matrix assembled by a1, g a vector were only having nonzero entries for the dofs. This adds contributions to all the other entries, where the bc is not set. You use set_bc to overwrite any entries with bc with the corresponding value from bcu.

Because whenever you assemble into a vector, you only assemble over cells/facets owned by the process. For dofs shared between processes, you need to add up contributions from all of them. See
for instance DOLFINx in Parallel with MPI — NewFrac FEniCSx Training

By this you mean dofs w.r.t boundary condtion or dofs w.r.t all nodes?And what is g?
I understand like this:
For example, after using a1=assemble_matrix(a1,bcs=bcu),assemble a1 will delete the row w.r.t boundary points?But b1=create_vector(L1) still considers boundary nodes and we use apply_lifting to take care of boundary conditions by subtracting boundary conditions from other dofs not corresponding with boundary points? So apply_lifting only changes dofs’ values w.r.t other dofs,not boundary dofs, while we use set_bc to change dofs w.r.t boundary terms?

This way what is the length of b1? Is its length equal to all dofs minus dofs w.r.t boundary conditions?

Imagine you have a boundary condition u=g_D on \partial \Omega_D. Then g is the setting described above is a Function in the function space of u, that is equal to
g_D on all dofs on the prescribed boundary, and 0 at all other dofs.

No, a1=... will assemble a matrix of size (num_dofs x num_dofs), where all contributions from dofs in any boundary condition has been nulled out. I.e. any row or column corresponding to a bc-dof has only zeros. Then, it sets a 1 on the diagonal, making all bc rows an identity row.

b1 is of size num_dofs, and thus we use set_bc to enforce the boundary condition for those rows.

Very clear! Thank you very much.

Sorry for another question about what does scatter_forward() do here?Is it needed necessarily here?

Please read the post

As it covers this aspect.
It is needed if you want your code to work in parallel.