diff --git a/.docs/Notebooks/feat_working_stack_examples.py b/.docs/Notebooks/feat_working_stack_examples.py index bf11f6afe..931121488 100644 --- a/.docs/Notebooks/feat_working_stack_examples.py +++ b/.docs/Notebooks/feat_working_stack_examples.py @@ -27,11 +27,14 @@ import matplotlib.pyplot as plt import numpy as np import pandas as pd - -# + +import pooch from IPython.display import clear_output, display -proj_root = Path.cwd().parent.parent +# First create a temporary workspace. + +# create a temporary workspace +temp_dir = TemporaryDirectory() +workspace = Path(temp_dir.name) # run installed version of flopy or add local path import flopy @@ -46,10 +49,34 @@ # ### Model Inputs # first lets load an existing model -model_ws = proj_root / "examples" / "data" / "freyberg_multilayer_transient" + +sim_name = "freyberg_multilayer_transient" +file_names = { + "freyberg.bas": "781585c140d40a27bce9369baee262c621bcf969de82361ad8d6b4d8c253ee02", + "freyberg.cbc": "d4e18e968cabde8470fcb7cb8a1c4cc57fcd643bd63b23e7751460bfdb651ea4", + "freyberg.ddn": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "freyberg.dis": "1ef61a467a219c036e58902ce11297e06b4eeb5f2f9d2ea40245b421a248a471", + "freyberg.drn": "93c22ab27d599938a8c2fc5b420ec03e5251b11b050d6ae1cb23ce2aa1b77997", + "freyberg.hds": "0b3e911ef35f625d2d046e05a20bc1300341b41028220c5b25ace6f5a267ceef", + "freyberg.list": "14ec36c22b48d253d6b82c44f36c5bad4f0785b3a3384b386f6b69c4ee2e31bf", + "freyberg.nam": "9e3747ce6d6229caec55a9357285a96cb4608dae11d90dd165a23e0bb394a2bd", + "freyberg.nwt": "d66c5cc255d050a0f871639af4af0cef8d48fa59c1c64217de65fc6e7fd78cb1", + "freyberg.oc": "faefd462d11b9a21c4579420b2156fb616ca642bc1e66fc5eb5e1b9046449e43", + "freyberg.rch": "93a12742a2d37961d53df0405e39cbecf0e6f14d45b5ca8cbba84a2d90828258", + "freyberg.upw": "80838be7af2f97c92965bad1d121c252b69d9c66e4885c5f3f49a6e99582deac", + "freyberg.wel": "dd322655eadff3f618f0835c9277af30720197bd48328aae2d6772f26eef2686", +} +for fname, fhash in file_names.items(): + pooch.retrieve( + url=f"https://github.com/modflowpy/flopy/raw/develop/examples/data/{sim_name}/{fname}", + fname=fname, + path=workspace, + known_hash=fhash, + ) + ml = flopy.modflow.Modflow.load( "freyberg.nam", - model_ws=model_ws, + model_ws=workspace, verbose=False, check=False, exe_name="mfnwt", @@ -66,11 +93,6 @@ ml.drn.plot(key="cond") ml.drn.plot(key="elev") -# First create a temporary workspace. - -# create a temporary workspace -temp_dir = TemporaryDirectory() -workspace = Path(temp_dir.name) # Write a shapefile of the DIS package. @@ -96,7 +118,7 @@ # # First, let's look at the list file. The list file summarizes the model's results. -mfl = flopy.utils.MfListBudget(model_ws / "freyberg.list") +mfl = flopy.utils.MfListBudget(workspace / "freyberg.list") df_flux, df_vol = mfl.get_dataframes(start_datetime="10-21-2015") df_flux @@ -116,7 +138,7 @@ # Now let's look at the simulated head. # if you pass the model instance, then the plots will be offset and rotated -h = flopy.utils.HeadFile(model_ws / "freyberg.hds", model=ml) +h = flopy.utils.HeadFile(workspace / "freyberg.hds", model=ml) h.times h.plot(totim=900, contour=True, grid=True, colorbar=True, figsize=(10, 10)) diff --git a/.docs/Notebooks/mf6_output_tutorial01.py b/.docs/Notebooks/mf6_output_tutorial01.py index 4044c1689..1982262ce 100644 --- a/.docs/Notebooks/mf6_output_tutorial01.py +++ b/.docs/Notebooks/mf6_output_tutorial01.py @@ -20,11 +20,12 @@ # by using the built in `.output` attribute on any MODFLOW 6 model or # package object -import os from pathlib import Path +from shutil import copytree from tempfile import TemporaryDirectory import numpy as np +import pooch # ## Package import import flopy @@ -32,9 +33,35 @@ # ## Load a simple demonstration model exe_name = "mf6" -project_root_path = Path.cwd().parent.parent -ws = os.path.abspath(os.path.dirname("")) -sim_ws = str(project_root_path / "examples" / "data" / "mf6" / "test001e_UZF_3lay") +sim_name = "test001e_UZF_3lay" + +temp_dir = TemporaryDirectory() +sim_ws = Path(temp_dir.name) + +files = { + "chd_spd.txt": "4d87f60022832372981caa2bd162681d5c4b8b3fcf8bc7f5de533c96ad1ed03c", + "mfsim.nam": "2f7889dedb9e7befb45251f08f015bd5531a4952f4141295ebad9e550be365fd", + "simulation.tdis": "d466787698c88b7f229cf244f2c9f226a87628c0a5748819e4e34fd4edc48d4c", + "test001e_UZF_3lay.chd": "96a00121e7004b152a03d0759bf4abfd70f8a1ea21cbce6b9441f18ce4d89b45", + "test001e_UZF_3lay.dis": "d2f879dcba84ec4be8883d6e29ea9197dd0e67c4058fdde7b9e1de737d1e0639", + "test001e_UZF_3lay.ic": "6e434a9d42ffe1b126b26890476f6893e9ab526f3a4ee96e63d443fd9008e1df", + "test001e_UZF_3lay.ims": "c4ef9ebe359def38f0e9ed810b61af0aae9a437c57d54b1db00b8dda20e5b67d", + "test001e_UZF_3lay.nam": "078ea7b0a774546a93c2cedfb98dc686395332ece7df6493653b072d43b4b834", + "test001e_UZF_3lay.npf": "89181af1fd91fe59ea931aae02fe64f855f27c705ee9200c8a9c23831aa7bace", + "test001e_UZF_3lay.obs": "b9857f604c0594a466255f040bd5a47a1687a69ae3be749488bd8736ead7d106", + "test001e_UZF_3lay.oc": "5eb327ead17588a1faa8b5c7dd37844f7a63d98351ef8bb41df1162c87a94d02", + "test001e_UZF_3lay.sto": "8d808d0c2ae4edc114455db3f1766446f9f9d6d3775c46a70369a57509bff811", + "test001e_UZF_3lay.uzf": "97624f1102abef4985bb40f432523df76bd94e069ac8a4aa17455d0d5b8f146e", + "test001e_UZF_3lay_obs.hed": "78c67035fc6f0c5c1d6090c1ce1e50dcab75b361e4ed44dc951f11fd3915a388", +} + +for fname, fhash in files.items(): + pooch.retrieve( + url=f"https://github.com/modflowpy/flopy/raw/develop/examples/data/mf6/{sim_name}/{fname}", + fname=fname, + path=sim_ws, + known_hash=fhash, + ) # load the model sim = flopy.mf6.MFSimulation.load( @@ -43,8 +70,6 @@ verbosity_level=0, ) # change the simulation path, rewrite the files, and run the model -temp_dir = TemporaryDirectory() -sim_ws = temp_dir.name sim.set_sim_path(sim_ws) sim.write_simulation(silent=True) sim.run_simulation(silent=True) diff --git a/.docs/Notebooks/mf6_parallel_model_splitting_example.py b/.docs/Notebooks/mf6_parallel_model_splitting_example.py index 7895f6bcf..2cb1a7914 100644 --- a/.docs/Notebooks/mf6_parallel_model_splitting_example.py +++ b/.docs/Notebooks/mf6_parallel_model_splitting_example.py @@ -26,6 +26,7 @@ import matplotlib.pyplot as plt import numpy as np +import pooch import yaml import flopy @@ -33,12 +34,9 @@ from flopy.plot import styles from flopy.utils.geometry import LineString, Polygon -geometries = yaml.safe_load( - open(Path("../../examples/data/groundwater2023/geometries.yml")) -) +# Define a few utility functions. -# define a few utility functions def string2geom(geostring, conversion=None): if conversion is None: multiplier = 1.0 @@ -56,22 +54,58 @@ def string2geom(geostring, conversion=None): return res -# ## Example 1: splitting a simple structured grid model -# -# This example shows the basics of using the `Mf6Splitter()` class and applies the method to the Freyberg (1988) model. - -simulation_ws = Path("../../examples/data/mf6-freyberg") -sim = flopy.mf6.MFSimulation.load(sim_ws=simulation_ws) - -# Create a temporary directory for this example and run the Freyberg (1988) model. +# Create a temporary directory for this example. temp_dir = TemporaryDirectory() workspace = Path(temp_dir.name) -# +# Download and load geometries. -sim.set_sim_path(workspace) -sim.write_simulation() +geometries_fname = "geometries.yml" +geometries_fpath = pooch.retrieve( + url=f"https://github.com/modflowpy/flopy/raw/develop/examples/data/groundwater2023/{geometries_fname}", + fname=geometries_fname, + path=workspace, + known_hash="4fb491f9dbd09ef04d6d067458e9866ac79d96448f70910e78c552131a12b6be", +) +geometries = yaml.safe_load(open(geometries_fpath)) + +# Download the Freyberg 1988 model. + +sim_name = "mf6-freyberg" +file_names = { + "bot.asc": "3107f907cb027460fd40ffc16cb797a78babb31988c7da326c9f500fba855b62", + "description.txt": "94093335eec6a24711f86d4d217ccd5a7716dd9e01cb6b732bc7757d41675c09", + "freyberg.cbc": "c8ad843b1da753eb58cf6c462ac782faf0ca433d6dcb067742d8bd698db271e3", + "freyberg.chd": "d8b8ada8d3978daea1758b315be983b5ca892efc7d69bf6b367ceec31e0dd156", + "freyberg.dis": "cac230a207cc8483693f7ba8ae29ce40c049036262eac4cebe17a4e2347a8b30", + "freyberg.dis.grb": "c8c26fb1fa4b210208134b286d895397cf4b3131f66e1d9dda76338502c7e96a", + "freyberg.hds": "926a06411ca658a89db6b5686f51ddeaf5b74ced81239cab1d43710411ba5f5b", + "freyberg.ic": "6efb56ee9cdd704b9a76fb9efd6dae750facc5426b828713f2d2cf8d35194120", + "freyberg.ims": "6dddae087d85417e3cdaa13e7b24165afb7f9575ab68586f3adb6c1b2d023781", + "freyberg.nam": "cee9b7b000fe35d2df26e878d09d465250a39504f87516c897e3fa14dcda081e", + "freyberg.npf": "81104d3546045fff0eddf5059465e560b83b492fa5a5acad1907ce18c2b9c15f", + "freyberg.oc": "c0715acd75eabcc42c8c47260a6c1abd6c784350983f7e2e6009ddde518b80b8", + "freyberg.rch": "a6ec1e0eda14fd2cdf618a5c0243a9caf82686c69242b783410d5abbcf971954", + "freyberg.riv": "a8cafc8c317cbe2acbb43e2f0cfe1188cb2277a7a174aeb6f3e6438013de8088", + "freyberg.sto": "74d748c2f0adfa0a32ee3f2912115c8f35b91011995b70c1ec6ae1c627242c41", + "freyberg.tdis": "9965cbb17caf5b865ea41a4ec04bcb695fe15a38cb539425fdc00abbae385cbe", + "freyberg.wel": "f19847de455598de52c05a4be745698c8cb589e5acfb0db6ab1f06ded5ff9310", + "k11.asc": "b6a8aa46ef17f7f096d338758ef46e32495eb9895b25d687540d676744f02af5", + "mfsim.nam": "6b8d6d7a56c52fb2bff884b3979e3d2201c8348b4bbfd2b6b9752863cbc9975e", + "top.asc": "3ad2b131671b9faca7f74c1dd2b2f41875ab0c15027764021a89f9c95dccaa6a", +} +for fname, fhash in file_names.items(): + pooch.retrieve( + url=f"https://github.com/modflowpy/flopy/raw/develop/examples/data/{sim_name}/{fname}", + fname=fname, + path=workspace, + known_hash=fhash, + ) + +# Load and run the simulation. + +sim = flopy.mf6.MFSimulation.load(sim_ws=workspace) success, buff = sim.run_simulation(silent=True) assert success @@ -234,7 +268,13 @@ def string2geom(geostring, conversion=None): # # Load an ASCII raster file -ascii_file = Path("../../examples/data/geospatial/fine_topo.asc") +ascii_file_name = "fine_topo.asc" +ascii_file = pooch.retrieve( + url=f"https://github.com/modflowpy/flopy/raw/develop/examples/data/geospatial/{ascii_file_name}", + fname=fname, + path=workspace, + known_hash=None, +) fine_topo = flopy.utils.Raster.load(ascii_file) fine_topo.plot() @@ -657,7 +697,7 @@ def string2geom(geostring, conversion=None): new_sim = mfsplit.split_model(split_array) temp_dir = TemporaryDirectory() -workspace = Path("temp") +workspace = Path(temp_dir.name) new_ws = workspace / "opt_split_models" new_sim.set_sim_path(new_ws) diff --git a/.docs/Notebooks/mf6_sfr_tutorial01.py b/.docs/Notebooks/mf6_sfr_tutorial01.py index 69d65bc40..65564add8 100644 --- a/.docs/Notebooks/mf6_sfr_tutorial01.py +++ b/.docs/Notebooks/mf6_sfr_tutorial01.py @@ -21,6 +21,8 @@ # + import sys +import pooch + import flopy print(sys.version) diff --git a/.docs/Notebooks/modpath6_example.py b/.docs/Notebooks/modpath6_example.py index 5620b023d..25189a7c3 100644 --- a/.docs/Notebooks/modpath6_example.py +++ b/.docs/Notebooks/modpath6_example.py @@ -33,6 +33,7 @@ import matplotlib.pyplot as plt import numpy as np import pandas as pd +import pooch import flopy @@ -50,14 +51,73 @@ # temporary directory temp_dir = TemporaryDirectory() -model_ws = temp_dir.name +model_ws = Path(temp_dir.name) +file_names = { + "EXAMPLE-1.endpoint": None, + "EXAMPLE-1.mpsim": None, + "EXAMPLE-2.endpoint": None, + "EXAMPLE-2.mplist": None, + "EXAMPLE-2.mpsim": None, + "EXAMPLE-3.endpoint": None, + "EXAMPLE-3.mplist": None, + "EXAMPLE-3.mpsim": None, + "EXAMPLE-3.pathline": None, + "EXAMPLE-4.endpoint": None, + "EXAMPLE-4.mplist": None, + "EXAMPLE-4.mpsim": None, + "EXAMPLE-4.timeseries": None, + "EXAMPLE-5.endpoint": None, + "EXAMPLE-5.mplist": None, + "EXAMPLE-5.mpsim": None, + "EXAMPLE-6.endpoint": None, + "EXAMPLE-6.mplist": None, + "EXAMPLE-6.mpsim": None, + "EXAMPLE-6.timeseries": None, + "EXAMPLE-7.endpoint": None, + "EXAMPLE-7.mplist": None, + "EXAMPLE-7.mpsim": None, + "EXAMPLE-7.timeseries": None, + "EXAMPLE-8.endpoint": None, + "EXAMPLE-8.mplist": None, + "EXAMPLE-8.mpsim": None, + "EXAMPLE-8.timeseries": None, + "EXAMPLE-9.endpoint": None, + "EXAMPLE-9.mplist": None, + "EXAMPLE-9.mpsim": None, + "EXAMPLE.BA6": None, + "EXAMPLE.BUD": None, + "EXAMPLE.DIS": None, + "EXAMPLE.DIS.metadata": None, + "EXAMPLE.HED": None, + "EXAMPLE.LPF": None, + "EXAMPLE.LST": None, + "EXAMPLE.MPBAS": None, + "EXAMPLE.OC": None, + "EXAMPLE.PCG": None, + "EXAMPLE.RCH": None, + "EXAMPLE.RIV": None, + "EXAMPLE.WEL": None, + "EXAMPLE.mpnam": None, + "EXAMPLE.nam": None, + "example-1.mplist": None, + "example-6.locations": None, + "example-7.locations": None, + "example-8.locations": None, + "example.basemap": None, +} +for fname, fhash in file_names.items(): + pooch.retrieve( + url=f"https://github.com/modflowpy/flopy/raw/develop/examples/data/mp6/{fname}", + fname=fname, + path=model_ws, + known_hash=fhash, + ) -model_path = Path.cwd().parent.parent / "examples" / "data" / "mp6" -mffiles = list(model_path.glob("EXAMPLE.*")) +mffiles = list(model_ws.glob("EXAMPLE.*")) -m = flopy.modflow.Modflow.load("EXAMPLE.nam", model_ws=model_path) +m = flopy.modflow.Modflow.load("EXAMPLE.nam", model_ws=model_ws) -hdsfile = flopy.utils.HeadFile(os.path.join(model_path, "EXAMPLE.HED")) +hdsfile = flopy.utils.HeadFile(os.path.join(model_ws, "EXAMPLE.HED")) hdsfile.get_kstpkper() hds = hdsfile.get_data(kstpkper=(0, 2)) @@ -93,7 +153,7 @@ modelname="ex6", exe_name="mp6", modflowmodel=m, - model_ws=str(model_path), + model_ws=str(model_ws), ) mpb = flopy.modpath.Modpath6Bas( @@ -109,10 +169,6 @@ start_time=(2, 0, 1.0), ) -shutil.copy(model_path / "EXAMPLE.DIS", join(model_ws, "EXAMPLE.DIS")) -shutil.copy(model_path / "EXAMPLE.HED", join(model_ws, "EXAMPLE.HED")) -shutil.copy(model_path / "EXAMPLE.BUD", join(model_ws, "EXAMPLE.BUD")) - mp.change_model_ws(model_ws) mp.write_name_file() mp.write_input() @@ -203,7 +259,7 @@ # Replace WEL package with MNW2, and create backward tracking simulation using particles released at MNW well. m2 = flopy.modflow.Modflow.load( - "EXAMPLE.nam", model_ws=str(model_path), exe_name="mf2005" + "EXAMPLE.nam", model_ws=str(model_ws), exe_name="mf2005" ) m2.get_package_list() diff --git a/.docs/tutorials.rst b/.docs/tutorials.rst index 7b2525504..56a7b3773 100644 --- a/.docs/tutorials.rst +++ b/.docs/tutorials.rst @@ -3,6 +3,11 @@ Tutorials The following tutorials demonstrate basic FloPy features and usage with MODFLOW 2005, MODFLOW 6, and related programs. +The basic set of MODFLOW executables as well as the `optional` dependency group are both required to run the tutorials. + +If the tutorial/example scripts detect that they are running within the repository, they will use local example data. +Otherwise they will download example data files where necessary from GitHub. + FloPy ----- diff --git a/pyproject.toml b/pyproject.toml index 9f5cf4e12..ade0dbaf1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,8 +62,10 @@ optional = [ "fiona", "geojson", "geopandas", + "GitPython", "imageio", "netcdf4", + "pooch", "pymetis ; platform_system != 'Windows'", "pyproj", "pyshp",