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 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 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))
mesh.mark_region('bnd', bnd_fn, entity_type='half_edge', on_boundary=True) # Mark averaging region dmn_fn = lambda x, y: x >= 0.75 and x <= 1 and y >= 0.75 and y <= 1 mesh.mark_region('dmn', dmn_fn, entity_type='cell', strict_containment=True, on_boundary=False) #cells = mesh.get_region(flag='dmn', entity_type='cell', on_boundary=False, subforest_flag=None) plot.mesh(mesh, regions=[('bnd', 'edge'), ('dmn', 'cell')]) # # Elements # Q0 = QuadFE(mesh.dim(), 'DQ0') # Constants for parameter Q1 = QuadFE(mesh.dim(), 'Q1') # Linear for output Q2 = QuadFE(mesh.dim(), 'Q2') # Quadratic for adjoint # # DofHandlers # dQ0 = DofHandler(mesh, Q0) dQ1 = DofHandler(mesh, Q1) dQ2 = DofHandler(mesh, Q2) # Distribute DOFs dQ0.distribute_dofs() dQ1.distribute_dofs() dQ2.distribute_dofs()
mesh = QuadMesh(resolution=(50, 50)) # Mark Dirichlet boundary regions out_fn = lambda x, y: abs(x - 1) < 1e-8 and 0.8 <= y and y <= 1 mesh.mark_region('out', out_fn, entity_type='half_edge', on_boundary=True) in_fn = lambda x, y: abs(x) < 1e-8 and 0 <= y and y <= 0.2 mesh.mark_region('in', in_fn, entity_type='half_edge', on_boundary=True) x_min, x_max = 0.7, 0.8 y_min, y_max = 0.4, 0.5 reg_fn = lambda x, y: x >= x_min and x <= x_max and y >= y_min and y <= y_max mesh.mark_region('reg', reg_fn, entity_type='cell') # Elements Q1 = QuadFE(mesh.dim(), 'Q1') dQ1 = DofHandler(mesh, Q1) dQ1.distribute_dofs() phi = Basis(dQ1) phi_x = Basis(dQ1, derivative='vx') phi_y = Basis(dQ1, derivative='vy') # # Diffusion Parameter # # Covariance Matrix K = Covariance(dQ1, name='exponential', parameters={'sgm': 1, 'l': 0.1}) # Gaussian random field θ
def test_eval_phi(self): """ Check that the shapes are correct """ # # Mesh # mesh = QuadMesh() dim = mesh.dim() # # element information # element = QuadFE(dim, 'Q2') dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() # Basis basis = Basis(dofhandler) # Define phi n_points = 5 phi = np.random.rand(n_points, 2) dofs = [0, 1] # # Deterministic Data # n_dofs = dofhandler.n_dofs() data = np.random.rand(n_dofs) # Define deterministic function f = Nodal(data=data, basis=basis) # Evaluate and check dimensions fx = f.eval(phi=phi, dofs=dofs) self.assertEqual(fx.shape, (n_points, 1)) # # Sampled Data # n_samples = 4 data = np.random.rand(n_dofs, n_samples) # Define stochastic function f = Nodal(data=data, basis=basis, dofhandler=dofhandler) # Evaluate and check dimensions fx = f.eval(phi=phi, dofs=dofs) self.assertEqual(fx.shape, (n_points, n_samples)) # # Bivariate deterministic # data = np.random.rand(n_dofs, n_dofs, 1) # Define deterministic function f = Nodal(data=data, basis=basis, dofhandler=dofhandler, n_variables=2) fx = f.eval(phi=(phi, phi), dofs=(dofs, dofs)) self.assertEqual(fx.shape, (n_points, 1)) # # Bivariate sampled # data = np.random.rand(n_dofs, n_dofs, n_samples) # Define stochastic function f = Nodal(data=data, basis=basis, dofhandler=dofhandler, n_variables=2) fx = f.eval(phi=(phi, phi), dofs=(dofs, dofs)) self.assertEqual(fx.shape, (n_points, n_samples)) # # Trivariate deterministic # data = np.random.rand(n_dofs, n_dofs, n_dofs, 1) f = Nodal(data=data, basis=basis, dofhandler=dofhandler, n_variables=3)
bnd_fn = lambda x, y: abs(x) < 1e-6 or abs(1 - x) < 1e-6 or abs( y) < 1e-6 or abs(1 - y) < 1e-6 mesh.mark_region('bnd', bnd_fn, entity_type='half_edge', on_boundary=True) # Mark averaging region dmn_fn = lambda x, y: x >= 0.75 and x <= 1 and y >= 0.75 and y <= 1 mesh.mark_region('dmn', dmn_fn, entity_type='cell', strict_containment=True, on_boundary=False) #cells = mesh.get_region(flag='dmn', entity_type='cell', on_boundary=False, subforest_flag=None) #plot.mesh(mesh, regions=[('bnd','edge'),('dmn','cell')]) # Define Elements Q0 = QuadFE(mesh.dim(), 'DQ0') dQ0 = DofHandler(mesh, Q0) dQ0.distribute_dofs() phi = Basis(dQ0) q = Nodal( f=lambda x: np.sin(2 * np.pi * x[:, 0]) * np.sin(2 * np.pi * x[:, 1]), dim=2, basis=phi) problem = Form(q) mesh.cells.refine(new_label='fine_mesh') assembler = Assembler(problem, mesh, subforest_flag='fine_mesh') assembler.assemble()
def reference_solution(): """ Use sparse grid method to compute a benchmark solution """ mesh = QuadMesh(resolution=(10,10)) mesh.mark_region('boundary', lambda x,y:True, entity_type='half_edge', on_boundary=True) element = QuadFE(mesh.dim(), 'Q1') dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() n = dofhandler.n_dofs() phi = Basis(dofhandler, 'u') phi_x = Basis(dofhandler, 'ux') phi_y = Basis(dofhandler, 'uy') yd_fn = Explicit(lambda x: np.sin(2*np.pi*x[:,0])*np.sin(2*np.pi*x[:,1]),dim=2) g = np.ones((n,1)) # # Random diffusion coefficient # # Sparse grid tasmanian_library="/home/hans-werner/bin/TASMANIAN-6.0/libtasmaniansparsegrid.so" grid = TasmanianSG.TasmanianSparseGrid(tasmanian_library=tasmanian_library) dimensions = 4 outputs = 1 depth = 4 type = 'tensor' rule = 'gauss-legendre' grid.makeGlobalGrid(dimensions, outputs, depth, type, rule) Y = grid.getPoints() w = grid.getQuadratureWeights() n_samples = grid.getNumPoints() x = dofhandler.get_dof_vertices() a_nodal = 1 + 0.1*(np.outer(np.cos(np.pi*x[:,1]),Y[:,0])+\ np.outer(np.cos(np.pi*x[:,0]),Y[:,1])+\ np.outer(np.sin(2*np.pi*x[:,1]),Y[:,2])+\ np.outer(np.sin(2*np.pi*x[:,0]),Y[:,3])) a = Nodal(data=a_nodal, dofhandler=dofhandler) yd_vec = yd_fn.eval(x) problems = [[Form(a, test=phi_x, trial=phi_x), Form(a, test=phi_y, trial=phi_y)], [Form(1, test=phi, trial=phi)]] assembler = Assembler(problems, mesh) assembler.assemble() A = assembler.af[0]['bilinear'].get_matrix() M = assembler.af[1]['bilinear'].get_matrix() state = LS(phi) state.add_dirichlet_constraint('boundary') adjoint = LS(phi) adjoint.add_dirichlet_constraint('boundary') tau = 10 k_max = 20 alpha = 0.1 u = np.zeros((n,1)) norm_dJ_iter = [] J_iter = [] u_iter = [] for k in range(k_max): print('iteration', k) # # Compute average cost and gradient # dJ = np.zeros((n,1)) J = 0 print('sampling') for n in range(n_samples): print(n) yn, pn, Jn, dJn = cost_gradient(state,adjoint,A[n],M, g,u,yd_vec,alpha) J += w[n]*Jn dJ += w[n]*dJn print('') norm_dJ = np.sqrt(dJ.T.dot(M.dot(dJ))) # # Store current iterates # norm_dJ_iter.append(norm_dJ) J_iter.append(J) u_iter.append(u) # # Check for convergence # if norm_dJ<1e-8: break # # Update iterate # u -= tau*dJ
u_t - div*(D*grad(u)) + div(v*u) + R(u) = 0 subject to the appropriate initial and boundary conditions, using SUPG and """ comment = Verbose() # Computational mesh mesh = QuadMesh(box=[0, 10, 0, 10], resolution=(100, 100)) left = mesh.mark_region('left', lambda x, y: abs(x) < 1e-10) # Finite elements # Piecewise constants E0 = QuadFE(mesh.dim(), 'DQ0') V0 = DofHandler(mesh, E0) V0.distribute_dofs() # Piecewise linears E1 = QuadFE(mesh.dim(), 'Q1') V1 = DofHandler(mesh, E1) V1.distribute_dofs() v = Basis(V1, 'v') v_x = Basis(V1, 'vx') v_y = Basis(V1, 'vy') V1.distribute_dofs() print(V1.n_dofs())
x_max = 2 y_min = 0 y_max = 1 mesh = QuadMesh(box=[x_min, x_max, y_min, y_max], resolution=(20, 10)) # Mark Dirichlet Edges mesh.mark_region('left', lambda x, y: np.abs(x) < 1e-9, entity_type='half_edge') mesh.mark_region('right', lambda x, y: np.abs(x - 2) < 1e-9, entity_type='half_edge') # Element element_Q0 = QuadFE(mesh.dim(), 'DQ0') element_Q1 = QuadFE(mesh.dim(), 'Q1') dh_Q0 = DofHandler(mesh, element_Q0) dh_Q0.distribute_dofs() n_Q0 = dh_Q0.n_dofs() dh_Q1 = DofHandler(mesh, element_Q1) dh_Q1.distribute_dofs() n_Q1 = dh_Q1.n_dofs() # Basis functions phi = Basis(dh_Q1, 'v') phi_x = Basis(dh_Q1, 'vx') phi_y = Basis(dh_Q1, 'vy')
def test_integrals_2d(self): """ Test Assembly of some 2D systems """ mesh = QuadMesh(box=[1, 2, 1, 2], resolution=(2, 2)) mesh.cells.get_leaves()[0].mark(0) mesh.cells.refine(refinement_flag=0) # Kernel kernel = Kernel(Explicit(f=lambda x: x[:, 0] * x[:, 1], dim=2)) problem = Form(kernel) assembler = Assembler(problem, mesh=mesh) assembler.assemble() self.assertAlmostEqual(assembler.get_scalar(), 9 / 4) # # Linear forms (x,x) and (x,x') over [1,2]^2 = 7/3, 3/2 # # Elements Q1 = QuadFE(mesh.dim(), 'Q1') Q2 = QuadFE(mesh.dim(), 'Q2') Q3 = QuadFE(mesh.dim(), 'Q3') # Dofhandlers dQ1 = DofHandler(mesh, Q1) dQ2 = DofHandler(mesh, Q2) dQ3 = DofHandler(mesh, Q3) # Distribute dofs [d.distribute_dofs() for d in [dQ1, dQ2, dQ3]] for dQ in [dQ1, dQ2, dQ3]: # Basis phi = Basis(dQ, 'u') phi_x = Basis(dQ, 'ux') # Kernel function xfn = Nodal(f=lambda x: x[:, 0], basis=phi) yfn = Nodal(f=lambda x: x[:, 1], basis=phi) # Kernel kernel = Kernel(xfn) # Form problem = [[Form(kernel, test=phi)], [Form(kernel, test=phi_x)]] # Assembly assembler = Assembler(problem, mesh) assembler.assemble() # Check b^Tx = (x,y) b0 = assembler.get_vector(0) self.assertAlmostEqual(np.sum(b0 * yfn.data()[:, 0]), 9 / 4) b1 = assembler.get_vector(1) self.assertAlmostEqual(np.sum(b1 * xfn.data()[:, 0]), 3 / 2) self.assertAlmostEqual(np.sum(b1 * yfn.data()[:, 0]), 0) # # Bilinear forms # # Compute (1,x,y) = 9/4, or (xy, 1, 1) = 9/4 for dQ in [dQ1, dQ2, dQ3]: # Basis phi = Basis(dQ, 'u') phi_x = Basis(dQ, 'ux') phi_y = Basis(dQ, 'uy') # Kernel function xyfn = Explicit(f=lambda x: x[:, 0] * x[:, 1], dim=2) xfn = Nodal(f=lambda x: x[:, 0], basis=phi) yfn = Nodal(f=lambda x: x[:, 1], basis=phi) # Form problems = [[Form(1, test=phi, trial=phi)], [Form(Kernel(xfn), test=phi, trial=phi_x)], [Form(Kernel(xyfn), test=phi_y, trial=phi_x)]] # Assemble assembler = Assembler(problems, mesh) assembler.assemble() x = xfn.data()[:, 0] y = yfn.data()[:, 0] for i_problem in range(3): A = assembler.get_matrix(i_problem) self.assertAlmostEqual(y.T.dot(A.dot(x)), 9 / 4)