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

Open-Sn / opensn / 18300593117

06 Oct 2025 10:47PM UTC coverage: 74.862% (-0.2%) from 75.031%
18300593117

push

github

web-flow
Merge pull request #759 from wdhawkins/performance

Sweep performance optimizations

294 of 302 new or added lines in 15 files covered. (97.35%)

334 existing lines in 80 files now uncovered.

17788 of 23761 relevant lines covered (74.86%)

61852783.95 hits per line

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

87.76
/python/lib/aquad.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/math/quadratures/angular/angular_quadrature.h"
6
#include "framework/math/quadratures/angular/curvilinear_product_quadrature.h"
7
#include "framework/math/quadratures/angular/product_quadrature.h"
8
#include "framework/math/quadratures/angular/sldfe_sq_quadrature.h"
9
#include "framework/math/quadratures/angular/lebedev_quadrature.h"
10
#include <pybind11/stl.h>
11
#include <memory>
12
#include <stdexcept>
13

14
namespace opensn
15
{
16

17
// Wrap quadrature point
18
void
19
WrapQuadraturePointPhiTheta(py::module& aquad)
416✔
20
{
21
  // clang-format off
22
  py::class_<QuadraturePointPhiTheta> quad_pt_phi_theta(aquad,
23
    "QuadraturePointPhiTheta",
24
    R"(
25
    Angular quadrature point.
26

27
    Wrapper of :cpp:class:`opensn::QuadraturePointPhiTheta`.
28
    )"
29
  );
416✔
30
  quad_pt_phi_theta.def_readonly(
416✔
31
    "phi",
32
    &QuadraturePointPhiTheta::phi,
33
    "Azimuthal angle."
34
  );
35
  quad_pt_phi_theta.def_readonly(
416✔
36
    "theta",
37
    &QuadraturePointPhiTheta::theta,
38
    "Polar angle."
39
  );
40
  quad_pt_phi_theta.def(
416✔
41
    "__repr__",
UNCOV
42
    [](QuadraturePointPhiTheta& self)
×
43
    {
44
      std::ostringstream os;
×
45
      os << "QuadraturePointPhiTheta(phi=" << self.phi << ", theta=" << self.theta << ")";
×
46
      return os.str();
×
47
    }
×
48
  );
49
  // clang-format on
50
}
416✔
51

52
// Wrap angular quadrature
53
void
54
WrapQuadrature(py::module& aquad)
416✔
55
{
56
  // clang-format off
57
  // angular quadrature
58
  auto angular_quadrature = py::class_<AngularQuadrature, std::shared_ptr<AngularQuadrature>>(
59
    aquad,
60
    "AngularQuadrature",
61
    R"(
62
    Angular quadrature.
63

64
    Wrapper of :cpp:class:`opensn::AngularQuadrature`.
65
    )"
66
  );
416✔
67
  angular_quadrature.def_readonly(
416✔
68
    "abscissae",
69
    &AngularQuadrature::abscissae,
70
    "Vector of polar and azimuthal angles."
71
  );
72
  angular_quadrature.def_readonly(
416✔
73
    "weights",
74
    &AngularQuadrature::weights,
75
    "Quadrature weights."
76
  );
77
  angular_quadrature.def_readonly(
416✔
78
    "omegas",
79
    &AngularQuadrature::omegas,
80
    "Vector of direction vectors."
81
  );
82
  // clang-format on
83
}
416✔
84

85
// Wrap product qudrature
86
void
87
WrapProductQuadrature(py::module& aquad)
416✔
88
{
89
  // clang-format off
90
  // product quadrature
91
  auto product_quadrature = py::class_<ProductQuadrature, std::shared_ptr<ProductQuadrature>,
92
                                       AngularQuadrature>(
93
    aquad,
94
    "ProductQuadrature",
95
    R"(
96
    Product quadrature.
97

98
    Wrapper of :cpp:class:`opensn::ProductQuadrature`.
99
    )"
100
  );
416✔
101

102
  // Gauss-Legendre 1D slab product quadrature
103
  auto angular_quadrature_gl_prod_1d_slab = py::class_<GLProductQuadrature1DSlab,
104
                                                       std::shared_ptr<GLProductQuadrature1DSlab>,
105
                                                       ProductQuadrature>(
106
    aquad,
107
    "GLProductQuadrature1DSlab",
108
    R"(
109
    Gauss-Legendre quadrature for 1D, slab geometry.
110

111
    Wrapper of :cpp:class:`opensn::GLProductQuadrature1DSlab`.
112
    )"
113
  );
416✔
114
  angular_quadrature_gl_prod_1d_slab.def(
416✔
115
    py::init(
416✔
UNCOV
116
      [](py::kwargs& params)
×
117
      {
118
        static const std::vector<std::string> required_keys = {"n_polar", "scattering_order"};
129✔
119
        static const std::vector<std::pair<std::string, py::object>> optional_keys = {{"verbose", py::bool_(false)}};
172✔
120
        return construct_from_kwargs<GLProductQuadrature1DSlab, int, int, bool>(params, required_keys, optional_keys);
43✔
121
      }
43✔
122
    ),
123
    R"(
124
    Construct a Gauss-Legendre product quadrature for 1D, slab geometry.
125

126
    Parameters
127
    ----------
128
    n_polar: int
129
        Number of polar angles.
130
    scattering_order: int
131
        Maximum scattering order supported by the angular quadrature.
132
    verbose: bool, default=False
133
        Verbosity.
134
    )"
135
  );
136

137
  // Gauss-Legendre-Chebyshev 2D XY product quadrature
138
  auto angular_quadrature_glc_prod_2d_xy = py::class_<GLCProductQuadrature2DXY,
139
                                                      std::shared_ptr<GLCProductQuadrature2DXY>,
140
                                                      ProductQuadrature>(
141
    aquad,
142
    "GLCProductQuadrature2DXY",
143
    R"(
144
    Gauss-Legendre-Chebyshev quadrature for 2D, XY geometry.
145

146
    Wrapper of :cpp:class:`opensn::GLCProductQuadrature2DXY`.
147
    )"
148
  );
416✔
149
  angular_quadrature_glc_prod_2d_xy.def(
416✔
150
    py::init(
416✔
UNCOV
151
      [](py::kwargs& params)
×
152
      {
153
        static const std::vector<std::string> required_keys = {"n_polar", "n_azimuthal", "scattering_order"};
360✔
154
        static const std::vector<std::pair<std::string, py::object>> optional_keys = {{"verbose", py::bool_(false)}};
480✔
155
        return construct_from_kwargs<GLCProductQuadrature2DXY, int, int, int, bool>(params, required_keys, optional_keys);
120✔
156
      }
120✔
157
    ),
158
    R"(
159
    Construct a Gauss-Legendre-Chebyshev product quadrature for 2D, XY geometry.
160

161
    Parameters
162
    ----------
163
    n_polar: int
164
        Number of polar angles.
165
    n_azimuthal: int
166
        Number of azimuthal angles.
167
    scattering_order: int
168
        Maximum scattering order supported by the angular quadrature.
169
    verbose: bool, default=False
170
        Verbosity.
171
    )"
172
  );
173

174
  // Gauss-Legendre-Chebyshev 3D XYZ product quadrature
175
  auto angular_quadrature_glc_prod_3d_xyz = py::class_<GLCProductQuadrature3DXYZ,
176
                                                       std::shared_ptr<GLCProductQuadrature3DXYZ>,
177
                                                       ProductQuadrature>(
178
    aquad,
179
    "GLCProductQuadrature3DXYZ",
180
    R"(
181
    Gauss-Legendre-Chebyshev quadrature for 3D, XYZ geometry.
182

183
    Wrapper of :cpp:class:`opensn::GLCProductQuadrature3DXYZ`.
184
    )"
185
  );
416✔
186
  angular_quadrature_glc_prod_3d_xyz.def(
416✔
187
    py::init(
416✔
UNCOV
188
      [](py::kwargs& params)
×
189
      {
190
        static const std::vector<std::string> required_keys = {"n_polar", "n_azimuthal", "scattering_order"};
360✔
191
        static const std::vector<std::pair<std::string, py::object>> optional_keys = {{"verbose", py::bool_(false)}};
480✔
192
        return construct_from_kwargs<GLCProductQuadrature3DXYZ, int, int, int, bool>(params, required_keys, optional_keys);
120✔
193
      }
120✔
194
    ),
195
    R"(
196
    Construct a Gauss-Legendre-Chebyshev product quadrature for 3D, XYZ geometry.
197

198
    Parameters
199
    ----------
200
    n_polar: int
201
        Number of polar angles.
202
    n_azimuthal: int
203
        Number of azimuthal angles.
204
    scattering_order: int
205
        Maximum scattering order supported by the angular quadrature.
206
    verbose: bool, default=False
207
        Verbosity.
208
    )"
209
  );
210
  // clang-format on
211
}
416✔
212

213
// Wrap curvilinear product quadrature
214
void
215
WrapCurvilinearProductQuadrature(py::module& aquad)
416✔
216
{
217
  // clang-format off
218
  // curvilinear product quadrature
219
  auto curvilinear_product_quadrature = py::class_<CurvilinearProductQuadrature,
220
                                                   std::shared_ptr<CurvilinearProductQuadrature>,
221
                                                   ProductQuadrature>(
222
    aquad,
223
    "CurvilinearProductQuadrature",
224
    R"(
225
    Curvilinear product quadrature.
226

227
    Wrapper of :cpp:class:`opensn::CurvilinearProductQuadrature`.
228
    )"
229
  );
416✔
230

231
  // Gauss-Legendre-Chebyshev 2D RZ curvilinear product quadrature
232
  auto curvilinear_quadrature_glc_2d_rz = py::class_<GLCProductQuadrature2DRZ,
233
                                                     std::shared_ptr<GLCProductQuadrature2DRZ>,
234
                                                     CurvilinearProductQuadrature>(
235
    aquad,
236
    "GLCProductQuadrature2DRZ",
237
    R"(
238
    Gauss-Legendre-Chebyshev product quadrature for 2D, RZ geometry.
239

240
    Wrapper of :cpp:class:`opensn::GLCProductQuadrature2DRZ`.
241
    )"
242
  );
416✔
243
  curvilinear_quadrature_glc_2d_rz.def(
416✔
244
    py::init(
416✔
UNCOV
245
      [](py::kwargs& params)
×
246
      {
247
        static const std::vector<std::string> required_keys = {"n_polar", "n_azimuthal", "scattering_order"};
24✔
248
        static const std::vector<std::pair<std::string, py::object>> optional_keys = {{"verbose", py::bool_(false)}};
32✔
249
        return construct_from_kwargs<GLCProductQuadrature2DRZ, int, int, int, bool>(params, required_keys, optional_keys);
8✔
250
      }
8✔
251
    ),
252
    R"(
253
    Construct a Gauss-Legendre Chebyshev product quadrature for 2D, RZ geometry.
254

255
    Parameters
256
    ----------
257
    n_polar: int
258
        Number of polar angles.
259
    n_azimuthal: int
260
        Number of azimuthal angles.
261
    scattering_order: int
262
        Maximum scattering order supported by the angular quadrature.
263
    verbose: bool, default=False
264
        Verbosity.
265
    )"
266
  );
267
  // clang-format on
268
}
416✔
269

270
// Wrap SLDFES quadrature
271
void
272
WrapSLDFESQuadrature(py::module& aquad)
416✔
273
{
274
  // clang-format off
275
  // simplified LDFES quadrature
276
  auto simplified_ldfes_quadrature = py::class_<SimplifiedLDFESQ::Quadrature,
277
                                                std::shared_ptr<SimplifiedLDFESQ::Quadrature>,
278
                                                AngularQuadrature>(
279
    aquad,
280
    "SLDFESQuadrature",
281
    R"(
282
    Piecewise-linear finite element quadrature using quadrilaterals.
283

284
    Wrapper of :cpp:class:`opensn::SimplifiedLDFESQ::Quadrature`.
285
    )"
286
  );
416✔
287
  simplified_ldfes_quadrature.def(
416✔
288
    py::init(
416✔
UNCOV
289
      [](py::kwargs& params)
×
290
      {
291
        static const std::vector<std::string> required_keys = {"level", "scattering_order"};
8✔
292
        auto [level, scattering_order] = extract_args_tuple<int, int>(params, required_keys);
4✔
293
        std::shared_ptr<SimplifiedLDFESQ::Quadrature> quad(new SimplifiedLDFESQ::Quadrature(scattering_order));
4✔
294
        quad->GenerateInitialRefinement(level);
4✔
295
        return quad;
4✔
296
      }
×
297
    ),
298
    R"(
299
    Generates uniform spherical quadrilaterals from the subdivision of an inscribed cube.
300

301
    Parameters
302
    ----------
303
    level: int
304
        Number of subdivisions of the inscribed cube.
305
    scattering_order: int
306
        Maximum scattering order supported by the angular quadrature.
307
    )"
308
  );
309
  simplified_ldfes_quadrature.def(
416✔
310
    "LocallyRefine",
311
    &SimplifiedLDFESQ::Quadrature::LocallyRefine,
416✔
312
    R"(
313
    Locally refines the cells.
314

315
    Parameters
316
    ----------
317
    ref_dir: pyopensn.math.Vector3
318
        Reference direction :math:`\vec{r}`.
319
    cone_size: float
320
        Cone size (in radians) :math:`\theta`.
321
    dir_as_plane_normal: bool, default=False
322
        If true, interpret SQ-splitting as when :math:`|\omega \cdot \vec{r}| < \sin(\theta)`.
323
        Otherwise, SQs will be split if :math:`\omega \cdot \vec{r} > \cos(\theta)`.
324
    )",
325
    py::arg("ref_dir"),
416✔
326
    py::arg("cone_size"),
416✔
327
    py::arg("dir_as_plane_normal") = false
832✔
328
  );
329
  simplified_ldfes_quadrature.def(
416✔
330
    "PrintQuadratureToFile",
331
    &SimplifiedLDFESQ::Quadrature::PrintQuadratureToFile,
416✔
332
    R"(
333
    Prints the quadrature to file.
334

335
    Parameters
336
    ----------
337
    file_base: str
338
        File base name.
339
    )",
340
    py::arg("file_base")
416✔
341
  );
342
  // clang-format on
343
}
416✔
344

345
// Wrap Lebedev quadrature
346
void
347
WrapLebedevQuadrature(py::module& aquad)
416✔
348
{
349
  // clang-format off
350
  auto lebedev_quadrature = py::class_<LebedevQuadrature,
351
                                       std::shared_ptr<LebedevQuadrature>,
352
                                       AngularQuadrature>(
353
    aquad,
354
    "LebedevQuadrature",
355
    R"(
356
    Lebedev quadrature for spherical integration.
357
    
358
    This quadrature provides high-order accuracy for spherical integration with
359
    symmetric distribution of points on the sphere.
360

361
    Wrapper of :cpp:class:`opensn::LebedevQuadrature`.
362
    )"
363
  );
416✔
364
  
365
  lebedev_quadrature.def(
416✔
366
    py::init(
416✔
UNCOV
367
      [](py::kwargs& params)
×
368
      {
369
        static const std::vector<std::string> required_keys = {"order"};
16✔
370
        static const std::vector<std::pair<std::string, py::object>> optional_keys = {{"verbose", py::bool_(false)}};
21✔
371
        return construct_from_kwargs<LebedevQuadrature, int, bool>(params, required_keys, optional_keys);
6✔
372
      }
5✔
373
    ),
374
    R"(
375
    Creates a Lebedev quadrature of the specified order.
376

377
    Parameters
378
    ----------
379
    order: int
380
        The order of the quadrature.
381
    verbose: bool, default=False
382
        Whether to print verbose output during initialization.
383
    )"
384
  );
385
  
386
  lebedev_quadrature.def(
416✔
387
    "LoadFromOrder",
388
    &LebedevQuadrature::LoadFromOrder,
416✔
389
    R"(
390
    Loads quadrature points from an Order.
391

392
    Parameters
393
    ----------
394
    order: int
395
        The order of the quadrature.
396
    verbose: bool, default=False
397
        Whether to print verbose output during loading.
398
    )",
399
    py::arg("order"),
416✔
400
    py::arg("verbose") = false
832✔
401
  );
402
  // clang-format on
403
}
416✔
404

405
// Wrap the angular quadrature components of OpenSn
406
void
407
py_aquad(py::module& pyopensn)
62✔
408
{
409
  py::module aquad = pyopensn.def_submodule("aquad", "Angular quadrature module.");
62✔
410
  WrapQuadraturePointPhiTheta(aquad);
62✔
411
  WrapQuadrature(aquad);
62✔
412
  WrapProductQuadrature(aquad);
62✔
413
  WrapCurvilinearProductQuadrature(aquad);
62✔
414
  WrapSLDFESQuadrature(aquad);
62✔
415
  WrapLebedevQuadrature(aquad);
62✔
416
}
62✔
417

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