def fmm_tester(K_name, far_only=False, one_cell=False): np.random.seed(123987) for order in [8]: #range(2, 13): float_type = np.float64 quad_order = 2 K_params = np.array([1.0, 0.25]) n = 20 offset = 0.0 if far_only: offset = 6.0 if far_only and one_cell: offset = 9.0 corners = [[-1.0, -1.0, 0], [-1.0, 1.0, 0], [1.0, 1.0, 0], [1.0, -1.0, 0]] m_src = tct.make_rect(n, n, corners) v = np.random.rand(m_src[1].shape[0] * 9).astype(float_type) m_obs = tct.make_rect(n, n, corners) m_obs[0][:, 0] += offset full_m = concat(m_src, m_obs) src_subset = np.arange(0, m_src[1].shape[0]) obs_subset = np.arange(0, m_obs[1].shape[0]) + m_src[1].shape[0] op = tct.TriToTriDirectFarfieldOp(quad_order, K_name, K_params, full_m[0], full_m[1], float_type, obs_subset, src_subset) y1 = op.dot(v) max_pts_per_cell = 2 if one_cell: max_pts_per_cell = int(1e9) fmm = TSFMM(m_obs, m_src, params=K_params, order=order, quad_order=quad_order, float_type=float_type, K_name=K_name, mac=2.5, max_pts_per_cell=max_pts_per_cell, n_workers_per_block=128) if far_only: assert (fmm.interactions.p2p.src_n_idxs.shape[0] == 0) report_interactions(fmm) y2 = fmm.dot(v) print(order, np.linalg.norm((y1 - y2)) / np.linalg.norm(y1)) print(y1, y2) np.testing.assert_almost_equal(y1, y2, 5)
def convergence_tester(f): n = 10 corners = [[-1, 0, 1], [-1, 0, -1], [1, 0, -1], [1, 0, 1]] pts, tris = tct.make_rect(n, n, corners) pts = np.array([(0, 0, 0), (1, 0, 0), (0, 1, 0), (0, -1, 0)]) #TODO: deal with flipping tris = np.array([[0, 1, 2], [1, 0, 3]]) Ks = ['elasticU3', 'elasticRT3', 'elasticRA3', 'elasticRH3'] for K in Ks: for i in range(5): print(K) pairs_int = PairsIntegrator(K, [1.0, 0.25], np.float64, 2, 5, pts, tris) for nq in range(1, 13, 2): mat1 = f(nq, pairs_int, pts, tris) mat2 = f(nq + 1, pairs_int, pts, tris) diff = mat1 - mat2 err = np.abs(diff / mat2) err[np.isnan(err)] = 1e-15 l2_diff = np.sqrt(np.sum(diff**2)) l2_mat = np.sqrt(np.sum(mat2**2)) print(nq, mat1.flatten()[0], mat2.flatten()[0], l2_diff / l2_mat)
def benchmark(): compare = False np.random.seed(123456) float_type = np.float32 n = 1000 K_name = 'elasticRH3' corners = [[-1.0, -1.0, 0], [-1.0, 1.0, 0], [1.0, 1.0, 0], [1.0, -1.0, 0]] m = tct.make_rect(n, n, corners) v = (100000 * np.random.rand(m[1].shape[0] * 9)).astype(float_type) t = tct.Timer() if compare: all_tris = np.arange(m[1].shape[0]) op = tct.TriToTriDirectFarfieldOp(2, K_name, [1.0, 0.25], m[0], m[1], float_type, all_tris, all_tris) t.report('build direct') for i in range(2): y1 = op.dot(v) t.report('op.dot direct') all_tris = np.arange(m[1].shape[0]) oldfmm = tct.FMMFarfieldOp(4.0, 400, 1e-5)(2, K_name, [1.0, 0.25], m[0], m[1], float_type, all_tris, all_tris) t.report('build oldfmm') for i in range(2): oldfmm.dot(v) t.report('op.dot oldfmm') # TODO: still maybe some room in p2p compared to direct # TODO: maybe do full fmm? fmm = TSFMM(m, m, params=np.array([1.0, 0.25]), order=4, K_name=K_name, quad_order=2, float_type=float_type, mac=2.5, max_pts_per_cell=80, n_workers_per_block=128) report_interactions(fmm) t.report('build') out = fmm.dot(v) t.report('first dot') out = fmm.dot(v) t.report('second dot') for i in range(1): start = time.time() out = fmm.dot(v) t.report('third dot') took = time.time() - start interactions = m[1].shape[0]**2 print('million rows/sec', m[1].shape[0] / took / 1e6) print('billion interactions/sec', interactions / took / 1e9) filename = 'tests/fmm/taylorbenchmarkcorrect.npy' # np.save(filename, out) correct = np.load(filename) # print(out, correct, y1) np.testing.assert_almost_equal(out, correct, 5)
import logging import numpy as np import tectosaur as tct tct.logger.setLevel(logging.INFO) n = 50 corners = [[-1.0, -1.0, 0], [-1.0, 1.0, 0], [1.0, 1.0, 0], [1.0, -1.0, 0]] m = tct.make_rect(n, n, corners) t = tct.Timer() all_tris = np.arange(m[1].shape[0]) op = tct.FMMFarfieldOp(mac=4.5, pts_per_cell=100)(2, 'elasticRT3', [1.0, 0.25], m[0], m[1], np.float32, all_tris, all_tris) t.report('build op') x = np.random.rand(m[1].shape[0] * 9) t.report('x') for i in range(1): y = op.dot(x) t.report('op.dot(x)')
import okada_wrapper which = 'H' TCTN = 50 SEP = 0.0 FAR = 4 NEAR = 8 VERTEX = 10 OKADAN = 20 CURVE = 0.0 #1.5 if CURVE != 0: assert (OKADAN == 0) corners = [[-1, 0, -1], [1, 0, -1], [1, 0, 1], [-1, 0, 1]] src_mesh = tct.make_rect(TCTN, TCTN, corners) src_mesh[0][:, 1] = CURVE * src_mesh[0][:, 0]**2 def gauss_slip_fnc(x, z): r2 = x**2 + z**2 R = 0.5 out = (np.cos(np.sqrt(r2) * np.pi / R) + 1) / 2.0 out[np.sqrt(r2) > R] = 0.0 return out dof_pts = src_mesh[0][src_mesh[1]] x = dof_pts[:, :, 0] z = dof_pts[:, :, 2] slip = np.zeros((src_mesh[1].shape[0], 3, 3)).astype(np.float32)
def make_mesh(n): corners = [[-1, 0, 1], [-1, 0, -1], [1, 0, -1], [1, 0, 1]] return tct.make_rect(n, n, corners)
def test_topo_bug(): n_fault = 51 fault_L = 4000 fault_W = 4000 fault_m = tct.make_rect(n_fault, n_fault, [[-fault_L, 0, 0], [-fault_L, 0, -2 * fault_W], [fault_L, 0, -2 * fault_W], [fault_L, 0, 0]]) n_surf = 101 surf_L = 8000 surf_W = 8000 surf_m = tct.make_rect(n_surf, n_surf, [[-surf_L, surf_W, 0], [-surf_L, -surf_W, 0], [surf_L, -surf_W, 0], [surf_L, surf_W, 0]]) n_tris = fault_m[1].shape[0] m = tct.CombinedMesh.from_named_pieces([('surf', surf_m), ('fault', fault_m)]) qd_cfg = dict( # Material properties sm=2e10, # Shear modulus (Pa) pr=0.25, # Poisson ratio density=2670, # rock density (kg/m^3) # Frictional properties Dc=0.012, # state evolution length scale (m) f0=0.6, # baseline coefficient of friction V0=1e-6, # when V = V0, f = f0, V is (m/s) a=np.ones(n_tris * 3) * 0.010, b=np.ones(n_tris * 3) * 0.015, # Boundary conditions plate_rate=1e-9, # (m/s), equivalent to ~31.5 mm/yr slipdir=(1.0, 0.0, 0.0), # This is only necessary because this is a full space model and there's no concept of depth or gravity additional_normal_stress=50e6, # numerical preferences only_x=True, # slip/velocity/traction in the y,z directions are set = 0 timestep_tol=1e-3, # error tolerance for the RK45 time stepper tectosaur_cfg=dict(quad_coincident_order=8, quad_edgeadj_order=8, quad_vertadj_order=8, quad_mass_order=5, quad_far_order=3, quad_near_order=5, quad_near_threshold=2.5, float_type=np.float32, use_fmm=False, fmm_order=150, fmm_mac=3.0, pts_per_cell=450, log_level='DEBUG')) model = TopoModel(m, qd_cfg) # print_length_scales(model) cm, c_rhs = surf_fault_continuity(m, False) traction_mass_op = tct.MassOp( model.cfg['tectosaur_cfg']['quad_mass_order'], m.pts, m.tris) constrained_traction_mass_op = cm.T.dot(traction_mass_op.mat.dot(cm)) disp_slip = np.zeros(model.H().shape[1]) import ipdb ipdb.set_trace() rhs = -model.H().dot(disp_slip) constrained_rhs = cm.T.dot(rhs) def callback(x): callback.iter += 1 print(callback.iter) callback.iter = 0 soln = cg(constrained_traction_mass_op, constrained_rhs)