def test_constructor(self): """ Test initialization """ # Initialize empty map f = Map() self.assertTrue(isinstance(f, Map)) self.assertIsNone(f.dim()) # # Exceptions # mesh = Mesh1D() # Mesh dimension incompatible with element element = QuadFE(2, 'DQ1') #self.assertRaises(Exception, Map, **{'mesh':mesh, 'element':element}) # Dofhandler incompatibility element = QuadFE(1, 'Q1') dofhandler = DofHandler(mesh, element) #self.assertRaises(Exception, Map, **{'dofhandler': dofhandler, # 'dim':2}) # function returns the same mesh f1 = Map(dofhandler=dofhandler) f2 = Map(mesh=mesh) self.assertEqual(f1.mesh(), f2.mesh())
def test_polynomial_degree(self): count = 1 for etype in ['Q1', 'Q2', 'Q3']: element = QuadFE(2, etype) n = element.polynomial_degree() self.assertEqual(n, count,\ 'Incorrect polynomial degree %d for element %s'%(n,etype) ) count += 1
def test_phi(self): for etype in ['DQ0', 'Q1', 'Q2', 'Q3']: element = QuadFE(2, etype) n_dofs = element.n_dofs() I = np.eye(n_dofs) x = element.reference_nodes() for n in range(n_dofs): self.assertTrue(np.allclose(element.phi(n,x),I[:,n]),\ 'Shape function evaluation incorrect')
def test_n_samples(self): # # Sampled Case # 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] } } # n_samples = 2 parms = {1: {1: [{}, {}], 2: [{}, {}]}, 2: {1: [{}, {}], 2: [{}, {}]}} for dim in [1, 2]: mesh = meshes[dim] element = elements[dim] dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() basis = Basis(dofhandler) for n_variables in [1, 2]: fn = fns[dim][n_variables] parm = parms[dim][n_variables] # # Deterministic # f = Nodal(f=fn, mesh=mesh, basis=basis, element=element, dim=dim, n_variables=n_variables) self.assertEqual(f.n_samples(), 1) # # Sampled # f = Nodal(f=fn, parameters=parm, basis=basis, mesh=mesh, element=element, dim=dim, n_variables=n_variables) self.assertEqual(f.n_samples(), 2)
def experiment01(): """ Compute the quantity of interest, it's expectation and variance """ # # FE Discretization # # Computational mesh mesh = Mesh1D(resolution=(64, )) # Element element = QuadFE(mesh.dim(), 'DQ0') dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() # Linear Functional mesh.mark_region('integrate', lambda x: x > 0.75, entity_type='cell', strict_containment=False) phi = Basis(dofhandler) assembler = Assembler(Form(1, test=phi, flag='integrate')) assembler.assemble() L = assembler.get_vector()
def test03(): """ Constant Anisotropy """ print('Test 3:') # Mesh mesh = Mesh.newmesh([0, 20, 0, 20], grid_size=(40, 40)) mesh.refine() element = QuadFE(2, 'Q1') system = System(mesh, element) gma = 1 bta = 8 tht = np.pi / 4 v = np.array([np.cos(tht), np.sin(tht)]) H = gma * np.eye(2, 2) + bta * np.outer(v, v) Z = 10 * np.random.normal(size=system.n_dofs()) # Bilinear forms bf = [(1,'u','v'), \ (H[0,0],'ux','vx'), (H[0,1],'uy','vx'),\ (H[1,0],'ux','vy'), (H[1,1],'uy','vy')] A = system.assemble(bilinear_forms=bf, linear_forms=None) M = system.assemble(bilinear_forms=[(1, 'u', 'v')]) m_lumped = np.array(M.sum(axis=1)).squeeze() X = spla.spsolve(A.tocsc(), np.sqrt(m_lumped) * Z) fig, ax = plt.subplots() plot = Plot() ax = plot.contour(ax, fig, X, mesh, element, resolution=(200, 200)) plt.show()
def test02(): """ Spatially varying anisotropy """ print('Test 2:') grid = Grid(box=[0, 20, 0, 20], resolution=(100, 100)) mesh = Mesh(grid=grid) element = QuadFE(2, 'Q1') system = System(mesh, element) alph = 2 kppa = 1 # Symmetric tensor gma T + bta* vv^T gma = 0.1 bta = 25 v2 = lambda x, y: -0.75 * np.cos(np.pi * x / 10) v1 = lambda x, y: 0.25 * np.sin(np.pi * y / 10) h11 = lambda x, y: gma + v1(x, y) * v1(x, y) h12 = lambda x, y: v1(x, y) * v2(x, y) h22 = lambda x, y: v2(x, y) * v2(x, y) X = Gmrf.from_matern_pde(alph, kppa, mesh, element, tau=(h11, h12, h22)) x = X.sample(1).ravel() fig, ax = plt.subplots() plot = Plot() ax = plot.contour(ax, fig, x, mesh, element, resolution=(200, 200)) plt.show()
def test_same_dofs(self): # # Construct nested mesh # mesh = QuadMesh() mesh.record(0) for dummy in range(2): mesh.cells.refine() # # Define dofhandler # element = QuadFE(mesh.dim(), 'Q1') dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() # # Define basis functions # phi0 = Basis(dofhandler, 'u', subforest_flag=0) phi0_x = Basis(dofhandler, 'ux', subforest_flag=0) phi1 = Basis(dofhandler, 'u') self.assertTrue(phi0.same_mesh(phi0_x)) self.assertFalse(phi0.same_mesh(phi1))
def test_assemble_iiform(self): mesh = Mesh1D(resolution=(1, )) Q1 = QuadFE(1, 'DQ1') dofhandler = DofHandler(mesh, Q1) dofhandler.distribute_dofs() phi = Basis(dofhandler, 'u') k = Explicit(lambda x, y: x * y, n_variables=2, dim=1) kernel = Kernel(k) form = IIForm(kernel, test=phi, trial=phi) assembler = Assembler(form, mesh) assembler.assemble() Ku = Nodal(lambda x: 1 / 3 * x, basis=phi) #af = assembler.af[0]['bilinear'] M = assembler.get_matrix().toarray() u = Nodal(lambda x: x, basis=phi) u_vec = u.data() self.assertTrue(np.allclose(M.dot(u_vec), Ku.data()))
def test_assemble_ipform(self): # ===================================================================== # Test 7: Assemble Kernel # ===================================================================== mesh = Mesh1D(resolution=(10, )) Q1 = QuadFE(1, 'DQ1') dofhandler = DofHandler(mesh, Q1) dofhandler.distribute_dofs() phi = Basis(dofhandler, 'u') k = Explicit(lambda x, y: x * y, n_variables=2, dim=1) kernel = Kernel(k) form = IPForm(kernel, test=phi, trial=phi) assembler = Assembler(form, mesh) assembler.assemble() #af = assembler.af[0]['bilinear'] M = assembler.get_matrix().toarray() u = Nodal(lambda x: x, basis=phi) v = Nodal(lambda x: 1 - x, basis=phi) u_vec = u.data() v_vec = v.data() I = v_vec.T.dot(M.dot(u_vec)) self.assertAlmostEqual(I[0, 0], 1 / 18)
def test_constructor(self): # # Define mesh, element, and dofhandler # mesh = QuadMesh(box=[0, 20, 0, 20], resolution=(20, 20), periodic={0, 1}) dim = mesh.dim() element = QuadFE(dim, 'Q2') dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() basis = Basis(dofhandler, 'u') alph = 2 kppa = 1 # Symmetric tensor gma T + bta* vv^T gma = 0.1 bta = 25 p = lambda x: 10/np.pi*(0.75*np.sin(np.pi*x[:,0]/10)+\ 0.25*np.sin(np.pi*x[:,1]/10)) f = Nodal(f=p, basis=basis) fx = f.differentiate((1, 0)) fy = f.differentiate((1, 1)) #plot.contour(f) x = np.linspace(0, 20, 12) X, Y = np.meshgrid(x, x) xy = np.array([X.ravel(), Y.ravel()]).T U = fx.eval(xy).reshape(X.shape) V = fy.eval(xy).reshape(X.shape) v1 = lambda x: -0.25 * np.cos(np.pi * x[:, 1] / 10) v2 = lambda x: 0.75 * np.cos(np.pi * x[:, 0] / 10) U = v1(xy).reshape(X.shape) V = v2(xy).reshape(X.shape) #plt.quiver(X,Y, U, V) #plt.show() h11 = Explicit(lambda x: gma + bta * v1(x) * v1(x), dim=2) h12 = Explicit(lambda x: bta * v1(x) * v2(x), dim=2) h22 = Explicit(lambda x: gma + bta * v2(x) * v2(x), dim=2) tau = (h11, h12, h22) #tau = (Constant(2), Constant(1), Constant(1)) # # Define default elliptic field # u = EllipticField(dofhandler, kappa=1, tau=tau, gamma=2) Q = u.precision() v = Nodal(data=u.sample(mode='precision', decomposition='chol'), basis=basis) plot = Plot(20) plot.contour(v)
def test03_dJdq(): """ Compute dJdq for a simple problem, check that it works """ # # Mesh # mesh = Mesh1D(resolution=(20, )) mesh.mark_region('left', lambda x: np.abs(x) < 1e-10) mesh.mark_region('right', lambda x: np.abs(x - 1) < 1e-10) # # Element # Q = QuadFE(mesh.dim(), 'Q3') dh = DofHandler(mesh, Q) dh.distribute_dofs() nx = dh.n_dofs() x = dh.get_dof_vertices() # # Basis # phi = Basis(dh, 'v') phi_x = Basis(dh, 'vx') # # Parameters # # Reference q q_ref = Nodal(data=np.zeros(nx), basis=phi) # Perturbation dq = Nodal(data=np.ones(nx), basis=phi) # # Sample Reference QoI # J, u_ref = sample_qoi(q_ref.data(), dh, return_state=True) u_ref = Nodal(data=u_ref, basis=phi) # # Compute dJdq # # Perturbation method Jp_per = dJdq_per(q_ref, dq, dh) # Sensitivity method Jp_sen = dJdq_sen(q_ref, u_ref, dq) # Adjoint method Jp_adj = dJdq_adj(q_ref, u_ref, dq) # Check that the answers are close to -1 assert np.allclose(Jp_per, -1) assert np.allclose(Jp_sen, -1) assert np.allclose(Jp_adj, -1)
def test_set(self): mesh = QuadMesh(resolution=(1, 1)) element = QuadFE(2, 'Q1') dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() px = Basis(dofhandler, 'ux') p = Basis(dofhandler, 'ux') self.assertNotEqual(px, p)
def test_n_dofs(self): """ Check that the total number of dofs is correct NOTE: A mesh with multiple levels has dofs on coarser levels that may not appear in leaves """ etypes = ['DQ0', 'DQ1', 'DQ2', 'DQ3', 'Q1', 'Q2', 'Q3'] # # Single cell # n_dofs = dict.fromkeys([0,1]) n_dofs[0] = {'DQ0': 1, 'DQ1': 2, 'DQ2': 3, 'DQ3': 4, 'Q1': 2, 'Q2': 3, 'Q3': 4} n_dofs[1] = {'DQ0': 1, 'DQ1': 4, 'DQ2': 9, 'DQ3': 16, 'Q1': 4, 'Q2': 9, 'Q3':16} for dim in range(2): if dim==0: mesh = Mesh1D() elif dim==1: mesh = QuadMesh() for etype in etypes: element = QuadFE(dim+1, etype) dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() self.assertEqual(n_dofs[dim][etype], dofhandler.n_dofs()) # # Mesh with multiple cells # n_dofs = dict.fromkeys([0,1]) n_dofs[0] = {'DQ0': 2, 'DQ1': 4, 'DQ2': 6, 'DQ3': 8, 'Q1': 3, 'Q2': 5, 'Q3': 7} n_dofs[1] = {'DQ0': 4, 'DQ1': 16, 'DQ2': 36, 'DQ3': 64, 'Q1': 9, 'Q2': 25, 'Q3': 49} for dim in range(2): if dim==0: mesh = Mesh1D(resolution=(2,)) elif dim==1: mesh = QuadMesh(resolution=(2,2)) for etype in etypes: element = QuadFE(dim+1, etype) dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() self.assertEqual(n_dofs[dim][etype], dofhandler.n_dofs())
def test02_1d_dirichlet_higher_order(self): mesh = Mesh1D() for etype in ['Q2', 'Q3']: element = QuadFE(1, etype) dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() # Basis functions ux = Basis(dofhandler, 'ux') u = Basis(dofhandler, 'u') # Exact solution ue = Nodal(f=lambda x: x * (1 - x), basis=u) # Define coefficient functions one = Constant(1) two = Constant(2) # Define forms a = Form(kernel=Kernel(one), trial=ux, test=ux) L = Form(kernel=Kernel(two), test=u) problem = [a, L] # Assemble problem assembler = Assembler(problem, mesh) assembler.assemble() A = assembler.get_matrix() b = assembler.get_vector() # Set up linear system system = LinearSystem(u, A=A, b=b) # Boundary functions bnd_left = lambda x: np.abs(x) < 1e-9 bnd_right = lambda x: np.abs(1 - x) < 1e-9 # Mark mesh mesh.mark_region('left', bnd_left, entity_type='vertex') mesh.mark_region('right', bnd_right, entity_type='vertex') # Add Dirichlet constraints to system system.add_dirichlet_constraint('left', 0) system.add_dirichlet_constraint('right', 0) # Solve system system.solve_system() system.resolve_constraints() # Compare solution with the exact solution ua = system.get_solution(as_function=True) self.assertTrue(np.allclose(ua.data(), ue.data()))
def test02a_sensitivity_gradient(): """ Test whether the sensitivity and adjoint calculations give the same gradient """ # Mesh mesh = Mesh1D(resolution=(100, )) mesh.mark_region('left', lambda x: np.abs(x) < 1e-10) mesh.mark_region('right', lambda x: np.abs(1 - x) < 1e-10) # Element Q = QuadFE(mesh.dim(), 'Q2') dh = DofHandler(mesh, Q) dh.distribute_dofs() n_dofs = dh.n_dofs() phi = Basis(dh, 'u') # Covariance cov = Covariance(dh, name='gaussian', parameters={'l': 0.05}) cov.compute_eig_decomp() lmd, V = cov.get_eig_decomp() d = len(lmd) # Coarse field (single sample) d0 = 2 z0 = np.random.randn(d0, 1) q0 = sample_q0(V, lmd, d0, z0) q0_fn = Nodal(data=q0, basis=phi) # State J0, u0 = sample_qoi(q0, dh, return_state=True) u0_fn = Nodal(data=u0, basis=phi) # Compute gradient using sensitivity dJs = np.zeros(n_dofs) for i in range(n_dofs): # Define perturbation dq = np.zeros(n_dofs) dq[i] = 1 dq_fn = Nodal(data=dq, basis=phi) # Compute gradient using sensitivity dJs[i] = dJdq_sen(q0_fn, u0_fn, dq_fn) dJs_fn = Nodal(data=dJs, basis=phi) plot = Plot() plot.line(dJs_fn) # Compute gradient using adjoint method dJa = dJdq_adj(q0_fn, u0_fn) dJa_fn = Nodal(data=dJa, basis=phi) print(dJa) plot.line(dJa_fn)
def test01_solve_2d(self): """ Solve a simple 2D problem with no hanging nodes """ mesh = QuadMesh(resolution=(5, 5)) # Mark dirichlet boundaries mesh.mark_region('left', lambda x, dummy: np.abs(x) < 1e-9, entity_type='half_edge') mesh.mark_region('right', lambda x, dummy: np.abs(x - 1) < 1e-9, entity_type='half_edge') Q1 = QuadFE(mesh.dim(), 'Q1') dQ1 = DofHandler(mesh, Q1) dQ1.distribute_dofs() phi = Basis(dQ1, 'u') phi_x = Basis(dQ1, 'ux') phi_y = Basis(dQ1, 'uy') problem = [ Form(1, test=phi_x, trial=phi_x), Form(1, test=phi_y, trial=phi_y), Form(0, test=phi) ] assembler = Assembler(problem, mesh) assembler.add_dirichlet('left', dir_fn=0) assembler.add_dirichlet('right', dir_fn=1) assembler.assemble() # Get matrix dirichlet correction and right hand side A = assembler.get_matrix().toarray() x0 = assembler.assembled_bnd() b = assembler.get_vector() ua = np.zeros((phi.n_dofs(), 1)) int_dofs = assembler.get_dofs('interior') ua[int_dofs, 0] = np.linalg.solve(A, b - x0) dir_bc = assembler.get_dirichlet() dir_vals = np.array([dir_bc[dof] for dof in dir_bc]) dir_dofs = [dof for dof in dir_bc] ua[dir_dofs] = dir_vals ue_fn = Nodal(f=lambda x: x[:, 0], basis=phi) ue = ue_fn.data() self.assertTrue(np.allclose(ue, ua)) self.assertTrue(np.allclose(x0 + A.dot(ua[int_dofs, 0]), b))
def test_timings(self): """ """ comment = Verbose() mesh = QuadMesh() element = QuadFE(2,'Q1') dofhandler = DofHandler(mesh, element) for dummy in range(7): mesh.cells.refine() comment.tic() dofhandler.distribute_dofs() comment.toc() print(dofhandler.n_dofs())
def test_clear_dofs(self): # Define new dofhandler mesh = Mesh2D(resolution=(1,1)) cell = mesh.cells.get_child(0) element = QuadFE(2, 'Q2') dofhandler = DofHandler(mesh, element) # Fill dofs dofhandler.fill_dofs(cell) # Clear dofs dofhandler.clear_dofs() # Check that there are no dofs self.assertIsNone(dofhandler.get_cell_dofs(cell))
def test01(): """ Condition on coarse realization """ print('Test 1:') grid = Grid(box=[0, 20, 0, 20], resolution=(10, 10)) mesh = Mesh.newmesh(grid=grid) mesh.record(flag=0) for _ in range(3): mesh.refine() mesh.record(flag=1) element = QuadFE(2, 'Q1') system = System(mesh, element, nested=True) #system = System(mesh, element) gma = 1 bta = 8 tht = np.pi / 4 v = np.array([np.cos(tht), np.sin(tht)]) H = gma * np.eye(2, 2) + bta * np.outer(v, v) Z = 10 * np.random.normal(size=system.n_dofs()) # Bilinear forms bf = [(1,'u','v'), \ (H[0,0],'ux','vx'), (H[0,1],'uy','vx'),\ (H[1,0],'ux','vy'), (H[1,1],'uy','vy')] print('assembly') A = system.assemble(bilinear_forms=bf, linear_forms=None) M = system.assemble(bilinear_forms=[(1, 'u', 'v')]) m_lumped = np.array(M.sum(axis=1)).squeeze() print('generating realizations') X = spla.spsolve(A.tocsc(), np.sqrt(m_lumped) * Z) fX = Function(X, 'nodal', mesh, element, flag=1) R01 = system.restrict(0, 1) Xr = Function(R01.dot(X), 'nodal', mesh, element, flag=0) print('plotting') plot = Plot() fig, ax = plt.subplots(2, 2) ax[0][0] = plot.mesh(ax[0][0], mesh, element, node_flag=0) ax[0][1] = plot.mesh(ax[0][1], mesh, element, node_flag=1) ax[1][0] = plot.contour(ax[1][0], fig, Xr, mesh, element, flag=0) ax[1][1] = plot.contour(ax[1][1], fig, fX, mesh, element, flag=1) plt.show()
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()
def test_edge_integrals(self): """ Test computing """ mesh = QuadMesh(resolution=(1, 1)) Q = QuadFE(2, 'Q1') dQ = DofHandler(mesh, Q) dQ.distribute_dofs() phi = Basis(dQ, 'u') f = Nodal(data=np.ones((phi.n_dofs(), 1)), basis=phi) kernel = Kernel(f) form = Form(kernel, dmu='ds') assembler = Assembler(form, mesh) cell = mesh.cells.get_leaves()[0] shape_info = assembler.shape_info(cell) xg, wg, phi, dofs = assembler.shape_eval(cell)
def test02_variance(): """ Compute the variance of J(q) for different mesh refinement levels and compare with MC estimates. """ l_max = 8 for i_res in np.arange(2, l_max): # Computational mesh mesh = Mesh1D(resolution=(2**i_res, )) # Element element = QuadFE(mesh.dim(), 'DQ0') dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() # Linear Functional mesh.mark_region('integrate', lambda x: x >= 0.75, entity_type='cell', strict_containment=False) phi = Basis(dofhandler) assembler = Assembler(Form(4, test=phi, flag='integrate')) assembler.assemble() L = assembler.get_vector() # Define Gaussian random field C = Covariance(dofhandler, name='gaussian', parameters={'l': 0.05}) C.compute_eig_decomp() eta = GaussianField(dofhandler.n_dofs(), K=C) eta.update_support() n_samples = 100000 J_paths = L.dot(eta.sample(n_samples=n_samples)) var_mc = np.var(J_paths) lmd, V = C.get_eig_decomp() LV = L.dot(V) var_an = LV.dot(np.diag(lmd).dot(LV.transpose())) print(var_mc, var_an)
def test_distribute_dofs(self): show_plots = False if show_plots: plot = Plot() # # Define QuadMesh with hanging node # mesh = QuadMesh(resolution=(1,1), periodic={0,1}) mesh.cells.refine() mesh.cells.get_child(0).get_child(0).mark(flag=0) mesh.cells.refine(refinement_flag=0) etypes = ['DQ0','DQ1', 'DQ2', 'DQ3', 'Q1', 'Q2', 'Q3'] for etype in etypes: # Define new element element = QuadFE(2,etype) # Distribute dofs dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() plot.mesh(mesh, dofhandler=dofhandler, dofs=True)
def test01_solve_1d(self): """ Test solving 1D systems """ mesh = Mesh1D(resolution=(20, )) mesh.mark_region('left', lambda x: np.abs(x) < 1e-9) mesh.mark_region('right', lambda x: np.abs(x - 1) < 1e-9) Q1 = QuadFE(1, 'Q1') dQ1 = DofHandler(mesh, Q1) dQ1.distribute_dofs() phi = Basis(dQ1, 'u') phi_x = Basis(dQ1, 'ux') problem = [Form(1, test=phi_x, trial=phi_x), Form(0, test=phi)] assembler = Assembler(problem, mesh) assembler.add_dirichlet('left', dir_fn=0) assembler.add_dirichlet('right', dir_fn=1) assembler.assemble() # Get matrix dirichlet correction and right hand side A = assembler.get_matrix().toarray() x0 = assembler.assembled_bnd() b = assembler.get_vector() ua = np.zeros((phi.n_dofs(), 1)) int_dofs = assembler.get_dofs('interior') ua[int_dofs, 0] = np.linalg.solve(A, b - x0) dir_bc = assembler.get_dirichlet() dir_vals = np.array([dir_bc[dof] for dof in dir_bc]) dir_dofs = [dof for dof in dir_bc] ua[dir_dofs] = dir_vals ue_fn = Nodal(f=lambda x: x[:, 0], basis=phi) ue = ue_fn.data() self.assertTrue(np.allclose(ue, ua)) self.assertTrue(np.allclose(x0 + A.dot(ua[int_dofs, 0]), b))
def example_2(): """ Oden et al """ u = lambda x, y: 5 * x**2 * (1 - x)**2 * (e(10 * x**2) - 1) * y**2 * ( 1 - y)**2 * (e(10 * y**2) - 1) f = lambda x,y: 10*((e(10*x**2)-1)*(x-1)**2*x**2* (e(10*y**2)-1)*(y-1)**2\ + (e(10*x**2)-1)*(x-1)**2*x**2*(e(10*y**2)-1)*y**2\ + 50*(e(10*x**2)-1)*(x-1)**2*x**2*e(10*y**2)*(y-1)**2*y**2 + 50*e(10*x**2)*(x-1)**2*x**2*(e(10*y**2)-1)*(y-1)**2*y**2\ + (e(10*x**2)-1)*x**2*(e(10*y**2)-1)*(y-1)**2*y**2\ + 4*(e(10*x**2)-1)*(x-1)**2*x**2*(e(10*y**2)-1)*(y-1)*y\ + 4*(e(10*x**2)-1)*(x-1)*x*(e(10*y**2)-1)*(y-1)**2*y**2\ + (e(10*x**2)-1)*(x-1)**2*(e(10*y**2)-1)*(y-1)**2*y**2\ + 200*(e(10*x**2)-1)*(x-1)**2*x**2*e(10*y**2)*(y-1)**2*y**4\ + 40*(e(10*x**2)-1)*(x-1)**2*x**2*e(10*y**2)*(y-1)*y**3\ + 200*e(10*x**2)*(x-1)**2*x**4*(e(10*y**2)-1)*(y-1)**2*y**2\ + 40*e(10*x**2)*(x-1)*x**3*(e(10*y**2)-1)*(y-1)**2*y**2) mesh = Mesh.newmesh(grid_size=(30, 30)) mesh.refine() element = QuadFE(2, 'Q2') system = System(mesh, element) linear_forms = [(f, 'v')] bilinear_forms = [(1, 'ux', 'vx')] dir_bnd = lambda x, y: np.abs(y) < 1e-10 dir_fun = u boundary_conditions = { 'dirichlet': [(dir_bnd, dir_fun)], 'neumann': None, 'robin': None } A, b = system.assemble(bilinear_forms, linear_forms, boundary_conditions) #A,b = system.extract_hanging_nodes(A, b, compress=True) ua = spla.spsolve(A.tocsc(), b) x = system.dof_vertices() ue = u(x[:, 0], x[:, 1])
def test_get_local_dofs(self): """ Extract local dofs from a corner vertex, halfEdge or cell """ local_dofs = {1: {'DQ0': [[0], [], [0]], 'DQ1': [[0,1], [1], []], 'DQ2': [[0,1,2], [1], [2]], 'DQ3': [[0,1,2,3], [1], [2,3]] }, 2: {'DQ0': [[0], [], [], [0]], 'DQ1': [[0,1,2,3], [1], [], []], 'DQ2': [[0,1,2,3,4,5,6,7,8], [1], [6], [8]], 'DQ3': [[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], [1], [8,9], [12,13,14,15]] } } etypes = ['DQ' + i for i in '0123'] for dim in range(1,3): if dim==1: mesh = Mesh1D(box=[2,4], resolution=(1,)) cell = mesh.cells.get_child(0) vertex = cell.get_vertex(1) entities = [None, vertex, cell] elif dim==2: mesh = QuadMesh(box = [0,2,0,2], resolution=(2,2)) cell = mesh.cells.get_child(1) vertex = cell.get_vertex(1) half_edge = cell.get_half_edge(2) entities = [None, vertex, half_edge, cell] for etype in etypes: element = QuadFE(dim, etype) dofhandler = DofHandler(mesh, element) for i_entity in range(len(entities)): entity = entities[i_entity] dofs = dofhandler.get_cell_dofs(cell, entity=entity, doftype='local', interior=True) self.assertEqual(local_dofs[dim][etype][i_entity], dofs)
def test_constructor(self): # # Errors # # Nothing specified self.assertRaises(Exception, Nodal) # Nominal case mesh = QuadMesh() element = QuadFE(2, 'Q1') dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() basis = Basis(dofhandler) data = np.arange(0, 4) f = Nodal(data=data, basis=basis, mesh=mesh, element=element) self.assertEqual(f.dim(), 2) self.assertTrue(np.allclose(f.data().ravel(), data)) # Now change the data -> Error false_data = np.arange(0, 6) self.assertRaises( Exception, Nodal, **{ 'data': false_data, 'mesh': mesh, 'element': element }) # Now omit mesh or element kwargs = {'data': data, 'mesh': mesh} self.assertRaises(Exception, Nodal, **kwargs) kwargs = {'data': data, 'element': element} self.assertRaises(Exception, Nodal, **kwargs)
def test_constructor(self): """ GMRF """ mesh = Mesh1D(resolution=(1000, )) element = QuadFE(1, 'Q1') dofhandler = DofHandler(mesh, element) cov_kernel = CovKernel(name='matern', dim=2, \ parameters= {'sgm': 1, 'nu': 2, 'l': 0.1, 'M': None}) print('assembling covariance') covariance = Covariance(cov_kernel, dofhandler) print('defining gmrf') X = GMRF(covariance=covariance) print('sampling') Xh = Nodal(data=X.chol_sample(), dofhandler=dofhandler) print('plotting') plot = Plot() plot.line(Xh) '''
""" Test 02 Parameter idenfication of continuous diffusion parameter """ # # Define Computational Mesh # mesh = Mesh1D(resolution=(200,)) mesh.mark_region('left', lambda x: np.abs(x)<1e-9) mesh.mark_region('right', lambda x: np.abs(x-1)<1e-9) # # Elements # Q0 = QuadFE(1, 'DQ0') Q1 = QuadFE(1, 'Q1') # # Exact diffusion coefficient # qe = Function(qfn, 'explicit', dim=1) one = Function(1, 'constant') k1 = 1e-9 k2 = 1000 # # Basis functions # u = Basis(Q1, 'u')