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

Open-Sn / opensn / 24065262673

06 Apr 2026 04:56PM UTC coverage: 75.039%. Remained the same
24065262673

push

github

web-flow
Merge pull request #1014 from wdhawkins/ff_fixes

Numerous bug fixes for field function and interpolation routines

48 of 71 new or added lines in 7 files covered. (67.61%)

152 existing lines in 9 files now uncovered.

20984 of 27964 relevant lines covered (75.04%)

66658029.72 hits per line

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

97.53
/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/materials/multi_group_xs/multi_group_xs.h"
6
#include "framework/materials/multi_group_xs/xsfile.h"
7
#include <pybind11/stl.h>
8
#include <memory>
9
#include <string>
10
#include <vector>
11

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

14
namespace opensn
15
{
16

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

29
    Wrapper of :cpp:class:`opensn::MultiGroupXS`.
30

31
    The Python API currently has two types of methods:
32

33
    - Creation/loading methods such as ``CreateSimpleOneGroup``,
34
      ``LoadFromOpenSn``, and ``LoadFromOpenMC`` populate an existing object.
35
    - ``Scale`` mutates the current object.
36
    - ``Combine`` returns a new cross-section object and does not mutate inputs.
37
    )"
38
  );
661✔
39
  multigroup_xs.def(
1,322✔
40
    py::init(
661✔
41
      []()
959✔
42
      {
43
        return std::make_shared<MultiGroupXS>();
959✔
44
      }),
45
    "Create an empty multi-group cross section."
46
  );
47
  multigroup_xs.def(
1,322✔
48
    "CreateSimpleOneGroup",
49
    [](MultiGroupXS& self, double sigma_t, double c, double velocity) {
848✔
50
      self = MultiGroupXS::CreateSimpleOneGroup(sigma_t, c, velocity);
187✔
51
    },
187✔
52
    R"(
53
    Populate this object with a one-group cross section.
54

55
    Parameters
56
    ----------
57
    sigma_t: float
58
        Total cross section.
59
    c: float
60
        Scattering ratio.
61
    velocity: float, optional
62
        Group velocity. If provided and positive, inverse velocity
63
        is populated with 1.0/velocity.
64

65
    Notes
66
    -----
67
    This method mutates ``self`` by replacing its current contents.
68
    )",
69
    py::arg("sigma_t"),
1,322✔
70
    py::arg("c"),
661✔
71
    py::arg("velocity") = 0.0
661✔
72
  );
73
  multigroup_xs.def(
661✔
74
    "LoadFromOpenSn",
75
    [](MultiGroupXS& self, const std::string& file_name)
1,349✔
76
    {
77
      self = MultiGroupXS::LoadFromOpenSn(file_name);
688✔
78
    },
688✔
79
    py::arg("file_name"),
661✔
80
    R"(
81
    Load multi-group cross sections from an OpenSn cross section input file
82
    into this object.
83

84
    Format is as follows (for transfers, gprime denotes the departing group and g is the arrival
85
    group).
86

87
    .. code-block:: none
88

89
       # Add comment lines, as needed
90
       NUM_GROUPS ng
91
       NUM_MOMENTS nmom
92

93
       SIGMA_T_BEGIN
94
       0 value
95
       .
96
       .
97
       ng-1 value
98
       SIGMA_T_END
99

100
       SIGMA_A_BEGIN
101
       0 value
102
       .
103
       .
104
       ng-1 value
105
       SIGMA_A_END
106

107
       TRANSFER_MOMENTS_BEGIN
108
       M_GFROM_GTO_VAL 0 0 0 value
109
       .
110
       M_GFROM_GTO_VAL moment gfrom gto value
111
       .
112
       M_GFROM_GTO_VAL nmom-1 ng-1 ng-1 value
113
       TRANSFER_MOMENTS_END
114

115
    Notes
116
    -----
117
    This method mutates ``self`` by replacing its current contents.
118
    )"
119
  );
120
  multigroup_xs.def_static(
661✔
121
    "Combine",
122
    &MultiGroupXS::Combine,
1,322✔
123
    R"(
124
    Return a new combined cross-section.
125

126
    Parameters
127
    ----------
128

129
    combinations: List[Tuple[pyopensn.xs.MultiGroupXS, float]]
130
        List of ``(cross_section, density)`` pairs.
131
        The density values are linear weights used to combine raw cross sections.
132

133
    Returns
134
    -------
135
    pyopensn.xs.MultiGroupXS
136
        A new combined cross-section object. The input cross sections are not
137
        modified.
138

139
    Notes
140
    -----
141
    Let :math:`d_i` be the supplied density for cross section :math:`i`.
142

143
    - Raw XS terms are density-weighted sums:
144
      :math:`\sigma = \sum_i d_i \sigma_i`
145
      (e.g. total, absorption, fission, transfer, production).
146
    - Named custom 1D XS are preserved and combined with the same density weighting.
147
    - Fission spectra and precursor yields are weighted by fissile density
148
      fraction so their sums remain normalized.
149
    - All inputs must have the same number of groups.
150
    - If inverse velocity is present, all inputs must have identical values.
151

152
    Examples
153
    --------
154

155
    >>> xs_1 = MultiGroupXS()
156
    >>> xs_1.CreateSimpleOneGroup(sigma_t=1, c=0.5)
157
    >>> xs_2 = MultiGroupXS()
158
    >>> xs_2.CreateSimpleOneGroup(sigma_t=2, c=1./3.)
159
    >>> combo = [
160
    ...     ( xs_1, 0.5 ),
161
    ...     ( xs_2, 3.0 )
162
    ... ]
163
    >>> xs_combined = MultiGroupXS.Combine(combo)
164
    )",
165
    py::arg("combinations")
661✔
166
  );
167
  multigroup_xs.def(
1,322✔
168
    "LoadFromOpenMC",
169
    [](MultiGroupXS& self,
745✔
170
       const std::string& file_name,
171
       const std::string& dataset_name,
172
       double temperature,
173
       const std::vector<std::string>& extra_xs_names)
174
    {
175
      self = MultiGroupXS::LoadFromOpenMC(file_name, dataset_name, temperature, extra_xs_names);
84✔
176
    },
84✔
177
    R"(
178
    Load multi-group cross sections from an OpenMC cross-section file into this
179
    object.
180

181
    Notes
182
    -----
183
    This method mutates ``self`` by replacing its current contents.
184
    )",
185
    py::arg("file_name"),
1,322✔
186
    py::arg("dataset_name"),
1,322✔
187
    py::arg("temperature"),
661✔
188
    py::arg("extra_xs_names") = std::vector<std::string>()
1,322✔
189
  );
190
  multigroup_xs.def(
661✔
191
    "Scale",
192
    &MultiGroupXS::Scale,
1,322✔
193
    R"(
194
    Scale the cross sections in-place.
195

196
    Notes
197
    -----
198
    Scaling does not compound. Each call scales from the original baseline data.
199
    Named custom 1D XS are scaled along with the standard 1D cross-section data.
200
    )",
201
    py::arg("factor")
661✔
202
  );
203
  multigroup_xs.def_property_readonly(
661✔
204
    "num_groups",
205
    &MultiGroupXS::GetNumGroups,
661✔
206
    "Get number of energy groups."
207
  );
208
  multigroup_xs.def_property_readonly(
661✔
209
    "scattering_order",
210
    &MultiGroupXS::GetScatteringOrder,
661✔
211
    "Get Legendre scattering order."
212
  );
213
  multigroup_xs.def_property_readonly(
661✔
214
    "num_precursors",
215
    &MultiGroupXS::GetNumPrecursors,
661✔
216
    "Get number of precursors."
217
  );
218
  multigroup_xs.def_property_readonly(
661✔
219
    "is_fissionable",
220
    &MultiGroupXS::IsFissionable,
661✔
221
    "Check if the material is fissile."
222
  );
223
  multigroup_xs.def(
661✔
224
    "GetScaleFactor",
225
    &MultiGroupXS::GetScaleFactor,
661✔
226
    "Get the scaling factor."
227
  );
228
  multigroup_xs.def_property_readonly(
661✔
229
    "sigma_t",
230
    XS_GETTER(GetSigmaTotal),
19✔
231
    "Get total cross section.",
232
    py::keep_alive<0, 1>()
661✔
233
  );
234
  multigroup_xs.def_property_readonly(
661✔
235
    "sigma_a",
236
    XS_GETTER(GetSigmaAbsorption),
2,512✔
237
    "Get absorption cross section.",
238
    py::keep_alive<0, 1>()
661✔
239
  );
240
  multigroup_xs.def_property_readonly(
661✔
241
    "sigma_f",
242
    XS_GETTER(GetSigmaFission),
4✔
243
    "Get fission cross section.",
244
    py::keep_alive<0, 1>()
661✔
245
  );
246
  multigroup_xs.def_property_readonly(
661✔
247
    "chi",
248
    XS_GETTER(GetChi),
2✔
249
    "Get neutron fission spectrum.",
250
    py::keep_alive<0, 1>()
661✔
251
  );
252
  multigroup_xs.def_property_readonly(
661✔
253
    "nu_sigma_f",
254
    XS_GETTER(GetNuSigmaF),
28✔
255
    "Get neutron production due to fission.",
256
    py::keep_alive<0, 1>()
661✔
257
  );
258
  multigroup_xs.def_property_readonly(
661✔
259
    "nu_prompt_sigma_f",
UNCOV
260
    XS_GETTER(GetNuPromptSigmaF),
×
261
    "Get prompt neutron production due to fission.",
262
    py::keep_alive<0, 1>()
661✔
263
  );
264
  multigroup_xs.def_property_readonly(
661✔
265
    "nu_delayed_sigma_f",
UNCOV
266
    XS_GETTER(GetNuDelayedSigmaF),
×
267
    "Get delayed neutron production due to fission.",
268
    py::keep_alive<0, 1>()
661✔
269
  );
270
  multigroup_xs.def(
661✔
271
    "has_custom_xs",
272
    &MultiGroupXS::HasCustomXS,
1,322✔
273
    "Check if a custom XS is available.",
274
    py::arg("name")
661✔
275
  );
276
  multigroup_xs.def(
661✔
277
    "get_custom_xs",
278
    [](MultiGroupXS& self, const std::string& name)
664✔
279
    { return convert_vector(self.GetCustomXS(name)); },
3✔
280
    "Get a custom XS vector.",
281
    py::arg("name")
661✔
282
  );
283
  multigroup_xs.def(
661✔
284
    "custom_xs_names",
285
    &MultiGroupXS::GetCustomXSNames,
661✔
286
    "Get a list of custom XS entries."
287
  );
288
  multigroup_xs.def_property_readonly(
661✔
289
    "inv_velocity",
290
    XS_GETTER(GetInverseVelocity),
25✔
291
    "Get inverse velocity.",
292
    py::keep_alive<0, 1>()
661✔
293
  );
294
  // clang-format on
295
}
661✔
296

297
// Wrap the cross section components of OpenSn
298
void
299
py_xs(py::module& pyopensn)
72✔
300
{
301
  py::module xs = pyopensn.def_submodule("xs", "Cross section module.");
72✔
302
  WrapMultiGroupXS(xs);
72✔
303
}
72✔
304

305
} // 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