def run_dg_test(mesh, V, degree): """ Manufactured Poisson problem, solving u = x[component]**n, where n is the degree of the Lagrange function space. """ u, v = TrialFunction(V), TestFunction(V) # Exact solution x = SpatialCoordinate(mesh) u_exact = x[1]**degree # Coefficient k = Function(V) k.vector.set(2.0) k.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD) # Source term f = -div(k * grad(u_exact)) # Mesh normals and element size n = FacetNormal(mesh) h = CellDiameter(mesh) h_avg = (h("+") + h("-")) / 2.0 # Penalty parameter alpha = 32 dx_ = dx(metadata={"quadrature_degree": -1}) ds_ = ds(metadata={"quadrature_degree": -1}) dS_ = dS(metadata={"quadrature_degree": -1}) a = inner(k * grad(u), grad(v)) * dx_ \ - k("+") * inner(avg(grad(u)), jump(v, n)) * dS_ \ - k("+") * inner(jump(u, n), avg(grad(v))) * dS_ \ + k("+") * (alpha / h_avg) * inner(jump(u, n), jump(v, n)) * dS_ \ - inner(k * grad(u), v * n) * ds_ \ - inner(u * n, k * grad(v)) * ds_ \ + (alpha / h) * inner(k * u, v) * ds_ L = inner(f, v) * dx_ - inner(k * u_exact * n, grad(v)) * ds_ \ + (alpha / h) * inner(k * u_exact, v) * ds_ for integral in a.integrals(): integral.metadata( )["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree( a) for integral in L.integrals(): integral.metadata( )["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree( L) b = assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) A = assemble_matrix(a, []) A.assemble() # Create LU linear solver solver = PETSc.KSP().create(MPI.COMM_WORLD) solver.setType(PETSc.KSP.Type.PREONLY) solver.getPC().setType(PETSc.PC.Type.LU) solver.setOperators(A) # Solve uh = Function(V) solver.solve(b, uh.vector) uh.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD) # Calculate error M = (u_exact - uh)**2 * dx M = fem.Form(M) error = mesh.mpi_comm().allreduce(assemble_scalar(M), op=MPI.SUM) assert np.absolute(error) < 1.0e-14
def readin_mesh(self): if self.meshfile_type=='ASCII': encoding = XDMFFile.Encoding.ASCII elif self.meshfile_type=='HDF5': encoding = XDMFFile.Encoding.HDF5 else: raise NameError('Choose either ASCII or HDF5 as meshfile_type, or add a different encoding!') # read in xdmf mesh - domain with XDMFFile(self.comm, self.mesh_domain, 'r', encoding=encoding) as infile: self.mesh = infile.read_mesh(name="Grid") self.mt_d = infile.read_meshtags(self.mesh, name="Grid") # read in xdmf mesh - boundary # here, we define b1 BCs as BCs associated to a topology one dimension less than the problem (most common), # b2 BCs two dimensions less, and b3 BCs three dimensions less # for a 3D problem - b1: surface BCs, b2: edge BCs, b3: point BCs # for a 2D problem - b1: edge BCs, b2: point BCs # 1D problems not supported (currently...) if self.mesh.topology.dim == 3: try: self.mesh.topology.create_connectivity(2, self.mesh.topology.dim) with XDMFFile(self.comm, self.mesh_boundary, 'r', encoding=encoding) as infile: self.mt_b1 = infile.read_meshtags(self.mesh, name="Grid") except: pass try: self.mesh.topology.create_connectivity(1, self.mesh.topology.dim) with XDMFFile(self.comm, self.mesh_boundary, 'r', encoding=encoding) as infile: self.mt_b2 = infile.read_meshtags(self.mesh, name="Grid_b2") except: pass try: self.mesh.topology.create_connectivity(0, self.mesh.topology.dim) with XDMFFile(self.comm, self.mesh_boundary, 'r', encoding=encoding) as infile: self.mt_b3 = infile.read_meshtags(self.mesh, name="Grid_b3") except: pass elif self.mesh.topology.dim == 2: try: self.mesh.topology.create_connectivity(1, self.mesh.topology.dim) with XDMFFile(self.comm, self.mesh_boundary, 'r', encoding=encoding) as infile: self.mt_b1 = infile.read_meshtags(self.mesh, name="Grid") except: pass try: self.mesh.topology.create_connectivity(0, self.mesh.topology.dim) with XDMFFile(self.comm, self.mesh_boundary, 'r', encoding=encoding) as infile: self.mt_b2 = infile.read_meshtags(self.mesh, name="Grid_b2") except: pass else: raise AttributeError("Your mesh seems to be 1D! Not supported!") # useful fields: # facet normal self.n0 = FacetNormal(self.mesh) # cell diameter self.h0 = CellDiameter(self.mesh)