@@ -468,6 +468,122 @@ TEST(ascent_mir, axom_q7o5_material_boundary)
468468 " with Axom balls_and_jacks_q7o5 material data." ;
469469 ASCENT_ACTIONS_DUMP (actions,output_file,msg);
470470}
471+ // -----------------------------------------------------------------------------
472+ TEST (ascent_mir, test_material_field_selection)
473+ {
474+ // Verify the "materials" field selection keeps material fields and matsets.
475+ auto mesh_domain = [](Node &mesh) -> Node *
476+ {
477+ if (mesh.has_path (" fields" ))
478+ {
479+ return &mesh;
480+ }
481+
482+ for (index_t i = 0 ; i < mesh.number_of_children (); ++i)
483+ {
484+ Node &candidate = mesh.child (i);
485+ if (candidate.has_path (" fields" ))
486+ {
487+ return &candidate;
488+ }
489+ }
490+
491+ return nullptr ;
492+ };
493+
494+ Node data;
495+ std::string root_file;
496+ ASSERT_TRUE (stage_axom_klee_fixture (" 3mat_q12o12" , root_file));
497+
498+ conduit::relay::io::blueprint::load_mesh (root_file, data);
499+ Node *input_dom = mesh_domain (data);
500+ ASSERT_TRUE (input_dom != nullptr );
501+ ASSERT_TRUE (input_dom->has_path (" fields/vol_frac_inner" ));
502+ ASSERT_TRUE (input_dom->has_path (" fields/vol_frac_middle" ));
503+ ASSERT_TRUE (input_dom->has_path (" fields/vol_frac_outer" ));
504+ (*input_dom)[" state/cycle" ] = 0 ;
505+
506+ const std::string output_path = prepare_output_dir ();
507+ const std::string output_file =
508+ conduit::utils::join_file_path (output_path,
509+ " tout_material_field_selection" );
510+ const std::string output_root_file = output_file + " .cycle_000000.root" ;
511+
512+ if (conduit::utils::is_file (output_root_file))
513+ {
514+ conduit::utils::remove_file (output_root_file);
515+ }
516+
517+ conduit::Node actions;
518+ conduit::Node &add_extracts = actions.append ();
519+ add_extracts[" action" ] = " add_extracts" ;
520+ conduit::Node &extracts = add_extracts[" extracts" ];
521+ extracts[" e1/type" ] = " relay" ;
522+ extracts[" e1/params/path" ] = output_file;
523+ extracts[" e1/params/protocol" ] = " blueprint/mesh/hdf5" ;
524+ extracts[" e1/params/fields" ].append () = " materials" ;
525+
526+ Ascent ascent;
527+ ascent.open ();
528+ ascent.publish (data);
529+ ascent.execute (actions);
530+ ascent.close ();
531+
532+ Node filtered;
533+ conduit::relay::io::blueprint::load_mesh (output_root_file, filtered);
534+ Node *filtered_dom = mesh_domain (filtered);
535+ ASSERT_TRUE (filtered_dom != nullptr );
536+
537+ const Node &dom = *filtered_dom;
538+ EXPECT_TRUE (dom.has_path (" fields/mesh_material_attribute" ));
539+ EXPECT_TRUE (dom.has_path (" fields/boundary_material_attribute" ));
540+ EXPECT_TRUE (dom.has_path (" fields/vol_frac_inner" ));
541+ EXPECT_TRUE (dom.has_path (" fields/vol_frac_middle" ));
542+ EXPECT_TRUE (dom.has_path (" fields/vol_frac_outer" ));
543+ EXPECT_TRUE (dom.has_path (" matsets/material" ));
544+
545+ const Node &material_values = dom[" fields/mesh_material_attribute/values" ];
546+ ASSERT_EQ (material_values.dtype ().number_of_elements (), 1 );
547+ ASSERT_TRUE (material_values.dtype ().is_int32 () || material_values.dtype ().is_int64 ());
548+ if (material_values.dtype ().is_int32 ())
549+ {
550+ EXPECT_EQ (material_values.as_int32_ptr ()[0 ], 1 );
551+ }
552+ else
553+ {
554+ EXPECT_EQ (material_values.as_int64_ptr ()[0 ], 1 );
555+ }
556+
557+ const Node &inner_values = dom[" fields/vol_frac_inner/values" ];
558+ ASSERT_TRUE (inner_values.dtype ().is_float64 () ||
559+ inner_values.dtype ().is_float32 ());
560+
561+ double inner_min = std::numeric_limits<double >::max ();
562+ double inner_max = -std::numeric_limits<double >::max ();
563+ const index_t num_inner_values = inner_values.dtype ().number_of_elements ();
564+ if (inner_values.dtype ().is_float64 ())
565+ {
566+ const float64 *values = inner_values.as_float64_ptr ();
567+ for (index_t i = 0 ; i < num_inner_values; ++i)
568+ {
569+ inner_min = std::min (inner_min, values[i]);
570+ inner_max = std::max (inner_max, values[i]);
571+ }
572+ }
573+ else
574+ {
575+ const float32 *values = inner_values.as_float32_ptr ();
576+ for (index_t i = 0 ; i < num_inner_values; ++i)
577+ {
578+ inner_min = std::min (inner_min, static_cast <double >(values[i]));
579+ inner_max = std::max (inner_max, static_cast <double >(values[i]));
580+ }
581+ }
582+
583+ EXPECT_GT (num_inner_values, 0 );
584+ EXPECT_GT (inner_max, inner_min);
585+ }
586+
471587// -----------------------------------------------------------------------------
472588int main (int argc, char * argv[])
473589{
0 commit comments