def plot_interior_displacement(self, soln): nxy = 40 nz = 40 d = 0 xs = np.linspace(-10, 10, nxy) zs = np.linspace(-0.1, -4.0, nz) X, Y, Z = np.meshgrid(xs, xs, zs) obs_pts = np.array([X.flatten(), Y.flatten(), Z.flatten()]).T.copy() t = Timer(output_fnc=logger.debug) interior_disp = -interior_integral( obs_pts, obs_pts, self.all_mesh, soln, 'elasticT3', 3, 8, self.k_params, self.float_type, fmm_params=None #[100, 3.0, 3000, 25] ).reshape((nxy, nxy, nz, 3)) t.report('eval %.2E interior pts' % obs_pts.shape[0]) for i in range(nz): plt.figure() plt.pcolor(xs, xs, interior_disp[:, :, i, d]) plt.colorbar() plt.title('at z = ' + ('%.3f' % zs[i]) + ' u' + ['x', 'y', 'z'][d]) plt.show()
def build_and_solve_T_regularized(data): timer = Timer(output_fnc=logger.debug) cs = build_constraints(data.surface_tris, data.fault_tris, data.all_mesh[0], data.all_mesh[1], data.gauss_z) timer.report("Constraints") T_op = RegularizedSparseIntegralOp( 6, 6, 6, 2, 5, 2.5, 'elasticRT3', 'elasticRT3', data.k_params, data.all_mesh[0], data.all_mesh[1], data.float_type, # farfield_op_type = TriToTriDirectFarfieldOp farfield_op_type=FMMFarfieldOp(mac=2.5, pts_per_cell=100, order=2)) import tectosaur.fmm.tsfmm as tsfmm tsfmm.report_interactions(T_op.farfield.fmm) timer.report("Integrals") mass_op = MultOp(MassOp(3, data.all_mesh[0], data.all_mesh[1]), 0.5) iop = SumOp([T_op, mass_op]) timer.report('mass op/sum op') soln = solve.iterative_solve(iop, cs, tol=1e-5) timer.report("Solve") return soln
def benchmark(): tct.logger.setLevel(logging.INFO) m = 1 n = 50 K = 'elasticRH3' m1 = mesh_gen.make_rect(n, n, [[-1, 0, 1], [-1, 0, -1], [1, 0, -1], [1, 0, 1]]) m2 = mesh_gen.make_rect(n, n, [[-3, 0, 1], [-3, 0, -1], [-2, 0, -1], [-2, 0, 1]]) x = np.random.rand(m2[1].shape[0] * 9) t = Timer() new_pts, new_tris = concat(m1, m2) n_obs_tris = m1[1].shape[0] sparse_op = RegularizedSparseIntegralOp( 8,8,8,2,5,2.5,K,K,[1.0, 0.25],new_pts,new_tris, np.float32,TriToTriDirectFarfieldOp, obs_subset = np.arange(0,n_obs_tris), src_subset = np.arange(n_obs_tris,new_tris.shape[0]) ) t.report('assemble matrix free') for i in range(m): y1 = sparse_op.dot(x) t.report('matrix free mv x10') fmm = FMMFarfieldOp(mac = 4.5, pts_per_cell = 300)( 2, K, [1.0, 0.25], new_pts, new_tris, np.float32, obs_subset = np.arange(0,n_obs_tris), src_subset = np.arange(n_obs_tris,new_tris.shape[0]) ) report_interactions(fmm.fmm_obj) t.report('setup fmm') y2 = fmm.dot(x) t.report('fmm mv x10') print(y1, y2)
def benchmark_vert_adj(): from tectosaur.util.timer import Timer import tectosaur.mesh.find_near_adj as find_near_adj from tectosaur.nearfield.pairs_integrator import PairsIntegrator kernel = 'elasticH3' params = [1.0, 0.25] float_type = np.float32 L = 5 nq_vert_adjacent = 7 nx = ny = int(2**L / np.sqrt(2)) t = Timer() pts, tris = mesh_gen.make_rect( nx, ny, [[-1, -1, 0], [-1, 1, 0], [1, 1, 0], [1, -1, 0]]) logger.debug('n_tris: ' + str(tris.shape[0])) t.report('make rect') close_or_touch_pairs = find_near_adj.find_close_or_touching( pts, tris, 1.25) nearfield_pairs, va, ea = find_near_adj.split_adjacent_close( close_or_touch_pairs, tris) t.report('find near') pairs_int = PairsIntegrator(kernel, params, float_type, 1, 1, pts, tris) t.report('setup integrator') va_mat_rot = pairs_int.vert_adj(nq_vert_adjacent, va) t.report('vert adj')
def build_and_solve_H_regularized(data): timer = Timer(output_fnc=logger.debug) cs = build_constraints(data.surface_tris, data.fault_tris, data.all_mesh[0], data.all_mesh[1], data.gauss_z) # For H, we need to constrain the edges of the surface to have 0 displacement. cs.extend(free_edge_constraints(data.surface_tris)) timer.report("Constraints") H_op = RegularizedSparseIntegralOp( 6, 6, 6, 2, 5, 2.5, 'elasticRH3', 'elasticRH3', data.k_params, data.all_mesh[0], data.all_mesh[1], data.float_type, # farfield_op_type = TriToTriDirectFarfieldOp farfield_op_type=FMMFarfieldOp(mac=2.5, pts_per_cell=100, order=2)) iop = SumOp([H_op]) timer.report("Integrals") soln = solve.iterative_solve(iop, cs, tol=1e-5) timer.report("Solve") return soln
def check_for_intersections(m): pts, tris = m close_or_touch_pairs = find_near_adj.find_close_or_touching(pts, tris, pts, tris, 2.0) nearfield_pairs, va, ea = find_near_adj.split_adjacent_close(close_or_touch_pairs, tris, tris) bad_pairs = [] t = Timer(output_fnc = logger.info) # Three situations: # 1) Nearfield pair is intersection bad_pairs.extend(check_for_intersections_nearfield(pts, tris, nearfield_pairs)) t.report('nearfield') # 2) Vertex adjacent pair actually intersects beyond just the vertex # We can test for this by moving the shared vertex short distance # along one of the edges of the first triangle. If there is still # an intersection, then the triangles intersect at locations besides # just the shared vertex. bad_pairs.extend(check_for_intersections_va(pts, tris, va)) t.report('va') # 3) Edge adjacent pair is actually coincident. <-- Easy! bad_pairs.extend(check_for_intersections_ea(pts, tris, ea)) t.report('ea') return np.array(bad_pairs, dtype = np.int64)
def main(): #python examples/okada.py 31 7 5.0 0.0 0.0 T #python examples/okada.py 31 7 5.0 0.0 0.0 H #python examples/okada.py 31 7 5.0 -0.5 -1.0 T #python examples/okada.py 31 7 5.0 -0.5 -1.0 H t = Timer(output_fnc=logger.info) obj = Okada(int(sys.argv[1]), n_fault=int(sys.argv[2]), surface_w=float(sys.argv[3]), top_depth=float(sys.argv[4]), gauss_z=float(sys.argv[5]), verbose=True) # obj.plot_mesh() if sys.argv[6] == 'T': soln = obj.run(build_and_solve=build_and_solve_T_regularized) else: soln = obj.run(build_and_solve=build_and_solve_H_regularized) t.report('tectosaur') okada_soln = obj.okada_exact() # np.save('okada_soln_for_plot.npy', [obj.all_mesh, obj.surface_tris, obj.fault_tris, soln, okada_soln]) t.report('okada') obj.xsec_plot([soln], okada_soln) # obj.plot_interior_displacement(soln) obj.print_error(soln, okada_soln) t.report('check')
def __init__(self, m, cfg): cfg = calc_derived_constants(cfg) self.cfg = cfg if not 'Timer' in self.cfg or self.cfg['Timer'] is None: self.cfg['Timer'] = lambda: Timer(output_fnc = lambda x: None) self.setup_mesh(m) self.setup_edge_bcs()
def make_meshes(surf_w, fault_L, top_depth, n_surf, n_fault): t = Timer(output_fnc=logger.debug) surface = make_free_surface(surf_w, n_surf) t.report('make free surface') fault = make_fault(fault_L, top_depth, n_fault) t.report('make fault') all_mesh = mesh_modify.concat(surface, fault) t.report('concat meshes') surface_tris = all_mesh[1][:surface[1].shape[0]] fault_tris = all_mesh[1][surface[1].shape[0]:] return all_mesh, surface_tris, fault_tris
def compile_module(tmpl, tmpl_name, save_code, tmpl_args): if tmpl_args is None: tmpl_args = dict() code = template_with_mako(tmpl, tmpl_args) t = Timer(output_fnc = logger.debug) logger.debug('start compiling ' + tmpl_name) if save_code: save_code_to_tmp(code) module_info = dict() module_info['tmpl_args'] = tmpl_args module_info['module'] = compile(code) t.report('compile') gpu_module[tmpl_name] = gpu_module.get(tmpl_name, []) + [module_info] return module_info['module']
def __init__(self, m, cfg): #, which_side): cfg = calc_derived_constants(cfg) # self.which_side = which_side self.cfg = cfg self.cfg['Timer'] = self.cfg.get( 'Timer', lambda: Timer(output_fnc=lambda x: None)) self.setup_mesh(m) self.setup_edge_bcs() self.disp_deficit = np.zeros(m.n_dofs('surf')) self.old_slip_deficit = np.zeros(m.n_dofs('fault'))
def benchmark_adjacency(): from tectosaur.mesh.mesh_gen import make_rect from tectosaur.util.timer import Timer L = 8 nx = ny = int(2**L / np.sqrt(2)) t = Timer() m = make_rect(nx, ny, [[-1, -1, 0], [-1, 1, 0], [1, 1, 0], [1, -1, 0]]) logger.debug('n_tris: ' + str(m[1].shape[0])) t.report('make') close_pairs = find_close_or_touching(m[0], m[1], 1.25) t.report('close or touching') close, va, ea = split_adjacent_close(close_pairs, m[1]) t.report('find adj')
def displacement_bie(sm, pr, m, input, solve_for, op_type): selfop = MassOp(3, m[0], m[1]) t = Timer() Uop = op_type([], 1, 1, 5, 3, 4, 4.0, 'U', sm, pr, m[0], m[1], use_tables=True) Uop2 = SparseIntegralOp([], 1, 1, 5, 3, 4, 4.0, 'U', sm, pr, m[0], m[1], use_tables=True) v = np.random.rand(Uop2.shape[1]) a = Uop2.dot(v) b = Uop.dot(v) import ipdb ipdb.set_trace() t.report('U') Top = SparseIntegralOp([], 1, 1, 5, 3, 4, 4.0, 'T', sm, pr, m[0], m[1], use_tables=True) t.report('T') if solve_for is 't': lhs = Uop rhs = Top.dot(input) + selfop.dot(input) else: lhs = SumOp([Top, selfop]) rhs = Uop.dot(input) return lhs, rhs
def test_c2e(request): n = 10 m1 = mesh_gen.make_rect(n, n, [[-1, 0, 1], [-1, 0, -1], [1, 0, -1], [1, 0, 1]]) m2 = mesh_gen.make_rect(n, n, [[-3, 0, 1], [-3, 0, -1], [-2, 0, -1], [-2, 0, 1]]) K = 'elasticRH3' t = Timer() cfg = make_config(K, [1.0, 0.25], 1.1, 2.5, 2, np.float64, treecode = True) tree1 = make_tree(m1, cfg, 100) tree2 = make_tree(m2, cfg, 100) print(len(tree1.nodes)) fmm = FMM(tree1, m1, tree2, m2, cfg) u2e_ops = [] for n in tree2.nodes: UT, eig, V = fmm.u2e_ops alpha = cfg.alpha R = n.bounds.R inv_eig = R * eig / ((R * eig) ** 2 + alpha ** 2) u2e_ops.append((V * inv_eig).dot(UT)) return np.array(u2e_ops)
def traction_bie(sm, pr, m, input, solve_for, op_type): # Why am I not able to get the same accuracy with the traction BIE as I am # with the displacement BIE? Is there something wrong with how I calculate things? # Maybe with the traction inputs? # TODO: MAYBE THIS IS RELATED TO HIGH ERROR IN THE H OPERATOR? selfop = MassOp(3, m[0], m[1]) selfop.mat *= -1 nqv = 15 t = Timer() Hop = SparseIntegralOp([], 1, 1, (nqv, nqv * 2, nqv), 3, 6, 4.0, 'H', sm, pr, m[0], m[1], use_tables=True) t.report('H') Aop = SparseIntegralOp([], 1, 1, 7, 3, 6, 4.0, 'A', sm, pr, m[0], m[1], use_tables=True) t.report('A') if solve_for is 't': lhs = SumOp([Aop, selfop]) rhs = Hop.dot(input) else: lhs = Hop rhs = Aop.dot(input) + selfop.dot(input) return lhs, rhs
def build_c2e(tree, check_r, equiv_r, cfg): t = Timer() assembler = FarfieldTriMatrix(cfg.K.name, cfg.params, 4, np.float64) check_surf = inscribe_surf(Ball(center = (0,0,0), R = 1), check_r, cfg.surf) equiv_surf = inscribe_surf(Ball(center = (0,0,0), R = 1), equiv_r, cfg.surf) new_pts, new_tris = concat(check_surf, equiv_surf) n_check_tris = check_surf[1].shape[0] check_tris = new_tris[:n_check_tris] equiv_tris = new_tris[n_check_tris:] mat = assembler.assemble(new_pts, check_tris, equiv_tris) nrows = mat.shape[0] * 9 ncols = mat.shape[3] * 9 equiv_to_check = mat.reshape((nrows, ncols)) t.report('build e2cs') U, eig, VT = np.linalg.svd(equiv_to_check) out = (U.T.copy(), eig.copy(), VT.T.copy()) t.report('svd') return out
async def farfield_dot(self, v): t = Timer(output_fnc=logger.debug) logger.debug("start farfield_dot") out = await self.farfield.async_dot(v) t.report('farfield_dot') return out
async def nearfield_dot(self, v): t = Timer(output_fnc=logger.debug) logger.debug("start nearfield_dot") out = self.nearfield.dot(v) t.report("nearfield_dot") return out
def benchmark_bsrmv(): from tectosaur.util.timer import Timer float_type = np.float32 blocksize = 9 nb = 100000 nnzbs = 5000000 t = Timer() rows = np.random.randint(nb, size=(nnzbs)) cols = np.random.randint(nb, size=(nnzbs)) data = np.ones((nnzbs, blocksize, blocksize)) x = np.random.rand(nb * blocksize).astype(float_type) t.report('random') mat_bcoo = sparse.BCOOMatrix(rows, cols, data, (nb * blocksize, nb * blocksize)) t.report('make bcoo') mat_bsr = mat_bcoo.to_bsr() t.report('make bsr') mat_sp = mat_bsr.to_scipy() t.report('make scipy') for i in range(3): y = mat_bsr.dot(x) t.report('bsr mv') y2 = mat_bcoo.dot(x) t.report('bcoo mv') correct = mat_sp.dot(x) t.report('scipy mv') np.testing.assert_almost_equal(y, correct, 2) np.testing.assert_almost_equal(y2, correct, 2)
def __init__(self, pts, tris, obs_subset, src_subset, nq_coincident, nq_edge_adj, nq_vert_adjacent, nq_far, nq_near, near_threshold, K_near_name, K_far_name, params, float_type): n_obs_dofs = obs_subset.shape[0] * 9 n_src_dofs = src_subset.shape[0] * 9 self.shape = (n_obs_dofs, n_src_dofs) timer = Timer(output_fnc=logger.debug, tabs=1) pairs_int = PairsIntegrator(K_near_name, params, float_type, nq_far, nq_near, pts, tris) correction_pairs_int = PairsIntegrator(K_far_name, params, float_type, nq_far, nq_near, pts, tris) timer.report('setup pairs integrator') co_tris = np.intersect1d(obs_subset, src_subset) co_indices = np.array([co_tris, co_tris]).T.copy() co_dofs = to_dof_space(co_indices, obs_subset, src_subset) co_mat = pairs_int.coincident(nq_coincident, co_indices) timer.report("Coincident") co_mat_correction = correction_pairs_int.correction(co_indices, True) timer.report("Coincident correction") close_or_touch_pairs = find_near_adj.find_close_or_touching( pts, tris[obs_subset], pts, tris[src_subset], near_threshold) nearfield_pairs_dofs, va_dofs, ea_dofs = find_near_adj.split_adjacent_close( close_or_touch_pairs, tris[obs_subset], tris[src_subset]) nearfield_pairs = to_tri_space(nearfield_pairs_dofs, obs_subset, src_subset) va = to_tri_space(va_dofs, obs_subset, src_subset) va = np.hstack((va, np.zeros((va.shape[0], 1)))) ea = resolve_ea_rotation(tris, to_tri_space(ea_dofs, obs_subset, src_subset)) timer.report("Find nearfield/adjacency") ea_mat_rot = pairs_int.edge_adj(nq_edge_adj, ea) timer.report("Edge adjacent") if ea.shape[0] == 0: ea_mat_correction = 0 * ea_mat_rot else: ea_mat_correction = correction_pairs_int.correction( ea[:, :2], False) timer.report("Edge adjacent correction") va_mat_rot = pairs_int.vert_adj(nq_vert_adjacent, va) timer.report("Vert adjacent") va_mat_correction = correction_pairs_int.correction(va[:, :2], False) timer.report("Vert adjacent correction") nearfield_mat = pairs_int.nearfield(nearfield_pairs) timer.report("Nearfield") nearfield_correction = correction_pairs_int.correction( nearfield_pairs, False) timer.report("Nearfield correction") self.mat = build_nearfield( self.shape, (co_mat - co_mat_correction, co_dofs), (ea_mat_rot - ea_mat_correction, ea_dofs[:, :2]), (va_mat_rot - va_mat_correction, va_dofs[:, :2]), (nearfield_mat - nearfield_correction, nearfield_pairs_dofs)) timer.report("Assemble matrix") self.mat_no_correction = build_nearfield( self.shape, (co_mat, co_dofs), (ea_mat_rot, ea_dofs[:, :2]), (va_mat_rot, va_dofs[:, :2]), (nearfield_mat, nearfield_pairs_dofs), ) timer.report("Assemble uncorrected matrix")
def test_tri_fmm_full(): np.random.seed(100) n = 40 K = 'elasticRA3' m1 = mesh_gen.make_rect(n, n, [[-1, 0, 1], [-1, 0, -1], [1, 0, -1], [1, 0, 1]]) m2 = mesh_gen.make_rect(n, n, [[-3, 0, 1], [-3, 0, -1], [-2, 0, -1], [-2, 0, 1]]) x = np.random.rand(m2[1].shape[0] * 9) t = Timer() cfg = make_config(K, [1.0, 0.25], 1.1, 4.5, 2, np.float32) tree1 = make_tree(m1, cfg, 100) tree2 = make_tree(m2, cfg, 100) print('n_nodes: ', str(len(tree1.nodes))) fmm = FMM(tree1, m1, tree2, m2, cfg) report_interactions(fmm) fmmeval = FMMEvaluator(fmm) t.report('setup fmm') full = op(m1, m2, K = K) t.report('setup dense') t.report('gen x') y1 = full.dot(x) t.report('dense mv') x_tree = fmm.to_tree(x) import taskloaf as tsk async def call_fmm(tsk_w): return (await fmmeval.eval(tsk_w, x_tree)) fmm_res = tsk.run(call_fmm) y2 = fmm.to_orig(fmm_res) t.report('fmm mv') np.testing.assert_almost_equal(y1, y2)
def mv(v): t = Timer(output_fnc = logger.debug) mv.iter += 1 out = cm.T.dot(iop.dot(cm.dot(v))) t.report('iteration # ' + str(mv.iter)) return out
def runner(solve_for, use_bie, refine, use_fmm): if use_fmm == 'fmm': op_type = FMMIntegralOp else: op_type = SparseIntegralOp a = 1.0 b = 2.0 sm = 1.0 pr = 0.25 pa = 3.0 pb = 1.0 center = [0, 0, 0] ua, ub = correct_displacement(a, b, pa, -pb, sm, pr, np.array([a, b])) print(correct_displacement(a, b, pa, -pb, sm, pr, np.array([a, b]))) print(correct_displacement(a, b, -pa, -pb, sm, pr, np.array([a, b]))) print(correct_displacement(a, b, -pa, pb, sm, pr, np.array([a, b]))) print(correct_displacement(a, b, pa, pb, sm, pr, np.array([a, b]))) t = Timer() m_inner = mesh.make_sphere(center, a, refine) m_outer = mesh.make_sphere(center, b, refine) m_outer = mesh.flip_normals(m_outer) t.report('make meshes') m = mesh.concat(m_inner, m_outer) t.report('concat meshes') print(m[1].shape) n_inner = m_inner[1].shape[0] inner_tris = m[1][:n_inner] outer_tris = m[1][n_inner:] tri_pts = m[0][m[1]] # mesh.plot_mesh3d(*m) cs = build_constraints(inner_tris, outer_tris, m, solve_for) t.report('build constraints') # solving: u(x) + int(T*u) = int(U*t) # values in radial direction because the sphere is centered at (0,0,0) r = tri_pts - np.array(center)[np.newaxis, np.newaxis, :] input_nd = r / np.linalg.norm(r, axis=2)[:, :, np.newaxis] if solve_for is 't': input_nd[:n_inner] *= ua input_nd[n_inner:] *= ub else: input_nd[:n_inner] *= pa input_nd[n_inner:] *= pb input = input_nd.reshape(-1) if use_bie == 'u': lhs, rhs = displacement_bie(sm, pr, m, input, solve_for, op_type) elif use_bie == 't': lhs, rhs = traction_bie(sm, pr, m, input, solve_for, op_type) # soln = direct_solve(lhs, cs, rhs) soln = iterative_solve(lhs, cs, rhs) soln = np.array(soln).reshape((int(lhs.shape[0] / 9), 3, 3)) soln_mag = np.sqrt(np.sum(soln**2, axis=2)) inner_soln_mag = soln_mag[:n_inner] outer_soln_mag = soln_mag[n_inner:] mean_inner = np.mean(inner_soln_mag) mean_outer = np.mean(outer_soln_mag) print(np.std(inner_soln_mag)) print(np.std(outer_soln_mag)) if solve_for is 't': print(mean_inner, pa) print(mean_outer, pb) np.testing.assert_almost_equal(mean_inner, pa, 1) np.testing.assert_almost_equal(mean_outer, pb, 1) else: print(mean_inner, ua) print(mean_outer, ub) np.testing.assert_almost_equal(mean_inner, ua, 1) np.testing.assert_almost_equal(mean_outer, ub, 1)
def iterative_solve(iop, constraints, rhs=None, tol=1e-8): timer = Timer(output_fnc=logger.debug) cm, c_rhs, _ = build_constraint_matrix(constraints, iop.shape[1]) timer.report('Build constraint matrix') cm = cm.tocsr() timer.report('constraint matrix tocsr') cmT = cm.T if rhs is None: rhs_constrained = cmT.dot(-iop.dot(c_rhs)) else: rhs_constrained = cmT.dot(rhs - iop.dot(c_rhs)) timer.report('constrain rhs') n = rhs_constrained.shape[0] iter = [0] def mv(v): iter[0] += 1 logger.debug('iteration # ' + str(iter[0])) return cmT.dot(iop.dot(cm.dot(v))) # P = sparse.linalg.spilu(cmT.dot(iop.nearfield_no_correction_dot(cm))) timer.report("Build preconditioner") def prec_f(x): # return P.solve(x) return x M = sparse.linalg.LinearOperator((n, n), matvec=prec_f) A = sparse.linalg.LinearOperator((n, n), matvec=mv) def report_res(R): logger.debug('residual: ' + str(R)) pass soln = sparse.linalg.gmres(A, rhs_constrained, M=M, tol=tol, callback=report_res, restart=200) timer.report("GMRES") return cm.dot(soln[0]) + c_rhs