Repository: simpeg/simpeg
Pull request #1589 (2024-11-26 21:46:04)

Rename delete on model update


#### Summary
Privatizes the `deleteOnModelUpdate` property, and unify with the `clean_on_model_update`.

#### PR Checklist
* [x] If this is a work in progress PR, set as a Draft PR
* [x] Linted my code according to the [style guides](https://docs.simpeg.xyz/latest/content/getting_started/contributing/code-style.html).
* [x] Added [tests](https://docs.simpeg.xyz/latest/content/getting_started/contributing/testing.html) to verify changes to the code.
* [x] Added necessary documentation to any new functions/classes following the
      expect [style](https://docs.simpeg.xyz/latest/content/getting_started/contributing/documentation.html).
* [x] Marked as ready for review (if this is was a draft PR), and converted 
      to a Pull Request
* [x] Tagged ``@simpeg/simpeg-developers`` when ready for review.

#### Reference issue
Working towards #1429

#### What does this implement/fix?
The `deleteOnModelUpdate` property is not needed to be public, this privatizes it. It also removes the somewhat duplicated purpose of the `clean_on_model_change`  property, as we should rely on the solvers to clean themselves up properly upon deletion instead of manually triggering it.


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/simpeg/simpeg/pull/1589?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg) Report
Attention: Patch coverage is `97.58065%` with `3 lines` in your changes missing coverage. Please review.
> Project coverage is 86.52%. Comparing base [(`84719dc`)](https://app.codecov.io/gh/simpeg/simpeg/commit/84719dcee7d8b121e6470297beccff1c18138d05?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg) to head [(`f21c8f3`)](https://app.codecov.io/gh/simpeg/simpeg/commit/f21c8f364dec8ec26193591f5f41681103339cd4?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg).
> Report is 1 commits behind head on main.

| [Files with missing lines](https://app.codecov.io/gh/simpeg/simpeg/pull/1589?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg) | Patch % | Lines |
|---|---|---|
| [simpeg/electromagnetics/time\_domain/simulation.py](https://app.codecov.io/gh/simpeg/simpeg/pull/1589?src=pr&el=tree&filepath=simpeg%2Felectromagnetics%2Ftime_domain%2Fsimulation.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg#diff-c2ltcGVnL2VsZWN0cm9tYWduZXRpY3MvdGltZV9kb21haW4vc2ltdWxhdGlvbi5weQ==) | 80.00% | [0 Missing and 1 partial :warning: ](https://app.codecov.io/gh/simpeg/simpeg/pull/1589?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg) |
| [simpeg/inverse\_problem.py](https://app.codecov.io/gh/simpeg/simpeg/pull/1589?src=pr&el=tree&filepath=simpeg%2Finverse_problem.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg#diff-c2ltcGVnL2ludmVyc2VfcHJvYmxlbS5weQ==) | 50.00% | [0 Missing and 1 partial :warning: ](https://app.codecov.io/gh/simpeg/simpeg/pull/1589?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg) |
| [simpeg/props.py](https://app.codecov.io/gh/simpeg/simpeg/pull/1589?src=pr&el=tree&filepath=simpeg%2Fprops.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg#diff-c2ltcGVnL3Byb3BzLnB5) | 85.71% | [0 Missing and 1 partial :warning: ](https://app.codecov.io/gh/simpeg/simpeg/pull/1589?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #1589      +/-   ##
==========================================
+ Coverage   86.49%   86.52%   +0.03%     
==========================================
  Files         408      409       +1     
  Lines       52608    52691      +83     
  Branches     4999     5000       +1     
==========================================
+ Hits        45502    45593      +91     
+ Misses       5684     5678       -6     
+ Partials     1422     1420       -2     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/simpeg/simpeg/pull/1589?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg).


Patch:
diff --git a/simpeg/base/pde_simulation.py b/simpeg/base/pde_simulation.py
index 32ba694d5..d0cdb46f1 100644
--- a/simpeg/base/pde_simulation.py
+++ b/simpeg/base/pde_simulation.py
@@ -615,11 +615,11 @@ class BaseElectricalPDESimulation(BasePDESimulation):
         self.rhoMap = rhoMap
 
     @property
-    def deleteTheseOnModelUpdate(self):
+    def _delete_on_model_update(self):
         """
         matrices to be deleted if the model for conductivity/resistivity is updated
         """
-        toDelete = super().deleteTheseOnModelUpdate
+        toDelete = super()._delete_on_model_update
         if self.sigmaMap is not None or self.rhoMap is not None:
             toDelete = (
                 toDelete + self._clear_on_sigma_update + self._clear_on_rho_update
@@ -658,11 +658,11 @@ class BaseMagneticPDESimulation(BasePDESimulation):
                     delattr(self, mat)
 
     @property
-    def deleteTheseOnModelUpdate(self):
+    def _delete_on_model_update(self):
         """
         items to be deleted if the model for Magnetic Permeability is updated
         """
-        toDelete = super().deleteTheseOnModelUpdate
+        toDelete = super()._delete_on_model_update
         if self.muMap is not None or self.muiMap is not None:
             toDelete = toDelete + self._clear_on_mu_update + self._clear_on_mui_update
         return toDelete
diff --git a/simpeg/electromagnetics/base_1d.py b/simpeg/electromagnetics/base_1d.py
index e29802214..a871d56bf 100644
--- a/simpeg/electromagnetics/base_1d.py
+++ b/simpeg/electromagnetics/base_1d.py
@@ -576,8 +576,8 @@ class BaseEM1DSimulation(BaseSimulation):
         self._W = self._W.tocsr()
 
     @property
-    def deleteTheseOnModelUpdate(self):
-        toDelete = super().deleteTheseOnModelUpdate
+    def _delete_on_model_update(self):
+        toDelete = super()._delete_on_model_update
         if self.fix_Jmatrix is False:
             toDelete += ["_J", "_gtgdiag"]
         return toDelete
diff --git a/simpeg/electromagnetics/frequency_domain/simulation.py b/simpeg/electromagnetics/frequency_domain/simulation.py
index 55ad162e7..bb3f68fc8 100644
--- a/simpeg/electromagnetics/frequency_domain/simulation.py
+++ b/simpeg/electromagnetics/frequency_domain/simulation.py
@@ -486,7 +486,7 @@ class BaseFDEMSimulation(BaseEMSimulation):
         return s_m, s_e
 
     @property
-    def deleteTheseOnModelUpdate(self):
+    def _delete_on_model_update(self):
         """List of model-dependent attributes to clean upon model update.
 
         Some of the FDEM simulation's attributes are model-dependent. This property specifies
@@ -497,7 +497,7 @@ class BaseFDEMSimulation(BaseEMSimulation):
         list of str
             List of the model-dependent attributes to clean upon model update.
         """
-        toDelete = super().deleteTheseOnModelUpdate
+        toDelete = super()._delete_on_model_update
         return toDelete + ["_Jmatrix", "_gtgdiag"]
 
 
diff --git a/simpeg/electromagnetics/natural_source/simulation.py b/simpeg/electromagnetics/natural_source/simulation.py
index cd531529a..651a34795 100644
--- a/simpeg/electromagnetics/natural_source/simulation.py
+++ b/simpeg/electromagnetics/natural_source/simulation.py
@@ -474,8 +474,8 @@ class Simulation2DElectricField(BaseFDEMSimulation):
         return self._boundary_fields
 
     @property
-    def deleteTheseOnModelUpdate(self):
-        items = super().deleteTheseOnModelUpdate
+    def _delete_on_model_update(self):
+        items = super()._delete_on_model_update
         items.append("_boundary_fields")
         return items
 
@@ -696,8 +696,8 @@ class Simulation2DMagneticField(BaseFDEMSimulation):
         return self._boundary_fields
 
     @property
-    def deleteTheseOnModelUpdate(self):
-        items = super().deleteTheseOnModelUpdate
+    def _delete_on_model_update(self):
+        items = super()._delete_on_model_update
         items.append("_boundary_fields")
         return items
 
diff --git a/simpeg/electromagnetics/natural_source/simulation_1d.py b/simpeg/electromagnetics/natural_source/simulation_1d.py
index bbadaad77..424c39c9d 100644
--- a/simpeg/electromagnetics/natural_source/simulation_1d.py
+++ b/simpeg/electromagnetics/natural_source/simulation_1d.py
@@ -352,8 +352,8 @@ class Simulation1DRecursive(BaseSimulation):
         return JTvec
 
     @property
-    def deleteTheseOnModelUpdate(self):
-        toDelete = super().deleteTheseOnModelUpdate
+    def _delete_on_model_update(self):
+        toDelete = super()._delete_on_model_update
         if self.fix_Jmatrix:
             return toDelete
         else:
diff --git a/simpeg/electromagnetics/static/induced_polarization/simulation.py b/simpeg/electromagnetics/static/induced_polarization/simulation.py
index cd598bcb9..321c86c0e 100644
--- a/simpeg/electromagnetics/static/induced_polarization/simulation.py
+++ b/simpeg/electromagnetics/static/induced_polarization/simulation.py
@@ -132,7 +132,7 @@ class BaseIPSimulation(BasePDESimulation):
         return super().Jtvec(m, v * self._scale, f)
 
     @property
-    def deleteTheseOnModelUpdate(self):
+    def _delete_on_model_update(self):
         toDelete = []
         return toDelete
 
diff --git a/simpeg/electromagnetics/static/resistivity/simulation.py b/simpeg/electromagnetics/static/resistivity/simulation.py
index 2a78b6a17..476488a8a 100644
--- a/simpeg/electromagnetics/static/resistivity/simulation.py
+++ b/simpeg/electromagnetics/static/resistivity/simulation.py
@@ -284,8 +284,8 @@ class BaseDCSimulation(BaseElectricalPDESimulation):
         return self._q
 
     @property
-    def deleteTheseOnModelUpdate(self):
-        toDelete = super().deleteTheseOnModelUpdate
+    def _delete_on_model_update(self):
+        toDelete = super()._delete_on_model_update
         return toDelete + ["_Jmatrix", "_gtgdiag"]
 
     def _mini_survey_data(self, d_mini):
diff --git a/simpeg/electromagnetics/static/resistivity/simulation_1d.py b/simpeg/electromagnetics/static/resistivity/simulation_1d.py
index b57ea3591..85d72bd2f 100644
--- a/simpeg/electromagnetics/static/resistivity/simulation_1d.py
+++ b/simpeg/electromagnetics/static/resistivity/simulation_1d.py
@@ -340,8 +340,8 @@ class Simulation1DLayers(BaseSimulation):
         return self.getJ(m, f=f).T @ v
 
     @property
-    def deleteTheseOnModelUpdate(self):
-        to_delete = super().deleteTheseOnModelUpdate
+    def _delete_on_model_update(self):
+        to_delete = super()._delete_on_model_update
         if not self.fix_Jmatrix:
             to_delete = to_delete + ["_Jmatrix"]
         return to_delete
diff --git a/simpeg/electromagnetics/static/resistivity/simulation_2d.py b/simpeg/electromagnetics/static/resistivity/simulation_2d.py
index 1dab7d3da..b37158343 100644
--- a/simpeg/electromagnetics/static/resistivity/simulation_2d.py
+++ b/simpeg/electromagnetics/static/resistivity/simulation_2d.py
@@ -445,8 +445,8 @@ class BaseDCSimulation2D(BaseElectricalPDESimulation):
         return q
 
     @property
-    def deleteTheseOnModelUpdate(self):
-        toDelete = super().deleteTheseOnModelUpdate
+    def _delete_on_model_update(self):
+        toDelete = super()._delete_on_model_update
         if self.fix_Jmatrix:
             return toDelete
         return toDelete + ["_Jmatrix"]
diff --git a/simpeg/electromagnetics/static/self_potential/simulation.py b/simpeg/electromagnetics/static/self_potential/simulation.py
index 2ee621464..05a657ad1 100644
--- a/simpeg/electromagnetics/static/self_potential/simulation.py
+++ b/simpeg/electromagnetics/static/self_potential/simulation.py
@@ -78,10 +78,10 @@ class Simulation3DCellCentered(dc.Simulation3DCellCentered):
         return self.Vol @ (self.qDeriv @ v)
 
     @property
-    def deleteTheseOnModelUpdate(self):
+    def _delete_on_model_update(self):
         # When enabling resistivity derivatives, uncomment these lines
         # if self.rhoMap is not None:
-        #     return super().deleteTheseOnModelUpdate
+        #     return super()._delete_on_model_update
         if self.storeJ and self.qMap is not None and not self.qMap.is_linear:
             return ["_Jmatrix", "_gtgdiag"]
         return []
diff --git a/simpeg/electromagnetics/static/spectral_induced_polarization/simulation.py b/simpeg/electromagnetics/static/spectral_induced_polarization/simulation.py
index 04263d319..5abc4b4e8 100644
--- a/simpeg/electromagnetics/static/spectral_induced_polarization/simulation.py
+++ b/simpeg/electromagnetics/static/spectral_induced_polarization/simulation.py
@@ -603,7 +603,7 @@ class BaseSIPSimulation(BaseIPSimulation):
             return Jtv
 
     @property
-    def deleteTheseOnModelUpdate(self):
+    def _delete_on_model_update(self):
         toDelete = [
             "_etaDeriv_store",
             "_tauiDeriv_store",
diff --git a/simpeg/electromagnetics/time_domain/simulation.py b/simpeg/electromagnetics/time_domain/simulation.py
index 31720a94c..c896e3d9d 100644
--- a/simpeg/electromagnetics/time_domain/simulation.py
+++ b/simpeg/electromagnetics/time_domain/simulation.py
@@ -608,7 +608,7 @@ class BaseTDEMSimulation(BaseTimeSimulation, BaseEMSimulation):
         return self._Adcinv
 
     @property
-    def clean_on_model_update(self):
+    def _delete_on_model_update(self):
         """List of model-dependent attributes to clean upon model update.
 
         Some of the TDEM simulation's attributes are model-dependent. This property specifies
@@ -619,8 +619,11 @@ class BaseTDEMSimulation(BaseTimeSimulation, BaseEMSimulation):
         list of str
             List of the model-dependent attributes to clean upon model update.
         """
-        items = super().clean_on_model_update
-        return items + ["_Adcinv"]  #: clear DC matrix factors on any model updates
+        items = super()._delete_on_model_update
+        if self.sigmaMap is not None:
+            items = items + ["_Adcinv"]  #: clear DC matrix factors on any model updates
+            # if there is a sigmaMap
+        return items
 
 
 ###############################################################################
diff --git a/simpeg/inverse_problem.py b/simpeg/inverse_problem.py
index df53169ab..affff7cd7 100644
--- a/simpeg/inverse_problem.py
+++ b/simpeg/inverse_problem.py
@@ -144,7 +144,7 @@ class BaseInvProblem:
         self._opt = validate_type("opt", value, Minimize, cast=False)
 
     @property
-    def deleteTheseOnModelUpdate(self):
+    def _delete_on_model_update(self):
         """A list of properties stored on this object to delete when the model is updated
 
         Returns
@@ -170,7 +170,7 @@ class BaseInvProblem:
             value = validate_ndarray_with_shape(
                 "model", value, shape=[("*",), ("*", "*")], dtype=None
             )
-        for prop in self.deleteTheseOnModelUpdate:
+        for prop in self._delete_on_model_update:
             if hasattr(self, prop):
                 delattr(self, prop)
         self._model = value
diff --git a/simpeg/meta/simulation.py b/simpeg/meta/simulation.py
index ae9846475..f2ebc30fd 100644
--- a/simpeg/meta/simulation.py
+++ b/simpeg/meta/simulation.py
@@ -325,8 +325,8 @@ class MetaSimulation(BaseSimulation):
         return self._jtjdiag
 
     @property
-    def deleteTheseOnModelUpdate(self):
-        return super().deleteTheseOnModelUpdate + ["_jtjdiag"]
+    def _delete_on_model_update(self):
+        return super()._delete_on_model_update + ["_jtjdiag"]
 
 
 class SumMetaSimulation(MetaSimulation):
diff --git a/simpeg/potential_fields/magnetics/simulation.py b/simpeg/potential_fields/magnetics/simulation.py
index a40a28bb9..05ddf5b99 100644
--- a/simpeg/potential_fields/magnetics/simulation.py
+++ b/simpeg/potential_fields/magnetics/simulation.py
@@ -682,8 +682,8 @@ class Simulation3DIntegral(BasePFSimulation):
         )
 
     @property
-    def deleteTheseOnModelUpdate(self):
-        deletes = super().deleteTheseOnModelUpdate
+    def _delete_on_model_update(self):
+        deletes = super()._delete_on_model_update
         if self.is_amplitude_data:
             deletes = deletes + ["_gtg_diagonal", "_ampDeriv"]
         return deletes
diff --git a/simpeg/props.py b/simpeg/props.py
index 5a55f77b0..1d9052c4f 100644
--- a/simpeg/props.py
+++ b/simpeg/props.py
@@ -1,5 +1,8 @@
+import warnings
+
 import numpy as np
 
+from simpeg.utils import deprecate_property
 from .maps import IdentityMap, ReciprocalMap
 from .utils import Zero, validate_type, validate_ndarray_with_shape
 
@@ -358,7 +361,7 @@ class HasModel(BaseSimPEG, metaclass=PhysicalPropertyMetaclass):
 
     # TODO: rename to _delete_on_model_update
     @property
-    def deleteTheseOnModelUpdate(self):
+    def _delete_on_model_update(self):
         """A list of properties stored on this object to delete when the model is updated
 
         Returns
@@ -368,6 +371,13 @@ class HasModel(BaseSimPEG, metaclass=PhysicalPropertyMetaclass):
         """
         return []
 
+    deleteTheseOnModelUpdate = deprecate_property(
+        _delete_on_model_update,
+        "deleteTheseOnModelUpdate",
+        removal_version="0.25.0",
+        future_warn=True,
+    )
+
     #: List of matrix names to have their factors cleared on a model update
     @property
     def clean_on_model_update(self):
@@ -377,6 +387,12 @@ class HasModel(BaseSimPEG, metaclass=PhysicalPropertyMetaclass):
         -------
         list of str
         """
+        warnings.warn(
+            "clean_on_model_update has been deprecated due to repeated functionality encompassed"
+            " by the _delete_on_model_update method",
+            FutureWarning,
+            stacklevel=2,
+        )
         return []
 
     @property
@@ -447,15 +463,10 @@ class HasModel(BaseSimPEG, metaclass=PhysicalPropertyMetaclass):
                 and np.allclose(previous_value, value)
             ):
                 # cached properties to delete
-                for prop in self.deleteTheseOnModelUpdate:
+                for prop in self._delete_on_model_update:
                     if hasattr(self, prop):
                         delattr(self, prop)
 
-                # matrix factors to clear
-                for mat in self.clean_on_model_update:
-                    if getattr(self, mat, None) is not None:
-                        getattr(self, mat).clean()  # clean factors
-                        setattr(self, mat, None)  # set to none
                 updated = True
 
         self._model = value
@@ -469,12 +480,6 @@ class HasModel(BaseSimPEG, metaclass=PhysicalPropertyMetaclass):
     def model(self):
         self._model = (None,)
         # cached properties to delete
-        for prop in self.deleteTheseOnModelUpdate:
+        for prop in self._delete_on_model_update:
             if hasattr(self, prop):
                 delattr(self, prop)
-
-        # matrix factors to clear
-        for mat in self.clean_on_model_update:
-            if getattr(self, mat, None) is not None:
-                getattr(self, mat).clean()  # clean factors
-                setattr(self, mat, None)  # set to none


Test patch:
diff --git a/tests/base/props/test_has_model.py b/tests/base/props/test_has_model.py
new file mode 100644
index 000000000..5d7cc0d7d
--- /dev/null
+++ b/tests/base/props/test_has_model.py
@@ -0,0 +1,115 @@
+import re
+
+import pytest
+import numpy as np
+import numpy.testing as npt
+from simpeg import props, maps
+
+
+@pytest.fixture(scope="module")
+def mock_model_class():
+    class MockModel(props.HasModel):
+        prop, prop_map, _prop_deriv = props.Invertible("test physical property")
+        other, other_map, _other_deriv = props.Invertible("another physical property")
+
+        def __init__(
+            self, prop=None, prop_map=None, other=None, other_map=None, **kwargs
+        ):
+            self.prop = prop
+            self.prop_map = prop_map
+            self.other = other
+            self.other_map = other_map
+            super().__init__(**kwargs)
+
+        @property
+        def prop_dependent_property(self):
+            if (thing := getattr(self, "_prop_dependent_property", None)) is None:
+                thing = 2 * self.prop
+                self._prop_dependent_property = thing
+            return thing
+
+        @property
+        def _delete_on_model_update(self):
+            if self.prop_map is not None:
+                return ["_prop_dependent_property"]
+            return []
+
+    return MockModel
+
+
+@pytest.fixture()
+def modeler(mock_model_class):
+    prop_map = maps.ExpMap()
+    modeler = mock_model_class(prop_map=prop_map)
+    return modeler
+
+
+def test_clear_on_model_change(modeler):
+    x = np.ones(10)
+    modeler.model = x
+    npt.assert_array_equal(np.exp(x), modeler.prop)
+
+    item_1 = modeler.prop_dependent_property
+    assert item_1 is not None
+
+    x2 = x + 1
+    modeler.model = x2
+    assert getattr(modeler, "_prop_dependent_property", None) is None
+
+    item_2 = modeler.prop_dependent_property
+    assert item_2 is not None
+    assert item_1 is not item_2
+
+
+def test_no_clear_on_model_reassign(modeler):
+    x = np.ones(10)
+
+    modeler.model = x
+    npt.assert_array_equal(np.exp(x), modeler.prop)
+
+    item_1 = modeler.prop_dependent_property
+    assert item_1 is not None
+
+    modeler.model = x.copy()
+    assert getattr(modeler, "_prop_dependent_property", None) is not None
+
+    item_2 = modeler.prop_dependent_property
+
+    assert item_1 is item_2
+
+
+def test_map_clearing(modeler):
+    modeler.prop = np.ones(10)
+    assert modeler.prop_map is None
+
+
+def test_no_clear_without_mapping(modeler):
+    modeler.prop_map = None
+    modeler.other_map = maps.ExpMap()
+    modeler.prop = np.ones(10)
+    item1 = modeler.prop_dependent_property
+    assert item1 is not None
+
+    modeler.model = np.zeros(10)
+
+    assert getattr(modeler, "_prop_dependent_property", None) is not None
+    assert modeler.prop_dependent_property is item1
+
+
+def test_model_needed(modeler):
+    assert modeler.needs_model
+
+
+def test_no_model_needed(modeler):
+    modeler.prop_map = None
+    assert not modeler.needs_model
+
+
+def test_deletion_deprecation(modeler):
+    msg = re.escape("HasModel.deleteTheseOnModelUpdate has been deprecated") + ".*"
+    with pytest.warns(FutureWarning, match=msg):
+        modeler.deleteTheseOnModelUpdate
+
+    msg = "clean_on_model_update has been deprecated due to repeated functionality.*"
+    with pytest.warns(FutureWarning, match=msg):
+        modeler.clean_on_model_update
diff --git a/tests/base/test_Props.py b/tests/base/props/test_prop_relationships.py
similarity index 100%
rename from tests/base/test_Props.py
rename to tests/base/props/test_prop_relationships.py
diff --git a/tests/base/test_base_pde_sim.py b/tests/base/test_base_pde_sim.py
index 5b23ec451..20501849e 100644
--- a/tests/base/test_base_pde_sim.py
+++ b/tests/base/test_base_pde_sim.py
@@ -32,11 +32,11 @@ class SimpleSim(BasePDESimulation):
         self.muMap = muMap
 
     @property
-    def deleteTheseOnModelUpdate(self):
+    def _delete_on_model_update(self):
         """
         matrices to be deleted if the model for conductivity/resistivity is updated
         """
-        toDelete = super().deleteTheseOnModelUpdate
+        toDelete = super()._delete_on_model_update
         if self.sigmaMap is not None or self.rhoMap is not None:
             toDelete = toDelete + self._clear_on_sigma_update
         return toDelete
diff --git a/tests/em/static/test_SPjvecjtvecadj.py b/tests/em/static/test_SPjvecjtvecadj.py
index 462f6747b..94fb2b86a 100644
--- a/tests/em/static/test_SPjvecjtvecadj.py
+++ b/tests/em/static/test_SPjvecjtvecadj.py
@@ -114,13 +114,11 @@ def test_clears():
     # set qMap as a non-linear map to make sure it adds the correct
     # items to be cleared on model update
     sim.qMap = maps.IdentityMap()
-    assert sim.deleteTheseOnModelUpdate == []
-    assert sim.clean_on_model_update == []
+    assert sim._delete_on_model_update == []
 
     sim.storeJ = True
     sim.qMap = maps.ExpMap()
-    assert sim.deleteTheseOnModelUpdate == ["_Jmatrix", "_gtgdiag"]
-    assert sim.clean_on_model_update == []
+    assert sim._delete_on_model_update == ["_Jmatrix", "_gtgdiag"]
 
 
 def test_deprecations():