• 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

85.12
/python/lib/mesh.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/graphs/graph_partitioner.h"
7
#include "framework/graphs/kba_graph_partitioner.h"
8
#include "framework/graphs/linear_graph_partitioner.h"
9
#include "framework/graphs/petsc_graph_partitioner.h"
10
#include "framework/mesh/io/mesh_io.h"
11
#include "framework/mesh/logical_volume/logical_volume.h"
12
#include "framework/mesh/mesh_continuum/mesh_continuum.h"
13
#include "framework/mesh/mesh_generator/mesh_generator.h"
14
#include "framework/mesh/mesh_generator/extruder_mesh_generator.h"
15
#include "framework/mesh/mesh_generator/orthogonal_mesh_generator.h"
16
#include "framework/mesh/mesh_generator/from_file_mesh_generator.h"
17
#include "framework/mesh/mesh_generator/split_file_mesh_generator.h"
18
#include "framework/mesh/mesh_generator/distributed_mesh_generator.h"
19
#include "framework/mesh/surface_mesh/surface_mesh.h"
20
#include "framework/utils/timer.h"
21
#include <pybind11/functional.h>
22
#include <pybind11/stl.h>
23
#include <cstdint>
24
#include <functional>
25
#include <memory>
26
#include <stdexcept>
27
#include <string>
28
#include <vector>
29

30
namespace opensn
31
{
32

33
// Wrap mesh continuum
34
void
35
WrapMesh(py::module& mesh)
416✔
36
{
37
  // clang-format off
38
  // mesh continuum
39
  auto mesh_continuum = py::class_<MeshContinuum, std::shared_ptr<MeshContinuum>>(
40
    mesh,
41
    "MeshContinuum",
42
    R"(
43
    Mesh continuum.
44

45
    Wrapper of :cpp:class:`opensn::MeshContinuum`.
46
    )"
47
  );
416✔
48
  mesh_continuum.def_property(
416✔
49
    "dimension",
UNCOV
50
    &MeshContinuum::GetDimension,
×
51
    &MeshContinuum::SetDimension,
416✔
52
    "Number of dimensions of the mesh."
53
  );
54
  mesh_continuum.def(
416✔
55
    "SetUniformBlockID",
56
    &MeshContinuum::SetUniformBlockID,
416✔
57
    "Set block ID's for all cells to the specified block ID.",
58
    py::arg("mat_id")
416✔
59
  );
60
  mesh_continuum.def(
416✔
61
    "SetBlockIDFromLogicalVolume",
62
    &MeshContinuum::SetBlockIDFromLogicalVolume,
416✔
63
    R"(
64
    Set block ID's using a logical volume.
65

66
    Parameters
67
    ----------
68
    log_vol: pyopensn.logvol.LogicalVolume
69
        Logical volume that determines which mesh cells will be selected.
70
    block_id: int
71
        Block ID that will be assigned.
72
    inside: bool
73
        If true, the selected mesh cells are the ones whose centroids are inside the logival volume.
74
        Otherwise, the selected meshes are the ones whose centroids are outside of the logical
75
        volume.
76
    )",
77
    py::arg("log_vol"),
416✔
78
    py::arg("block_id"),
416✔
79
    py::arg("inside")
416✔
80
  );
81
  mesh_continuum.def(
416✔
82
    "SetBoundaryIDFromLogicalVolume",
83
    &MeshContinuum::SetBoundaryIDFromLogicalVolume,
416✔
84
    R"(
85
    Set boundary ID's using a logical volume.
86

87
    Parameters
88
    ----------
89
    log_vol: pyopensn.logvol.LogicalVolume
90
        Logical volume that determines which mesh cells will be selected.
91
    boundary_name: str
92
        Name of the boundary.
93
    inside: bool, default=True
94
        If true, the selected cell facess are the ones whose centroids are inside the logival
95
        volume. Otherwise, the selected meshes are the ones whose centroids are outside of the
96
        logical volume.
97
    )",
98
    py::arg("log_vol"),
416✔
99
    py::arg("boundary_name"),
416✔
100
    py::arg("inside") = true
832✔
101
  );
102
  mesh_continuum.def(
416✔
103
    "SetOrthogonalBoundaries",
104
    &MeshContinuum::SetOrthogonalBoundaries,
416✔
105
    "Set boundary IDs for xmin/xmax, ymin/ymax, zmin/zmax for a right parallelpiped domain."
106
  );
107
  mesh_continuum.def(
416✔
108
    "ExportToPVTU",
UNCOV
109
    [](std::shared_ptr<MeshContinuum> self, const std::string& file_name) {
×
110
      MeshIO::ToPVTU(self, file_name);
19✔
111
    },
19✔
112
    R"(
113
    Write grid cells into PVTU format.
114

115
    Parameters
116
    ----------
117
    file_base_name: str
118
        Base name of the output file.
119
    )",
120
    py::arg("file_base_name")
416✔
121
  );
122
  mesh_continuum.def(
416✔
123
    "ComputeVolumePerBlockID",
124
    &MeshContinuum::ComputeVolumePerBlockID,
416✔
125
    R"(
126
    Compute volume per block ID
127

128
    Returns
129
    -------
130
    Dict[int, float]
131
        Key is the block ID and the value is the computed volume
132
    )"
133
  );
134
  mesh_continuum.def(
416✔
135
    "SetBlockIDFromFunction",
UNCOV
136
    [](MeshContinuum& self, const std::function<int(Vector3, int)>& func)
×
137
    {
138
      int local_num_cells_modified = 0;
4✔
139
      // change local cells
140
      for (Cell& cell : self.local_cells)
376,004✔
141
      {
142
        int new_block_id = func(cell.centroid, cell.block_id);
376,000✔
143
        if (cell.block_id != new_block_id)
376,000✔
144
        {
145
          cell.block_id = new_block_id;
4,514✔
146
          ++local_num_cells_modified;
4,514✔
147
        }
148
      }
149
      // change ghost cells
150
      std::vector<std::uint64_t> ghost_ids = self.cells.GetGhostGlobalIDs();
4✔
151
      for (std::uint64_t ghost_id : ghost_ids)
4✔
152
      {
153
        Cell& cell = self.cells[ghost_id];
×
154
        int new_block_id = func(cell.centroid, cell.block_id);
×
155
        if (cell.block_id != new_block_id)
×
156
        {
157
          cell.block_id = new_block_id;
×
158
          ++local_num_cells_modified;
×
159
        }
160
      }
161
      // print number of modified cells
162
      int global_num_cells_modified;
163
      mpi_comm.all_reduce(local_num_cells_modified, global_num_cells_modified, mpi::op::sum<int>());
4✔
164
      log.Log0Verbose1() << program_timer.GetTimeString()
8✔
165
                         << " Done setting block id from Python function. "
4✔
166
                         << "Number of cells modified = " << global_num_cells_modified << ".";
4✔
167
    },
4✔
168
    R"(
169
    Set block ID from a function.
170

171
    Parameters
172
    ----------
173
    func: Callable[[pyopensn.math.Vector3, int], int]
174
        Function/lambda computing new block ID from cell centroid and old block ID.
175

176
    Examples
177
    --------
178
    >>> # Change block ID from 0 to 1 for cells inside the unit sphere.
179
    >>> def block_id_setter(cell_centroid, old_id):
180
    ...     if (old_id == 0) and (cell_centroid.Norm() < 1.0):
181
    ...         return 1
182
    ...     return old_id
183
    >>> mesh.SetBlockIDFromFunction(block_id_setter)
184
    )",
185
    py::arg("func")
416✔
186
  );
187

188
  // surface mesh
189
  auto surface_mesh = py::class_<SurfaceMesh, std::shared_ptr<SurfaceMesh>>(
190
    mesh,
191
    "SurfaceMesh",
192
    R"(
193
    Surface mesh.
194

195
    Wrapper of :cpp:class:`opensn::SurfaceMesh`.
196
    )"
197
  );
416✔
198
  surface_mesh.def(
416✔
199
    py::init(
416✔
UNCOV
200
      [](py::kwargs& params)
×
201
      {
202
        return SurfaceMesh::Create(kwargs_to_param_block(params));
1✔
203
      }
204
    ),
205
    R"(
206
    Construct a surface mesh.
207

208
    This function does not take any arguments.
209
    )"
210
  );
211
  surface_mesh.def(
416✔
212
    "ImportFromOBJFile",
213
    &SurfaceMesh::ImportFromOBJFile,
416✔
214
    R"(
215
    Loads a surface mesh from a wavefront .obj file.
216

217
    Parameters
218
    ----------
219
    file_name: str
220
        Surface mesh filename.
221
    as_poly: bool, default=False
222
        Indicate if the surface mesh is allowed to contain polygonal facets (as opposed to only
223
        triangular faces).
224
    translation: pyopensn.math.Vector3, default=(0.0, 0.0, 0.0)
225
        Translation to perform on the mesh.
226
    )",
227
    py::arg("file_name"),
416✔
228
    py::arg("as_poly") = false,
832✔
229
    py::arg("transform") = Vector3()
832✔
230
  );
231
  surface_mesh.def(
416✔
232
    "ImportFromTriangleFiles",
233
    &SurfaceMesh::ImportFromTriangleFiles,
416✔
234
    R"(
235
    Loads a surface mesh from triangle's file format.
236

237
    Parameters
238
    ----------
239
    file_name: str
240
        Surface mesh filename.
241
    as_poly: bool
242
        Indicate if the surface mesh is allowed to contain polygonal facets (as opposed to only
243
        triangular faces).
244
    )",
245
    py::arg("file_name"),
416✔
246
    py::arg("as_poly")
416✔
247
  );
248
  surface_mesh.def(
416✔
249
    "ImportFromMshFiles",
250
    &SurfaceMesh::ImportFromMshFiles,
416✔
251
    R"(
252
    Loads a surface mesh from gmsh's file format.
253

254
    Parameters
255
    ----------
256
    file_name: str
257
        Surface mesh filename.
258
    as_poly: bool
259
        Indicate if the surface mesh is allowed to contain polygonal facets (as opposed to only
260
        triangular faces).
261
    )",
262
    py::arg("file_name"),
416✔
263
    py::arg("as_poly")
416✔
264
  );
265
  // clang-format on
266
}
416✔
267

268
// Wrap mesh generator
269
void
270
WrapMeshGenerator(py::module& mesh)
416✔
271
{
272
  // clang-format off
273
  // base mesh generator
274
  auto mesh_generator = py::class_<MeshGenerator, std::shared_ptr<MeshGenerator>>(
275
    mesh,
276
    "MeshGenerator",
277
    R"(
278
    Generic mesh generator.
279

280
    Wrapper of :cpp:class:`opensn::MeshGenerator`.
281
    )"
282
  );
416✔
283
  mesh_generator.def(
416✔
284
    "Execute",
285
    &MeshGenerator::Execute,
416✔
286
    "Final execution step."
287
  );
288

289
  // extruded mesh generator
290
  auto extruder_mesh_generator = py::class_<ExtruderMeshGenerator,
291
                                            std::shared_ptr<ExtruderMeshGenerator>, MeshGenerator>(
292
    mesh,
293
    "ExtruderMeshGenerator",
294
    R"(
295
    Extruded mesh generator.
296

297
    Wrapper of :cpp:class:`opensn::ExtruderMeshGenerator`.
298
    )"
299
  );
416✔
300
  extruder_mesh_generator.def(
416✔
301
    py::init(
416✔
UNCOV
302
      [](py::kwargs& params)
×
303
      {
304
        return ExtruderMeshGenerator::Create(kwargs_to_param_block(params));
53✔
305
      }
306
    ),
307
    R"(
308
    Construct an extruded mesh generator.
309

310
    Extrude 2D geometry using extrusion layers. Each layer is specified by either:
311

312
     - ``n`` and ``z`` to compute the z-levels automatically.
313
     - ``n`` and ``h`` to compute the h-levels automatically.
314

315
    The list of layers can be specified with a mixture of both ways.
316

317
    Parameters
318
    ----------
319
    scale: float, default=1.0
320
        Uniform scale to apply to the mesh after reading.
321
    inputs: List[pyopensn.mesh.MeshGenerator], default=[]
322
        A list of MeshGenerator objects.
323
    partitioner: pyopensn.mesh.GraphPartitioner, default=None
324
        Handle to a GraphPartitioner object to use for parallel partitioning. This will default to
325
        PETScGraphPartitioner with a "parmetis" setting.
326
    replicated_mesh: bool, default=False
327
        Flag, when set, makes the mesh appear in full fidelity on each process.
328
    layers: List[Dict]
329
        List of layers. Parameters of each layers are represented as Python dictionary.
330
    top_boundary_name: str, default='ZMAX'
331
        The name to associate with the top boundary.
332
    bottom_boundary_name: str, default='ZMIN'
333
        The name to associate with the bottom boundary.
334

335
    Examples
336
    --------
337
    >>> emg = ExtruderMeshGenerator(
338
    ...     layers=[{"n": 1, "z": 2}, {"n": 2, "h": 0.5}]
339
    ... )
340
    )"
341
  );
342

343
  // orthogonal mesh generator
344
  auto orthogonal_mesh_generator = py::class_<OrthogonalMeshGenerator,
345
                                              std::shared_ptr<OrthogonalMeshGenerator>,
346
                                              MeshGenerator>(
347
    mesh,
348
    "OrthogonalMeshGenerator",
349
    R"(
350
    Orthogonal mesh generator.
351

352
    Wrapper of :cpp:class:`opensn::OrthogonalMeshGenerator`.
353
    )"
354
  );
416✔
355
  orthogonal_mesh_generator.def(
416✔
356
    py::init(
416✔
UNCOV
357
      [](py::kwargs& params)
×
358
      {
359
        return OrthogonalMeshGenerator::Create(kwargs_to_param_block(params));
234✔
360
      }
361
    ),
362
    R"(
363
    Construct an orthogonal mesh generator.
364

365
    Parameters
366
    ----------
367
    scale: float, default=1.0
368
        Uniform scale to apply to the mesh after reading.
369
    inputs: List[pyopensn.mesh.MeshGenerator], default=[]
370
        A list of MeshGenerator objects.
371
    partitioner: pyopensn.mesh.GraphPartitioner, default=None
372
        Handle to a GraphPartitioner object to use for parallel partitioning. This will default to
373
        PETScGraphPartitioner with a "parmetis" setting.
374
    replicated_mesh: bool, default=False
375
        Flag, when set, makes the mesh appear in full fidelity on each process.
376
    node_sets: List[List[float]]
377
        Sets of nodes per dimension. Node values must be monotonically increasing.
378
    coord_sys: {'cartesian', 'cylindrical', 'spherical'}
379
        The coordinate system of the mesh.
380
    )"
381
  );
382

383
  // from file mesh generator
384
  auto from_file_mesh_generator = py::class_<FromFileMeshGenerator,
385
                                             std::shared_ptr<FromFileMeshGenerator>, MeshGenerator>(
386
    mesh,
387
    "FromFileMeshGenerator",
388
    R"(
389
    From file mesh generator.
390

391
    Wrapper of :cpp:class:`opensn::FromFileMeshGenerator`.
392
    )"
393
  );
416✔
394
  from_file_mesh_generator.def(
416✔
395
    py::init(
416✔
UNCOV
396
      [](py::kwargs & params)
×
397
      {
398
        return FromFileMeshGenerator::Create(kwargs_to_param_block(params));
164✔
399
      }
400
    ),
401
    R"(
402
    Construct a from-file mesh generator.
403

404
    Parameters
405
    ----------
406
    scale: float, default=1.0
407
        Uniform scale to apply to the mesh after reading.
408
    inputs: List[pyopensn.mesh.MeshGenerator], default=[]
409
        A list of MeshGenerator objects.
410
    partitioner: pyopensn.mesh.GraphPartitioner, default=None
411
        Handle to a GraphPartitioner object to use for parallel partitioning. This will default to
412
        PETScGraphPartitioner with a "parmetis" setting.
413
    replicated_mesh: bool, default=False
414
        Flag, when set, makes the mesh appear in full fidelity on each process.
415
    filename: str
416
        Path to the file.
417
    block_id_fieldname: str, default='BlockID'
418
        The name of the field storing cell block/block ids. Only really used for .vtu, .pvtu and
419
        .e files.
420
    boundary_id_fieldname: str, default=''
421
        The name of the field storing boundary-ids.
422
    coord_sys: {'cartesian', 'cylindrical', 'spherical'}
423
        The coordinate system of the mesh.
424
    )"
425
  );
426

427
  // split file mesh generator
428
  auto split_file_mesh_generator = py::class_<SplitFileMeshGenerator,
429
                                              std::shared_ptr<SplitFileMeshGenerator>,
430
                                              MeshGenerator>(
431
    mesh,
432
    "SplitFileMeshGenerator",
433
    R"(
434
    Split file mesh generator.
435

436
    Wrapper of :cpp:class:`opensn::SplitFileMeshGenerator`.
437

438
    Generates the mesh only on rank 0. After partitioning, the mesh is not broadcast
439
    to other ranks; instead, a binary mesh file for each is written .
440
    )"
441
  );
416✔
442
  split_file_mesh_generator.def(
416✔
443
    py::init(
416✔
UNCOV
444
      [](py::kwargs & params)
×
445
      {
446
        return SplitFileMeshGenerator::Create(kwargs_to_param_block(params));
8✔
447
      }
448
    ),
449
    R"(
450
    Construct a split-file mesh generator.
451

452
    Parameters
453
    ----------
454
    scale: float, default=1.0
455
        Uniform scale to apply to the mesh after reading.
456
    inputs: List[pyopensn.mesh.MeshGenerator], default=[]
457
        A list of MeshGenerator objects.
458
    partitioner: pyopensn.mesh.GraphPartitioner, default=None
459
        Handle to a GraphPartitioner object to use for parallel partitioning. This will default to
460
        PETScGraphPartitioner with a "parmetis" setting.
461
    replicated_mesh: bool, default=False
462
        Flag, when set, makes the mesh appear in full fidelity on each process.
463
    num_partitions: int, default=0
464
        The number of partitions to generate. If zero, it will default to the number of MPI
465
        processes. Automatically ignored if the number of MPI processes greater 1.
466
    split_mesh_dir_path: str, default='split_mesh'
467
        Path of the directory to be created for containing the split meshes.
468
    file_prefix: str, default=''
469
        Prefix to use for all split mesh files. If not provided, it default to the input path's
470
        folder.
471
    read_only: bool, default=False
472
        Controls whether the split mesh is recreated or just read.
473
    verbosity_level: int, default=1
474
        Verbosity level. 1 will report each 10% complete. 2 will print each part and the number of
475
        local cells it wrote.
476
    )"
477
  );
478

479
  // distributed mesh generator
480
  auto distributed_mesh_generator = py::class_<DistributedMeshGenerator,
481
                                               std::shared_ptr<DistributedMeshGenerator>,
482
                                               MeshGenerator>(
483
    mesh,
484
    "DistributedMeshGenerator",
485
    R"(
486
    Distributed mesh generator.
487

488
    This class is responsible for generating a mesh, partitioning it, and distributing the
489
    individual partitions to different MPI locations. The mesh is generated on location 0,
490
    partitioned into multiple parts, serialized, and distributed to all other MPI ranks.
491

492
    Wrapper of :cpp:class:`opensn::DistributedMeshGenerator`.
493
    )"
494
  );
416✔
495
  distributed_mesh_generator.def(
416✔
496
    py::init(
416✔
UNCOV
497
      [](py::kwargs & params)
×
498
      {
499
        return DistributedMeshGenerator::Create(kwargs_to_param_block(params));
8✔
500
      }
501
    ),
502
    R"(
503
    Construct a distributed mesh generator.
504

505
    Parameters
506
    ----------
507
    scale: float, default=1.0
508
        Uniform scale to apply to the mesh after reading.
509
    inputs: List[pyopensn.mesh.MeshGenerator], default=[]
510
        A list of MeshGenerator objects.
511
    partitioner: pyopensn.mesh.GraphPartitioner, default=None
512
        Handle to a GraphPartitioner object to use for parallel partitioning. This will default to
513
        PETScGraphPartitioner with a "parmetis" setting.
514
    replicated_mesh: bool, default=False
515
        Flag, when set, makes the mesh appear in full fidelity on each process.
516
    coord_sys: {'cartesian', 'cylindrical', 'spherical'}
517
        The coordinate system of the mesh.
518
    )"
519
  );
520
  // clang-format on
521
}
416✔
522

523
// Wrap graph partitioner
524
void
525
WrapGraphPartitioner(py::module& mesh)
416✔
526
{
527
  // clang-format off
528
  // base graph partitioner
529
  auto graph_partitioner = py::class_<GraphPartitioner, std::shared_ptr<GraphPartitioner>>(
530
    mesh,
531
    "GraphPartitioner",
532
    R"(
533
    Generic graph partitioner.
534

535
    Wrapper of :cpp:class:`opensn::GraphPartitioner`.
536
    )");
416✔
537

538
  // KBA graph partitioner
539
  auto kba_graph_partitioner = py::class_<KBAGraphPartitioner, std::shared_ptr<KBAGraphPartitioner>,
540
                                          GraphPartitioner>(
541
    mesh,
542
    "KBAGraphPartitioner",
543
    R"(
544
    Koch, Baker and Alcouffe based partitioning.
545

546
    This is an overlayed ortho-grid based partitioner.
547

548
    Wrapper of :cpp:class:`opensn::KBAGraphPartitioner`.
549
    )"
550
  );
416✔
551
  kba_graph_partitioner.def(
416✔
552
    py::init(
416✔
UNCOV
553
      [](py::kwargs& params)
×
554
      {
555
        return KBAGraphPartitioner::Create(kwargs_to_param_block(params));
74✔
556
      }
557
    ),
558
    R"(
559
    Construct a KBA graph partitioner.
560

561
    Parameters
562
    ----------
563
    nx: int, default=1
564
        Number of partitions in x.
565
    ny: int, default=1
566
        Number of partitions in y.
567
    nz: int, default=1
568
        Number of partitions in z.
569
    xcuts: List[float], default=[]
570
        Location of the internal x-cuts. Requires ``nx - 1`` entries.
571
    ycuts: List[float], default=[]
572
        Location of the internal y-cuts. Requires ``ny - 1`` entries.
573
    zcuts: List[float], default=[]
574
        Location of the internal z-cuts. Requires ``nz - 1`` entries.
575
    )"
576
  );
577

578
  // linear graph partitioner
579
  auto linear_graph_partitioner = py::class_<LinearGraphPartitioner,
580
                                             std::shared_ptr<LinearGraphPartitioner>,
581
                                             GraphPartitioner>(
582
    mesh,
583
    "LinearGraphPartitioner",
584
    R"(
585
    Basic linear partitioning.
586

587
    This type of partitioner works basically only for testing.
588

589
    Orthogonal meshes can produce decent partitioning but for unstructured grids it can be pretty
590
    bad. It partitions cells based on their linear index ``global_id`` instead of actually
591
    working with the graph.
592

593
    Wrapper of :cpp:class:`opensn::LinearGraphPartitioner`.
594
    )"
595
  );
416✔
596
  linear_graph_partitioner.def(
416✔
597
    py::init(
416✔
598
      [](py::kwargs & params)
×
599
      {
600
        return LinearGraphPartitioner::Create(kwargs_to_param_block(params));
×
601
      }
602
    ),
603
    R"(
604
    Construct a linear graph partitioner.
605

606
    Parameters
607
    ----------
608
    all_to_rank: int, default=-1
609
        Rank to which all cells are restricted if non-zero. Otherwise, the partitioner is equivalent
610
        to a single-rank partitioner.
611
    )"
612
  );
613

614
  // PETSc graph partitioner
615
  auto petsc_graph_partitioner = py::class_<PETScGraphPartitioner,
616
                                            std::shared_ptr<PETScGraphPartitioner>,
617
                                            GraphPartitioner>(
618
    mesh,
619
    "PETScGraphPartitioner",
620
    R"(
621
    PETSc based partitioning.
622

623
    Wrapper of :cpp:class:`opensn::PETScGraphPartitioner`.
624
    )"
625
  );
416✔
626
  petsc_graph_partitioner.def(
416✔
627
    py::init(
416✔
UNCOV
628
      [](py::kwargs & params) {
×
629
        return PETScGraphPartitioner::Create(kwargs_to_param_block(params));
28✔
630
      }
631
    ),
632
    R"(
633
    Construct a PETSc based graph partitioner.
634

635
    Parameters
636
    ----------
637
    type: {'parmetis', 'ptscotch'}, default='parmetis'
638
        Type of PETSc partitioner.
639
    )"
640
  );
641
  // clang-format on
642
}
416✔
643

644
void
645
py_mesh(py::module& pyopensn)
62✔
646
{
647
  py::module mesh = pyopensn.def_submodule("mesh", "Mesh generation module.");
62✔
648
  WrapMesh(mesh);
62✔
649
  WrapMeshGenerator(mesh);
62✔
650
  WrapGraphPartitioner(mesh);
62✔
651
}
62✔
652

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