Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@
"parent": "mesh",
"label": "Value(s)",
"property": "",
"value": 0.0
"value": 0.0001
},
"topography_object": {
"main": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@
"parent": "mesh",
"label": "Initial chargeability (V/V)",
"property": "",
"value": 0.0
"value": 0.0001
},
"reference_model": {
"association": "Cell",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"property": "",
"min": 0.0,
"max": 10000.0,
"value": 0.0
"value": 0.0001
},
"topography_object": {
"main": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
"property": "",
"min": 0.0,
"max": 10000.0,
"value": 0.0
"value": 0.0001
},
"reference_model": {
"association": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
"parent": "mesh",
"label": "Value(s)",
"property": "",
"value": 0.001
"value": 0.0001
},
"topography_object": {
"main": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
"parent": "mesh",
"label": "Initial chargeability (V/V)",
"property": "",
"value": 0.001
"value": 0.0001
},
"reference_model": {
"association": "Cell",
Expand Down
2 changes: 1 addition & 1 deletion simpeg_drivers/components/factories/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from .entity_factory import EntityFactory
from .misfit_factory import MisfitFactory
from .simulation_factory import SimulationFactory
from .survey_factory import SurveyFactory, receiver_group
from .survey_factory import SurveyFactory

# pylint: disable=unused-import
# flake8: noqa
37 changes: 3 additions & 34 deletions simpeg_drivers/components/factories/survey_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,39 +33,6 @@
from simpeg_drivers.components.factories.source_factory import SourcesFactory


def receiver_group(txi, potential_electrodes):
"""
Group receivers by common transmitter id.

:param: txi : transmitter index number.
:param: potential_electrodes : geoh5py object that holds potential electrodes
ab_map and ab_cell_id for a dc survey.

:return: ids : list of ids of potential electrodes used with transmitter txi.
"""

index_map = potential_electrodes.ab_map()
index_map = {int(v): k for k, v in index_map.items() if v != "Unknown"}
ids = np.where(
potential_electrodes.ab_cell_id.values.astype(int) == index_map[txi]
)[0]

return ids


def group_locations(obj, ids):
"""
Return vertex locations for possible group of cells.

:param obj : geoh5py object containing cells, vertices structure.
:param ids : list of ids (or possibly single id) that indexes cells array.

:return locations : tuple of n locations arrays where n is length of second
dimension of cells array.
"""
return (obj.vertices[obj.cells[ids, i]] for i in range(obj.cells.shape[1]))


class SurveyFactory(SimPEGFactory):
"""Build SimPEG sources objects based on factory type."""

Expand Down Expand Up @@ -289,7 +256,9 @@ def _dcip_arguments(self, data=None, local_index=None):
sources = []
self.local_index = []
for source_id in source_ids[np.argsort(order)]: # Cycle in original order
receiver_indices = receiver_group(source_id, receiver_entity)
receiver_indices = np.where(receiver_entity.ab_cell_id.values == source_id)[
0
]

if local_index is not None:
receiver_indices = list(set(receiver_indices).intersection(local_index))
Expand Down
5 changes: 4 additions & 1 deletion simpeg_drivers/components/topography.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,16 @@ def expand_actives(
neighbours = get_neighbouring_cells(mesh.mesh, containing_cells)
neighbours_xy = np.r_[neighbours[0] + neighbours[1]]

neighbours_xy = neighbours_xy[neighbours_xy != -1]
# Make sure the new actives are connected to the old actives
new_actives = ~active_cells[neighbours_xy]
if np.any(new_actives):
neighbours = get_neighbouring_cells(
mesh.mesh, neighbours_xy[new_actives]
)
active_cells[np.r_[neighbours[2][0]]] = True # z-axis neighbours
neighbours_z = np.r_[neighbours[2][0]]
neighbours_z = neighbours_z[neighbours_z != -1]
active_cells[neighbours_z] = True # z-axis neighbours

active_cells[neighbours_xy] = True # xy-axis neighbours

Expand Down
4 changes: 2 additions & 2 deletions simpeg_drivers/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
ReferencedData,
)
from geoh5py.groups import PropertyGroup, SimPEGGroup, UIJsonGroup
from geoh5py.objects import DrapeModel, Octree, Points
from geoh5py.objects import DrapeModel, Grid2D, Octree, Points
from geoh5py.shared.utils import fetch_active_workspace
from geoh5py.ui_json import InputFile
from pydantic import BaseModel, ConfigDict, field_validator, model_validator
Expand All @@ -54,7 +54,7 @@ class ActiveCellsOptions(BaseModel):
model_config = ConfigDict(
arbitrary_types_allowed=True,
)
topography_object: Points | None = None
topography_object: Points | Grid2D | None = None
topography: FloatData | float | None = None
active_model: BooleanData | IntegerData | None = None

Expand Down
25 changes: 22 additions & 3 deletions tests/topography_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@

import numpy as np

from simpeg_drivers.components import InversionTopography
from simpeg_drivers.components import InversionData, InversionMesh, InversionTopography
from simpeg_drivers.options import ActiveCellsOptions
from simpeg_drivers.potential_fields import MVIInversionOptions
from simpeg_drivers.utils.testing import Geoh5Tester, setup_inversion_workspace


def test_get_locations(tmp_path: Path):
geoh5, entity, model, survey, topography = setup_inversion_workspace(
geoh5, mesh, model, survey, topography = setup_inversion_workspace(
tmp_path,
background=0.0,
anomaly=0.05,
Expand All @@ -31,7 +31,6 @@ def test_get_locations(tmp_path: Path):
inversion_type="magnetic_vector",
)
with geoh5.open():
mesh = model.parent
tmi_channel, gyz_channel = survey.add_data(
{
"tmi": {"values": np.random.rand(survey.n_vertices)},
Expand All @@ -51,6 +50,7 @@ def test_get_locations(tmp_path: Path):
),
starting_model=1.0,
)

geoh5 = params.geoh5
with geoh5.open():
topo = InversionTopography(geoh5, params)
Expand All @@ -60,6 +60,25 @@ def test_get_locations(tmp_path: Path):
params.active_cells.topography.values,
)

# Check that boundary cells are handled properly
# Shift one of the survey vertices to the corner
survey.vertices[0, :] = mesh.centroids[0, :]
geoh5.update_attribute(survey, "vertices")
inversion_mesh = InversionMesh(geoh5, params)
inversion_data = InversionData(geoh5, params)
params.inversion_type = "magnetotellurics"
active_cells = topo.active_cells(inversion_mesh, inversion_data)

mesh.add_data(
{
"active_cells": {
"values": active_cells,
}
}
)
assert not active_cells[-1]

# Test flat topo
params.active_cells.topography = 199.0
locs = topo.get_locations(params.active_cells.topography_object)
np.testing.assert_allclose(locs[:, 2], np.ones_like(locs[:, 2]) * 199.0)