Skip to content

Commit

Permalink
Merge pull request #1218 from LLNL/bugfix/whitlock/shape_is_poly_wrong
Browse files Browse the repository at this point in the history
Fixes for blueprint::utils::ShapeType.
  • Loading branch information
BradWhitlock committed Dec 22, 2023
2 parents b8485d3 + 944ff10 commit 8934836
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ and this project aspires to adhere to [Semantic Versioning](https://semver.org/s

#### Blueprint
- The `conduit::blueprint::mpi::mesh::partition_map_back()` function was enhanced so it accepts a "field_prefix" value in its options. The prefix is used when looking for the `global_vertex_ids` field, which could have been created with a prefix by the same option in the `conduit::blueprint::mpi::mesh::generate_partition_field()` function.
- The `conduit::blueprint::mesh::utils::ShapeType` class was enhanced so it can take topologies other than unstructured.

### Fixed

Expand Down
27 changes: 26 additions & 1 deletion src/libs/blueprint/conduit_blueprint_mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4672,6 +4672,11 @@ mesh::topology::unstructured::generate_lines(const Node &topo,
{
CONDUIT_ANNOTATE_MARK_FUNCTION;

if(topo.has_path("type") && topo["type"].as_string() != "unstructured")
{
CONDUIT_ERROR("The topology was not unstructured.");
}

// TODO(JRC): Revise this function so that it works on every base topology
// type and then move it to "mesh::topology::{uniform|...}::generate_lines".
const Node *coordset = bputils::find_reference_node(topo, "coordset");
Expand Down Expand Up @@ -4700,6 +4705,11 @@ mesh::topology::unstructured::generate_faces(const Node &topo,
{
CONDUIT_ANNOTATE_MARK_FUNCTION;

if(topo.has_path("type") && topo["type"].as_string() != "unstructured")
{
CONDUIT_ERROR("The topology was not unstructured.");
}

// TODO(JRC): Revise this function so that it works on every base topology
// type and then move it to "mesh::topology::{uniform|...}::generate_faces".
const Node *coordset = bputils::find_reference_node(topo, "coordset");
Expand Down Expand Up @@ -4761,7 +4771,12 @@ mesh::topology::unstructured::generate_sides(const Node &topo,
{
CONDUIT_ANNOTATE_MARK_FUNCTION;

// Retrieve Relevent Coordinate/Topology Metadata //
if(topo.has_path("type") && topo["type"].as_string() != "unstructured")
{
CONDUIT_ERROR("The topology was not unstructured.");
}

// Retrieve Relevant Coordinate/Topology Metadata //

const Node *coordset = bputils::find_reference_node(topo, "coordset");
const std::vector<std::string> csys_axes = bputils::coordset::axes(*coordset);
Expand Down Expand Up @@ -5560,6 +5575,11 @@ mesh::topology::unstructured::generate_sides(const conduit::Node &topo_src,
{
CONDUIT_ANNOTATE_MARK_FUNCTION;

if(topo_src.has_path("type") && topo_src["type"].as_string() != "unstructured")
{
CONDUIT_ERROR("The topology was not unstructured.");
}

std::string field_prefix = "";
std::vector<std::string> field_names;
const Node &fields_src = (*(topo_src.parent()->parent()))["fields"];
Expand Down Expand Up @@ -5662,6 +5682,11 @@ mesh::topology::unstructured::generate_corners(const Node &topo,
{
CONDUIT_ANNOTATE_MARK_FUNCTION;

if(topo.has_path("type") && topo["type"].as_string() != "unstructured")
{
CONDUIT_ERROR("The topology was not unstructured.");
}

// Retrieve Relevent Coordinate/Topology Metadata //

const Node *coordset = bputils::find_reference_node(topo, "coordset");
Expand Down
36 changes: 33 additions & 3 deletions src/libs/blueprint/conduit_blueprint_mesh_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,41 @@ ShapeType::ShapeType(const conduit::Node &topology)
{
init(-1);

if(topology["type"].as_string() == "unstructured" &&
topology["elements"].has_child("shape"))
const std::string type = topology["type"].as_string();
if(type == "unstructured" && topology["elements"].has_child("shape"))
{
init(topology["elements/shape"].as_string());
}
else if(type == "points")
{
// handle points separately.
init("point");
}
else
{
// Handle other topology types. Using the spatial dimension as a proxy
// for the topological dimension.
const Node *coordset = find_reference_node(topology, "coordset");
conduit::index_t d = coordset::dims(*coordset);
switch(d)
{
case 0:
init("point");
break;
case 1:
init("line");
break;
case 2:
init("quad");
break;
case 3:
init("hex");
break;
default:
CONDUIT_ERROR("Unable to determine shape for topology.");
break;
}
}
}


Expand Down Expand Up @@ -138,7 +168,7 @@ ShapeType::init(const index_t type_id)
bool
ShapeType::is_poly() const
{
return embedding == NULL;
return embedding == NULL && (dim == 2 || dim == 3);
}


Expand Down
52 changes: 52 additions & 0 deletions src/tests/blueprint/t_blueprint_mesh_generate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1828,3 +1828,55 @@ TEST(conduit_blueprint_generate_unstructured, generate_corners)
}
}
}

//-----------------------------------------------------------------------------
TEST(conduit_blueprint_generate, generate_exceptions)
{
for(int i = 0; i < 4; i++)
{
conduit::Node out;
conduit::blueprint::mesh::examples::braid("uniform", 2, 2, 2, out);
const conduit::Node &topologies = out["topologies"];
const conduit::Node &n_topo = topologies[0];
bool generatedException = false;
try
{
// Pass a uniform topology to a routine that expects unstructured.
conduit::Node s2dmap, d2smap;
switch(i)
{
case 0:
conduit::blueprint::mesh::topology::unstructured::generate_lines(n_topo,
out["topologies/line"],
s2dmap,
d2smap);
break;
case 1:
conduit::blueprint::mesh::topology::unstructured::generate_faces(n_topo,
out["topologies/face"],
s2dmap,
d2smap);
break;
case 2:
conduit::blueprint::mesh::topology::unstructured::generate_sides(n_topo,
out["topologies/side"],
out["coordsets/side_coords"],
s2dmap,
d2smap);
break;
case 3:
conduit::blueprint::mesh::topology::unstructured::generate_corners(n_topo,
out["topologies/corner"],
out["coordsets/corner_coords"],
s2dmap,
d2smap);
break;
}
}
catch(conduit::Error &)
{
generatedException = true;
}
EXPECT_TRUE(generatedException);
}
}
75 changes: 75 additions & 0 deletions src/tests/blueprint/t_blueprint_mesh_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,81 @@ void save_mesh(const conduit::Node &root, const std::string &filebase)
#endif
}

//-----------------------------------------------------------------------------
TEST(conduit_blueprint_mesh_utils, shapetype)
{
struct test_case
{
std::string meshtype;
std::string shapetype;
int sdim;
// answers
int tdim;
bool is_poly, is_polygonal, is_polyhedral;
};
std::vector<test_case> tests{
// non-unstructured topo types.
{"points", "point", 2, 0, false, false, false},
{"points", "point", 3, 0, false, false, false},
{"points_implicit", "point", 2, 0, false, false, false},
{"points_implicit", "point", 3, 0, false, false, false},

{"uniform", "line", 1, 1, false, false, false},
{"uniform", "quad", 2, 2, false, false, false},
{"uniform", "hex", 3, 3, false, false, false},

{"rectilinear", "line", 1, 1, false, false, false},
{"rectilinear", "quad", 2, 2, false, false, false},
{"rectilinear", "hex", 3, 3, false, false, false},

{"structured", "quad", 2, 2, false, false, false},
{"structured", "hex", 3, 3, false, false, false},

// unstructured types
{"lines", "line", 2, 1, false, false, false},
{"lines", "line", 3, 1, false, false, false},

{"tris", "tri", 2, 2, false, false, false},

{"quads", "quad", 2, 2, false, false, false},
{"quads_poly", "polygonal", 2, 2, true, true, false},

{"tets", "tet", 3, 3, false, false, false},

{"pyramids", "pyramid", 3, 3, false, false, false},
{"wedges", "wedge", 3, 3, false, false, false},

{"hexs", "hex", 3, 3, false, false, false},
{"hexs_poly", "polyhedral", 3, 3, true, false, true}
};

for(const auto &t : tests)
{
const conduit::index_t s = 5;
conduit::Node mesh;
conduit::blueprint::mesh::examples::braid(t.meshtype,
s, t.sdim >= 2 ? s : 0, t.sdim >= 3 ? s : 0,
mesh);

// Make sure we can pass various topology types to ShapeType.
const conduit::Node &topo = mesh["topologies/mesh"];
conduit::blueprint::mesh::utils::ShapeType shape(topo);

EXPECT_EQ(conduit::blueprint::mesh::coordset::dims(mesh["coordsets/coords"]), t.sdim);
EXPECT_EQ(shape.type, t.shapetype);
EXPECT_EQ(shape.dim, t.tdim);
EXPECT_EQ(shape.is_poly(), t.is_poly);
EXPECT_EQ(shape.is_polygonal(), t.is_polygonal);
EXPECT_EQ(shape.is_polyhedral(), t.is_polyhedral);
}

// Initialize with a bad shape name.
conduit::blueprint::mesh::utils::ShapeType shape("bogus");
EXPECT_FALSE(shape.is_poly());
EXPECT_FALSE(shape.is_polygonal());
EXPECT_FALSE(shape.is_polyhedral());
}

//-----------------------------------------------------------------------------
TEST(conduit_blueprint_mesh_utils, adjset_validate_element_0d)
{
Expand Down

0 comments on commit 8934836

Please sign in to comment.