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_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())
# adjoint.set_matrix(sp.csr_matrix(A, copy=True)) adjoint.set_rhs(M.dot(dy)) adjoint.solve_system() p = adjoint.get_solution(as_function=False) # Gradient g = p + gamma * u return f, g, y, p # ============================================================================= # Variational Form # ============================================================================= comment = Verbose() # # Mesh # # Computational domain x_min = 0 x_max = 2 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
state.set_rhs(b) state.solve_system() y_data = state.get_solution(as_function=True) fig, ax = plt.subplots(1,2) plot = Plot(quickview=False) ax[0].plot(v[dofs_prod],z_data,'ro') ax[0] = plot.line(y_data, axis=ax[0]) ax[0].plot(v[dofs_inj],np.zeros((len(dofs_inj),1)), 'C0o') ax[1].plot(np.array(f_iter)) plt.show() vb = Verbose() # ============================================================================= # Mesh # ============================================================================= # Computational domain x_min = 0 x_max = 2 # # Plot # """ plot = Plot(quickview=False) fig, ax = plt.subplots(n_resolutions,1)
def test_ft(): plot = Plot() vb = Verbose() # ============================================================================= # Parameters # ============================================================================= # # Flow # # permeability field phi = Constant(1) # porosity D = Constant(0.0252) # dispersivity K = Constant(1) # permeability # ============================================================================= # Mesh and Elements # ============================================================================= # Mesh mesh = QuadMesh(resolution=(30, 30)) # Mark left and right regions 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 - 1) < 1e-9, entity_type='half_edge') # Elements p_element = QuadFE(2, 'Q1') # element for pressure c_element = QuadFE(2, 'Q1') # element for concentration # Dofhandlers p_dofhandler = DofHandler(mesh, p_element) c_dofhandler = DofHandler(mesh, c_element) p_dofhandler.distribute_dofs() c_dofhandler.distribute_dofs() # Basis functions p_ux = Basis(p_dofhandler, 'ux') p_uy = Basis(p_dofhandler, 'uy') p_u = Basis(p_dofhandler, 'u') p_inflow = lambda x, y: np.ones(shape=x.shape) p_outflow = lambda x, y: np.zeros(shape=x.shape) c_inflow = lambda x, y: np.zeros(shape=x.shape) # ============================================================================= # Solve the steady state flow equations # ============================================================================= vb.comment('Solving flow equations') # Define problem flow_problem = [ Form(1, test=p_ux, trial=p_ux), Form(1, test=p_uy, trial=p_uy), Form(0, test=p_u) ] # Assemble vb.tic('assembly') assembler = Assembler(flow_problem) assembler.add_dirichlet('left', 1) assembler.add_dirichlet('right', 0) assembler.assemble() vb.toc() # Solve linear system vb.tic('solve') A = assembler.get_matrix().tocsr() b = assembler.get_vector() x0 = assembler.assembled_bnd() # Interior nodes pa = np.zeros((p_u.n_dofs(), 1)) int_dofs = assembler.get_dofs('interior') pa[int_dofs, 0] = spla.spsolve(A, b - x0) # Resolve Dirichlet conditions dir_dofs, dir_vals = assembler.get_dirichlet(asdict=False) pa[dir_dofs] = dir_vals vb.toc() # Pressure function pfn = Nodal(data=pa, basis=p_u) px = pfn.differentiate((1, 0)) py = pfn.differentiate((1, 1)) #plot.contour(px) #plt.show() # ============================================================================= # Transport Equations # ============================================================================= # Specify initial condition c0 = Constant(1) dt = 1e-1 T = 6 N = int(np.ceil(T / dt)) c = Basis(c_dofhandler, 'c') cx = Basis(c_dofhandler, 'cx') cy = Basis(c_dofhandler, 'cy') print('assembling transport equations') k_phi = Kernel(f=phi) k_advx = Kernel(f=[K, px], F=lambda K, px: -K * px) k_advy = Kernel(f=[K, py], F=lambda K, py: -K * py) tht = 1 m = [Form(kernel=k_phi, test=c, trial=c)] s = [ Form(kernel=k_advx, test=c, trial=cx), Form(kernel=k_advy, test=c, trial=cy), Form(kernel=Kernel(D), test=cx, trial=cx), Form(kernel=Kernel(D), test=cy, trial=cy) ] problems = [m, s] assembler = Assembler(problems) assembler.add_dirichlet('left', 0, i_problem=0) assembler.add_dirichlet('left', 0, i_problem=1) assembler.assemble() x0 = assembler.assembled_bnd() # Interior nodes int_dofs = assembler.get_dofs('interior') # Dirichlet conditions dir_dofs, dir_vals = assembler.get_dirichlet(asdict=False) # System matrices M = assembler.get_matrix(i_problem=0) S = assembler.get_matrix(i_problem=1) # Initialize c0 and cp c0 = np.ones((c.n_dofs(), 1)) cp = np.zeros((c.n_dofs(), 1)) c_fn = Nodal(data=c0, basis=c) # # Compute solution # print('time stepping') for i in range(N): # Build system A = M + tht * dt * S b = M.dot(c0[int_dofs]) - (1 - tht) * dt * S.dot(c0[int_dofs]) # Solve linear system cp[int_dofs, 0] = spla.spsolve(A, b) # Add Dirichlet conditions cp[dir_dofs] = dir_vals # Record current iterate c_fn.add_samples(data=cp) # Update c0 c0 = cp.copy() #plot.contour(c_fn, n_sample=i) # # Quantity of interest # def F(c, px, py, entity=None): """ Compute c(x,y,t)*(grad p * n) """ n = entity.unit_normal() return c * (px * n[0] + py * n[1]) px.set_subsample(i=np.arange(41)) py.set_subsample(i=np.arange(41)) #kernel = Kernel(f=[c_fn,px,py], F=F) kernel = Kernel(c_fn) #print(kernel.n_subsample()) form = Form(kernel, flag='right', dmu='ds') assembler = Assembler(form, mesh=mesh) assembler.assemble() QQ = assembler.assembled_forms()[0].aggregate_data()['array'] Q = np.array([assembler.get_scalar(i_sample=i) for i in np.arange(N + 1)]) t = np.linspace(0, T, N + 1) plt.plot(t, Q) plt.show() print(Q)
from function import Nodal, Explicit, Constant from mesh import QuadMesh from plot import Plot from solver import LinearSystem from diagnostics import Verbose import numpy as np """ Simulate the time dependent advection-diffusion-reaction system 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()
import scipy from scipy import linalg from scipy.sparse import linalg as spla import matplotlib.pyplot as plt from matplotlib import animation import time from diagnostics import Verbose # ============================================================================= # Parameters # ============================================================================= # # Flow # comment = Verbose() # permeability field phi = Constant(1) # porosity D = Constant(0.0252) # dispersivity K = Constant(1) # permeability # ============================================================================= # Mesh and Elements # ============================================================================= # Mesh comment.tic('initializing mesh') mesh = QuadMesh(resolution=(100, 100)) comment.toc() comment.tic('iterating over mesh cells')
def experiment06_sensitivity_stats(): """ Compute the sensitivities """ comment = Verbose() comment.comment('Computing statistics for the sensitivity dJ_dq') # # Computational mesh # mesh = Mesh1D(resolution=(100, )) mesh.mark_region('left', lambda x: np.abs(x) < 1e-10) mesh.mark_region('right', lambda x: np.abs(x - 1) < 1e-10) # # Element # Q1 = QuadFE(mesh.dim(), 'Q1') dQ1 = DofHandler(mesh, Q1) dQ1.distribute_dofs() n_dofs = dQ1.n_dofs() phi = Basis(dQ1, 'u') # # Covariance # cov = Covariance(dQ1, name='gaussian', parameters={'l': 0.05}) cov.compute_eig_decomp() lmd, V = cov.get_eig_decomp() d = len(lmd) # Fix coarse truncation level d0 = 10 # # Build Sparse Grid # grid = TasmanianSG.TasmanianSparseGrid() dimensions = d0 outputs = 1 depth = 4 type = 'level' rule = 'gauss-hermite' grid.makeGlobalGrid(dimensions, outputs, depth, type, rule) # Sample Points zzSG = grid.getPoints() zSG = np.sqrt(2) * zzSG # transform to N(0,1) # Quadrature Weights wSG = grid.getQuadratureWeights() wSG /= np.sqrt(np.pi)**d0 # normalize weights # Number of grid points n0 = grid.getNumPoints() comment.comment('Element DOFs: {0}'.format(n_dofs)) comment.comment('Sparse Grid Size: {0}'.format(n0)) # # Sample low dimensional input parameter # comment.tic('Sampling reference') q0 = sample_q0(V, lmd, d0, zSG.T) J0, u0 = sample_qoi(q0, dQ1, return_state=True) comment.toc() comment.tic('Sampling gradient') dJdq = np.zeros((n_dofs, n0)) for i in range(n0): # Sample input and state q = Nodal(data=q0[:, i], basis=phi) u = Nodal(data=u0[:, i], basis=phi) # Compute gradient using adjoint approach dJdq[:, i] = dJdq_adj(q, u) comment.toc() # Compute sparse grid mean and variance E_dJ = np.dot(dJdq, wSG) V_dJ = np.dot(dJdq**2, wSG) - E_dJ**2 E_dJ = Nodal(data=E_dJ, basis=phi) V_dJ = Nodal(data=V_dJ, basis=phi) fig, ax = plt.subplots(nrows=1, ncols=2) plot = Plot(quickview=False) ax[0] = plot.line(E_dJ, axis=ax[0]) ax[1] = plot.line(V_dJ, axis=ax[1]) plt.show()
def solve_system(self, b=None, factor=False): """ Compute the solution of the linear system Ax = b, subject to constraints "x=Cx+d" This method combines set_constraint_relation constrain_matrix constrain_rhs factor_matrix invert_matrix resolve_constraints """ comment = Verbose() # # Parse right hand side # if b is None: # # No b specified # assert self.get_rhs() is not None, 'No right hand side specified.' else: # # New b # self.set_rhs(b) # # Define constraint system # comment.tic('Setting constraint relation') if self.get_C() is None: self.set_constraint_relation() comment.toc() # # Apply constraints to A # comment.tic('Constraining matrix') if not self.matrix_is_constrained(): self.constrain_matrix() comment.toc() # # Apply constraints to b # comment.tic('constraining vector') if not self.rhs_is_constrained(): self.constrain_rhs() comment.toc() # # Factor matrix # if factor: if not self.matrix_is_factored(): self.factor_matrix() # # Solve the system # comment.tic('Inverting matrix') self.invert_matrix(factor=factor) comment.toc() # # Resolve constraints # comment.tic('Resolving constraints') self.resolve_constraints() comment.toc()
def sample_timings(): """ Test the amount of time it takes to compute a sample Record: assembly time per sample solve """ c = Verbose() sample_sizes = [10,100,1000,10000] cell_numbers = [2**i for i in range(11)] """ n_sample_sizes = len(sample_sizes) n_cell_numbers = len(cell_numbers) assembly_timings = np.empty((n_cell_numbers, n_sample_sizes)) solver_timings = np.empty((n_cell_numbers, n_sample_sizes)) for resolution, n_mesh in zip(cell_numbers, range(n_cell_numbers)): c.comment('Number of cells: %d'%(resolution)) mesh = Mesh1D(resolution=(resolution,)) 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') for n_samples, n_experiment in zip(sample_sizes, range(n_sample_sizes)): c.comment('Number of samples: %d'%(n_samples)) z = get_points(n_samples=n_samples) 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.comment('assembly') tic_assembly = time.time() assembler = Assembler(problems, mesh) assembler.assemble() assembly_timings[n_mesh,n_experiment] = time.time()-tic_assembly np.save('ex01a_assembly_timings', assembly_timings) 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.comment('solve') tic_solve = time.time() for n in range(n_samples): system.set_matrix(A[n]) system.set_rhs(b.copy()) system.solve_system() solver_timings[n_mesh,n_experiment] = (time.time()-tic_solve)/n_samples np.save('ex01a_solver_timings', solver_timings) """ solver_timings = np.load('ex01a_solver_timings.npy') assembly_timings = np.load('ex01a_assembly_timings.npy') plt.rc('text', usetex=True) plt.rc('font', family='serif', size=12) sample_sizes = np.array(sample_sizes) cell_numbers = np.array(cell_numbers) C,S = np.meshgrid(cell_numbers, sample_sizes) fig = plt.figure(figsize=(9,4)) ax = fig.add_subplot(121, projection='3d') ax.plot_surface(C,S, assembly_timings.T, alpha=0.5, ) ax.set_xlabel(r'Number of elements') ax.set_ylabel(r'Number of samples') ax.set_zlabel(r'Time', rotation=90) ax.set_title(r'Assembly timings') ax.view_init(azim=-120, elev=25) ax = fig.add_subplot(122, projection='3d') ax.plot_surface(C, S, solver_timings.T, alpha=0.5) ax.set_xlabel(r'Number of elements') ax.set_ylabel(r'Number of samples') ax.set_zlabel(r'Time', rotation=90) ax.set_title(r'Solver timings') ax.view_init(azim=-120, elev=25) plt.tight_layout() plt.savefig('ex01a_timings.pdf')