0
# Boundary Conditions
1
2
Boundary condition system supporting Dirichlet, Neumann, mixed, and periodic conditions with expression-based inhomogeneous boundaries for precise control of field behavior at domain edges.
3
4
## Capabilities
5
6
### Dirichlet Boundary Conditions
7
8
Impose specific values at boundaries.
9
10
```python { .api }
11
class DirichletBC:
12
def __init__(self, value, *, rank=0):
13
"""
14
Initialize Dirichlet boundary condition.
15
16
Parameters:
17
- value: float, str, array, or callable, boundary value
18
- rank: int, tensor rank of the field (0=scalar, 1=vector, 2=tensor)
19
"""
20
21
@property
22
def value(self):
23
"""Boundary value specification"""
24
25
def get_data(self, grid, *, derivatives=False):
26
"""
27
Get boundary data for given grid.
28
29
Parameters:
30
- grid: GridBase, spatial grid
31
- derivatives: bool, whether to return derivative information
32
33
Returns:
34
array-like: Boundary values
35
"""
36
```
37
38
### Neumann Boundary Conditions
39
40
Impose specific normal derivatives at boundaries.
41
42
```python { .api }
43
class NeumannBC:
44
def __init__(self, value, *, rank=0):
45
"""
46
Initialize Neumann boundary condition.
47
48
Parameters:
49
- value: float, str, array, or callable, normal derivative value
50
- rank: int, tensor rank of the field
51
"""
52
53
def get_virtual_point_data(self, grid):
54
"""
55
Get data for virtual points beyond boundary.
56
57
Parameters:
58
- grid: GridBase, spatial grid
59
60
Returns:
61
array-like: Virtual point values
62
"""
63
```
64
65
### Mixed Boundary Conditions
66
67
Impose linear combinations of field values and derivatives.
68
69
```python { .api }
70
class MixedBC:
71
def __init__(self, value, const, *, rank=0):
72
"""
73
Initialize mixed boundary condition: ∂ₙf + value·f = const
74
75
Parameters:
76
- value: float, str, array, or callable, coefficient for field value
77
- const: float, str, array, or callable, constant term
78
- rank: int, tensor rank of the field
79
"""
80
81
@property
82
def value(self):
83
"""Coefficient for field value"""
84
85
@property
86
def const(self):
87
"""Constant term in boundary condition"""
88
```
89
90
### Curvature Boundary Conditions
91
92
Impose specific second derivatives (curvature) at boundaries.
93
94
```python { .api }
95
class CurvatureBC:
96
def __init__(self, value, *, rank=0):
97
"""
98
Initialize curvature boundary condition.
99
100
Parameters:
101
- value: float, str, array, or callable, second derivative value
102
- rank: int, tensor rank of the field
103
"""
104
```
105
106
### Normal Component Boundary Conditions
107
108
Boundary conditions affecting only the normal component of vector/tensor fields.
109
110
```python { .api }
111
class NormalDirichletBC:
112
def __init__(self, value):
113
"""
114
Dirichlet condition for normal component only.
115
116
Parameters:
117
- value: float, str, array, or callable, normal component value
118
"""
119
120
class NormalNeumannBC:
121
def __init__(self, value):
122
"""
123
Neumann condition for normal component only.
124
125
Parameters:
126
- value: float, str, array, or callable, normal derivative value
127
"""
128
129
class NormalMixedBC:
130
def __init__(self, value, const):
131
"""
132
Mixed condition for normal component only.
133
134
Parameters:
135
- value: float, coefficient for normal component
136
- const: float, constant term
137
"""
138
139
class NormalCurvatureBC:
140
def __init__(self, value):
141
"""
142
Curvature condition for normal component only.
143
144
Parameters:
145
- value: float, second derivative of normal component
146
"""
147
```
148
149
### Expression-Based Boundary Conditions
150
151
Use mathematical expressions for inhomogeneous boundary conditions.
152
153
```python { .api }
154
class ExpressionValueBC:
155
def __init__(self, expression, *, rank=0):
156
"""
157
Dirichlet condition with expression-based values.
158
159
Parameters:
160
- expression: str or callable, mathematical expression
161
- rank: int, tensor rank of the field
162
"""
163
164
def get_value(self, coordinates):
165
"""
166
Evaluate expression at coordinates.
167
168
Parameters:
169
- coordinates: array-like, boundary coordinates
170
171
Returns:
172
array-like: Expression values
173
"""
174
175
class ExpressionDerivativeBC:
176
def __init__(self, expression, *, rank=0):
177
"""
178
Neumann condition with expression-based derivatives.
179
180
Parameters:
181
- expression: str or callable, derivative expression
182
- rank: int, tensor rank of the field
183
"""
184
185
class ExpressionMixedBC:
186
def __init__(self, value_expr, const_expr, *, rank=0):
187
"""
188
Mixed condition with expression-based coefficients.
189
190
Parameters:
191
- value_expr: str or callable, coefficient expression
192
- const_expr: str or callable, constant expression
193
- rank: int, tensor rank of the field
194
"""
195
```
196
197
### Boundary Management
198
199
Classes for organizing boundary conditions across grid axes.
200
201
```python { .api }
202
class BoundariesList:
203
def __init__(self, boundaries):
204
"""
205
Initialize boundaries for all grid axes.
206
207
Parameters:
208
- boundaries: list or dict, boundary conditions per axis
209
"""
210
211
def __getitem__(self, axis):
212
"""Get boundary condition for specific axis"""
213
214
def copy(self):
215
"""
216
Create copy of boundary list.
217
218
Returns:
219
BoundariesList: Copy of boundaries
220
"""
221
222
def check_value_rank(self, rank):
223
"""
224
Check compatibility with field rank.
225
226
Parameters:
227
- rank: int, tensor rank to check
228
229
Raises:
230
ValueError: If incompatible
231
"""
232
233
class BoundaryPair:
234
def __init__(self, lower, upper):
235
"""
236
Pair of boundary conditions for opposite sides of an axis.
237
238
Parameters:
239
- lower: boundary condition for lower side
240
- upper: boundary condition for upper side
241
"""
242
243
@property
244
def lower(self):
245
"""Lower boundary condition"""
246
247
@property
248
def upper(self):
249
"""Upper boundary condition"""
250
251
class BoundaryPeriodic:
252
def __init__(self):
253
"""
254
Periodic boundary conditions for an axis.
255
"""
256
257
def check_value_rank(self, rank):
258
"""
259
Check compatibility with field rank.
260
261
Parameters:
262
- rank: int, tensor rank to check
263
"""
264
265
class BoundariesSetter:
266
def __init__(self, setter_func):
267
"""
268
Custom function for setting boundary conditions.
269
270
Parameters:
271
- setter_func: callable, function that sets boundary values
272
"""
273
274
def set_ghost_cells(self, data_full, *, args=None):
275
"""
276
Set ghost cell values using custom function.
277
278
Parameters:
279
- data_full: array, field data including ghost cells
280
- args: additional arguments for setter function
281
"""
282
283
def set_default_bc(bc):
284
"""
285
Set default boundary conditions for the package.
286
287
Parameters:
288
- bc: boundary condition specification
289
"""
290
```
291
292
### Boundary Condition Registry
293
294
Functions for discovering available boundary condition types.
295
296
```python { .api }
297
def registered_boundary_condition_classes():
298
"""
299
Get all registered boundary condition classes.
300
301
Returns:
302
dict: Mapping of names to boundary condition classes
303
"""
304
305
def registered_boundary_condition_names():
306
"""
307
Get names of all registered boundary conditions.
308
309
Returns:
310
list of str: Boundary condition names
311
"""
312
```
313
314
## Usage Examples
315
316
### Basic Boundary Conditions
317
318
```python
319
import pde
320
321
# Create grid and field
322
grid = pde.CartesianGrid([[0, 10], [0, 5]], [64, 32])
323
field = pde.ScalarField.random_uniform(grid)
324
325
# Simple Dirichlet boundaries
326
bc_dirichlet = {"value": 1.0}
327
328
# Simple Neumann boundaries
329
bc_neumann = {"derivative": 0.0}
330
331
# Apply Laplacian with different boundary conditions
332
laplace_dirichlet = field.laplace(bc_dirichlet)
333
laplace_neumann = field.laplace(bc_neumann)
334
335
print("Boundary conditions applied successfully")
336
```
337
338
### Axis-Specific Boundary Conditions
339
340
```python
341
import pde
342
343
grid = pde.CartesianGrid([[-1, 1], [0, 2]], [32, 16])
344
field = pde.ScalarField.random_uniform(grid)
345
346
# Different conditions for each axis
347
bc = {
348
"x": "periodic", # Periodic in x-direction
349
"y-": {"value": 0}, # Dirichlet at bottom
350
"y+": {"derivative": -1} # Neumann at top
351
}
352
353
result = field.laplace(bc)
354
print(f"Applied mixed boundary conditions")
355
```
356
357
### Expression-Based Inhomogeneous Boundaries
358
359
```python
360
import pde
361
362
grid = pde.CartesianGrid([[0, 2*3.14159], [0, 1]], [64, 32])
363
field = pde.ScalarField.random_uniform(grid)
364
365
# Sinusoidal boundary conditions
366
bc = {
367
"x": "periodic",
368
"y-": {"value": "sin(x)"}, # Sin function at bottom
369
"y+": {"derivative": "cos(x)"} # Cosine derivative at top
370
}
371
372
result = field.laplace(bc)
373
print("Applied expression-based boundaries")
374
```
375
376
### Mixed Boundary Conditions
377
378
```python
379
import pde
380
381
grid = pde.UnitGrid([64], periodic=False)
382
field = pde.ScalarField.random_uniform(grid)
383
384
# Robin boundary condition: ∂ₙf + 2f = 5
385
bc = {
386
"left": {"type": "mixed", "value": 2, "const": 5},
387
"right": {"derivative": 0} # Neumann on right
388
}
389
390
result = field.laplace(bc)
391
print("Applied Robin boundary condition")
392
```
393
394
### Custom Boundary Function
395
396
```python
397
import pde
398
399
def custom_bc_setter(data, args=None):
400
"""Custom boundary condition setter function"""
401
# Set left boundary to average of interior
402
data[0] = data[1:3].mean()
403
404
# Set right boundary to reflect interior
405
data[-1] = 2 * data[-2] - data[-3]
406
407
grid = pde.UnitGrid([64], periodic=False)
408
field = pde.ScalarField.random_uniform(grid)
409
410
# Use custom function directly
411
result = field.laplace(custom_bc_setter)
412
print("Applied custom boundary function")
413
```
414
415
### Vector Field Boundary Conditions
416
417
```python
418
import pde
419
420
grid = pde.CartesianGrid([[-1, 1], [-1, 1]], [32, 32])
421
vector_field = pde.VectorField.random_uniform(grid)
422
423
# Normal component boundary conditions
424
bc_normal = {
425
"x": pde.NormalDirichletBC(0), # No-penetration
426
"y": pde.NormalNeumannBC(0) # Free-slip
427
}
428
429
# Apply to divergence calculation
430
div_result = vector_field.divergence(bc_normal)
431
print("Applied vector boundary conditions")
432
```
433
434
### Auto Boundary Conditions
435
436
```python
437
import pde
438
439
# Mixed periodic/non-periodic grid
440
grid = pde.CartesianGrid([[0, 10], [0, 5]], [64, 32], periodic=[True, False])
441
field = pde.ScalarField.random_uniform(grid)
442
443
# Automatic boundary condition selection
444
bc_auto = "auto_periodic_neumann" # Periodic where grid is periodic,
445
# Neumann elsewhere
446
447
result = field.laplace(bc_auto)
448
print("Applied automatic boundary conditions")
449
```