def interpolate(frame, field): # read coordinate of nodes fl = flac.Flac() xx, zz = fl.read_mesh(frame) x, z = flac.make_uniform_grid(xmin, xmax, zmin, zmax, dx, dz) if field == 'phase': ## phase # read marker location, age and phase mx, mz, mage, mphase, mid = fl.read_markers(frame) mx, mz, mphase = excluding(mx, mz, mphase, xmin-dx, xmax+dx, zmin-dz, zmax+dz) ph = flac.nearest_neighbor_interpolation2d(mx, mz, mphase, x, z) f = ph.astype(np.float32) elif field in ('temperature', 'aps', 'density', 'eII', 'sII', 'sxx', 'szz', 'sxz', 'srII', 'pres', 'diss', 'visc'): # read field cf = getattr(fl, 'read_'+field)(frame) cx, cz = flac.elem_coord(xx, zz) cx, cz, cf = excluding(cx, cz, cf, xmin-dx, xmax+dx, zmin-dz, zmax+dz) f = flac.gaussian_interpolation2d(cx, cz, cf, x, z) else: raise RuntimeError('unknown field %s' % field) f = clip_topo(x, z, f, xx, zz) return x, z, f
def get_maxarcT(time): arc_phase = [14] arcT = [] time = np.reshape(time, (-1, 1)) for folderk in range(len(foldername)): path = inputpath + foldername[folderk] os.chdir(path) import flac fl = flac.Flac() arcthickness = [0] frame = time2vts(time[folderk], path) if frame != 1: phase = fl.read_phase(frame) x, z = fl.read_mesh(frame) #zz=z[:,0] #imax = zz.argmax() #the highest point = arc peak for kk1 in range(0, fl.nx - 1): if phase[kk1, 0] in arc_phase: for kk2 in range(fl.nz): if phase[kk1, kk2] not in arc_phase: break arcthickness.append(z[kk1, 0] - z[kk1, kk2]) arcT.append(round(max(arcthickness), 2)) else: arcT.append(0.0) arcT = np.reshape(arcT, arraysize) return arcT
def main(path, start=1, end=-1): # changing directory os.chdir(path) fl = flac.Flac() if end == -1: end = fl.nrec for i in range(start, end + 1): x, z, age, temp, tempmax, coolingrate, phase, ID, chronage, chronif, chrontemp = fl.read_markers( i) if filtering: x, z, age,temp,tempmax,coolingrate, phase, ID,chronage,chronif,chrontemp = \ filter_marker(x, z, age,temp,tempmax,coolingrate, phase, ID, chronage,chronif,chrontemp) nmarkers = len(x) print('Writing record #%d, model time=%.3e, %d markers' % (i, fl.time[i - 1], nmarkers)) fvtp = open('flacmarker.%06d.vtp' % i, 'w') vtp_header(fvtp, nmarkers) # point-based data fvtp.write(' <PointData>\n') vts_dataarray(fvtp, age, 'age', 1) vts_dataarray(fvtp, temp, 'temp', 1) vts_dataarray(fvtp, tempmax, 'tempmax', 1) vts_dataarray(fvtp, coolingrate, 'cooling rate', 1) vts_dataarray(fvtp, phase.astype(np.int32), 'phase', 1) for j in range(fl.chron.size): vts_dataarray(fvtp, chronage[j], fl.chron[j] + ' age', 1) vts_dataarray(fvtp, chronif[j].astype(np.int32), fl.chron[j] + ' if', 1) vts_dataarray(fvtp, chrontemp[j], fl.chron[j] + ' Temp.', 1) vts_dataarray(fvtp, ID.astype(np.int32), 'ID', 1) fvtp.write(' </PointData>\n') # point coordinates # VTK requires vector field (velocity, coordinate) has 3 components. # Allocating a 3-vector tmp array for VTK data output. tmp = np.zeros((nmarkers, 3), dtype=x.dtype) tmp[:, 0] = x tmp[:, 1] = z fvtp.write(' <Points>\n') vts_dataarray(fvtp, tmp, '', 3) fvtp.write(' </Points>\n') vtp_footer(fvtp) fvtp.close() return
def main(path, start=1, end=-1): # changing directory os.chdir(path) fl = flac.Flac() if end == -1: end = fl.nrec if start == -1: vtplist = sorted(glob.glob('flacmarker.*.vtp')) lastframe = int(vtplist[-1][11:-4]) if vtplist else 0 start = lastframe + 1 for i in range(start, end + 1): x, z, age, phase, ID = fl.read_markers(i) if filtering: x, z, age, phase, ID = filter_marker(x, z, age, phase, ID) nmarkers = len(x) print('Writing record #%d, model time=%.3e, %d markers' % (i, fl.time[i - 1], nmarkers), end='\r') sys.stdout.flush() fvtp = open('flacmarker.%06d.vtp' % i, 'w') vtp_header(fvtp, nmarkers, fl.time[i - 1], fl.steps[i - 1]) # point-based data fvtp.write(' <PointData>\n') vts_dataarray(fvtp, age, 'age', 1) vts_dataarray(fvtp, phase.astype(np.int32), 'phase', 1) vts_dataarray(fvtp, ID.astype(np.int32), 'ID', 1) fvtp.write(' </PointData>\n') # point coordinates # VTK requires vector field (velocity, coordinate) has 3 components. # Allocating a 3-vector tmp array for VTK data output. tmp = np.zeros((nmarkers, 3), dtype=x.dtype) tmp[:, 0] = x tmp[:, 1] = z fvtp.write(' <Points>\n') vts_dataarray(fvtp, tmp, '', 3) fvtp.write(' </Points>\n') vtp_footer(fvtp) fvtp.close() print() return
def read_slab_dip(frame, depth1, depth2): import flac fl = flac.Flac() import math import function_ReadData as rd # read the dip of dip between depth1 and depth2(as the input parameters) xmesh, zmesh = fl.read_mesh(frame) x_len, z_len = xmesh.shape phase = fl.read_phase(frame) temp = 0 # when here's no slab between depth1 and depth2, both two depth will be shallower depth2_temp = depth2 + 5 while temp <= 0: depth2_temp = depth2_temp - 5 for kk in range(0, z_len - 1): # find z-index in depth2 -> j2 if (rd.read_depth(zmesh, 0, kk) > depth2_temp): j2 = kk break for kk in range(0, x_len - 1): if phase[kk, j2] in rd.slab_phase: i2 = kk temp = 5 break if (depth2_temp - 20) <= depth1: depth1_temp = depth2_temp - 20 else: depth1_temp = depth1 for kk in range(0, z_len - 1): # find z-index in depth2 -> j2 if (rd.read_depth(zmesh, 0, kk) < depth1_temp): j1 = kk else: break # find x-index of surface of slab in depth2 -> i2 for kk in range(0, x_len - 1): if phase[kk, j1] in rd.slab_phase: i1 = kk break detla_x = abs(xmesh[i1, j1] - xmesh[i2, j2]) detla_z = abs(zmesh[i1, j1] - zmesh[i2, j2]) di = math.degrees(math.atan(detla_z / detla_x)) return di
def get_magmaP(time): magmaP = [] time = np.reshape(time, (-1, 1)) for folderk in range(len(foldername)): path = inputpath + foldername[folderk] os.chdir(path) import flac fl = flac.Flac() frame = time2vts(time[folderk], path) if frame != 1: production = 0 for framek in range(frame - 10, frame + 10): countmarker = fl.read_countmarker(framek) meltingmarker = fl.read_meltingmarker(framek) x, z = fl.read_mesh(framek) mi = ip.read_data('D_melt', path, 5) mj = ip.read_data('D_melt', path, 6) mt = ip.read_data('D_melt', path, 4) for tkk in range(len(mt) - 1): if mt[tkk] > fl.time[framek] and mt[tkk] < fl.time[framek + 1]: meltingmarker[mi[tkk], mj[tkk]] = meltingmarker[mi[tkk], mj[tkk]] + 1 for xk in range(fl.nx - 1): for zk in range(fl.nz - 1): production = production + ( 0.25 * (meltingmarker[xk, zk] / countmarker[xk, zk]) * read_area(x, z, xk, zk)) deltaT = fl.time[frame + 10] - fl.time[frame - 10] #in Myrs magmaP.append(production / deltaT) else: magmaP.append(0.) magmaP = np.reshape(magmaP, arraysize) return magmaP
def get_magmaP(frame): frame = frame + 1 import flac fl = flac.Flac() time = fl.time[frame] if frame > 10: production = 0 for framek in range(frame - 5, frame + 5): x, z = fl.read_mesh(framek) countmarker = fl.read_countmarker(framek) meltingmarker = fl.read_meltingmarker(framek) mi = ip.read_data('D_melt', path, 5) mj = ip.read_data('D_melt', path, 6) mt = ip.read_data('D_melt', path, 4) for tkk in range(len(mt) - 1): if mt[tkk] > fl.time[framek] and mt[tkk] < fl.time[framek + 1]: meltingmarker[mi[tkk], mj[tkk]] = meltingmarker[mi[tkk], mj[tkk]] + 1 for xk in range(1, fl.nx - 1): for zk in range(1, fl.nz - 1): production = production + ( 0.25 * (meltingmarker[xk, zk] / countmarker[xk, zk]) * read_area(x, z, xk, zk)) deltaT = fl.time[frame + 5] - fl.time[frame - 5] #in Myrs magmaP = production / deltaT else: magmaP = 0 return magmaP, time
# resolution in km fi.dx = dx fi.dz = dz xx, zz, dens = fi.interpolate(frame, 'density') return xx, zz, dens ############################################### frame = int(sys.argv[1]) left2 = int(sys.argv[2]) rigth2 = left2 + 200 fl = flac.Flac() x, z = fl.read_mesh(frame) itrench = find_trench_index(z) xtrench = x[itrench, 0] print('trench =', itrench) print('trench location =', xtrench) # get interpolated phase either from previous run or from original data phasefile = 'intp3-phase.%d' % frame if not os.path.exists(phasefile): xx, zz, ph = interpolate_phase(frame, xtrench, 1) f = open(phasefile, 'w') f.write('%d %d\n' % xx.shape) flac.printing(xx, zz, ph, stream=f) f.close() else:
def main(path, start=1, end=-1): # changing directory os.chdir(path) fl = flac.Flac() nex = fl.nx - 1 nez = fl.nz - 1 if end == -1: end = fl.nrec for i in range(start, end+1): print ('Writing record #%d, model time=%.3e' % (i, fl.time[i-1]), end='\r') sys.stdout.flush() fvts = open('flac.%06d.vts' % i, 'w') vts_header(fvts, nex, nez, fl.time[i-1], fl.steps[i-1]) # node-based field fvts.write(' <PointData>\n') vx, vz = fl.read_vel(i) # VTK requires vector field (velocity, coordinate) has 3 components. # Allocating a 3-vector tmp array for VTK data output. tmp = np.zeros((fl.nx, fl.nz, 3), dtype=vx.dtype) tmp[:,:,0] = vx tmp[:,:,1] = vz # vts requires x-axis increment fastest, swap axes order vts_dataarray(fvts, tmp.swapaxes(0,1), 'Velocity', 3) a = fl.read_temperature(i) vts_dataarray(fvts, a.swapaxes(0,1), 'Temperature') fvts.write(' </PointData>\n') # element-based field fvts.write(' <CellData>\n') # logrithm of strain rate 2nd invariant a = fl.read_srII(i) srat = a vts_dataarray(fvts, a.swapaxes(0,1), 'Strain rate') a = fl.read_eII(i) eii = a vts_dataarray(fvts, a.swapaxes(0,1), 'eII') a = fl.read_density(i) vts_dataarray(fvts, a.swapaxes(0,1), 'Density') a = fl.read_chamber(i) vts_dataarray(fvts, a.swapaxes(0,1), 'Melting history') a = fl.read_countmarker(i) vts_dataarray(fvts, a.swapaxes(0,1), 'Count of markers') a = fl.read_meltingmarker(i) vts_dataarray(fvts, a.swapaxes(0,1), 'Melting marker') exx, ezz, exz = fl.read_strain(i) e1 = compute_p_axis(exx, ezz, exz) vts_dataarray(fvts, e1.swapaxes(0,1), 'Strain 1-axis', 3) a = fl.read_aps(i) vts_dataarray(fvts, a.swapaxes(0,1), 'Plastic strain') a = fl.read_sII(i) sii = a vts_dataarray(fvts, a.swapaxes(0,1), 'Stress') sxx = fl.read_sxx(i) vts_dataarray(fvts, sxx.swapaxes(0,1), 'Sxx') szz = fl.read_szz(i) vts_dataarray(fvts, szz.swapaxes(0,1), 'Szz') sxz = fl.read_sxz(i) vts_dataarray(fvts, sxz.swapaxes(0,1), 'Sxz') pressure = fl.read_pres(i) vts_dataarray(fvts, pressure.swapaxes(0,1), 'Pressure') # compression axis of stress a = compute_p_axis(sxx, szz, sxz) vts_dataarray(fvts, a.swapaxes(0,1), 'P-axis', 3) a = fl.read_diss(i) vts_dataarray(fvts, a.swapaxes(0,1), 'Dissipation') # logrithm of effective viscosity eff_visc = np.log10(a + 1e-45) + 8 - srat vts_dataarray(fvts, eff_visc.swapaxes(0,1), 'Eff. Visc') a = fl.read_visc(i) vts_dataarray(fvts, a.swapaxes(0,1), 'Viscosity') a = fl.read_phase(i) vts_dataarray(fvts, a.swapaxes(0,1), 'Phase') # Work done by stress a = sii * 1e8 * eii vts_dataarray(fvts, a.swapaxes(0,1), 'Work') fvts.write(' </CellData>\n') # coordinate x, z = fl.read_mesh(i) tmp[:,:,0] = x tmp[:,:,1] = z fvts.write(' <Points>\n') vts_dataarray(fvts, tmp.swapaxes(0,1), '', 3) fvts.write(' </Points>\n') vts_footer(fvts) fvts.close() return
def compute_gravity(frame): ## read data fl = flac.Flac() x, z = fl.read_mesh(frame) # in km x *= 1e3 z *= 1e3 # surface coordinates xx = x[:,0] zz = z[:,0] xmin = x[0,0] xmax = x[-1,0] # center of elements cx, cz = flac.elem_coord(x, z) # area of elements = 0.5 * | AC x BD | = 0.5 * |xdiag1*zdiag2 - xdiag2*zdiag1| # A -- D # | | # B -- C xdiag1 = x[0:-1, 0:-1] - x[1:, 1:] zdiag1 = z[0:-1, 0:-1] - z[1:, 1:] xdiag2 = x[1:, 0:-1] - x[0:-1, 1:] zdiag2 = z[1:, 0:-1] - z[0:-1, 1:] area = 0.5 * np.abs(xdiag1*zdiag2 - xdiag2*zdiag1) rho = fl.read_density(frame) # in kg/m^3 # anything above sea level is removed rho[cz > 0] = 0 ## benchmark case: infinite-long cylinder with radius R ## buried at depth D #R = 10e3 #D = -150e3 #drho = 1000 #rho = np.zeros(cx.shape) #midx = 0.5 * (xmin + xmax) #midz = 0.5 * z.min() #dist2 = (x - midx)**2 + (z - D)**2 #rho[dist2 < R**2] = drho #ocean_density = 0 mass = rho * area ## calculate gravity at these points # px in uniform spacing px = np.linspace(xmin, xmax, num=5*fl.nx) # pz is a few km above the highest topography to avoid high frequency oscillation pz_height = max(0, np.max(zz)) + 4e3 print ('gravity evaluated at %f km' % pz_height) pz = np.ones(px.shape) * pz_height # original topography defined in px grid topo = np.interp(px, x[:,0], z[:,0]) ## contribution of material inside the model grav = np.empty(px.shape) for i in range(len(grav)): dx = px[i] - cx dz = pz[i] - cz dist2 = (dx**2 + dz**2) # downward component of gravity of an infinite long line source of density anomaly # see Turcotte & Schubert, 1st Ed., Eq 5-104 grav[i] = 2 * gn * np.sum(mass * dz / dist2) ## contribution of sedimentary basin, only to the right of trench peaks = find_peaks(zz) itrench = find_trench_index(zz) basin_depth = -2000 sed_density = 2200 sed_thickness = np.zeros(fl.nx) for ii in range(len(peaks)-1): fill_height = min((basin_depth, zz[peaks[ii]], zz[peaks[ii+1]])) for i in range(peaks[ii], peaks[ii+1]): if zz[i] < fill_height: sed_thickness[i] = fill_height - zz[i] zz[i] = fill_height for i in range(itrench, fl.nx-1): sedz = 0.5 * (sed_thickness[i] + sed_thickness[i+1]) if sedz > 0: midz = 0.5 * (zz[i] + zz[i+1]) midx = 0.5 * (xx[i] + xx[i+1]) m = (xx[i+1] - xx[i]) * sedz * sed_density dx = px - midx dz = pz - midz dist2 = (dx**2 + dz**2) grav += 2 * gn * m * dz / dist2 ## contribution of ocean for i in range(fl.nx-1): midz = 0.5 * (zz[i] + zz[i+1]) if midz < 0: midx = 0.5 * (xx[i] + xx[i+1]) m = (xx[i+1] - xx[i]) * -midz * ocean_density dx = px - midx dz = pz - midz dist2 = (dx**2 + dz**2) grav += 2 * gn * m * dz / dist2 # contribution of material outside left boundary # assuming the leftmost element extend to negative infinity # see Turcotte & Schubert, 1st Ed., Eq 5-106 for i in range(fl.nz-1): sigma = rho[0,i] * (z[0,i] - z[0,i+1]) dx = px - xmin dz = pz - 0.5 * (z[0,i] + z[0,i+1]) angle = np.arctan2(dx, dz) grav += 2 * gn * sigma * (0.5*np.pi - angle) if zz[0] < 0: sigma = ocean_density * -zz[0] dx = px - xmin dz = pz - 0.5 * zz[0] angle = np.arctan2(dx, dz) grav += 2 * gn * sigma * (0.5*np.pi - angle) # ditto for right boundary for i in range(fl.nz-1): sigma = rho[-1,i] * (z[-1,i] - z[-1,i+1]) dx = xmax - px dz = pz - 0.5 * (z[-1,i] + z[-1,i+1]) angle = np.arctan2(dx, dz) grav += 2 * gn * sigma * (0.5*np.pi - angle) if zz[-1] < 0: sigma = ocean_density * -zz[-1] dx = xmax - px dz = pz - 0.5 * zz[-1] angle = np.arctan2(dx, dz) grav += 2 * gn * sigma * (0.5*np.pi - angle) ## set reference gravity ## far right gravity to 0 grav -= grav[-1] return px, topo, grav
olddir = 'orig/' if len(sys.argv) > 2: olddir = sys.argv[2] + '/' curdir = os.getcwd() newdir = './' # name holder old = 0 new = 0 try: # read old and new results os.chdir(olddir) flo = flac.Flac() old = read_data(flo, frame) os.chdir('../' + newdir) fln = flac.Flac() new = read_data(fln, frame) # compare results print() print('Relative difference (max, stddev) of frame =', frame, ' step =', int(flo.steps[frame])) compare(old, new) finally: # restort to original directory os.chdir(curdir)