vp2 = np.zeros([vp.shape[0] + 4 + 2 * nab, vp.shape[1] + 2 * nab]) vp2[nab + 4:-nab, nab:-nab] = vp vp2[0:nab + 4, :] = 1500 for ii in range(vp2.shape[1]): vp2[-nab:, ii] = vp2[-nab - 1, ii] for ii in range(vp2.shape[0]): vp2[ii, 0:nab] = vp2[ii, nab] vp2[ii, -nab:] = vp2[ii, -nab - 1] vp = vp2 rho = vp * 0 + 2000 vs = vp * 0 models = {'vp': vp, 'vs': vs, 'rho': rho} """ _____________________Simulation constants input file___________________________ """ seis = SeisCL() seis.csts['N'] = np.array([vp.shape[0], vp.shape[1]]) seis.csts['ND'] = 2 # Flag for dimension. 3: 3D, 2: 2D P-SV, 21: 2D SH seis.csts['dh'] = dh = 16 # Grid spatial spacing seis.csts['dt'] = 6 * dh / (7 * np.sqrt(2) * np.max(vp)) * 0.85 seis.csts['NT'] = int(7 / seis.csts['dt']) # Number of time steps seis.csts['freesurf'] = 0 # Include a free surface at z=0: 0: no, 1: yes seis.csts['FDORDER'] = 4 # Order of the finite difference stencil. seis.csts['MAXRELERROR'] = 0 # Taylor coefficients seis.csts['f0'] = f0 # Central frequency seis.csts['abs_type'] = 2 # Absorbing boundary type: 2: Absorbing layer seis.csts['nab'] = nab # Width in grid points of the absorbing layer seis.csts['abpc'] = 6 # Exponential decay of the absorbing layer seis.csts['FP16'] = 1 # Create data in FP32
def define_SeisCL(ND=3, dt=0.25e-03, NT=800, dh=2, f0=20, L=0, FL=[], FDORDER=4, N=300, nab=112): """ Function to define common parameters of the tests for SeisCL Args: ND (int): Number of dimension (2 or 3) dt (float): Time interval in seconds NT (int): Number of timesteps dh (float): spatial grid step f0 (float): Center frequency of the wavelet in Hz L (int): Number of Maxwell mechanism for viscoelastic modeling FL (list): List of the central frequency in Hz of each Maxwell mechanism FDORDER (int): Order of the finte-difference stencil N (int): Number of grid element in each dimension nab (int) Number of grid points in the absorbing layer Returns: seis (SeisCL): A SeisCL object that can launch FD simulations. """ seis = SeisCL() seis.ND = ND seis.N = np.array([N for _ in range(ND)]) seis.dt = dt seis.NT = NT seis.dh = dh seis.f0 = f0 seis.L = L seis.FL = np.array(FL) seis.freesurf = 0 seis.FDORDER = FDORDER seis.MAXRELERROR = 1 seis.MAX = FDORDER seis.abs_type = 2 seis.seisout = 1 seis.nab = nab seis.abpc = 3 # 3 nab 112 workdir = "./seiscl" if not os.path.isdir(workdir): os.mkdir(workdir) return seis
def main(vp=3500, vs=2000, rho=2000, dt=0.6e-03, NT=3000, dh=6, f0=20, FDORDER=12, N=[700, 700], nab=112): #700, 2400 nab 112 dh 6.25 ntoplot = 1 fp16s = [1, 2, 3] seis = SeisCL() seis.csts['no_use_GPUs'] = np.array([0]) seis.csts['dt'] = dt seis.csts['NT'] = NT seis.csts['dh'] = dh seis.csts['f0'] = f0 seis.csts['freesurf'] = 0 seis.csts['FDORDER'] = FDORDER seis.csts['MAXRELERROR'] = 1 seis.csts['MAX'] = FDORDER seis.csts['abs_type'] = 2 seis.csts['seisout'] = 1 seis.csts['ND'] = 3 seis.csts['nab'] = nab seis.csts['abpc'] = 3 # 3 nab 112 workdir = "./seiscl" if not os.path.isdir(workdir): os.mkdir(workdir) fig, axs = plt.subplots(ntoplot * 3, 2, figsize=(16 / 2.54, 10 / 2.54)) t = np.arange(0, NT - 1) * dt freqs = np.fft.fftfreq(NT - 1, dt) titles = [["a)", "b)", "c)"], ["d)", "e)", "f)"], ["g)", "h)", "j)"]] labels = ["Analytic", "Numeric", "Error"] plots = [[] for _ in range(3)] for fp16 in fp16s: # Recordings in z seis.csts['N'] = np.array([N[0], N[1], N[1]]) data = fd_solution(seis, vp=vp, vs=vs, rho=rho, fp16=fp16, dir="z")[2][:NT - 1, :] seis.csts['NT'] = 2 * NT src = seis.ricker_wavelet() seis.csts['NT'] = NT gx = seis.rec_pos_all[0, [0, -1]] gy = seis.rec_pos_all[1, [0, -1]] gz = seis.rec_pos_all[2, [0, -1]] sx = seis.src_pos_all[0, :] sy = seis.src_pos_all[1, :] sz = seis.src_pos_all[2, :] rec_pos = [[x, y, z] for x, y, z in zip(gx - sx, gy - sy, gz - sz)] vx, vy, vz = analytic_visco_pointz(vp, vs, rho, dt, rec_pos, src) vz_true = vz[1:NT, :] - vz[:NT - 1, :] vz_true = vz_true / np.max(vz_true) vz_num = data / np.max(data) norm = np.max(vz_true[:, -1]) vz_true = vz_true / norm vz_num = vz_num / norm if fp16 == 1: vref = vz_num err = np.sum((vz_true[:, -1] - vref[:, -1])**2) / np.sum( (vz_true[:, -1])**2) * 100 print("Error due to dispersion for fp32 = %f %%" % err) else: err = np.sum((vz_num[:, -1] - vref[:, -1])**2) / np.sum( (vref[:, -1])**2) * 100 print("Error between fp16 = %d and fp32 = %f %%" % (fp16, err)) axs[fp16 - 1, 0].plot(t, (vz_true[:, -1] - vz_num[:, -1]) * 10, "g") axs[fp16 - 1, 0].plot(t, vz_true[:, -1], 'k') axs[fp16 - 1, 0].plot(t, vz_num[:, -1], "r") axs[fp16 - 1, 0].set_xlabel("Time (s)") axs[fp16 - 1, 0].set_ylabel("Amplitude") axs[fp16 - 1, 0].set_title(titles[0][fp16 - 1]) axs[fp16 - 1, 0].text(1.85, 0.7, "Error X 10", ha='right', weight='bold') axs[fp16 - 1, 0].set_ylim([-1.2, 1.2]) Vz_true = np.fft.fft(vz_true[:, -1], axis=0) Vz_num = np.fft.fft(vz_num[:, -1], axis=0) Vz_true_a = 2 * np.abs(Vz_true)[:NT // 2] norm = np.max(Vz_true) Vz_true_a = Vz_true_a / norm Vz_num_a = 2 * np.abs(Vz_num)[:NT // 2] / norm Vz_diff_a = 2 * np.abs(Vz_true - Vz_num)[:NT // 2] / norm plots[2], = axs[fp16 - 1, 1].loglog(freqs[:NT // 2], Vz_diff_a, "g") plots[0], = axs[fp16 - 1, 1].loglog(freqs[:NT // 2], Vz_true_a, "k") plots[1], = axs[fp16 - 1, 1].loglog(freqs[:NT // 2], Vz_num_a, "r") axs[fp16 - 1, 1].set_ylim([10**-8, 10**1]) axs[fp16 - 1, 1].set_xlabel("Frequency (Hz)") axs[fp16 - 1, 1].set_ylabel("Amplitude") axs[fp16 - 1, 1].set_title(titles[1][fp16 - 1]) #axs[fp16-1, 1].set_xscale('log', basex=2) axs[fp16 - 1, 1].set_yscale('log', basey=2) axs[fp16 - 1, 1].set_yticks([2**-0, 2**-8, 2**-16, 2**-24, 2**-32]) if fp16 == 1: axs[fp16 - 1, 1].legend(plots[0:3], labels[0:3], loc='upper right', bbox_to_anchor=(1.05, 1.5), framealpha=1) plt.tight_layout() plt.savefig('analytic.eps') plt.savefig('analytic_lowres.eps')
parser.add_argument("name", type=str, help="Name of the device") parser.add_argument("FP16compute", type=int, help="FP16 compute capacity (0: no support, 1: support)") parser.add_argument("ND", type=int, help="Number of dimension (2: 2D, 3: 3D)") args = parser.parse_args() appendname = args.name FP16compute = args.FP16compute ND = args.ND filepath = os.getcwd() + '/' filename = filepath + "times_" + str(ND) + "D" + appendname + ".mat" """ _____________________Simulation constants input file___________________________ """ seis = SeisCL() seis.csts['ND'] = ND # Flag for dimension. 3: 3D, 2: 2D P-SV, 21: 2D SH seis.csts['dh'] = 10 # Grid spatial spacing seis.csts['dt'] = 0.0008 # Time step size seis.csts['NT'] = 1000 # Number of time steps seis.csts['freesurf'] = 0 # Include a free surface at z=0: 0: no, 1: yes seis.csts['FDORDER'] = 4 # Order of the finite difference stencil. seis.csts['f0'] = 7.5 # Central frequency of the source seis.csts['abs_type'] = 0 # Absorbing boundary type (none here) seis.csts['seisout'] = 0 # Output seismograms (none here) """ _________________________Sources and receivers_________________________________ """ # Dummy receiver positions gx = np.arange(0, 2) * seis.csts['dh'] gz = np.arange(0, 2) * seis.csts['dh']
# -*- coding: utf-8 -*- """ Perform RTM on marmousi """ import os import numpy as np import h5py as h5 from scipy.ndimage.filters import gaussian_filter import sys import shutil from SeisCL import SeisCL names = ['fp32', 'fp16io', 'fp16com'] filedata = os.getcwd() + '/marmfp32' seis = SeisCL() seis.file = os.getcwd() + '/marmfp32' seis.read_csts(workdir="") seis.file = 'SeisCL' seis.file_datalist = filedata + '_din.mat' seis.file_din = filedata + '_din.mat' file = h5.File(filedata + '_model.mat', "r") models = { 'vp': gaussian_filter(np.transpose(file['vp']), sigma=3), 'vs': np.transpose(file['vs']), 'rho': np.transpose(file['rho']) } file.close() """ _________________Set inversion parameters for SeisCL____________________
def define_SeisCL(ND=3, dt=0.25e-03, NT=800, dh=2, f0=20, L=0, FL=[], FDORDER=4, N=300, nab=112): seis = SeisCL() seis.csts['ND'] = ND seis.csts['N'] = np.array([N for _ in range(ND)]) #seis.csts['no_use_GPUs'] = np.array([0]) seis.csts['dt'] = dt seis.csts['NT'] = NT seis.csts['dh'] = dh seis.csts['f0'] = f0 seis.csts['L'] = L seis.csts['FL'] = np.array(FL) seis.csts['freesurf'] = 0 seis.csts['FDORDER'] = FDORDER seis.csts['MAXRELERROR'] = 1 seis.csts['MAX'] = FDORDER seis.csts['abs_type'] = 2 seis.csts['seisout'] = 1 seis.csts['nab'] = nab seis.csts['abpc'] = 3 # 3 nab 112 workdir = "./seiscl" if not os.path.isdir(workdir): os.mkdir(workdir) return seis