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

Open-Sn / opensn / 25359736025

04 May 2026 04:34PM UTC coverage: 75.416% (-0.001%) from 75.417%
25359736025

push

github

web-flow
Merge pull request #1038 from quocdang1998/sycl-mod

Extend SYCL implementation for caribou and OpenSn

21817 of 28929 relevant lines covered (75.42%)

65645385.67 hits per line

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

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

31
namespace opensn
32
{
33

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

46
    Wrapper of :cpp:class:`opensn::MeshContinuum`.
47
    )"
48
  );
674✔
49
  mesh_continuum.def_property(
674✔
50
    "dimension",
51
    &MeshContinuum::GetDimension,
1,348✔
52
    &MeshContinuum::SetDimension,
674✔
53
    "Number of dimensions of the mesh."
54
  );
55
  mesh_continuum.def(
674✔
56
    "GetGlobalNumberOfCells",
57
    &MeshContinuum::GetGlobalNumberOfCells,
674✔
58
    "Get global number of cells."
59
  );
60
  mesh_continuum.def(
674✔
61
    "SetUniformBlockID",
62
    &MeshContinuum::SetUniformBlockID,
1,348✔
63
    "Set block ID's for all cells to the specified block ID.",
64
    py::arg("mat_id")
674✔
65
  );
66
  mesh_continuum.def(
674✔
67
    "SetBlockIDFromLogicalVolume",
68
    &MeshContinuum::SetBlockIDFromLogicalVolume,
1,348✔
69
    R"(
70
    Set block ID's using a logical volume.
71

72
    Parameters
73
    ----------
74
    log_vol: pyopensn.logvol.LogicalVolume
75
        Logical volume that determines which mesh cells will be selected.
76
    block_id: int
77
        Block ID that will be assigned.
78
    inside: bool
79
        If true, the selected mesh cells are the ones whose centroids are inside the logival volume.
80
        Otherwise, the selected meshes are the ones whose centroids are outside of the logical
81
        volume.
82
    )",
83
    py::arg("log_vol"),
1,348✔
84
    py::arg("block_id"),
1,348✔
85
    py::arg("inside")
674✔
86
  );
87
  mesh_continuum.def(
674✔
88
    "SetUniformBoundaryID",
89
    &MeshContinuum::SetUniformBoundaryID,
1,348✔
90
    R"(
91
    Assign all boundary faces to a single name
92

93
    Parameters
94
    ----------
95
    boundary_name: str
96
        Name of the boundary to assign to all boundary faces
97
    )",
98
    py::arg("boundary_name")
674✔
99
  );
100
  mesh_continuum.def(
1,348✔
101
    "SetBoundaryIDFromLogicalVolume",
102
    &MeshContinuum::SetBoundaryIDFromLogicalVolume,
1,348✔
103
    R"(
104
    Set boundary ID's using a logical volume.
105

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

134
    Parameters
135
    ----------
136
    file_base_name: str
137
        Base name of the output file.
138
    )",
139
    py::arg("file_base_name")
674✔
140
  );
141
  mesh_continuum.def(
674✔
142
    "ComputeVolumePerBlockID",
143
    &MeshContinuum::ComputeVolumePerBlockID,
674✔
144
    R"(
145
    Compute volume per block ID
146

147
    Returns
148
    -------
149
    Dict[int, float]
150
        Key is the block ID and the value is the computed volume
151
    )"
152
  );
153
  mesh_continuum.def(
674✔
154
    "SetBlockIDFromFunction",
155
    [](MeshContinuum& self, const std::function<unsigned int(Vector3, unsigned int)>& func)
679✔
156
    {
157
      int local_num_cells_modified = 0;
5✔
158
      // change local cells
159
      for (Cell& cell : self.local_cells)
665,131✔
160
      {
161
        auto new_block_id = func(cell.centroid, cell.block_id);
665,126✔
162
        if (cell.block_id != new_block_id)
665,126✔
163
        {
164
          cell.block_id = new_block_id;
22,771✔
165
          ++local_num_cells_modified;
22,771✔
166
        }
167
      }
168
      // change ghost cells
169
      std::vector<std::uint64_t> ghost_ids = self.cells.GetGhostGlobalIDs();
5✔
170
      for (std::uint64_t ghost_id : ghost_ids)
5✔
171
      {
172
        Cell& cell = self.cells[ghost_id];
×
173
        auto new_block_id = func(cell.centroid, cell.block_id);
×
174
        if (cell.block_id != new_block_id)
×
175
        {
176
          cell.block_id = new_block_id;
×
177
          ++local_num_cells_modified;
×
178
        }
179
      }
180
      // print number of modified cells
181
      int global_num_cells_modified = 0;
5✔
182
      mpi_comm.all_reduce(local_num_cells_modified, global_num_cells_modified, mpi::op::sum<int>());
5✔
183
      log.Log0Verbose1() << program_timer.GetTimeString()
15✔
184
                         << " Done setting block id from Python function. "
5✔
185
                         << "Number of cells modified = " << global_num_cells_modified << ".";
10✔
186
    },
5✔
187
    R"(
188
    Set block ID from a function.
189

190
    Parameters
191
    ----------
192
    func: Callable[[pyopensn.math.Vector3, int], int]
193
        Function/lambda computing new block ID from cell centroid and old block ID.
194

195
    Examples
196
    --------
197
    >>> # Change block ID from 0 to 1 for cells inside the unit sphere.
198
    >>> def block_id_setter(cell_centroid, old_id):
199
    ...     if (old_id == 0) and (cell_centroid.Norm() < 1.0):
200
    ...         return 1
201
    ...     return old_id
202
    >>> mesh.SetBlockIDFromFunction(block_id_setter)
203
    )",
204
    py::arg("func")
674✔
205
  );
206

207
  // surface mesh
208
  auto surface_mesh = py::class_<SurfaceMesh, std::shared_ptr<SurfaceMesh>>(
674✔
209
    mesh,
210
    "SurfaceMesh",
211
    R"(
212
    Surface mesh.
213

214
    Wrapper of :cpp:class:`opensn::SurfaceMesh`.
215
    )"
216
  );
674✔
217
  surface_mesh.def(
1,348✔
218
    py::init(
674✔
219
      [](py::kwargs& params)
2✔
220
      {
221
        return SurfaceMesh::Create(kwargs_to_param_block(params));
2✔
222
      }
223
    ),
224
    R"(
225
    Construct a surface mesh.
226

227
    This function does not take any arguments.
228
    )"
229
  );
230
  surface_mesh.def(
1,348✔
231
    "ImportFromOBJFile",
232
    &SurfaceMesh::ImportFromOBJFile,
1,348✔
233
    R"(
234
    Loads a surface mesh from a wavefront .obj file.
235

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

256
    Parameters
257
    ----------
258
    file_name: str
259
        Surface mesh filename.
260
    as_poly: bool
261
        Indicate if the surface mesh is allowed to contain polygonal facets (as opposed to only
262
        triangular faces).
263
    )",
264
    py::arg("file_name"),
1,348✔
265
    py::arg("as_poly")
674✔
266
  );
267
  surface_mesh.def(
674✔
268
    "ImportFromMshFiles",
269
    &SurfaceMesh::ImportFromMshFiles,
1,348✔
270
    R"(
271
    Loads a surface mesh from gmsh's file format.
272

273
    Parameters
274
    ----------
275
    file_name: str
276
        Surface mesh filename.
277
    as_poly: bool
278
        Indicate if the surface mesh is allowed to contain polygonal facets (as opposed to only
279
        triangular faces).
280
    )",
281
    py::arg("file_name"),
1,348✔
282
    py::arg("as_poly")
674✔
283
  );
284
  // clang-format on
285
}
674✔
286

287
// Wrap mesh generator
288
void
289
WrapMeshGenerator(py::module& mesh)
674✔
290
{
291
  // clang-format off
292
  // base mesh generator
293
  auto mesh_generator = py::class_<MeshGenerator, std::shared_ptr<MeshGenerator>>(
674✔
294
    mesh,
295
    "MeshGenerator",
296
    R"(
297
    Generic mesh generator.
298

299
    Wrapper of :cpp:class:`opensn::MeshGenerator`.
300
    )"
301
  );
674✔
302
  mesh_generator.def(
674✔
303
    "Execute",
304
    &MeshGenerator::Execute,
674✔
305
    "Final execution step."
306
  );
307

308
  // extruded mesh generator
309
  auto extruder_mesh_generator = py::class_<ExtruderMeshGenerator,
674✔
310
                                            std::shared_ptr<ExtruderMeshGenerator>, MeshGenerator>(
311
    mesh,
312
    "ExtruderMeshGenerator",
313
    R"(
314
    Extruded mesh generator.
315

316
    Wrapper of :cpp:class:`opensn::ExtruderMeshGenerator`.
317
    )"
318
  );
674✔
319
  extruder_mesh_generator.def(
1,348✔
320
    py::init(
674✔
321
      [](py::kwargs& params)
69✔
322
      {
323
        return ExtruderMeshGenerator::Create(kwargs_to_param_block(params));
69✔
324
      }
325
    ),
326
    R"(
327
    Construct an extruded mesh generator.
328

329
    Extrude 2D geometry using extrusion layers. Each layer is specified by either:
330

331
     - ``n`` and ``z`` to compute the z-levels automatically.
332
     - ``n`` and ``h`` to compute the h-levels automatically.
333

334
    The list of layers can be specified with a mixture of both ways.
335

336
    Parameters
337
    ----------
338
    scale: float, default=1.0
339
        Uniform scale to apply to the mesh after reading.
340
    inputs: List[pyopensn.mesh.MeshGenerator], default=[]
341
        A list of MeshGenerator objects.
342
    partitioner: pyopensn.mesh.GraphPartitioner, default=None
343
        Handle to a GraphPartitioner object to use for parallel partitioning. This will default to
344
        PETScGraphPartitioner with a "parmetis" setting.
345
    replicated_mesh: bool, default=False
346
        Flag, when set, makes the mesh appear in full fidelity on each process.
347
    layers: List[Dict]
348
        List of layers. Each layer is a dictionary with entries:
349
          - n: int, default=1
350
              Number of sub-layers in this layer.
351
          - h: float, default=1.0
352
              Layer height. Cannot be specified if ``z`` is specified.
353
          - z: float, default=0.0
354
              Z-coordinate at the top of the layer. Cannot be specified if ``h`` is specified.
355
    top_boundary_name: str, default='ZMAX'
356
        The name to associate with the top boundary.
357
    bottom_boundary_name: str, default='ZMIN'
358
        The name to associate with the bottom boundary.
359

360
    Examples
361
    --------
362
    >>> emg = ExtruderMeshGenerator(
363
    ...     layers=[{"n": 1, "z": 2}, {"n": 2, "h": 0.5}]
364
    ... )
365
    )"
366
  );
367

368
  // orthogonal mesh generator
369
  auto orthogonal_mesh_generator = py::class_<OrthogonalMeshGenerator,
674✔
370
                                              std::shared_ptr<OrthogonalMeshGenerator>,
371
                                              MeshGenerator>(
372
    mesh,
373
    "OrthogonalMeshGenerator",
374
    R"(
375
    Orthogonal mesh generator.
376

377
    Wrapper of :cpp:class:`opensn::OrthogonalMeshGenerator`.
378
    )"
379
  );
674✔
380
  orthogonal_mesh_generator.def(
1,348✔
381
    py::init(
674✔
382
      [](py::kwargs& params)
427✔
383
      {
384
        return OrthogonalMeshGenerator::Create(kwargs_to_param_block(params));
427✔
385
      }
386
    ),
387
    R"(
388
    Construct an orthogonal mesh generator.
389

390
    Parameters
391
    ----------
392
    scale: float, default=1.0
393
        Uniform scale to apply to the mesh after reading.
394
    inputs: List[pyopensn.mesh.MeshGenerator], default=[]
395
        A list of MeshGenerator objects.
396
    partitioner: pyopensn.mesh.GraphPartitioner, default=None
397
        Handle to a GraphPartitioner object to use for parallel partitioning. This will default to
398
        PETScGraphPartitioner with a "parmetis" setting.
399
    replicated_mesh: bool, default=False
400
        Flag, when set, makes the mesh appear in full fidelity on each process.
401
    node_sets: List[List[float]]
402
        Sets of nodes per dimension. Node values must be monotonically increasing.
403
    coord_sys: {'cartesian', 'cylindrical', 'spherical'}
404
        The coordinate system of the mesh.
405
    )"
406
  );
407

408
  // from file mesh generator
409
  auto from_file_mesh_generator = py::class_<FromFileMeshGenerator,
674✔
410
                                             std::shared_ptr<FromFileMeshGenerator>, MeshGenerator>(
411
    mesh,
412
    "FromFileMeshGenerator",
413
    R"(
414
    From file mesh generator.
415

416
    Wrapper of :cpp:class:`opensn::FromFileMeshGenerator`.
417
    )"
418
  );
674✔
419
  from_file_mesh_generator.def(
1,348✔
420
    py::init(
674✔
421
      [](py::kwargs & params)
283✔
422
      {
423
        return FromFileMeshGenerator::Create(kwargs_to_param_block(params));
283✔
424
      }
425
    ),
426
    R"(
427
    Construct a from-file mesh generator.
428

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

452
  // split file mesh generator
453
  auto split_file_mesh_generator = py::class_<SplitFileMeshGenerator,
674✔
454
                                              std::shared_ptr<SplitFileMeshGenerator>,
455
                                              MeshGenerator>(
456
    mesh,
457
    "SplitFileMeshGenerator",
458
    R"(
459
    Split file mesh generator.
460

461
    Wrapper of :cpp:class:`opensn::SplitFileMeshGenerator`.
462

463
    Generates the mesh only on rank 0. After partitioning, the mesh is not broadcast
464
    to other ranks; instead, a binary mesh file for each is written .
465
    )"
466
  );
674✔
467
  split_file_mesh_generator.def(
1,348✔
468
    py::init(
674✔
469
      [](py::kwargs & params)
8✔
470
      {
471
        return SplitFileMeshGenerator::Create(kwargs_to_param_block(params));
8✔
472
      }
473
    ),
474
    R"(
475
    Construct a split-file mesh generator.
476

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

504
  // distributed mesh generator
505
  auto distributed_mesh_generator = py::class_<DistributedMeshGenerator,
674✔
506
                                               std::shared_ptr<DistributedMeshGenerator>,
507
                                               MeshGenerator>(
508
    mesh,
509
    "DistributedMeshGenerator",
510
    R"(
511
    Distributed mesh generator.
512

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

517
    Wrapper of :cpp:class:`opensn::DistributedMeshGenerator`.
518
    )"
519
  );
674✔
520
  distributed_mesh_generator.def(
1,348✔
521
    py::init(
674✔
522
      [](py::kwargs & params)
8✔
523
      {
524
        return DistributedMeshGenerator::Create(kwargs_to_param_block(params));
8✔
525
      }
526
    ),
527
    R"(
528
    Construct a distributed mesh generator.
529

530
    Parameters
531
    ----------
532
    scale: float, default=1.0
533
        Uniform scale to apply to the mesh after reading.
534
    inputs: List[pyopensn.mesh.MeshGenerator], default=[]
535
        A list of MeshGenerator objects.
536
    partitioner: pyopensn.mesh.GraphPartitioner, default=None
537
        Handle to a GraphPartitioner object to use for parallel partitioning. This will default to
538
        PETScGraphPartitioner with a "parmetis" setting.
539
    replicated_mesh: bool, default=False
540
        Flag, when set, makes the mesh appear in full fidelity on each process.
541
    coord_sys: {'cartesian', 'cylindrical', 'spherical'}
542
        The coordinate system of the mesh.
543
    )"
544
  );
545
  // clang-format on
546
}
674✔
547

548
// Wrap graph partitioner
549
void
550
WrapGraphPartitioner(py::module& mesh)
674✔
551
{
552
  // clang-format off
553
  // base graph partitioner
554
  auto graph_partitioner = py::class_<GraphPartitioner, std::shared_ptr<GraphPartitioner>>(
674✔
555
    mesh,
556
    "GraphPartitioner",
557
    R"(
558
    Generic graph partitioner.
559

560
    Wrapper of :cpp:class:`opensn::GraphPartitioner`.
561
    )");
674✔
562

563
  // KBA graph partitioner
564
  auto kba_graph_partitioner = py::class_<KBAGraphPartitioner, std::shared_ptr<KBAGraphPartitioner>,
674✔
565
                                          GraphPartitioner>(
566
    mesh,
567
    "KBAGraphPartitioner",
568
    R"(
569
    Koch, Baker and Alcouffe based partitioning.
570

571
    This is an overlayed ortho-grid based partitioner.
572

573
    Wrapper of :cpp:class:`opensn::KBAGraphPartitioner`.
574
    )"
575
  );
674✔
576
  kba_graph_partitioner.def(
1,348✔
577
    py::init(
674✔
578
      [](py::kwargs& params)
111✔
579
      {
580
        return KBAGraphPartitioner::Create(kwargs_to_param_block(params));
111✔
581
      }
582
    ),
583
    R"(
584
    Construct a KBA graph partitioner.
585

586
    Parameters
587
    ----------
588
    nx: int, default=1
589
        Number of partitions in x.
590
    ny: int, default=1
591
        Number of partitions in y.
592
    nz: int, default=1
593
        Number of partitions in z.
594
    xcuts: List[float], default=[]
595
        Location of the internal x-cuts. Requires ``nx - 1`` entries.
596
    ycuts: List[float], default=[]
597
        Location of the internal y-cuts. Requires ``ny - 1`` entries.
598
    zcuts: List[float], default=[]
599
        Location of the internal z-cuts. Requires ``nz - 1`` entries.
600
    )"
601
  );
602

603
  // linear graph partitioner
604
  auto linear_graph_partitioner = py::class_<LinearGraphPartitioner,
674✔
605
                                             std::shared_ptr<LinearGraphPartitioner>,
606
                                             GraphPartitioner>(
607
    mesh,
608
    "LinearGraphPartitioner",
609
    R"(
610
    Basic linear partitioning.
611

612
    This type of partitioner works basically only for testing.
613

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

618
    Wrapper of :cpp:class:`opensn::LinearGraphPartitioner`.
619
    )"
620
  );
674✔
621
  linear_graph_partitioner.def(
1,348✔
622
    py::init(
674✔
623
      [](py::kwargs & params)
×
624
      {
625
        return LinearGraphPartitioner::Create(kwargs_to_param_block(params));
×
626
      }
627
    ),
628
    R"(
629
    Construct a linear graph partitioner.
630

631
    Parameters
632
    ----------
633
    all_to_rank: int, default=-1
634
        Rank to which all cells are restricted if non-zero. Otherwise, the partitioner is equivalent
635
        to a single-rank partitioner.
636
    )"
637
  );
638

639
  // PETSc graph partitioner
640
  auto petsc_graph_partitioner = py::class_<PETScGraphPartitioner,
674✔
641
                                            std::shared_ptr<PETScGraphPartitioner>,
642
                                            GraphPartitioner>(
643
    mesh,
644
    "PETScGraphPartitioner",
645
    R"(
646
    PETSc based partitioning.
647

648
    Wrapper of :cpp:class:`opensn::PETScGraphPartitioner`.
649
    )"
650
  );
674✔
651
  petsc_graph_partitioner.def(
1,348✔
652
    py::init(
674✔
653
      [](py::kwargs & params) {
28✔
654
        return PETScGraphPartitioner::Create(kwargs_to_param_block(params));
28✔
655
      }
656
    ),
657
    R"(
658
    Construct a PETSc based graph partitioner.
659

660
    Parameters
661
    ----------
662
    type: {'parmetis', 'ptscotch'}, default='parmetis'
663
        Type of PETSc partitioner.
664
    )"
665
  );
666
  // clang-format on
667
}
674✔
668

669
void
670
py_mesh(py::module& pyopensn)
72✔
671
{
672
  py::module mesh = pyopensn.def_submodule("mesh", "Mesh generation module.");
72✔
673
  WrapMesh(mesh);
72✔
674
  WrapMeshGenerator(mesh);
72✔
675
  WrapGraphPartitioner(mesh);
72✔
676
}
72✔
677

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