Skip to content

Commit

Permalink
some new matset utils
Browse files Browse the repository at this point in the history
  • Loading branch information
JustinPrivitera committed Jan 7, 2025
1 parent f75b514 commit 2548674
Show file tree
Hide file tree
Showing 3 changed files with 237 additions and 30 deletions.
11 changes: 11 additions & 0 deletions src/libs/blueprint/conduit_blueprint_mesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,17 @@ namespace matset
conduit::Node &dest,
const float64 epsilon = CONDUIT_EPSILON);

//-------------------------------------------------------------------------
index_t CONDUIT_BLUEPRINT_API count_zones_from_matset(const conduit::Node &matset);
//-------------------------------------------------------------------------
bool CONDUIT_BLUEPRINT_API is_material_in_zone(const conduit::Node &matset,
const std::string &matname,
const index_t zone_id,
const float64 epsilon = CONDUIT_EPSILON);
//-----------------------------------------------------------------------------
std::map<int, std::string> CONDUIT_BLUEPRINT_API create_reverse_material_map(
const conduit::Node &src_matset);

//-------------------------------------------------------------------------
// blueprint::mesh::matset::index protocol interface
//-------------------------------------------------------------------------
Expand Down
168 changes: 138 additions & 30 deletions src/libs/blueprint/conduit_blueprint_mesh_matset_xforms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,22 +527,6 @@ copy_matset_independent_parts_of_field(const conduit::Node &src_field,
dest_field["matset"] = dest_matset_name;
}

//-----------------------------------------------------------------------------
void
create_reverse_matmap(const conduit::Node &src_matset,
std::map<int, std::string> &reverse_matmap)
{
// fill out map
auto matmap_itr = src_matset["material_map"].children();
while (matmap_itr.has_next())
{
const Node &matmap_entry = matmap_itr.next();
const std::string matname = matmap_itr.name();

reverse_matmap[matmap_entry.to_int()] = matname;
}
}

//-----------------------------------------------------------------------------
// load the element ids into a set to find out how many there are
int
Expand All @@ -564,13 +548,13 @@ determine_num_elems_in_multi_buffer_by_material(const conduit::Node &elem_ids)
}

return static_cast<int>(elem_ids_set.size());
};
}

//-----------------------------------------------------------------------------
void
walk_uni_buffer_by_element_to_multi_buffer_by_element(
const conduit::Node &src_matset,
std::map<int, std::string> &reverse_matmap,
const std::map<int, std::string> &reverse_matmap,
float64_accessor &values, // can be either vol fracs or matset vals
int64_accessor &material_ids,
std::map<std::string, std::vector<float64>> &new_vals)
Expand All @@ -579,7 +563,7 @@ walk_uni_buffer_by_element_to_multi_buffer_by_element(
int num_elems = o2m_idx.size();

// initialize sizes
for (auto & mapitem : reverse_matmap)
for (const auto & mapitem : reverse_matmap)
{
const std::string &matname = mapitem.second;
new_vals[matname] = std::vector<float64>(num_elems);
Expand All @@ -594,7 +578,7 @@ walk_uni_buffer_by_element_to_multi_buffer_by_element(

float64 val = values[data_index];
int mat_id = material_ids[data_index];
const std::string &matname = reverse_matmap[mat_id];
const std::string &matname = reverse_matmap.at(mat_id);
new_vals[matname][elem_id] = val;
}
}
Expand Down Expand Up @@ -806,8 +790,7 @@ uni_buffer_by_element_to_multi_buffer_by_element_matset(const conduit::Node &src
dest_matset["topology"].set(src_matset["topology"]);

// map material numbers to material names
std::map<int, std::string> reverse_matmap;
create_reverse_matmap(src_matset, reverse_matmap);
const std::map<int, std::string> reverse_matmap = create_reverse_material_map(src_matset["material_map"]);

// get ptr to vol fracs and mat ids
float64_accessor volume_fractions = src_matset["volume_fractions"].value();
Expand Down Expand Up @@ -843,8 +826,7 @@ uni_buffer_by_element_to_multi_buffer_by_element_field(const conduit::Node &src_
dest_field);

// map material numbers to material names
std::map<int, std::string> reverse_matmap;
create_reverse_matmap(src_matset, reverse_matmap);
const std::map<int, std::string> reverse_matmap = create_reverse_material_map(src_matset["material_map"]);

// get ptr to matset values and mat ids
float64_accessor matset_values = src_field["matset_values"].value();
Expand Down Expand Up @@ -879,8 +861,7 @@ uni_buffer_by_element_to_multi_buffer_by_material_matset(const conduit::Node &sr
dest_matset["topology"].set(src_matset["topology"]);

// map material numbers to material names
std::map<int, std::string> reverse_matmap;
create_reverse_matmap(src_matset, reverse_matmap);
const std::map<int, std::string> reverse_matmap = create_reverse_material_map(src_matset["material_map"]);

// get ptr to vol fracs and mat ids
float64_accessor volume_fractions = src_matset["volume_fractions"].value();
Expand All @@ -900,7 +881,7 @@ uni_buffer_by_element_to_multi_buffer_by_material_matset(const conduit::Node &sr

float64 vol_frac = volume_fractions[data_index];
int64 mat_id = material_ids[data_index];
const std::string &matname = reverse_matmap[mat_id];
const std::string &matname = reverse_matmap.at(mat_id);

new_vol_fracs[matname].push_back(vol_frac);
new_elem_ids[matname].push_back(elem_id);
Expand Down Expand Up @@ -929,8 +910,7 @@ uni_buffer_by_element_to_multi_buffer_by_material_field(const conduit::Node &src
dest_field);

// map material numbers to material names
std::map<int, std::string> reverse_matmap;
create_reverse_matmap(src_matset, reverse_matmap);
const std::map<int, std::string> reverse_matmap = create_reverse_material_map(src_matset["material_map"]);

// get ptr to matset values and mat ids
float64_accessor matset_values = src_field["matset_values"].value();
Expand All @@ -948,7 +928,7 @@ uni_buffer_by_element_to_multi_buffer_by_material_field(const conduit::Node &src

float64 mset_val = matset_values[data_index];
int64 mat_id = material_ids[data_index];
const std::string &matname = reverse_matmap[mat_id];
const std::string &matname = reverse_matmap.at(mat_id);

new_mset_vals[matname].push_back(mset_val);
}
Expand Down Expand Up @@ -1304,6 +1284,134 @@ to_silo(const conduit::Node &matset,
epsilon);
}

//-----------------------------------------------------------------------------
std::map<int, std::string>
create_reverse_material_map(const conduit::Node &src_material_map)
{
std::map<int, std::string> reverse_matmap;
// fill out map
auto matmap_itr = src_material_map.children();
while (matmap_itr.has_next())
{
const Node &matmap_entry = matmap_itr.next();
const std::string matname = matmap_itr.name();
reverse_matmap[matmap_entry.to_int()] = matname;
}
return reverse_matmap;
}
//-------------------------------------------------------------------------
index_t
count_zones_from_matset(const conduit::Node &matset)
{
// extra seat belt here
if (! matset.dtype().is_object())
{
CONDUIT_ERROR("blueprint::mesh::matset::count_zones_in_matset"
" passed matset node must be a valid matset tree.");
}
// full
if (is_element_dominant(matset) && is_multi_buffer(matset))
{
if (matset["volume_fractions"].number_of_children() > 0)
{
return matset["volume_fractions"][0].dtype().number_of_elements();
}
else
{
return 0;
}
}
// sparse_by_element
else if (is_element_dominant(matset))
{
return matset["sizes"].dtype().number_of_elements();
}
// sparse_by_material
else if (is_material_dominant(matset))
{
return detail::determine_num_elems_in_multi_buffer_by_material(matset["element_ids"]);
}
else
{
CONDUIT_ERROR("Unknown matset type.");
}

return -1;
}

//-------------------------------------------------------------------------
bool
is_material_in_zone(const conduit::Node &matset,
const std::string &matname,
const index_t zone_id,
const float64 epsilon)
{
// extra seat belt here
if (! matset.dtype().is_object())
{
CONDUIT_ERROR("blueprint::mesh::matset::is_material_in_zone"
" passed matset node must be a valid matset tree.");
}
// full
if (is_element_dominant(matset) && is_multi_buffer(matset))
{
if (matset["volume_fractions"].has_child(matname))
{
const float64_accessor vfs = matset["volume_fractions"][matname].value();
return vfs[zone_id] > epsilon;
}
else
{
// obviously the material is not present in the zone; it is not
// present in the matset
return false;
}
}
// sparse_by_element
else if (is_element_dominant(matset))
{
const index_t_accessor sizes = matset["sizes"].value();
const index_t_accessor offsets = matset["offsets"].value();
const index_t_accessor material_ids = matset["material_ids"].value();
const index_t size = sizes[zone_id];
const index_t offset = offsets[zone_id];
std::map<int, std::string> reverse_matmap = mesh::matset::create_reverse_material_map(matset["material_map"]);
// look at materials in this zone
for (index_t idx = 0; idx < size; idx ++)
{
const index_t mat_id = material_ids[idx + offset];
const std::string &curr_matname = reverse_matmap.at(mat_id);
if (curr_matname == matname)
{
// we found the right material in this zone
return true;
}
}
// not found in this zone
return false;
}
// sparse_by_material
else if (is_material_dominant(matset))
{
if (matset["element_ids"].has_child(matname))
{
const index_t_accessor elem_ids = matset["element_ids"][matname].value();
return elem_ids.count(zone_id) > 0;
}
else
{
// obviously the material is not present in the zone; it is not
// present in the matset
return false;
}
}
else
{
CONDUIT_ERROR("Unknown matset type.");
}
return false;
}

//-----------------------------------------------------------------------------
void
to_multi_buffer_full(const conduit::Node &src_matset,
Expand Down
88 changes: 88 additions & 0 deletions src/tests/blueprint/t_blueprint_mesh_matset_xforms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,94 @@ convert_to_material_based(const Node &topo, Node &mset)

/// Test Cases ///

//-----------------------------------------------------------------------------
TEST(conduit_blueprint_mesh_matset_xforms, mesh_util_create_reverse_matmap)
{
Node material_map;
material_map["mat1"] = 5;
material_map["mat2"] = 213423;
material_map["mat3"] = 6;
material_map["mat4"] = 0;

const std::map<int, std::string> reverse_matmap =
blueprint::mesh::matset::create_reverse_material_map(material_map);
EXPECT_EQ("mat4", reverse_matmap.at(0));
EXPECT_EQ("mat1", reverse_matmap.at(5));
EXPECT_EQ("mat3", reverse_matmap.at(6));
EXPECT_EQ("mat2", reverse_matmap.at(213423));
}

//-----------------------------------------------------------------------------
TEST(conduit_blueprint_mesh_matset_xforms, mesh_util_count_zones_from_matset)
{
const int nx = 4, ny = 4;
const double radius = 0.25;

CONDUIT_INFO("venn full count zones");
{
Node mesh;
blueprint::mesh::examples::venn("full", nx, ny, radius, mesh);
const Node &mset = mesh["matsets/matset"];

EXPECT_EQ(16, blueprint::mesh::matset::count_zones_from_matset(mset));
}

CONDUIT_INFO("venn sparse_by_material count zones");
{
Node mesh;
blueprint::mesh::examples::venn("sparse_by_material", nx, ny, radius, mesh);
const Node &mset = mesh["matsets/matset"];

EXPECT_EQ(16, blueprint::mesh::matset::count_zones_from_matset(mset));
}

CONDUIT_INFO("venn sparse_by_element count zones");
{
Node mesh;
blueprint::mesh::examples::venn("sparse_by_element", nx, ny, radius, mesh);
const Node &mset = mesh["matsets/matset"];

EXPECT_EQ(16, blueprint::mesh::matset::count_zones_from_matset(mset));
}
}

//-----------------------------------------------------------------------------
TEST(conduit_blueprint_mesh_matset_xforms, mesh_util_is_material_in_zone)
{
const int nx = 2, ny = 2;
const double radius = 0.25;

CONDUIT_INFO("venn full check mat in zone");
{
Node mesh;
blueprint::mesh::examples::venn("full", nx, ny, radius, mesh);
const Node &mset = mesh["matsets/matset"];

EXPECT_FALSE(blueprint::mesh::matset::is_material_in_zone(mset, "circle_c", 0));
EXPECT_TRUE(blueprint::mesh::matset::is_material_in_zone(mset, "circle_c", 3));
}

CONDUIT_INFO("venn sparse_by_material check mat in zone");
{
Node mesh;
blueprint::mesh::examples::venn("sparse_by_material", nx, ny, radius, mesh);
const Node &mset = mesh["matsets/matset"];

EXPECT_FALSE(blueprint::mesh::matset::is_material_in_zone(mset, "circle_c", 0));
EXPECT_TRUE(blueprint::mesh::matset::is_material_in_zone(mset, "circle_c", 3));
}

CONDUIT_INFO("venn sparse_by_element check mat in zone");
{
Node mesh;
blueprint::mesh::examples::venn("sparse_by_element", nx, ny, radius, mesh);
const Node &mset = mesh["matsets/matset"];

EXPECT_FALSE(blueprint::mesh::matset::is_material_in_zone(mset, "circle_c", 0));
EXPECT_TRUE(blueprint::mesh::matset::is_material_in_zone(mset, "circle_c", 3));
}
}

//-----------------------------------------------------------------------------
TEST(conduit_blueprint_mesh_matset_xforms, mesh_util_to_silo_basic)
{
Expand Down

0 comments on commit 2548674

Please sign in to comment.