Skip to content

Neo: handle empty connectivity in the graph. #2093

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
11 changes: 9 additions & 2 deletions arctools/neo/src/neo/Items.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
//-----------------------------------------------------------------------------
// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
// See the top-level COPYRIGHT file for details.
// SPDX-License-Identifier: Apache-2.0
//-----------------------------------------------------------------------------
/*---------------------------------------------------------------------------*/
/* Items (C) 2000-2024 */
/* Items (C) 2000-2025 */
/* */
/* Tooling to manipulate Mesh Items */
/*---------------------------------------------------------------------------*/
Expand Down Expand Up @@ -249,6 +249,13 @@ struct FutureItemRange
return std::move(new_items);
}

ItemRange::size_type size() const {
if (is_data_released)
throw std::runtime_error(
"Impossible to call FutureItemRange.size(), data already released.");
return new_items.size();
}

private:
virtual ItemRange& _toItemRange() {
return new_items;
Expand Down
8 changes: 8 additions & 0 deletions arctools/neo/src/neo/Mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ class Mesh
if (nb_connected_elements.size() == 0) {return 0;}
return *std::max_element(nb_connected_elements.begin(), nb_connected_elements.end());
}

bool isEmpty() const {
return maxNbConnectedItems() == 0;
}

friend bool operator==(Connectivity const& lhs, Connectivity const& rhs) {
return (lhs.source_family == rhs.source_family) && (lhs.target_family == rhs.target_family) && lhs.name == rhs.name;
}
};

enum class ConnectivityOperation
Expand Down
17 changes: 11 additions & 6 deletions arctools/neo/src/neo/MeshSchedule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,17 @@ void Neo::Mesh::_scheduleAddConnectivity(Neo::Family& source_family, Neo::ItemRa
// Create connectivity wrapper and add it to mesh
auto& connectivity_property = source_family.getConcreteProperty<Mesh::ConnectivityPropertyType>(connectivity_unique_name);
auto& connectivity_orientation = source_family.getConcreteProperty<Mesh::ConnectivityPropertyType>(orientation_name);
Connectivity current_connectivity = Connectivity {source_family,target_family,
connectivity_unique_name,connectivity_property,
connectivity_orientation};
auto [iterator, is_inserted] = m_connectivities.insert(std::make_pair(connectivity_unique_name,current_connectivity));
m_connectivities_per_family[{source_family.itemKind(),source_family.name()}].push_back(current_connectivity);
if (!is_inserted && add_or_modify == ConnectivityOperation::Add) {
Connectivity current_connectivity = Connectivity{ source_family, target_family,
connectivity_unique_name, connectivity_property,
connectivity_orientation };
auto [inserted_connectivity_iterator, is_inserted] = m_connectivities.insert(std::make_pair(connectivity_unique_name, current_connectivity));
auto& source_family_con = m_connectivities_per_family[{ source_family.itemKind(), source_family.name() }];
if (std::find(source_family_con.begin(),
source_family_con.end(),
current_connectivity) == source_family_con.end()) {
source_family_con.push_back(current_connectivity);
}
if (!is_inserted && add_or_modify == ConnectivityOperation::Add && !inserted_connectivity_iterator->second.isEmpty()) {
throw std::invalid_argument("Cannot include already inserted connectivity " + connectivity_unique_name + ". Choose ConnectivityOperation::Modify");
}
m_mesh_graph->addAlgorithm(
Expand Down
7 changes: 5 additions & 2 deletions arctools/neo/src/tests/NeoBaseTest.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
//-----------------------------------------------------------------------------
// Copyright 2000-2023 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
// See the top-level COPYRIGHT file for details.
// SPDX-License-Identifier: Apache-2.0
//-----------------------------------------------------------------------------
/*---------------------------------------------------------------------------*/
/* NeoBaseTest.cpp (C) 2000-2023 */
/* NeoBaseTest.cpp (C) 2000-2025 */
/* */
/* Base tests for Neo kernel */
/*---------------------------------------------------------------------------*/
Expand Down Expand Up @@ -164,9 +164,11 @@ TEST(NeoTestItemRange, test_item_range) {

TEST(NeoTestFutureItemRange, test_future_item_range) {
Neo::FutureItemRange future_item_range{};
EXPECT_EQ(future_item_range.size(), 0);
// Manually fill contained ItemRange
std::vector<Neo::utils::Int32> lids{ 0, 2, 4, 6 };
future_item_range.new_items = Neo::ItemRange{ Neo::ItemLocalIds{ lids } };
EXPECT_EQ(future_item_range.size(), lids.size());
Neo::ItemRange& internal_range = future_item_range;
EXPECT_EQ(&future_item_range.new_items, &internal_range);
auto end_update = Neo::EndOfMeshUpdate{};
Expand All @@ -175,6 +177,7 @@ TEST(NeoTestFutureItemRange, test_future_item_range) {
std::vector<int> filter{ 0, 1, 2 };
auto filtered_future_range =
Neo::make_future_range(future_item_range, filter);
EXPECT_EQ(filtered_future_range.size(), 0);
// Get item_ranges
auto filtered_range = filtered_future_range.get(end_update);
auto item_range = future_item_range.get(end_update);
Expand Down
28 changes: 26 additions & 2 deletions arctools/neo/src/tests/NeoMeshAPITest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,17 @@ TEST(NeoMeshApiTest, SetNodeCoordsTest) {

/*---------------------------------------------------------------------------*/

TEST(NeoMeshApiTest,EmptyMeshConnectivity) {
// Check empty connectivity
Neo::Family empty_family{Neo::ItemKind::IK_None, "EmptyFamily"};
Neo::Mesh::ConnectivityPropertyType empty_property{};
Neo::Mesh::Connectivity empty_connectivity{empty_family,empty_family,"empty_connectivity",
empty_property,empty_property};
EXPECT_TRUE(empty_connectivity.isEmpty());
}

/*---------------------------------------------------------------------------*/

bool areEqual(Neo::Mesh::Connectivity const con1, Neo::Mesh::Connectivity const con2) {
bool are_equal = con1.name == con2.name;
are_equal &= &con1.source_family == &con2.source_family;
Expand Down Expand Up @@ -301,6 +312,10 @@ TEST(NeoMeshApiTest, AddItemConnectivity) {
// check connectivities
// check cell_to_nodes
auto cell_to_nodes = mesh.getConnectivity(cell_family, node_family, cell_to_nodes_connectivity_name);
EXPECT_FALSE(cell_to_nodes.isEmpty());
// check operator ==
auto cell_to_nodes_copy{cell_to_nodes};
EXPECT_EQ(cell_to_nodes,cell_to_nodes_copy);
EXPECT_EQ(cell_to_nodes_connectivity_name, cell_to_nodes.name);
EXPECT_EQ(&cell_family, &cell_to_nodes.source_family);
EXPECT_EQ(&node_family, &cell_to_nodes.target_family);
Expand Down Expand Up @@ -445,14 +460,23 @@ TEST(NeoMeshApiTest, AddAndChangeItemConnectivity) {
auto future_dofs = Neo::FutureItemRange{};
mesh.scheduleAddItems(cell_family, cell_uids, future_cells);
mesh.scheduleAddItems(dof_family, dof_uids, future_dofs);
// Add en empty connectivity
mesh.scheduleAddConnectivity(cell_family, Neo::ItemRange{}, dof_family, 0,
{}, "cell_to_dofs");
mesh.applyScheduledOperations();
// It is possible to modifiy an empty connectivity using ConnectivityOperation::Add (the default)
mesh.scheduleAddConnectivity(cell_family, future_cells, dof_family, 3,
cell_dofs, "cell_to_dofs");
mesh.applyScheduledOperations();

// Change an existing connectivity : cell 0 now points to dofs uids {3,4}
// Change an existing connectivity: cell 0 now points to dofs uids {3,4}
auto cell_lids = cell_family.itemUniqueIdsToLocalids({ 0 });
Neo::ItemRange cell_range{ cell_lids };
auto connected_dofs = std::vector<Neo::utils::Int64>{ 3, 4 };
// First try using ConnectivityOperation::Add an existing connectivity: it fails
EXPECT_THROW(mesh.scheduleAddConnectivity(cell_family, cell_range, dof_family, 2,
connected_dofs, "cell_to_dofs",
Neo::Mesh::ConnectivityOperation::Add), std::invalid_argument);
// Second try using ConnectivityOperation::Add an existing connectivity: it works
mesh.scheduleAddConnectivity(cell_family, cell_range, dof_family, 2,
connected_dofs, "cell_to_dofs",
Neo::Mesh::ConnectivityOperation::Modify);
Expand Down