Skip to content

Commit 3c13f92

Browse files
done
1 parent bff6655 commit 3c13f92

3 files changed

Lines changed: 257 additions & 9 deletions

File tree

src/libs/blueprint/conduit_blueprint_mesh.hpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1010,7 +1010,7 @@ namespace specset
10101010
const std::string &dest_matset_name,
10111011
conduit::Node &dest_specset,
10121012
const float64 epsilon = CONDUIT_EPSILON);
1013-
1013+
10141014
//-------------------------------------------------------------------------
10151015
index_t CONDUIT_BLUEPRINT_API get_num_species_for_material(
10161016
const conduit::Node &specset,
@@ -1023,6 +1023,15 @@ namespace specset
10231023
//-------------------------------------------------------------------------
10241024
index_t CONDUIT_BLUEPRINT_API count_materials_from_specset(const conduit::Node &specset);
10251025

1026+
//-------------------------------------------------------------------------
1027+
// this will use set external if the species_names already exist
1028+
void CONDUIT_BLUEPRINT_API create_or_reuse_species_names(const conduit::Node &specset,
1029+
conduit::Node &species_names);
1030+
1031+
//-------------------------------------------------------------------------
1032+
// this will use set if the species_names already exist
1033+
void CONDUIT_BLUEPRINT_API create_or_copy_species_names(const conduit::Node &specset,
1034+
conduit::Node &species_names);
10261035
//-------------------------------------------------------------------------
10271036
// Converts a blueprint specset to the silo style sparse mixed slot
10281037
// representation.

src/libs/blueprint/conduit_blueprint_mesh_matset_xforms.cpp

Lines changed: 205 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ namespace detail
6767
//-----------------------------------------------------------------------------
6868

6969
//-----------------------------------------------------------------------------
70+
// for each element:
71+
// for each material:
72+
// do_for_each_material()
7073
template <class ForEachValue>
7174
void
7275
walk_matset_value_by_element(const MatsetAccessor &m_acc,
@@ -86,6 +89,10 @@ walk_matset_value_by_element(const MatsetAccessor &m_acc,
8689
}
8790

8891
//-----------------------------------------------------------------------------
92+
// for each element:
93+
// for each material:
94+
// do_for_each_material()
95+
// do_for_each_elem()
8996
template <class ForEachValue, class ForEachElement>
9097
void
9198
walk_matset_by_element(const MatsetAccessor &m_acc,
@@ -142,6 +149,12 @@ walk_matset_by_element(const MatsetAccessor &m_acc,
142149
}
143150

144151
//-----------------------------------------------------------------------------
152+
// for each element:
153+
// for each material:
154+
// for each species:
155+
// do_for_each_species()
156+
// do_for_each_material()
157+
// do_for_each_elem()
145158
template <class ForEachSpeciesValue, class ForEachValue, class ForEachElement>
146159
void
147160
walk_matset_species_by_element(const MatsetAccessor &m_acc,
@@ -164,6 +177,7 @@ walk_matset_species_by_element(const MatsetAccessor &m_acc,
164177
for (index_t elem_idx = 0; elem_idx < num_elems; elem_idx ++)
165178
{
166179
index_t nmats_in_elem = 0;
180+
index_t nspec_in_elem = 0;
167181
for (index_t mat_idx = 0; mat_idx < nmats; mat_idx ++)
168182
{
169183
const float64 vol_frac = m_acc.get_vol_frac(elem_idx, mat_idx);
@@ -180,9 +194,10 @@ walk_matset_species_by_element(const MatsetAccessor &m_acc,
180194
// nmats_in_elem is running count of materials in the current zone
181195
for_each_value(elem_idx, mat_idx, nmats_in_elem);
182196
nmats_in_elem ++;
197+
nspec_in_elem += num_spec_for_mat;
183198
}
184199
}
185-
for_each_element(elem_idx, nmats_in_elem);
200+
for_each_element(elem_idx, nmats_in_elem, nspec_in_elem);
186201
}
187202
}
188203
// sparse by element
@@ -191,6 +206,7 @@ walk_matset_species_by_element(const MatsetAccessor &m_acc,
191206
for (index_t elem_idx = 0; elem_idx < num_elems; elem_idx ++)
192207
{
193208
const index_t nmats_in_elem = m_acc.num_mats_for_elem(elem_idx);
209+
index_t nspec_in_elem = 0;
194210
for (index_t mat_idx = 0; mat_idx < nmats_in_elem; mat_idx ++)
195211
{
196212
const index_t num_spec_for_mat = m_acc.num_spec_for_mat(elem_idx, mat_idx);
@@ -204,13 +220,18 @@ walk_matset_species_by_element(const MatsetAccessor &m_acc,
204220
// we pass it twice because it is also the running count of materials
205221
// in the current zone
206222
for_each_value(elem_idx, mat_idx, mat_idx);
223+
224+
nspec_in_elem += num_spec_for_mat;
207225
}
208-
for_each_element(elem_idx, nmats_in_elem);
226+
for_each_element(elem_idx, nmats_in_elem, nspec_in_elem);
209227
}
210228
}
211229
}
212230

213231
//-----------------------------------------------------------------------------
232+
// for each material:
233+
// for each element:
234+
// do_for_each_elem()
214235
template <class ForEachValue>
215236
void
216237
walk_matset_value_by_material(const MatsetAccessor &m_acc,
@@ -230,6 +251,10 @@ walk_matset_value_by_material(const MatsetAccessor &m_acc,
230251
}
231252

232253
//-----------------------------------------------------------------------------
254+
// for each material:
255+
// for each element:
256+
// do_for_each_elem()
257+
// do_for_each_material()
233258
template <class ForEachValue, class ForEachMaterial>
234259
void
235260
walk_matset_by_material(const MatsetAccessor &m_acc,
@@ -247,13 +272,13 @@ walk_matset_by_material(const MatsetAccessor &m_acc,
247272
// we *can* walk this elem-dom representation by material, and sometimes
248273
// we have to. But it is not very efficient.
249274

250-
const index_t num_zones = m_acc.num_elems();
275+
const index_t num_elems = m_acc.num_elems();
251276
// Material ids need not be within in the range [0, N-1), so we iterate
252277
// over the order materials appear in the matset.
253278
for (index_t mat_idx = 0; mat_idx < num_materials; mat_idx ++)
254279
{
255280
index_t num_elems_for_mat = 0;
256-
for (index_t elem_idx = 0; elem_idx < num_zones; elem_idx ++)
281+
for (index_t elem_idx = 0; elem_idx < num_elems; elem_idx ++)
257282
{
258283
const float64 vol_frac = m_acc.get_vol_frac(elem_idx, mat_idx);
259284
if (vol_frac > epsilon)
@@ -281,7 +306,7 @@ walk_matset_by_material(const MatsetAccessor &m_acc,
281306
{
282307
// Material ids need not be within in the range [0, N-1), so we iterate
283308
// over the order materials appear in the matset.
284-
for (int mat_idx = 0; mat_idx < num_materials; mat_idx ++)
309+
for (index_t mat_idx = 0; mat_idx < num_materials; mat_idx ++)
285310
{
286311
const index_t num_elems_for_mat = m_acc.num_elems_for_mat(mat_idx);
287312
for (index_t elem_idx = 0; elem_idx < num_elems_for_mat; elem_idx ++)
@@ -304,6 +329,12 @@ walk_matset_by_material(const MatsetAccessor &m_acc,
304329
}
305330

306331
//-----------------------------------------------------------------------------
332+
// for each material:
333+
// for each element:
334+
// for each species:
335+
// do_for_each_species()
336+
// do_for_each_elem()
337+
// do_for_each_material()
307338
template <class ForEachSpeciesValue, class ForEachValue, class ForEachMaterial>
308339
void
309340
walk_matset_species_by_material(const MatsetAccessor &m_acc,
@@ -322,13 +353,13 @@ walk_matset_species_by_material(const MatsetAccessor &m_acc,
322353
// we *can* walk this elem-dom representation by material, and sometimes
323354
// we have to. But it is not very efficient.
324355

325-
const index_t num_zones = m_acc.num_elems();
356+
const index_t num_elems = m_acc.num_elems();
326357
// Material ids need not be within in the range [0, N-1), so we iterate
327358
// over the order materials appear in the matset.
328359
for (index_t mat_idx = 0; mat_idx < num_materials; mat_idx ++)
329360
{
330361
index_t num_elems_for_mat = 0;
331-
for (index_t elem_idx = 0; elem_idx < num_zones; elem_idx ++)
362+
for (index_t elem_idx = 0; elem_idx < num_elems; elem_idx ++)
332363
{
333364
const float64 vol_frac = m_acc.get_vol_frac(elem_idx, mat_idx);
334365
if (vol_frac > epsilon)
@@ -362,7 +393,7 @@ walk_matset_species_by_material(const MatsetAccessor &m_acc,
362393
{
363394
// Material ids need not be within in the range [0, N-1), so we iterate
364395
// over the order materials appear in the matset.
365-
for (int mat_idx = 0; mat_idx < num_materials; mat_idx ++)
396+
for (index_t mat_idx = 0; mat_idx < num_materials; mat_idx ++)
366397
{
367398
const index_t num_elems_for_mat = m_acc.num_elems_for_mat(mat_idx);
368399
for (index_t elem_idx = 0; elem_idx < num_elems_for_mat; elem_idx ++)
@@ -390,6 +421,101 @@ walk_matset_species_by_material(const MatsetAccessor &m_acc,
390421
}
391422
}
392423

424+
//-----------------------------------------------------------------------------
425+
// for each material:
426+
// for each species:
427+
// for each element:
428+
// do_for_each_elem()
429+
// do_for_each_species()
430+
// do_for_each_material()
431+
template <class ForEachElementValue,
432+
class ForEachMaterialSpecies,
433+
class ForEachMaterial>
434+
void
435+
walk_matset_element_by_material_species(const MatsetAccessor &m_acc,
436+
ForEachElementValue &&for_each_element_value,
437+
ForEachMaterialSpecies &&for_each_material_species,
438+
ForEachMaterial &&for_each_material,
439+
const float64 epsilon = CONDUIT_EPSILON)
440+
{
441+
const index_t num_materials = m_acc.num_mats();
442+
443+
if (m_acc.is_element_dominant())
444+
{
445+
// elem-dom multi-buffer "full"
446+
if (m_acc.is_multi_buffer())
447+
{
448+
// we *can* walk this elem-dom representation by material, and sometimes
449+
// we have to. But it is not very efficient.
450+
451+
const index_t num_elems = m_acc.num_elems();
452+
// Material ids need not be within in the range [0, N-1), so we iterate
453+
// over the order materials appear in the matset.
454+
for (index_t mat_idx = 0; mat_idx < num_materials; mat_idx ++)
455+
{
456+
const index_t num_spec_for_mat = m_acc.num_spec_for_mat(0, mat_idx);
457+
for (index_t spec_idx = 0; spec_idx < num_spec_for_mat; spec_idx ++)
458+
{
459+
index_t num_elems_for_spec = 0;
460+
for (index_t elem_idx = 0; elem_idx < num_elems; elem_idx ++)
461+
{
462+
const float64 vol_frac = m_acc.get_vol_frac(elem_idx, mat_idx);
463+
if (vol_frac > epsilon)
464+
{
465+
// mat_idx is an index over all materials
466+
// spec_idx is an index over all species for material mat_idx
467+
// elem_idx is an index over all elements
468+
// num_elems_for_spec is running count of elements for the current species
469+
for_each_element_value(mat_idx, spec_idx, elem_idx, num_elems_for_spec);
470+
num_elems_for_spec ++;
471+
}
472+
}
473+
for_each_material_species(mat_idx, spec_idx, num_elems_for_spec);
474+
}
475+
for_each_material(mat_idx, num_spec_for_mat);
476+
}
477+
}
478+
// elem-dom uni-buffer "sparse by element"
479+
else
480+
{
481+
CONDUIT_ERROR("Walking by material is not supported for element-dominant uni-buffer material sets.");
482+
}
483+
}
484+
else
485+
{
486+
// mat-dom multi-buffer "sparse by material"
487+
if (m_acc.is_multi_buffer())
488+
{
489+
// Material ids need not be within in the range [0, N-1), so we iterate
490+
// over the order materials appear in the matset.
491+
for (index_t mat_idx = 0; mat_idx < num_materials; mat_idx ++)
492+
{
493+
const index_t num_spec_for_mat = m_acc.num_spec_for_mat(0, mat_idx);
494+
for (index_t spec_idx = 0; spec_idx < num_spec_for_mat; spec_idx ++)
495+
{
496+
const index_t num_elems_for_spec = m_acc.num_elems_for_mat(mat_idx);
497+
for (index_t elem_idx = 0; elem_idx < num_elems_for_spec; elem_idx ++)
498+
{
499+
// mat_idx is an index over all materials
500+
// spec_idx is an index over all species for material mat_idx
501+
// elem_idx is an index over all elements the material is in
502+
// we pass elem_idx twice because it is also the running count of
503+
// elements for the current material species
504+
for_each_element_value(mat_idx, spec_idx, elem_idx, elem_idx);
505+
}
506+
for_each_material_species(mat_idx, spec_idx, num_elems_for_spec);
507+
}
508+
for_each_material(mat_idx, num_spec_for_mat);
509+
}
510+
}
511+
// mat-dom uni-buffer - currently unsupported
512+
else
513+
{
514+
CONDUIT_ERROR("material-dominant uni-buffer material set is unsupported.");
515+
}
516+
}
517+
}
518+
393519
//-------------------------------------------------------------------------
394520
// helper for multi-buffer material sets that do not have
395521
// material maps.
@@ -408,6 +534,27 @@ create_material_map(const conduit::Node &matset,
408534
}
409535
}
410536

537+
//-------------------------------------------------------------------------
538+
// helper for multi-buffer species sets that do not have
539+
// species_names.
540+
void
541+
create_species_names(const conduit::Node &specset,
542+
conduit::Node &species_names)
543+
{
544+
// We must be multi-buffer, so we can assume we have a
545+
// "matset_values" child that is an object.
546+
const std::vector<std::string> &matnames = specset["matset_values"].child_names();
547+
for (const auto &matname : matnames)
548+
{
549+
const std::vector<std::string> &specnames =
550+
specset["matset_values"][matname].child_names();
551+
for (const auto &specname : specnames)
552+
{
553+
species_names[matname][specname];
554+
}
555+
}
556+
}
557+
411558
//-----------------------------------------------------------------------------
412559
// Single implementation that supports the case where just matset
413560
// is passed, and the case where the field is passed.
@@ -2510,6 +2657,56 @@ get_material_names(const conduit::Node &specset,
25102657
}
25112658
}
25122659

2660+
//-------------------------------------------------------------------------
2661+
// this will use set external if the species_names already exist
2662+
void
2663+
create_or_reuse_species_names(const conduit::Node &specset,
2664+
conduit::Node &species_names)
2665+
{
2666+
// extra seat belt here
2667+
if (! specset.dtype().is_object())
2668+
{
2669+
CONDUIT_ERROR("blueprint::mesh::specset::create_or_reuse_species_names"
2670+
" passed specset node must be a valid specset tree.");
2671+
}
2672+
2673+
species_names.reset();
2674+
2675+
if (specset.has_child("species_names"))
2676+
{
2677+
species_names.set_external(specset["species_names"]);
2678+
}
2679+
else
2680+
{
2681+
conduit::blueprint::mesh::matset::detail::create_species_names(specset, species_names);
2682+
}
2683+
}
2684+
2685+
//-------------------------------------------------------------------------
2686+
// this will use set if the species_names already exist
2687+
void
2688+
create_or_copy_species_names(const conduit::Node &specset,
2689+
conduit::Node &species_names)
2690+
{
2691+
// extra seat belt here
2692+
if (! specset.dtype().is_object())
2693+
{
2694+
CONDUIT_ERROR("blueprint::mesh::specset::create_or_copy_species_names"
2695+
" passed specset node must be a valid specset tree.");
2696+
}
2697+
2698+
species_names.reset();
2699+
2700+
if (specset.has_child("species_names"))
2701+
{
2702+
species_names.set(specset["species_names"]);
2703+
}
2704+
else
2705+
{
2706+
conduit::blueprint::mesh::matset::detail::create_species_names(specset, species_names);
2707+
}
2708+
}
2709+
25132710
//-------------------------------------------------------------------------
25142711
index_t
25152712
count_materials_from_specset(const conduit::Node &specset)

0 commit comments

Comments
 (0)