def solve_system(N): fenics_mesh = dolfinx.UnitCubeMesh(fenicsx_comm, N, N, N) fenics_space = dolfinx.FunctionSpace(fenics_mesh, ("CG", 1)) u = ufl.TrialFunction(fenics_space) v = ufl.TestFunction(fenics_space) k = 2 # print(u*v*ufl.ds) form = (ufl.inner(ufl.grad(u), ufl.grad(v)) - k**2 * ufl.inner(u, v)) * ufl.dx # locate facets on the cube boundary facets = locate_entities_boundary( fenics_mesh, 2, lambda x: np.logical_or( np.logical_or( np.logical_or(np.isclose(x[2], 0.0), np.isclose(x[2], 1.0)), np.logical_or(np.isclose(x[1], 0.0), np.isclose(x[1], 1.0))), np.logical_or(np.isclose(x[0], 0.0), np.isclose(x[0], 1.0)))) facets.sort() # alternative - more general approach boundary = entities_to_geometry( fenics_mesh, fenics_mesh.topology.dim - 1, exterior_facet_indices(fenics_mesh), True, ) # print(len(facets) assert len(facets) == len(exterior_facet_indices(fenics_mesh)) u0 = fem.Function(fenics_space) with u0.vector.localForm() as u0_loc: u0_loc.set(0) # solution vector bc = DirichletBC(u0, locate_dofs_topological(fenics_space, 2, facets)) A = 1 + 1j f = Function(fenics_space) f.interpolate(lambda x: A * k**2 * np.cos(k * x[0]) * np.cos(k * x[1])) L = ufl.inner(f, v) * ufl.dx u0.name = "u" problem = fem.LinearProblem(form, L, u=u0, petsc_options={ "ksp_type": "preonly", "pc_type": "lu" }) # problem = fem.LinearProblem(form, L, bcs=[bc], u=u0, petsc_options={"ksp_type": "preonly", "pc_type": "lu"}) start_time = time.time() soln = problem.solve() if world_rank == 0: print("--- fenics solve done in %s seconds ---" % (time.time() - start_time))
# Now, we have specified the variational forms and can consider the # solution of the variational problem. First, we need to define a # :py:class:`Function <dolfinx.functions.fem.Function>` ``u`` to # represent the solution. (Upon initialization, it is simply set to the # zero function.) A :py:class:`Function # <dolfinx.functions.fem.Function>` represents a function living in a # finite element function space. Next, we initialize a solver using the # :py:class:`LinearProblem <dolfinx.fem.linearproblem.LinearProblem>`. # This class is initialized with the arguments ``a``, ``L``, and ``bc`` # as follows: :: In this problem, we use a direct LU solver, which is # defined through the dictionary ``petsc_options``. problem = fem.LinearProblem(a, L, bcs=[bc], petsc_options={ "ksp_type": "preonly", "pc_type": "lu" }) # When we want to compute the solution to the problem, we can specify # what kind of solver we want to use. uh = problem.solve() # The function ``u`` will be modified during the call to solve. The # default settings for solving a variational problem have been used. # However, the solution process can be controlled in much more detail if # desired. # # A :py:class:`Function <dolfinx.functions.fem.Function>` can be # manipulated in various ways, in particular, it can be plotted and
# Test and trial function space V = FunctionSpace(mesh, ("Lagrange", deg)) # Define variational problem u = TrialFunction(V) v = TestFunction(V) f = Function(V) f.interpolate(lambda x: A * k0**2 * np.cos(k0 * x[0]) * np.cos(k0 * x[1])) a = inner(grad(u), grad(v)) * dx - k0**2 * inner(u, v) * dx L = inner(f, v) * dx # Compute solution uh = fem.Function(V) uh.name = "u" problem = fem.LinearProblem(a, L, u=uh) problem.solve() # Save solution in XDMF format (to be viewed in Paraview, for example) with XDMFFile(MPI.COMM_WORLD, "plane_wave.xdmf", "w", encoding=XDMFFile.Encoding.HDF5) as file: file.write_mesh(mesh) file.write_function(uh) # Calculate L2 and H1 errors of FEM solution and best approximation. # This demonstrates the error bounds given in Ihlenburg. Pollution errors # are evident for high wavenumbers. ::