def test_save_2d_mixed(tempdir): mesh = UnitCubeMesh(MPI.COMM_WORLD, 3, 3, 3) P2 = ufl.VectorElement("Lagrange", mesh.ufl_cell(), 2) P1 = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), 1) TH = P2 * P1 W = FunctionSpace(mesh, TH) def vec_func(x): vals = np.zeros((3, x.shape[1])) vals[0] = x[0] vals[1] = 0.2 * x[1] return vals def scal_func(x): return 0.5 * x[0] U = Function(W) U.sub(0).interpolate(vec_func) U.sub(1).interpolate(scal_func) U.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD) filename = os.path.join(tempdir, "u.pvd") with VTKFile(mesh.mpi_comm(), filename, "w") as vtk: vtk.write_function([U.sub(i) for i in range(W.num_sub_spaces())], 0.)
file.write_mesh(mesh) # Step in time t = 0.0 # Check if we are running on CI server and reduce run time if "CI" in os.environ.keys() or "GITHUB_ACTIONS" in os.environ.keys(): T = 3 * dt else: T = 50 * dt u.vector.copy(result=u0.vector) u0.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD) while (t < T): t += dt r = solver.solve(problem, u.vector) print("Step, num iterations:", int(t / dt), r[0]) u.vector.copy(result=u0.vector) file.write_function(u.sub(0), t) file.close() # Within the time stepping loop, the nonlinear problem is solved by # calling :py:func:`solver.solve(problem,u.vector)<dolfinx.cpp.NewtonSolver.solve>`, # with the new solution vector returned in :py:func:`u.vector<dolfinx.cpp.Function.vector>`. # The solution vector associated with ``u`` is copied to ``u0`` at the # end of each time step, and the ``c`` component of the solution # (the first component of ``u``) is then written to file.
# Set Dirichlet boundary condition values in the RHS dolfinx.fem.assemble.set_bc(b, bcs) # Create and configure solver ksp = PETSc.KSP().create(mesh.mpi_comm()) ksp.setOperators(A) ksp.setType("preonly") ksp.getPC().setType("lu") ksp.getPC().setFactorSolverType("superlu_dist") # Compute the solution U = Function(W) ksp.solve(b, U.vector) # Split the mixed solution and collapse u = U.sub(0).collapse() p = U.sub(1).collapse() # Compute norms norm_u_3 = u.vector.norm() norm_p_3 = p.vector.norm() if MPI.COMM_WORLD.rank == 0: print("(D) Norm of velocity coefficient vector (monolithic, direct): {}".format(norm_u_3)) print("(D) Norm of pressure coefficient vector (monolithic, direct): {}".format(norm_p_3)) assert np.isclose(norm_u_3, norm_u_0) # Write the solution to file with XDMFFile(MPI.COMM_WORLD, "new_velocity.xdmf", "w") as ufile_xdmf: u.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD) ufile_xdmf.write_mesh(mesh) ufile_xdmf.write_function(u)
# The line ``c, mu = split(u)`` permits direct access to the components of # a mixed function. Note that ``c`` and ``mu`` are references for # components of ``u``, and not copies. # # .. index:: # single: interpolating functions; (in Cahn-Hilliard demo) # # The initial conditions are interpolated into a finite element space:: # Zero u with u.vector.localForm() as x_local: x_local.set(0.0) # Interpolate initial condition u.sub(0).interpolate(lambda x: 0.63 + 0.02 * (0.5 - np.random.rand(x.shape[1]))) # The first line creates an object of type ``InitialConditions``. The # following two lines make ``u`` and ``u0`` interpolants of ``u_init`` # (since ``u`` and ``u0`` are finite element functions, they may not be # able to represent a given function exactly, but the function can be # approximated by interpolating it in a finite element space). # # .. index:: automatic differentiation # # The chemical potential :math:`df/dc` is computed using automated # differentiation:: # Compute the chemical potential df/dc c = variable(c) f = 100 * c**2 * (1 - c)**2
# deep copy. If no argument is given we will get a shallow copy. We want # a deep copy for further computations on the coefficient vectors:: # Compute solution w = Function(W) solve(a == L, w, bcs, petsc_options={ "ksp_type": "preonly", "pc_type": "lu", "pc_factor_mat_solver_type": "mumps" }) # Split the mixed solution and collapse u = w.sub(0).collapse() p = w.sub(1).collapse() # We can calculate the :math:`L^2` norms of u and p as follows:: print("Norm of velocity coefficient vector: %.15g" % u.vector.norm()) print("Norm of pressure coefficient vector: %.15g" % p.vector.norm()) # Check pressure norm assert np.isclose(p.vector.norm(), 4147.69457577) # Finally, we can save and plot the solutions:: # Save solution in XDMF format with XDMFFile(MPI.comm_world, "velocity.xdmf") as ufile_xdmf: ufile_xdmf.write(u)
# Output file file = XDMFFile(MPI.comm_world, "output.xdmf") # Step in time t = 0.0 # Check if we are running on CI server and reduce run time if "CI" in os.environ.keys(): T = 3 * dt else: T = 50 * dt u.vector.copy(result=u0.vector) u0.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD) while (t < T): t += dt r = solver.solve(problem, u.vector) print("Step, num iterations:", int(t / dt), r[0]) u.vector.copy(result=u0.vector) file.write(u.sub(0), t) # Within the time stepping loop, the nonlinear problem is solved by # calling :py:func:`solver.solve(problem,u.vector)<dolfinx.cpp.NewtonSolver.solve>`, # with the new solution vector returned in :py:func:`u.vector<dolfinx.cpp.Function.vector>`. # The solution vector associated with ``u`` is copied to ``u0`` at the # end of each time step, and the ``c`` component of the solution # (the first component of ``u``) is then written to file.