def test_eval_projection(self): """ Test validity of the local projection-based kernel. Choose u, v in V k(x,y) in VxV (symmetric/non-symm) cell01, cell02 Compare v^T*Kloc*u ?= Icell01 Icell02 k(x,y)u(y)dy dx """ # # 1D # # Mesh mesh = Mesh1D(resolution=(3, )) # Finite element space etype = 'Q1' element = QuadFE(1, etype) # Dofhandler dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() # Basis functions phi = Basis(dofhandler, 'u') # Symmetric kernel function kfns = { 'symmetric': lambda x, y: x * y, 'non_symmetric': lambda x, y: x - y } vals = { 'symmetric': (1 / 2 * 1 / 9 - 1 / 3 * 1 / 27) * (1 / 3 - 1 / 3 * 8 / 27), 'non_symmetric': (1 / 18 - 1 / 3 * 1 / 27) * (1 / 2 - 2 / 9) + (1 / 18 - 1 / 3) * (1 / 3 - 1 / 3 * 8 / 27) } for ktype in ['symmetric', 'non_symmetric']: # Get kernel function kfn = kfns[ktype] # Define integral kernel kernel = Kernel(Explicit(kfn, dim=1, n_variables=2)) # Define Bilinear Form form = IPForm(kernel, trial=phi, test=phi) # # Compute inputs required for evaluating form_loc # # Assembler assembler = Assembler(form, mesh) # Cells ci = mesh.cells.get_child(0) cj = mesh.cells.get_child(2) # Shape function info on cells ci_sinfo = assembler.shape_info(ci) cj_sinfo = assembler.shape_info(cj) # Gauss nodes and weights on cell xi_g, wi_g, phii, dofsi = assembler.shape_eval(ci) xj_g, wj_g, phij, dofsj = assembler.shape_eval(cj) # # Evaluate form # form_loc = form.eval((ci,cj), (xi_g,xj_g), \ (wi_g,wj_g), (phii,phij), (dofsi,dofsj)) # # Define functions # u = Nodal(f=lambda x: x, basis=phi) v = Nodal(f=lambda x: 1 - x, basis=phi) # # Get local node values # # Degrees of freedom ci_dofs = phi.dofs(ci) cj_dofs = phi.dofs(cj) uj = u.data()[np.array(cj_dofs)] vi = v.data()[np.array(ci_dofs)] if ktype == 'symmetric': # Local form by hand c10 = 1 / 54 c11 = 1 / 27 c20 = 3 / 2 - 1 - 3 / 2 * 4 / 9 + 8 / 27 c21 = 4 / 27 fl = np.array([[c10 * c20, c10 * c21], [c11 * c20, c11 * c21]]) # Compare computed and explicit local forms self.assertTrue(np.allclose(fl, form_loc)) # Evaluate Ici Icj k(x,y) y dy (1-x)dx fa = np.dot(vi.T, form_loc.dot(uj)) fe = vals[ktype] self.assertAlmostEqual(fa, fe)
def test_eval_interpolation(self): # # 1D # # Mesh mesh = Mesh1D(resolution=(3, )) # Finite element space etype = 'Q1' element = QuadFE(1, etype) # Dofhandler dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() # Basis functions phi = Basis(dofhandler, 'u') # Symmetric kernel function kfns = { 'symmetric': lambda x, y: x * y, 'non_symmetric': lambda x, y: x - y } vals = { 'symmetric': np.array([0, 1 / 9 * (1 - 8 / 27)]), 'non_symmetric': np.array([1 / 3 * (-1 + 8 / 27), 1 / 6 * 5 / 9 - 1 / 3 * 19 / 27]) } for ktype in ['symmetric', 'non_symmetric']: # Get kernel function kfn = kfns[ktype] # Define integral kernel kernel = Kernel(Explicit(kfn, dim=1, n_variables=2)) # Define Bilinear Form form = IIForm(kernel, trial=phi, test=phi) # # Compute inputs required for evaluating form_loc # # Assembler assembler = Assembler(form, mesh) # Cells cj = mesh.cells.get_child(2) ci = mesh.cells.get_child(0) # Gauss nodes and weights on cell xj_g, wj_g, phij, dofsj = assembler.shape_eval(cj) # # Evaluate form # form_loc = form.eval(cj, xj_g, wj_g, phij, dofsj) # # Define functions # u = Nodal(lambda x: x, basis=phi) # # Get local node values # # Degrees of freedom cj_dofs = phi.dofs(cj) ci_dofs = phi.dofs(ci) uj = u.data()[np.array(cj_dofs)] # Evaluate Ici Icj k(x,y) y dy (1-x)dx fa = form_loc[ci_dofs].dot(uj) fe = vals[ktype][:, None] self.assertTrue(np.allclose(fa, fe))