From 0b75090b3519388ea43b483bb3bdefd96d51ef42 Mon Sep 17 00:00:00 2001 From: Joseph Capriotti Date: Thu, 24 Oct 2024 10:40:21 -0600 Subject: [PATCH 01/14] allow random_model to accept the random_seed keyword argument --- discretize/mixins/mpl_mod.py | 2 +- discretize/utils/mesh_utils.py | 19 +++++++++++++++---- examples/plot_image.py | 2 +- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/discretize/mixins/mpl_mod.py b/discretize/mixins/mpl_mod.py index fecff2235..c58fda18a 100644 --- a/discretize/mixins/mpl_mod.py +++ b/discretize/mixins/mpl_mod.py @@ -495,7 +495,7 @@ def plot_slice( the given normal. >>> M = discretize.TensorMesh([32, 32, 32]) - >>> v = discretize.utils.random_model(M.vnC, seed=789).reshape(-1, order='F') + >>> v = discretize.utils.random_model(M.vnC, random_seed=789).reshape(-1, order='F') >>> x_slice, y_slice, z_slice = 0.75, 0.25, 0.9 >>> plt.figure(figsize=(7.5, 3)) >>> ax = plt.subplot(131) diff --git a/discretize/utils/mesh_utils.py b/discretize/utils/mesh_utils.py index 7aeeaf0d8..e6a7b6f19 100644 --- a/discretize/utils/mesh_utils.py +++ b/discretize/utils/mesh_utils.py @@ -14,7 +14,9 @@ num_types = [int, float] -def random_model(shape, seed=None, anisotropy=None, its=100, bounds=None): +def random_model( + shape, random_seed=None, anisotropy=None, its=100, bounds=None, seed=None +): """Create random tensor model. Creates a random tensor model by convolving a kernel function with a @@ -56,7 +58,7 @@ def random_model(shape, seed=None, anisotropy=None, its=100, bounds=None): >>> vmin, vmax = 0., 1. >>> mesh = TensorMesh([h, h]) - >>> model = random_model(mesh.shape_cells, seed=4, bounds=[vmin, vmax]) + >>> model = random_model(mesh.shape_cells, random_seed=4, bounds=[vmin, vmax]) >>> fig = plt.figure(figsize=(5, 4)) >>> ax = plt.subplot(111) @@ -68,8 +70,17 @@ def random_model(shape, seed=None, anisotropy=None, its=100, bounds=None): if bounds is None: bounds = [0, 1] - rng = np.random.default_rng(seed) - if seed is None: + if seed is not None: + warnings.warn( + "Deprecated in version 0.11.0. The `seed` keyword argument has been renamed to `random_seed` " + "for consistency across the package. Please update your code to use the new keyword argument.", + FutureWarning, + stacklevel=2, + ) + random_seed = seed + + rng = np.random.default_rng(random_seed) + if random_seed is None: print("Using a seed of: ", rng.bit_generator.seed_seq) if type(shape) in num_types: diff --git a/examples/plot_image.py b/examples/plot_image.py index c31f6deae..27a896507 100644 --- a/examples/plot_image.py +++ b/examples/plot_image.py @@ -11,7 +11,7 @@ def run(plotIt=True): M = discretize.TensorMesh([32, 32]) - v = discretize.utils.random_model(M.vnC, seed=789) + v = discretize.utils.random_model(M.vnC, random_seed=789) v = discretize.utils.mkvc(v) O = discretize.TreeMesh([32, 32]) From d4d770ee87eacc30605957ad95fdacfa2d63cffd Mon Sep 17 00:00:00 2001 From: Joseph Capriotti Date: Thu, 24 Oct 2024 10:40:41 -0600 Subject: [PATCH 02/14] update pypi distribution action --- .github/workflows/build_distributions.yml | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build_distributions.yml b/.github/workflows/build_distributions.yml index 6dff9ce6c..d494cf741 100644 --- a/.github/workflows/build_distributions.yml +++ b/.github/workflows/build_distributions.yml @@ -18,13 +18,6 @@ jobs: - name: Build wheels uses: pypa/cibuildwheel@v2.21.3 - # env: - # CIBW_SOME_OPTION: value - # ... - # with: - # package-dir: . - # output-dir: wheelhouse - # config-file: "{package}/pyproject.toml" - uses: actions/upload-artifact@v4 with: @@ -63,5 +56,8 @@ jobs: merge-multiple: true - uses: pypa/gh-action-pypi-publish@release/v1 - # with: - # To test: repository-url: https://test.pypi.org/legacy/ + with: + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} + skip-existing: true + packages-dir: ./dist/ From 6d0cc73a61d2e4f0ec4bab46c2d7d191b80398b9 Mon Sep 17 00:00:00 2001 From: Joseph Capriotti Date: Thu, 24 Oct 2024 10:54:31 -0600 Subject: [PATCH 03/14] add release notes --- docs/release/0.11.0-notes.rst | 92 +++++++++++++++++++++++++++++++++++ docs/release/index.rst | 1 + 2 files changed, 93 insertions(+) create mode 100644 docs/release/0.11.0-notes.rst diff --git a/docs/release/0.11.0-notes.rst b/docs/release/0.11.0-notes.rst new file mode 100644 index 000000000..fea7245a1 --- /dev/null +++ b/docs/release/0.11.0-notes.rst @@ -0,0 +1,92 @@ +.. currentmodule:: discretize + +.. _0.11.0_notes: + +=================================== +``discretize`` 0.11.0 Release Notes +=================================== + +October 24, 2024 + +This minor release contains many bugfixes and updates related to new package builds. + +Numpy 2 +------- +`discretize` now fully supports `numpy` 2! It is both built against and tested against `numpy` 2.0. It still +has a minimum required runtime of `numpy` 1.22 though, as building against numpy 2.0 emits ABI compatible calls for +older numpy versions. + +Of note to developers, we now require `numpy` 2.0 for building as it makes use of the `numpy-config` tool to locate +the `numpy` include directory. + +Python versions +--------------- +`discretize` has bumped its minimum supported `python` version to 3.10, and is tested against versions 3.10-3.13. In the +future we intended to stay in line with the minimum `python` version supported by the most recent `numpy` release. + + +Random Generators +----------------- +`discretize` and its testing utilities now make use of ``numpy.random.RandomGenerator`` to make draws from random +number generators instead of the deprecated ``numpy.random.rand`` functions. These functions now support a new keyword +argument `random_seed` : + +* :func:``discretize.tests.setup_mesh`` (only used when ``"random" in mesh_type``) +* :func:``discretize.tests.check_derivative`` (only used when ``dx=None``) +* :func:``discretize.tests.assert_isadjoint`` +* :func:``discretize.tests.OrderTest.orderTest`` (only used when ``"random" in mesh_type``) +* :func:``discretize.utils.random_model`` + +Maintainers of downstream packages should explicitly set seeded generators when using these methods for testing +purposess to ensure reproducibility. + + +Cell Bounds +----------- +:class:``discretize.TensorMesh`` and :class:``discretize.TreeMesh`` now have a ``cell_bounds`` property that returns the +``(x_min, x_max, y_min, y_max, z_min, z_max)`` of every cell in the mesh at once. Also now the +:class:``discretize.tree_mesh.TreeCell`` has a corresponding ``bounds`` property. + + +``TreeMesh`` updates +-------------------- +You can now query a :class:``discretize.TreeMesh`` for cells contained in the same geometric primitives that are supported +for refining. In addition there is a new :func:``discretize.TreeMesh.refine_plane`` method for refining along a plane. + + +Contributors +============ + +* @jcapriot +* @santisoler +* @prisae +* @xiaolongw1223 +* @lheagy +* @omid-b + +Pull requests +============= + +* `#347 `__: Replace deprecated Numpy's `product` by `prod` +* `#353 `__: Fix typo in tutorials +* `#351 `__: Replace Slack links for Mattermost links +* `#354 `__: Update year in LICENSE +* `#368 `__: Set minimum to Python 3.10 (and general CI Maintenance) +* `#358 `__: Replace hanging CurviMesh in docstring for CurvilinearMesh +* `#364 `__: Fix slicer re #363 +* `#371 `__: Add version switcher to discretize docs +* `#372 `__: Deploy docs to a new folder named after their tagged version +* `#373 `__: display dev doc banner +* `#360 `__: Update use of `numpy`'s random number generators. +* `#374 `__: Bump pydata_sphinx_theme version to 0.15.4 +* `#375 `__: Fix caching of internal projection matrices +* `#376 `__: Fix macos-latest build +* `#356 `__: Expose TreeMesh geometric intersections used for refine functions. +* `#366 `__: Add `TensorMesh.cell_bounds` property +* `#367 `__: Add `TreeCell.bounds` and `TreeMesh.cell_bounds` methods +* `#380 `__: Create build_distributions.yml +* `#379 `__: Numpy2.0 updates + + + +* `#342 `__: 0.11.0 Release Notes diff --git a/docs/release/index.rst b/docs/release/index.rst index beefd65dd..1b6cc7b39 100644 --- a/docs/release/index.rst +++ b/docs/release/index.rst @@ -4,6 +4,7 @@ Release Notes .. toctree:: :maxdepth: 2 + 0.11.0 <0.11.0-notes> 0.10.0 <0.10.0-notes> 0.9.0 <0.9.0-notes> 0.8.3 <0.8.3-notes> From 93abf5ef7beff760415c47f2cfbede672cd38f70 Mon Sep 17 00:00:00 2001 From: Joseph Capriotti Date: Thu, 24 Oct 2024 10:55:27 -0600 Subject: [PATCH 04/14] fix github link target --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index e0165cb41..41b37b634 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -257,7 +257,7 @@ def linkcode_resolve(domain, info): "icon_links": [ { "name": "GitHub", - "url": "https://github.com/simpeg/simpeg", + "url": "https://github.com/simpeg/discretize", "icon": "fab fa-github", }, { From b663f34470ef1ffce4af835954ca1ab80b1e5951 Mon Sep 17 00:00:00 2001 From: Joseph Capriotti Date: Thu, 24 Oct 2024 11:00:38 -0600 Subject: [PATCH 05/14] update readme's install instructions. --- README.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 1185ad205..750047f49 100644 --- a/README.rst +++ b/README.rst @@ -61,24 +61,25 @@ Currently, discretize supports: Installing ^^^^^^^^^^ -**discretize** is on conda-forge +**discretize** is on conda-forge, and is the recommended installation method. .. code:: shell conda install -c conda-forge discretize -**discretize** is on pypi +Prebuilt wheels of **discretize** are on pypi for most platforms .. code:: shell pip install discretize -To install from source +To install from source, note this requires a `c++` compiler supporting the `c++17` standard. .. code:: shell git clone https://github.com/simpeg/discretize.git - python setup.py install + cd discretize + pip install . Citing discretize ^^^^^^^^^^^^^^^^^ From a60f29a0e0a7deff7b592b0022dd6fb45333bf50 Mon Sep 17 00:00:00 2001 From: Joseph Capriotti Date: Thu, 24 Oct 2024 11:02:02 -0600 Subject: [PATCH 06/14] add release note PR to notice --- docs/release/0.11.0-notes.rst | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/release/0.11.0-notes.rst b/docs/release/0.11.0-notes.rst index fea7245a1..60e88e3ca 100644 --- a/docs/release/0.11.0-notes.rst +++ b/docs/release/0.11.0-notes.rst @@ -86,7 +86,4 @@ Pull requests * `#367 `__: Add `TreeCell.bounds` and `TreeMesh.cell_bounds` methods * `#380 `__: Create build_distributions.yml * `#379 `__: Numpy2.0 updates - - - -* `#342 `__: 0.11.0 Release Notes +* `#381 `__: 0.11.0 Release Notes From 2811bed6b3a876752fa2ef94716004ef6162b005 Mon Sep 17 00:00:00 2001 From: Joseph Capriotti Date: Thu, 24 Oct 2024 11:03:15 -0600 Subject: [PATCH 07/14] sort PR list by number --- docs/release/0.11.0-notes.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/release/0.11.0-notes.rst b/docs/release/0.11.0-notes.rst index 60e88e3ca..7c12e4262 100644 --- a/docs/release/0.11.0-notes.rst +++ b/docs/release/0.11.0-notes.rst @@ -68,22 +68,22 @@ Pull requests ============= * `#347 `__: Replace deprecated Numpy's `product` by `prod` -* `#353 `__: Fix typo in tutorials * `#351 `__: Replace Slack links for Mattermost links +* `#353 `__: Fix typo in tutorials * `#354 `__: Update year in LICENSE -* `#368 `__: Set minimum to Python 3.10 (and general CI Maintenance) +* `#356 `__: Expose TreeMesh geometric intersections used for refine functions. * `#358 `__: Replace hanging CurviMesh in docstring for CurvilinearMesh +* `#360 `__: Update use of `numpy`'s random number generators. * `#364 `__: Fix slicer re #363 +* `#366 `__: Add `TensorMesh.cell_bounds` property +* `#367 `__: Add `TreeCell.bounds` and `TreeMesh.cell_bounds` methods +* `#368 `__: Set minimum to Python 3.10 (and general CI Maintenance) * `#371 `__: Add version switcher to discretize docs * `#372 `__: Deploy docs to a new folder named after their tagged version * `#373 `__: display dev doc banner -* `#360 `__: Update use of `numpy`'s random number generators. * `#374 `__: Bump pydata_sphinx_theme version to 0.15.4 * `#375 `__: Fix caching of internal projection matrices * `#376 `__: Fix macos-latest build -* `#356 `__: Expose TreeMesh geometric intersections used for refine functions. -* `#366 `__: Add `TensorMesh.cell_bounds` property -* `#367 `__: Add `TreeCell.bounds` and `TreeMesh.cell_bounds` methods -* `#380 `__: Create build_distributions.yml * `#379 `__: Numpy2.0 updates +* `#380 `__: Create build_distributions.yml * `#381 `__: 0.11.0 Release Notes From 7c5dbcd2945755a2806f0cde923e437d9ce5874a Mon Sep 17 00:00:00 2001 From: Joseph Capriotti Date: Thu, 24 Oct 2024 14:32:01 -0600 Subject: [PATCH 08/14] fix random_seed argument name in docstring --- discretize/utils/mesh_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discretize/utils/mesh_utils.py b/discretize/utils/mesh_utils.py index e6a7b6f19..ec9583893 100644 --- a/discretize/utils/mesh_utils.py +++ b/discretize/utils/mesh_utils.py @@ -31,7 +31,7 @@ def random_model( ---------- shape : (dim) tuple of int shape of the model. - seed : numpy.random.Generator, int, optional + random_seed : numpy.random.Generator, int, optional pick which model to produce, prints the seed if you don't choose anisotropy : numpy.ndarray, optional this is the kernel that is convolved with the model From 70e128d2894b9810c0e8fc4c18c62ab9998489e3 Mon Sep 17 00:00:00 2001 From: Joseph Capriotti Date: Thu, 24 Oct 2024 14:33:12 -0600 Subject: [PATCH 09/14] make a copy of the location array before modifying the input... --- discretize/base/base_tensor_mesh.py | 1 + 1 file changed, 1 insertion(+) diff --git a/discretize/base/base_tensor_mesh.py b/discretize/base/base_tensor_mesh.py index dcd28f346..58375b19c 100644 --- a/discretize/base/base_tensor_mesh.py +++ b/discretize/base/base_tensor_mesh.py @@ -721,6 +721,7 @@ def _get_interpolation_matrix( raise ValueError("Points outside of mesh") else: indZeros = np.logical_not(self.is_inside(loc)) + loc = loc.copy() loc[indZeros, :] = np.array([v.mean() for v in self.get_tensor("CC")]) location_type = self._parse_location_type(location_type) From 9694f65891bfcb3b44761146477184441a6101d8 Mon Sep 17 00:00:00 2001 From: Joseph Capriotti Date: Fri, 25 Oct 2024 00:40:13 -0600 Subject: [PATCH 10/14] update versions.json to point to v0.11.0 [no-ci] --- docs/_static/versions.json | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/_static/versions.json b/docs/_static/versions.json index 7b2780fe4..772a34c12 100644 --- a/docs/_static/versions.json +++ b/docs/_static/versions.json @@ -4,10 +4,15 @@ "url": "https://discretize.simpeg.xyz/en/main/" }, { - "name": "0.10.0 (stable)", - "version": "v0.10.0", - "url": "https://discretize.simpeg.xyz/en/v0.10.0/", + "name": "0.11.0 (stable)", + "version": "v0.11.0", + "url": "https://discretize.simpeg.xyz/en/v0.11.0/", "preferred": true + }, + { + "name": "0.10.0", + "version": "v0.10.0", + "url": "https://discretize.simpeg.xyz/en/v0.10.0/" } ] From cf1b6b58dbcf722179da1b4e96dc8cd831bd4750 Mon Sep 17 00:00:00 2001 From: Joseph Capriotti Date: Fri, 25 Oct 2024 01:07:33 -0600 Subject: [PATCH 11/14] create symlink from the en directory --- .ci/azure/deploy.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.ci/azure/deploy.yml b/.ci/azure/deploy.yml index 23e8d851c..b53a56f89 100644 --- a/.ci/azure/deploy.yml +++ b/.ci/azure/deploy.yml @@ -49,9 +49,9 @@ jobs: - bash: | # Update latest symlink - cd discretize-docs - rm -f en/latest - ln -s "en/$BRANCH_NAME" en/latest + cd discretize-docs/en + rm -f latest + ln -s "$BRANCH_NAME" latest displayName: Point Latest to tag condition: eq(variables.IS_TAG, true) From 94c44b27c73d9013842fdc72c42e2f3270aeeb6d Mon Sep 17 00:00:00 2001 From: Joseph Capriotti Date: Fri, 25 Oct 2024 08:35:56 -0600 Subject: [PATCH 12/14] fix name of called function of point2index --- discretize/tree_mesh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discretize/tree_mesh.py b/discretize/tree_mesh.py index 2b711a195..382d5a023 100644 --- a/discretize/tree_mesh.py +++ b/discretize/tree_mesh.py @@ -926,7 +926,7 @@ def face_z_divergence(self): # NOQA D102 def point2index(self, locs): # NOQA D102 # Documentation inherited from discretize.base.BaseMesh - return self.get_containing_cell_indexes(locs) + return self.get_containing_cells(locs) def cell_levels_by_index(self, indices): """Fast function to return a list of levels for the given cell indices. From 5c4741127e17597095e58cc7faade963ce47d101 Mon Sep 17 00:00:00 2001 From: Joseph Capriotti Date: Fri, 25 Oct 2024 11:57:56 -0600 Subject: [PATCH 13/14] add tests --- tests/tree/test_tree.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/tree/test_tree.py b/tests/tree/test_tree.py index de487f7d2..6fd92936f 100644 --- a/tests/tree/test_tree.py +++ b/tests/tree/test_tree.py @@ -573,5 +573,22 @@ def test_insert_point(self): self.assertEqual(mesh1.nC, mesh2.nC) +@pytest.mark.parametrize("dim", [2, 3]) +def test_cell_locator(dim): + mesh = discretize.TreeMesh((16, 16, 16)[:dim]) + mesh.insert_cells([0.5, 0.5, 0.5][:dim], levels=-1) + + query_point = [0.21, 0.42, 0.22][:dim] + identified_cell = mesh.point2index(query_point) + found = False + for i, cell in enumerate(mesh): + bounds = cell.bounds.reshape((-1, 2)) + + if np.all((bounds[:, 0] <= query_point) & (bounds[:, 1] >= query_point)): + found = True + assert i == identified_cell + assert found + + if __name__ == "__main__": unittest.main() From 0c0af0be634ddcafc2ec336563035d7ff779266d Mon Sep 17 00:00:00 2001 From: Joseph Capriotti Date: Fri, 25 Oct 2024 12:05:40 -0600 Subject: [PATCH 14/14] add warning for pending default behavoir change for TreeMesh --- discretize/tree_mesh.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/discretize/tree_mesh.py b/discretize/tree_mesh.py index 382d5a023..6ae4c17e1 100644 --- a/discretize/tree_mesh.py +++ b/discretize/tree_mesh.py @@ -1,5 +1,7 @@ """Module containing the TreeMesh implementation.""" +import warnings + # ___ ___ ___ ___ ___ ___ # /\ \ /\ \ /\ \ /\ \ /\ \ /\ \ # /::\ \ /::\ \ \:\ \ /::\ \ /::\ \ /::\ \ @@ -169,7 +171,7 @@ class TreeMesh( diagonal_balance : bool, optional Whether to balance cells along the diagonal of the tree during construction. - This will effect all calls to refine the tree. + This will affect all calls to refine the tree. Examples -------- @@ -233,9 +235,20 @@ class TreeMesh( _items = {"h", "origin", "cell_state"} # inheriting stuff from BaseTensorMesh that isn't defined in _QuadTree - def __init__(self, h=None, origin=None, diagonal_balance=False, **kwargs): + def __init__(self, h=None, origin=None, diagonal_balance=None, **kwargs): if "x0" in kwargs: origin = kwargs.pop("x0") + + if diagonal_balance is None: + diagonal_balance = False + warnings.warn( + "In discretize v1.0 the TreeMesh will change the default value of " + "diagonal_balance to True, which will likely slightly change meshes you have" + "previously created. If you need to keep the current behavoir, explicitly set " + "diagonal_balance=False.", + FutureWarning, + stacklevel=2, + ) super().__init__(h=h, origin=origin, diagonal_balance=diagonal_balance) cell_state = kwargs.pop("cell_state", None)