Skip to content

Commit c4d4936

Browse files
Error on mixed vector fields for Silo I/O and matset field conversions (#1555)
1 parent 68164af commit c4d4936

3 files changed

Lines changed: 243 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ and this project aspires to adhere to [Semantic Versioning](https://semver.org/s
5151
- Field/Species Set conversion routines (`to_multi_buffer_by_element()`, `to_uni_buffer_by_element()`, and `to_multi_buffer_by_material()`) previously forced materials to appear in the same order in fields/specsets as they do in the associated material set. This restriction has been relaxed.
5252
- Updated `conduit::blueprint::o2mrelation::O2MIndex` such that the number of "ones" in the one-to-many relationship is precomputed when the object is created. The number of "ones" is computed by using the `size()` method from an `O2MIndex`. If an `O2MIndex` is created but `sizes`, `offsets`, and `indices` are not present, then the `O2MIndex` constructor will examine the provided `Node` and search for data arrays to determine the number of "ones". If all data arrays in the provided `Node` have the same number of elements, then that number is assumed to be the number of "ones". If there is disagreement or there are no data arrays present, then the `O2MIndex` throws an error, as the number of "ones" is ambiguous or unknowable.
5353
- Renamed `conduit::blueprint::mesh::matset::count_zones_from_matset()` to `conduit::blueprint::mesh::matset::count_elements_from_matset()`.
54+
- Added error checking for mixed vector fields (fields with `matset_values` defined on vector components). `conduit::blueprint::mesh::field::to_multi_buffer_by_element()`, `conduit::blueprint::mesh::field::to_multi_buffer_by_material()`, `conduit::blueprint::mesh::field::to_uni_buffer_by_element()`, and `conduit::blueprint::mesh::field::to_silo()` now error in this case.
5455

5556
#### Relay
5657
- Updates to use Silo 4.12 and HDF5 2.0.0.

src/libs/blueprint/conduit_blueprint_mesh_matset_xforms.cpp

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,102 @@ create_species_names(const conduit::Node &specset,
555555
}
556556
}
557557

558+
//-------------------------------------------------------------------------
559+
// returns true if we are in this case:
560+
// (multi-buffer case where vector components are first class)
561+
// field:
562+
// topology: "topo"
563+
// association: "element"
564+
// values:
565+
// a: [1,2,5,4,4,5,8,6]
566+
// b: [1,2,5,4,4,5,8,6]
567+
// ...
568+
// matset: "mset"
569+
// matset_values:
570+
// a:
571+
// mat1: [1,1,234,32,4545,...]
572+
// mat2: [1,1,234,32,4545,...]
573+
// b:
574+
// mat1: [1,1,234,32,4545,...]
575+
// mat2: [1,1,234,32,4545,...]
576+
// ...
577+
// OR
578+
// (multi-buffer case where materials are first class)
579+
// field:
580+
// topology: "topo"
581+
// association: "element"
582+
// values:
583+
// a: [1,2,5,4,4,5,8,6]
584+
// b: [1,2,5,4,4,5,8,6]
585+
// ...
586+
// matset: "mset"
587+
// matset_values:
588+
// mat1:
589+
// a: [1,1,234,32,4545,...]
590+
// b: [1,1,234,32,4545,...]
591+
// ...
592+
// mat2:
593+
// a: [1,1,234,32,4545,...]
594+
// b: [1,1,234,32,4545,...]
595+
// ...
596+
// OR
597+
// (uni-buffer case with vector components)
598+
// field:
599+
// topology: "topo"
600+
// association: "element"
601+
// values:
602+
// a: [1,2,5,4,4,5,8,6]
603+
// b: [1,2,5,4,4,5,8,6]
604+
// ...
605+
// matset: "mset"
606+
// matset_values:
607+
// a: [1,1,234,32,4545,...]
608+
// b: [1,1,234,32,4545,...]
609+
// ...
610+
bool
611+
detect_mixed_vector_field(const conduit::Node &matset,
612+
const conduit::Node &field)
613+
{
614+
// extra seat belt here
615+
if (! matset.dtype().is_object())
616+
{
617+
CONDUIT_ERROR("blueprint::mesh::field::detect_mixed_vector_field"
618+
" passed matset node must be a valid matset tree.");
619+
}
620+
621+
if (! field.dtype().is_object())
622+
{
623+
CONDUIT_ERROR("blueprint::mesh::field::detect_mixed_vector_field"
624+
" passed field node must be a valid field tree.");
625+
}
626+
627+
// if this field is NOT material dependent
628+
if (! field.has_child("matset_values"))
629+
{
630+
return false;
631+
}
632+
633+
if (conduit::blueprint::mesh::matset::is_multi_buffer(matset))
634+
{
635+
if (field["matset_values"].number_of_children() > 0)
636+
{
637+
// it should be sufficient to check the first child
638+
if (field["matset_values"].child(0).dtype().is_object())
639+
{
640+
return true;
641+
}
642+
}
643+
}
644+
else // uni-buffer
645+
{
646+
if (field["matset_values"].dtype().is_object())
647+
{
648+
return true;
649+
}
650+
}
651+
return false;
652+
}
653+
558654
//-----------------------------------------------------------------------------
559655
// Single implementation that supports the case where just matset
560656
// is passed, and the case where the field is passed.
@@ -3073,6 +3169,13 @@ to_silo(const conduit::Node &field,
30733169
" must be a valid matset tree.");
30743170
}
30753171

3172+
if (conduit::blueprint::mesh::matset::detail::detect_mixed_vector_field(matset, field))
3173+
{
3174+
CONDUIT_ERROR("blueprint::mesh::field::to_silo"
3175+
" Mixed (material-based) field with vector components is unsupported."
3176+
" Please contact a Conduit developer.");
3177+
}
3178+
30763179
conduit::blueprint::mesh::matset::detail::to_silo(field,
30773180
matset,
30783181
dest,
@@ -3109,6 +3212,13 @@ to_multi_buffer_by_element(const conduit::Node &src_matset,
31093212
return;
31103213
}
31113214

3215+
if (conduit::blueprint::mesh::matset::detail::detect_mixed_vector_field(src_matset, src_field))
3216+
{
3217+
CONDUIT_ERROR("blueprint::mesh::field::to_multi_buffer_by_element"
3218+
" Mixed (material-based) field with vector components is unsupported."
3219+
" Please contact a Conduit developer.");
3220+
}
3221+
31123222
dest_field.reset();
31133223
conduit::blueprint::mesh::matset::detail::copy_matset_independent_parts_of_field(
31143224
src_field,
@@ -3183,6 +3293,13 @@ to_uni_buffer_by_element(const conduit::Node &src_matset,
31833293
return;
31843294
}
31853295

3296+
if (conduit::blueprint::mesh::matset::detail::detect_mixed_vector_field(src_matset, src_field))
3297+
{
3298+
CONDUIT_ERROR("blueprint::mesh::field::to_uni_buffer_by_element"
3299+
" Mixed (material-based) field with vector components is unsupported."
3300+
" Please contact a Conduit developer.");
3301+
}
3302+
31863303
dest_field.reset();
31873304
conduit::blueprint::mesh::matset::detail::copy_matset_independent_parts_of_field(
31883305
src_field,
@@ -3257,6 +3374,13 @@ to_multi_buffer_by_material(const conduit::Node &src_matset,
32573374
return;
32583375
}
32593376

3377+
if (conduit::blueprint::mesh::matset::detail::detect_mixed_vector_field(src_matset, src_field))
3378+
{
3379+
CONDUIT_ERROR("blueprint::mesh::field::to_multi_buffer_by_material"
3380+
" Mixed (material-based) field with vector components is unsupported."
3381+
" Please contact a Conduit developer.");
3382+
}
3383+
32603384
dest_field.reset();
32613385
conduit::blueprint::mesh::matset::detail::copy_matset_independent_parts_of_field(
32623386
src_field,

src/tests/blueprint/t_blueprint_mesh_matset_xforms.cpp

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,3 +1258,121 @@ TEST(conduit_blueprint_mesh_matset_xforms, mesh_util_renumber_mat_ids)
12581258
}
12591259
}
12601260

1261+
//-----------------------------------------------------------------------------
1262+
TEST(conduit_blueprint_mesh_matset_xforms, mixed_field_vector_error)
1263+
{
1264+
// multi-buffer case
1265+
{
1266+
Node matset, field;
1267+
const std::string yaml_text1 =
1268+
"topology: \"topo\"\n"
1269+
"volume_fractions: \n"
1270+
" background: [1.0, 1.0, 1.0, 0.0]\n"
1271+
" circle_a: [0.0, 0.0, 0.0, 0.333333333333333]\n"
1272+
" circle_b: [0.0, 0.0, 0.0, 0.333333333333333]\n"
1273+
" circle_c: [0.0, 0.0, 0.0, 0.333333333333333]\n";
1274+
matset.parse(yaml_text1, "yaml");
1275+
1276+
const std::string yaml_text2 =
1277+
"association: \"element\"\n"
1278+
"topology: \"topo\"\n"
1279+
"matset: \"matset\"\n"
1280+
"values:\n"
1281+
" a: [0.0, 0.5, 0.5, 0.300000009437402]\n"
1282+
" b: [0.0, 0.5, 0.5, 0.300000009437402]\n"
1283+
"matset_values: \n"
1284+
" a:\n"
1285+
" background: [0.0, 0.5, 0.5, 0.0]\n"
1286+
" circle_a: [0.0, 0.0, 0.0, 0.100000001490116]\n"
1287+
" circle_b: [0.0, 0.0, 0.0, 0.200000002980232]\n"
1288+
" circle_c: [0.0, 0.0, 0.0, 0.600000023841858]\n"
1289+
" b:\n"
1290+
" background: [0.0, 0.5, 0.5, 0.0]\n"
1291+
" circle_a: [0.0, 0.0, 0.0, 0.100000001490116]\n"
1292+
" circle_b: [0.0, 0.0, 0.0, 0.200000002980232]\n"
1293+
" circle_c: [0.0, 0.0, 0.0, 0.600000023841858]\n";
1294+
field.parse(yaml_text2, "yaml");
1295+
1296+
Node converted_field, matset_silo;
1297+
const std::string converted_matset_name = "matset2";
1298+
1299+
EXPECT_THROW(blueprint::mesh::field::to_multi_buffer_by_element(matset,
1300+
field,
1301+
converted_matset_name,
1302+
converted_field),
1303+
conduit::Error);
1304+
1305+
EXPECT_THROW(blueprint::mesh::field::to_multi_buffer_by_material(matset,
1306+
field,
1307+
converted_matset_name,
1308+
converted_field),
1309+
conduit::Error);
1310+
1311+
EXPECT_THROW(blueprint::mesh::field::to_uni_buffer_by_element(matset,
1312+
field,
1313+
converted_matset_name,
1314+
converted_field),
1315+
conduit::Error);
1316+
1317+
EXPECT_THROW(blueprint::mesh::field::to_silo(field,
1318+
matset,
1319+
matset_silo),
1320+
conduit::Error);
1321+
}
1322+
1323+
// uni-buffer case
1324+
{
1325+
Node matset, field;
1326+
const std::string yaml_text1 =
1327+
"topology: \"topo\"\n"
1328+
"material_map: \n"
1329+
" circle_a: 1\n"
1330+
" circle_b: 2\n"
1331+
" circle_c: 3\n"
1332+
" background: 0\n"
1333+
"volume_fractions: [1.0, 1.0, 1.0, 0.333333333333333, 0.333333333333333, 0.333333333333333]\n"
1334+
"material_ids: [0, 0, 0, 1, 2, 3]\n"
1335+
"sizes: [1, 1, 1, 3]\n"
1336+
"offsets: [0, 1, 2, 3]\n";
1337+
matset.parse(yaml_text1, "yaml");
1338+
1339+
const std::string yaml_text2 =
1340+
"association: \"element\"\n"
1341+
"topology: \"topo\"\n"
1342+
"matset: \"matset\"\n"
1343+
"values:\n"
1344+
" a: [0.0, 0.5, 0.5, 0.300000009437402]\n"
1345+
" b: [0.0, 0.5, 0.5, 0.300000009437402]\n"
1346+
"matset_values:\n"
1347+
" a: [0.0, 0.5, 0.5, 0.100000001490116, 0.200000002980232, 0.600000023841858]\n"
1348+
" b: [0.0, 0.5, 0.5, 0.100000001490116, 0.200000002980232, 0.600000023841858]\n";
1349+
field.parse(yaml_text2, "yaml");
1350+
1351+
Node converted_field, matset_silo;
1352+
const std::string converted_matset_name = "matset2";
1353+
1354+
EXPECT_THROW(blueprint::mesh::field::to_multi_buffer_by_element(matset,
1355+
field,
1356+
converted_matset_name,
1357+
converted_field),
1358+
conduit::Error);
1359+
1360+
EXPECT_THROW(blueprint::mesh::field::to_multi_buffer_by_material(matset,
1361+
field,
1362+
converted_matset_name,
1363+
converted_field),
1364+
conduit::Error);
1365+
1366+
EXPECT_THROW(blueprint::mesh::field::to_uni_buffer_by_element(matset,
1367+
field,
1368+
converted_matset_name,
1369+
converted_field),
1370+
conduit::Error);
1371+
1372+
EXPECT_THROW(blueprint::mesh::field::to_silo(field,
1373+
matset,
1374+
matset_silo),
1375+
conduit::Error);
1376+
}
1377+
}
1378+

0 commit comments

Comments
 (0)