In [1]:
%load_ext autoreload
%autoreload 2

In [2]:
import numpy as np
from scipy.sparse.linalg import cg, lsqr, gmres
import matplotlib.pyplot as plt
import matplotlib.tri
import okada_wrapper
import tectosaur as tct

In [28]:
TCTN = 121
CURVE = 1.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 * np.abs(src_mesh[0][:,0])
#src_mesh[0][:,1] = CURVE * (src_mesh[0][:,0] ** 2 + src_mesh[0][:,2] ** 2)
def gauss_slip_fnc(x, z):
    r2 = x ** 2 + z ** 2
    R = 0.6
    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)
slip[:,:,0] = gauss_slip_fnc(x, z)

In [29]:
plt.tripcolor(src_mesh[0][:,0], src_mesh[0][:,2], src_mesh[1], src_mesh[0][:,1])
plt.show()



In [30]:
H = tct.RegularizedSparseIntegralOp(
    6, 6, 6, 2, 5, 2.5,
    'elasticRH3', 'elasticRH3', [1.0, 0.25], src_mesh[0], src_mesh[1], np.float32,
    farfield_op_type = tct.TriToTriDirectFarfieldOp
)
traction_mass_op = tct.MassOp(4, src_mesh[0], src_mesh[1])


[576339:DEBUG:tectosaur.util.gpu]
    returning cached gpu module assemble.cl
[576344:DEBUG:tectosaur.util.gpu]
    returning cached gpu module assemble.cl
[576346:DEBUG:tectosaur.nearfield.nearfield_op]
         setup pairs integrator took 0.007436618208885193
[577483:DEBUG:tectosaur.nearfield.nearfield_op]
         Coincident took 1.1365202590823174
[577491:DEBUG:tectosaur.nearfield.nearfield_op]
         Coincident correction took 0.00697755441069603
[578252:DEBUG:tectosaur.nearfield.nearfield_op]
         Find nearfield/adjacency took 0.7596284411847591
[578655:DEBUG:tectosaur.nearfield.nearfield_op]
         Edge adjacent took 0.4019304923713207
[578680:DEBUG:tectosaur.nearfield.nearfield_op]
         Edge adjacent correction took 0.023844093084335327
[579246:DEBUG:tectosaur.nearfield.nearfield_op]
         Vert adjacent took 0.5650332905352116
[579328:DEBUG:tectosaur.nearfield.nearfield_op]
         Vert adjacent correction took 0.08103799819946289
[580415:DEBUG:tectosaur.nearfield.nearfield_op]
         Nearfield took 1.0862015634775162
[581243:DEBUG:tectosaur.nearfield.nearfield_op]
         Nearfield correction took 0.8273206017911434
[581794:DEBUG:tectosaur.nearfield.nearfield_op]
         Assemble matrix took 0.5498335920274258
[581795:DEBUG:tectosaur.nearfield.nearfield_op]
         Assemble uncorrected matrix took 5.264952778816223e-05
[581804:DEBUG:tectosaur.util.gpu]
    returning cached gpu module matrix_free.cl

In [31]:
dof_pts = src_mesh[0][src_mesh[1]]
from tectosaur.util.geometry import unscaled_normals
ns = unscaled_normals(dof_pts)
ns /= np.linalg.norm(ns, axis = 1)[:, np.newaxis]
ns = np.repeat(ns, 3, axis = 0)

edge_dofs = tct.free_edge_dofs(src_mesh[1], tct.find_free_edges(src_mesh[1]))

obs_pts = dof_pts.reshape((-1,3))[edge_dofs]
obs_ns = ns[edge_dofs]
interior_op = tct.InteriorOp(obs_pts.copy(), obs_ns.copy(), src_mesh, 'elasticH3', 4.0, 11, 7, 7, [1.0, 0.25], np.float32)

C_ik = 0.5 * np.ones
trac_edges = -interior_op.dot(slip.flatten())# / 4.0

vec_edge_dofs = np.tile(3 * np.array(edge_dofs)[:,np.newaxis], (1,3))
vec_edge_dofs[:,1] += 1
vec_edge_dofs[:,2] += 2
vec_edge_dofs = vec_edge_dofs.flatten()
edge_cs = tct.simple_constraints(vec_edge_dofs, trac_edges)


[582054:DEBUG:tectosaur.util.gpu]
    returning cached gpu module matrix_free.cl
[582057:DEBUG:tectosaur.util.gpu]
    returning cached gpu module assemble.cl
[582113:DEBUG:tectosaur.util.gpu]
    returning cached gpu module assemble.cl
[582202:DEBUG:tectosaur.util.gpu]
    start compiling interior_corners.cl
[583329:DEBUG:tectosaur.util.gpu]
     compile took 1.1266359947621822

In [32]:
cs = tct.continuity_constraints(src_mesh[0], src_mesh[1], src_mesh[1].shape[0])
cs.extend(edge_cs)
cmU, _, _ = tct.build_constraint_matrix(cs, src_mesh[1].shape[0] * 9)

In [33]:
csT1, csT2 = tct.traction_admissibility_constraints(src_mesh[0], src_mesh[1])
csT1.extend(edge_cs)
#csT1.extend(csT2)
cmT, c_rhs, _ = tct.build_constraint_matrix(csT1, src_mesh[1].shape[0] * 9)

import scipy.sparse
rows = []
cols = []
data = []
cmT2_rhs = np.zeros((len(csT2)))
for i in range(len(csT2)):
    c = csT2[i]
    for j in range(len(c.terms)):
        rows.append(i)
        cols.append(c.terms[j].dof)
        data.append(c.terms[j].val)
    cmT2_rhs[i] = c.rhs
cmT2 = scipy.sparse.csr_matrix((data, (rows, cols)), shape = (len(csT2), cmT.shape[0]))

constrained_traction_mass_op = cmU.T.dot(traction_mass_op.mat.dot(cmT))
full_lhs = scipy.sparse.vstack((constrained_traction_mass_op, cmT2.dot(cmT)))
rhs = -cmU.T.dot(H.dot(slip.flatten())) - cmU.T.dot(traction_mass_op.mat.dot(c_rhs))
full_rhs = np.concatenate((rhs, cmT2_rhs - cmT2.dot(c_rhs)))

# full_lhs.shape, full_rhs.shape, cmT.shape, cmU.shape, cmT2.shape, constrained_traction_mass_op.shape

#soln = cg(constrained_traction_mass_op, rhs)
soln = scipy.sparse.linalg.lsmr(full_lhs, full_rhs, show = True, atol = 1e-8)
out = cmT.dot(soln[0]) + c_rhs

pts = src_mesh[0][src_mesh[1]].reshape((-1,3))
idxs = np.where(np.abs(pts[:,2] - 0.115) < 0.005)[0]
#idxs = np.where(np.abs(pts[:,0]) < 0.01)[0]
plt.figure(figsize = (18, 6))
for d in range(3):
    plt.subplot(1,3,d+1)
    plt.plot(pts[idxs][:,0], out.reshape((-1,3))[idxs][:,d], '-*')
plt.show()
    
pts = src_mesh[0][src_mesh[1]].reshape((-1,3))
idxs = np.where(np.abs(pts[:,0]) < 0.01)[0]
#idxs = np.where(np.abs(pts[:,0]) < 0.01)[0]
plt.figure(figsize = (18, 6))
for d in range(3):
    plt.subplot(1,3,d+1)
    plt.plot(pts[idxs][:,2], out.reshape((-1,3))[idxs][:,d], '.')
plt.show()


[594171:DEBUG:tectosaur.ops.sparse_integral_op]
    start farfield_dot
[594569:DEBUG:tectosaur.ops.sparse_integral_op]
     farfield_dot took 0.39803582802414894
[594573:DEBUG:tectosaur.ops.sparse_integral_op]
    start nearfield_dot
[595386:DEBUG:tectosaur.ops.sparse_integral_op]
     nearfield_dot took 0.8131952695548534
 
LSMR            Least-squares solution of  Ax = b

The matrix A has    42840 rows  and    42840 cols
damp = 0.00000000000000e+00

atol = 1.00e-08                 conlim = 1.00e+08

btol = 1.00e-06             maxiter =    42840

 
   itn      x(1)       norm r    norm Ar  compatible   LS      norm A   cond A
     0  0.00000e+00  8.544e-01  6.255e+01   1.0e+00  8.6e+01
     1 -3.34940e-14  5.354e-01  2.959e+01   6.3e-01  6.0e-01  9.2e+01  1.0e+00
     2 -8.49452e-14  3.474e-01  1.707e+01   4.1e-01  3.7e-01  1.3e+02  1.4e+00
     3 -1.51239e-13  2.173e-01  1.047e+01   2.5e-01  2.9e-01  1.6e+02  1.6e+00
     4 -2.31423e-13  1.200e-01  6.197e+00   1.4e-01  2.7e-01  1.9e+02  1.6e+00
     5 -3.15392e-13  5.603e-02  3.179e+00   6.6e-02  2.6e-01  2.2e+02  1.5e+00
     6 -3.84940e-13  2.865e-02  1.397e+00   3.4e-02  2.0e-01  2.4e+02  1.3e+00
     7 -4.39810e-13  2.184e-02  5.619e-01   2.6e-02  9.8e-02  2.6e+02  1.3e+00
     8 -4.88014e-13  2.070e-02  2.185e-01   2.4e-02  3.8e-02  2.8e+02  1.3e+00
     9 -5.33965e-13  2.053e-02  8.448e-02   2.4e-02  1.4e-02  3.0e+02  1.3e+00
    10 -5.79215e-13  2.050e-02  3.372e-02   2.4e-02  5.2e-03  3.2e+02  1.3e+00
    20 -3.06605e-11  2.008e-02  9.857e-03   2.3e-02  1.1e-03  4.5e+02  9.1e+00
    30 -2.87521e-10  1.823e-02  1.767e-03   2.1e-02  1.8e-04  5.5e+02  4.0e+01
    40 -5.63279e-10  1.816e-02  2.618e-04   2.1e-02  2.3e-05  6.3e+02  4.9e+01
    50 -8.33851e-10  1.816e-02  3.885e-05   2.1e-02  3.0e-06  7.1e+02  1.1e+01
    60 -1.10360e-09  1.816e-02  9.120e-06   2.1e-02  6.5e-07  7.8e+02  3.3e+00
    70 -1.19483e-09  1.816e-02  8.430e-06   2.1e-02  5.5e-07  8.4e+02  7.4e+00
    80 -1.37831e-09  1.816e-02  7.142e-06   2.1e-02  4.4e-07  9.0e+02  2.2e+02
    90 -1.64480e-09  1.816e-02  7.097e-06   2.1e-02  4.1e-07  9.5e+02  3.6e+03
   100 -1.91487e-09  1.816e-02  7.096e-06   2.1e-02  3.9e-07  1.0e+03  7.8e+03
   110 -2.19019e-09  1.816e-02  7.096e-06   2.1e-02  3.7e-07  1.1e+03  9.1e+03
 
   itn      x(1)       norm r    norm Ar  compatible   LS      norm A   cond A
   120 -2.70567e-09  1.816e-02  7.096e-06   2.1e-02  3.6e-07  1.1e+03  6.0e+03
   130 -5.57553e-09  1.816e-02  7.096e-06   2.1e-02  3.4e-07  1.1e+03  2.8e+03
   140 -1.77654e-08  1.816e-02  7.096e-06   2.1e-02  3.3e-07  1.2e+03  2.6e+03
   150 -5.83351e-07  1.816e-02  7.095e-06   2.1e-02  3.2e-07  1.2e+03  1.9e+03
   160 -2.67472e-05  1.796e-02  7.056e-06   2.1e-02  3.1e-07  1.3e+03  5.6e+02
   170 -8.27427e-04  1.182e-02  5.724e-06   1.4e-02  3.7e-07  1.3e+03  3.6e+01
   180 -2.27599e-03  8.463e-04  1.397e-06   9.9e-04  1.2e-06  1.3e+03  4.1e+00
   188 -2.33762e-03  5.237e-04  8.007e-07   6.1e-04  1.1e-06  1.4e+03  3.8e+00
 
LSMR finished
Ax - b is small enough, given atol, btol                  
istop =       1    normr = 5.2e-04
    normA = 1.4e+03    normAr = 8.0e-07
itn   =     188    condA = 3.8e+00
    normx = 4.6e+01
   188 -2.33762e-03   5.237e-04  8.007e-07
   6.1e-04  1.1e-06   1.4e+03  3.8e+00

In [34]:
def plotter(fields):
    levels = []
    for f in fields:
        minf = np.min(f)
        maxf = np.max(f)
        levels.append(np.linspace(minf - 1e-12, maxf + 1e-12, 21))
    #levels[2] = np.linspace(-0.15, 0.15, 11)
    # levels = [
    #     np.linspace(-0.1, 0.6, 21),
    #     np.linspace(-1.9, 1.9, 21),
    #     np.linspace(-0.2, 0.2, 21)
    # ]
    tri_centers = np.mean(src_mesh[0][src_mesh[1]], axis = 1)
    side = np.zeros(src_mesh[1].shape[0]).astype(np.int)
    side[tri_centers[:,0] > 0] = 1
    n_sides = 2

    cmap = 'RdBu_r'
    plt.figure(figsize = (16, 6))
    for d in range(len(fields)):
        plt.subplot(1,len(fields),d+1)
        field = fields[d]
        for i in range(n_sides):
            which_tris = np.where(side == i)[0]
            reduced_m = tct.mesh.modify.remove_unused_pts((src_mesh[0], src_mesh[1][which_tris]))
            soln_vals = np.empty(reduced_m[0].shape[0])
            soln_vals[reduced_m[1]] = field[which_tris]
            cntf = plt.tricontourf(
                reduced_m[0][:,0], reduced_m[0][:,2], reduced_m[1], soln_vals, 
                cmap = cmap, linewidth = 0.5, levels = levels[d], extend = 'both'
            )
            if levels[d].shape[0] < 25:
                plt.tricontour(
                    reduced_m[0][:,0], reduced_m[0][:,2], reduced_m[1], soln_vals, 
                    linestyles = 'solid', colors='k', linewidths = 0.7, levels = levels[d]
                ) 
        plt.colorbar(cntf)
        plt.tight_layout()
    plt.show()
    
zvec = np.cross(ns, [0,1,0])
xvec = np.cross(zvec, ns)

normal_trac = np.sum(out.reshape((-1,3)) * ns, axis = 1).reshape((-1,3))
horizontal_shear = np.sum(out.reshape((-1,3)) * xvec, axis = 1).reshape((-1,3))
vertical_shear = np.sum(out.reshape((-1,3)) * zvec, axis = 1).reshape((-1,3))
    
# plotter([
#     horizontal_shear, 
#     normal_trac,
#     vertical_shear
# ])
plotter([
    out.reshape((-1,3,3))[:,:,d]
    for d in range(3)
])


/home/tthompson/tools/pyenv/versions/miniconda3-4.3.11/lib/python3.6/site-packages/matplotlib/contour.py:1004: UserWarning: The following kwargs were not used by contour: 'linewidth'
  s)

In [35]:
cmT.shape, cmT2.shape, cmU.shape, cmT.shape[1] - cmT2.shape[0]


Out[35]:
((259200, 42840), (357, 259200), (259200, 42483), 42483)