|
| 1 | +import os |
| 2 | + |
| 3 | +import cartopy.crs as ccrs |
| 4 | +import flopy |
| 5 | +import matplotlib.pyplot as plt |
| 6 | +import numpy as np |
| 7 | +import xarray as xr |
| 8 | +from matplotlib.collections import PolyCollection |
| 9 | + |
| 10 | +QS_ROOT = os.path.abspath(os.path.join(__file__, "..")) |
| 11 | +modelname = "mymodel" |
| 12 | +ws = os.path.join(QS_ROOT, "quickstart_data") |
| 13 | + |
| 14 | + |
| 15 | +def _pcolormesh(grid, da, ax): |
| 16 | + vertices = [] |
| 17 | + for face in grid.iverts: |
| 18 | + f = [] |
| 19 | + for i in face: |
| 20 | + f.append(grid.verts[i]) |
| 21 | + vertices.append(f) |
| 22 | + vertices = np.array(vertices) |
| 23 | + |
| 24 | + collection = PolyCollection(vertices) |
| 25 | + collection.set_array(da.to_numpy().ravel()) |
| 26 | + p = ax.add_collection(collection, autolim=False) |
| 27 | + |
| 28 | + xmin, xmax, ymin, ymax = grid.extent |
| 29 | + ax.set_xlim(xmin, xmax) |
| 30 | + ax.set_ylim(ymin, ymax) |
| 31 | + cverts = (xmin, ymin), (xmax, ymax) |
| 32 | + ax.update_datalim(cverts) |
| 33 | + |
| 34 | + return p |
| 35 | + |
| 36 | + |
| 37 | +# create budget reader |
| 38 | +bpth = os.path.join(ws, f"{modelname}.bud") |
| 39 | +bobj = flopy.utils.CellBudgetFile(bpth, precision="double") |
| 40 | + |
| 41 | +# set specific discharge |
| 42 | +spdis = bobj.get_data(text="DATA-SPDIS")[0] |
| 43 | + |
| 44 | +# create head reader |
| 45 | +hpth = os.path.join(ws, f"{modelname}.hds") |
| 46 | +hobj = flopy.utils.HeadFile(hpth, precision="double") |
| 47 | + |
| 48 | +# set heads |
| 49 | +heads = hobj.get_alldata() |
| 50 | + |
| 51 | +# create grb reader |
| 52 | +grbpth = os.path.join(ws, f"{modelname}.dis.grb") |
| 53 | +grbobj = flopy.mf6.utils.MfGrdFile(grbpth) |
| 54 | +grid = None |
| 55 | + |
| 56 | +# flow vector component arrays |
| 57 | +uflow = None |
| 58 | +vflow = None |
| 59 | + |
| 60 | +# create grid object |
| 61 | +if "NROW" in grbobj._datadict and "NCOL" in grbobj._datadict: |
| 62 | + grid = flopy.discretization.StructuredGrid.from_binary_grid_file(grbpth) |
| 63 | + u = [] |
| 64 | + v = [] |
| 65 | + for r in spdis: |
| 66 | + u.append(r[3]) |
| 67 | + v.append(r[4]) |
| 68 | + uflow = np.array(u).reshape(grid.nrow, grid.ncol) |
| 69 | + vflow = np.array(v).reshape(grid.nrow, grid.ncol) |
| 70 | +else: |
| 71 | + raise Exception("unsupported discretization") |
| 72 | + |
| 73 | +# set data coordinate arrays |
| 74 | +xcrs = grid.xycenters[0] |
| 75 | +ycrs = grid.xycenters[1] |
| 76 | + |
| 77 | +# create qx, qy dataarrys |
| 78 | +qx = xr.DataArray(uflow, dims=("y", "x"), coords={"x": xcrs, "y": ycrs}) |
| 79 | +qy = xr.DataArray(vflow, dims=("y", "x"), coords={"x": xcrs, "y": ycrs}) |
| 80 | + |
| 81 | +# create head data array |
| 82 | +da = xr.DataArray( |
| 83 | + heads[0][0], |
| 84 | + dims=("y", "x"), |
| 85 | + coords={"x": xcrs, "y": ycrs}, |
| 86 | + name="head", |
| 87 | +) |
| 88 | + |
| 89 | +# quickstart mesh with contours and flow arrows |
| 90 | +fig, ax = plt.subplots() |
| 91 | +_pcolormesh(grid, da, ax) |
| 92 | +qz = np.sin(np.sqrt(uflow**2 + vflow**2)) |
| 93 | +plt.quiver(xcrs, ycrs, qx, qy, color="w") |
| 94 | +cbar = plt.colorbar(label=da.name) |
| 95 | +plt.contour(xcrs, ycrs, qz, 4, cmap="viridis") |
| 96 | +# plt.contourf(xcrs, ycrs, qz, 5, cmap='viridis', alpha=0.4) |
| 97 | +qs_pth = os.path.join(QS_ROOT, "image", "qs.png") |
| 98 | +fig.savefig(qs_pth) |
| 99 | + |
| 100 | +# projection example with cartopy |
| 101 | +fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}) |
| 102 | +da.plot(ax=ax, transform=ccrs.PlateCarree()) |
| 103 | +ax.coastlines() |
| 104 | +ax.stock_img() |
| 105 | +ax.set_extent([-5, 15, -4, 14], crs=ccrs.PlateCarree()) |
| 106 | +gln = ax.gridlines(draw_labels=True) |
| 107 | +gln.top_labels = False |
| 108 | +gln.right_labels = False |
| 109 | +ax.set_title("Head") |
| 110 | +qsprj_pth = os.path.join(QS_ROOT, "image", "qsprj.png") |
| 111 | +fig.savefig(qsprj_pth) |
0 commit comments