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

Open-Sn / opensn / 21974448813

12 Feb 2026 03:12AM UTC coverage: 74.409%. Remained the same
21974448813

push

github

web-flow
Merge pull request #922 from wdhawkins/named_xs

Adding ability to load user-specifed OpenMC cross sections

28 of 52 new or added lines in 4 files covered. (53.85%)

15 existing lines in 3 files now uncovered.

19839 of 26662 relevant lines covered (74.41%)

67860570.25 hits per line

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

96.51
/python/lib/xs.cc
1
// SPDX-FileCopyrightText: 2025 The OpenSn Authors <https://open-sn.github.io/opensn/>
2
// SPDX-License-Identifier: MIT
3

4
#include "python/lib/py_wrappers.h"
5
#include "framework/runtime.h"
6
#include "framework/materials/multi_group_xs/multi_group_xs.h"
7
#include "framework/materials/multi_group_xs/xsfile.h"
8
#include <pybind11/stl.h>
9
#include <memory>
10
#include <string>
11
#include <vector>
12

13
#define XS_GETTER(method_name) [](MultiGroupXS& self) { return convert_vector(self.method_name()); }
14

15
namespace opensn
16
{
17

18
// Wrap multi-group cross section
19
void
20
WrapMultiGroupXS(py::module& xs)
668✔
21
{
22
  // clang-format off
23
  // multi-group cross section
24
  auto multigroup_xs = py::class_<MultiGroupXS, std::shared_ptr<MultiGroupXS>>(
668✔
25
    xs,
26
    "MultiGroupXS",
27
    R"(
28
    Multi-group cross section.
29

30
    Wrapper of :cpp:class:`opensn::MultiGroupXS`.
31
    )"
32
  );
668✔
33
  multigroup_xs.def(
1,336✔
34
    py::init(
668✔
35
      []()
888✔
36
      {
37
        std::shared_ptr<MultiGroupXS> xs = std::make_shared<MultiGroupXS>();
888✔
38
        multigroup_xs_stack.push_back(xs);
888✔
39
        return xs;
888✔
40
      }),
×
41
    "Create an empty multi-group cross section."
42
  );
43
  multigroup_xs.def(
1,336✔
44
    "CreateSimpleOneGroup",
45
    [](MultiGroupXS& self, double sigma_t, double c, double velocity) {
852✔
46
      self = MultiGroupXS::CreateSimpleOneGroup(sigma_t, c, velocity);
184✔
47
    },
184✔
48
    R"(
49
    Create a one-group cross section.
50

51
    Parameters
52
    ----------
53
    sigma_t: float
54
        Total cross section.
55
    c: float
56
        Scattering ratio.
57
    velocity: float, optional
58
        Group velocity. If provided and positive, inverse velocity
59
        is populated with 1.0/velocity.
60
    )",
61
    py::arg("sigma_t"),
1,336✔
62
    py::arg("c"),
668✔
63
    py::arg("velocity") = 0.0
668✔
64
  );
65
  multigroup_xs.def(
668✔
66
    "LoadFromOpenSn",
67
    [](MultiGroupXS& self, const std::string& file_name)
1,294✔
68
    {
69
      self = MultiGroupXS::LoadFromOpenSn(file_name);
626✔
70
    },
626✔
71
    py::arg("file_name"),
668✔
72
    R"(
73
    Load multi-group cross sections from an OpenSn cross section input file.
74

75
    Format is as follows (for transfers, gprime denotes the departing group and g is the arrival
76
    group).
77

78
    .. code-block:: none
79

80
       # Add comment lines, as needed
81
       NUM_GROUPS ng
82
       NUM_MOMENTS nmom
83

84
       SIGMA_T_BEGIN
85
       0 value
86
       .
87
       .
88
       ng-1 value
89
       SIGMA_T_END
90

91
       SIGMA_A_BEGIN
92
       0 value
93
       .
94
       .
95
       ng-1 value
96
       SIGMA_A_END
97

98
       TRANSFER_MOMENTS_BEGIN
99
       M_GFROM_GTO_VAL 0 0 0 value
100
       .
101
       M_GFROM_GTO_VAL moment gfrom gto value
102
       .
103
       M_GFROM_GTO_VAL nmom-1 ng-1 ng-1 value
104
       TRANSFER_MOMENTS_END
105
    )"
106
  );
107
  multigroup_xs.def(
668✔
108
    "Combine",
109
    [](MultiGroupXS& self, const std::vector<std::pair<std::shared_ptr<MultiGroupXS>, double>>& combinations)
673✔
110
    {
111
      self = MultiGroupXS::Combine(combinations);
5✔
112
    },
5✔
113
    R"(
114
    Combine cross-section
115

116
    Parameters
117
    ----------
118

119
    combinations: List[Tuple[pyopensn.xs.MultiGroupXS, float]]
120
        List of combinations (cross section, factor)
121

122
    Examples
123
    --------
124

125
    >>> xs_1 = MultiGroupXS()
126
    >>> xs_1.CreateSimpleOneGroup(sigma_t=1, c=0.5)
127
    >>> xs_2 = MultiGroupXS()
128
    >>> xs_2.CreateSimpleOneGroup(sigma_t=2, c=1./3.)
129
    >>> xs_combined = MultiGroupXS()
130
    >>> combo = [
131
    ...     ( xs_1, 0.5 ),
132
    ...     ( xs_2, 3.0 )
133
    ... ]
134
    >>> xs_combined.Combine(combo)
135
    )",
136
    py::arg("combinations")
668✔
137
  );
138
  multigroup_xs.def(
1,336✔
139
    "LoadFromOpenMC",
140
    [](MultiGroupXS& self,
741✔
141
       const std::string& file_name,
142
       const std::string& dataset_name,
143
       double temperature,
144
       const std::vector<std::string>& extra_xs_names)
145
    {
146
      self = MultiGroupXS::LoadFromOpenMC(file_name, dataset_name, temperature, extra_xs_names);
73✔
147
    },
73✔
148
    "Load multi-group cross sections from an OpenMC cross-section file.",
149
    py::arg("file_name"),
1,336✔
150
    py::arg("dataset_name"),
1,336✔
151
    py::arg("temperature"),
668✔
152
    py::arg("extra_xs_names") = std::vector<std::string>()
1,336✔
153
  );
154
  multigroup_xs.def(
668✔
155
    "SetScalingFactor",
156
    &MultiGroupXS::SetScalingFactor,
1,336✔
157
    "Scale the cross sections by the specified factor.",
158
    py::arg("factor")
668✔
159
  );
160
  multigroup_xs.def_property_readonly(
668✔
161
    "num_groups",
162
    &MultiGroupXS::GetNumGroups,
668✔
163
    "Get number of energy groups."
164
  );
165
  multigroup_xs.def_property_readonly(
668✔
166
    "scattering_order",
167
    &MultiGroupXS::GetScatteringOrder,
668✔
168
    "Get Legendre scattering order."
169
  );
170
  multigroup_xs.def_property_readonly(
668✔
171
    "num_precursors",
172
    &MultiGroupXS::GetNumPrecursors,
668✔
173
    "Get number of precursors."
174
  );
175
  multigroup_xs.def_property_readonly(
668✔
176
    "is_fissionable",
177
    &MultiGroupXS::IsFissionable,
668✔
178
    "Check if the material is fissile."
179
  );
180
  multigroup_xs.def_property_readonly(
668✔
181
    "scaling_factor",
182
    &MultiGroupXS::GetScalingFactor,
668✔
183
    "Get the arbitrary scaling factor."
184
  );
185
  multigroup_xs.def_property_readonly(
668✔
186
    "sigma_t",
187
    XS_GETTER(GetSigmaTotal),
19✔
188
    "Get total cross section.",
189
    py::keep_alive<0, 1>()
668✔
190
  );
191
  multigroup_xs.def_property_readonly(
668✔
192
    "sigma_a",
193
    XS_GETTER(GetSigmaAbsorption),
2,512✔
194
    "Get absorption cross section.",
195
    py::keep_alive<0, 1>()
668✔
196
  );
197
  multigroup_xs.def_property_readonly(
668✔
198
    "sigma_f",
199
    XS_GETTER(GetSigmaFission),
4✔
200
    "Get fission cross section.",
201
    py::keep_alive<0, 1>()
668✔
202
  );
203
  multigroup_xs.def_property_readonly(
668✔
204
    "chi",
205
    XS_GETTER(GetChi),
2✔
206
    "Get neutron fission spectrum.",
207
    py::keep_alive<0, 1>()
668✔
208
  );
209
  multigroup_xs.def_property_readonly(
668✔
210
    "nu_sigma_f",
211
    XS_GETTER(GetNuSigmaF),
28✔
212
    "Get neutron production due to fission.",
213
    py::keep_alive<0, 1>()
668✔
214
  );
215
  multigroup_xs.def_property_readonly(
668✔
216
    "nu_prompt_sigma_f",
UNCOV
217
    XS_GETTER(GetNuPromptSigmaF),
×
218
    "Get prompt neutron production due to fission.",
219
    py::keep_alive<0, 1>()
668✔
220
  );
221
  multigroup_xs.def_property_readonly(
668✔
222
    "nu_delayed_sigma_f",
UNCOV
223
    XS_GETTER(GetNuDelayedSigmaF),
×
224
    "Get delayed neutron production due to fission.",
225
    py::keep_alive<0, 1>()
668✔
226
  );
227
  multigroup_xs.def(
668✔
228
    "has_custom_xs",
229
    &MultiGroupXS::HasCustomXS,
1,336✔
230
    "Check if a custom XS is available.",
231
    py::arg("name")
668✔
232
  );
233
  multigroup_xs.def(
668✔
234
    "get_custom_xs",
235
    [](MultiGroupXS& self, const std::string& name)
669✔
236
    { return convert_vector(self.GetCustomXS(name)); },
1✔
237
    "Get a custom XS vector.",
238
    py::arg("name")
668✔
239
  );
240
  multigroup_xs.def(
668✔
241
    "custom_xs_names",
242
    &MultiGroupXS::GetCustomXSNames,
668✔
243
    "Get a list of custom XS entries."
244
  );
245
  multigroup_xs.def_property_readonly(
668✔
246
    "inv_velocity",
247
    XS_GETTER(GetInverseVelocity),
25✔
248
    "Get inverse velocity.",
249
    py::keep_alive<0, 1>()
668✔
250
  );
251
  // clang-format on
252
}
668✔
253

254
// Wrap the cross section components of OpenSn
255
void
256
py_xs(py::module& pyopensn)
63✔
257
{
258
  py::module xs = pyopensn.def_submodule("xs", "Cross section module.");
63✔
259
  WrapMultiGroupXS(xs);
63✔
260
}
63✔
261

262
} // namespace opensn
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