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 test_tri_fmm_p2p(): np.random.seed(100) 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' cfg = make_config(K, [1.0, 0.25], 1.1, 2.5, 2, np.float32, treecode = True, force_order = 1000000) tree1 = make_tree(m1, cfg, 10) tree2 = make_tree(m2, cfg, 10) print('n_nodes: ', str(len(tree1.nodes))) fmm = FMM(tree1, m1, tree2, m2, cfg) fmmeval = FMMEvaluator(fmm) full = op(m1, m2, K = K) x = np.random.rand(full.shape[1]) y1 = full.dot(x) x_tree = fmm.to_tree(x) import taskloaf as tsk async def call_fmm(tsk_w): return (await fmmeval.eval(tsk_w, x_tree, return_all_intermediates = True)) fmm_res, m_check, multipoles, l_check, locals = tsk.run(call_fmm) y2 = fmm.to_orig(fmm_res) np.testing.assert_almost_equal(y1, y2)
def test_tri_fmm_m2p_single(): np.random.seed(100) 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, [[-10, 0, 1], [-10, 0, -1], [-8, 0, -1], [-8, 0, 1]]) K = 'elasticRH3' cfg = make_config(K, [1.0, 0.25], 1.1, 2.5, 2, np.float32, treecode = True, force_order = 1) tree1 = make_tree(m1, cfg, 1000) tree2 = make_tree(m2, cfg, 1000) src_R = tree2.nodes[0].bounds.R center = tree2.nodes[0].bounds.center R_outer = cfg.outer_r R_inner = cfg.inner_r scaling = 1.0 check_sphere = mesh_gen.make_sphere(center, scaling * R_outer * src_R, 2) equiv_sphere = mesh_gen.make_sphere(center, scaling * R_inner * src_R, 2) src_tri_idxs = tree2.orig_idxs src_tris = m2[1][src_tri_idxs] obs_tri_idxs = tree1.orig_idxs obs_tris = m1[1][obs_tri_idxs] p2c = op(check_sphere, (m2[0], src_tris), K) e2c = op(check_sphere, equiv_sphere, K, nq = 4) c2e = reg_lstsq_inverse(e2c, cfg.alpha) e2p = op((m1[0], obs_tris), equiv_sphere, K) p2p = op((m1[0], obs_tris), (m2[0], src_tris), K) fmm_mat = e2p.dot(c2e.dot(p2c)) full = op(m1, m2, K = K) fmm = FMM(tree1, m1, tree2, m2, cfg) fmmeval = FMMEvaluator(fmm) x = np.random.rand(full.shape[1]) y1 = full.dot(x) x_tree = fmm.to_tree(x) import taskloaf as tsk async def call_fmm(tsk_w): return (await fmmeval.eval(tsk_w, x_tree, return_all_intermediates = True)) fmm_res, m_check, multipoles, l_check, locals = tsk.run(call_fmm) y2 = fmm.to_orig(fmm_res) m_check2 = p2c.dot(x_tree) np.testing.assert_almost_equal(m_check, m_check2) np.testing.assert_almost_equal(multipoles, c2e.dot(m_check)) np.testing.assert_almost_equal(fmm_res, e2p.dot(multipoles), 4) np.testing.assert_almost_equal(y1, y2, 5)
def test_full_integral_op_nofmm_fast(request): m = mesh_gen.make_rect(5, 5, [[-1, 0, 1], [-1, 0, -1], [1, 0, -1], [1, 0, 1]]) dense_op = dense_integral_op.DenseIntegralOp(5, 3, 3, 2.0, 'elasticU3', [1.0, 0.25], m[0], m[1], float_type) return dense_op.mat
def test_interior_nearfield(request): np.random.seed(10) corners = [[-1, -1, 0], [1, -1, 0], [1, 1, 0], [-1, 1, 0]] src_mesh = mesh_gen.make_rect(30, 30, corners) xs = np.linspace(-3, 3, 50) X, Z = np.meshgrid(xs, xs) Y = np.ones_like(X) * 0.0 obs_pts = np.array([e.flatten() for e in [X, Y, Z]]).T.copy() obs_ns = np.zeros(obs_pts.shape) obs_ns[:, 2] = 1.0 input = np.zeros(src_mesh[1].shape[0] * 9) input.reshape((-1, 3))[:, 0] = 1.0 K = 'elasticT3' params = [1.0, 0.25] op = tct.InteriorOp(obs_pts, obs_ns, src_mesh, K, 4, params, float_type) out = op.dot(input) # import matplotlib.pyplot as plt # for d in range(3): # plt.subplot(1, 3, d + 1) # plt.contourf(X, Z, out.reshape((-1,3))[:,d].reshape(X.shape)) # plt.colorbar() # plt.show() return out
def benchmark_nearfield_construction(): corners = [[-1, -1, 0], [1, -1, 0], [1, 1, 0], [-1, 1, 0]] near_threshold = 1.5 n = 80 pts, tris = mesh_gen.make_rect(n, n, corners) n = nearfield_op.NearfieldIntegralOp(1, 1, 1, 2.0, 'elasticU3', [1.0, 0.25], pts, tris)
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 make_meshes(n_m = 8, sep = 2, w = 1, n_m2 = None): if n_m2 is None: n_m2 = n_m m1 = make_rect(n_m, n_m, [ [-w, 0, w], [-w, 0, -w], [w, 0, -w], [w, 0, w] ]) m2 = make_rect(n_m2, n_m2, [ [-w, sep, w], [-w, sep, -w], [w, sep, -w], [w, sep, w] ]) m = concat(m1, m2) surf1_idxs = np.arange(m1[1].shape[0]) surf2_idxs = (surf1_idxs[-1] + 1) + surf1_idxs return m, surf1_idxs, surf2_idxs
def test_flip_normals(): m = make_rect(2, 2, [[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]]) m_flip = flip_normals(m) for i in range(m[1].shape[0]): n1 = tri_normal(m[0][m[1][i, :]]) n2 = tri_normal(m_flip[0][m_flip[1][i, :]]) np.testing.assert_almost_equal(n1, -n2)
def benchmark_find_nearfield(): corners = [[-1, -1, 0], [1, -1, 0], [1, 1, 0], [-1, 1, 0]] nx = ny = 707 pts, tris = mesh_gen.make_rect(nx, ny, corners) print('n_tris: ' + str(tris.shape[0])) # va, ea = adjacency.find_adjacents(tris) near_pairs = find_close_or_touching(pts, tris, 1.25)
def test_cpp_pt_average(): n = 5 corners = [[-1, -1, 0], [-1, 1, 0], [1, 1, 0], [1, -1, 0]] m = mesh_gen.make_rect(n, n, corners) x = np.random.rand(m[1].shape[0] * 3) y1 = pt_average_py(m[0], m[1], x) y2 = pt_average_cpp(m[0], m[1], x) np.testing.assert_almost_equal(y1, y2)
def test_find_nearfield_real(request): n = 20 pts, tris = mesh_gen.make_rect( n, n, [[-1, -1, 0], [1, -1, 0], [1, 1, 0], [-1, 1, 0]]) va, ea = find_adjacents(tris) close_pairs = find_close_or_touching(pts, tris, pts, tris, 1.25) close, va, ea = split_adjacent_close(close_pairs, tris, tris) return close[np.lexsort([close[:, 1], close[:, 0]], axis=0)].flatten()
def test_mass_op(): m = mesh_gen.make_rect(2, 2, [[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]]) op = mass_op.MassOp(3, m[0], m[1]) exact00 = quad.quadrature( lambda x: (1 - x[:, 0] - x[:, 1]) * (1 - x[:, 0] - x[:, 1]), quad.gauss2d_tri(10)) exact03 = quad.quadrature(lambda x: (1 - x[:, 0] - x[:, 1]) * x[:, 0], quad.gauss2d_tri(10)) np.testing.assert_almost_equal(op.mat[0, 0], exact00) np.testing.assert_almost_equal(op.mat[0, 3], exact03)
def test_mass_tensor_dim(): m = mesh_gen.make_rect(2, 2, [[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]]) op1 = mass_op.MassOp(3, m[0], m[1], tensor_dim=1) op3 = mass_op.MassOp(3, m[0], m[1]) x = np.random.rand(op3.shape[1]).reshape((-1, 3, 3)) x[:, :, 1] = 0 x[:, :, 2] = 0 y3 = op3.dot(x.flatten()) y1 = op1.dot(x[:, :, 0].flatten()) np.testing.assert_almost_equal(y1, y3.reshape((-1, 3, 3))[:, :, 0].flatten())
def test_nearfield(): corners = [[-1, -1, 0], [1, -1, 0], [1, 1, 0], [-1, 1, 0]] pts, tris = mesh_gen.make_rect(3, 3, corners) assert (tris.shape[0] == 8) close_pairs = find_close_or_touching(pts, tris, pts, tris, 1.0) close, va, ea = split_adjacent_close(close_pairs, tris, tris) check_for = [(0, 5), (0, 6), (0, 3), (1, 7), (2, 7), (3, 0), (4, 7), (5, 0), (6, 0), (7, 2), (7, 1), (7, 4)] assert (len(close) == len(check_for)) for pair in check_for: assert (pair in close)
def test_find_close_notself(request): corners = [[-1, -1, 0], [1, -1, 0], [1, 1, 0], [-1, 1, 0]] m = mesh_gen.make_rect(2, 2, corners) threshold = 1.0 obs_pts = np.array( [0.5 * np.ones(5), 0.5 * np.ones(5), np.linspace(0, 2, 5)]).T.copy() out = fast_find_nearfield.get_nearfield(obs_pts, np.zeros(obs_pts.shape[0]), *get_tri_centroids_rs(*m), threshold, 50) return out
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 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 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 test_interior(request): np.random.seed(10) corners = [[-1, -1, 0], [1, -1, 0], [1, 1, 0], [-1, 1, 0]] pts, tris = mesh_gen.make_rect(3, 3, corners) obs_pts = pts.copy() obs_pts[:, 2] += 1.0 obs_ns = np.random.rand(*obs_pts.shape) obs_ns /= np.linalg.norm(obs_ns, axis=1)[:, np.newaxis] input = np.ones(tris.shape[0] * 9) K = 'elasticH3' params = [1.0, 0.25] op = tct.InteriorOp(obs_pts, obs_ns, (pts, tris), K, 4, params, float_type) return op.dot(input)
def benchmark_build_constraint_matrix(): from tectosaur.util.timer import timer from tectosaur.constraints import fast_constraints import scipy.sparse t = Timer() corners = [[-1.0, -1.0, 0], [-1.0, 1.0, 0], [1.0, 1.0, 0], [1.0, -1.0, 0]] n = 100 m = mesh_gen.make_rect(n, n, corners) t.report('make mesh') cs = continuity_constraints(m[1], np.array([]), m[0]) t.report('make constraints') n_total_dofs = m[1].size * 3 rows, cols, vals, rhs, n_unique_cs = fast_constraints.build_constraint_matrix( cs, n_total_dofs) t.report('build matrix') n_rows = n_total_dofs n_cols = n_total_dofs - n_unique_cs cm = scipy.sparse.csr_matrix((vals, (rows, cols)), shape=(n_rows, n_cols)) t.report('to csr')
def build_subset_mesh(): n = 10 m = mesh_gen.make_rect(n, n, [[-1, 0, 1], [-1, 0, -1], [1, 0, -1], [1, 0, 1]]) n_tris = m[1].shape[0] overlap = n_tris // 2 obs_subset = np.arange(n_tris // 2) src_subset = np.arange(n_tris // 2 - overlap, n_tris) obs_range = [0, (obs_subset[-1] + 1) * 9] src_range = [src_subset[0] * 9, (src_subset[-1] + 1) * 9] # import matplotlib.pyplot as plt # plt.figure() # plt.triplot(m[0][:,0], m[0][:,2], m[1], 'k-') # plt.figure() # plt.triplot(m[0][:,0], m[0][:,2], m[1][obs_subset], 'b-') # plt.triplot(m[0][:,0], m[0][:,2], m[1][src_subset], 'r-') # plt.show() return m, obs_subset, src_subset, obs_range, src_range
def full_integral_op_tester(k, use_fmm, n=5): pts = np.array([[0, 0, 0], [1, 1, 0], [0, 1, 1], [0, 0, 2]]) tris = np.array([[0, 1, 2], [2, 1, 3]]) rect_mesh = mesh_gen.make_rect( n, n, [[-1, 0, 1], [-1, 0, -1], [1, 0, -1], [1, 0, 1]]) out = np.zeros(1) params = [1.0, 0.25] for m in [(pts, tris), rect_mesh]: dense_op = dense_integral_op.DenseIntegralOp(5, 3, 3, 2.0, k, params, m[0], m[1], float_type) x = np.ones(dense_op.shape[1]) dense_res = dense_op.dot(x) if use_fmm: farfield_op_type = PtToPtFMMFarfieldOp(100, 3.0, 300) else: farfield_op_type = PtToPtDirectFarfieldOp sparse_op = sparse_integral_op.SparseIntegralOp( 5, 3, 3, 2.0, k, params, m[0], m[1], float_type, farfield_op_type) sparse_res = sparse_op.dot(x) assert (np.max(np.abs(sparse_res - dense_res)) / np.mean(np.abs(dense_res)) < 5e-4) out = np.hstack((out, sparse_res)) return out
def test_close_or_touching(request): n = 20 pts, tris = mesh_gen.make_rect( n, n, [[-1, -1, 0], [1, -1, 0], [1, 1, 0], [-1, 1, 0]]) near_pairs = find_close_or_touching(pts, tris, pts, tris, 1.25) return np.sort(near_pairs, axis=0)
def make_free_surface(w, n): corners = [[-w, -w, 0], [-w, w, 0], [w, w, 0], [w, -w, 0]] return mesh_gen.make_rect(n, n, corners)
def make_fault(L, top_depth, n_fault): m = mesh_gen.make_rect(n_fault, n_fault, [[-L, 0, top_depth], [-L, 0, top_depth - 1], [L, 0, top_depth - 1], [L, 0, top_depth]]) return m
def simple_rect_mesh(n): corners = [[-1.0, -1.0, 0], [-1.0, 1.0, 0], [1.0, 1.0, 0], [1.0, -1.0, 0]] return mesh_gen.make_rect(n, n, corners)
def test_remove_duplicates(): surface1 = make_rect(2, 2, [[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]]) surface2 = make_rect(2, 2, [[0, 0, 0], [-1, 0, 0], [-1, 1, 0], [0, 1, 0]]) m_f = concat(surface1, surface2) assert (m_f[0].shape[0] == 6) assert (m_f[1].shape[0] == 4)
import numpy as np import matplotlib.pyplot as plt import tectosaur.mesh.mesh_gen as mesh_gen import tectosaur.mesh.modify as mesh_modify from tectosaur.ops.dense_integral_op import DenseIntegralOp from tectosaur.ops.mass_op import MassOp n, w = 10, 10.0 surf = mesh_gen.make_rect(n, n, [[-w, -w, 0], [-w, w, 0], [w, w, 0], [w, -w, 0]]) n_fault, L, top_depth = 9, 1.0, -1.0 fault = mesh_gen.make_rect(n_fault, n_fault, [[-L, 0, top_depth], [-L, 0, top_depth - 1], [L, 0, top_depth - 1], [L, 0, top_depth]]) all_mesh = mesh_modify.concat(surf, fault) surface_subset = np.arange(surf[1].shape[0]) fault_subset = np.arange(surf[1].shape[0], all_mesh[1].shape[0]) all_set = np.arange(all_mesh[1].shape[0]) A_set, B_set = all_set, all_set #fault_subset pairs = [('elasticU3', 'elasticU3', False), ('elasticT3', 'elasticA3', True), ('elasticH3', 'elasticH3', False)] for K1, K2, M in pairs: opA = DenseIntegralOp(7, 4, 3, 2.0, K1, [1.0, 0.25], all_mesh[0], all_mesh[1], np.float32,