def get_slip_to_traction(m, tectosaur_cfg): import tectosaur from tectosaur.ops.sparse_integral_op import make_integral_op from tectosaur.constraint_builders import free_edge_constraints, continuity_constraints from tectosaur.constraints import build_constraint_matrix from tectosaur.ops.mass_op import MassOp from scipy.sparse.linalg import spsolve pts, tris = m tectosaur.logger.setLevel(tectosaur_cfg['log_level']) n_dofs = tris.shape[0] * 9 cs = [] # cs.extend(traction_continuity_constraints(pts, tris, np.array([]))) cs = continuity_constraints(tris, np.array([])) # cs.extend(free_edge_constraints(tris)) cm, c_rhs = build_constraint_matrix(cs, n_dofs) all_tri_idxs = np.arange(tris.shape[0]) hypersingular_op = make_integral_op( pts, tris, 'elasticH3', [tectosaur_cfg['sm'], tectosaur_cfg['pr']], tectosaur_cfg, all_tri_idxs, all_tri_idxs) traction_mass_op = MassOp(tectosaur_cfg['quad_mass_order'], pts, tris) constrained_traction_mass_op = cm.T.dot(traction_mass_op.mat.dot(cm)) def slip_to_traction(slip): rhs = hypersingular_op.dot(slip.reshape(-1)) # rhs = cm.dot(cm.T.dot(hypersingular_op.dot(slip.reshape(-1)))) out = spsolve(traction_mass_op.mat, rhs) # out = cm.dot(spsolve(constrained_traction_mass_op, cm.T.dot(rhs))) return out return slip_to_traction
def direct_solve(iop, constraints, rhs=None): cm, c_rhs = build_constraint_matrix(constraints, iop.shape[0]) cm = cm.tocsr() cmT = cm.T iop_constrained = cmT.dot(cmT.dot(iop.mat.T).T) if rhs is None: rhs_constrained = cmT.dot(-iop.mat.dot(c_rhs)) else: rhs_constrained = cmT.dot(rhs - iop.mat.dot(c_rhs)) soln_constrained = np.linalg.solve(iop_constrained, rhs_constrained) soln = cm.dot(soln_constrained) return soln
def setup_edge_bcs(self): cs = free_edge_constraints(self.m.get_tris('fault')) cm, c_rhs, _ = build_constraint_matrix(cs, self.m.n_dofs('fault')) constrained_slip = np.ones(cm.shape[1]) self.ones_interior = cm.dot(constrained_slip) self.field_inslipdir_interior = self.ones_interior.copy() self.field_inslipdir = self.field_inslipdir_interior.copy() for d in range(3): val = self.cfg.get('slipdir', (1.0, 0.0, 0.0))[d] self.field_inslipdir_interior.reshape(-1, 3)[:, d] *= val self.field_inslipdir.reshape(-1, 3)[:, d] = val self.field_inslipdir_edges = (self.field_inslipdir - self.field_inslipdir_interior)
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
def build_system(pts, tris, ops, slip): trac_cs = [] trac_cs.extend(jump_constraints(np.zeros_like(slip), True)) disp_cs = [] disp_cs.extend(continuity_constraints(tris, np.array([]))) disp_cs.extend(jump_constraints(slip, False)) ND = tris.shape[0] * 9 n_total_dofs = ND * 4 cs = build_composite_constraints((trac_cs, 0), (disp_cs, 2 * ND)) cm, c_rhs = build_constraint_matrix(cs, n_total_dofs) chunk_mat = gdbem(ops) ops_and_starts = [] for i in range(4): for j in range(4): chunk = chunk_mat[i][j] if chunk == 0: continue ops_and_starts.append((chunk, i * ND, j * ND)) lhs = CompositeOp(*ops_and_starts) rhs = -lhs.dot(c_rhs) return cm, lhs, rhs
def build_continuity(m, cfg): cs = tct.continuity_constraints(m.pts, m.tris, m.tris.shape[0]) cs.extend(free_edge_constraints(m.get_tris('fault'))) cm, c_rhs, _ = build_constraint_matrix(cs, m.n_dofs('fault')) return cm
import numpy as np import scipy.sparse import tectosaur.mesh as mesh from tectosaur.constraints import constraints, build_constraint_matrix from tectosaur.dense_integral_op import DenseIntegralOp sm = 1.0 pr = 0.25 w = 4 corners = [[w, w, 0], [w, -w, 0], [-w, -w, 0], [-w, w, 0]] m = mesh.make_rect(4, 4, corners) cs = constraints(m[1], np.empty((0, 3)), m[0]) cm = build_constraint_matrix(cs, m[1].shape[0] * 9) cm = cm[0].todense() old_iop = None for i, nq in enumerate(range(2, 20, 1)): eps = (2.0**-np.arange(0, nq)) / (6.7) # eps = np.linspace(1.1, 0.9, nq) # eps = [1.0, 0.3] # eps = np.linspace((1 + nq) / 10.0, 0.1, nq) # if i == 0: # eps = [0.2, 0.1] # elif i == 1: # eps = [0.2, 0.1, 0.05] # elif i == 2: # eps = [0.2, 0.1, 0.05, 0.025] # elif i == 3: # eps = [0.2, 0.1, 0.05, 0.025, 0.0125] print(eps)
def regularized_tester(K, sep, continuity, mass_op_factor=0.0, which=None): if which is None: raise Exception('select some operators!') n_m = 30 full_K_name = f'elastic{K}3' full_RK_name = f'elasticR{K}3' m, surf1_idxs, surf2_idxs = make_meshes(n_m=n_m, sep=sep) if sep == 0.0: surf2_idxs = surf1_idxs near_threshold = 2.0 nq_near = 5 nq_far = 2 if any_nearfield(m[0], m[1], surf1_idxs, surf2_idxs, near_threshold): nearfield = True else: nearfield = False def sparse_unregularized(far_op, Kn): return SparseIntegralOp(6, nq_far, nq_near, near_threshold, Kn, [1.0, 0.25], m[0], m[1], np.float32, farfield_op_type=far_op, obs_subset=surf1_idxs, src_subset=surf2_idxs) def change_K_tri_tri(to): def f(*args, to=to): args = list(args) args[1] = to return TriToTriDirectFarfieldOp(*args) return f def add_sparse_reg(farfield_K, farfield_type): ops.append( SumOp([ RegularizedSparseIntegralOp(10, 10, 6, nq_far, nq_near, near_threshold, full_RK_name, farfield_K, [1.0, 0.25], m[0], m[1], np.float32, farfield_type, obs_subset=surf1_idxs, src_subset=surf2_idxs), MultOp(MassOp(3, m[0], m[1][surf1_idxs]), mass_op_factor) ])) ops = [sparse_unregularized(PtToPtDirectFarfieldOp, full_K_name)] if 'pt_to_pt_fmm' in which: ops.append( sparse_unregularized(PtToPtFMMFarfieldOp(150, 2.5, 5), full_K_name)) if 'tri_farfield_regularized' in which: ops.append( sparse_unregularized(change_K_tri_tri(full_RK_name), full_K_name)) if 'dense_regularized' in which: ops.append( SumOp([ RegularizedDenseIntegralOp(10, 10, 6, nq_far, nq_near, near_threshold, full_RK_name, full_RK_name, [1.0, 0.25], m[0], m[1], np.float32, obs_subset=surf1_idxs, src_subset=surf2_idxs), MultOp(MassOp(3, m[0], m[1][surf1_idxs]), mass_op_factor) ])) if 'sparse_regularized' in which: add_sparse_reg(full_RK_name, TriToTriDirectFarfieldOp) if 'sparse_regularized_fmm' in which: add_sparse_reg(full_K_name, PtToPtFMMFarfieldOp(150, 2.5, 5)) if 'sparse_regularized_but_unregularized_far': add_sparse_reg(full_K_name, change_K_tri_tri(full_K_name)) print('built ops') x = build_x_field(m, surf1_idxs, surf2_idxs) x_flat = x.flatten() outs = [o.dot(x_flat) for o in ops] if continuity: from tectosaur.constraint_builders import continuity_constraints, \ free_edge_constraints from tectosaur.constraints import build_constraint_matrix cs = continuity_constraints(m[1][surf1_idxs], np.array([])) cs.extend(free_edge_constraints(m[1][surf1_idxs])) cm, c_rhs = build_constraint_matrix(cs, outs[0].shape[0]) final_outs = [cm.T.dot(v) for v in outs] plot_outs = [cm.dot(v) for v in final_outs] else: plot_outs = outs final_outs = outs should_plot = True if should_plot: plot_fnc(m, surf1_idxs, surf2_idxs, x, plot_outs) for i in range(len(final_outs)): for j in range(i + 1, len(final_outs)): print(i, j, final_outs[i] / final_outs[j]) np.testing.assert_almost_equal(final_outs[i], final_outs[j], 6)