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

openmc-dev / openmc / 13860705201

14 Mar 2025 04:10PM UTC coverage: 84.925% (-0.1%) from 85.042%
13860705201

Pull #3305

github

web-flow
Merge f02782e46 into 906548db2
Pull Request #3305: New Feature Development: The Implementation of chord length sampling (CLS) method for stochastic media( #3286 )

20 of 161 new or added lines in 8 files covered. (12.42%)

1010 existing lines in 44 files now uncovered.

51574 of 60729 relevant lines covered (84.92%)

36935786.37 hits per line

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

6.8
/src/stochastic_media.cpp
1
#include <algorithm> // for min, max, sort, fill
2
#include <cassert>
3
#include <cmath>
4
#include <iterator>
5

6
#include "openmc/cell.h"
7
#include "openmc/container_util.h"
8
#include "openmc/error.h"
9
#include "openmc/material.h"
10
#include "openmc/math_functions.h"
11
#include "openmc/simulation.h"
12
#include "openmc/stochastic_media.h"
13
#include "openmc/string_utils.h"
14
#include "openmc/xml_interface.h"
15

16
namespace openmc {
17
//==============================================================================
18
// Global variables
19
//==============================================================================
20
namespace model {
21
std::unordered_map<int32_t, int32_t> stochastic_media_map;
22
vector<unique_ptr<Stochastic_Media>> stochastic_media;
23

24
} // namespace model
25
//==============================================================================
26
// Stochastic_Media implementation
27
//==============================================================================
28

NEW
29
Stochastic_Media::~Stochastic_Media()
×
30
{
NEW
31
  model::stochastic_media_map.erase(id_);
×
32
}
NEW
33

×
34
void Stochastic_Media::adjust_indices()
35
{
36
  // Adjust the indices for the materials array.
NEW
37
  for (auto& mat : particle_mat_) {
×
38

NEW
39
    auto search = model::material_map.find(mat);
×
40
    if (search != model::universe_map.end()) {
41
      mat = search->second;
NEW
42
    } else {
×
43
      fatal_error(fmt::format("Invalid material number {} specified on the "
44
                              "particle for stochastic media {}",
NEW
45
        mat, id_));
×
46
    }
NEW
47
  }
×
NEW
48

×
NEW
49
  auto search = model::material_map.find(matrix_mat_);
×
50
  if (search != model::universe_map.end()) {
NEW
51
    matrix_mat_ = search->second;
×
52
  } else {
NEW
53
    fatal_error(fmt::format("Invalid material number {} specified on the "
×
54
                            "matrix for stochastic media {}",
55
      matrix_mat_, id_));
56
  }
NEW
57
}
×
NEW
58

×
NEW
59
CLS_Media::CLS_Media(pugi::xml_node node)
×
60
{
NEW
61
  index_ = model::stochastic_media.size(); // Avoids warning about narrowing
×
62
  if (check_for_node(node, "id")) {
NEW
63
    this->set_id(std::stoi(get_node_value(node, "id")));
×
64
  } else {
65
    fatal_error("Must specify id of material in materials XML file.");
66
  }
NEW
67

×
68
  if (check_for_node(node, "name")) {
NEW
69
    name_ = get_node_value(node, "name");
×
NEW
70
  }
×
NEW
71

×
72
  bool particle_mat_present = check_for_node(node, "particle_material");
NEW
73
  bool matrix_mat_present = check_for_node(node, "matrix_material");
×
74

75
  // Read the material element.  There can be zero materials (filled with a
NEW
76
  // universe), more than one material (distribmats), and some materials may
×
NEW
77
  // be "void".
×
78
  if (particle_mat_present) {
79
    vector<std::string> mats {
NEW
80
      get_node_array<std::string>(node, "particle_material", true)};
×
NEW
81
    if (mats.size() > 0) {
×
82
      particle_mat_.reserve(mats.size());
83
      for (std::string mat : mats) {
84
        if (mat.compare("void") == 0) {
85
          particle_mat_.push_back(MATERIAL_VOID);
NEW
86
        } else {
×
87
          particle_mat_.push_back(std::stoi(mat));
NEW
88
        }
×
NEW
89
      }
×
NEW
90
    }
×
NEW
91
  } else {
×
NEW
92
    fatal_error(fmt::format(
×
NEW
93
      "An empty material element was specified for stochastic media {}", id_));
×
94
  }
NEW
95

×
96
  if (matrix_mat_present) {
97
    vector<std::string> mats {
98
      get_node_array<std::string>(node, "matrix_material", true)};
NEW
99
    matrix_mat_ = std::stoi(mats[0]);
×
NEW
100
    if (mats.size() > 1) {
×
NEW
101
      fatal_error(fmt::format(
×
102
        "Only one matrix material can be specified for stochastic media {}",
103
        id_));
NEW
104
    }
×
105
  } else {
NEW
106
    fatal_error(fmt::format(
×
NEW
107
      "An empty matrix material was specified for stochastic media {}", id_));
×
NEW
108
  }
×
NEW
109

×
110
  if (check_for_node(node, "radius")) {
NEW
111
    radius_ = node.attribute("radius").as_double();
×
112
  } else {
NEW
113
    fatal_error(fmt::format(
×
NEW
114
      "An empty particle radius was specified for stochastic media {}", id_));
×
NEW
115
  }
×
116

117
  if (check_for_node(node, "pack_fraction")) {
NEW
118
    pf_ = node.attribute("pack_fraction").as_double();
×
NEW
119
  } else {
×
120
    fatal_error(fmt::format(
NEW
121
      "An empty pack fraction was specified for stochastic media {}", id_));
×
NEW
122
  }
×
123
}
124

NEW
125
double distance_to_stochamedia(Particle& p)
×
NEW
126
{ // Sample the distance to the stochastic media
×
127
  auto i_cell = p.lowest_coord().cell;
NEW
128
  Cell& c {*model::cells[i_cell]};
×
NEW
129
  auto& media = *model::stochastic_media[c.fill_];
×
130

131
  double distance = INFINITY;
132
  if (p.status() == ParticleStatus::IN_STOCHASTIC_MEDIA) {
NEW
133
    // Designed for a randomized medium only for the time
×
134
    // being, to be upgraded subsequently
NEW
135
    double cos_value = sqrt(prn(p.current_seed()));
×
NEW
136
    distance = 2 * media.radius() * cos_value;
×
NEW
137
  } else if (p.status() == ParticleStatus::IN_MATRIX) {
×
138
    double matrix_mean_chord =
NEW
139
      4 / 3 * media.radius() * (1 - media.pf()) / media.pf();
×
NEW
140
    distance = -matrix_mean_chord * std::log(prn(p.current_seed()));
×
141
  }
142
  return distance;
NEW
143
}
×
NEW
144
void CLS_Media::sample_material(GeometryState& p)
×
NEW
145
{
×
146
  p.material_last() = p.material();
NEW
147
  p.sqrtkT_last() = p.sqrtkT();
×
NEW
148

×
149
  // Sample the material based on the packing fraction
NEW
150
  auto i_cell = p.lowest_coord().cell;
×
151
  Cell& c {*model::cells[i_cell]};
NEW
152

×
153
  double rand = openmc::prn(this->current_seed());
NEW
154
  if (rand < pf_) {
×
NEW
155
    p.status() = ParticleStatus::IN_STOCHASTIC_MEDIA;
×
156

157
    p.material() = this->particle_mat(0);
NEW
158

×
NEW
159
  } else {
×
160
    p.status() = ParticleStatus::IN_MATRIX;
NEW
161
    p.material() = this->matrix_mat();
×
NEW
162
  }
×
NEW
163
  p.sqrtkT() = c.sqrtkT(p.cell_instance());
×
164
}
NEW
165

×
166
void Stochastic_Media::set_id(int32_t id)
167
{
NEW
168
  assert(id >= 0 || id == C_NONE);
×
NEW
169

×
170
  // Clear entry in stochastic media map if an ID was already assigned before
NEW
171
  if (id_ != C_NONE) {
×
172
    model::stochastic_media_map.erase(id_);
173
    id_ = C_NONE;
NEW
174
  }
×
175

176
  // Make sure no other material has same ID
177
  if (model::stochastic_media_map.find(id) !=
178
      model::stochastic_media_map.end()) {
NEW
179
    throw std::runtime_error {
×
NEW
180
      "Two stochastic media have the same ID: " + std::to_string(id)};
×
NEW
181
  }
×
182

183
  // If no ID specified, auto-assign next ID in sequence
184
  if (id == C_NONE) {
NEW
185
    id = 0;
×
NEW
186
    for (const auto& m : model::stochastic_media) {
×
NEW
187
      id = std::max(id, m->id_);
×
NEW
188
    }
×
189
    ++id;
190
  }
191

NEW
192
  // Update ID and entry in material map
×
NEW
193
  id_ = id;
×
NEW
194
  model::stochastic_media_map[id] = index_;
×
NEW
195
}
×
196
//==============================================================================
NEW
197
// Non-method functions
×
198
//==============================================================================
199
void read_stochastic_media(pugi::xml_node root)
200
{
NEW
201
  // read stochastic media
×
NEW
202
  if (check_for_node(root, "CLS_media")) {
×
203
    for (pugi::xml_node media_node : root.children("CLS_media")) {
204
      model::stochastic_media.push_back(make_unique<CLS_Media>(media_node));
205
    }
206
    model::stochastic_media.shrink_to_fit();
207
  }
6,368✔
208
}
209

210
void free_memory_stochastic_media()
6,368✔
NEW
211
{
×
NEW
212
  model::stochastic_media.clear();
×
213
  model::stochastic_media_map.clear();
NEW
214
}
×
215
} // 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

© 2025 Coveralls, Inc