Эталон AM-01 (29.09.2026) —
reference.md. Числа этого файла — прикидка (solver.py: ν ≥ 30 м²/с, слой перемешивания 3 К/км, Δτ_u = 600 с). В эталоне (air.py) физика и сходимость другие: K — Троен–Март/Холтслаг–Бовилль + длина перемешивания + Смагоринский, нагрев по слою перемешивания, фон и z_i из погоды игры; время — область 400 м 0,6–1,1 с, окно 100 м 0,3–0,5 с, окно 50 м 0,7–1,7 с, 8 м/с сходится везде. Подъём у старта в штиль 0,57 м/с (прикидка 0,18–0,21), ошибки ближайшего поля и рекомендация по библиотеке — пересчитаны там.
3D-Пикар на рельефе Онгудая: время, сходимость, размер поля — итог прикидки
Задача (по запросу пользователя): понять для библиотеки опорных полей (docs/plan/air_model.md,
AM-01/AM-06б), сколько стоит одно 3D-решение «среднего поля на час» на реальном рельефе, сходится ли
Пикар в 3D с ветром, помогает ли тёплый старт, можно ли хранить поля через 2–3 ч и сколько это места.
Оценка, не продукт: декартова сетка с маской вместо σ-сетки, CuPy на RTX 4070 SUPER. Команды —
README.md, все числа — out/*.json, сводные таблицы — out/tables.md.
Коротко
Сходится: 182 из 182 решений матрицы (400 и 200 м × 6 часов + без нагрева × 13 ветров: штиль, 3 м/с × 8 направлений, 6 м/с × 4) и все 35 решений окон 100/50 м — после трёх физически обоснованных правок (ниже). ∇·u (СКО) ≤ 6·10⁻⁸ 1/с; баланс тепла сходится до 5·10⁻⁴ от нагрева с ветром, до 8·10⁻³ в штиль.
Время на 4070 SUPER (холодный старт, критерий ≈ 1 % по w):
Сетка Клеток Итераций Время мс/итер. Память вся область 400 м (96×96×48) 0,48 M 31–81 0,3–0,8 с 9,5 170 МБ вся область 200 м (192×192×48) 1,9 M 41–141 1,2–4,2 с 28,5 670 МБ окно 100 м 64×64×62 (Δz 50 м) 0,27 M 51–291 0,4–2,3 с 8 ~100 МБ окно 50 м 64×64×112 (Δz 25 м) 0,48 M 141–771 1,8–10 с 13 ~170 МБ Штиль сходится быстрее всего, 6 м/с — медленнее; окна требуют больше итераций, чем область (см. «Не доделано»).
Тёплый старт помогает только по часу: опора ±1…4 ч → на 40–70 % меньше итераций, но только если сохранено давление p вместе с u, v, w, θ′. Опора с другим направлением (45°…180°) или силой ветра не даёт выигрыша, иногда хуже холодного; «без нагрева → полдень» — 0–30 %. Холодное решение и так стоит 40–140 итераций. Библиотека опор ради тёплого старта при загрузке себя не окупает.
Интерполяция по часам: шаг 2 ч (12:00 ≈ ½(11:00 + 13:00)) — 2,4 % (отн. L2), максимум 0,02 м/с по w, 0,04 м/с по u; шаг 3 ч — 4–5 % (0,04 / 0,1 м/с); 4 ч — ~10 %. Просто соседний час без интерполяции — 9–20 %. Часы ставить симметрично истинному полудню (13:15 по UTC+7): пара 9/15 даёт для 12:00 уже 20 %. Оговорка: в прикидке от часа меняется только солнце (угол к склонам); фон θ̄(z) и верх слоя перемешивания постоянны — реальный суточный ход сильнее, оценка оптимистична.
Размер одного поля (u, v, w, θ′): 400 м — 3,4 МБ fp16 → 1,7 МБ fp16+zstd → 0,35 МБ при квантовании 0,02 м/с / 0,02 К + разности по высоте + zstd-19; 200 м — 13,5 → 6,2 → 1,2 МБ; окно 100 м — 1,9 → 0,84 → 0,16 МБ; окно 50 м — 3,5 → 1,3 → 0,2 МБ. Погрешность квантования ±0,01 — на порядок меньше ошибки интерполяции по часам.
Рекомендация: хранить не опоры, а готовые поля «все часы через 2 ч (9–17) × 8 направлений × 2 силы + штиль» на 400 м + окно 100 м у старта — ~43 МБ на место (квант), ~2–3,5 мин на 4070 SUPER; или «через 3 ч (10, 13, 16)» / «3 часа старта» — ~26 МБ, ~1,5–2 мин. Точное поле для условий полёта — пересчитывать при загрузке (0,7 с + окно ~2 с), библиотека — пока оно не готово и для слабых карт. Подробности — «Рекомендация».
Постановка и упрощения (границы прикидки)
Уравнения — как в плане (масштаб 1): установившийся Буссинеск; ∇·u = 0 точно (проекция); импульс:
перенос, турбулентная вязкость, трение о землю, плавучесть g·θ′/θ0, нелокальное давление; тепло:
перенос, турбулентная диффузия, нагрев от земли, выхолаживание к фону τ = 2 ч, −w·dθ̄/dz. Итерация
Пикара — схема опыта 2 (heat_ca/exp2_picard) в 3D: Озеен с псевдошагом и полунеявной плавучестью,
зебра-прогонки по линиям z, x, y → проекция SIMPLEC одним V-циклом (полуогрубление по x, y, прогонки
по вертикали) → тепло с псевдошагом, прогонки. Остановка — по невязке самих установившихся уравнений
(СКО < 2·10⁻⁵ м/с², 5·10⁻⁷ К/с, ∇·u < 10⁻⁶ 1/с); по опыту conv при этом ошибка u, w против
досчитанного до пола fp32 решения ≈ 0,3–0,5 % (L2) с ветром; в штиль w — 0,2 %, слабая горизонталь —
до 3 % (≤ 2 см/с). Графики — out/fig_convergence.png.
| Что | В прикидке | В плане / в жизни | Чем грозит |
|---|---|---|---|
| Сетка | декартова MAC, маска «под землёй»; Δz = 105 м (область), 50 м (окно 100), 25 м (окно 50); рельеф — «лесенка» | σ-сетка, первый слой ~10 м | у земли на 50 м видна лесенка (полосы на срезах); тонкий склоновый слой не разрешён; ключевые числа в окнах всё равно сходятся (ниже) |
| Перенос | противопоточный 1-го порядка | тот же тип (полулагранжев в 2D) | численная вязкость ~U·Δx/2 на крупной клетке — 400 м сглаживает бровку |
| Турбулентность | ν = κ = max(30 м²/с, K_CBL); K_CBL = 0,4·w_m·z·(1 − z/z_i)² (профиль Троена–Марта/Холтслага–Бовилля), w_m = 0,65·w*, w* из сглаженного (σ 1,5 км) потока тепла, z_i — до 3500 м над морем | «постоянная или по высоте» | в полдень ν до ~150–200 м²/с; конвективный перенос тепла идёт через K, а не разрешёнными струями → в штиль средний подъём слабый (0,15–0,2 м/с), остальное — термики масштаба 2 (это и есть «стык 1↔2») |
| Трение | объёмное сопротивление в первом слое, C_d = (0,4/ln(Δz/2/z0))², z0 = 0,1 м | то же по смыслу | лес не учтён |
| Фон | θ̄: 3 К/км (T −6,8 К/км) до 3500 м, выше 6 К/км; ветер U постоянный по высоте | профили из погоды на час, инверсия | суточный ход фона не моделируется → ошибка интерполяции по часам занижена |
| Нагрев | 330 Вт/м² при нормальном падении × max(0, cos угла к склону) + 10 %·sin h рассеянного; вода не греется; солнце 15 июля, 50,79° с. ш. 86,13° в. д., UTC+7, запаздывание 0,3 ч | surface_heating.gd, классы поверхности | в полдень 360–430 Вт/м² на горизонтальную площадь на солнечных склонах; классы (лес, камни) не учтены |
| Границы области | «жёсткие»: приток = фон, выход = фон × const (баланс площадей), губки 2 км по бокам и 1 км у потолка; в штиль — стенки | открытые | у краёв поток принудительно фоновый; от края до старта 12 км |
| Окна | все грани и ореол — трилинейно из родителя, поправка потока ΣΦ = 0, без губок | клипмапы WF-14 | окно 100 м от родителя 200 м и от 400 м дало одно и то же (разница ≤ 0,03 м/с) |
Не умеет (как и план): пузыри, отрыв вихрей, влага, вращение Земли, излучение кроме τ.
Что не сошлось сразу и чем исправлено (все правки — в пределах физики, без подгонки)
- ν = 30 м²/с в штиль с нагревом: над плоским прогретым дном долины (400 м) блуждают сеточные конвективные струи, невязка стоит на ~10⁻³ м/с² (изменения w 0,05–0,3 м/с за 10 итераций) — неустойчивая свободная конвекция на сетке. Физически так и должно быть: среднее поле при перемешанном воздухе требует турбулентной вязкости слоя перемешивания → замыкание K_CBL, после него сходится монотонно.
- Полунеявная плавучесть с множителем 0,3 (как в 2D): при 3 м/с и нагреве раскачиваются внутренние волны в устойчивом слое выше 3,5 км. Множитель 1 (полностью полунеявно) — сходится; член исчезает в неподвижной точке, на ответ не влияет.
- Выход «снос из соседней грани + масштаб» (как в 2D) даёт медленную моду 0,989/итер. во всех полях (выход «плывёт» на поперечную дивергенцию). «Дирихле φ = 0 за выходом» ломает V-цикл (полуогрубление с кусочно-постоянной интерполяцией расходится с Дирихле). Взяты «жёсткие» границы с губками → 0,955/итер. (в 4 раза быстрее по логарифму).
- Δτ_u = 600 с вместо 120 с — штиль в 1,5–2 раза быстрее; на ветер почти не влияет.
Сходимость по клетке (out/cells.json, out/fig_cells.png)
Цепочка: область 400 м → область 200 м → окно 100 м (от 200 м) → окно 50 м (от 100 м). «Подъём» — максимальный w на 200 м над землёй в 1,5 км от старта; ветер — горизонтальная скорость на 50 м над землёй в точке.
| 13:00 | 400 м | 200 м | 100 м | 50 м |
|---|---|---|---|---|
| штиль: подъём у старта, м/с | 0,15 | 0,17 | 0,18 | 0,21 |
| штиль: ветер над стартом (приток), м/с | 0,08 | 0,17 | 0,19 | 0,20 |
| южный 3 м/с: подъём у старта | 0,66 | 0,70 | 0,75 | 0,79 |
| южный 3 м/с: ветер над стартом | 2,40 | 2,61 | 2,55 | 2,76 |
| южный 3 м/с: седловина к северу | 2,50 | 3,01 | 2,84 | 2,87 |
| ЮВ 3 м/с (на склон старта): подъём / ветер над стартом | 0,59 / 3,09 | 0,73 / 3,09 | 0,79 / 3,00 | 0,80 / 3,09 |
| южный 6 м/с: подъём / ветер / седловина | 1,15 / 3,98 / 4,22 | 1,21 / 4,13 / 5,00 | 1,31 / 4,08 / 4,84 | 1,34 / 4,53 / 4,83 |
| южный 3 м/с без нагрева: подъём | 0,31 | 0,37 | 0,48 | 0,47 |
- Ключевые числа сходятся: от 200 к 50 м подъём +10–15 %, ветер ±5–10 %. 400 м занижает подъём на 15–25 % и разгон на бровке на 5–10 %, в штиль — вдвое.
- Нагрев добавляет к механическому подъёму у старта +0,3 (3 м/с) … +0,5 м/с (6 м/с) — разделение 1↔2 из плана вторым решением без нагрева работает.
- «Седловина» к северу от старта (точка —
common.probes) — пологий гребень, а не узкий перевал поперёк ветра: «трубы ×1,5» нет, ×1,0–1,1 от U при южном ветре, ×1,16 при западном 3 м/с. - В штиль средний подъём слабый (0,2 м/с) из-за замыкания K_CBL — см. таблицу упрощений; приток к
склону 0,2–0,4 м/с на 50 м виден (
out/fig_windows.png).
Тёплый старт (out/warm.json, out/fig_warm_start.png)
Итераций до критерия, 200 м (400 м — out/tables.md, картина та же; проверка раз в 10 итераций →
точность ±10):
| Опора отличается | Холодный | Тёплый (u, v, w, θ′, p в fp16) | Тёплый без p |
|---|---|---|---|
| час ±1 ч | 71 | 31 | 71 |
| час ±2 ч | 71 | 21–41 | 71 |
| час 3–4 ч | 71 | 41 | 61–71 |
| штиль, час ±2–3 ч | 51 | 21–41 | 21–41 |
| направление 45° | 71 | 71 | 81 |
| направление 90° | 71 / 131 (6 м/с) | 91 / 131 | 91 / 131 |
| направление 180° | 71 | 111 | 111 |
| сила 3 → 6 м/с | 131 | 111 | 131 |
| сила 6 → 3 м/с | 71 | 111 | 111 |
| без нагрева → полдень (3 / 6 м/с) | 71 / 131 | 51 / 91 | 71 / 131 |
| «ближайшая опора» к U4 160° 14 ч; U5 200° 10 ч | 101; 111 | 81; 91 | 91–101; 111 |
Вывод: из опоры дёшево берётся только смена часа (сдвиг поля). Смена направления/силы перестраивает всю картину обтекания (ошибка «опоры как есть» 60–170 % по w), и Пикару проще начать с потенциального обтекания. Давление хранить нужно, если вообще использовать тёплый старт по часу: без p выигрыша нет (p, fp16 zstd — 0,17 МБ на окно 100 м).
Интерполяция по часам (out/interp.json, out/fig_interp_hours.png)
Худший из 7 ветров (штиль, 3 м/с × 4, 6 м/с × 2), сетка 200 м (400 м — то же ±0,5 %):
| Что храним → что нужно | w: отн. L2 / макс., м/с | u: отн. / макс., м/с | θ′: отн. / макс., К |
|---|---|---|---|
| шаг 2 ч: 12 ← ½(11 + 13) | 2,4 % / 0,02 | 2,2 % / 0,04 | 2,3 % / 0,04 |
| шаг 3 ч: 11 ← (9, 12), 13 ← (12, 15) | 4,6–4,9 % / 0,03–0,04 | 4,1–4,5 % / 0,07–0,11 | 4,1–4,7 % / 0,08–0,10 |
| шаг 3 ч несимметрично полудню: 12 ← ½(9 + 15) | 21 % / 0,14 | 19 % / 0,38 | 20 % / 0,37 |
| шаг 4 ч: 13 ← ½(11 + 15) и др. | 9,5 % / 0,06–0,07 | 9 % / 0,14–0,21 | 9 % / 0,16–0,19 |
| без интерполяции: соседний час (±1 ч) | 9–12 % / 0,05–0,07 | 8–11 % / 0,07–0,15 | 6–10 % / 0,16–0,22 |
| без интерполяции: ±2 ч | 15–20 % / 0,10–0,11 | 13–18 % / 0,13–0,21 | 4–15 % / 0,24–0,38 |
Абсолютные ошибки малы (сотые м/с по w), потому что от часа в прикидке меняется только геометрия солнца. Линейная интерполяция по часам с шагом 2–3 ч пригодна при узлах, симметричных истинному полудню (13:15 по UTC+7 для Онгудая), например 10/13/16 или 9/11/13/15/17. С реальным суточным ходом (утренняя инверсия, рост слоя перемешивания) ошибка будет больше — шаг 3 ч на грани.
Размер и библиотеки (out/size.json, out/library.json)
Время — холодные решения на 4070 SUPER (медианы с ветром: 400 м 0,68 с, 200 м 2,5 с, окно 100 м 1,8 с), в скобках — с тёплым стартом по часам (×0,51 итераций, p в опоре). На место — одно окно 100 м у старта (на других местах окон столько, сколько стартов).
| Вариант | Полей | 400 м + окно 100: МБ fp16-zstd / квант | время | 200 м + окно 100: МБ fp16-zstd / квант | время |
|---|---|---|---|---|---|
| а) опоры 8 напр. × 2 силы × {без нагрева, 13 ч} (план) | 32 | 82 / 16 | 79 с (60) | 224 / 43 | 136 с (103) |
| б1) все часы через 2 ч (9…17) × (8 × 2 + штиль) | 85 | 217 / 43 | 210 с (128) | 596 / 115 | 362 с (221) |
| б2) все часы через 3 ч (10, 13, 16) × (8 × 2 + штиль) | 51 | 130 / 26 | 126 с (85) | 358 / 69 | 217 с (147) |
| в) 3 часа старта (11, 13, 15) × (8 × 2 + штиль) | 51 | 130 / 26 | 126 с (85) | 358 / 69 | 217 с (147) |
| г) 16 напр. × 4 силы × 5 часов + штиль | 325 | 830 / 166 | 804 с (490) | 2279 / 441 | 1384 с (844) |
«Все сочетания» плана (≈ 2300 решений, 23 ГБ) при квантованном хранении на 400 м + окно — ~1,2 ГБ и ~1,5 ч: смысла нет. Поля без нагрева (для разделения механической/конвективной вертикали) удваивают библиотеку, если их хранить; их можно считать при загрузке (0,5–0,8 с на 400 м). Размер поля в основном — воздух выше 2 км над рельефом, где поле почти фоновое: обрезка по высоте или разреживание верхних уровней даст ещё ×1,5–2 (не мерилось).
Перенос на Vulkan / AMD (грубо)
Итерация упирается в память: ~2,4 КБ на клетку за итерацию (13 проходов прогонок по 7 коэффициентам
- V-цикл + сборка шаблонов); на 4070 SUPER это 28 мс на 1,9 M клеток ≈ 30 % пика ПСП (главные потери — некоалесцированные прогонки вдоль x и зебра). При той же доле пика на Vulkan время ∝ 1/ПСП:
| Карта | ПСП | Решение 400 м / 200 м (ветер) | Окно 100 м |
|---|---|---|---|
| RTX 4070 SUPER (замер) | 504 ГБ/с | 0,7 / 2,5 с | 1,8 с |
| RX 6700 XT | 384 | 0,9 / 3,2 с | 2,4 с |
| RX 7600 | 288 | 1,2 / 4,3 с | 3,1 с |
| RX 6600 / RX 580 | 224–256 | 1,3–1,5 / 4,8–5,5 с | 3,5–4,0 с |
| Radeon 780M (встроенная) | ~90 | 3,8 / 14 с | 10 с |
| Vega 8 (встроенная, DDR4) | ~45 | 7,6 / 28 с | 20 с |
Сборка коэффициентов шаблонов на лету (а не хранение 7 массивов на компоненту) даст ~×2 по трафику и ~×3 по памяти (сейчас 360 Б на клетку). Линии ≤ 194 точек — в одну группу, многопроходная прогонка не нужна.
Рекомендация
- Библиотеку опор (вариант а) как ускоритель загрузки не делать: тёплый старт от опоры с другим ветром не экономит итераций, а холодное решение точных условий на 400 м — 0,3–0,8 с, на 200 м — 1–4 с (4070 SUPER; на AMD среднего класса ~1,5 и ~5 с).
- Если библиотека нужна (мгновенная загрузка, слабые карты, сеть), хранить готовые поля:
- по умолчанию — область 400 м + окна 100 м у стартов, часы 9, 11, 13, 15, 17 × 8 направлений × {3, 6 м/с} + штиль, квант 0,02 + zstd: ~43 МБ на место (1 старт), ~2 мин на 4070 SUPER с тёплым стартом по часам (~3,5 мин холодными);
- компромисс — часы 10, 13, 16 (шаг 3 ч, симметрично полудню, интерполяция ~5 %) или ограничить выбор старта тремя часами: ~26 МБ, ~1,5 мин — укладывается в цель плана «место с карты ≤ 2 мин»;
- между направлениями/силами — ближайшее поле из библиотеки сразу, точное решение фоном (0,7 с + окно). Интерполяцию по направлению не проверяли — поле нелинейно.
- Сетка по области — 400 м достаточно для библиотеки: она занижает подъём/разгон на 5–25 % против 200 м, но окно 100 м у старта от 400-метрового родителя даёт те же числа, что от 200-метрового (≤ 0,03 м/с). 200 м по области — ×4 по времени и ×3 по месту при малой пользе вдали от стартов.
Для задач плана
- AM-01: шлюз по сути пройден — в 3D на реальном рельефе при ветре 0–6 м/с Пикар сходится на всех клетках 400–50 м. В схему добавить: замыкание K_CBL, полностью полунеявную плавучесть, «жёсткие» границы с губками (или открытый выход с решателем, выдерживающим Дирихле). Проверить 8 м/с при 50 м (здесь не делали). Окна мельче 100 м сходятся медленно (500–770 итераций на 50 м) — нужен многосеточный решатель импульса или тёплый старт окна от прошлого положения.
- AM-06б: формат — поля u, v, w, θ′ (+ p, если нужен тёплый старт по часу) в клетках, квант 0,02 + разность по z + zstd; метаданные — версия модели, сетка, час, ветер. Состав по умолчанию — «все часы через 2 ч × 8 × 2 + штиль», 400 м + окна 100 м; место с карты — ~2 мин и ~40–60 МБ (1–2 старта). При загрузке — ближайшее поле сразу, точное фоном. Опоры «без нагрева» не хранить — считать при загрузке.
- AM-03/AM-04: цель «200 м по области ≤ 5 с» на 4070 SUPER выполнена (1–4 с); узкое место — окна (100 м 1–2 с, 50 м 2–10 с): план «окна < 1 с фоном» требует тёплого старта окна и более быстрого решателя импульса.
Не доделано
- σ-сетка, синтетика (Аньези, седловина), Askervein — не делались (это AM-01).
- 8 м/с и сильная инверсия не прогонялись.
- Сходимость окна 50 м медленная (сотни итераций); причину (жёсткие границы от родителя или анизотропия Δx/Δz = 2 при прогонках) не разбирал. Тёплый старт окна от сдвинутого окна не мерил.
- Интерполяция по направлению ветра не проверялась.
- Хранение p учтено только для окон (0,17 МБ / 0,26 МБ).
Картинки
out/fig_map.png— рельеф, область, окна, старт, седловина; поток тепла в 13:00.out/fig_slices_200m.png— w на 50/200 м и ветер на 50 м, 200 м по области: штиль, южный 3 м/с с нагревом и без, западный 6 м/с.out/fig_windows.png— окна 100 и 50 м у старта: штиль и южный 3 м/с.out/fig_section.png— разрез ЮЮВ→ССЗ через старт (w, θ′, стрелки): окна 100/50 м и область 200 м.out/fig_convergence.png— невязки и ошибка против итераций;out/fig_warm_start.png— тёплый старт;out/fig_interp_hours.png— интерполяция по часам;out/fig_cells.png— ключевые числа против клетки.out/3d/kayancha_w100_*.html,out/3d/ongudai_d200_*.html— 3D (plotly): рельеф, линии тока с цветом по скорости, изоповерхности w = +1 / −0,5 м/с (окно), кнопки масштаба высоты.