def sampling_error(): """ Test the sampling error by comparing the accuracy of the quantities of interest q1 = E[|y|] and q2 = E[y(0.5)] """ c = Verbose() mesh = Mesh1D(resolution=(1026,)) mesh.mark_region('left', lambda x:np.abs(x)<1e-10) mesh.mark_region('right', lambda x:np.abs(x-1)<1e-10) element = QuadFE(1,'Q1') dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() dofhandler.set_dof_vertices() phi = Basis(dofhandler,'u') phi_x = Basis(dofhandler,'ux') ns_ref = 10000 z = get_points(n_samples=ns_ref) q = set_diffusion(dofhandler,z) problems = [[Form(q, test=phi_x, trial=phi_x), Form(1, test=phi)], [Form(1, test=phi, trial=phi)]] c.tic('assembling') assembler = Assembler(problems, mesh) assembler.assemble() c.toc() A = assembler.af[0]['bilinear'].get_matrix() b = assembler.af[0]['linear'].get_matrix() M = assembler.af[0]['bilinear'].get_matrix() system = LS(phi) system.add_dirichlet_constraint('left') system.add_dirichlet_constraint('right') c.tic('solving') for n in range(ns_ref): system.set_matrix(A[n]) system.set_rhs(b.copy()) system.solve_system() c.toc()
mesh = Mesh1D(box=[x_min, x_max], resolution=(256, )) # Mark Dirichlet Vertices mesh.mark_region('left', lambda x: np.abs(x) < 1e-9) mesh.mark_region('right', lambda x: np.abs(x - 2) < 1e-9) # # Finite element spaces # Q1 = QuadFE(mesh.dim(), 'Q1') # Dofhandler for state dh = DofHandler(mesh, Q1) dh.distribute_dofs() m = dh.n_dofs() dh.set_dof_vertices() x = dh.get_dof_vertices() # Basis functions phi = Basis(dh, 'v') phi_x = Basis(dh, 'vx') state = LS(phi) state.add_dirichlet_constraint('left', 1) state.add_dirichlet_constraint('right', 0) state.set_constraint_relation() adjoint = LS(phi) adjoint.add_dirichlet_constraint('left', 0) adjoint.add_dirichlet_constraint('right', 0) adjoint.set_constraint_relation()
def test_set_hanging_nodes(self): """ Check that functions in the finite element space can be interpolated by linear combinations of shape functions at supporting nodes. TODO: Move this test to tests for system """ # # Define QuadMesh with hanging node # mesh = QuadMesh(resolution=(1,1)) mesh.cells.refine() mesh.cells.get_child(0).get_child(0).mark(flag=0) mesh.cells.refine(refinement_flag=0) c_00 = mesh.cells.get_child(0).get_child(0) # # Define test functions to interpolate # test_functions = {'Q1': lambda x,y: x + y, \ 'Q2': lambda x,y: x**2 + y**2,\ 'Q3': lambda x,y: x**3*y + y**2*x**2} etypes = ['Q1', 'Q2', 'Q3'] plot = Plot() for etype in etypes: #print(etype) # Define new element element = QuadFE(2,etype) # Distribute dofs and set vertices dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() dofhandler.set_dof_vertices() # Determine hanging nodes dofhandler.set_hanging_nodes() hanging_nodes = dofhandler.get_hanging_nodes() for dof, support in hanging_nodes.items(): # Get hanging node vertex x_hgnd = dofhandler.get_dof_vertices(dof) # Extract support indices and weights js, ws = support # Extract dofs_glb = dofhandler.get_cell_dofs(c_00) #print(dof, js) # Local dof numbers for supporting nodes dofs_loc_supp = [i for i in range(element.n_dofs()) if dofs_glb[i] in js] #x_dofs = c_00.reference_map(element.reference_nodes()) #phi_supp = element.shape(x_hgnd, cell=c_00, local_dofs=dofs_loc_supp) #print(phi_supp, js) # Evaluate test function at hanging node #f_hgnd = test_functions[etype](x_hgnd[0],x_hgnd[1]) #print('Weighted sum of support function', np.dot(phi_supp,ws)) #print(f_hgnd - np.dot(phi_supp, ws)) #phi_hgnd = element.shape(x_dofs, cell=c_00, local_dofs=dofs_loc_hgnd) #print(phi_supp) #print(phi_hgnd) #plot.mesh(mesh, dofhandler=dofhandler, dofs=True) # Evaluate c_01 = mesh.cells.get_child(0).get_child(1) c_022 = mesh.cells.get_child(0).get_child(2).get_child(2) #print(dofhandler.get_global_dofs(c_022)) x_ref = element.reference_nodes() #print(dofhandler.get_global_dofs(c_01)) #print(dofhandler.get_hanging_nodes()) x = c_01.reference_map(x_ref)
def test_set_data(self): meshes = {1: Mesh1D(), 2: QuadMesh()} elements = {1: QuadFE(1, 'Q2'), 2: QuadFE(2, 'Q2')} # # Use function to set data # fns = { 1: { 1: lambda x: 2 * x[:, 0]**2, 2: lambda x, y: 2 * x[:, 0] + 2 * y[:, 0] }, 2: { 1: lambda x: x[:, 0]**2 + x[:, 1], 2: lambda x, y: x[:, 0] * y[:, 0] + x[:, 1] * y[:, 1] } } parms = {1: {1: [{}, {}], 2: [{}, {}]}, 2: {1: [{}, {}], 2: [{}, {}]}} for dim in [1, 2]: # Get mesh and element mesh = meshes[dim] element = elements[dim] # Set dofhandler dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() n_dofs = dofhandler.n_dofs() # Set basis basis = Basis(dofhandler) # Determine the shapes of the data det_shapes = {1: (n_dofs, 1), 2: (n_dofs, n_dofs, 1)} smp_shapes = {1: (n_dofs, 2), 2: (n_dofs, n_dofs, 2)} # Get a vertex i = np.random.randint(n_dofs) j = np.random.randint(n_dofs) dofhandler.set_dof_vertices() x = dofhandler.get_dof_vertices() x1 = np.array([x[i, :]]) x2 = np.array([x[j, :]]) for n_variables in [1, 2]: fn = fns[dim][n_variables] parm = parms[dim][n_variables] # # Deterministic # f = Nodal(f=fn, basis=basis, n_variables=n_variables) # Check shape self.assertEqual(f.data().shape, det_shapes[n_variables]) # Check value if n_variables == 1: val = fn(x1)[0] self.assertEqual(val, f.data()[i]) else: val = fn(x1, x2) self.assertEqual(val[0], f.data()[i, j]) # # Sampled # f = Nodal(f=fn, parameters=parm, basis=basis, n_variables=n_variables) # Check shape self.assertEqual(f.data().shape, smp_shapes[n_variables]) # Check that samples are stored in the right place if n_variables == 1: self.assertTrue(np.allclose(f.data()[:, 0], f.data()[:, 1])) elif n_variables == 2: self.assertTrue( np.allclose(f.data()[:, :, 0], f.data()[:, :, 1]))
def test_constructor(self): # ===================================================================== # Test 1D # ===================================================================== # # Kernel consists of a single explicit Function: # f1 = lambda x: x+2 f = Explicit(f1, dim=1) k = Kernel(f) x = np.linspace(0,1,100) n_points = len(x) # Check that it evaluates correctly. self.assertTrue(np.allclose(f1(x), k.eval(x).ravel())) # Check shape of kernel self.assertEqual(k.eval(x).shape, (n_points,1)) # # Kernel consists of a combination of two explicit functions # f1 = Explicit(lambda x: x+2, dim=1) f2 = Explicit(lambda x: x**2 + 1, dim=1) F = lambda f1, f2: f1**2 + f2 f_t = lambda x: (x+2)**2 + x**2 + 1 k = Kernel([f1,f2], F=F) # Check evaluation self.assertTrue(np.allclose(f_t(x), k.eval(x).ravel())) # Check shape self.assertEqual(k.eval(x).shape, (n_points,1)) # # Same thing as above, but with nodal functions # mesh = Mesh1D(resolution=(1,)) Q1 = QuadFE(1,'Q1') Q2 = QuadFE(1,'Q2') dQ1 = DofHandler(mesh,Q1) dQ2 = DofHandler(mesh,Q2) # Distribute dofs [dQ.distribute_dofs() for dQ in [dQ1,dQ2]] # Basis functions phi1 = Basis(dQ1,'u') phi2 = Basis(dQ2,'u') f1 = Nodal(lambda x: x+2, basis=phi1) f2 = Nodal(lambda x: x**2 + 1, basis=phi2) k = Kernel([f1,f2], F=F) # Check evaluation self.assertTrue(np.allclose(f_t(x), k.eval(x).ravel())) # # Replace f2 above with its derivative # k = Kernel([f1,f2], derivatives=['f', 'fx'], F=F) f_t = lambda x: (x+2)**2 + 2*x # Check derivative evaluation F = F(f1, df2_dx) self.assertTrue(np.allclose(f_t(x), k.eval(x).ravel())) # # Sampling # one = Constant(1) f1 = Explicit(lambda x: x**2 + 1, dim=1) # Sampled function a = np.linspace(0,1,11) n_samples = len(a) # Define Dofhandler dh = DofHandler(mesh, Q2) dh.distribute_dofs() dh.set_dof_vertices() xv = dh.get_dof_vertices() n_dofs = dh.n_dofs() phi = Basis(dh, 'u') # Evaluate parameterized function at mesh dof vertices f2_m = np.empty((n_dofs, n_samples)) for i in range(n_samples): f2_m[:,i] = xv.ravel() + a[i]*xv.ravel()**2 f2 = Nodal(data=f2_m, basis=phi) # Define kernel F = lambda f1, f2, one: f1 + f2 + one k = Kernel([f1,f2,one], F=F) # Evaluate on a fine mesh x = np.linspace(0,1,100) n_points = len(x) self.assertEqual(k.eval(x).shape, (n_points, n_samples)) for i in range(n_samples): # Check evaluation self.assertTrue(np.allclose(k.eval(x)[:,i], f1.eval(x)[:,i] + x + a[i]*x**2+ 1)) # # Sample multiple constant functions # f1 = Constant(data=a) f2 = Explicit(lambda x: 1 + x**2, dim=1) f3 = Nodal(data=f2_m[:,-1], basis=phi) F = lambda f1, f2, f3: f1 + f2 + f3 k = Kernel([f1,f2,f3], F=F) x = np.linspace(0,1,100) for i in range(n_samples): self.assertTrue(np.allclose(k.eval(x)[:,i], \ a[i] + f2.eval(x)[:,i] + f3.eval(x)[:,i])) # # Submeshes # mesh = Mesh1D(resolution=(1,)) mesh_labels = Tree(regular=False) mesh = Mesh1D(resolution=(1,)) Q1 = QuadFE(1,'Q1') Q2 = QuadFE(1,'Q2') dQ1 = DofHandler(mesh,Q1) dQ2 = DofHandler(mesh,Q2) # Distribute dofs [dQ.distribute_dofs() for dQ in [dQ1,dQ2]] # Basis p1 = Basis(dQ1) p2 = Basis(dQ2) f1 = Nodal(lambda x: x, basis=p1) f2 = Nodal(lambda x: -2+2*x**2, basis=p2) one = Constant(np.array([1,2])) F = lambda f1, f2, one: 2*f1**2 + f2 + one I = mesh.cells.get_child(0) kernel = Kernel([f1,f2, one], F=F) rule1D = GaussRule(5,shape='interval') x = I.reference_map(rule1D.nodes())
flag = tuple(mtags.get_node_address()) mesh.cells.record(flag) mtags.add_child() new_flag = tuple(mtags.get_child(0).get_node_address()) mesh.cells.refine(subforest_flag=flag, \ new_label=new_flag) for leaf in mesh.cells.get_leaves(subforest_flag=flag): leaf.info() print('==' * 20) for leaf in mesh.cells.get_leaves(subforest_flag=new_flag): leaf.info() element = QuadFE(1, 'Q2') dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() dofhandler.set_dof_vertices() dofs = dofhandler.get_global_dofs(subforest_flag=flag) print(dofs) dofs = dofhandler.get_global_dofs(subforest_flag=new_flag) print(dofs) dv = dofhandler.get_dof_vertices(dofs) print(dv)
def test_eval(self): # # Out of the box covariance kernels # fig, ax = plt.subplots(6, 4, figsize=(5, 7)) cov_names = [ 'constant', 'linear', 'gaussian', 'exponential', 'matern', 'rational' ] anisotropies = {1: [None, 2], 2: [None, np.diag([2, 1])]} m_count = 0 for mesh in [Mesh1D(resolution=(10, )), QuadMesh(resolution=(10, 10))]: # Dimension dim = mesh.dim() # # Construct computational mesh # # Piecewise constant elements element = QuadFE(dim, 'DQ0') # Define dofhandler -> get vertices dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() dofhandler.set_dof_vertices() v = dofhandler.get_dof_vertices() # Define meshgrid for 1 and 2 dimensions n_dofs = dofhandler.n_dofs() M1, M2 = np.mgrid[0:n_dofs, 0:n_dofs] if dim == 1: X = v[:, 0][M1].ravel() Y = v[:, 0][M2].ravel() elif dim == 2: X = np.array([v[:, 0][M1].ravel(), v[:, 1][M1].ravel()]).T Y = np.array([v[:, 0][M2].ravel(), v[:, 1][M2].ravel()]).T x = convert_to_array(X, dim=dim) y = convert_to_array(Y, dim=dim) a_count = 0 isotropic_label = ['isotropic', 'anisotropic'] for M in anisotropies[dim]: # Cycle through anisotropies # Define covariance parameters cov_pars = { 'constant': { 'sgm': 1 }, 'linear': { 'sgm': 1, 'M': M }, 'gaussian': { 'sgm': 1, 'l': 0.1, 'M': M }, 'exponential': { 'l': 0.1, 'M': M }, 'matern': { 'sgm': 1, 'nu': 2, 'l': 0.5, 'M': M }, 'rational': { 'a': 3, 'M': M } } c_count = 0 for cov_name in cov_names: C = CovKernel(cov_name, cov_pars[cov_name]) Z = C.eval((x, y)).reshape(M1.shape) col = int(m_count * 2**1 + a_count * 2**0) row = c_count ax[row, col].imshow(Z) if col == 0: ax[row, col].set_ylabel(cov_name) if row == 0: ax[row, col].set_title('%dD mesh\n %s' % (dim, isotropic_label[a_count])) ax[row, col].set_xticks([], []) ax[row, col].set_yticks([], []) c_count += 1 a_count += 1 m_count += 1 fig.savefig('test_covkernel_eval.eps')