|
30 | 30 | import os |
31 | 31 | import sys |
32 | 32 | from pathlib import Path |
| 33 | +from pprint import pformat |
33 | 34 | from tempfile import TemporaryDirectory |
34 | 35 |
|
35 | 36 | import numpy as np |
36 | 37 |
|
37 | 38 | import flopy |
38 | 39 | from flopy.export import vtk |
39 | 40 |
|
40 | | -sys.path.append(os.path.join("..", "common")) |
41 | | -import notebook_utils |
42 | | - |
43 | 41 | print(sys.version) |
44 | 42 | print(f"flopy version: {flopy.__version__}") |
45 | 43 | # - |
46 | 44 |
|
47 | 45 | # load model for examples |
48 | 46 | nam_file = "freyberg.nam" |
49 | | -prj_root = notebook_utils.get_project_root_path() |
50 | | -model_ws = prj_root / "examples" / "data" / "freyberg_multilayer_transient" |
| 47 | +model_ws = Path( |
| 48 | + os.path.join( |
| 49 | + "..", "..", "examples", "data", "freyberg_multilayer_transient" |
| 50 | + ) |
| 51 | +) |
51 | 52 | ml = flopy.modflow.Modflow.load(nam_file, model_ws=model_ws, check=False) |
52 | 53 |
|
53 | 54 | # Create a temporary workspace. |
|
375 | 376 | # |
376 | 377 | # The `Vtk` class supports writing MODPATH pathline/timeseries data to a VTK file. To start the example, let's first load and run a MODPATH simulation (see flopy3_modpath7_unstructured_example for details) and then add the output to a `Vtk` object. |
377 | 378 |
|
| 379 | + |
378 | 380 | # + |
379 | 381 | # load and run the vertex grid model and modpath7 |
380 | | -notebook_utils.run(workspace) |
| 382 | +def run_vertex_grid_example(ws): |
| 383 | + """load and run vertex grid example""" |
| 384 | + if not os.path.exists(ws): |
| 385 | + os.mkdir(ws) |
| 386 | + |
| 387 | + from flopy.utils.gridgen import Gridgen |
| 388 | + |
| 389 | + Lx = 10000.0 |
| 390 | + Ly = 10500.0 |
| 391 | + nlay = 3 |
| 392 | + nrow = 21 |
| 393 | + ncol = 20 |
| 394 | + delr = Lx / ncol |
| 395 | + delc = Ly / nrow |
| 396 | + top = 400 |
| 397 | + botm = [220, 200, 0] |
| 398 | + |
| 399 | + ms = flopy.modflow.Modflow() |
| 400 | + dis5 = flopy.modflow.ModflowDis( |
| 401 | + ms, |
| 402 | + nlay=nlay, |
| 403 | + nrow=nrow, |
| 404 | + ncol=ncol, |
| 405 | + delr=delr, |
| 406 | + delc=delc, |
| 407 | + top=top, |
| 408 | + botm=botm, |
| 409 | + ) |
| 410 | + |
| 411 | + model_name = "mp7p2" |
| 412 | + model_ws = os.path.join(ws, "mp7_ex2", "mf6") |
| 413 | + gridgen_ws = os.path.join(model_ws, "gridgen") |
| 414 | + g = Gridgen(ms.modelgrid, model_ws=gridgen_ws) |
| 415 | + |
| 416 | + rf0shp = os.path.join(gridgen_ws, "rf0") |
| 417 | + xmin = 7 * delr |
| 418 | + xmax = 12 * delr |
| 419 | + ymin = 8 * delc |
| 420 | + ymax = 13 * delc |
| 421 | + rfpoly = [ |
| 422 | + [ |
| 423 | + [ |
| 424 | + (xmin, ymin), |
| 425 | + (xmax, ymin), |
| 426 | + (xmax, ymax), |
| 427 | + (xmin, ymax), |
| 428 | + (xmin, ymin), |
| 429 | + ] |
| 430 | + ] |
| 431 | + ] |
| 432 | + g.add_refinement_features(rfpoly, "polygon", 1, range(nlay)) |
| 433 | + |
| 434 | + rf1shp = os.path.join(gridgen_ws, "rf1") |
| 435 | + xmin = 8 * delr |
| 436 | + xmax = 11 * delr |
| 437 | + ymin = 9 * delc |
| 438 | + ymax = 12 * delc |
| 439 | + rfpoly = [ |
| 440 | + [ |
| 441 | + [ |
| 442 | + (xmin, ymin), |
| 443 | + (xmax, ymin), |
| 444 | + (xmax, ymax), |
| 445 | + (xmin, ymax), |
| 446 | + (xmin, ymin), |
| 447 | + ] |
| 448 | + ] |
| 449 | + ] |
| 450 | + g.add_refinement_features(rfpoly, "polygon", 2, range(nlay)) |
| 451 | + |
| 452 | + rf2shp = os.path.join(gridgen_ws, "rf2") |
| 453 | + xmin = 9 * delr |
| 454 | + xmax = 10 * delr |
| 455 | + ymin = 10 * delc |
| 456 | + ymax = 11 * delc |
| 457 | + rfpoly = [ |
| 458 | + [ |
| 459 | + [ |
| 460 | + (xmin, ymin), |
| 461 | + (xmax, ymin), |
| 462 | + (xmax, ymax), |
| 463 | + (xmin, ymax), |
| 464 | + (xmin, ymin), |
| 465 | + ] |
| 466 | + ] |
| 467 | + ] |
| 468 | + g.add_refinement_features(rfpoly, "polygon", 3, range(nlay)) |
| 469 | + |
| 470 | + g.build(verbose=False) |
| 471 | + |
| 472 | + gridprops = g.get_gridprops_disv() |
| 473 | + ncpl = gridprops["ncpl"] |
| 474 | + top = gridprops["top"] |
| 475 | + botm = gridprops["botm"] |
| 476 | + nvert = gridprops["nvert"] |
| 477 | + vertices = gridprops["vertices"] |
| 478 | + cell2d = gridprops["cell2d"] |
| 479 | + # cellxy = gridprops['cellxy'] |
| 480 | + |
| 481 | + # create simulation |
| 482 | + sim = flopy.mf6.MFSimulation( |
| 483 | + sim_name=model_name, version="mf6", exe_name="mf6", sim_ws=model_ws |
| 484 | + ) |
| 485 | + |
| 486 | + # create tdis package |
| 487 | + tdis_rc = [(1000.0, 1, 1.0)] |
| 488 | + tdis = flopy.mf6.ModflowTdis( |
| 489 | + sim, pname="tdis", time_units="DAYS", perioddata=tdis_rc |
| 490 | + ) |
| 491 | + |
| 492 | + # create gwf model |
| 493 | + gwf = flopy.mf6.ModflowGwf( |
| 494 | + sim, modelname=model_name, model_nam_file=f"{model_name}.nam" |
| 495 | + ) |
| 496 | + gwf.name_file.save_flows = True |
| 497 | + |
| 498 | + # create iterative model solution and register the gwf model with it |
| 499 | + ims = flopy.mf6.ModflowIms( |
| 500 | + sim, |
| 501 | + pname="ims", |
| 502 | + print_option="SUMMARY", |
| 503 | + complexity="SIMPLE", |
| 504 | + outer_hclose=1.0e-5, |
| 505 | + outer_maximum=100, |
| 506 | + under_relaxation="NONE", |
| 507 | + inner_maximum=100, |
| 508 | + inner_hclose=1.0e-6, |
| 509 | + rcloserecord=0.1, |
| 510 | + linear_acceleration="BICGSTAB", |
| 511 | + scaling_method="NONE", |
| 512 | + reordering_method="NONE", |
| 513 | + relaxation_factor=0.99, |
| 514 | + ) |
| 515 | + sim.register_ims_package(ims, [gwf.name]) |
| 516 | + |
| 517 | + # disv |
| 518 | + disv = flopy.mf6.ModflowGwfdisv( |
| 519 | + gwf, |
| 520 | + nlay=nlay, |
| 521 | + ncpl=ncpl, |
| 522 | + top=top, |
| 523 | + botm=botm, |
| 524 | + nvert=nvert, |
| 525 | + vertices=vertices, |
| 526 | + cell2d=cell2d, |
| 527 | + ) |
| 528 | + |
| 529 | + # initial conditions |
| 530 | + ic = flopy.mf6.ModflowGwfic(gwf, pname="ic", strt=320.0) |
| 531 | + |
| 532 | + # node property flow |
| 533 | + npf = flopy.mf6.ModflowGwfnpf( |
| 534 | + gwf, |
| 535 | + xt3doptions=[("xt3d")], |
| 536 | + save_specific_discharge=True, |
| 537 | + icelltype=[1, 0, 0], |
| 538 | + k=[50.0, 0.01, 200.0], |
| 539 | + k33=[10.0, 0.01, 20.0], |
| 540 | + ) |
| 541 | + |
| 542 | + # wel |
| 543 | + wellpoints = [(4750.0, 5250.0)] |
| 544 | + welcells = g.intersect(wellpoints, "point", 0) |
| 545 | + # welspd = flopy.mf6.ModflowGwfwel.stress_period_data.empty(gwf, maxbound=1, aux_vars=['iface']) |
| 546 | + welspd = [[(2, icpl), -150000, 0] for icpl in welcells["nodenumber"]] |
| 547 | + wel = flopy.mf6.ModflowGwfwel( |
| 548 | + gwf, |
| 549 | + print_input=True, |
| 550 | + auxiliary=[("iface",)], |
| 551 | + stress_period_data=welspd, |
| 552 | + ) |
| 553 | + |
| 554 | + # rch |
| 555 | + aux = [np.ones(ncpl, dtype=int) * 6] |
| 556 | + rch = flopy.mf6.ModflowGwfrcha( |
| 557 | + gwf, recharge=0.005, auxiliary=[("iface",)], aux={0: [6]} |
| 558 | + ) |
| 559 | + # riv |
| 560 | + riverline = [[(Lx - 1.0, Ly), (Lx - 1.0, 0.0)]] |
| 561 | + rivcells = g.intersect(riverline, "line", 0) |
| 562 | + rivspd = [ |
| 563 | + [(0, icpl), 320.0, 100000.0, 318] for icpl in rivcells["nodenumber"] |
| 564 | + ] |
| 565 | + riv = flopy.mf6.ModflowGwfriv(gwf, stress_period_data=rivspd) |
| 566 | + |
| 567 | + # output control |
| 568 | + oc = flopy.mf6.ModflowGwfoc( |
| 569 | + gwf, |
| 570 | + pname="oc", |
| 571 | + budget_filerecord=f"{model_name}.cbb", |
| 572 | + head_filerecord=f"{model_name}.hds", |
| 573 | + headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], |
| 574 | + saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], |
| 575 | + printrecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], |
| 576 | + ) |
| 577 | + |
| 578 | + sim.write_simulation() |
| 579 | + success, buff = sim.run_simulation(silent=True, report=True) |
| 580 | + if success: |
| 581 | + for line in buff: |
| 582 | + print(line) |
| 583 | + else: |
| 584 | + raise ValueError("Failed to run.") |
| 585 | + |
| 586 | + mp_namea = f"{model_name}a_mp" |
| 587 | + mp_nameb = f"{model_name}b_mp" |
| 588 | + |
| 589 | + pcoord = np.array( |
| 590 | + [ |
| 591 | + [0.000, 0.125, 0.500], |
| 592 | + [0.000, 0.375, 0.500], |
| 593 | + [0.000, 0.625, 0.500], |
| 594 | + [0.000, 0.875, 0.500], |
| 595 | + [1.000, 0.125, 0.500], |
| 596 | + [1.000, 0.375, 0.500], |
| 597 | + [1.000, 0.625, 0.500], |
| 598 | + [1.000, 0.875, 0.500], |
| 599 | + [0.125, 0.000, 0.500], |
| 600 | + [0.375, 0.000, 0.500], |
| 601 | + [0.625, 0.000, 0.500], |
| 602 | + [0.875, 0.000, 0.500], |
| 603 | + [0.125, 1.000, 0.500], |
| 604 | + [0.375, 1.000, 0.500], |
| 605 | + [0.625, 1.000, 0.500], |
| 606 | + [0.875, 1.000, 0.500], |
| 607 | + ] |
| 608 | + ) |
| 609 | + nodew = gwf.disv.ncpl.array * 2 + welcells["nodenumber"][0] |
| 610 | + plocs = [nodew for i in range(pcoord.shape[0])] |
| 611 | + |
| 612 | + # create particle data |
| 613 | + pa = flopy.modpath.ParticleData( |
| 614 | + plocs, |
| 615 | + structured=False, |
| 616 | + localx=pcoord[:, 0], |
| 617 | + localy=pcoord[:, 1], |
| 618 | + localz=pcoord[:, 2], |
| 619 | + drape=0, |
| 620 | + ) |
| 621 | + |
| 622 | + # create backward particle group |
| 623 | + fpth = f"{mp_namea}.sloc" |
| 624 | + pga = flopy.modpath.ParticleGroup( |
| 625 | + particlegroupname="BACKWARD1", particledata=pa, filename=fpth |
| 626 | + ) |
| 627 | + |
| 628 | + facedata = flopy.modpath.FaceDataType( |
| 629 | + drape=0, |
| 630 | + verticaldivisions1=10, |
| 631 | + horizontaldivisions1=10, |
| 632 | + verticaldivisions2=10, |
| 633 | + horizontaldivisions2=10, |
| 634 | + verticaldivisions3=10, |
| 635 | + horizontaldivisions3=10, |
| 636 | + verticaldivisions4=10, |
| 637 | + horizontaldivisions4=10, |
| 638 | + rowdivisions5=0, |
| 639 | + columndivisions5=0, |
| 640 | + rowdivisions6=4, |
| 641 | + columndivisions6=4, |
| 642 | + ) |
| 643 | + pb = flopy.modpath.NodeParticleData(subdivisiondata=facedata, nodes=nodew) |
| 644 | + # create forward particle group |
| 645 | + fpth = f"{mp_nameb}.sloc" |
| 646 | + pgb = flopy.modpath.ParticleGroupNodeTemplate( |
| 647 | + particlegroupname="BACKWARD2", particledata=pb, filename=fpth |
| 648 | + ) |
| 649 | + |
| 650 | + # create modpath files |
| 651 | + mp = flopy.modpath.Modpath7( |
| 652 | + modelname=mp_namea, flowmodel=gwf, exe_name="mp7", model_ws=model_ws |
| 653 | + ) |
| 654 | + flopy.modpath.Modpath7Bas(mp, porosity=0.1) |
| 655 | + flopy.modpath.Modpath7Sim( |
| 656 | + mp, |
| 657 | + simulationtype="combined", |
| 658 | + trackingdirection="backward", |
| 659 | + weaksinkoption="pass_through", |
| 660 | + weaksourceoption="pass_through", |
| 661 | + referencetime=0.0, |
| 662 | + stoptimeoption="extend", |
| 663 | + timepointdata=[500, 1000.0], |
| 664 | + particlegroups=pga, |
| 665 | + ) |
| 666 | + |
| 667 | + # write modpath datasets |
| 668 | + mp.write_input() |
| 669 | + |
| 670 | + # run modpath |
| 671 | + success, buff = mp.run_model(silent=True, report=True) |
| 672 | + if success: |
| 673 | + for line in buff: |
| 674 | + print(line) |
| 675 | + else: |
| 676 | + raise ValueError("Failed to run.") |
| 677 | + |
| 678 | + # create modpath files |
| 679 | + mp = flopy.modpath.Modpath7( |
| 680 | + modelname=mp_nameb, flowmodel=gwf, exe_name="mp7", model_ws=model_ws |
| 681 | + ) |
| 682 | + flopy.modpath.Modpath7Bas(mp, porosity=0.1) |
| 683 | + flopy.modpath.Modpath7Sim( |
| 684 | + mp, |
| 685 | + simulationtype="endpoint", |
| 686 | + trackingdirection="backward", |
| 687 | + weaksinkoption="pass_through", |
| 688 | + weaksourceoption="pass_through", |
| 689 | + referencetime=0.0, |
| 690 | + stoptimeoption="extend", |
| 691 | + particlegroups=pgb, |
| 692 | + ) |
| 693 | + |
| 694 | + # write modpath datasets |
| 695 | + mp.write_input() |
| 696 | + |
| 697 | + # run modpath |
| 698 | + success, buff = mp.run_model(silent=True, report=True) |
| 699 | + assert success, pformat(buff) |
| 700 | + |
| 701 | + |
| 702 | +run_vertex_grid_example(workspace) |
381 | 703 |
|
382 | 704 | # check if model ran properly |
383 | 705 | modelpth = workspace / "mp7_ex2" / "mf6" |
|
0 commit comments