Комплекс Физических Программ

Я разработал учебный комплекс по моделированию различных физических процессов, на данный момент он включает в себя 126 модулей. Первую версию я разработал ещё будучи студентом, двадцать лет назад. Сейчас же я выпускаю вторую версию, которая вполне может составить конкурренцию таким гигантам индустрии как PhET колорадского университета и прочим, с той лишь разницей - что в отличии от них, это моя собственная разработка, которую я вёл в одиночку. Плюс в своей программе я сделал упор на трёхмерную графику и аппаратное ускорение вычислений на CUDA и OpenCL, потому в отличии от уже существующих решений, я могу создавать более масштабные модели с огромным количеством частиц/моделей, работа которых вычисляется параллельно на видеокарте. Предфинальное видео, которое расскажет больше, чем я смогу описать словами:

Несколько примеров модулей, содержащего на данный момент более 120 различных физических экспериментов.

Магнитное поле планеты - с хорошей точностью обычный диполь, той же формы, что у полосового магнита, только огромный. Заряженная частица, захваченная на силовую линию, вьётся вдоль неё по спирали, и по мере усиления поля к полюсам тот же закон сохранения, который разгоняет пируэт фигуристки, прижавшей руки, заставляет ускоряться и вращение частицы вокруг силовой линии - а поскольку её полная скорость не меняется никогда, движение ВДОЛЬ линии обязано на столько же замедлиться. Запущенная преимущественно поперёк поля (большой питч-угол), она останавливается и разворачивается задолго до атмосферы - магнитное зеркало. Запущенная преимущественно вдоль поля (малый питч-угол), она не имеет достаточно поперечного движения для превращения и едет по силовой линии прямо вниз, в атмосферу, - это высыпание, и именно оно буквально стягивает сияние в кольцо вокруг каждого полюса.

Жидкость течёт по каналу вокруг всего, что стоит на пути: за цилиндром след теряет устойчивость и срывается знаменитой вихревой дорожкой Кармана. Рисуйте свои препятствия левой кнопкой, стирайте правой, впрыскивайте полосы краски и переключайте вид между краской, скоростью и завихренностью.

Четыре материала в одном решателе: снег сползает по склону, песок обрушивается, желе пружинит, вода течёт, и всё это облака материальных точек. Рисуйте материал левой кнопкой, взрывайте поток правой и переключайте сцены, чтобы увидеть, как каждый материал разрушается по-своему.

Тяжёлая частица, толкаемая невидимой тепловой баней, блуждает случайным образом. Одна траектория выглядит бесцельной, но ансамбль подчиняется строгому закону: средний квадрат смещения растёт линейно, и график накладывает измеренную кривую на предсказание 6Dt соотношения Эйнштейна. Подогрейте или добавьте трение.

Две вещи здесь считаются, а не принимаются. Поле интегрируется по Био - Савару по обеим катушкам, поэтому однородность пары Гельмгольца - результат: в центре оно сходится с формулой до десятой доли процента и перестаёт сходиться в нескольких сантиметрах от него. Орбита ведётся схемой Бориса, сохраняющей модуль скорости точно, и e/m читается обратно из радиуса, которого след действительно достиг.

Полотно ткани как тысячи ограничений расстояния: повесьте его на ветру, уроните на сферу или на пол и посмотрите, как возникают складки, морщины и самоконтакт. Меняйте материал от шёлка до резины, включите разрывание и следите по графику растяжения, как крепко решатель держит ткань.

Гибкий стержень в трёх измерениях: кабель провисает цепной линией между двумя стойками, защемлённая консоль вживую сверяется с учебниковым qL⁴/8EI, хлыст щёлкает на рукояти. Цвет трубки следует локальной кривизне — прямые участки холодные, крутые изгибы тепло светятся. Схватите любую точку мышью и тяните, или щипните стержень вверх либо вбок и смотрите, как волна бежит в пространстве. Ползунок изгиба — от варёной спагетти до пружинной стали; ползунок демпфирования решает, сколько живёт звон.

Катушка с железным сердечником и поднос с настоящими опилками - каждая жёсткая игла намагничивается, чувствует соседей и заваливается. Подними ток, и поднос встаёт щетиной, выгнутой от полюса; выключи ток, и узор держит трение; встряхни поднос, и всё начинается заново, каждый раз иначе. Катушку можно таскать мышью по листу; потяните за торец сердечника (или удерживайте Shift), чтобы повернуть её. Правая кнопка мыши вращает всю сцену.

Маятник качается в неподвижной плоскости; это Земля поворачивается под ним. На полюсе плоскость качания делает полный круг за сутки, на 45 градусах ей нужно около 34 часов, на экваторе она не поворачивается вовсе: прецессия идёт как синус широты. Тяните широту, пользуйтесь кнопками пресетов и ускорьте вращение, чтобы увидеть это ясно. Кольцо латунных колышков стоит у самой границы размаха: поворачивающаяся платформа вносит каждый в замороженную плоскость качания, и остриё боба его сбивает — постановка Пантеона, движимая настоящим размахом, а не скриптом.

Шары падают сквозь решётку пегов и складываются в отсеки. Нигде на доске нет подбрасывания монеты: каждый шар - сфера под действием тяжести, отскакивающая от круглых пегов с реституцией и трением, и колокол - это то, что дают такие столкновения. Доска - настоящая доска: щель глубиной в несколько шагов решётки между двумя стёклами, так что физика внутри честно трёхмерна, а статистика живёт вдоль x, где и гистограмма. Ряды решётки смещены на полшага: на квадратной сетке шары падают по коридорам между пегами и прилетают неотклонёнными. Наклоните доску, чтобы сместить результат: среднее сдвигается потому, что у тяжести появляется горизонтальная составляющая, а не потому, что подкрутили параметр.

Обучение нейросети И ЕСТЬ физика: потери - потенциальная энергия над пространством весов, а обучение - частица, катящаяся вниз. Трёхмерная поверхность - тот самый ландшафт, срез по двум направлениям сквозь 1194 измерения, перерисовываемый вокруг сети по мере её движения; светящийся шарик - сама сеть, а золотой след - только что пройденный спуск. Слайдеры - это механика: скорость обучения - шаг, momentum - инерция, проскакивающая овраги, а температура превращает спуск в динамику Ланжевена - нагрей, и шарик вечно дребезжит над минимумом, в точности как тепловая частица в яме. А панель из кубиков показывает цифру, которую сеть читает прямо сейчас.

Настоящая оптика, отрисованная трассировкой самого света: каждый кадр GPU пускает миллионы лучей сквозь призмы, линзы и стеклянные сферы, длина волны за длиной волны, поэтому радуги, каустики и полное внутреннее отражение возникают потому, что их требует физика. Картинка уточняется по мере накопления сэмплов; двигайте солнце и поднимайте дисперсию.

Нажмите на малый поршень - большой поднимет автомобиль. Давление одинаково во всей жидкости, поэтому F₂/F₁ = A₂/A₁ - но малый поршень обязан пройти во столько же раз больший путь, и работа с обеих сторон совпадает до последней цифры. Пресс - это рычаг, а не источник. Рядом четыре сосуда совершенно разной формы и объёма приходят ровно к одному уровню, потому что течение гонит давление, а давление зависит от глубины. U-образная трубка с двумя жидкостями НЕ выравнивается: она уравновешивается при ρ₁h₁ = ρ₂h₂ - так одну плотность и измеряют через другую. А дно сосуда не чувствует формы над собой: расширяющаяся банка с шестью литрами давит на своё дно ровно так же, как узкая с одним литром, если глубина та же. Разницу несут стенки, и в панели напечатаны оба числа, чтобы этот разрыв было видно, а не заявлено. А шар Паскаля делает сам закон видимым: надавите на плунжер - вода бьёт из всех отверстий, вверх, вбок и вниз, почти с одной скоростью, потому что добавленное давление приходит к каждому отверстию неослабленным. Оставшаяся разница - это ρgh тяжести, и с ростом давления она исчезает.

Ряд маятников с длинами, подобранными так, что i-й делает ровно K+i качаний за цикл: отпущенные вместе, они плетут бегущие волны, гребёнки и спирали, рассыпаются в хаос и в момент t = T снова собираются в одну линию. Каждый маятник - ПОЛНЫЙ нелинейный: поднимите амплитуду, и часовой механизм честно расстроится. График пишет хореографию одним числом - фазовой когерентностью r.

Сосчитайте нити, тянущие груз вверх, - это и есть выигрыш в силе, а не число из таблицы. Поднимите один и тот же вес через неподвижный блок или через шестикратный полиспаст: затраченная работа одинакова, полиспаст лишь размазывает её по шести метрам троса. Рядом со сборкой поднимаются две метки - груз и выбранный трос, - и расходятся ровно на величину выигрыша: сила покупается расстоянием и никогда энергией. Добавьте трение, и затраченная работа вырастет, а полезная не сдвинется: КПД умеет только отнимать.

Поезд Эйнштейна, поставленный по-настоящему: молнии бьют в оба конца идущего поезда, световые фронты растут кругами со скоростью c, и наблюдатель на перроне M ловит обе вспышки одновременно, а M′ в центре поезда встречает переднюю вспышку раньше. Поставьте галочку «ехать в поезде» — и ТЕ ЖЕ два удара нарисованы в кадре поезда: вагоны покоятся во всю длину, перрон утекает назад сжатым, удары больше не одновременны — а фронты по-прежнему круги со скоростью c, в чём и весь постулат. Потяните скорость системы отсчёта - и сетка Минковского скашивается вживую: мировые линии поезда наклоняются, а две молнии - одновременные на перроне - расходятся в системе поезда ровно на v·L₀. На стенде часов покоящиеся и летящие световые часы гоняют фотоны между зеркалами; путешественник рисует заметно более длинный зигзаг, и его счётчик отстаёт ровно в γ раз. Потом пустите мюонный дождь: при 0.995c падение с 15 км переживает примерно каждый десятый - точно по exp(−h/γvτ) - тогда как жизнь без замедления времени пропустила бы одного из десяти миллиардов. Поставьте галочку - и полетите вместе с ними: тогда сжимается гора.

Здесь свет представлен именно как волна. Снизу на экран с прорезями приходит плоская волна, проходит через открытые щели и дальше распространяется уже от каждой из них. Волны накладываются друг на друга: там, где их фазы совпадают, они усиливаются, а там, где приходят в противофазе, гасят друг друга. Так постепенно и появляется интерференционная картина.

Самое интересное, что полосы на экране здесь не нарисованы заранее по готовой формуле. В режиме Live Field программа численно решает двумерное волновое уравнение на сетке и показывает, как волна действительно проходит через щели, расходится за ними и интерферирует. Интенсивность на экране тоже измеряется из этого поля - программа некоторое время накапливает квадрат амплитуды пришедшей волны, примерно как при длительной экспозиции фотопластинки.

Здесь чёрная дыра не нарисована заранее и не сделана как обычный 3D-объект с красивой текстурой. Картинка собирается прямо во время работы программы. Для каждого пикселя камера как будто запускает луч света назад в пространство и смотрит, откуда он мог прийти.

В обычной сцене такой луч летел бы по прямой. Но рядом с чёрной дырой пространство-время сильно искривлено, поэтому изгибается и траектория света. В модуле эти траектории рассчитываются для чёрной дыры Шварцшильда - то есть невращающейся чёрной дыры.

Если луч проходит слишком близко, он уже не возвращается наружу. Так появляется чёрная область в центре. А свет, который проходит чуть дальше, может очень сильно отклониться. Иногда он почти обходит чёрную дыру, прежде чем попасть к наблюдателю. Из-за этого вокруг неё и возникает характерное яркое кольцо.

Маятник кажется самой скучной вещью в физике. Груз на верёвке, качается туда-сюда, период считается по формуле из школы. Я сделал семь разных маятников в одной программе, и оказалось, что скучный из них ровно один - да и тот при внимательном взгляде врёт.

Начнём с обычного. Школьная формула для периода верна только при малых углах, где-то до пяти градусов. Отклоните маятник сильнее, и период вырастет: при 90 градусах примерно на 18 процентов, при 170 - почти вдвое. Причина в том, что возвращающая сила пропорциональна не самому углу, а его синусу, и при больших отклонениях синус начинает заметно отставать. В программе точный период считается честно, через эллиптический интеграл, и его видно рядом со школьным.

Дальше начинается интересное. Прицепите к маятнику второй - и предсказуемость кончается. Запустите десяток копий, отличающихся на тысячную долю градуса: сначала они идут вместе, потом расходятся, и через десяток секунд каждая живёт своей жизнью. Это и есть хаос, причём никакой случайности в уравнениях нет - они полностью детерминированы. Просто ошибка растёт экспоненциально, и любая неточность в начальных условиях через какое-то время становится размером с сам ответ.

Пружинный маятник умеет качаться и подпрыгивать одновременно. Если подобрать жёсткость так, чтобы частота подпрыгивания была вдвое выше частоты качания, начинается перекачка: маятник раскачивается, потом качание затухает и вместо него появляется подпрыгивание, потом обратно. Энергия ходит между двумя движениями сама по себе.

Резонанс. Качаете маятник медленно - он вяло следует за вами. Быстро — почти не двигается. А на своей собственной частоте амплитуда взлетает. Насколько именно — зависит от трения: чем его меньше, тем выше и уже пик. В программе этот пик рисуется как кривая, и по ней сразу видно, почему солдатам запрещают идти по мосту в ногу.

И напоследок самый знаменитый. Маятник Фуко качается в одной плоскости, а плоскость эта медленно поворачивается. Только поворачивается не она - поворачивается Земля под ним. На полюсе полный оборот за сутки, на широте Москвы примерно за 30 часов, на экваторе не поворачивается вообще. Фуко подвесил такой маятник в Пантеоне в 1851 году и показал вращение Земли людям, которые в жизни не выходили из Парижа.

В этой программе нет ни одной нарисованной спирали. Есть тридцать тысяч точек, у каждой своя масса, и один закон: каждая притягивает каждую. Дальше компьютер считает, куда они полетят.

Возникает вопрос, как такое считается в реальном времени. Тридцать тысяч звёзд, каждая тянет каждую, это девятьсот миллионов пар на каждом кадре. Хитрость в приёме под названием дерево Барнса-Хата: далёкую группу звёзд заменяют одной точкой с общей массой, примерно как вы не считаете притяжение каждого камня в горе, а говорите «гора». Точность падает чуть-чуть, работы становится в тысячи раз меньше.

Нутация - это кивание, которое волчок совершает вдобавок к прецессии: угол наклона θ не стоит на месте, пока ось обходит вертикаль, а опускается и поднимается. Мой модуль гироскопа решает тяжёлый симметричный волчок честно - RK4 по (θ, θ), с двумя сохраняющимися импульсами p_φ и p_ψ, зафиксированными при запуске, - поэтому кивание не анимация, добавленная для вида: оно вытекает из тех же уравнений, что дают прецессию.

Твёрдое тело, свободно вращающееся в невесомости, причём момент сил не действует на него ни в один момент времени. Из уравнений Эйлера следует, что у любого тела три главные оси, и вращение вокруг наибольшего и наименьшего моментов инерции устойчиво, а вокруг среднего — нет: крохотная боковая составляющая растёт экспоненциально со скоростью σ = ω·√((I₂−I₁)(I₃−I₂)/(I₁I₃)), дорастает до величины самого вращения, переворачивает тело — и всё начинается заново. Переворот ничем не вызван: жёлтая стрелка — момент импульса в пространстве, и она неподвижна, пока тело кувыркается вокруг неё. Кувыркание — это то, как выглядит сохранение, когда ось вращения средняя. Каждая декада уменьшения начального возмущения откладывает первый переворот на ln(10)/σ — на константу, а не в разы, — поэтому настоящая гайка-барашек продолжает переворачиваться примерно с одинаковым интервалом, а не успокаивается. В панели напечатан дрейф обоих инвариантов, |L| и энергии: модуль, утверждающий «на тело ничто не действует», обязан показать, что и его интегратор на тело не действует.

Например, здесь можно посмотреть на визуализацию молекулярных структур. Такие модули для меня интересны не столько как «красивая картинка», сколько как возможность сделать объект наглядным и интерактивным — чтобы его можно было рассматривать, вращать и исследовать.

А это уже совсем другая задача — гравитационная симуляция большого количества объектов.

Здесь интересно то, что каждая частица взаимодействует с остальными, поэтому при прямом расчёте количество вычислений очень быстро становится огромным. Для подобных задач приходится использовать алгоритмические оптимизации, например Barnes–Hut, и думать уже не только о физике, но и о производительности.

Отдельное направление проекта — оптика.

Можно размещать источники света, линзы и другие объекты, менять их параметры и непосредственно наблюдать, как распространяются лучи.

Мне всегда нравилась идея виртуальной лаборатории, где вместо заранее записанной анимации пользователь сам собирает эксперимент.

Есть и более привычные физические эксперименты: электричество, электромагнетизм, цепи, катушки и другие системы.

Причём часть комплекса — это не просто визуализация. Например, электрические схемы можно собирать из компонентов, соединять их проводниками и запускать расчёт получившейся цепи.

По сути, программа одновременно является редактором схемы и симулятором.

Я стараюсь делать визуализацию так, чтобы происходящее было не только математически интересно, но и просто приятно было наблюдать.

Есть различные волновые модели: распространение волн, интерференция и взаимодействие с объектами.

Такие вещи особенно хорошо показывают, зачем вообще нужна компьютерная симуляция. Формулу можно написать на бумаге, но когда видишь процесс в движении, интуитивно понимать его становится намного проще.

Одна из моих любимых тем — моделирование жидкостей.

Здесь используется SPH (Smoothed Particle Hydrodynamics): жидкость представляется большим количеством взаимодействующих частиц, а поверхность затем визуализируется уже как единый объём.

Уточка физически совершенно необязательна.

Но без уточки эксперимент был бы объективно хуже.

И, конечно, есть обычная механика: твёрдые тела, столкновения, конструкции, гравитация и устойчивость систем.

Практически весь этот проект я делаю самостоятельно.

Основная часть написана на C#/.NET. Для графики использую в том числе OpenGL, для некоторых расчётов — GPU. В проекте есть как обычная растеризация, так и ray tracing/path tracing, разные численные методы и собственные реализации физических алгоритмов.

Но конечная цель для меня не в том, чтобы собрать коллекцию технических демонстраций.

Мне хочется сделать своего рода универсальную виртуальную лабораторию: открыл программу, выбрал интересующую область физики, собрал эксперимент, изменил параметры и сразу увидел результат.

Программа доступна на Steam:

23
8
1
1
1