示例#1
0
def get_cstrt(nlay, ncol, length, x1, x2, a1, a2, b, c1, c2, c3):
    cstrt = c1 * np.ones((nlay, ncol), dtype=float)
    from flopy.utils.gridintersect import GridIntersect
    from shapely.geometry import Polygon

    p3 = Polygon([(0, b), (x2 - a2, b), (x2 + a2, 0), (0, 0)])
    p2 = Polygon([(x2 - a2, b), (x1 - a1, b), (x1 + a1, 0), (x1 - a1, 0)])
    delc = b / nlay * np.ones(nlay)
    delr = length / ncol * np.ones(ncol)
    sgr = flopy.discretization.StructuredGrid(delc, delr)
    ix = GridIntersect(sgr, method="structured")
    for ival, p in [(c2, p2), (c3, p3)]:
        result = ix.intersect(p)
        for i, j in list(result["cellids"]):
            cstrt[i, j] = ival
    return cstrt
示例#2
0
def test_tri_grid_linestring_on_inner_boundary(rtree=True):
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_tri_grid()
    if gr == -1:
        return
    ix = GridIntersect(gr, rtree=rtree)
    result = ix.intersect(LineString([(5.0, 10.0), (15.0, 10.0)]))
    assert len(result) == 2
    assert result.lengths.sum() == 10.0
    assert result.cellids[0] == 0
    assert result.cellids[1] == 1
    return result
示例#3
0
def test_rect_grid_polygon_with_hole_shapely(rtree=True):
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_rect_grid()
    ix = GridIntersect(gr, method="vertex", rtree=rtree)
    p = Polygon(
        [(5.0, 5.0), (5.0, 15.0), (25.0, 15.0), (25.0, -5.0), (5.0, -5.0)],
        holes=[[(9.0, -1), (9, 11), (21, 11), (21, -1)]],
    )
    result = ix.intersect(p)
    assert len(result) == 3
    assert result.areas.sum() == 104.0
    return result
示例#4
0
def test_rect_grid_linestring_in_and_out_of_cell2():
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_rect_grid()
    ix = GridIntersect(gr, method="structured")
    result = ix.intersect(
        LineString([(5, 15), (5.0, 9), (15.0, 5.0), (5.0, 1.0)])
    )
    assert len(result) == 3
    # assert result.cellids[0] == (1, 0)
    # assert result.cellids[1] == (1, 1)
    # assert np.allclose(result.lengths.sum(), 21.540659228538015)
    return result
示例#5
0
def test_tri_grid_polygon_with_hole(rtree=True):
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_tri_grid()
    if gr == -1:
        return
    ix = GridIntersect(gr, rtree=rtree)
    p = Polygon([(5., 5.), (5., 15.), (25., 15.), (25., -5.), (5., -5.)],
                holes=[[(9., -1), (9, 11), (21, 11), (21, -1)]])
    result = ix.intersect(p)
    assert len(result) == 6
    assert result.areas.sum() == 104.
    return result
示例#6
0
def test_tri_grid_linestring_in_2cells(rtree=True):
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_tri_grid()
    if gr == -1:
        return
    ix = GridIntersect(gr, rtree=rtree)
    result = ix.intersect(LineString([(5., 5.), (5., 15.)]))
    assert len(result) == 2
    assert result.lengths.sum() == 10.
    assert result.cellids[0] == 1
    assert result.cellids[1] == 3
    return result
def test_tri_grid_linestring_on_inner_boundary():
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_tri_grid(triangle_exe=triangle_exe)
    if gr == -1:
        return
    ix = GridIntersect(gr)
    result = ix.intersect_linestring(LineString([(5., 10.), (15., 10.)]))
    assert len(result) == 2
    assert result.lengths.sum() == 10.
    assert result.cellids[0] == 0
    assert result.cellids[1] == 1
    return result
示例#8
0
def test_tri_grid_polygon_in_2cells(rtree=True):
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_tri_grid()
    if gr == -1:
        return
    ix = GridIntersect(gr, rtree=rtree)
    result = ix.intersect(
        Polygon([(2.5, 5.0), (5.0, 5.0), (5.0, 15.0), (2.5, 15.0)])
    )
    assert len(result) == 2
    assert result.areas.sum() == 25.0
    return result
示例#9
0
def test_rect_grid_multilinestring_in_one_cell_shapely(rtree=True):
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_rect_grid()
    ix = GridIntersect(gr, method='vertex', rtree=rtree)
    result = ix.intersect(
        MultiLineString([
            LineString([(1., 1), (9., 1.)]),
            LineString([(1., 9.), (9., 9.)])
        ]))
    assert len(result) == 1
    assert result.lengths == 16.
    assert result.cellids[0] == (1, 0)
    return result
示例#10
0
def test_tri_grid_multipolygon_in_multiple_cells(rtree=True):
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_tri_grid()
    if gr == -1:
        return
    ix = GridIntersect(gr, rtree=rtree)
    p1 = Polygon([(1., 1.), (19., 1.), (19., 3.), (1., 3.)])
    p2 = Polygon([(1., 9.), (19., 9.), (19., 7.), (1., 7.)])
    p = MultiPolygon([p1, p2])
    result = ix.intersect(p)
    assert len(result) == 4
    assert result.areas.sum() == 72.
    return result
示例#11
0
def test_tri_grid_multipolygon_in_one_cell(rtree=True):
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_tri_grid()
    if gr == -1:
        return
    ix = GridIntersect(gr, rtree=rtree)
    p1 = Polygon([(1.0, 1.0), (8.0, 1.0), (8.0, 3.0), (3.0, 3.0)])
    p2 = Polygon([(5.0, 5.0), (8.0, 5.0), (8.0, 8.0)])
    p = MultiPolygon([p1, p2])
    result = ix.intersect(p)
    assert len(result) == 1
    assert result.areas.sum() == 16.5
    return result
def test_tri_grid_multipolygon_in_one_cell():
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_tri_grid(triangle_exe=triangle_exe)
    if gr == -1:
        return
    ix = GridIntersect(gr)
    p1 = Polygon([(1., 1.), (8., 1.), (8., 3.), (3., 3.)])
    p2 = Polygon([(5., 5.), (8., 5.), (8., 8.)])
    p = MultiPolygon([p1, p2])
    result = ix.intersect_polygon(p)
    assert len(result) == 1
    assert result.areas.sum() == 16.5
    return result
示例#13
0
def test_polygon_offset_rot_structured_grid_shapely(rtree=True):
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    sgr = get_rect_grid(angrot=45.0, xyoffset=10.0)
    p = Polygon(
        [
            (5, 10.0 + np.sqrt(200.0)),
            (15, 10.0 + np.sqrt(200.0)),
            (15, 10.0 + 1.5 * np.sqrt(200.0)),
            (5, 10.0 + 1.5 * np.sqrt(200.0)),
        ]
    )
    ix = GridIntersect(sgr, method="vertex", rtree=rtree)
    result = ix.intersect(p)
    # assert len(result) == 3.
    return result
示例#14
0
def test_tri_grid_multilinestring_in_one_cell(rtree=True):
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_tri_grid()
    if gr == -1:
        return
    ix = GridIntersect(gr, rtree=rtree)
    result = ix.intersect(
        MultiLineString([
            LineString([(1., 1), (9., 1.)]),
            LineString([(2., 2.), (9., 2.)])
        ]))
    assert len(result) == 1
    assert result.lengths == 15.
    assert result.cellids[0] == 4
    return result
示例#15
0
def test_rect_grid_multilinestring_in_one_cell():
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_rect_grid()
    ix = GridIntersect(gr, method="structured")
    result = ix.intersect(
        MultiLineString(
            [
                LineString([(1.0, 1), (9.0, 1.0)]),
                LineString([(1.0, 9.0), (9.0, 9.0)]),
            ]
        )
    )
    assert len(result) == 1
    assert result.lengths == 16.0
    assert result.cellids[0] == (1, 0)
    return result
示例#16
0
def gp2cellids(grid,
               gp,
               idomain,
               idomain_active=True,
               type="polygon",
               layer=0,
               areas=3):
    """
    this function extract the cellids of the intersection between a geopandas object and a grid 
    grid : modelgrid
    gp : geopandas object (polygon, linestring only)
    idomain : the idomain array to update it
    idomain_active : bool, if true the idomain is update (cells intersect by the gp will be noted as active), prevents some issues
    type : str, features type (polygon or line)
    layer : int, the layer on which is the gp
    areas : factor that determine if a cell is accounted intersected or not based on the total area intersected in this cell 
    (a value of 3, for example, mean only cells which have 1/3 of their area intersected by the polygon will be taken into account)
    """

    ix = GridIntersect(grid)
    if type == "polygon":
        result = ix.intersect_polygon(gp.geometry[0])
        result = result[result.areas > (
            np.max(result.areas) / 3
        )]  # only take into account cells that have a least 1/3 intersected
        result = result[result.areas != 0]  # fix bug

    if type == "boundary":
        result = ix.intersect_linestring(gp.geometry[0].boundary)

    if type == "line":
        result = ix.intersect_linestring(gp.geometry[0])

    lst = []

    for irow, icol in result.cellids:
        lst.append(((layer, irow, icol)))
        if idomain_active:
            idomain[irow * grid.ncol + icol] = 1
    return lst
示例#17
0
def test_rect_grid_polygon_in_edge_in_cell(rtree=True):
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_rect_grid()
    ix = GridIntersect(gr, method="vertex", rtree=rtree)
    p = Polygon(
        [
            (0.0, 5.0),
            (3.0, 0.0),
            (7.0, 0.0),
            (10.0, 5.0),
            (10.0, -1.0),
            (0.0, -1.0),
        ]
    )
    result = ix.intersect(p)
    assert len(result) == 1
    assert result.areas.sum() == 15.0
    return result
示例#18
0
def gp2cellids (grid, gp, idomain, idomain_active=True, type = "polygon",layer=0,areas=3):
    """
    this function extract the cellids of the intersection between a geopandas object and a grid 
    """
    
    ix = GridIntersect(grid)
    if type == "polygon":
        result = ix.intersect_polygon(gp.geometry[0])
        result = result[result.areas>(np.max(result.areas)/3)] # only take into account cells that have a least 1/3 intersected by the polygon
        
    if type == "boundary" :
        result = ix.intersect_linestring(gp.geometry[0].boundary)

        
    if type == "line" :
        result = ix.intersect_linestring(gp.geometry[0])
        
    lst=[];
    for irow, icol in result.cellids:
        lst.append(((layer,irow,icol)))
        if idomain_active:
            idomain[irow*grid.ncol+icol] = 1
    return lst
示例#19
0
def importWells3D(path,
                  grid,
                  lst_domain,
                  fac=1 / 365 / 86400,
                  V_col="V Bancaris",
                  geol_col="NAPPE_CAPT",
                  geol_layer=["PLIOCENE", "QUATERNAIRE"],
                  layer_num=[1, 0]):
    """
    extract the infos about the amount of water uptake by wells
    path : path to the shp (multi points required)
    grid : the modelgrid
    fac : the factor to transform volume units to get m3/s (depends of original units)
    V_col : the column name containing info about Volume
    geol_col = the column name containing geol infos
    geol_layer : the name of the differents lithology encountered 
    layer_num : the num layer corresponding to the lithology in geol_layer
    """

    ix = GridIntersect(grid)
    BD_prlvm = gp.read_file(path)
    stress_data_well = []

    for ilayer in range(len(geol_layer)):  # iterate through layers
        BD = BD_prlvm[BD_prlvm[geol_col] == geol_layer[
            ilayer]]  # only keep layers with the right geol
        for o in BD.index:  #iterate through each well
            Vw = BD.loc[o, V_col]
            if not (np.isnan(Vw)) | (Vw == 0):  #keep productive well
                cellidx = ix.intersect_point(BD.geometry[o]).cellids[0][0]
                cellidy = ix.intersect_point(BD.geometry[o]).cellids[0][1]
                cellid = (layer_num[ilayer], cellidx, cellidy
                          )  #cell on which the well is active
                if cellid in lst_domain:  # check if the well is in the domain
                    stress_data_well.append((cellid, -fac * Vw))

    return stress_data_well
示例#20
0
def test_rect_vertex_grid_point_in_one_cell_shapely(rtree=True):
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_rect_vertex_grid()
    ix = GridIntersect(gr, method='vertex', rtree=rtree)
    result = ix.intersect(Point(4., 4.))
    assert len(result) == 1
    assert result.cellids[0] == 0
    result = ix.intersect(Point(4., 6.))
    assert len(result) == 1
    assert result.cellids[0] == 0
    result = ix.intersect(Point(6., 6.))
    assert len(result) == 1
    assert result.cellids[0] == 0
    result = ix.intersect(Point(6., 4.))
    assert len(result) == 1
    assert result.cellids[0] == 0
    return result
示例#21
0
def gp2idomain(gp, grid, idomain, area=0, layer=0, method="none"):
    '''
    This function attribute active values to cells given a certain geopandas object and a grid (flopy.discretization) with idomain
    the area is a value that determine at which level a cell will be counted as intersected by the polygon 
    (3 for example mean that only cells that have 1/3 of their area intersected by the polygon will be accounted)
    '''
    if method == "none":
        ix = GridIntersect(grid)
    if method == "structured":
        ix = GridIntersect(grid, method=method)

    if area == 0:
        result = ix.intersect_polygon(gp.geometry[0])

    if area >= 1:
        result = ix.intersect_polygon(gp.geometry[0])
        result = result[result.areas > (np.max(result.areas) / area)]

    lst = []
    for irow, icol in result.cellids:
        idomain[irow * grid.ncol + icol] = 1
        lst.append(((layer, irow, icol)))
    return lst
示例#22
0
ss_4="ss_roc.txt"



# we are including the qbg hydraulic conductivity  by using shapes
gravoso=sf.Reader(path_sh+"/Superficies/Cont_Qbg2.shp")
gravoso1=gravoso.shapeRecords()[0]
firstkg=gravoso1.shape.__geo_interface__
# print(firstd)
shp_geomkg=shape(firstkg)


# now we use shapely to instersect
# plt.figure()
gwf.modelgrid.plot()
ix = GridIntersect(gwf.modelgrid, method="structured", rtree=False)

resultkg= ix.intersect(shp_geomkg)
gravoso_cells=[]
for i in range(resultkg.shape[0]):
    gravoso_cells.append([*resultkg["cellids"][i]])#hay que revisar si la tupla quedó mal

# creating the idomain matrix
domin_grav=np.zeros((nrows,ncols))
# print(nlay,nrows,ncols)
for i, value in enumerate(gravoso_cells):
    # print(i)
    # print(value)
    k_qd_qbg[tuple(value)]=1e-5
    ss_qd_qbg[tuple(value)]=1e-4
    sy_qd_qbg[tuple(value)]=1e-1
示例#23
0
def import_riv(grid, gp):
    """
    This function extract infos about a river (geopandas object, LINESTRING),cellids + lengths of in each cells in the right order. 
    Format : import_riv (Grid (from the gwf model, gwf.modelgrid for ex.), gp (a geopandas object containing a unique Linestring))
    Return a dataframe containing these datas, post-processing necessary to remove cells that are already counted as BC in the model
    """

    ix = GridIntersect(grid)
    coord_riv = []
    for x, y in zip(gp.geometry[0].xy[0], gp.geometry[0].xy[1]):
        coord_riv.append((x, y))

    verti = []
    df_tot_ord = pd.DataFrame()  # empty DF
    for i in range(len(coord_riv)):
        if i < len(coord_riv) - 1:
            lsi = LineString([coord_riv[i], coord_riv[i + 1]
                              ])  # create the linestring btw point i and i+1
            res = ix.intersect_linestring(lsi)  # do the intersection
            cellids = res.cellids  # extract cellids

            if len(
                    cellids
            ) > 1:  # if more than one cells is intersected --> we need to order them

                dirx = coord_riv[i + 1][0] - coord_riv[i][
                    0]  # Xdirection of the linestring

                for x, y in res.vertices:  # extract the 1st vertice of the intersections in order to organize
                    verti.append(x)
                vertix = np.array(verti)[:, 0]
                df = pd.DataFrame({
                    "cellids": cellids,
                    "vertix": vertix,
                    "lengths": res.lengths
                })  # create a DF to order
                verti = []

                #organize the cells given the direction
                if dirx > 0:
                    df.sort_values(by=["vertix"], ascending=True, inplace=True)
                if dirx < 0:
                    df.sort_values(by=["vertix"],
                                   ascending=False,
                                   inplace=True)

                # append these data in a big DF
                df_tot_ord = df_tot_ord.append(df).drop(["vertix"], axis=1)

            else:  # if only one cell is intersected by the linestring
                df_tot_ord = df_tot_ord.append(
                    pd.DataFrame({
                        "cellids": cellids,
                        "lengths": res.lengths
                    }))

    df_riv = df_tot_ord.groupby(["cellids"], sort=False).sum()

    # retrieve data
    lst_len_Riv = df_riv["lengths"].values

    cellids_Riv = []
    # list of all the cells intersected by the river
    cellids = df_riv.index
    for irow, icol in cellids:
        cell = (0, irow, icol)
        if cell not in cellids_Riv:
            cellids_Riv.append(cell)

    df_riv = pd.DataFrame({"cellids": cellids_Riv, "lengths": lst_len_Riv})

    return df_riv
示例#24
0
def build_model():
    if config.buildModel:
        sim_ws = os.path.join(ws, sim_name)
        sim = flopy.mf6.MFSimulation(
            sim_name=sim_name, sim_ws=sim_ws, exe_name=config.mf6_exe
        )
        flopy.mf6.ModflowTdis(
            sim, nper=nper, perioddata=tdis_ds, time_units=time_units
        )
        flopy.mf6.ModflowIms(
            sim,
            outer_maximum=nouter,
            outer_dvclose=hclose,
            inner_maximum=ninner,
            inner_dvclose=hclose,
            rcloserecord=[rclose, "strict"],
        )
        gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name, save_flows=True)
        flopy.mf6.ModflowGwfdis(
            gwf,
            length_units=length_units,
            nlay=nlay,
            nrow=nrow,
            ncol=ncol,
            delr=delr,
            delc=delc,
            top=top,
            botm=botm,
        )
        flopy.mf6.ModflowGwfnpf(
            gwf,
            cvoptions="perched",
            perched=True,
            icelltype=icelltype,
            k=k11,
            k33=k33,
            save_specific_discharge=True,
        )
        flopy.mf6.ModflowGwfic(gwf, strt=strt)
        flopy.mf6.ModflowGwfsto(
            gwf,
            iconvert=1,
            ss=1.0e-6,
            sy=sy,
            steady_state={0: True},
            transient={1: True},
        )

        ghb_spd = []
        ghb_spd += [
            [1, i, 9, "tides", 15.0, "ESTUARY-L2"] for i in range(nrow)
        ]
        ghb_spd += [
            [2, i, 9, "tides", 1500.0, "ESTUARY-L3"] for i in range(nrow)
        ]
        ghb_spd = {0: ghb_spd}
        fname = os.path.join(config.data_ws, sim_name, "tides.csv")
        tsdict = get_timeseries(fname, "tides", "linear")
        ghbobs_dict = {}
        ghbobs_dict["{}.ghb.obs.csv".format(sim_name)] = [
            ("ghb_2_6_10", "ghb", (1, 5, 9)),
            ("ghb_3_6_10", "ghb", (2, 5, 9)),
            ("estuary2", "ghb", "ESTUARY-L2"),
            ("estuary3", "ghb", "ESTUARY-L3"),
        ]

        flopy.mf6.ModflowGwfghb(
            gwf,
            stress_period_data=ghb_spd,
            boundnames=True,
            timeseries=tsdict,
            observations=ghbobs_dict,
            pname="GHB-TIDAL",
        )

        wel_spd = {}
        wel_spd[1] = [
            [0, 11, 2, -50, ""],
            [2, 4, 7, "well_1_rate", "well_1"],
            [2, 3, 2, "well_2_rate", "well_2"],
        ]
        wel_spd[2] = [
            [2, 3, 2, "well_2_rate", "well_2"],
            [2, 4, 7, "well_1_rate", "well_1"],
        ]
        wel_spd[3] = [
            [2, 4, 7, "well_1_rate", "well_1"],
            [2, 3, 2, "well_2_rate", "well_2"],
            [0, 11, 2, -10, ""],
            [0, 2, 4, -20, ""],
            [0, 13, 5, -40, ""],
        ]
        fname = os.path.join(config.data_ws, sim_name, "wellrates.csv")
        tsdict = get_timeseries(
            fname,
            ["well_1_rate", "well_2_rate", "well_6_rate"],
            3 * ["stepwise"],
        )
        flopy.mf6.ModflowGwfwel(
            gwf,
            stress_period_data=wel_spd,
            boundnames=True,
            timeseries=tsdict,
            pname="WEL",
        )

        rivlay = 20 * [0]
        rivrow = [2, 3, 4, 4, 5, 5, 5, 4, 4, 4, 9, 8, 7, 6, 6, 5, 5, 6, 6, 6]
        rivcol = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        rivstg = 10 * ["river_stage_1"] + 10 * ["river_stage_2"]
        rivcnd = 2 * [1000 + f + 1 for f in range(10)]
        rivrbt = list(np.linspace(35.9, 35.0, 10)) + list(
            np.linspace(36.9, 36.0, 10)
        )
        rivbnd = (
            5 * [""]
            + ["riv1_c6", "riv1_c7"]
            + 3 * [""]
            + 3 * ["riv2_upper"]
            + 2 * [""]
            + ["riv2_c6", "riv2_c7"]
            + 3 * [""]
        )
        riv_spd = list(
            zip(rivlay, rivrow, rivcol, rivstg, rivcnd, rivrbt, rivbnd)
        )
        fname = os.path.join(config.data_ws, sim_name, "riverstage.csv")
        tsdict = get_timeseries(
            fname, ["river_stage_1", "river_stage_2"], ["linear", "stepwise"],
        )
        flopy.mf6.ModflowGwfriv(
            gwf,
            stress_period_data=riv_spd,
            boundnames=True,
            timeseries=tsdict,
            pname="RIV",
        )

        for ipak, p in enumerate(
            [recharge_zone_1, recharge_zone_2, recharge_zone_3]
        ):
            ix = GridIntersect(gwf.modelgrid, method="vertex", rtree=True)
            result = ix.intersect(p)
            rch_spd = []
            for i in range(result.shape[0]):
                rch_spd.append(
                    [
                        0,
                        *result["cellids"][i],
                        "rch_{}".format(ipak + 1),
                        result["areas"][i] / delr / delc,
                    ]
                )
            fname = os.path.join(
                config.data_ws, sim_name, "recharge{}.csv".format(ipak + 1)
            )
            tsdict = get_timeseries(
                fname,
                ["rch_{}".format(ipak + 1)],
                ["stepwise"],
                filename="{}.rch{}.ts".format(sim_name, ipak + 1),
            )
            flopy.mf6.ModflowGwfrch(
                gwf,
                stress_period_data=rch_spd,
                boundnames=True,
                timeseries=tsdict,
                fixed_cell=True,
                print_input=True,
                print_flows=True,
                save_flows=True,
                auxiliary=["MULTIPLIER"],
                auxmultname="MULTIPLIER",
                pname="RCH-ZONE_{}".format(ipak + 1),
                filename="{}.rch{}".format(sim_name, ipak + 1),
            )

        nseg = 3
        etsurf = 50
        etrate = 0.0004
        depth = 10.0
        pxdp = [0.2, 0.5]
        petm = [0.3, 0.1]
        row, col = np.where(np.zeros((nrow, ncol)) == 0)
        cellids = list(zip(nrow * ncol * [0], row, col))
        evt_spd = [
            [k, i, j, etsurf, etrate, depth, *pxdp, *petm]
            for k, i, j in cellids
        ]
        flopy.mf6.ModflowGwfevt(
            gwf, nseg=nseg, stress_period_data=evt_spd, pname="EVT"
        )

        head_filerecord = "{}.hds".format(sim_name)
        budget_filerecord = "{}.cbc".format(sim_name)
        flopy.mf6.ModflowGwfoc(
            gwf,
            head_filerecord=head_filerecord,
            budget_filerecord=budget_filerecord,
            saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")],
        )

        obsdict = {}
        obslist = [["h1_13_8", "head", (2, 12, 7)]]
        obsdict["{}.obs.head.csv".format(sim_name)] = obslist
        obslist = [["icf1", "flow-ja-face", (0, 4, 5), (0, 5, 5)]]
        obsdict["{}.obs.flow.csv".format(sim_name)] = obslist
        obs = flopy.mf6.ModflowUtlobs(
            gwf, print_input=False, continuous=obsdict
        )

        return sim
    return None
示例#25
0
def build_model(sim_name):
    if config.buildModel:
        sim_ws = os.path.join(ws, sim_name)
        sim = flopy.mf6.MFSimulation(sim_name=sim_name,
                                     sim_ws=sim_ws,
                                     exe_name=config.mf6_exe)
        flopy.mf6.ModflowTdis(sim,
                              nper=nper,
                              perioddata=tdis_ds,
                              time_units=time_units)
        flopy.mf6.ModflowIms(
            sim,
            linear_acceleration="bicgstab",
            outer_maximum=nouter,
            outer_dvclose=hclose,
            inner_maximum=ninner,
            inner_dvclose=hclose,
            rcloserecord="{} strict".format(rclose),
        )
        gwf = flopy.mf6.ModflowGwf(sim, modelname=sim_name, save_flows=True)
        flopy.mf6.ModflowGwfdisv(
            gwf,
            length_units=length_units,
            nlay=nlay,
            top=top,
            botm=botm,
            **gridprops,
        )
        flopy.mf6.ModflowGwfnpf(
            gwf,
            icelltype=icelltype,
            k=k11,
            k33=k33,
            save_specific_discharge=True,
            xt3doptions=True,
        )
        flopy.mf6.ModflowGwfic(gwf, strt=strt)

        theta = np.arange(0.0, 2 * np.pi, 0.2)
        radius = 1500.0
        x = radius * np.cos(theta)
        y = radius * np.sin(theta)
        outer = [(x, y) for x, y in zip(x, y)]
        radius = 1025.0
        x = radius * np.cos(theta)
        y = radius * np.sin(theta)
        hole = [(x, y) for x, y in zip(x, y)]
        p = Polygon(outer, holes=[hole])
        ix = GridIntersect(gwf.modelgrid, method="vertex", rtree=True)
        result = ix.intersect(p)
        ghb_cellids = np.array(result["cellids"], dtype=int)

        ghb_spd = []
        ghb_spd += [[0, i, 0.0, k33 * cell_areas[i] / 10.0]
                    for i in ghb_cellids]
        ghb_spd = {0: ghb_spd}
        flopy.mf6.ModflowGwfghb(
            gwf,
            stress_period_data=ghb_spd,
            pname="GHB",
        )

        ncpl = gridprops["ncpl"]
        rchcells = np.array(list(range(ncpl)), dtype=int)
        rchcells[ghb_cellids] = -1
        rch_spd = [(0, rchcells[i], recharge) for i in range(ncpl)
                   if rchcells[i] > 0]
        rch_spd = {0: rch_spd}
        flopy.mf6.ModflowGwfrch(gwf, stress_period_data=rch_spd, pname="RCH")

        head_filerecord = "{}.hds".format(sim_name)
        budget_filerecord = "{}.cbc".format(sim_name)
        flopy.mf6.ModflowGwfoc(
            gwf,
            head_filerecord=head_filerecord,
            budget_filerecord=budget_filerecord,
            saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")],
        )

        return sim
    return None