|
5 | 5 | from pathlib import Path |
6 | 6 |
|
7 | 7 | import numpy as np |
8 | | -import xarray as xr |
9 | 8 |
|
10 | 9 | import flopy4 |
11 | 10 |
|
|
16 | 15 | nper = time.nper |
17 | 16 |
|
18 | 17 | # Grid |
19 | | -nlay = 5 |
| 18 | +nlay = 3 |
20 | 19 | nrow = 15 |
21 | 20 | ncol = 15 |
22 | 21 | shape = (nlay, nrow, ncol) |
|
25 | 24 | delc = np.ones((nrow,)) * 5000.0 |
26 | 25 | idomain = np.ones(shape, dtype=int) |
27 | 26 | top = np.ones((nrow, ncol), dtype=float) * 200.0 |
28 | | -bottom = np.stack([np.full((nrow, ncol), val) for val in [-150.0, -200.0, -300.0, -350.0, -450.0]]) |
| 27 | +bottom = np.stack([np.full((nrow, ncol), val) for val in [-200.0, -300.0, -450.0]]) |
29 | 28 | grid = flopy4.mf6.utils.grid.StructuredGrid( |
30 | 29 | nlay=nlay, nrow=nrow, ncol=ncol, top=top, botm=bottom, delr=delr, delc=delc, idomain=idomain |
31 | 30 | ) |
32 | 31 | dims = {"nper": nper, **dict(grid.dataset.sizes)} # TODO: temporary |
33 | 32 |
|
34 | 33 | # Grid discretization |
| 34 | +# TODO: xorigin, yorigin |
35 | 35 | dis = flopy4.mf6.gwf.Dis.from_grid(grid=grid) |
36 | 36 |
|
37 | 37 | # Constant head boundary on the left |
38 | 38 | chd = flopy4.mf6.gwf.Chd( |
39 | | - head={"*": {(k, i, 0): 0.0 for k in range(nlay) for i in range(nrow)}}, |
| 39 | + head={"*": {(k, i, 0): 0.0 for k in range(nlay - 1) for i in range(nrow)}}, |
40 | 40 | print_input=True, |
41 | 41 | print_flows=True, |
42 | 42 | save_flows=True, |
|
47 | 47 | elevation = [0.0, 0.0, 10.0, 20.0, 30.0, 50.0, 70.0, 90.0, 100.0] |
48 | 48 | conductance = 1.0 |
49 | 49 | drn = flopy4.mf6.gwf.Drn( |
50 | | - elev={"*": {(0, 7, j): elevation[j] for j in range(9)}}, |
51 | | - cond={"*": {(0, 7, j): conductance for j in range(9)}}, |
| 50 | + elev={"*": {(0, 7, j + 1): elevation[j] for j in range(9)}}, |
| 51 | + cond={"*": {(0, 7, j + 1): conductance for j in range(9)}}, |
52 | 52 | print_input=True, |
53 | 53 | print_flows=True, |
54 | 54 | save_flows=True, |
|
59 | 59 | ic = flopy4.mf6.gwf.Ic(strt=0.0, dims=dims) |
60 | 60 |
|
61 | 61 | # Node properties |
62 | | -icelltype = np.stack([np.full((nrow, ncol), val) for val in [1, 0, 0, 0, 0]]) |
63 | | -k = np.stack([np.full((nrow, ncol), val) for val in [1.0e-3, 1.0e-8, 1.0e-4, 5.0e-7, 2.0e-4]]) |
64 | | -k33 = np.stack([np.full((nrow, ncol), val) for val in [1.0e-3, 1.0e-8, 1.0e-4, 5.0e-7, 2.0e-4]]) |
| 62 | +icelltype = np.stack([np.full((nrow, ncol), val) for val in [1, 0, 0]]) |
| 63 | +k = np.stack([np.full((nrow, ncol), val) for val in [1.0e-3, 1.0e-4, 2.0e-4]]) |
| 64 | +k33 = np.stack([np.full((nrow, ncol), val) for val in [2.0e-8, 2.0e-8, 2.0e-8]]) |
65 | 65 | npf = flopy4.mf6.gwf.Npf( |
66 | 66 | # TODO: no need for reshaping once array structuring converter is done |
67 | 67 | icelltype=icelltype.reshape((nodes,)), |
68 | 68 | k=k.reshape((nodes,)), |
69 | 69 | k33=k33.reshape((nodes,)), |
70 | | - cvoptions=flopy4.mf6.gwf.Npf.CvOptions(variablecv=True, dewatered=True), |
| 70 | + cvoptions=flopy4.mf6.gwf.Npf.CvOptions(dewatered=True), |
71 | 71 | perched=True, |
72 | 72 | save_flows=True, |
73 | 73 | dims=dims, |
|
78 | 78 | storagecoefficient=False, |
79 | 79 | ss=1.0e-5, |
80 | 80 | sy=0.15, |
81 | | - transient={"*": False}, |
| 81 | + steady_state=[True, False, False], |
82 | 82 | iconvert=0, |
83 | 83 | dims=dims, |
84 | 84 | ) |
85 | 85 |
|
86 | 86 | # Uniform recharge on the top layer |
87 | | -rch_rate = xr.full_like(grid.idomain.sel(k=1), 3.0e-8, dtype=float) |
88 | | -rch = flopy4.mf6.gwf.Rch(recharge=rch_rate, dims=dims) |
| 87 | +rch_rate = np.stack(np.full((nlay, nrow, ncol), flopy4.mf6.constants.FILL_DNODATA)) |
| 88 | +rate = np.repeat(np.expand_dims(rch_rate, axis=0), repeats=nper, axis=0) |
| 89 | +rate[0, 0, :] = 3.0e-8 |
| 90 | +rch = flopy4.mf6.gwf.Rch(recharge=rate.reshape(nper, -1), dims=dims) |
89 | 91 |
|
90 | 92 | # Output control |
91 | 93 | # TODO: show both ways to set up the Oc package, strings |
92 | 94 | # and proper record types? and/or with perioddata param? |
93 | | -oc = flopy4.mf6.gwf.Oc(save_head="all", save_budget="all", dims=dims) |
| 95 | +oc = flopy4.mf6.gwf.Oc( |
| 96 | + budget_file="gwf.bud", |
| 97 | + head_file="gwf.hds", |
| 98 | + save_head={0: "all"}, |
| 99 | + save_budget={0: "all"}, |
| 100 | + dims=dims, |
| 101 | +) |
94 | 102 |
|
95 | 103 | # Wells scattered throughout the model |
96 | 104 | wel_q = -5.0 |
97 | 105 | wel_nodes = [ |
98 | | - [3, 4, 10, -5.0], |
99 | | - [2, 3, 5, -5.0], |
100 | | - [2, 5, 11, -5.0], |
| 106 | + [2, 4, 10, -5.0], |
| 107 | + [1, 3, 5, -5.0], |
| 108 | + [1, 5, 11, -5.0], |
101 | 109 | [0, 8, 7, -5.0], |
102 | 110 | [0, 8, 9, -5.0], |
103 | 111 | [0, 8, 11, -5.0], |
|
119 | 127 | # Flow model |
120 | 128 | gwf = flopy4.mf6.gwf.Gwf( |
121 | 129 | dis=grid, |
122 | | - chd=chd, |
123 | 130 | ic=ic, |
124 | 131 | npf=npf, |
125 | 132 | sto=sto, |
126 | 133 | oc=oc, |
127 | | - rch=rch, |
128 | | - wel=wel, |
129 | | - drn=drn, |
| 134 | + chd=[chd], |
| 135 | + rch=[rch], |
| 136 | + wel=[wel], |
| 137 | + drn=[drn], |
130 | 138 | dims=dims, |
131 | 139 | ) |
132 | 140 |
|
|
143 | 151 | scaling_method=None, |
144 | 152 | reordering_method=None, |
145 | 153 | relaxation_factor=0.97, |
| 154 | + models=["gwf"], |
146 | 155 | ) |
147 | 156 |
|
148 | 157 | # TDIS |
|
166 | 175 | sim.run() # assumes the ``mf6`` executable is available on your PATH. |
167 | 176 |
|
168 | 177 | # Load head results |
169 | | -gwf_ws = Path(workspace) / gwf.name |
170 | 178 | head = flopy4.mf6.utils.open_hds( |
171 | | - gwf_ws / f"{gwf.name}.hds", |
172 | | - gwf_ws / f"{dis.name}.dis.grb", |
| 179 | + workspace / f"{gwf.name}.hds", |
| 180 | + workspace / f"{gwf.name}.dis.grb", |
173 | 181 | ) |
174 | 182 |
|
175 | 183 | # Plot head results |
|
0 commit comments