Ejemplo n.º 1
0
def test_gridgen():

    # define the base grid and then create a couple levels of nested
    # refinement
    Lx = 10000.
    Ly = 10500.
    nlay = 3
    nrow = 21
    ncol = 20
    delr = Lx / ncol
    delc = Ly / nrow
    top = 400
    botm = [220, 200, np.random.random((nrow, ncol))]

    # create a dummy dis package for gridgen
    ms = flopy.modflow.Modflow()
    dis5 = flopy.modflow.ModflowDis(ms,
                                    nlay=nlay,
                                    nrow=nrow,
                                    ncol=ncol,
                                    delr=delr,
                                    delc=delc,
                                    top=top,
                                    botm=botm)

    sim = flopy.mf6.MFSimulation()
    gwf = gwf = flopy.mf6.ModflowGwf(sim)
    dis6 = flopy.mf6.ModflowGwfdis(gwf,
                                   nlay=nlay,
                                   nrow=nrow,
                                   ncol=ncol,
                                   delr=delr,
                                   delc=delc,
                                   top=top,
                                   botm=botm)

    ms_u = flopy.modflow.Modflow(modelname='mymfusgmodel',
                                 model_ws=cpth,
                                 version='mfusg')
    dis_usg = flopy.modflow.ModflowDis(ms_u,
                                       nlay=nlay,
                                       nrow=nrow,
                                       ncol=ncol,
                                       delr=delr,
                                       delc=delc,
                                       top=top,
                                       botm=botm)

    gridgen_ws = cpth
    g = Gridgen(dis5, model_ws=gridgen_ws, exe_name=exe_name)
    g6 = Gridgen(dis6, model_ws=gridgen_ws, exe_name=exe_name)
    gu = Gridgen(dis_usg,
                 model_ws=gridgen_ws,
                 exe_name=exe_name,
                 vertical_pass_through=True)

    if shapefile is None:
        return  # skip remainder

    rf0shp = os.path.join(gridgen_ws, 'rf0')
    xmin = 7 * delr
    xmax = 12 * delr
    ymin = 8 * delc
    ymax = 13 * delc
    rfpoly = [[[(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax),
                (xmin, ymin)]]]
    g.add_refinement_features(rfpoly, 'polygon', 1, range(nlay))
    g6.add_refinement_features(rfpoly, 'polygon', 1, range(nlay))
    gu.add_refinement_features(rfpoly, 'polygon', 1, range(nlay))

    rf1shp = os.path.join(gridgen_ws, 'rf1')
    xmin = 8 * delr
    xmax = 11 * delr
    ymin = 9 * delc
    ymax = 12 * delc
    rfpoly = [[[(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax),
                (xmin, ymin)]]]
    g.add_refinement_features(rfpoly, 'polygon', 2, range(nlay))
    g6.add_refinement_features(rfpoly, 'polygon', 2, range(nlay))
    gu.add_refinement_features(rfpoly, 'polygon', 2, range(nlay))

    rf2shp = os.path.join(gridgen_ws, 'rf2')
    xmin = 9 * delr
    xmax = 10 * delr
    ymin = 10 * delc
    ymax = 11 * delc
    rfpoly = [[[(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax),
                (xmin, ymin)]]]
    g.add_refinement_features(rfpoly, 'polygon', 3, range(nlay))
    g6.add_refinement_features(rfpoly, 'polygon', 3, range(nlay))
    gu.add_refinement_features(rfpoly, 'polygon', 3, range(nlay))

    # inactivate parts of mfusg layer 2 to test vertical-pass-through option
    xmin = 0 * delr
    xmax = 18 * delr
    ymin = 0 * delc
    ymax = 18 * delc
    adpoly2 = [[[(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax),
                 (xmin, ymin)]]]
    gu.add_active_domain(adpoly2, layers=[1])
    adpoly1_3 = [[[(0., 0.), (Lx, 0.), (Lx, Ly), (0., Ly), (0., 0.)]]]
    gu.add_active_domain(adpoly1_3, layers=[0, 2])

    # if gridgen executable is available then do the main part of the test
    if run:

        # Use gridgen to build the grid
        g.build()
        g6.build()

        # test the different gridprops dictionaries, which contain all the
        # information needed to make the different discretization packages
        gridprops = g.get_gridprops_disv()
        gridprops = g.get_gridprops_disu5()
        gridprops = g.get_gridprops_disu6()

        # test the gridgen point intersection
        points = [(4750., 5250.)]
        cells = g.intersect(points, 'point', 0)
        n = cells['nodenumber'][0]
        msg = ('gridgen point intersect did not identify the correct '
               'cell {} <> {}'.format(n, 308))
        assert n == 308, msg

        # test the gridgen line intersection
        line = [[[(Lx, Ly), (Lx, 0.)]]]
        cells = g.intersect(line, 'line', 0)
        nlist = [n for n in cells['nodenumber']]
        nlist2 = [
            19, 650, 39, 630, 59, 610, 79, 590, 99, 570, 119, 550, 139, 530,
            159, 510, 194, 490, 265, 455, 384
        ]
        msg = ('gridgen line intersect did not identify the correct '
               'cells {} <> {}'.format(nlist, nlist2))
        assert nlist == nlist2, msg

        # test getting a modflow-usg disu package
        mu = flopy.modflow.Modflow(version='mfusg', structured=False)
        disu = g.get_disu(mu)

        # test mfusg with vertical pass-through (True above at instantiation)
        gu.build()
        disu_vp = gu.get_disu(ms_u)
        #  -check that node 1 (layer 1) is connected to layer 3 but not layer 2:
        ja0 = disu_vp.ja[:disu_vp.iac[0]]
        msg = ("MFUSG node 1 (layer 1) is not connected to layer 3 but should "
               "be (with vertical pass through activated).")
        assert max(ja0) > sum(disu_vp.nodelay[:2]), msg
        #  -check that node 1 (layer 1) is not connected to any layer 2 nodes
        msg = ("MFUSG node 1 (layer 1) is connected to layer 2 but should not "
               "be (with vertical pass through activated).")
        assert len(ja0[(ja0 > disu_vp.nodelay[0]) & \
                       (ja0 <= sum(disu_vp.nodelay[:2]))]
                   ) == 0, msg
        #ms_u.disu.write_file()

        # test mfusg without vertical pass-through
        gu.vertical_pass_through = False
        gu.build()
        disu_vp = gu.get_disu(ms_u)
        #  -check that node 1 (layer 1) is connected to layer 1 only:
        ja0 = disu_vp.ja[:disu_vp.iac[0]]
        msg = ("MFUSG node 1 (layer 1) is connected to layer 2 or 3 but "
               "should not be (without vertical pass through activated).")
        assert max(ja0) <= disu_vp.nodelay[0], msg

    return
Ejemplo n.º 2
0
def test_mf6disu():

    name = "dummy"
    nlay = 3
    nrow = 10
    ncol = 10
    delr = delc = 1.0
    top = 1
    bot = 0
    dz = (top - bot) / nlay
    botm = [top - k * dz for k in range(1, nlay + 1)]

    # Create a dummy model and regular grid to use as the base grid for gridgen
    sim = flopy.mf6.MFSimulation(sim_name=name,
                                 sim_ws=gridgen_ws,
                                 exe_name="mf6")
    gwf = flopy.mf6.ModflowGwf(sim, modelname=name)

    dis = flopy.mf6.ModflowGwfdis(
        gwf,
        nlay=nlay,
        nrow=nrow,
        ncol=ncol,
        delr=delr,
        delc=delc,
        top=top,
        botm=botm,
    )

    # Create and build the gridgen model with a refined area in the middle
    g = Gridgen(dis, model_ws=gridgen_ws)
    polys = [Polygon([(4, 4), (6, 4), (6, 6), (4, 6)])]
    g.add_refinement_features(polys, "polygon", 3, layers=[0])
    g.build()
    disu_gridprops = g.get_gridprops_disu6()

    chdspd = []
    for x, y, head in [(0, 10, 1.0), (10, 0, 0.0)]:
        ra = g.intersect([(x, y)], "point", 0)
        ic = ra["nodenumber"][0]
        chdspd.append([(ic, ), head])

    # build run and post-process the MODFLOW 6 model
    ws = os.path.join(tpth, "gridgen_disu")
    name = "mymodel"
    sim = flopy.mf6.MFSimulation(
        sim_name=name,
        sim_ws=ws,
        exe_name="mf6",
        verbosity_level=VERBOSITY_LEVEL,
    )
    tdis = flopy.mf6.ModflowTdis(sim)
    ims = flopy.mf6.ModflowIms(sim, linear_acceleration="bicgstab")
    gwf = flopy.mf6.ModflowGwf(sim, modelname=name, save_flows=True)
    disu = flopy.mf6.ModflowGwfdisu(gwf, **disu_gridprops)
    ic = flopy.mf6.ModflowGwfic(gwf)
    npf = flopy.mf6.ModflowGwfnpf(gwf,
                                  xt3doptions=True,
                                  save_specific_discharge=True)
    chd = flopy.mf6.ModflowGwfchd(gwf, stress_period_data=chdspd)
    budget_file = name + ".bud"
    head_file = name + ".hds"
    oc = flopy.mf6.ModflowGwfoc(
        gwf,
        budget_filerecord=budget_file,
        head_filerecord=head_file,
        saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")],
    )
    sim.write_simulation()

    gwf.modelgrid.set_coord_info(angrot=15)

    # The flopy Gridgen object includes the plottable layer number to the
    # diagonal position in the ihc array.  This is why and how modelgrid.nlay
    # is set to 3 and ncpl has a different number of cells per layer.
    assert gwf.modelgrid.nlay == 3
    assert np.allclose(gwf.modelgrid.ncpl, np.array([436, 184, 112]))

    # write grid and model shapefiles
    fname = os.path.join(ws, "grid.shp")
    gwf.modelgrid.write_shapefile(fname)
    fname = os.path.join(ws, "model.shp")
    gwf.export(fname)

    if mf6_exe is not None:
        sim.run_simulation(silent=True)
        head = flopy.utils.HeadFile(os.path.join(ws, head_file)).get_data()
        bud = flopy.utils.CellBudgetFile(os.path.join(ws, budget_file),
                                         precision="double")
        spdis = bud.get_data(text="DATA-SPDIS")[0]

        if matplotlib is not None:
            f = plt.figure(figsize=(10, 10))
            vmin = head.min()
            vmax = head.max()
            for ilay in range(gwf.modelgrid.nlay):
                ax = plt.subplot(1, gwf.modelgrid.nlay, ilay + 1)
                pmv = flopy.plot.PlotMapView(gwf, layer=ilay, ax=ax)
                ax.set_aspect("equal")
                pmv.plot_array(head.flatten(),
                               cmap="jet",
                               vmin=vmin,
                               vmax=vmax)
                pmv.plot_grid(colors="k", alpha=0.1)
                pmv.contour_array(
                    head,
                    levels=[0.2, 0.4, 0.6, 0.8],
                    linewidths=3.0,
                    vmin=vmin,
                    vmax=vmax,
                )
                ax.set_title("Layer {}".format(ilay + 1))
                pmv.plot_specific_discharge(spdis, color="white")
            fname = "results.png"
            fname = os.path.join(ws, fname)
            plt.savefig(fname)
            plt.close("all")

    return