Наконец, необходимо рассмотреть то, как согласуются с объектно-ориентированным подходом менее универсальные понятия вычислительной математики, чем описанные выше понятия системы уравнений, схемы и сетки. Прежде всего, существуют многообразные свойства расчётных схем: явность, устойчивость, монотонность, консервативность, гибридность и т.д. Свойства устойчивости и монотонности являются чисто математическими и не имеют отношения к реализации схем; поэтому объектно-ориентированный подход не привносит в эти понятия ничего нового. Почти то же можно сказать о консервативности (свойство, имеющее смысл для гиперболических уравнений), однако практика показывает, что схемы, являющиеся удобными для своей объектной реализации, обычно одновременно являются консервативными. Это связано с тем, что объектные схемы всегда ближе к физике задачи, и реализующие их элементы соответствуют реальным объектам.
Гибридные схемы решения уравнений в частных производных (прежде всего гиперболических, поскольку именно они имеют требующие гибридизации разрывные решения) несколько проще реализуются с помощью объектно-ориентированного подхода, чем с помощью процедурного. Благодаря тому, что схема как объект в разделе 3.2.2 была отделена от самого расчётного элемента (в данном случае – от сеточного узла), для совместного использования в каждом узле двух схем, совершенно не нужно изменять ни код элемента, ни код схем. Достаточно создать класс гибридной схемы (один класс для всех возможных пар элементарных схем!), которая будет в соответствии с градиентом решения интерполировать результаты, получаемые по каждой из двух схем.
Несколько менее впечатляющим выглядит применение объектно-ориентированного подхода к реализации неявных схем. С одной стороны, самый простейший объектно-ориентированный численный метод для уравнений практически любого типа (который не следит за тем, на каком временном слое или на какой итерации берутся значения параметров) фактически является полуявным (треугольным), в то время как простейший процедурный численный метод – явный. С другой стороны, решение какой-либо вспомогательной системы уравнений на верхнем слое объектно-ориентированным способом достаточно сложно. В случае обыкновенных дифференциальных уравнений вспомогательная система уравнений нелинейная, и единственный разумный способ её решения состоит в привязке к основному расчётному элементу – к дифференциальной системе – ещё одного элемента (алгебраической системы). На каждом шаге своего решения дифференциальная система должна изменять некоторые коэффициенты алгебраической, после чего итерировать её схему до получения заданной точности.
Реализация неявных схем в случае пространственно-распределённых задач возможна без использования вспомогательных элементов, но лишь ценой существенного усложнения структуры и функций основных элементов – сеточных узлов. Большинство алгоритмов решения уравнений на верхнем временном слое не являются локальными, в отличие от самих схем для уравнений в частных производных, поэтому теряются некоторые преимущества объектного подхода по отношению к таким уравнениям. К примеру, алгоритм прогонки (даже монотонной прогонки) требует двукратного обращения к методам одного и того же сеточного узла: первый раз для вычисления прогоночных коэффициентов, а второй – для расчёта искомых параметров в этих узлах. Код метода прогонки получается более компактным и развиваемым, если выделить прогоночные коэффициенты в отдельный элемент, связанный с каждым сеточным узлом. Прямой ход прогонки состоит в цепочке вызовов методов расчёта именно этих вспомогательных элементов, и только на обратном ходу прогонки сами сеточные узлы последовательно вызывают друг у друга методы обновления своего состояния. Следует заметить, что распространение простейшего алгоритма прогонки на более сложные задачи (многомерные, с циклическими граничными условиями и т.д.) приводит к серьёзным трудностям, а объектно-ориентированная немонотонная прогонка вообще, по-видимому, невозможна. Если же решать уравнения на верхнем слое итерационными методами, то возникает необходимость в описанных выше вспомогательных элементах алгебраической системы уравнений, привязанных, в данном случае, к каждому сеточному узлу. Тем не менее в разделе 3.3.2.2 показывается, что и в случае неявных схем ООП может стимулировать развитие численных методов.
Выше речь шла о применимости объектов к некоторым типам схем; осталось рассмотреть их эффективность с точки зрения некоторых видов пространственных сеток. Отсутствие регулярной структуры сетки вполне соответствует объектному подходу, поскольку он (в отличие от процедурного) также не предполагает упорядочение узлов по координатам в массивах. Более того, так как для нерегулярных сеток характерно использование в разных узлах шаблонов разного размера и схем различного типа, объектный подход выглядит намного эффективнее процедурного в плане хранения коэффициентов этих схем. Он также облегчает алгоритмы поиска наилучших узлов шаблона.
Методология адаптивных сеток, применяющаяся для получения решений с большими градиентами, плохо соотносится с принятым в данной работе подходом. Если сеточные узлы просто перемещаются в пространстве (скапливаясь в областях «разрывов»), а их число остаётся неизменным, то никаких неудобств представление узлов в виде объектов не вызывает. Правда, и преимуществ никаких это представление не несёт: на каждом шаге по времени состояние узлов меняется полностью (это не согласуется с их объектной природой), причём за это отвечают не сами узлы (практически не взаимодействующие друг с другом), а внешний алгоритм. Если же число узлов со временем может изменяться, то объектный подход приведёт к недопустимым затратам ресурсов: нельзя конструировать (и уничтожать) тысячи объектов на каждом шаге по времени.
Описанные выше отношения между объектными трактовками различных понятий вычислительной математики резюмируются на рис. 3.2, а изложенные соображения о применимости объектно-ориентированного подхода к этим понятиям – в табл. 3.1.
Уровень последовательности вычислений | |
Уровень расчётов по формулам | |
Уровень взятия и присвоения значений | |
Рис. 3.2. Отношения агрегации между классами объектов, соответствующими основным понятиям вычислительной математики | |
Примечание 1. Рисунок соответствует объектной нотации UML, цифры около конца связи между классами означают её кратность (число объектов, которое может содержать агрегирующий объект) | |
Примечание 2. Кратность связи класса элемента с самим собой (0..*) указана для случая однотипных элементов (например, узлов сетки); при использовании сложных методов элемент может иметь ещё одну принципиально иную связь с элементом другого типа |
Таблица 3.1
Применимость ООП к некоторым понятиям вычислительной математики
Понятие | Степень соответствия ООП | |
Система уравнений | Выше среднего | ООП наиболее полезен, если совместно решаются несколько связанных систем, особенно разных типов |
Схема | Средняя | объектное представление схемы нужно лишь для создания легко развиваемых библиотек численных методов; объектное представление параметра схемы значительно сокращает код, но увеличивает ресурсоёмкость программ; объектное представление элементов (систем) позволяет упорядочивать их переходы к следующим моментам времени (или итерациям) |
Пространственная сетка и шаблон | Высокая | объектное представление узлов сетки позволяет гораздо эффективнее использовать характерное для распределённых задач условие локальности связей между узлами |
Гибридная схема | Выше среднего | ООП позволяет при гибридизации использовать ранее реализованные негибридные схемы, не изменяя их |
Неявная схема | Ниже среднего | объектная реализация неявных схем столь же сложна, как и процедурная, а в случае пространственно-распределённых задач теряется локальность алгоритмов и многие связанные с ней преимущества ООП |
Нерегулярная сетка | Высокая | нерегулярные сетки с помощью ООП реализовать даже проще, чем регулярные |
Адаптивная сетка | Низкая | объектная реализация алгоритмов перемещения сеточных узлов слабо отличается от процедурной, а динамическое создание (удаление) узлов в случае использования ООП недопустимо |
Все методы решения обыкновенных дифференциальных уравнений (ОДУ) делятся на одношаговые и многошаговые, и их объектная реализация существенно различается.
В принципе, при объектном представлении параметров очень удобно хранить в них любое требуемое число их значений на последовательных шагах по времени, что создаёт предпосылки для реализации многошаговых схем. Однако правая часть уравнений обычно состоит не только из параметров, но и из объектов-функций и объектов-операций, для которых хранение истории своего изменения во времени является избыточным. Поэтому целесообразно создавать специальные объекты (класса «параметр»), в каждом из которых хранить последовательность значений одного компонента вектора правой части. Кроме того, сложные задачи, для которых имеет смысл применять объектно-ориентированный подход, обычно приводят к жёстким системам уравнений, в связи с чем необходимо изменять шаг по времени в ходе расчётов, а к этому многошаговые схемы можно приспособить только за счёт существенного усложнения алгоритма. Такие задачи также часто содержат не только сосредоточенные, но и распределённые подсистемы, для расчёта которых многослойные схемы применяются редко. Поэтому использование многошаговых схем для ОДУ нецелесообразно и с точки зрения единообразия расчётов всех частей рассматриваемой системы.