mesh-sieve 4.0.1

Modular, high-performance Rust library for mesh and data management, designed for scientific computing and PDE codes.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
# mesh-sieve API Guide


This guide describes the current public API shape of `mesh-sieve` as it exists
in this repository. The crate is version `3.8.0`, uses Rust edition `2024`, and
has no default feature flags.

`mesh-sieve` is organized around a small set of mesh abstractions:

- `PointId`: nonzero mesh entity identifiers.
- `Sieve`: directed incidence graphs for topology.
- `Atlas`: point-to-slice layout metadata.
- `Section<V, S>`: values stored over an atlas with a storage backend.
- `LabelSet`: integer labels on mesh points.
- `Coordinates`: coordinate sections with topological and embedding dimensions.
- `Overlap`: local-to-rank sharing information.
- `Communicator`: serial, Rayon, and MPI communication abstraction.
- `MeshData` and `MeshBundle`: I/O containers for topology and data.
- `MeshDM`: a DMPlex-like facade over topology, coordinates, labels, sections,
  distribution, and solver numbering.

The preferred style is fallible and explicit: use `try_*` methods, propagate
`MeshSieveError`, and enable `strict-invariants` in at least one test lane.

## 1. Crate Setup


```toml
[dependencies]
mesh-sieve = "3.8.0"
```

Common local commands:

```sh
cargo check
cargo test
cargo test --features strict-invariants
```

The default feature set is empty. Important opt-in features:

| Feature | Use |
| --- | --- |
| `strict-invariants` | Run deeper invariant checks outside debug-only paths. |
| `check-invariants` | Alias for `strict-invariants`. |
| `map-adapter` | Expose legacy infallible map helpers. Prefer `try_*`. |
| `rayon` | Enable Rayon-backed parallel utilities and `RayonComm`. |
| `mpi-support` | Enable MPI communication and MPI distribution paths. |
| `mpi-derive` | Enable derive support from the `mpi` crate. |
| `metis-support` | Enable the vendored METIS backend through `metis-sys`. |
| `fast-hash` | Enable `ahash` in selected hot paths. |
| `deterministic-order` | Prefer deterministic map/set ordering where supported. |
| `wgpu` | Enable GPU-backed section storage. |
| `cgns` | Enable the experimental CGNS/HDF5 reader. |

Feature-gated paths may require system support: MPI, HDF5, GPU drivers,
or a compatible WGPU adapter.

## 2. Points and Arrows


Every mesh entity is a `PointId`. `PointId::new(0)` is invalid because zero is
reserved as a sentinel.

```rust
use mesh_sieve::topology::point::PointId;

fn main() -> Result<(), mesh_sieve::mesh_error::MeshSieveError> {
    let cell = PointId::new(1)?;
    let face = PointId::new(2)?;
    assert_eq!(cell.get(), 1);
    assert_ne!(cell, face);
    Ok(())
}
```

`Arrow<P>` represents a directed incidence `src -> dst` carrying an arbitrary
payload. For vertical stack arrows, `Polarity::{Forward, Reverse}` represents
slice orientation during refinement and assembly. For group-valued mesh
orientation, use types in `topology::orientation` and `OrientedSieve`.

## 3. Sieve Topology


The core trait is `topology::sieve::Sieve`. A sieve is a directed graph with
bidirectional incidence queries:

- `cone(p)`: outgoing arrows from `p`.
- `support(p)`: incoming arrows to `p`.
- `cone_points(p)` and `support_points(p)`: point-only adapters.
- `add_arrow(src, dst, payload)`: insert or replace one edge.
- `remove_arrow(src, dst)`: remove one edge.
- `closure_iter(seeds)`, `star_iter(seeds)`, `closure_both_iter(seeds)`.
- `height`, `depth`, `diameter`, `height_stratum`, `depth_stratum`.
- `base_points`, `cap_points`, `points`, `points_sorted`, `points_chart_order`.

A sieve stores at most one arrow for a `(src, dst)` pair. Adding the same edge
again replaces its payload rather than creating a parallel edge.

Common implementations and aliases:

- `InMemorySieve<P, T>`: generic in-memory topology.
- `InMemoryOrientedSieve<P, T, O>`: per-arrow orientation.
- `MeshSieve`: default orientation-preserving mesh topology alias.
- `InMemorySieveDeterministic`: deterministic in-memory variant.
- `FrozenSieveCsr`: frozen CSR representation for cache-friendly traversal.
- `InMemoryStack<B, C, T>`: vertical base-to-cap relation.

```rust
use mesh_sieve::topology::point::PointId;
use mesh_sieve::topology::sieve::{InMemorySieve, Sieve};

fn main() -> Result<(), mesh_sieve::mesh_error::MeshSieveError> {
    let mut sieve = InMemorySieve::<PointId, ()>::default();
    let cell = PointId::new(1)?;
    let face = PointId::new(2)?;

    sieve.add_arrow(cell, face, ());

    let cone: Vec<_> = sieve.cone_points(cell).collect();
    let closure: Vec<_> = sieve.closure_iter([cell]).collect();

    assert_eq!(cone, vec![face]);
    assert!(closure.contains(&face));
    Ok(())
}
```

Use `SieveBuildExt` and `SieveReserveExt` for bulk construction and
preallocation. Use `SieveRef` traversal variants when you need borrowed
payloads rather than cloned payloads.

## 4. Labels


`LabelSet` stores integer labels by point and name. It is used for boundaries,
regions, material IDs, imported mesh tags, and selecting submeshes.

Key methods:

- `set_label(point, name, value)`
- `get_label(point, name)`
- `stratum_points(name, value)`
- `stratum_values(name)`
- `stratum_points_in_range(name, range)`
- `stratum_union`, `stratum_intersection`, `stratum_difference`
- `propagate_label_set_closure`, `propagate_label_set_star`

```rust
use mesh_sieve::topology::labels::LabelSet;
use mesh_sieve::topology::point::PointId;

fn main() -> Result<(), mesh_sieve::mesh_error::MeshSieveError> {
    let wall = PointId::new(11)?;

    let mut labels = LabelSet::new();
    labels.set_label(wall, "boundary", 1);

    assert_eq!(labels.get_label(wall, "boundary"), Some(1));
    assert_eq!(labels.stratum_points("boundary", 1), vec![wall]);
    Ok(())
}
```

## 5. Atlas and Section


`Atlas` is layout only. It maps each point to a contiguous slice in a flat data
buffer.

Key `Atlas` methods:

- `try_insert(point, len) -> Result<offset, MeshSieveError>`
- `get(point) -> Option<(offset, len)>`
- `contains(point)`
- `remove_point(point)`
- `points()`, `iter_entries()`, `iter_spans()`
- `total_len()`, `len()`, `is_empty()`
- `version()`, `build_scatter_plan()`

`Section<V, S>` couples an atlas with storage. The storage bound is
`data::storage::Storage<V>`. `VecStorage<V>` is the normal CPU backend and
`CpuSection<V>` is the crate alias for `Section<V, VecStorage<V>>`.

Key `Section` methods:

- `new(atlas)`
- `atlas()`
- `try_restrict(point) -> Result<&[V], MeshSieveError>`
- `try_restrict_mut(point) -> Result<&mut [V], MeshSieveError>`
- `try_set(point, values)`
- `try_add_point(point, len)`
- `try_remove_point(point)`
- `with_atlas_mut(|atlas| ...)`
- `with_atlas_resize(policy, |atlas| ...)`
- `try_apply_delta_between_points(src, dst, delta)`
- `gather_in_order()`
- `try_scatter_in_order(buf)`
- `try_scatter_from(buf, spans)`
- `try_scatter_with_plan(buf, plan)`

```rust
use mesh_sieve::data::atlas::Atlas;
use mesh_sieve::data::section::Section;
use mesh_sieve::data::storage::VecStorage;
use mesh_sieve::topology::point::PointId;

fn main() -> Result<(), mesh_sieve::mesh_error::MeshSieveError> {
    let p = PointId::new(7)?;

    let mut atlas = Atlas::default();
    atlas.try_insert(p, 3)?;

    let mut section = Section::<f64, VecStorage<f64>>::new(atlas);
    section.try_set(p, &[1.0, 2.0, 3.0])?;

    assert_eq!(section.try_restrict(p)?, &[1.0, 2.0, 3.0]);
    Ok(())
}
```

### Layout Mutation


Use `with_atlas_mut` when existing points keep their slice lengths. If an
existing point changes length, the mutation is rolled back and returns
`MeshSieveError::AtlasPointLengthChanged`.

Use `with_atlas_resize` when length changes are intentional:

```rust
use mesh_sieve::data::atlas::Atlas;
use mesh_sieve::data::section::{ResizePolicy, Section};
use mesh_sieve::data::storage::VecStorage;
use mesh_sieve::topology::point::PointId;

fn main() -> Result<(), mesh_sieve::mesh_error::MeshSieveError> {
    let p = PointId::new(7)?;
    let q = PointId::new(8)?;

    let mut atlas = Atlas::default();
    atlas.try_insert(p, 2)?;

    let mut section = Section::<f64, VecStorage<f64>>::new(atlas);
    section.try_set(p, &[1.0, 2.0])?;

    section.with_atlas_resize(ResizePolicy::PreservePrefix, |atlas| {
        let _ = atlas.try_insert(q, 3);
    })?;

    Ok(())
}
```

Available resize policies:

- `ZeroInit`
- `PreservePrefix`
- `PreserveSuffix`
- `PadWith(value)`

### Storage Traits


`Storage<V>` provides the storage interface used by `Section`: construction by
length, resize, immutable/mutable flat slices, and delta/scatter helpers.

`SliceStorage<V>` is a lower-level trait implemented by `VecStorage` and, when
enabled, `WgpuStorage`. Most users should program against `Section<V, S>` and
`Storage<V>` rather than using `SliceStorage` directly.

## 6. Deltas


There are two delta concepts:

- `data::refine::delta::SliceDelta<V>` transforms one slice into another. It is
  used by section-internal copy/refine paths and by `Polarity`.
- `overlap::delta::ValueDelta<V>` restricts and fuses individual values for
  exchange across overlaps. Built-ins include `CopyDelta`, `AddDelta`,
  `ZeroDelta`, and `CellTypeDelta`.

`Delta` aliases may still exist for compatibility, but new code should use
`SliceDelta` and `ValueDelta` by name.

## 7. Coordinates and Geometry Data


`Coordinates<V, S>` wraps a section and validates that every point has exactly
`embedding_dimension` values. It also records the mesh topological dimension.

Related types:

- `Coordinates<V, S>`
- `CpuCoordinates<V>`
- `HighOrderCoordinates<V, S>`
- `MeshVelocity<V, S>`
- `CoordinateDM<V, S>`

```rust
use mesh_sieve::data::atlas::Atlas;
use mesh_sieve::data::coordinates::{Coordinates, HighOrderCoordinates};
use mesh_sieve::data::storage::VecStorage;
use mesh_sieve::topology::point::PointId;

fn main() -> Result<(), mesh_sieve::mesh_error::MeshSieveError> {
    let p = PointId::new(1)?;

    let mut atlas = Atlas::default();
    atlas.try_insert(p, 3)?;

    let mut coords = Coordinates::<f64, VecStorage<f64>>::try_new(2, 3, atlas)?;
    coords.try_restrict_mut(p)?.copy_from_slice(&[0.0, 1.0, 0.0]);

    let mut ho_atlas = Atlas::default();
    ho_atlas.try_insert(p, 9)?;
    let high_order = HighOrderCoordinates::<f64, VecStorage<f64>>::try_new(3, ho_atlas)?;
    coords.set_high_order(high_order)?;

    Ok(())
}
```

Geometry and physics helpers live in:

- `geometry::metrics`
- `geometry::quality`
- `geometry::locate`
- `geometry::fvm`
- `physics::fe`
- `physics::fvm`
- `discretization::runtime`

See [docs/geometry-quality.md](docs/geometry-quality.md) and
[Physics_Guide.md](Physics_Guide.md).

## 8. Discretization and Section Layouts


There are two related but separate API areas:

- `data::discretization`: basis and quadrature metadata keyed by regions.
- `data::section_layout`: DOF layout construction helpers.

`Discretization` stores named `FieldDiscretization` records. Each field maps a
`RegionKey` to `DiscretizationMetadata`.

```rust
use mesh_sieve::data::discretization::{
    Discretization, DiscretizationMetadata, FieldDiscretization,
};
use mesh_sieve::topology::cell_type::CellType;

let mut fields = Discretization::new();

let tri_p1 = DiscretizationMetadata::new("lagrange", "gauss")
    .with_basis_metadata(1, ["phi0", "phi1", "phi2"])
    .with_quadrature_metadata(
        2,
        vec![vec![1.0 / 3.0, 1.0 / 3.0]],
        vec![0.5],
    );

let mut velocity = FieldDiscretization::new();
velocity.set_cell_type_metadata(CellType::Triangle, tri_p1);
velocity.set_label_metadata(
    "fluid",
    1,
    DiscretizationMetadata::new("lagrange", "gauss"),
);

fields.insert_field("velocity", velocity);
```

For actual DOF vector layouts, use `data::section_layout` helpers such as
`DofLayout`, `build_layout_with`, `layout_for_section_with_constraints_and_periodic`,
`layout_for_multi_section_with_periodic`, `local_vector_for_section`, and
`local_vector_for_layout`.

## 9. Constraints and Multi-Field Data


`ConstrainedSection<V, S>` wraps a section and stores fixed DOF values by point
and component. It is useful for Dirichlet-style constraints.

```rust
use mesh_sieve::data::atlas::Atlas;
use mesh_sieve::data::constrained_section::ConstrainedSection;
use mesh_sieve::data::section::Section;
use mesh_sieve::data::storage::VecStorage;
use mesh_sieve::topology::point::PointId;

fn main() -> Result<(), mesh_sieve::mesh_error::MeshSieveError> {
    let p = PointId::new(7)?;

    let mut atlas = Atlas::default();
    atlas.try_insert(p, 3)?;

    let section = Section::<f64, VecStorage<f64>>::new(atlas);
    let mut constrained = ConstrainedSection::new(section);

    constrained.insert_constraint(p, 2, 0.0)?;
    constrained.apply_constraints()?;

    Ok(())
}
```

`MultiSection<V, S>` stacks multiple named `FieldSection<V, S>` values and
computes field offsets/spans for a point:

- `FieldSection::new(name, section)`
- `FieldSection::insert_constraint(point, index, value)`
- `MultiSection::new(fields)`
- `field_offset(point, field_index)`
- `field_span(point, field_index)`
- `field_offset_by_name(point, name)`
- `apply_constraints()`

```rust
use mesh_sieve::data::atlas::Atlas;
use mesh_sieve::data::multi_section::{FieldSection, MultiSection};
use mesh_sieve::data::section::Section;
use mesh_sieve::data::storage::VecStorage;
use mesh_sieve::topology::point::PointId;

fn main() -> Result<(), mesh_sieve::mesh_error::MeshSieveError> {
    let p = PointId::new(7)?;

    let mut atlas = Atlas::default();
    atlas.try_insert(p, 3)?;

    let velocity = Section::<f64, VecStorage<f64>>::new(atlas.clone());
    let pressure = Section::<f64, VecStorage<f64>>::new(atlas);

    let fields = vec![
        FieldSection::new("velocity", velocity),
        FieldSection::new("pressure", pressure),
    ];

    let multi = MultiSection::new(fields)?;
    let (_offset, dof_count) = multi.field_span(p, 0)?;
    assert_eq!(dof_count, 3);

    Ok(())
}
```

Hanging-node constraints are available through `HangingNodeConstraints`,
`HangingDofConstraint`, `LinearConstraintTerm`,
`constraints_from_topological_anchors`, and `apply_hanging_constraints_to_section`.

## 10. Mixed Scalar Sections


`MixedSectionStore` keeps named sections with different scalar types. Supported
scalar tags are `f64`, `f32`, `i32`, `i64`, `u32`, and `u64`.

```rust
use mesh_sieve::data::atlas::Atlas;
use mesh_sieve::data::mixed_section::MixedSectionStore;
use mesh_sieve::data::section::Section;
use mesh_sieve::data::storage::VecStorage;

let atlas = Atlas::default();

let mut store = MixedSectionStore::new();
store.insert("temperature", Section::<f64, VecStorage<f64>>::new(atlas.clone()));
store.insert("material_id", Section::<i32, VecStorage<i32>>::new(atlas));

let temp = store.get::<f64>("temperature");
assert!(temp.is_some());
```

Use `get_tagged`, `iter`, `gather_in_order`, and `try_scatter_in_order` when
the scalar type is not known statically.

## 11. Bundles, Refinement, and Assembly


`Bundle<V, S, D>` combines:

- `stack: InMemoryStack<PointId, PointId, Polarity>`
- `section: Section<V, S>`
- `delta: D`

`Bundle::refine(bases)` pushes data from base points to cap points using stack
orientation. `Bundle::assemble_with(bases, reducer)` pulls cap slices back to
base slices using a reducer such as `AverageReducer`.

Common APIs:

- `refine(bases)`
- `refine_with_constraints(bases, constraints)`
- `assemble(bases)`
- `assemble_with(bases, reducer)`
- `assemble_with_constraints(bases, reducer, constraints)`
- `apply_constraints(constraints)`

Reducers implement `SliceReducer<V>`. `AverageReducer` is the default reducer
used by `assemble`.

## 12. Overlap


`Overlap` stores local point sharing with remote ranks. Internally it is a
bipartite graph between local points and `Part(rank)` nodes, with a
`Remote { rank, remote_point }` payload.

Key APIs:

- `add_link_structural_one(local, rank)`
- `try_add_link_structural_one(local, rank)`
- `add_links_structural_bulk(iter)` and `try_add_links_structural_bulk(iter)`
- `resolve_remote_point(local, rank, remote)`
- `resolve_remote_points(iter)`
- `neighbor_ranks()`
- `links_to(rank)`
- `links_to_resolved(rank)`
- `links_to_sorted(rank)`
- `links_to_resolved_sorted(rank)`
- `remove_neighbor_rank(rank)`
- `retain_neighbor_ranks(keep)`
- `prune_empty_parts()`
- `validate_invariants()`

```rust
use mesh_sieve::overlap::overlap::Overlap;
use mesh_sieve::topology::point::PointId;

fn main() -> Result<(), mesh_sieve::mesh_error::MeshSieveError> {
    let local = PointId::new(42)?;
    let remote = PointId::new(42042)?;

    let mut overlap = Overlap::default();
    overlap.add_link_structural_one(local, 1);
    overlap.resolve_remote_point(local, 1, remote)?;

    let links: Vec<_> = overlap.links_to_resolved(1).collect();
    assert_eq!(links, vec![(local, remote)]);
    Ok(())
}
```

Use completion helpers such as `ensure_closure_of_support`,
`ensure_closure_of_support_from_seeds`, and `expand_one_layer_mesh` to grow
overlap along topology. After deleting links or recomputing neighbor sets, call
`prune_empty_parts()` if you use the `check-empty-part` invariant feature.

## 13. Communication and Distribution


`algs::communicator::Communicator` is the byte-oriented communication trait.
Implementations include:

- `NoComm`: serial/no-op communicator.
- `RayonComm`: available with `rayon`.
- `MpiComm`: available with `mpi-support`.

Important communicator operations:

- `isend(peer, tag, bytes)`
- `irecv(peer, tag, buffer)`
- `rank()`, `size()`
- `barrier()`
- `broadcast(root, buffer)`
- `allreduce_sum(values)`

Higher-level distribution and PETSc-SF-style APIs live in:

- `algs::point_sf`
- `algs::distribute`
- `algs::completion`
- `algs::assembly`

Selected exports:

- `PointSF`, `PointSfLeaf`, `RemotePoint`, `SfDistribution`
- `create_point_sf`, `create_process_sf`, `create_migration_sf`
- `distribute_topology`, `distribute_section`, `distribute_labels`,
  `distribute_field`
- `DistributionConfig`, `ProvidedPartition`, `CustomPartitioner`
- `distribute_mesh`, `distribute_with_overlap`,
  `distribute_with_overlap_periodic`
- `complete_sieve`, `complete_sieve_with_tags`,
  `complete_sieve_until_converged`
- `complete_section`, `complete_section_with_ownership`,
  `complete_section_with_tags`, `complete_section_with_tags_and_ownership`
- `complete_stack`, `complete_stack_with_tags`

MPI examples usually need an MPI launcher:

```sh
mpirun -n 2 cargo run --features mpi-support --example mpi_complete
```

## 14. Partitioning


The crate has two partitioning surfaces:

- `algs::partition` and `algs::metis_partition` for algorithm-level helpers.
- `partitioning` for MPI-gated in-tree partitioning algorithms and metrics.

`metis-support` enables the vendored METIS bindings. The `partitioning` module is compiled
with `mpi-support`.

Related APIs and examples:

- `algs::dual_graph`
- `algs::adjacency_graph`
- `algs::rcm::distributed_rcm`
- `partitioning::{partition, PartitionerConfig}` when `mpi-support` is enabled
- examples `partition.rs`, `distributed_rcm.rs`, and `mpi_partition_exchange.rs`

## 15. Mesh Containers and I/O


`io::MeshData<S, V, St, CtSt>` is the common container returned by readers:

- `sieve`
- `coordinates`
- `sections`
- `mixed_sections`
- `labels`
- `cell_types`
- `discretization`

Readers and writers use:

- `SieveSectionReader`
- `SieveSectionWriter`

Available format modules:

- `io::gmsh`
- `io::vtk`
- `io::ply`
- `io::fluent`
- `io::exodus`
- `io::xdmf`
- `io::hdf5`
- `io::petsc_hdf5`
- `io::partitioned`
- `io::bundle`
- `io::cgns` with `cgns`

```rust
use mesh_sieve::data::section::Section;
use mesh_sieve::data::storage::VecStorage;
use mesh_sieve::io::MeshData;
use mesh_sieve::topology::cell_type::CellType;
use mesh_sieve::topology::point::PointId;
use mesh_sieve::topology::sieve::InMemorySieve;

let sieve = InMemorySieve::<PointId, ()>::default();
let mut mesh: MeshData<_, f64, VecStorage<f64>, VecStorage<CellType>> = MeshData::new(sieve);
mesh.sections
    .insert("temperature".to_string(), Section::new(Default::default()));
```

`MeshBundle` stores multiple `MeshData` values and can synchronize labels or
coordinates across them with `sync_labels()` and `sync_coordinates()`.

See:

- [docs/io-format-capabilities.md]docs/io-format-capabilities.md
- [docs/hdf5-layout.md]docs/hdf5-layout.md
- [docs/exodus.md]docs/exodus.md

## 16. MeshDM


`MeshDM` is a higher-level DMPlex-like facade. It coordinates topology,
coordinates, labels, named sections, distribution metadata, and solver
preallocation workflows.

Commonly used exported types:

- `MeshDM`
- `MeshDMBuilder`
- `MeshDMOptions`
- `MeshDMDistribution`
- `MeshDMLabelSelection`
- `MeshDMSubmesh`
- `MeshPointChart`
- `MeshVector`
- `MeshVectorInsertMode`
- `PreallocationGraph`

Use `MeshDM` when you want one object to manage a mesh workflow end to end. Use
the lower-level `Sieve`, `Atlas`, `Section`, `Coordinates`, and `LabelSet` APIs
when you need direct control over topology and data layout.

The facade includes DMPlex-style point-chart, cone/support, height/depth, and
transitive-closure queries. `create_section_from_depth()` builds a named local
section from per-depth DOF counts, with a label-restricted variant for field
support. Local vectors created by `create_local_vector()` support oriented
closure gather and insert/add operations through `get_local_vector_closure()`
and `set_local_vector_closure()`.

## 17. Algorithms Overview


The `algs` module re-exports the main mesh algorithms:

- `meshgen`: mesh generation helpers.
- `interpolate`: topology interpolation.
- `extrude`: boundary and mesh extrusion workflows.
- `boundary`: boundary classification and label creation.
- `submesh`: submesh extraction.
- `transform`: coordinate transforms.
- `field_transfer`: nearest-point, nearest-cell, refinement-map, and
  label-based transfers.
- `renumber`: point renumbering and stratified permutations.
- `rcm`: reverse Cuthill-McKee ordering, including distributed paths.
- `reduction`: reductions over mesh data.
- `wire`: wire encoding utilities for communication.

Use the examples directory for complete workflows:

- `meshgen_basic.rs`
- `gmsh_io.rs`
- `gmsh_interpolate_quality.rs`
- `poisson_segment.rs`
- `poisson_quad.rs`
- `refine_triangle.rs`
- `adapt_with_metric.rs`
- `dm_metric_label_adapt.rs`
- `distribute_with_overlap.rs`
- `periodic_2d_wrap.rs`
- `e2e_showcase.rs`
- `external_mesh_workflows.rs`
- `comprehensive_mesh_workflow.rs`
- `extrude_boundary_constraints.rs`

## 18. WGPU Storage


With `--features wgpu`, `data::WgpuStorage<V>` is available for `V:
bytemuck::Pod + bytemuck::Zeroable + Send + Sync + 'static`.

The WGPU backend implements the lower-level slice storage operations used by
sections: GPU buffer allocation, host staging reads/writes, forward copy,
temporary-buffer copy for overlapping ranges, and a reverse-copy compute path
for `Polarity::Reverse`.

This backend is optional and lower-level than normal `VecStorage` use. Most
code should remain generic over `Section<V, S>` and `Storage<V>`, using
`VecStorage` unless a workflow explicitly needs GPU-backed storage.

## 18.1 CUDA Execution Plans

With `--features cuda`, the `accelerator` module exposes explicit device
buffers and immutable execution plans rather than a CUDA-backed `Section`.
`DeviceFvmOperator` combines a `DeviceFvmPlan`, `FiniteVolumeMetadata`, scheme
settings, standard boundary coefficients, and least-squares weights.
`DeviceFvmState::upload_components` uses component-major storage and retains
all flux, gradient, source, and residual workspaces across evaluations.

Use `DeviceReduction` for resident sum, dot, L2, and maximum-absolute-value
reductions. `DeviceCsrMatrix` validates symbolic/global CSR patterns and offers
CPU SpMV; enable `cuda-cusparse` for CUDA SpMV. CUDA stream events are exposed
through `CudaBackend::{record_event,wait_event,synchronize_event,elapsed_ms}`.

## 19. Error Model


Most public operations return `Result<_, MeshSieveError>`.

Common error families:

- Point and topology: invalid point IDs, missing points, duplicate points,
  cyclic topology, invalid strata.
- Atlas and section: zero-length slices, missing atlas points, slice length
  mismatches, stale scatter plans, changed atlas lengths.
- Constraints: constraint index out of bounds.
- Tags and mixed sections: missing section names or scalar type mismatch.
- Geometry: invalid dimensions and geometry validation failures.
- Overlap: non-bipartite links, rank mismatches, duplicate overlap edges, empty
  parts when that check is enabled, strict mirror mismatches.
- Communication and I/O: backend-specific communication, parsing, and format
  errors.

Use the exact error variants in `mesh_error.rs` when matching errors in tests.
Deprecated compatibility variants may still exist; new code should match the
current non-deprecated variants.

## 20. Testing Recommendations


At minimum:

```sh
cargo test
cargo test --features strict-invariants
```

Useful feature lanes:

```sh
cargo test --features rayon
cargo test --features cgns
cargo test --features wgpu
cargo test --features mpi-support
```

For API-level tests, cover:

- atlas and section invariants after insertion, removal, scatter, and resize
- missing-point and length-mismatch errors
- deterministic traversal or sorted traversal where output order matters
- label propagation through closure/star
- overlap mirror validation under `strict-invariants`
- serial versus Rayon or MPI parity where feature-gated paths are used

## 21. Quick Reference


| Area | Main APIs |
| --- | --- |
| Points | `PointId::new`, `PointId::get` |
| Topology | `Sieve`, `InMemorySieve`, `InMemoryOrientedSieve`, `MeshSieve`, `FrozenSieveCsr` |
| Traversal | `cone`, `support`, `closure_iter`, `star_iter`, `points_chart_order` |
| Labels | `LabelSet`, `stratum_points`, `stratum_values`, label propagation helpers |
| Data layout | `Atlas`, `Section`, `CpuSection`, `VecStorage`, `Storage` |
| Layout mutation | `with_atlas_mut`, `with_atlas_resize`, `ResizePolicy` |
| Coordinates | `Coordinates`, `HighOrderCoordinates`, `MeshVelocity`, `CoordinateDM` |
| Discretization | `Discretization`, `FieldDiscretization`, `DiscretizationMetadata`, `RegionKey` |
| DOF layouts | `DofLayout`, `build_layout_with`, section layout helpers |
| Constraints | `ConstrainedSection`, `ConstraintSet`, hanging-node constraints |
| Multi-field data | `FieldSection`, `MultiSection` |
| Mixed scalar data | `MixedSectionStore`, `TaggedSection`, `TaggedSectionBuffer`, `ScalarType` |
| Refinement workflow | `Bundle`, `SliceReducer`, `AverageReducer`, `Polarity` |
| Overlap | `Overlap`, `Remote`, `CopyDelta`, `AddDelta`, `ZeroDelta` |
| Communication | `Communicator`, `NoComm`, `RayonComm`, `MpiComm` |
| Distribution | `PointSF`, `distribute_topology`, `distribute_section`, `distribute_with_overlap` |
| Completion | `complete_sieve`, `complete_section`, `complete_stack` |
| I/O | `MeshData`, `MeshBundle`, `SieveSectionReader`, `SieveSectionWriter` |
| Facade | `MeshDM`, `MeshDMBuilder`, `MeshDMOptions` |

## 22. Additional Documentation


- [README.md]README.md
- [Physics_Guide.md]Physics_Guide.md
- [docs/topology-api.md]docs/topology-api.md
- [docs/fe-setup.md]docs/fe-setup.md
- [docs/geometry-quality.md]docs/geometry-quality.md
- [docs/io-format-capabilities.md]docs/io-format-capabilities.md
- [docs/hdf5-layout.md]docs/hdf5-layout.md
- [docs/exodus.md]docs/exodus.md
- [docs/coastal-mesh-labels.md]docs/coastal-mesh-labels.md