Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
580fcf6525 |
@@ -125,8 +125,8 @@ with CudaContext(0) as ctx, FixedPatchStepper(cfg, context=ctx, refinements=[(8,
|
||||
|
||||
Scope and limits:
|
||||
- The examples below use D2Q9, SRT, FP32, double buffer, unshifted, no LES or
|
||||
forcing. Fixed 2:1 hierarchies can use level lists of arbitrary depth; the
|
||||
legacy two/three-level forms are shown below.
|
||||
forcing. Fixed 2:1 hierarchies use level lists of arbitrary depth; two- and
|
||||
three-level examples below use that same constructor.
|
||||
- `coarse_boundary="periodic"` (default) or `"slot_reservoir"` (bottom slot, top
|
||||
reservoir; patch needs `y0 >= 4`, `y1 <= ny-4`). Periodic mode ignores the wall/slot config fields.
|
||||
- Object centers/radii use the coarse **cell-edge** frame (cell `I` spans `[I, I+1)`),
|
||||
@@ -151,7 +151,7 @@ Scope and limits:
|
||||
inside the union's active region with
|
||||
its boundary stencil clear of transfer cells; a jet may not select links of two
|
||||
different bodies, even across regions. Wall-touching patches remain unsupported.
|
||||
For nesting, use the level lists or legacy child forms below.
|
||||
For nesting, add further `refinements` entries as shown below.
|
||||
|
||||
```python
|
||||
cfg = LBMConfig(nx=32, ny=16, viscosity=.1)
|
||||
@@ -165,19 +165,20 @@ Scope and limits:
|
||||
coarse_g, fine_g = run.download() # coarse: NaN on every covered cell;
|
||||
# fine: NaN on every non-ACTIVE cell
|
||||
```
|
||||
- Legacy three-level scalar chain: add `child=(x0, y0, x1, y1)` in
|
||||
**L1 window cells** (the patch's fine grid including its 4-cell ghost band) and
|
||||
all three `level_blocks` entries. L2 must sit inside L1's
|
||||
ACTIVE cells, away from L1's ghost band and transfer footprint (checked before
|
||||
any GPU allocation). `initialize` and `download` take/return three arrays; each
|
||||
level is NaN on its non-ACTIVE (and child-covered) cells. One coarse step = 2 L1
|
||||
steps = 4 L2 steps. One L1 patch only. Optional stationary circles and Jets
|
||||
live on L2 via `level_objects[2]` and `level_jets[2]`; L1 bodies/Jets retain
|
||||
their L1 meaning and must be empty in this mode. All object and Jet geometry
|
||||
uses the **L0 edge frame**, not the child bounds' L1 window frame. L2 has
|
||||
dx=dt=0.25, so prescribed lattice velocity is unchanged. Each whole body and
|
||||
its BFL stencil must be inside L2 ACTIVE cells, outside the transfer footprint.
|
||||
A Jet may select one physical body across multiple blocks, never two bodies.
|
||||
- Three-level nested windows: pass two scalar rectangles in `refinements` —
|
||||
L1 in L0 cells, L2 in **L1 window cells** (the parent's fine grid including its
|
||||
4-cell ghost band) — plus all three `level_blocks` entries. L2 must sit inside
|
||||
L1's ACTIVE cells, away from L1's ghost band and transfer footprint (checked
|
||||
before any GPU allocation). `initialize` and `download` take/return three
|
||||
arrays; each level is NaN on its non-ACTIVE (and child-covered) cells. One
|
||||
coarse step = 2 L1 steps = 4 L2 steps. One L1 window only in this scalar
|
||||
chain. Optional stationary circles and Jets live on L2 via `level_objects[2]`
|
||||
and `level_jets[2]`; L1 bodies/Jets retain their L1 meaning and must be empty
|
||||
in this mode. All object and Jet geometry uses the **L0 edge frame**, not the
|
||||
child bounds' L1 window frame. L2 has dx=dt=0.25, so prescribed lattice
|
||||
velocity is unchanged. Each whole body and its BFL stencil must be inside L2
|
||||
ACTIVE cells, outside the transfer footprint. A Jet may select one physical
|
||||
body across multiple blocks, never two bodies.
|
||||
|
||||
```python
|
||||
from CelerisLab.body.geometry.circle import CircleGeometry
|
||||
@@ -199,16 +200,16 @@ Scope and limits:
|
||||
run.step(4)
|
||||
coarse_g, l1_g, l2_g = run.download() # solids/covered/nonleaves are NaN
|
||||
```
|
||||
- Level lists: `refinements[l]` describes level `l+1` in allocated level-`l`
|
||||
integer cells; use a rectangle list for a union, or a scalar rectangle for a
|
||||
single window (a scalar child requires a scalar parent). `level_blocks`,
|
||||
`level_objects` and `level_jets` each have one entry per level, including L0.
|
||||
These lists are mutually exclusive with the legacy patch keywords. Three or
|
||||
more levels require all-blocked storage and bodies/Jets only on the finest
|
||||
level. Every adjacent pair must preserve inherited ACTIVE coverage, valid
|
||||
donors/receivers, surviving pulls and the upstream transfer footprint.
|
||||
Level `l` takes `2**l` steps per base interval. This describes implemented
|
||||
topology and scheduling, not accuracy or convergence qualification.
|
||||
- Level lists (the only constructor): `refinements[l]` describes level `l+1`
|
||||
in allocated level-`l` integer cells; use a rectangle list for a union, or a
|
||||
scalar rectangle for a single window (a scalar child requires a scalar
|
||||
parent). `level_blocks`, `level_objects` and `level_jets` each have one entry
|
||||
per level, including L0. Three or more levels require all-blocked storage and
|
||||
bodies/Jets only on the finest level. Every adjacent pair must preserve
|
||||
inherited ACTIVE coverage, valid donors/receivers, surviving pulls and the
|
||||
upstream transfer footprint. Level `l` takes `2**l` steps per base interval.
|
||||
This describes implemented topology and scheduling, not accuracy or
|
||||
convergence qualification.
|
||||
- Blocked body levels can enable `observe_raw_exchange=True` and call
|
||||
`read_raw_exchange(body_id, level=...)` after a completed base interval.
|
||||
It reduces unique cut-link observations into wall/aperture/total force,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Fixed three-level rectangle unions
|
||||
|
||||
This page describes the legacy three-level entry point of `FixedPatchStepper`,
|
||||
with rectangle unions on either adjacent pair. The `refinements` level-list
|
||||
entry point also supports arbitrary depth; three or more levels require
|
||||
This page describes three-level `FixedPatchStepper` setups built from the
|
||||
`refinements` level list, with rectangle unions on either adjacent pair. The
|
||||
same constructor supports arbitrary depth; three or more levels require
|
||||
all-blocked storage and bodies/Jets only on the finest level. This is not
|
||||
general AMR: there is no per-region timestep, moving geometry, automatic
|
||||
dynamic refinement or L1 body support in the three-level form.
|
||||
@@ -12,15 +12,15 @@ No CUDA kernel changes are involved.
|
||||
|
||||
## Explicit coordinate frames
|
||||
|
||||
Keep the existing scalar `child=(x0,y0,x1,y1)` for a single scalar parent patch.
|
||||
Its coordinates retain their original meaning: half-open integer indices in the
|
||||
allocated L1 window, including its ghost band.
|
||||
For a single scalar parent patch, pass a scalar rectangle as `refinements[1]`:
|
||||
`(x0,y0,x1,y1)` in half-open integer indices of the allocated L1 window,
|
||||
including its ghost band.
|
||||
|
||||
A rectangle list as the second `refinements` entry (formerly the keyword
|
||||
`child_rectangles_in_parent=[...]`) accepts a scalar or a set parent and interprets every rectangle in
|
||||
the actual allocated L1 array, including ghost bands and holes. It never infers
|
||||
region-local coordinates. The physical root cell edge corresponding to an L1
|
||||
index `(x,y)` is `parent.fine_origin + (x,y)/2`:
|
||||
A rectangle list as `refinements[1]` accepts a scalar or a set parent and
|
||||
interprets every rectangle in the actual allocated L1 array, including ghost
|
||||
bands and holes. It never infers region-local coordinates. The physical root
|
||||
cell edge corresponding to an L1 index `(x,y)` is
|
||||
`parent.fine_origin + (x,y)/2`:
|
||||
|
||||
- A scalar L1 parent has a shifted window origin.
|
||||
- A set L1 parent has origin `(0,0)` and public shape `(2*ny,2*nx)`.
|
||||
|
||||
@@ -75,13 +75,13 @@ def _check_levels(refinements, blocks, objects, jets):
|
||||
raise ValueError(f"{name} needs one entry per level ({depth})")
|
||||
for level, block in enumerate(blocks):
|
||||
if block is not None and len(block) != 2:
|
||||
raise ValueError(f"{_level_name(level)}_block must be (by, bx)")
|
||||
raise ValueError(f"level_blocks[{level}] must be (by, bx)")
|
||||
if objects[0] or jets[0]:
|
||||
raise ValueError("base-level bodies/Jets are not supported")
|
||||
if any(blocks[level - 1] is not None and blocks[level] is None for level in range(1, depth)):
|
||||
raise ValueError("a blocked level requires blocked refined levels below it")
|
||||
if not is_rectangle(refinements[0]) and (blocks[0] is None or blocks[1] is None):
|
||||
raise ValueError("several patches require fine_block and base_block")
|
||||
raise ValueError("several L1 patches require level_blocks[0] and level_blocks[1]")
|
||||
if depth > 2:
|
||||
if any(block is None for block in blocks):
|
||||
raise ValueError("three or more levels must all be blocked")
|
||||
@@ -149,9 +149,11 @@ class FixedPatchStepper:
|
||||
Nested levels: a child set's coordinates index the allocated parent array,
|
||||
including ghost bands and holes: root edge = parent fine_origin + index / 2
|
||||
(zero origin for a parent set; a scalar parent keeps its shifted window
|
||||
origin). A scalar child requires a scalar parent. Each pair requires gap >= 4
|
||||
in its own parent-cell units. All regions share one buffer pair per level
|
||||
and the fixed schedule of 2**l hops per base step at level l. Bodies/Jets are supported only on the
|
||||
origin). A scalar child requires a scalar parent. Rectangle unions impose no
|
||||
fixed gap rule: adjacent, overlapping and concave unions are accepted when
|
||||
their actual transfer dependencies close (FixedPatchSet2D /
|
||||
nest_patch_set). All regions share one buffer pair per level and the fixed
|
||||
schedule of 2**l hops per base step at level l. Bodies/Jets are supported only on the
|
||||
finest level of a nested hierarchy (L2 dx=dt=.25 in root units, unchanged
|
||||
lattice velocity); every whole circle and its BFL stencil must fit strictly
|
||||
away from that level's transfer footprint.
|
||||
|
||||
Reference in New Issue
Block a user