def sample_qoi(q, dofhandler): """ Sample total energy of output for a given sample of q's """ # # Set up weak form # # Basis phi = Basis(dofhandler, 'v') phi_x = Basis(dofhandler, 'vx') # Elliptic problem problems = [[Form(q, test=phi_x, trial=phi_x), Form(1, test=phi)], [Form(1, test=phi, trial=phi)]] # Assemble assembler = Assembler(problems, mesh) assembler.assemble() # System matrices A = assembler.af[0]['bilinear'].get_matrix() b = assembler.af[0]['linear'].get_matrix() M = assembler.af[1]['bilinear'].get_matrix() # Define linear system system = LS(phi) system.add_dirichlet_constraint('left',1) system.add_dirichlet_constraint('right',0) n_samples = q.n_samples() y_smpl = [] QoI_smpl = [] for i in range(n_samples): # Sample system if n_samples > 1: Ai = A[i] else: Ai = A system.set_matrix(Ai) system.set_rhs(b.copy()) # Solve system system.solve_system() # Record solution and qoi y = system.get_solution(as_function=False) y_smpl.append(y) QoI_smpl.append(y.T.dot(M.dot(y))) # Convert to numpy array y_smpl = np.concatenate(y_smpl,axis=1) QoI = np.concatenate(QoI_smpl, axis=1).ravel() return y_smpl, QoI
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 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 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 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 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 sensitivity_sample_qoi(exp_q, dofhandler): """ Sample QoI by means of Taylor expansion J(q+dq) ~= J(q) + dJdq(q)dq """ # Basis phi = Basis(dofhandler, 'v') phi_x = Basis(dofhandler, 'vx') # Define problem exp_q_fn = Nodal(data=exp_q, basis=phi) primal = [Form(exp_q_fn, test=phi_x, trial=phi_x), Form(1, test=phi)] adjoint = [Form(exp_q_fn, test=phi_x, trial=phi_x), Form(0, test=phi)] qoi = [Form(exp_q_fn, test=phi_x)] problems = [primal, adjoint, qoi] # Define assembler assembler = Assembler(problems) # # Dirichlet conditions for primal problem # assembler.add_dirichlet('left', 0, i_problem=0) assembler.add_dirichlet('right', 1, i_problem=0) # Dirichlet conditions for adjoint problem assembler.add_dirichlet('left', 0, i_problem=1) assembler.add_dirichlet('right', -1, i_problem=1) # Assemble system assembler.assemble() # Compute solution and qoi at q (primal) u = assembler.solve(i_problem=0) # Compute solution of the adjoint problem v = assembler.solve(i_problem=1) # Evaluate J J = u.dot(assembler.get_vector(2)) # # Assemble gradient # ux_fn = Nodal(data=u, basis=phi_x) vx_fn = Nodal(data=v, basis=phi_x) k_int = Kernel(f=[exp_q_fn, ux_fn, vx_fn], F=lambda exp_q, ux, vx: exp_q * ux * vx) problem = [Form(k_int, test=phi)] assembler = Assembler(problem) assembler.assemble() dJ = -assembler.get_vector() return dJ
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 sample_state(mesh,dQ,z,mflag,reference=False): """ Compute the sample output corresponding to a given input """ n_samples = z.shape[0] q = set_diffusion(dQ,z) phi = Basis(dQ,'u', mflag) phi_x = Basis(dQ, 'ux', mflag) if reference: problems = [[Form(q,test=phi_x,trial=phi_x), Form(1,test=phi)], [Form(1,test=phi, trial=phi)], [Form(1,test=phi_x, trial=phi_x)]] else: problems = [[Form(q,test=phi_x,trial=phi_x), Form(1,test=phi)]] assembler = Assembler(problems, mesh, subforest_flag=mflag) assembler.assemble() A = assembler.af[0]['bilinear'].get_matrix() b = assembler.af[0]['linear'].get_matrix() if reference: M = assembler.af[1]['bilinear'].get_matrix() K = assembler.af[2]['bilinear'].get_matrix() system = LS(phi) system.add_dirichlet_constraint('left') system.add_dirichlet_constraint('right') n_dofs = dQ.n_dofs(subforest_flag=mflag) y = np.empty((n_dofs,n_samples)) for n in range(n_samples): system.set_matrix(A[n]) system.set_rhs(b.copy()) system.solve_system() y[:,n] = system.get_solution(as_function=False)[:,0] y_fn = Nodal(dofhandler=dQ,subforest_flag=mflag,data=y) if reference: return y_fn, M, K else: return y_fn
def test08_1d_sampled_rhs(self): # # Mesh # mesh = Mesh1D(resolution=(1, )) mesh.mark_region('left', lambda x: np.abs(x) < 1e-9, on_boundary=True) mesh.mark_region('right', lambda x: np.abs(1 - x) < 1e-9, on_boundary=True) # # Elements # Q3 = QuadFE(1, 'Q3') dofhandler = DofHandler(mesh, Q3) dofhandler.distribute_dofs() # # Basis # v = Basis(dofhandler, 'u') vx = Basis(dofhandler, 'ux') # # Define sampled right hand side and exact solution # xv = dofhandler.get_dof_vertices() n_points = dofhandler.n_dofs() n_samples = 6 a = np.arange(n_samples) f = lambda x, a: a * x u = lambda x, a: a / 6 * (x - x**3) + x fdata = np.zeros((n_points, n_samples)) udata = np.zeros((n_points, n_samples)) for i in range(n_samples): fdata[:, i] = f(xv, a[i]).ravel() udata[:, i] = u(xv, a[i]).ravel() # Define sampled function fn = Nodal(data=fdata, basis=v) ue = Nodal(data=udata, basis=v) # # Forms # one = Constant(1) a = Form(Kernel(one), test=vx, trial=vx) L = Form(Kernel(fn), test=v) problem = [a, L] # # Assembler # assembler = Assembler(problem, mesh) assembler.assemble() A = assembler.get_matrix() b = assembler.get_vector() # # Linear System # system = LinearSystem(v, A=A, b=b) # Set constraints system.add_dirichlet_constraint('left', 0) system.add_dirichlet_constraint('right', 1) #system.set_constraint_relation() #system.incorporate_constraints() # Solve and resolve constraints system.solve_system() #system.resolve_constraints() # Extract finite element solution ua = system.get_solution(as_function=True) # Check that the solution is close print(ue.data()[:, [0]]) print(ua.data()) self.assertTrue(np.allclose(ue.data()[:, [0]], ua.data()))
def test01_1d_dirichlet_linear(self): """ Solve one dimensional boundary value problem with dirichlet conditions on left and right """ # # Define mesh # mesh = Mesh1D(resolution=(10, )) for etype in ['Q1', 'Q2', 'Q3']: element = QuadFE(1, etype) dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() phi = Basis(dofhandler) # # Exact solution # ue = Nodal(f=lambda x: x, basis=phi) # # Define Basis functions # u = Basis(dofhandler, 'u') ux = Basis(dofhandler, 'ux') # # Define bilinear form # one = Constant(1) zero = Constant(0) a = Form(kernel=Kernel(one), trial=ux, test=ux) L = Form(kernel=Kernel(zero), test=u) problem = [a, L] # # Assemble # assembler = Assembler(problem, mesh) assembler.assemble() # # Form linear system # A = assembler.get_matrix() b = assembler.get_vector() system = LinearSystem(u, A=A, b=b) # # Dirichlet conditions # # Boundary functions bm_left = lambda x: np.abs(x) < 1e-9 bm_rght = lambda x: np.abs(x - 1) < 1e-9 # Mark boundary regions mesh.mark_region('left', bm_left, on_boundary=True) mesh.mark_region('right', bm_rght, on_boundary=True) # Add Dirichlet constraints system.add_dirichlet_constraint('left', ue) system.add_dirichlet_constraint('right', ue) # # Solve system # #system.solve_system() system.solve_system() # # Get solution # #ua = system.get_solution(as_function=True) uaa = system.get_solution(as_function=True) #uaa = uaa.data().ravel() # Compare with exact solution #self.assertTrue(np.allclose(ua.data(), ue.data())) self.assertTrue(np.allclose(uaa.data(), ue.data()))
def test05_2d_dirichlet(self): """ Two dimensional Dirichlet problem with hanging nodes """ # # Define mesh # mesh = QuadMesh(resolution=(1, 2)) mesh.cells.get_child(1).mark(1) mesh.cells.refine(refinement_flag=1) mesh.cells.refine() # # Mark left and right boundaries # bm_left = lambda x, dummy: np.abs(x) < 1e-9 bm_right = lambda x, dummy: np.abs(1 - x) < 1e-9 mesh.mark_region('left', bm_left, entity_type='half_edge') mesh.mark_region('right', bm_right, entity_type='half_edge') for etype in ['Q1', 'Q2', 'Q3']: # # Element # element = QuadFE(2, etype) dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() # # Basis # u = Basis(dofhandler, 'u') ux = Basis(dofhandler, 'ux') uy = Basis(dofhandler, 'uy') # # Construct forms # ue = Nodal(f=lambda x: x[:, 0], basis=u) ax = Form(kernel=Kernel(Constant(1)), trial=ux, test=ux) ay = Form(kernel=Kernel(Constant(1)), trial=uy, test=uy) L = Form(kernel=Kernel(Constant(0)), test=u) problem = [ax, ay, L] # # Assemble # assembler = Assembler(problem, mesh) assembler.assemble() # # Get system matrices # A = assembler.get_matrix() b = assembler.get_vector() # # Linear System # system = LinearSystem(u, A=A, b=b) # # Constraints # # Add dirichlet conditions system.add_dirichlet_constraint('left', ue) system.add_dirichlet_constraint('right', ue) # # Solve # system.solve_system() #system.resolve_constraints() # # Check solution # ua = system.get_solution(as_function=True) self.assertTrue(np.allclose(ua.data(), ue.data()))
# # Random diffusion coefficient # n_samples = 200 cov = Covariance(dh_y, name='gaussian', parameters={'l':0.1}) k = GaussianField(ny, K=cov) k.update_support() kfn = Nodal(dofhandler=dh_y, data=k.sample(n_samples=n_samples)) # ============================================================================= # Assembly # ============================================================================= K = Kernel(kfn, F=lambda f:np.exp(f)) # diffusivity problems = [[Form(K, test=phi_x, trial=phi_x)], [Form(test=phi, trial=phi)]] assembler = Assembler(problems, mesh) assembler.assemble() # Mass matrix (for control) M = assembler.af[1]['bilinear'].get_matrix() # ============================================================================= # Define State and Adjoint Systems # ============================================================================= state = LS(phi) adjoint = LS(phi)
def test04_1d_periodic(self): # # Dirichlet Problem on a Periodic Mesh # # Define mesh, element mesh = Mesh1D(resolution=(100, ), periodic=True) element = QuadFE(1, 'Q3') dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() # Basis functions u = Basis(dofhandler, 'u') ux = Basis(dofhandler, 'ux') # Exact solution ue = Nodal(f=lambda x: np.sin(2 * np.pi * x), basis=u) # # Mark dirichlet regions # bnd_left = lambda x: np.abs(x) < 1e-9 mesh.mark_region('left', bnd_left, entity_type='vertex') # # Set up forms # # Bilinear form a = Form(kernel=Kernel(Constant(1)), trial=ux, test=ux) # Linear form f = Explicit(lambda x: 4 * np.pi**2 * np.sin(2 * np.pi * x), dim=1) L = Form(kernel=Kernel(f), test=u) # # Assemble # problem = [a, L] assembler = Assembler(problem, mesh) assembler.assemble() A = assembler.get_matrix() b = assembler.get_vector() # # Linear System # system = LinearSystem(u, A=A, b=b) # Add dirichlet constraint system.add_dirichlet_constraint('left', 0, on_boundary=False) # Assemble constraints #system.set_constraint_relation() #system.incorporate_constraints() system.solve_system() #system.resolve_constraints() # Compare with interpolant of exact solution ua = system.get_solution(as_function=True) #plot = Plot(2) #plot.line(ua) #plot.line(ue) self.assertTrue(np.allclose(ua.data(), ue.data()))
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
cov.compute_eig_decomp() q = GaussianField(dQ0.n_dofs(), K=cov) # Sample Random field n_samples = 100 eq = Nodal(basis=phi_0, data=np.exp(q.sample(n_samples))) plot.contour(eq, n_sample=25) # # Compute state # # Define weak form state = [[ Form(eq, test=phix_1, trial=phix_1), Form(eq, test=phiy_1, trial=phiy_1), Form(1, test=phi_1) ], [Form(1, test=phi_1, flag='dmn')]] # Assemble system assembler = Assembler(state) assembler.add_dirichlet('bnd') assembler.assemble() J = assembler.get_vector(1) # Solve system u_vec = assembler.solve() u = Nodal(basis=phi_1, data=u_vec)
n_samples = n_batches * n_samples_per_batch f_mc = [] g_mc = [] for n_batch in tqdm(range(n_batches)): # # Generate random sample # z = np.random.normal(size=(r, n_samples_per_batch)) q_smpl = Vr.dot(np.diag(np.sqrt(lr)).dot(z)) q.set_data(q_smpl) expq = Kernel(q, F=lambda f: np.exp(f)) # # Assemble system # problems = [[Form(expq, test=phi_x, trial=phi_x)], [Form(test=phi, trial=phi)]] assembler = Assembler(problems, mesh) assembler.assemble() M = assembler.af[0]['bilinear'].get_matrix()[0] for n in range(n_samples_per_batch): A = assembler.af[0]['bilinear'].get_matrix()[n] fn, gn, yn, pn = sample_cost_gradient(state, adjoint, A, M, u, y_data, gamma) f_mc.append(fn) g_mc.append(gn) f_mc = np.concatenate(f_mc, axis=1) g_mc = np.concatenate(g_mc, axis=1) np.save('f_mc', f_mc)
# ============================================================================= Q1 = QuadFE(2, 'Q1') dofhandler = DofHandler(mesh, Q1) dofhandler.distribute_dofs() u = Basis(dofhandler, 'u') ux = Basis(dofhandler, 'ux') uy = Basis(dofhandler, 'uy') epsilon = 1e-6 vx = Explicit(f=lambda x: -x[:, 1], dim=2) vy = Explicit(f=lambda x: x[:, 0], dim=2) uB = Explicit(f=lambda x: np.cos(2 * np.pi * (x[:, 1] + 0.25)), dim=2) problem = [ Form(epsilon, trial=ux, test=ux), Form(epsilon, trial=uy, test=uy), Form(vx, trial=ux, test=u), Form(vy, trial=uy, test=u), Form(0, test=u) ] print('assembling', end=' ') assembler = Assembler(problem, mesh) assembler.assemble() print('done') print('solving', end=' ') A = assembler.get_matrix() b = np.zeros(u.n_dofs()) system = LS(u, A=A, b=b)
def plot_heuristics(f, tht, basis, region, condition): """ Parameters ---------- f : lambda, Function of θ to be integrated. n : int, Sample size for Monte Carlo sample """ tht.update_support() # # Plot samples of the random field # n = 10000 tht_sample = tht.sample(n) tht_fn = Nodal(data=tht_sample, basis=basis) # # Compute the quantity of interest # # Define the kernel kf = Kernel(tht_fn, F=f) # Assemble over the mesh problems = [[Form(kernel=kf, flag=region)], [Form(flag=region)]] assembler = Assembler(problems, basis.mesh()) assembler.assemble() # Extract sample dx = assembler.get_scalar(i_problem=1) q_sample = assembler.get_scalar(i_sample=None) / dx # # Compute correlation coefficients of q with spatial data # plot = Plot(quickview=False) fig, ax = plt.subplots() plt_args = {'linewidth': 0.5, 'color': 'k'} ax = plot.line(tht_fn, axis=ax, i_sample=list(range(100)), plot_kwargs=plt_args) fig.savefig('ex01_sample_paths.eps') fig, ax = plt.subplots() ftht = Nodal(data=f(tht_sample), basis=basis) ax = plot.line(ftht, axis=ax, i_sample=list(range(100)), plot_kwargs=plt_args) fig.savefig('ex01_integrand.eps') fig, ax = plt.subplots(1, 1) plt.hist(q_sample, bins=50, density=True) ax.set_title(r'Histogram $Q(\theta)$') fig.savefig('ex01_histogram.eps') plt.close('all') dh = basis.dofhandler() n_dofs = dh.n_dofs() # Extract the region on which we condition cnd_dofs = dh.get_region_dofs(entity_flag=condition) I = np.eye(n_dofs) I = I[cnd_dofs, :] # Measured tht tht_msr = tht_sample[cnd_dofs, 0][:, None] n_cnd = 30 cnd_tht = tht.condition(I, tht_msr, n_samples=n_cnd) #cnd_tht_data = np.array([tht_sample[:,0] for dummy in range(n_cnd)]) #cnd_tht_data[cnd_dofs,:] = cnd_tht cnd_tht_fn = Nodal(data=f(cnd_tht), basis=basis) fig, ax = plt.subplots() ax = plot.line(cnd_tht_fn, axis=ax, i_sample=np.arange(n_cnd), plot_kwargs=plt_args) fig.tight_layout() plt.show()
def test09_1d_inverse(self): """ Compute the inverse of a matrix and apply it to a vector/matrix. """ # # Mesh # mesh = Mesh1D(resolution=(1, )) mesh.mark_region('left', lambda x: np.abs(x) < 1e-9, on_boundary=True) mesh.mark_region('right', lambda x: np.abs(1 - x) < 1e-9, on_boundary=True) # # Elements # Q3 = QuadFE(1, 'Q3') dofhandler = DofHandler(mesh, Q3) dofhandler.distribute_dofs() # # Basis # u = Basis(dofhandler, 'u') ux = Basis(dofhandler, 'ux') # # Define sampled right hand side and exact solution # xv = dofhandler.get_dof_vertices() n_points = dofhandler.n_dofs() n_samples = 6 a = np.arange(n_samples) ffn = lambda x, a: a * x ufn = lambda x, a: a / 6 * (x - x**3) + x fdata = np.zeros((n_points, n_samples)) udata = np.zeros((n_points, n_samples)) for i in range(n_samples): fdata[:, i] = ffn(xv, a[i]).ravel() udata[:, i] = ufn(xv, a[i]).ravel() # Define sampled function fn = Nodal(data=fdata, basis=u) ue = Nodal(data=udata, basis=u) # # Forms # one = Constant(1) a = Form(Kernel(one), test=ux, trial=ux) L = Form(Kernel(fn), test=u) problem = [[a], [L]] # # Assembler # assembler = Assembler(problem, mesh) assembler.assemble() A = assembler.get_matrix() b = assembler.get_vector(i_problem=1) # # Linear System # system = LinearSystem(u, A=A) # Set constraints system.add_dirichlet_constraint('left', 0) system.add_dirichlet_constraint('right', 1) system.solve_system(b) # Extract finite element solution ua = system.get_solution(as_function=True) system2 = LinearSystem(u, A=A, b=b) # Set constraints system2.add_dirichlet_constraint('left', 0) system2.add_dirichlet_constraint('right', 1) system2.solve_system() u2 = system2.get_solution(as_function=True) # Check that the solution is close self.assertTrue(np.allclose(ue.data()[:, 0], ua.data()[:, 0])) self.assertTrue(np.allclose(ue.data()[:, [0]], u2.data()))
""" Task: Modify the kernel class to allow for the computation of forms involving (i) normal derivatives or (ii) jumps across cell edges. i.e. I n.A*grad(u) ds or """ # # Define mesh # mesh = QuadMesh(resolution=(20, 20)) element = QuadFE(2, 'DQ1') u = Nodal(f=lambda x: -1 + x[:, 0]**5 + x[:, 1]**8, mesh=mesh, element=element) print(u.data()) plot = Plot(3) plot.wire(u) kernel = JumpKernel(u, dfdx='fx') form = Form(kernel=kernel, dmu='ds') assembler = Assembler(form, mesh) assembler.assemble() cf = assembler.af[0]['constant'] print(cf.get_matrix())
eta_trunc_sg = V[:, :k].dot(np.diag(np.sqrt(D[:k])).dot(z.T)) # Generate a Monte Carlo sample on top of sparse grid n_mc = 20 zz = np.random.randn(n_dofs - k, n_mc) eta_tail_mc = V[:, k:].dot(np.diag(np.sqrt(D[k:]))).dot(zz) # ----------------------------------------------------------------------------- # Sample and Integrate # ----------------------------------------------------------------------------- # Samples of random field theta_trunc = Nodal(data=eta_trunc_sg[:, [50]] + eta_tail_mc, basis=phi_1) # Assembler k = Kernel(theta_trunc, F=lambda tht: tht**2) problem = Form(flag='integration', kernel=k) assembler = Assembler(problem, mesh) assembler.assemble() v = assembler.get_scalar(i_sample=3) #plot = Plot(quickview=False) #fig, ax = plt.subplots() #plot.mesh(mesh,regions=[('region','cell')]) """ ax = plot.line(theta_trunc, axis=ax, i_sample=np.arange(n_mc), plot_kwargs={'linewidth':0.2, 'color':'k'}) """ #plt.show()
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_qoi(f, tht, basis, region, n=1000000, verbose=True): """ Parameters ---------- f : lambda function, Function of θ to be integrated. tht : GaussianField, Random field θ defined on mesh in terms of its mean and covariance basis : Basis, Basis function defining the nodal interpolant. It incorporates the mesh, the dofhandler, and the derivative. region : meshflag, Flag indicating the region of integration n : int, default=1000000 Sample size Returns ------- Q_ref : double, Reference quantity of interest err : double, Expected RMSE given by var(Q)/n. """ # # Assemble integral # batch_size = 100000 n_batches = n // batch_size + (0 if (n % batch_size) == 0 else 1) if verbose: print('Computing Reference Quantity of Interest') print('========================================') print('Sample size: ', n) print('Batch size: ', batch_size) print('Number of batches: ', n_batches) Q_smpl = np.empty(n) for k in range(n_batches): # Determine sample sizes for each batch if k < n_batches - 1: n_sample = batch_size else: # Last sample may be smaller than batch_size n_sample = n - k * batch_size if verbose: print(' - Batch Number ', k) print(' - Sample Size: ', n_sample) print(' - Sampling random field') # Sample from field tht_smpl = tht.sample(n_sample) # Define kernel tht_n = Nodal(data=tht_smpl, basis=basis) kf = Kernel(tht_n, F=f) # Define forms if k == 0: problems = [[Form(kernel=kf, flag=region)], [Form(flag=region)]] else: problems = [Form(kernel=kf, flag=region)] if verbose: print(' - Assembling.') # Compute the integral assembler = Assembler(problems, basis.mesh()) assembler.assemble() # # Compute statistic # # Get samples if k == 0: dx = assembler.get_scalar(i_problem=1) if verbose: print(' - Updating samples \n') batch_sample = assembler.get_scalar(i_problem=0, i_sample=None) Q_smpl[k * batch_size:k * batch_size + n_sample] = batch_sample / dx # Compute mean and MSE Q_ref = np.mean(Q_smpl) err = np.var(Q_smpl) / n # Return reference return Q_ref, err
Q,R = linalg.qr(A, mode='economic') r = np.diag(R) print(len(r[np.abs(r)>1e-13])) print(Q,'\n',R) ''' print("TasmanianSG version: {0:s}".format(TasmanianSG.__version__)) print("TasmanianSG license: {0:s}".format(TasmanianSG.__license__)) mesh = Mesh1D(resolution=(2, )) element = QuadFE(mesh.dim(), 'Q1') dofhandler = DofHandler(mesh, element) phi_x = Basis(dofhandler, 'ux') problems = [Form(1, test=phi_x, trial=phi_x)] assembler = Assembler(problems, mesh) assembler.assemble() A = assembler.af[0]['bilinear'].get_matrix() n = dofhandler.n_dofs() b = np.ones((n, 1)) mesh.mark_region('left', lambda x: np.abs(x) < 1e-9) mesh.mark_region('right', lambda x: np.abs(1 - x) < 1e-9) print('A before constraint', A.toarray()) system = LS(phi_x) system.add_dirichlet_constraint('left', 1) system.add_dirichlet_constraint('right', 0)
# Define element # element = QuadFE(2, etype) dofhandler = DofHandler(mesh, element) dofhandler.distribute_dofs() # # Define Basis Functions # u = Basis(dofhandler, 'u') ux = Basis(dofhandler, 'ux') uy = Basis(dofhandler, 'uy') # # Define weak form # a_diff_x = Form(eps, trial=ux, test=ux) a_diff_y = Form(eps, trial=uy, test=uy) a_adv_x = Form(vx, trial=ux, test=u) a_adv_y = Form(vy, trial=uy, test=u) b = Form(f, test=u) problem = [a_diff_x, a_diff_y, a_adv_x, a_adv_y, b] # # Assembler system # assembler = Assembler([problem], mesh) assembler.add_dirichlet(None, ue) assembler.assemble() #
# Sample from field tht_fn = Nodal(data=tht.sample(n_samples=3), basis=phi) plot = Plot() plot.contour(tht_fn) # # Advection # v = [0.1, -0.1] plot.mesh(mesh, regions=[('in', 'edge'), ('out', 'edge'), ('reg', 'cell')]) k = Kernel(tht_fn, F=lambda tht: np.exp(tht)) adv_diff = [ Form(k, trial=phi_x, test=phi_x), Form(k, trial=phi_y, test=phi_y), Form(0, test=phi), Form(v[0], trial=phi_x, test=phi), Form(v[1], trial=phi_y, test=phi) ] average = [Form(1, test=phi, flag='reg'), Form(1, flag='reg')] assembler = Assembler([adv_diff, average], mesh) assembler.add_dirichlet('out', dir_fn=0) assembler.add_dirichlet('in', dir_fn=10) assembler.assemble() u_vec = assembler.solve(i_problem=0, i_matrix=0, i_vector=0) plot.contour(Nodal(data=u_vec, basis=phi))
one = Function(1, 'constant') k1 = 1e-9 k2 = 1000 # # Basis functions # u = Basis(Q1, 'u') ux = Basis(Q1, 'ux') q = Basis(Q1, 'q') # # Forms # a_qe = Form(kernel=Kernel(qe), trial=ux, test=ux) a_one = Form(kernel=Kernel(one), trial=ux, test=ux) L = Form(kernel=Kernel(one), test=u) # # Problems # problems = [[a_qe,L], [a_one]] # # Assembly # assembler = Assembler(problems, mesh) assembler.assemble()
Q1 = QuadFE(1, 'Q1') qe = Function(qfn, 'explicit', dim=1) one = Function(1, 'constant') # # Basis functions # u = Basis(Q1, 'u') ux = Basis(Q1, 'ux') q = Basis(Q0, 'q') # # Forms # a_qe = Form(kernel=Kernel(qe), trial=ux, test=ux) a_one = Form(kernel=Kernel(one), trial=ux, test=ux) m = Form(kernel=Kernel(one), trial=u, test=u) L = Form(kernel=Kernel(one), test=u) # # Problems # problems = [[a_qe,L], [a_one], [m]] # # Assembly # assembler = Assembler(problems, mesh) assembler.assemble()