grid1d 0.2.0

A mathematically rigorous, type-safe Rust library for 1D grid operations and interval partitions, supporting both native and arbitrary-precision numerics.
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
# Grid1D Decision Guide

This guide helps you make informed choices about which grid types, scalar types, and features to use in your application.

## Quick Decision Trees

### ๐ŸŽฏ Which Grid Type Should I Use?

```
START: What kind of spacing do I need?
โ”‚
โ”œโ”€ Equal spacing everywhere?
โ”‚  โ””โ”€ โœ… Use Grid1DUniform
โ”‚     โ€ข O(1) point location
โ”‚     โ€ข Maximum performance
โ”‚     โ€ข Perfect for regular discretizations
โ”‚
โ”œโ”€ Custom/adaptive spacing?
โ”‚  โ””โ”€ โœ… Use Grid1DNonUniform
โ”‚     โ€ข O(log n) point location
โ”‚     โ€ข Flexible point distribution
โ”‚     โ€ข Ideal for boundary layers, shock capturing
โ”‚
โ””โ”€ Combining multiple grids?
   โ””โ”€ โœ… Use Grid1DUnion
      โ€ข Combines grids from different physics
      โ€ข Maintains mappings to original grids
      โ€ข For multi-physics simulations
```

### ๐Ÿ”ข Which Scalar Type Should I Use?

```
START: What are your priorities?
โ”‚
โ”œโ”€ Maximum performance, fully trusted inputs?
โ”‚  โ””โ”€ โœ… Use f64
โ”‚     โ€ข Zero overhead
โ”‚     โ€ข Standard IEEE 754
โ”‚     โ€ข โš ๏ธ  No validation - can propagate NaN/Inf
โ”‚
โ”œโ”€ Good performance + safety during development?
โ”‚  โ””โ”€ โœ… Use RealNative64StrictFiniteInDebug (โญ RECOMMENDED)
โ”‚     โ€ข Same as f64 in release builds
โ”‚     โ€ข Validates in debug builds
โ”‚     โ€ข Perfect development โ†’ production workflow
โ”‚
โ”œโ”€ Safety-critical application?
โ”‚  โ””โ”€ โœ… Use RealNative64StrictFinite
โ”‚     โ€ข Always validates (small overhead ~5-10%)
โ”‚     โ€ข Guaranteed finite values
โ”‚     โ€ข For medical, aerospace, financial
โ”‚
โ””โ”€ Need arbitrary precision?
   โ””โ”€ โœ… Use RealRugStrictFinite<N>
      โ€ข N-bit precision (e.g., 256, 512, 1024)
      โ€ข For scientific computing, symbolic math
      โ€ข Requires `--features=rug`
```

## Detailed Comparison Tables

### Grid Type Comparison

| Feature | Grid1DUniform | Grid1DNonUniform | Grid1DUnion |
|---------|--------------|------------------|-------------|
| **Point Location** | O(1) analytical | O(log n) binary search | O(log n) on unified grid |
| **Memory Usage** | 8n + 40 bytes | 8n + 40 bytes | 8(n+m) + overhead |
| **Construction** | O(n) | O(n) | O(n+m) |
| **Best For** | Regular meshes, FDM | Adaptive meshes, FEM | Multi-physics coupling |
| **Spacing** | Uniform | Arbitrary | Combined |
| **Flexibility** | Low | High | Very High |
| **Performance** | โšกโšกโšก Excellent | โšกโšก Good | โšกโšก Good |

*Where n = number of points, m = points in second grid*

### Scalar Type Comparison

| Scalar Type | Validation | Debug | Release | Use Case |
|-------------|-----------|--------|---------|----------|
| **f64** | โŒ None | โšกโšกโšก | โšกโšกโšก | Trusted inputs, maximum speed |
| **RealNative64StrictFiniteInDebug** | โœ… Debug only | โšกโšก | โšกโšกโšก | **Recommended default** |
| **RealNative64StrictFinite** | โœ… Always | โšกโšก | โšกโšก | Safety-critical |
| **RealRugStrictFinite\<N\>** | โœ… Always | โšก | โšก | Arbitrary precision |

### Interval Type Selection

| Mathematical Need | Interval Type | Notation | Use Case |
|------------------|---------------|----------|----------|
| Include both endpoints | `IntervalClosed` | [a, b] | Standard bounded domains |
| Exclude both endpoints | `IntervalOpen` | (a, b) | Open sets, strict inequalities |
| Include left, exclude right | `IntervalLowerClosedUpperOpen` | [a, b) | Periodic domains, half-open ranges |
| Include right, exclude left | `IntervalLowerOpenUpperClosed` | (a, b] | Asymmetric boundaries |
| Unbounded above | `IntervalLowerClosedUpperUnbounded` | [a, +โˆž) | Semi-infinite domains |
| Unbounded below | `IntervalLowerUnboundedUpperClosed` | (-โˆž, b] | Semi-infinite domains |
| Single point | `IntervalSingleton` | {a} | Degenerate intervals |

## Use Case โ†’ Recommended Configuration

### Finite Difference Methods (Regular Mesh)

**Scenario**: Solving PDEs on uniform grids

```rust
// Recommended configuration
type Real = RealNative64StrictFiniteInDebug;  // Debug safety
type Domain = IntervalClosed<Real>;            // Closed boundaries

let grid = Grid1D::uniform(
    Domain::new(Real::try_new(0.0).unwrap(), Real::try_new(1.0).unwrap()),
    NumIntervals::try_new(1000).unwrap()
);
```

**Why?**

- โœ… Uniform grid: O(1) point location for maximum performance
- โœ… Debug validation: Catches NaN/Inf during development
- โœ… Closed interval: Standard for boundary value problems
- โœ… Release performance: Same as raw f64

### Finite Element Methods (Adaptive Mesh)

**Scenario**: FEM with mesh refinement in regions of interest

```rust
// Recommended configuration
type Real = RealNative64StrictFinite;  // Always validated
type Domain = IntervalClosed<Real>;

// Start with coarse base mesh
let base_grid = Grid1D::uniform(/* ... */);

// Refine selectively where solution changes rapidly
let refined = base_grid.refine(&refinement_plan);
```

**Why?**

- โœ… Non-uniform capability: Supports adaptive refinement
- โœ… Always validated: Prevents propagation of numerical errors
- โœ… Refinement tracking: Maintains parent-child relationships
- โœ… Flexible spacing: Optimal resolution where needed

### Computational Fluid Dynamics (Boundary Layers)

**Scenario**: Viscous flow with wall boundary layers

```rust
// Recommended configuration
type Real = RealNative64StrictFiniteInDebug;
type Domain = IntervalClosed<Real>;

// Generate boundary layer mesh
let coords = create_boundary_layer_distribution(
    wall_thickness,
    num_boundary_points,
    stretching_ratio
);

let grid = Grid1D::try_from_sorted(
    Domain::new(/* ... */),
    SortedSet::from_unsorted(coords)
).unwrap();
```

**Why?**

- โœ… Non-uniform grid: Fine near wall, coarse in freestream
- โœ… Custom distribution: Precise control over point clustering
- โœ… Performance: Fast lookups even with non-uniform spacing

### Multi-Physics Coupling

**Scenario**: Coupling fluid flow with chemical reactions

```rust
// Recommended configuration
type Real = RealNative64StrictFinite;  // Safety for complex coupling

// Separate grids for each physics
let flow_grid = Grid1D::uniform(/* coarse global */);
let chemistry_grid = Grid1D::try_from_sorted(/* fine local */);

// Unified grid for data transfer
let coupled = Grid1DUnion::try_new(&flow_grid, &chemistry_grid).unwrap();

// Map between grids
for (unified_id, flow_id, chem_id) in coupled.iter_interval_mappings() {
    // Transfer data between physics
}
```

**Why?**

- โœ… Grid union: Preserves both discretizations
- โœ… Bidirectional mapping: Efficient data transfer
- โœ… Validated scalars: Prevents coupling instabilities

### High-Precision Scientific Computing

**Scenario**: Numerical analysis requiring exact arithmetic

```rust
#[cfg(feature = "rug")]
{
    // Recommended configuration
    type Real = RealRugStrictFinite<256>;  // 256-bit precision
    type Domain = IntervalClosed<Real>;
    
    let grid = Grid1D::uniform(
        Domain::new(
            Real::try_new(0.0).unwrap(),
            Real::try_new(1.0).unwrap()
        ),
        NumIntervals::try_new(100).unwrap()
    );
}
```

**Why?**

- โœ… Arbitrary precision: Eliminates rounding errors
- โœ… Validated: Maintains numerical integrity
- โœ… Same API: Easy to switch from f64

### Real-Time Applications

**Scenario**: Simulation loop with strict timing requirements

```rust
// Recommended configuration
type Real = f64;  // Maximum performance, no validation
type Domain = IntervalClosed<Real>;

let grid = Grid1D::uniform(
    Domain::new(0.0, 1.0),
    NumIntervals::try_new(1000).unwrap()
);

// In real-time loop
loop {
    // O(1) point location - predictable timing
    let interval_id = grid.find_interval_id_of_point(&sensor_value);
    // ... process ...
}
```

**Why?**

- โœ… Raw f64: Zero overhead, predictable performance
- โœ… Uniform grid: O(1) lookups, no branch prediction issues
- โœ… No validation: No runtime checks in critical path

## Performance Tuning Guidelines

### When to Choose Uniform Grid

โœ… **Choose uniform grid when:**

- All intervals need equal spacing
- Maximum performance is critical
- Simple, regular domain discretization
- Point location happens frequently

โŒ **Avoid uniform grid when:**

- Features occur at different scales
- Adaptive refinement is needed
- Boundary layer resolution required

### When to Choose Non-Uniform Grid

โœ… **Choose non-uniform grid when:**

- Adaptive spacing is beneficial
- Multiple length scales present
- Boundary layer capture needed
- Features localized in space

โŒ **Avoid non-uniform grid when:**

- Uniform spacing is sufficient
- Maximum performance is critical
- Simple regular problem

### When to Use Grid Union

โœ… **Use grid union when:**

- Coupling multiple physics
- Different solvers on different grids
- Need to preserve original grid structure
- Frequent data transfer between grids

โŒ **Avoid grid union when:**

- Single physics problem
- Don't need grid mapping
- Memory is constrained

## Scalar Type Performance Impact

### Benchmarked Overheads (relative to f64)

| Operation | f64 | RealNative64StrictFiniteInDebug (Debug) | RealNative64StrictFiniteInDebug (Release) | RealNative64StrictFinite |
|-----------|-----|----------------------------------------|-------------------------------------------|--------------------------|
| Arithmetic | 1.0ร— | 1.5-2.0ร— | 1.0ร— | 1.05-1.10ร— |
| Comparison | 1.0ร— | 1.3-1.5ร— | 1.0ร— | 1.02-1.05ร— |
| Grid creation | 1.0ร— | 1.5ร— | 1.0ร— | 1.10ร— |
| Point location | 1.0ร— | 1.2ร— | 1.0ร— | 1.05ร— |

**Key takeaway**: `RealNative64StrictFiniteInDebug` has zero overhead in release builds.

## Migration Strategies

### From f64 to Validated Types

**Step 1**: Start with raw f64

```rust
let grid = Grid1D::uniform(
    IntervalClosed::new(0.0_f64, 1.0_f64),
    NumIntervals::try_new(100).unwrap()
);
```

**Step 2**: Add debug validation (no code changes needed in release!)

```rust
type Real = RealNative64StrictFiniteInDebug;
let grid = Grid1D::uniform(
    IntervalClosed::new(
        Real::try_new(0.0).unwrap(),
        Real::try_new(1.0).unwrap()
    ),
    NumIntervals::try_new(100).unwrap()
);
```

**Step 3**: If safety-critical, use always-validated

```rust
type Real = RealNative64StrictFinite;
// Same code as Step 2
```

### From Uniform to Non-Uniform

**Before** (uniform):

```rust
let grid = Grid1D::uniform(domain, NumIntervals::try_new(100).unwrap());
```

**After** (non-uniform with custom spacing):

```rust
let coords = generate_custom_distribution();
let grid = Grid1D::try_from_sorted(domain, SortedSet::from_unsorted(coords)).unwrap();
```

## Common Pitfalls and Solutions

### Pitfall 1: Using Wrong Grid Type

โŒ **Wrong**:

```rust
// Using non-uniform grid when uniform would work
let coords: Vec<f64> = (0..=100).map(|i| i as f64 / 100.0).collect();
let grid = Grid1D::try_from_sorted(/* ... */).unwrap();  // Slow!
```

โœ… **Correct**:

```rust
// Use uniform grid for better performance
let grid = Grid1D::uniform(
    IntervalClosed::new(0.0, 1.0),
    NumIntervals::try_new(100).unwrap()
);
```

### Pitfall 2: Over-validating in Performance-Critical Code

โŒ **Wrong**:

```rust
type Real = RealNative64StrictFinite;  // Always validates

// In hot loop
for _ in 0..1_000_000 {
    let result = a + b;  // Validates every operation
}
```

โœ… **Correct**:

```rust
type Real = RealNative64StrictFiniteInDebug;  // Validates only in debug

// In hot loop - no overhead in release
for _ in 0..1_000_000 {
    let result = a + b;  // Fast in release
}
```

### Pitfall 3: Forgetting to Handle Errors

โŒ **Wrong**:

```rust
let grid = Grid1D::try_from_sorted(domain, coords).unwrap();  // Panics on error
```

โœ… **Correct**:

```rust
let grid = Grid1D::try_from_sorted(domain, coords)
    .map_err(|e| {
        eprintln!("Grid creation failed: {:?}", e);
        e
    })?;
```

## Summary Recommendations

### For Most Users (โญ Recommended)

```rust
use grid1d::{Grid1D, intervals::IntervalClosed, scalars::NumIntervals};
use num_valid::RealNative64StrictFiniteInDebug;
use try_create::TryNew;

type Real = RealNative64StrictFiniteInDebug;
type Domain = IntervalClosed<Real>;

// Uniform grid for regular problems
let grid = Grid1D::uniform(
    Domain::new(Real::try_new(0.0).unwrap(), Real::try_new(1.0).unwrap()),
    NumIntervals::try_new(100).unwrap()
);
```

**This gives you**:

- โœ… Maximum performance in release builds
- โœ… Safety validation during development
- โœ… O(1) point location for uniform grids
- โœ… Easy to change if needs evolve

### Quick Reference Card

| Need | Use |
|------|-----|
| Regular mesh, maximum speed | `Grid1DUniform` + `f64` |
| **Most applications** | **`Grid1DUniform` + `RealNative64StrictFiniteInDebug`** |
| Adaptive mesh | `Grid1DNonUniform` + `RealNative64StrictFiniteInDebug` |
| Safety-critical | Any grid + `RealNative64StrictFinite` |
| Multi-physics | `Grid1DUnion` + `RealNative64StrictFinite` |
| High precision | Any grid + `RealRugStrictFinite<N>` |
| Periodic domains | Any grid + `IntervalLowerClosedUpperOpen` |

---

For more details, see:

- [Complete Tutorial]./TUTORIAL.md
- [API Documentation]https://docs.rs/grid1d
- [README]./README.md