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) system.add_dirichlet_constraint('B', uB) system.add_dirichlet_constraint('perimeter', 0) system.solve_system() ua = system.get_solution() print('done') plot = Plot() plot.wire(ua)
# 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() # ============================================================================= # System Parameters # ============================================================================= # Target y_target = Nodal(f=lambda x: 3 - 4 * (x[:, 0] - 1)**2, dim=1, dofhandler=dh) y_data = y_target.data()
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
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) system.set_matrix(sp.csr_matrix(A, copy=True)) system.set_rhs(b) system.solve_system() print('A after constraint\n', system.get_matrix().toarray()) print('column records\n', system.column_records) print('rhs after constraint\n', system.get_rhs().toarray()) y = system.get_solution() plot = Plot() plot.line(y)
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
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) # Apply Dirichlet Constraints (state) state.add_dirichlet_constraint('left',1) state.add_dirichlet_constraint('right',0) state.set_constraint_relation() # Apply Dirichlet Constraints (adjoint) adjoint.add_dirichlet_constraint('left',0) adjoint.add_dirichlet_constraint('right',0) adjoint.set_constraint_relation() # Initial guess x = np.array([-520.02634251, -378.1222316, 1182.85592199, 273.54809863, 198.63821595, 171.72602221])[:,None]
# ============================================================================= 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) A = assembler.af[0]['bilinear'].get_matrix() M = assembler.af[1]['bilinear'].get_matrix() # ============================================================================= # Define State and Adjoint Systems # ============================================================================= state = LS(phi) #, A=sp.csr_matrix(A, copy=True)) adjoint = LS(phi) #, A=sp.csr_matrix(A, copy=True)) # Apply Dirichlet Constraints (state) state.add_dirichlet_constraint('left', 1) state.add_dirichlet_constraint('right', 0) state.set_constraint_relation() # Apply Dirichlet Constraints (adjoint) adjoint.add_dirichlet_constraint('left', 0) adjoint.add_dirichlet_constraint('right', 0) adjoint.set_constraint_relation() # ============================================================================= # Optimization # =============================================================================
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 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