Пристеночная функция Spalding, многоуровневый домен, группы J и K
Решатель: - --wall-function spalding поверх bouzidi/grad/hrr: моментные схемы берут модельную скорость узла и u_τ²/ν в тензор давлений, Bouzidi — скольжение стенки, согласованное по напряжению (в вязком подслое тождественно ноль); - --levels: цепочка вложенных уровней с рекурсивным шагом на CPU и GPU, одиночный патч — её частный случай, прежние постановки побитово те же; - --sponge-side, β по узлам; в сводке y⁺, cl_mean, rho_probe_rms. - Исправлено: на GPU при --refine >= 3 сила лишних подшагов терялась за краем буфера, Cd занижался в r/2 раза. Кампания: группы J (65, схемы стенки с функцией) и K (25, внешний домен), 205 прогонов на 5 долей по ≈27 ч; bench/compare.py сводит J и K против эталонов; parity.py сверяет Spalding и три уровня. Образ 1.4.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
# Валидационная кампания
|
||||
|
||||
115 прогонов, ≈90 машинных часов: 108 на GPU (≈87 часов на RTX 4070 Ti) и 7 на CPU (≈3 часа —
|
||||
исследования сходимости группы A, где нужен f64). Проверяет решатель по трём независимым линиям:
|
||||
205 прогонов в одиннадцати группах, ≈101 машинный час: 198 на GPU (≈98 часов при 1200 MLUPS)
|
||||
и 7 на CPU (≈3 часа — исследования сходимости группы A, где нужен f64). Проверяет решатель по трём независимым линиям:
|
||||
эталонам из статей авторов метода, литературе по обтеканию тел и внутренним инвариантам самой
|
||||
схемы. Каждый прогон кладёт в собственную папку `cmd.txt`, `log.txt`, `report.txt`, `series.csv`
|
||||
и `summary.json`; гифку пишут **59 прогонов из 115** — остальным `--gif` не передаётся.
|
||||
и `summary.json`; гифку пишут **59 прогонов из 205** — остальным `--gif` не передаётся.
|
||||
|
||||
## Пять долей: чужие ПК под Windows / WSL2
|
||||
|
||||
@@ -44,11 +44,11 @@ Desktop с бэкендом WSL2 (так по умолчанию) либо Docke
|
||||
|
||||
| доля | прогонов | ≈ часов |
|
||||
|---|---|---|
|
||||
| 1 | 22 | 24.0 |
|
||||
| 2 | 23 | 24.0 |
|
||||
| 3 | 23 | 24.0 |
|
||||
| 4 | 23 | 24.0 |
|
||||
| 5 | 24 | 24.0 |
|
||||
| 1 | 40 | 26.7 |
|
||||
| 2 | 40 | 26.7 |
|
||||
| 3 | 41 | 26.7 |
|
||||
| 4 | 42 | 26.7 |
|
||||
| 5 | 42 | 26.7 |
|
||||
|
||||
Часы — оценка при 1200 MLUPS на крупной сетке **с поправкой на размер сетки**: на dzn мелкие
|
||||
сетки считаются медленнее на узел, а сверхмелкие из группы I идут через раздельные привязки
|
||||
@@ -66,7 +66,7 @@ Desktop с бэкендом WSL2 (так по умолчанию) либо Docke
|
||||
|
||||
## Быстрый старт на сервере
|
||||
|
||||
Образ опубликован, собирать ничего не нужно: **`notbigghost/kbc2d:1.3.0`**. Исходники на
|
||||
Образ опубликован, собирать ничего не нужно: **`notbigghost/kbc2d:1.4.0`**. Исходники на
|
||||
сервере тоже не нужны — переносится один файл `docker-compose.server.yml`.
|
||||
|
||||
```sh
|
||||
@@ -75,7 +75,7 @@ mkdir -p ~/kbc2d && cd ~/kbc2d # сюда же ляжет ./out с ре
|
||||
|
||||
C=docker-compose.server.yml
|
||||
docker compose -f $C --profile check run --rm vulkan # 1. карта видна из контейнера?
|
||||
docker compose -f $C --profile check run --rm preflight # 2. все 115 сценариев стартуют?
|
||||
docker compose -f $C --profile check run --rm preflight # 2. все 205 сценариев стартуют?
|
||||
docker compose -f $C --profile check run --rm calibrate # 3. сколько MLUPS на этой машине?
|
||||
docker compose -f $C --profile check run --rm plan # 4. смета в часах по замеренному
|
||||
docker compose -f $C up -d # 5. кампания
|
||||
@@ -277,6 +277,38 @@ out/<id>/xt_*.csv x–t диаграммы (группа G)
|
||||
| **G** | 14 | старт, акустика, время жизни: x–t диаграммы, губки, предел по Re, прогон на 10⁷ шагов |
|
||||
| **H** | 9 | инварианты: симметрия, зеркальность, зависимость от числа Маха, расхождение f32 против f64 |
|
||||
| **I** | 9 | сверхмелкие сетки 4096×2048 по всем формам и композиции из трёх тел |
|
||||
| **J** | 65 | схемы стенки с пристеночной функцией: Bouzidi без неё против Bouzidi, Grad и HRR со Spalding — цилиндр Re=150 / 2000 (D=8…64) и 5000 (D=32, 64), NACA 0012 α=4° Re=2000 (хорда 24…96) и 10⁴ (48, 96); эталон каждой серии — Bouzidi при удвоенном разрешении |
|
||||
| **K** | 25 | внешний домен: грубые буферы до тела, после и по бокам, переход разрешения скачком ×4 / ×8 против ступеней ×2, длина тонкого следа, ширина промежуточного уровня, боковые губки — против однородной тонкой сетки на домене 30D+60D, ±30D |
|
||||
|
||||
### Группы J и K: как читать
|
||||
|
||||
Обе группы отвечают на практические вопросы, и обе меряются против эталона внутри группы, а не
|
||||
против литературы — для турбулентных Re и для домена её просто нет.
|
||||
|
||||
**J** — что точнее: Bouzidi (лучшая геометрия) или моментные схемы с пристеночной функцией
|
||||
Spalding. Bouzidi + Spalding добавлен, чтобы отделить вклад функции от вклада схемы. Сетка
|
||||
однородная, разрешение задано числом клеток на тело. Re выбраны с оглядкой на устойчивость:
|
||||
предел здесь задаёт не модель стенки, а τ − ½ = 3uD/Re — при τ − ½ < 6·10⁻⁴ счёт
|
||||
разваливается у всех схем одинаково (замерено: цилиндр Re = 10⁴ при D = 16 и 32), и такой
|
||||
прогон сравнивал бы не схемы, а предел устойчивости. Отсюда Re = 5000 вместо 10⁴ у цилиндра и
|
||||
хорды от 48 у профиля при Re = 10⁴. В каждой сводке — y⁺ первого узла: при y⁺ < 5 функция
|
||||
обязана почти совпасть с прилипанием, разница возможна только там, где первая клетка дальше.
|
||||
|
||||
**K** — как строить внешний домен (ключ `--levels` решателя). Тело везде одно: цилиндр с
|
||||
D = 32 на самом тонком уровне. База — L0 в 4 раза грубее тела, домен 20D до тела, 40D после,
|
||||
±20D, две ступени ×2. Серии меняют по одному параметру. Кроме St, ⟨Cd⟩ и rms Cl сравнивается
|
||||
`rho_probe_rms` — пульсация плотности в зонде, мера паразитной акустики от отражений на границах
|
||||
и стыках уровней, — и стоимость: конфигурации K обходятся в 1–2 % стоимости эталона.
|
||||
|
||||
Сводка обеих групп:
|
||||
|
||||
```sh
|
||||
python compare.py # Markdown-таблицы против эталонов, читает out/
|
||||
python compare.py --out ../all_out --csv jk.csv # по сведённым результатам пяти долей
|
||||
```
|
||||
|
||||
Не посчитанный прогон помечается «нет», развалившийся — «развал»; под каждой серией J — какая
|
||||
схема ближе всех к эталону на каждом разрешении (по |ΔCd| у цилиндра, по |ΔCl| у профиля).
|
||||
|
||||
## Стоимость и время
|
||||
|
||||
@@ -298,6 +330,12 @@ python gen_scenarios.py --scale 3 # все прогоны в полтора
|
||||
группы A идут на CPU — это указано в самих сценариях.
|
||||
- **Развалы ожидаемы** в группе G (предел по Re) и у прогона `A09_shear_n512_lbgk`: LBGK при
|
||||
Re=3·10⁴ обязан развалиться там, где KBC доживает — это и есть проверяемое утверждение.
|
||||
Длинные прогоны канала показали предел около τ − ½ ≈ 6·10⁻⁴ (τ − ½ = 3uD/Re), а не
|
||||
Re ≈ 5·10⁴ при D = 16, как оценивалось раньше по коротким прогонам: при этом пределе
|
||||
`G11_limit_re10000` (τ − ½ = 7.2·10⁻⁴) на грани, а `G12` и `G13` обязаны развалиться.
|
||||
- **`F09_refine3` до версии 1.4.0 считался на GPU с заниженным в 1.5 раза Cd** — сила третьего
|
||||
подшага терялась за краем буфера. Исправлено; результаты этого прогона из образов до 1.4.0
|
||||
не использовать.
|
||||
- **Гифки** пишутся на всю длительность прогона, в реальном времени, 10 кадр/с. Число кадров
|
||||
этим задано жёстко (у самого длинного прогона их 16 666), поэтому единственный рычаг —
|
||||
размер кадра. Замерено: 0.103 байта на пиксель после LZW; отсюда бюджет
|
||||
|
||||
Reference in New Issue
Block a user