• 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

65.82
/python/lib/math.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/functions/function.h"
6
#include "framework/math/quadratures/angular/legendre_poly/legendrepoly.h"
7
#include "framework/data_types/vector3.h"
8
#include <pybind11/functional.h>
9
#include <pybind11/stl.h>
10
#include <memory>
11
#include <sstream>
12
#include <stdexcept>
13

14
namespace opensn
15
{
16

17
// Wrap spherical harmonics
18
void
19
WrapYlm(py::module& math)
416✔
20
{
21
  // clang-format off
22
  math.def(
416✔
23
    "Ylm",
24
    &Ylm,
416✔
25
    R"(
26
    Compute the tesseral spherical harmonics.
27

28
    Parameters
29
    ----------
30
    l: int
31
        Degree of the associated Legendre polynomial.
32
    m: int
33
        Order of the associated Legendre polynomial.
34
    theta: float
35
        Polar angle of the evaluation point.
36
    varphi: float
37
        Azimuthal angle of the evaluation point.
38
    )",
39
    py::arg("l"),
416✔
40
    py::arg("m"),
416✔
41
    py::arg("theta"),
416✔
42
    py::arg("varphi")
416✔
43
  );
44
  // clang-format on
45
}
416✔
46

47
// Wrap Vector3
48
void
49
WrapVector3(py::module& math)
416✔
50
{
51
  // clang-format off
52
  auto vector3 = py::class_<Vector3, std::shared_ptr<Vector3>>(
53
    math,
54
    "Vector3",
55
    R"(
56
    General 3-element vector structure.
57

58
    Wrapper of :cpp:class:`opensn::Vector3`.
59

60
    Examples
61
    --------
62
    >>> a = Vector3(2.0, 3.0, 6.0)
63
    >>> b = Vector3(2.0, 1.0, -1.0)
64
    >>> a + b
65
    Vector3(4, 4, 5)
66
    >>> a - b
67
    Vector3(0, 2, 7)
68
    >>> 2 * a
69
    Vector3(4, 6, 12)
70
    >>> a / 2
71
    Vector3(1, 1.5, 3)
72
    >>> a *= 2
73
    >>> a
74
    Vector3(4, 6, 12)
75
    >>> a /= 2
76
    >>> a
77
    Vector3(2, 3, 6)
78
    >>> a.Norm()
79
    7.0
80
    >>> a @ b  # scalar product
81
    1.0
82
    )"
83
  );
416✔
84
  vector3.def(
416✔
85
    py::init(
416✔
UNCOV
86
      [](double x, double y, double z)
×
87
      {
88
        return std::make_shared<Vector3>(x, y, z);
1,155✔
89
      }
90
    ),
91
    R"(
92
    Construct a 3-element vector object.
93

94
    Parameters
95
    ----------
96
    x: float, default=0.0
97
        X-coordinate.
98
    y: float, default=0.0
99
        Y-coordinate.
100
    z: float, default=0.0
101
        Z-coordinate.
102
    )",
103
    py::arg("x") = 0.0,
832✔
104
    py::arg("y") = 0.0,
832✔
105
    py::arg("z") = 0.0
832✔
106
  );
107
  vector3.def_readwrite(
416✔
108
    "x",
109
    &Vector3::x,
110
    "X-coordinate."
111
  );
112
  vector3.def_readwrite(
416✔
113
    "y",
114
    &Vector3::y,
115
    "Y-coordinate."
116
  );
117
  vector3.def_readwrite(
416✔
118
    "z",
119
    &Vector3::z,
120
    "Z-coordinate."
121
  );
122
  vector3.def(
416✔
123
    "__add__",
UNCOV
124
    [](Vector3& self, Vector3& other)
×
125
    {
126
      return self + other;
×
127
    }
128
  );
129
  vector3.def(
416✔
130
    "__iadd__",
UNCOV
131
    [](Vector3& self, Vector3& other)
×
132
    {
133
      return self += other;
×
134
    }
135
  );
136
  vector3.def(
416✔
137
    "__sub__",
UNCOV
138
    [](Vector3& self, Vector3& other)
×
139
    {
140
      return self - other;
×
141
    }
142
  );
143
  vector3.def(
416✔
144
    "__isub__",
UNCOV
145
    [](Vector3& self, Vector3& other)
×
146
    {
147
      return self -= other;
×
148
    }
149
  );
150
  vector3.def(
416✔
151
    "__mul__",
UNCOV
152
    [](Vector3& self, double value)
×
153
    {
154
      return self * value;
×
155
    }
156
  );
157
  vector3.def(
416✔
158
    "__rmul__",
UNCOV
159
    [](Vector3& self, double value)
×
160
    {
161
      return self * value;
×
162
    }
163
  );
164
  vector3.def(
416✔
165
    "__imul__",
UNCOV
166
    [](Vector3& self, double value)
×
167
    {
168
      return self *= value;
×
169
    }
170
  );
171
  vector3.def(
416✔
172
    "__truediv__",
UNCOV
173
    [](Vector3& self, double value)
×
174
    {
175
      return self / value;
×
176
    }
177
  );
178
  vector3.def(
416✔
179
    "__itruediv__",
UNCOV
180
    [](Vector3& self, double value)
×
181
    {
182
      return self /= value;
×
183
    }
184
  );
185
  vector3.def(
416✔
186
    "__matmul__",
UNCOV
187
    [](Vector3& self, Vector3& other)
×
188
    {
189
      return self.Dot(other);
×
190
    }
191
  );
192
  vector3.def(
416✔
193
    "Norm",
UNCOV
194
    [](Vector3& self)
×
195
    {
196
      return self.Norm();
×
197
    }
198
  );
199
  vector3.def(
416✔
200
    "__repr__",
UNCOV
201
    [](Vector3& self)
×
202
    {
203
      std::ostringstream os;
416✔
204
      os << "Vector3(" << self.x << ", " << self.y << ", " << self.z << ")";
416✔
205
      return os.str();
832✔
206
    }
416✔
207
  );
208
  // clang-format on
209
}
416✔
210

211
// Wrap functors (temporary solution until the Lua interface is eradicated)
212
void
213
WrapFunctors(py::module& math)
416✔
214
{
215
  // clang-format off
216
  // vector spatial function
217
  auto vector_spatial_function = py::class_<VectorSpatialFunction, std::shared_ptr<VectorSpatialFunction>>(
218
    math,
219
    "VectorSpatialFunction",
220
    R"(
221
    Vector spatial function.
222

223
    Functions that accept a point and a number of groups as input and return a vector (per group).
224

225
    Wrapper of :cpp:class:`opensn::VectorSpatialFunction`.
226

227
    Examples
228
    --------
229
    >>> # Create from a Python function
230
    >>> def foo(point, n_groups):
231
    ...     return [point.x * point.y] * n_groups
232
    >>> f = VectorSpatialFunction(foo)
233
    >>> 
234
    >>> # Create from lambda
235
    >>> g = VectorSpatialFunction(lambda p, n : [p.x + p.y + p.z] * n)
236
    >>> 
237
    >>> # Evaluate
238
    >>> f(Vector3(1.0, 2.0, 3.0), 2)
239
    [2.0, 2.0]
240
    >>> g(Vector3(1.0, 2.0, 3.0), 3)
241
    [6.0, 6.0, 6.0]
242
    )"
243
  );
416✔
244
  vector_spatial_function.def(
416✔
245
    py::init(
416✔
UNCOV
246
      [](const std::function<std::vector<double>(const Vector3&, int)>& func)
×
247
      {
248
        return std::make_shared<VectorSpatialFunction>(func);
16✔
249
      }
250
    ),
251
    R"(
252
    Construct a vector spatial function from associated Python function or lambda.
253

254
    Parameters
255
    ----------
256
    func: Callable[[pyopensn.math.Vector3, int], List[float]]
257
        Referenced vector spatial function.
258
    )",
259
    py::arg("func")
416✔
260
  );
261
  vector_spatial_function.def(
416✔
262
    "__call__",
UNCOV
263
    [](VectorSpatialFunction& self, const Vector3& xyz, int num_groups)
×
264
    {
265
      return self(xyz, num_groups);
×
266
    },
267
    R"(
268
    Evaluate the associated function.
269

270
    Parameters
271
    ----------
272
    xyz: pyopensn.math.Vector3
273
        The xyz coordinates of the point where the function is called.
274
    num_groups: int
275
        The number of groups.
276
    )",
277
    py::arg("xyz"),
416✔
278
    py::arg("num_groups")
416✔
279
  );
280
  // clang-format on
281
}
416✔
282

283
// Wrap the angular quadrature components of OpenSn
284
void
285
py_math(py::module& pyopensn)
62✔
286
{
287
  py::module math = pyopensn.def_submodule("math", "Math module.");
62✔
288
  WrapYlm(math);
62✔
289
  WrapVector3(math);
62✔
290
  WrapFunctors(math);
62✔
291
}
62✔
292

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