Skip to content

Commit

Permalink
Add IndexMap::global_to_local to the Python interface (#2972)
Browse files Browse the repository at this point in the history
* Add `global_to_local` to the Python interface.
Make it required to send in output array, as it makes sense from a performance perspective to let the user send in this array, as it might be used in loops.

* Add global indices

* Make indexmap local_to_global and global_to_local pure functions in python interface

* Simplify
  • Loading branch information
jorgensd authored Jan 15, 2024
1 parent 0a3582b commit f71be27
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
14 changes: 12 additions & 2 deletions python/dolfinx/wrappers/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,18 @@ void common(nb::module_& m)
self.local_to_global(std::span(local.data(), local.size()), global);
return dolfinx_wrappers::as_nbarray(std::move(global));
},
nb::arg("local"));

nb::arg("local"))
.def(
"global_to_local",
[](const dolfinx::common::IndexMap& self,
nb::ndarray<const std::int64_t, nb::ndim<1>, nb::c_contig> global)
{
std::vector<std::int32_t> local(global.size());
self.global_to_local(std::span(global.data(), global.size()),
local);
return dolfinx_wrappers::as_nbarray(std::move(local));
},
nb::arg("global"));
// dolfinx::common::Timer
nb::class_<dolfinx::common::Timer>(m, "Timer", "Timer class")
.def(nb::init<>())
Expand Down
14 changes: 13 additions & 1 deletion python/test/unit/common/test_index_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,19 @@ def test_index_map_ghost_lifetime():
map = dolfinx.common.IndexMap(comm, local_size, [dest, src], map_ghosts, src)
assert map.size_global == local_size * comm.size

# Test global to local map
global_indices = np.arange(map.size_global, dtype=np.int64)
local_indices = map.global_to_local(global_indices)
for i, ghost in enumerate(map_ghosts):
assert local_indices[ghost] == local_size + i

# Create marker for all indices that are on process (local or ghost)
on_process = np.zeros(map.size_global, dtype=bool)
on_process[map.local_range[0]:map.local_range[1]] = True
on_process[map.ghosts] = True
assert (local_indices[on_process] >= 0).all()
assert np.allclose(local_indices[np.invert(on_process)], -1)

# Test lifetime management
ghosts = map.ghosts
assert np.array_equal(ghosts, map_ghosts)
Expand Down Expand Up @@ -167,6 +180,5 @@ def test_create_submap_owner_change():
assert np.array_equal(sub_imap.ghosts, [2 * (comm.rank + 1)])
assert np.array_equal(sub_imap.owners, [comm.rank + 1])
assert np.array_equal(sub_imap_to_imap, [0, 2, 3])

global_indices = sub_imap.local_to_global(np.arange(sub_imap.size_local + sub_imap.num_ghosts, dtype=np.int32))
assert np.array_equal(global_indices, np.arange(comm.rank * 2, comm.rank * 2 + 3))

0 comments on commit f71be27

Please sign in to comment.