Моделирование планеты маргариток
- Лирика
- Описание интерфейса
- Декомпозиция
- Модель
- Логика
1. Лирика
Давным-давно, не помню где, я узнал об одном удивительном эксперименте, начало описания было такое: Представьте себе планету, примерно такую, как Земля, которая вращается вокруг звезды примерно такой, как Солнце. На планете есть жизнь, но не очень разнообразная — всего два вида маргариток — черные и белые. Представили? Какой заход! Автор красавчик, почти Экзюпери.
Далее описывался эксперимент: В начальной точке маргаритки есть только в виде семян, а планета настолько холодна, что на экваторе температура на грани выживания. Тем не менее прорастает несколько маргариток черных и белых, и они даже начинают цвести. Белая маргаритка, из-за своей большой отражательной способности отражает больше света, чем зеленые листики и коричневая земля, в этом месте локально становится холодней, и она замерзает. Вокруг черной маргаритки, наоборот возникает небольшая прогретая зона, так как она поглощает больше энергии от звезды. Маргаритка начинает чувствовать себя лучше, цветет, а потом, в прогретую землю бросает свои семена. Из этих семян прорастают еще несколько черных маргариток (потому что родитель у них черный), цветение этих маргариток прогревает еще больший участок, на котором может расти еще больше маргариток, и они тоже будут черными, потому что здесь оставляют семена только черные маргаритки.
Таким образом, потепление, вызванное цветением черных маргариток, провоцирует еще большее распространение черных маргариток, которые в свою очередь прогревают больше площади вокруг себя, и так по кругу. Таким образом черные маргаритки захватывают экваториальную область, но дальше распространяться не могут — там слишком холодно.
Однако такое бурное цветение черных маргариток уменьшает отражательную способность всей планеты (альбедо), это повлияет на баланс поглощенной/отраженной энергии в планетарном масштабе, что приводит к повышению эффективной температуры планеты, то есть на всей планете становится теплей. После этого черные маргаритки еще немного расширяют свои территории на юг и на север, что в свою очередь приводит к еще большему глобальному потеплению. Таким образом черные маргаритки пробираются к полюсам, а планета разогревается.
Но не нужно забывать — на планете стало теплее, и теперь есть все условия для роста и белых маргариток тоже. Более того, по мере прогрева, на экваторе становится все жарче, а черные маргаритки еще сильнее утепляют землю вокруг себя, и в этом районе им становится все более некомфортно. Не то, что белым маргариткам, которые отражают больше энергии, и создают вокруг себя приятную прохладную зону, в которой им хорошо расти, и туда же отбрасывать семена. Ну вы поняли — белые теснят с экватора черных. Но тут сюрприз — альбедо планеты снова увеличивается из-за больших площадей белых маргариток, планета холодеет и в конечном итоге наступает некоторое равновесие.
Далее автор не намерен оставлять планету в этом унылом для него, и комфортном для маргариток состоянии. Происходит вот что — Звезда, как у них это обычно бывает, начинает светиться ярче, и на планету падает больше энергии. Реакция планеты — увеличение площади распространения белых маргариток, увеличение альбедо — и снижение эффективной температуры, переход в новое равновесное состояние. Почти то же самое происходит при снижении светимости звезды, только появляется больше черных маргариток.
Вывод, который делает автор — биосфера сама себе создает комфортные температурные условия на планете в широких диапазонах светимости звезды. Авторов этого замечательного эксперимента зовут Джеймс Лавлок и Эндрю Уотсон. Кому интересны все выводы и более подробное описание см. Википедия — Маргаритковый мир, там написано больше и лучше. Смысл этого долгого вступления не пересказать статью из вики, а подвести к самому интересному — непосредственно проведению эксперимента. Автор статьи, описывающей эксперимент, задавал риторический вопрос: Рассуждения выглядят логично, но как провести такой эксперимент, где взять планету со звездой, с подходящими условиями, и как доставить туда семена маргариток? Даже если кому-то взбредет в голову использовать для этого Марс то у него ничего не получиться. Я был очень опечален таким поворотом потому, что большой фанат терраформирования и крутых экспериментов. Но автор, к моей большой радости, сказал, что такой эксперимент возможен с помощью компьютерного моделирования.
Ну конечно!!! Этот эксперимент, как бы собственно для компьютерного моделирования и был придуман, и даже достиг своей цели (ну то есть посрамил каких-то там двух мудрецов, см. вики). На этом отрезке повествования об эксперименте у меня прям сперло дыхание, потому что я подумал о счастливчиках, которые смотря на это описание, каким-то образом, превращают идею во что-то наглядное, доступное для того, чтобы посмотреть в реальном времени, «потрогать руками». При том, интересен был как сам процесс моделирования, так и проведение экспериментов. Прочитать эксперимент и подивиться выводам это одно, а «поиграть» с этой планетой, поэкспериментировать с разными условиями, это совсем другое. Но тогда я еще не мог программировать :(, но настали нынешние времена, к счастью, и поэтому предлагаю перейти от длинной и скучной лирики, к содержательной части. Кто просто хочет поиграть с планетой может переходить к описанию интерфейса, кого увлекает процесс моделирования к части под названием Декомпозиция и далее.
2. Описание интерфейса
![](https://habrastorage.org/webt/fj/up/jq/fjupjqeefu_k9quyvbhxaxcvf4k.jpeg)
В левой части расположено два блока Populator и Updater, в центральной части визуальное отображение планеты и некоторых параметров, в правой части графики изменения эффективной температуры и Звездной постоянной.
Управление осуществляется в блоках Populator и Updater.
В блоке Populator можно задать соотношение белых маргариток, черных маргариток и пустых ячеек, после нажатия кнопки Populate, планета будет заселена соответствующим образом. Заселить планету можно как в начале эксперимента, так и в любой другой момент, если понадобится.
Блок Updater отвечает за обновление модели планеты, в нем можно задать количество обновлений за раз, а также значение (допускаются отрицательные) и периодичность инкрементирования звездной постоянной (например, обновить 100 раз, при этом увеличивать звездную постоянную на 1 каждые две итерации).
Визуальное отображение планеты:
Белые кружочки — это районы с белыми маргаритками, черные — с черными, оливковые — пустые ячейки.
В левом верхнем углу текущие значения эффективной температуры по кельвину, звездной постоянной, альбедо и номер итерации.
Справа от планеты две цветовые шкалы: левая — для черных маргариток, правая для белых. Каждая точка шкалы соответствует температуре расположенного напротив пояса планеты. Легенда такая: Синий — слишком холодно для жизни, Желтый — жить можно, Зеленый — жить не только можно, но и комфортно, Красный — слишком жарко для жизни.
3. Декомпозиция
В приложении использован паттерн MVC, хотя в JavaFX, как известно вью и контролер немного слиплись, зато границы модели очерчены совершенно отчетливо.
Модель, в свою очередь, также разбита на часть, отвечающую за состояние, и часть, отвечающую за поведение, в лучших традициях, так сказать. Еще есть часть, отвечающая за сохранение результатов в БД, работает вроде нормально, но в интерфейс и в настройки не стал выносить за ненадобностью. Вид и слой персистентности описывать не буду, ниже все про модель и поведение.
4. Модель
Модель представлена шестью обычными классами Planet, Starr, Zone, Conditions, BlackDaizy, WhiteDaizy, NoDaizy, одним абстрактным Daizy, и одним перечислением Type. Хотя можно было и меньшим числом классов, я подумал, что звезда настолько крупная и важная вещь, что оставлять ее без класса было бы некрасиво. А для маргариток, в программе под названием «Планета Маргариток» была выстроена целая небольшая иерархия классов, и даже введено перечисление. Таким образом, основные классы, определяющие состояние это, Planet, Conditions и Zone.
Planet — является основным агрегирующим классом, экземпляр этого класса в приложении играет роль модели, из него контроллеры получают состояние для вью, а классы, отвечающие за поведение, получают ссылку на экземпляр Planet для изменения состояния.
Класс Planet содержит поля, характеризующие состояние планеты: это
/** Отражающая способность, характеризуется отношением отраженного света к падающему*/
private double albedo = 0;
/** Эффективная температура: зависит от поглощаемой энергии,
* вычисляется как температура абсолютно черного тела по закону Стефана-Больцмана*/
private double temperature = 0;
/** Да планета имеет размер*/
private double radius = Conditions.getInstance().radius;
/** количество поясов на которое разбито одно полушарие, локальная температура вычисляется для каждого пояса, на всей площади одного пояса — одинаковая температура*/
private int halfZonation = Conditions.getInstance().halfZonation;
/** фрагментация пояса: максимальное количество маргариток на пояс,
на всех поясах - количество маргариток одинаковое, это не ограничение программы, а геометрический закон, ибо пояса с одинаковой высотой имеют одинаковую площадь,
* так - то*/
private long daiziesPerZone = Conditions.getInstance().daiziesPerZone;
/** эффективная площадь - проекция планеты на плоскость перпендикулярную направлению излучения идущему от звезды к планете, используется для расчета альбедо */
private double effectiveArea;
/** площадь пояса. у всех поясов area - одинаковая
S = 2?rh,
r – радиус сферы,
h – высота сферического пояса.
*/
private double zoneArea;
/** условная площадь одной маргаритки, справочный параметр*/
private double daisyArea;
Кроме того, класс Planet содержит ссылку на звезду Starr, массив экземпляров класса Zone, каждый элемент которого характеризует отдельный пояс, счетчик апдейтов, признак inhabited ну, то есть обитаемая ли планета. А также ссылки на классы, отвечающие за поведение
PopulatorImpl populator = new PopulatorImpl();
AlbedoCalculator albedoCalculator = new AlbedoCalculatorImpl();
о которых речь пойдет ниже.
Второй важный класс — это Conditions, в нем собраны все константы. Вот некоторые
public double Kelvin = -273.15;
// Planet constants
public double radius = 1000.0;
public int halfZonation = 90;
public long daiziesPerZone = 100;
/**
эмпирическая отсебятина: разница температур на экваторе и на полюсах, если вычислять в зависимости от широты
то на полисе окажется нулевая по кельвину, что противоречит здравому смыслу
величина должна зависеть от теплопроводности планеты, миграции тепла по атмосфере, и т.п.
к тому же температура на поверхности должна быть выше расчетной из-за того, что поверхность первой прогревается,
и из-за парникового эффекта, если, конечно, есть подходящая атмосфера
*/
public double planetDeltaTemper = 70.0;
/* используются для вычисления большого альбедо*/
public double blackDaisyAlbedo = 0.1;
public double whiteDaisyAlbedo = 0.9;
public double noDaisyAlbedo = 0.5;
/* Значение комфортной температуры для жизни маргариток
Собственно, реализация прогрева и охлаждения почвы вокруг маргариток,
*/
public double blackComfortableTemper = 18 + (-Kelvin);
public double whiteComfortableTemper = 22 + (-Kelvin);
/**Звездная постоянная - суммарная мощность излучения звезды, проходящего через единичную площадку,
* ориентированную перпендикулярно потоку, на расстоянии одной астрономической единицы от Звезды
* для Солнца и Земли равняется 1367 Вт/м?*/
public double StarConstant = 1367.0;
/** Значение постоянной Стефана-Больцмана
* */
public double StephanBoltsmanConst = 5.67e-8;
И третий важный, но не большой класс модели Zone:
/** высота границы ближайшей к экватору */
private double latitude;
/** эффективная площадь - проекция половины шарового слоя на плоскость,
* используется для расчета альбедо */
private double effectiveArea;
/** высота шарового слоя*/
private double height;
/** температура на поверхности в данной zone*/
private double localTemperature;
// количество маргариток
private long numBlackDaisies;
private long numWhiteDaisies;
private long numEmptyCells;
Обратите внимание на метод установки локальной температуры вычисляет температуру, как описано выше:
public void setLocalTemperature(double globalTemperature) {
this.localTemperature = globalTemperature + Conditions.getInstance().planetDeltaTemper*Math.cos(latitude);
}
В классе нет методов, вычисляющих состояние, значение всех полей передается в параметрах конструктора, либо устанавливаются сеттерами.
5. Логика
Почти всё поведение собрано в паке logic, и представлено следующими классами:
ZoneMaker — класс используется для создания всего массива зон планеты, с учетом того, что у разной планеты может быть разная фрагментация (количество зон), а у каждой зоны своя уникальная широта, соответствующая индексу в массиве
AlbedoCalculator — интерфейс, единственный метод
double calcAlbedo(Zone[] zones);
его реализации используются для вычисления альбедо всей планеты в зависимости от соотношения черных и белых маргариток и незанятого пространства, а также внимание, их расположения — так как маргаритки, растущие на разных широтах, вносят разный вклад в общее альбедо.StephanBoltsman — класс для расчета эффективной температуры планеты.
Populator — интерфейс, отвечающий за заселения планеты маргариткам.
Метод
void populate(Zone zone, int whiteExpectance, int blackExpectance, int noneExpectance);
предназначен для заполнения одной, переданной в параметре, зоны, параметры
int whiteExpectance, int blackExpectance, int noneExpectance
что-то вроде математических ожиданий, в зависимости от их соотношения, в случайном порядке по зоне будут посажены белые и черные маргаритки, или будет сделан пропуск, но общее число ячеек для маргариток в зоне всегда постоянно, и зависит от начальных настроек (задается Conditions.daiziesPerZone).
Этот метод используется в двух других методах, которые заполняют уже все зоны на планете:
void populateInitial(Zone[] zones, int whiteExpectance, int blackExpectance, int noneExpectance);
Заполняет все зоны с одинаковым соотношением. В конструкторе планеты стоят параметры 0,0,1. То-есть планета создается необитаемой.
Метод
void rePopulate(Planet planet);
является реализацией механизма вытеснения маргаритками маргариток, и заполнения пустого пространства. Он используется для перераспределения маргариток на планете, в зависимости от сложившихся на Планете условий. Метод работает приблизительно следующим образом: в нем определены три переменные, в первую очередь они устанавливаются в значения количества белых, черных маргариток и пустых ячеек очередной зоны.
Далее, если температура для какого-либо вида маргариток не соответствует жизненным условиям, соответствующий параметр обнуляется. Если соответствует жизненным условиям, то значение остается неизменным. Если температура находится в интервале комфорта, то значение удваивается. В случае, если температура впервые стала пригодна для жизни, для какого-либо вида маргариток, то соответствующий параметр устанавливается в среднее арифметическое от количества соответствующих маргариток из смежных зон.
И наконец, нужно описать метод update() класса Planet, который отвечает за жизненный цикл каждой итерации:
public void update() {
albedo = albedoCalculator.calcAlbedo(zones);
temperature = StephanBoltsman.countTemperature(albedo,star.getStarConstant());
updateLocalTempers();
populator.rePopulate(this);
iterationId++;
}
В первую очередь вычисляется альбедо планеты, исходя из количества и расположения маргариток. Затем вычисляется эффективная температура планеты используя только что найденное альбедо и звездную постоянную (значение которой также может измениться). Затем обновляются значения локальных температур в зонах исходя из найденной эффективной температуры. И в конце, используя новые данные локальных температур, осуществляется перераспределения маргариток.
Ссылка на гит. Сборка: gradlew build
Комментарии (16)
Survtur
05.11.2017 23:11Называется Модель Лавлока. Лично я читал про маргаритковый мир в книге «Кирилл Еськов: Удивительная палеонтология. История Земли и жизни на ней». Очень рекомендую книгу. Написано не как скучные исторические факты, а как последовательный рассказ с причинами, следствиями и примерами.
модель ЛавлокаИтак, модель Лавлока. Гипотетическая планета, имеющая те же примерно параметры, что и Земля, вращается вокруг звезды того же спектрального класса, что и наше Солнце. Большую часть поверхности планеты занимает суша, которая повсеместно обводнена и допускает существование жизни. Планета называется Маргаритковый Мир, ибо единственная форма жизни на ней – маргаритки (Bellis) с темными и светлыми цветами (ТМ и СМ). Эти растения способны существовать в температурном диапазоне от 5 до 40°C, предпочитая температуру 20°C. Светимость местного Солнца, согласно одной из современных астрофизических гипотез, закономерно возрастает по мере его «старения», поэтому температура планетной поверхности вроде бы должна на протяжении всей ее истории увеличиваться, причем практически линейно.
Но вот экваториальная область планеты нагрелась до оговоренных 5°C, и тут на сцене появляются наши маргаритки – ТМ и СМ в примерно равной пропорции. При этом в тех местах, где доля темных цветов случайно окажется выше средней, локальное альбедо будет несколько уменьшаться, а грунт прогреваться до более высокой температуры, т.е. более близкой к оптимальным для маргариток 20°C. В итоге ТМ получат селективное преимущество перед СМ и доля последних уменьшится до предела. С этого момента в системе складывается положительная обратная связь: темные цветы несколько понижают суммарное альбедо планеты; прогретая до 5°C (и пригодная для жизни маргариток) область расширяется от экватора, что вызывает дальнейшее понижение альбедо, и т.д. Но вот наступает время, когда на планете, уже полностью заселенной ТМ, температура на экваторе переваливает за 20°C в результате усиления светимости Солнца. С этого момента селективные преимущества оказываются на стороне светлых цветов, увеличивающих локальное альбедо и понижающих температуру своих местообитаний. Расселение по планете СМ, вытесняющих ТМ, происходит по точно такой же схеме (от экватора к полюсам) и тоже с положительной обратной связью. Светимость Солнца тем временем продолжает расти; наступает момент, когда возможности СМ по кондиционированию среды обитания оказываются исчерпанными; температура переваливает за 40°C, и планета опять становится безжизненной. Так вот, расчеты Лавлока показали, что на протяжении почти всего времени между этими двумя критическими моментами температура поверхности планеты будет практически постоянной – около 20°C (рис. 15), несмотря на непрерывное возрастание светимости Солнца.
Даже такая суперпримитивная биосфера (состоящая из единственного вида растений, которые всего-то и умеют, что варьировать цвет своих лепестков) способна создавать эффект вполне космического характера – глобально менять температуру поверхности планеты. Однако более существен не факт изменения температуры, а то, что планета превращается в гомеостат и поддерживает свою температуру постоянной вопреки внешним изменениям (светимости Солнца). Замечательно и то, что система как целое работает с отрицательной обратной связью, хотя каждый из ее элементов – с положительной; это является характерной особенностью именно живых систем (вспомним, например, систему «хищник – жертва»).Survtur
05.11.2017 23:17
Рис. 15. «Маргаритковый Мир» Лавлока. Изменения температуры поверхности планеты с изменением светимости Солнца (1,0 – нынешнее состояние) при наличии единственной морфы маргариток (а) и при двух, «светлой» и «темной», способных кондиционировать среду обитания (б) (по Lovelock, 1982)
Survtur
05.11.2017 23:20Блин, прочитал начало статьи и побежал вспоминать, где же я про такое читал и как это называется., а в статье подальше уже всё написано. 15 минут жизни потерял :-/
DanilinS
05.11.2017 23:29А какой смысл этой статьи? Изучение основ программирования?
Я ожидал красивых графиков результатов, анализа динамики развития ситуации. Любопытно посмотреть на устойчивость модели. Возможность существования стационарных состояний. Устойчивость этих состояний к возмущениям.
А сейчас это статья плана «есть интересная задача и я написал программу для неё. » Может и мне писать сюда все программки, что я пишу? (сарказм)izzholtik
05.11.2017 23:41В репозитории лежит pom. Возможна
человечесаясборка через Maven, или он нерабочий?
не та ветка, да.. (izzholtik
06.11.2017 03:07Понял, рабочий.
Вам стоит пробежаться по приложению профилировщиком, 50% производительности теряется на перерисовке UI после обсчёта (слишком много точек графика?), из оставшейся половины 25% оседают на форматировании строк в вызовах логгера и 10% — на чудесной строке
Random random = new Random(GregorianCalendar.getInstance().getTimeInMillis());
Итого выходит, что непосредственно вычисления выполняются 25-40% времени (разные профилировщики врут по-разному). Печально это всё.SergeyImber Автор
06.11.2017 09:07Спасибо огромное за рекомендации. В дополнение могу еще посоветовать не проводить эксперименты с числом операций более 40 000, забивается оперативка
SergeyImber Автор
06.11.2017 08:25Но ведь в программе Вы сами можете получить результаты, проверить ее устойчивость, посмотреть на графики, разве не в этом прелесть моделирования? Задача давно решена, усложнена, а потом решена снова, результаты можно найти при желании, наверное. Смысл статьи в том, чтобы рассказать про идею, и дать возможность самому поиграть с планетой.
third112
06.11.2017 03:52Метод работает приблизительно следующим образом
Что значит «приблизительно»? В методе используются приближенные вычисления? В методе баги? Что-то еще?SergeyImber Автор
06.11.2017 09:17Спасибо за интерес. В методе, для оптимизации некоторые проверки происходят раньше, плюс есть дополнительные операции. Приблизительно — означает, что если описывать метод так как он представлен в коде было бы скучно читать, поэтому такой реверанс. На счет багов, вроде не замечено.
xilix
Очень интересная история про маргаритки. Буду детям рассказывать. Спасибо.
SergeyImber Автор
Спасибо