Repository navigation
Conversation
Without the horizontal shift, the elevation came from the surface cell with the closest center, which on a tree mesh can be in the neighboring column (near a change in cell size where the surface steps), so the location wasn't on its own column's surface. It now walks down each location's column to its highest active cell instead. With the horizontal shift, locations given with an elevation took their horizontal position from whatever cell held the original point (not the closest surface cell the elevation came from), so many ended up off the surface. Both coordinates now come from the closest surface cell, which is what horizontal-only locations (and the old `drapeTopotoLoc`) already did. Tensor mesh results are unchanged. This also accepts integer `active_cells` on tensor meshes and raises a clear error for an invalid `topo_cell_cutoff` on tree meshes.
On tree meshes this returned every active cell with an inactive cell directly above it, which included the floors of inactive pockets (and the ground under an overhang), and `shift_to_discrete_topography(..., shift_horizontal=True)` could drape onto those. It now walks down through the inactive cells from the top of the mesh using each cell's neighbors, so it stops at the upper surface. Where finer inactive cells sit on a coarser surface cell, that cell's top is split up into the horizontal positions of the finer cells above it (it's what the surface looks like from above, and the old center of the coarse cell could be under a finer active cell). Tensor mesh results are unchanged, except that columns without active cells are now skipped instead of raising. This also accepts integer `active_cells` on both mesh types, and raises a clear error for an invalid `topo_cell_cutoff` on tree meshes.
Simpler than keeping an explicit stack. A coarser inactive cell under several finer inactive cells (like below a refined box in the air for airborne data) is reached from each of them, so it's only walked the first time. I tried only walking it from the finer cell in its lower corner instead, but that skips it when that finer cell is active (and the corner check needs care with uneven tree mesh widths), so there are tests for both cases.
The recursive walk recursed once per inactive cell in a column, so a tall enough column of air cells hit Python's recursion limit. This keeps the same walk as a loop. Also raises a clear error from shift_to_discrete_topography when there are no active cells at all (with the horizontal shift it failed on an empty argmin before).
`mesh.h_gridded` isn't cached, so every access builds it for every cell again (about 0.45 s on a 32 million cell tensor mesh), and both functions read it twice. This roughly halves `shift_to_discrete_topography` on large tensor meshes.
The closest column center isn't always the column a location is in on a tensor mesh either, when the widths are uneven (like in the padding), so `main` could give the elevation of the neighboring column there too. I had only compared against uniform tensor meshes before, so the first commit's "tensor mesh results are unchanged" isn't right in general.
shift_to_discrete_topography on the discrete surface of tree meshesshift_to_discrete_topography locations on the discrete surface
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1840 +/- ##
==========================================
+ Coverage 86.81% 86.85% +0.03%
==========================================
Files 436 436
Lines 57838 57952 +114
Branches 5457 5460 +3
==========================================
+ Hits 50214 50332 +118
+ Misses 6187 6185 -2
+ Partials 1437 1435 -2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes
shift_to_discrete_topographyputting locations off of the discrete surface on tree meshes.PR Checklist
expect style.
to a Pull Request
@simpeg/simpeg-developerswhen ready for review.Reference issue
Came up while working on receiver locations for #1839, and follows up on the closest center vs containing cell comment in #1683 (#1683 (comment)).
What does this implement/fix?
There were a few ways a shifted location could end up off of the discrete surface on tree meshes, and on tensor meshes with uneven cell widths (like padding):
shift_horizontal=False, the elevation came from the surface cell with the closest center, which can be in the neighboring column (near a change in cell size where the surface steps, including the padding of a tensor mesh). It now walks down each location's own column to its highest active cell.shift_horizontal=Trueand locations that include an elevation (which is whatdrape_electrodes_on_topographypasses for 2D surveys), the horizontal position came from whatever cell held the original point, while the elevation came from the closest surface cell. Both now come from the closest surface cell, which is what horizontal only locations (and the olddrapeTopotoLoc) already did.get_discrete_topographyreturned every active cell with an inactive cell directly above it, which included the floors of inactive pockets (and the ground under an overhang), so the horizontal shift could put a location underground. It now walks down through the inactive cells from the top of the mesh using each cell's neighbors, so it only finds the upper surface. Where finer inactive cells sit on a coarser surface cell, that cell's top is also split up into the horizontal positions of the finer cells above it (what the surface looks like from above).For example, with the surface stepping down from
z = 0toz = -2atx = 0:On
mainthis gives[0.2, 0.0]and[1.0, 0.0], which are both in the air (the surface is atz = -2there). With this PR it gives[0.2, -2.0]and[-0.5, 0.0].Shifted electrode locations on the same mesh, for a few more electrodes. Open circles are the original locations and filled circles the shifted ones, and the ringed ones end up in the air on
main. Everything else lands in the same place.The same thing on a tensor mesh, with a 10 m column (0 < x < 10) next to 1 m columns. The ringed locations end up in the ground on
main, because the closest column center isn't the one they're in.Both functions also accept integer
active_cellsnow, and raise a clear error for an invalidtopo_cell_cutoffon tree meshes (and, without the horizontal shift, for a column with no active cells).Additional information
I'm not really sold on
shift_horizontal=Trueas the default (especially for the nodal DC simulations), but I'll open a separate issue for that.