• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

openmc-dev / openmc / 21666331756

04 Feb 2026 09:39AM UTC coverage: 81.764% (+0.001%) from 81.763%
21666331756

Pull #3767

github

web-flow
Merge a19b37095 into b41e22f68
Pull Request #3767: Make MaterialFilter support void material

17308 of 24257 branches covered (71.35%)

Branch coverage included in aggregate %.

33 of 33 new or added lines in 2 files covered. (100.0%)

1 existing line in 1 file now uncovered.

55928 of 65313 relevant lines covered (85.63%)

44281473.2 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.2
/src/tallies/filter_material.cpp
1
#include "openmc/tallies/filter_material.h"
2

3
#include <cassert>
4

5
#include <fmt/core.h>
6

7
#include "openmc/capi.h"
8
#include "openmc/material.h"
9
#include "openmc/xml_interface.h"
10

11
namespace openmc {
12

13
void MaterialFilter::from_xml(pugi::xml_node node)
1,976✔
14
{
15
  // Get material IDs and convert to indices in the global materials vector
16
  auto mats = get_node_array<int32_t>(node, "bins");
1,976✔
17
  for (auto& m : mats) {
4,350✔
18
    // If void material skip check
19
    if (m == MATERIAL_VOID)
2,374✔
20
      continue;
11✔
21

22
    auto search = model::material_map.find(m);
2,363✔
23
    if (search == model::material_map.end()) {
2,363!
24
      throw std::runtime_error {fmt::format(
×
25
        "Could not find material {} specified on tally filter.", m)};
×
26
    }
27
    m = search->second;
2,363✔
28
  }
29

30
  this->set_materials(mats);
1,976✔
31
}
1,976✔
32

33
void MaterialFilter::set_materials(span<const int32_t> materials)
2,334✔
34
{
35
  // Clear existing materials
36
  materials_.clear();
2,334✔
37
  materials_.reserve(materials.size());
2,334✔
38
  map_.clear();
2,334✔
39

40
  int32_t size = model::materials.size();
2,334✔
41

42
  // Update materials and mapping
43
  for (auto& index : materials) {
6,504✔
44
    assert(index >= MATERIAL_VOID);
3,409!
45
    assert(index < size);
3,409!
46
    materials_.push_back(index);
4,170✔
47
    map_[index] = materials_.size() - 1;
4,170✔
48
  }
49

50
  n_bins_ = materials_.size();
2,334✔
51
}
2,334✔
52

53
void MaterialFilter::get_all_bins(
1,573,715,241✔
54
  const Particle& p, TallyEstimator estimator, FilterMatch& match) const
55
{
56
  auto search = map_.find(p.material());
1,573,715,241✔
57
  if (search != map_.end()) {
1,573,715,241✔
58
    match.bins_.push_back(search->second);
841,645,081✔
59
    match.weights_.push_back(1.0);
841,645,081✔
60
  }
61
}
1,573,715,241✔
62

63
void MaterialFilter::to_statepoint(hid_t filter_group) const
2,898✔
64
{
65
  Filter::to_statepoint(filter_group);
2,898✔
66
  vector<int32_t> material_ids;
2,898✔
67
  for (auto c : materials_) {
16,695✔
68
    auto id = MATERIAL_VOID;
13,797✔
69
    if (c != MATERIAL_VOID)
13,797✔
70
      id = model::materials[c]->id_;
13,786✔
71
    material_ids.push_back(id);
13,797✔
72
  }
73
  write_dataset(filter_group, "bins", material_ids);
2,898✔
74
}
2,898✔
75

76
std::string MaterialFilter::text_label(int bin) const
10,329✔
77
{
78
  std::string label = "Material Void";
10,329✔
79
  if (materials_[bin] != MATERIAL_VOID)
10,329✔
80
    label = fmt::format("Material {}", model::materials[materials_[bin]]->id_);
20,636✔
81
  return label;
10,329✔
UNCOV
82
}
×
83

84
//==============================================================================
85
// C-API functions
86
//==============================================================================
87

88
extern "C" int openmc_material_filter_get_bins(
319✔
89
  int32_t index, const int32_t** bins, size_t* n)
90
{
91
  // Make sure this is a valid index to an allocated filter.
92
  if (int err = verify_filter(index))
319!
93
    return err;
×
94

95
  // Get a pointer to the filter and downcast.
96
  const auto& filt_base = model::tally_filters[index].get();
319✔
97
  auto* filt = dynamic_cast<MaterialFilter*>(filt_base);
319!
98

99
  // Check the filter type.
100
  if (!filt) {
319!
101
    set_errmsg("Tried to get material filter bins on a non-material filter.");
×
102
    return OPENMC_E_INVALID_TYPE;
×
103
  }
104

105
  // Output the bins.
106
  *bins = filt->materials().data();
319✔
107
  *n = filt->materials().size();
319✔
108
  return 0;
319✔
109
}
110

111
extern "C" int openmc_material_filter_set_bins(
358✔
112
  int32_t index, size_t n, const int32_t* bins)
113
{
114
  // Make sure this is a valid index to an allocated filter.
115
  if (int err = verify_filter(index))
358!
116
    return err;
×
117

118
  // Get a pointer to the filter and downcast.
119
  const auto& filt_base = model::tally_filters[index].get();
358✔
120
  auto* filt = dynamic_cast<MaterialFilter*>(filt_base);
358!
121

122
  // Check the filter type.
123
  if (!filt) {
358!
124
    set_errmsg("Tried to set material filter bins on a non-material filter.");
×
125
    return OPENMC_E_INVALID_TYPE;
×
126
  }
127

128
  // Update the filter.
129
  filt->set_materials({bins, n});
358✔
130
  return 0;
358✔
131
}
132

133
} // namespace openmc
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc