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

Open-Sn / opensn / 19881058708

02 Dec 2025 03:32PM UTC coverage: 74.147% (+0.003%) from 74.144%
19881058708

push

github

web-flow
Merge pull request #842 from andrsd/issue/90-block-id

Block ID is `unsigned int`

42 of 46 new or added lines in 18 files covered. (91.3%)

2 existing lines in 1 file now uncovered.

18312 of 24697 relevant lines covered (74.15%)

58507748.83 hits per line

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

94.89
/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)
451✔
36
{
37
  // clang-format off
38
  // mesh continuum
39
  auto mesh_continuum = py::class_<MeshContinuum, std::shared_ptr<MeshContinuum>>(
451✔
40
    mesh,
41
    "MeshContinuum",
42
    R"(
43
    Mesh continuum.
44

45
    Wrapper of :cpp:class:`opensn::MeshContinuum`.
46
    )"
47
  );
451✔
48
  mesh_continuum.def_property(
451✔
49
    "dimension",
50
    &MeshContinuum::GetDimension,
902✔
51
    &MeshContinuum::SetDimension,
451✔
52
    "Number of dimensions of the mesh."
53
  );
54
  mesh_continuum.def(
451✔
55
    "SetUniformBlockID",
56
    &MeshContinuum::SetUniformBlockID,
902✔
57
    "Set block ID's for all cells to the specified block ID.",
58
    py::arg("mat_id")
451✔
59
  );
60
  mesh_continuum.def(
451✔
61
    "SetBlockIDFromLogicalVolume",
62
    &MeshContinuum::SetBlockIDFromLogicalVolume,
902✔
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"),
902✔
78
    py::arg("block_id"),
902✔
79
    py::arg("inside")
451✔
80
  );
81
  mesh_continuum.def(
451✔
82
    "SetUniformBoundaryID",
83
    &MeshContinuum::SetUniformBoundaryID,
902✔
84
    R"(
85
    Assign all boundary faces to a single name
86

87
    Parameters
88
    ----------
89
    boundary_name: str
90
        Name of the boundary to assign to all boundary faces
91
    )",
92
    py::arg("boundary_name")
451✔
93
  );
94
  mesh_continuum.def(
902✔
95
    "SetBoundaryIDFromLogicalVolume",
96
    &MeshContinuum::SetBoundaryIDFromLogicalVolume,
902✔
97
    R"(
98
    Set boundary ID's using a logical volume.
99

100
    Parameters
101
    ----------
102
    log_vol: pyopensn.logvol.LogicalVolume
103
        Logical volume that determines which mesh cells will be selected.
104
    boundary_name: str
105
        Name of the boundary.
106
    inside: bool, default=True
107
        If true, the selected cell facess are the ones whose centroids are inside the logival
108
        volume. Otherwise, the selected meshes are the ones whose centroids are outside of the
109
        logical volume.
110
    )",
111
    py::arg("log_vol"),
902✔
112
    py::arg("boundary_name"),
451✔
113
    py::arg("inside") = true
451✔
114
  );
115
  mesh_continuum.def(
451✔
116
    "SetOrthogonalBoundaries",
117
    &MeshContinuum::SetOrthogonalBoundaries,
451✔
118
    "Set boundary IDs for xmin/xmax, ymin/ymax, zmin/zmax for a right parallelpiped domain."
119
  );
120
  mesh_continuum.def(
451✔
121
    "ExportToPVTU",
122
    [](std::shared_ptr<MeshContinuum> self, const std::string& file_name) {
470✔
123
      MeshIO::ToPVTU(self, file_name);
19✔
124
    },
19✔
125
    R"(
126
    Write grid cells into PVTU format.
127

128
    Parameters
129
    ----------
130
    file_base_name: str
131
        Base name of the output file.
132
    )",
133
    py::arg("file_base_name")
451✔
134
  );
135
  mesh_continuum.def(
451✔
136
    "ComputeVolumePerBlockID",
137
    &MeshContinuum::ComputeVolumePerBlockID,
451✔
138
    R"(
139
    Compute volume per block ID
140

141
    Returns
142
    -------
143
    Dict[int, float]
144
        Key is the block ID and the value is the computed volume
145
    )"
146
  );
147
  mesh_continuum.def(
451✔
148
    "SetBlockIDFromFunction",
149
    [](MeshContinuum& self, const std::function<unsigned int(Vector3, unsigned int)>& func)
455✔
150
    {
151
      int local_num_cells_modified = 0;
4✔
152
      // change local cells
153
      for (Cell& cell : self.local_cells)
376,004✔
154
      {
155
        auto new_block_id = func(cell.centroid, cell.block_id);
376,000✔
156
        if (cell.block_id != new_block_id)
376,000✔
157
        {
158
          cell.block_id = new_block_id;
4,514✔
159
          ++local_num_cells_modified;
4,514✔
160
        }
161
      }
162
      // change ghost cells
163
      std::vector<std::uint64_t> ghost_ids = self.cells.GetGhostGlobalIDs();
4✔
164
      for (std::uint64_t ghost_id : ghost_ids)
4✔
165
      {
166
        Cell& cell = self.cells[ghost_id];
×
NEW
167
        auto new_block_id = func(cell.centroid, cell.block_id);
×
168
        if (cell.block_id != new_block_id)
×
169
        {
170
          cell.block_id = new_block_id;
×
171
          ++local_num_cells_modified;
×
172
        }
173
      }
174
      // print number of modified cells
175
      int global_num_cells_modified = 0;
4✔
176
      mpi_comm.all_reduce(local_num_cells_modified, global_num_cells_modified, mpi::op::sum<int>());
4✔
177
      log.Log0Verbose1() << program_timer.GetTimeString()
12✔
178
                         << " Done setting block id from Python function. "
4✔
179
                         << "Number of cells modified = " << global_num_cells_modified << ".";
8✔
180
    },
4✔
181
    R"(
182
    Set block ID from a function.
183

184
    Parameters
185
    ----------
186
    func: Callable[[pyopensn.math.Vector3, int], int]
187
        Function/lambda computing new block ID from cell centroid and old block ID.
188

189
    Examples
190
    --------
191
    >>> # Change block ID from 0 to 1 for cells inside the unit sphere.
192
    >>> def block_id_setter(cell_centroid, old_id):
193
    ...     if (old_id == 0) and (cell_centroid.Norm() < 1.0):
194
    ...         return 1
195
    ...     return old_id
196
    >>> mesh.SetBlockIDFromFunction(block_id_setter)
197
    )",
198
    py::arg("func")
451✔
199
  );
200

201
  // surface mesh
202
  auto surface_mesh = py::class_<SurfaceMesh, std::shared_ptr<SurfaceMesh>>(
451✔
203
    mesh,
204
    "SurfaceMesh",
205
    R"(
206
    Surface mesh.
207

208
    Wrapper of :cpp:class:`opensn::SurfaceMesh`.
209
    )"
210
  );
451✔
211
  surface_mesh.def(
902✔
212
    py::init(
451✔
213
      [](py::kwargs& params)
1✔
214
      {
215
        return SurfaceMesh::Create(kwargs_to_param_block(params));
1✔
216
      }
217
    ),
218
    R"(
219
    Construct a surface mesh.
220

221
    This function does not take any arguments.
222
    )"
223
  );
224
  surface_mesh.def(
902✔
225
    "ImportFromOBJFile",
226
    &SurfaceMesh::ImportFromOBJFile,
902✔
227
    R"(
228
    Loads a surface mesh from a wavefront .obj file.
229

230
    Parameters
231
    ----------
232
    file_name: str
233
        Surface mesh filename.
234
    as_poly: bool, default=False
235
        Indicate if the surface mesh is allowed to contain polygonal facets (as opposed to only
236
        triangular faces).
237
    translation: pyopensn.math.Vector3, default=(0.0, 0.0, 0.0)
238
        Translation to perform on the mesh.
239
    )",
240
    py::arg("file_name"),
451✔
241
    py::arg("as_poly") = false,
902✔
242
    py::arg("transform") = Vector3()
451✔
243
  );
244
  surface_mesh.def(
451✔
245
    "ImportFromTriangleFiles",
246
    &SurfaceMesh::ImportFromTriangleFiles,
902✔
247
    R"(
248
    Loads a surface mesh from triangle's file format.
249

250
    Parameters
251
    ----------
252
    file_name: str
253
        Surface mesh filename.
254
    as_poly: bool
255
        Indicate if the surface mesh is allowed to contain polygonal facets (as opposed to only
256
        triangular faces).
257
    )",
258
    py::arg("file_name"),
902✔
259
    py::arg("as_poly")
451✔
260
  );
261
  surface_mesh.def(
451✔
262
    "ImportFromMshFiles",
263
    &SurfaceMesh::ImportFromMshFiles,
902✔
264
    R"(
265
    Loads a surface mesh from gmsh's file format.
266

267
    Parameters
268
    ----------
269
    file_name: str
270
        Surface mesh filename.
271
    as_poly: bool
272
        Indicate if the surface mesh is allowed to contain polygonal facets (as opposed to only
273
        triangular faces).
274
    )",
275
    py::arg("file_name"),
902✔
276
    py::arg("as_poly")
451✔
277
  );
278
  // clang-format on
279
}
451✔
280

281
// Wrap mesh generator
282
void
283
WrapMeshGenerator(py::module& mesh)
451✔
284
{
285
  // clang-format off
286
  // base mesh generator
287
  auto mesh_generator = py::class_<MeshGenerator, std::shared_ptr<MeshGenerator>>(
451✔
288
    mesh,
289
    "MeshGenerator",
290
    R"(
291
    Generic mesh generator.
292

293
    Wrapper of :cpp:class:`opensn::MeshGenerator`.
294
    )"
295
  );
451✔
296
  mesh_generator.def(
451✔
297
    "Execute",
298
    &MeshGenerator::Execute,
451✔
299
    "Final execution step."
300
  );
301

302
  // extruded mesh generator
303
  auto extruder_mesh_generator = py::class_<ExtruderMeshGenerator,
451✔
304
                                            std::shared_ptr<ExtruderMeshGenerator>, MeshGenerator>(
305
    mesh,
306
    "ExtruderMeshGenerator",
307
    R"(
308
    Extruded mesh generator.
309

310
    Wrapper of :cpp:class:`opensn::ExtruderMeshGenerator`.
311
    )"
312
  );
451✔
313
  extruder_mesh_generator.def(
902✔
314
    py::init(
451✔
315
      [](py::kwargs& params)
57✔
316
      {
317
        return ExtruderMeshGenerator::Create(kwargs_to_param_block(params));
57✔
318
      }
319
    ),
320
    R"(
321
    Construct an extruded mesh generator.
322

323
    Extrude 2D geometry using extrusion layers. Each layer is specified by either:
324

325
     - ``n`` and ``z`` to compute the z-levels automatically.
326
     - ``n`` and ``h`` to compute the h-levels automatically.
327

328
    The list of layers can be specified with a mixture of both ways.
329

330
    Parameters
331
    ----------
332
    scale: float, default=1.0
333
        Uniform scale to apply to the mesh after reading.
334
    inputs: List[pyopensn.mesh.MeshGenerator], default=[]
335
        A list of MeshGenerator objects.
336
    partitioner: pyopensn.mesh.GraphPartitioner, default=None
337
        Handle to a GraphPartitioner object to use for parallel partitioning. This will default to
338
        PETScGraphPartitioner with a "parmetis" setting.
339
    replicated_mesh: bool, default=False
340
        Flag, when set, makes the mesh appear in full fidelity on each process.
341
    layers: List[Dict]
342
        List of layers. Parameters of each layers are represented as Python dictionary.
343
    top_boundary_name: str, default='ZMAX'
344
        The name to associate with the top boundary.
345
    bottom_boundary_name: str, default='ZMIN'
346
        The name to associate with the bottom boundary.
347

348
    Examples
349
    --------
350
    >>> emg = ExtruderMeshGenerator(
351
    ...     layers=[{"n": 1, "z": 2}, {"n": 2, "h": 0.5}]
352
    ... )
353
    )"
354
  );
355

356
  // orthogonal mesh generator
357
  auto orthogonal_mesh_generator = py::class_<OrthogonalMeshGenerator,
451✔
358
                                              std::shared_ptr<OrthogonalMeshGenerator>,
359
                                              MeshGenerator>(
360
    mesh,
361
    "OrthogonalMeshGenerator",
362
    R"(
363
    Orthogonal mesh generator.
364

365
    Wrapper of :cpp:class:`opensn::OrthogonalMeshGenerator`.
366
    )"
367
  );
451✔
368
  orthogonal_mesh_generator.def(
902✔
369
    py::init(
451✔
370
      [](py::kwargs& params)
238✔
371
      {
372
        return OrthogonalMeshGenerator::Create(kwargs_to_param_block(params));
238✔
373
      }
374
    ),
375
    R"(
376
    Construct an orthogonal mesh generator.
377

378
    Parameters
379
    ----------
380
    scale: float, default=1.0
381
        Uniform scale to apply to the mesh after reading.
382
    inputs: List[pyopensn.mesh.MeshGenerator], default=[]
383
        A list of MeshGenerator objects.
384
    partitioner: pyopensn.mesh.GraphPartitioner, default=None
385
        Handle to a GraphPartitioner object to use for parallel partitioning. This will default to
386
        PETScGraphPartitioner with a "parmetis" setting.
387
    replicated_mesh: bool, default=False
388
        Flag, when set, makes the mesh appear in full fidelity on each process.
389
    node_sets: List[List[float]]
390
        Sets of nodes per dimension. Node values must be monotonically increasing.
391
    coord_sys: {'cartesian', 'cylindrical', 'spherical'}
392
        The coordinate system of the mesh.
393
    )"
394
  );
395

396
  // from file mesh generator
397
  auto from_file_mesh_generator = py::class_<FromFileMeshGenerator,
451✔
398
                                             std::shared_ptr<FromFileMeshGenerator>, MeshGenerator>(
399
    mesh,
400
    "FromFileMeshGenerator",
401
    R"(
402
    From file mesh generator.
403

404
    Wrapper of :cpp:class:`opensn::FromFileMeshGenerator`.
405
    )"
406
  );
451✔
407
  from_file_mesh_generator.def(
902✔
408
    py::init(
451✔
409
      [](py::kwargs & params)
195✔
410
      {
411
        return FromFileMeshGenerator::Create(kwargs_to_param_block(params));
195✔
412
      }
413
    ),
414
    R"(
415
    Construct a from-file mesh generator.
416

417
    Parameters
418
    ----------
419
    scale: float, default=1.0
420
        Uniform scale to apply to the mesh after reading.
421
    inputs: List[pyopensn.mesh.MeshGenerator], default=[]
422
        A list of MeshGenerator objects.
423
    partitioner: pyopensn.mesh.GraphPartitioner, default=None
424
        Handle to a GraphPartitioner object to use for parallel partitioning. This will default to
425
        PETScGraphPartitioner with a "parmetis" setting.
426
    replicated_mesh: bool, default=False
427
        Flag, when set, makes the mesh appear in full fidelity on each process.
428
    filename: str
429
        Path to the file.
430
    block_id_fieldname: str, default='BlockID'
431
        The name of the field storing cell block/block ids. Only really used for .vtu, .pvtu and
432
        .e files.
433
    boundary_id_fieldname: str, default=''
434
        The name of the field storing boundary-ids.
435
    coord_sys: {'cartesian', 'cylindrical', 'spherical'}
436
        The coordinate system of the mesh.
437
    )"
438
  );
439

440
  // split file mesh generator
441
  auto split_file_mesh_generator = py::class_<SplitFileMeshGenerator,
451✔
442
                                              std::shared_ptr<SplitFileMeshGenerator>,
443
                                              MeshGenerator>(
444
    mesh,
445
    "SplitFileMeshGenerator",
446
    R"(
447
    Split file mesh generator.
448

449
    Wrapper of :cpp:class:`opensn::SplitFileMeshGenerator`.
450

451
    Generates the mesh only on rank 0. After partitioning, the mesh is not broadcast
452
    to other ranks; instead, a binary mesh file for each is written .
453
    )"
454
  );
451✔
455
  split_file_mesh_generator.def(
902✔
456
    py::init(
451✔
457
      [](py::kwargs & params)
8✔
458
      {
459
        return SplitFileMeshGenerator::Create(kwargs_to_param_block(params));
8✔
460
      }
461
    ),
462
    R"(
463
    Construct a split-file mesh generator.
464

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

492
  // distributed mesh generator
493
  auto distributed_mesh_generator = py::class_<DistributedMeshGenerator,
451✔
494
                                               std::shared_ptr<DistributedMeshGenerator>,
495
                                               MeshGenerator>(
496
    mesh,
497
    "DistributedMeshGenerator",
498
    R"(
499
    Distributed mesh generator.
500

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

505
    Wrapper of :cpp:class:`opensn::DistributedMeshGenerator`.
506
    )"
507
  );
451✔
508
  distributed_mesh_generator.def(
902✔
509
    py::init(
451✔
510
      [](py::kwargs & params)
8✔
511
      {
512
        return DistributedMeshGenerator::Create(kwargs_to_param_block(params));
8✔
513
      }
514
    ),
515
    R"(
516
    Construct a distributed mesh generator.
517

518
    Parameters
519
    ----------
520
    scale: float, default=1.0
521
        Uniform scale to apply to the mesh after reading.
522
    inputs: List[pyopensn.mesh.MeshGenerator], default=[]
523
        A list of MeshGenerator objects.
524
    partitioner: pyopensn.mesh.GraphPartitioner, default=None
525
        Handle to a GraphPartitioner object to use for parallel partitioning. This will default to
526
        PETScGraphPartitioner with a "parmetis" setting.
527
    replicated_mesh: bool, default=False
528
        Flag, when set, makes the mesh appear in full fidelity on each process.
529
    coord_sys: {'cartesian', 'cylindrical', 'spherical'}
530
        The coordinate system of the mesh.
531
    )"
532
  );
533
  // clang-format on
534
}
451✔
535

536
// Wrap graph partitioner
537
void
538
WrapGraphPartitioner(py::module& mesh)
451✔
539
{
540
  // clang-format off
541
  // base graph partitioner
542
  auto graph_partitioner = py::class_<GraphPartitioner, std::shared_ptr<GraphPartitioner>>(
451✔
543
    mesh,
544
    "GraphPartitioner",
545
    R"(
546
    Generic graph partitioner.
547

548
    Wrapper of :cpp:class:`opensn::GraphPartitioner`.
549
    )");
451✔
550

551
  // KBA graph partitioner
552
  auto kba_graph_partitioner = py::class_<KBAGraphPartitioner, std::shared_ptr<KBAGraphPartitioner>,
451✔
553
                                          GraphPartitioner>(
554
    mesh,
555
    "KBAGraphPartitioner",
556
    R"(
557
    Koch, Baker and Alcouffe based partitioning.
558

559
    This is an overlayed ortho-grid based partitioner.
560

561
    Wrapper of :cpp:class:`opensn::KBAGraphPartitioner`.
562
    )"
563
  );
451✔
564
  kba_graph_partitioner.def(
902✔
565
    py::init(
451✔
566
      [](py::kwargs& params)
82✔
567
      {
568
        return KBAGraphPartitioner::Create(kwargs_to_param_block(params));
82✔
569
      }
570
    ),
571
    R"(
572
    Construct a KBA graph partitioner.
573

574
    Parameters
575
    ----------
576
    nx: int, default=1
577
        Number of partitions in x.
578
    ny: int, default=1
579
        Number of partitions in y.
580
    nz: int, default=1
581
        Number of partitions in z.
582
    xcuts: List[float], default=[]
583
        Location of the internal x-cuts. Requires ``nx - 1`` entries.
584
    ycuts: List[float], default=[]
585
        Location of the internal y-cuts. Requires ``ny - 1`` entries.
586
    zcuts: List[float], default=[]
587
        Location of the internal z-cuts. Requires ``nz - 1`` entries.
588
    )"
589
  );
590

591
  // linear graph partitioner
592
  auto linear_graph_partitioner = py::class_<LinearGraphPartitioner,
451✔
593
                                             std::shared_ptr<LinearGraphPartitioner>,
594
                                             GraphPartitioner>(
595
    mesh,
596
    "LinearGraphPartitioner",
597
    R"(
598
    Basic linear partitioning.
599

600
    This type of partitioner works basically only for testing.
601

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

606
    Wrapper of :cpp:class:`opensn::LinearGraphPartitioner`.
607
    )"
608
  );
451✔
609
  linear_graph_partitioner.def(
902✔
610
    py::init(
451✔
611
      [](py::kwargs & params)
×
612
      {
613
        return LinearGraphPartitioner::Create(kwargs_to_param_block(params));
×
614
      }
615
    ),
616
    R"(
617
    Construct a linear graph partitioner.
618

619
    Parameters
620
    ----------
621
    all_to_rank: int, default=-1
622
        Rank to which all cells are restricted if non-zero. Otherwise, the partitioner is equivalent
623
        to a single-rank partitioner.
624
    )"
625
  );
626

627
  // PETSc graph partitioner
628
  auto petsc_graph_partitioner = py::class_<PETScGraphPartitioner,
451✔
629
                                            std::shared_ptr<PETScGraphPartitioner>,
630
                                            GraphPartitioner>(
631
    mesh,
632
    "PETScGraphPartitioner",
633
    R"(
634
    PETSc based partitioning.
635

636
    Wrapper of :cpp:class:`opensn::PETScGraphPartitioner`.
637
    )"
638
  );
451✔
639
  petsc_graph_partitioner.def(
902✔
640
    py::init(
451✔
641
      [](py::kwargs & params) {
28✔
642
        return PETScGraphPartitioner::Create(kwargs_to_param_block(params));
28✔
643
      }
644
    ),
645
    R"(
646
    Construct a PETSc based graph partitioner.
647

648
    Parameters
649
    ----------
650
    type: {'parmetis', 'ptscotch'}, default='parmetis'
651
        Type of PETSc partitioner.
652
    )"
653
  );
654
  // clang-format on
655
}
451✔
656

657
void
658
py_mesh(py::module& pyopensn)
62✔
659
{
660
  py::module mesh = pyopensn.def_submodule("mesh", "Mesh generation module.");
62✔
661
  WrapMesh(mesh);
62✔
662
  WrapMeshGenerator(mesh);
62✔
663
  WrapGraphPartitioner(mesh);
62✔
664
}
62✔
665

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