3.1 Библиотека SCore

Одним из приоритетных направлений в использовании параллельных вычислительных систем является численное моделирование сложных и масштабных физических процессов. Задача численного моделирования в большинстве случаев сводится к решению систем линейных алгебраических уравнений. В настоящее время существуют множество вычислительных библиотек для решения больших систем уравнений на параллельных архитектурах, в которых уже реализованы параллельные алгоритмы решения СЛАУ. При реализации задач численного моделирования с использованием параллельных численных пакетов приходится писать достаточно много кода для построения системы уравнений, при этом надо учитывать низкоуровневую работу с памятью. Большое количество оперируемых данных увеличивает сложность программы и соответственно увеличивает количество ошибок, возникающих при реализации математических моделей. При усложнении математических моделей сложность кода увеличивается в разы, поэтому при рассмотрения сложных моделей необходимо разделить построение систем уравнений, т.е. аппроксимацию уравнений и постановку моделей.

3.1.1 Общее описание

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

Ценность такого подхода состоит в том, что освоившись с подходом, вы получаете в свое распоряжение множество приемов, позволяющих поладить с возрастающей сложностью "цивилизованным"путем. Например, с увеличением количества численных алгоритмов или количества вычисляемых переменных задачи достаточно лишь создать новые объекты. При использовании стандартного подхода численного моделирования в аналогичной ситуации пришлось бы добавлять в логику метода дополнительные условия, что привело бы в последующем к плохому коду. Если вы столько же неравнодушны к объектам, как мы, то наверняка предпочли бы применение объектно-ориентированного подхода даже в самых простых ситуациях.

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

Отметим что поскольку библиотека обладает сложной структурой и включает различного рода информацию, которую требуется представить. В пособии приводится визуализация кода в виде UML-диаграмм, упрощающих представление подобного рода информации.

Рассмотрим задачу математического моделирования которая описывается системой нестационарных уравнений. Полученную систему необходимо численно решить. На рисунке 3.1. изображена логика численного решения задачи.


PIC

Рис. 3.1: Логика численного решения задачи.


Задача может состоять из произвольного числа уравнений для численного решения которого проводится стандартная конечно разностная аппроксимация по пространству. В результате получаем дифференциально-разностную задачу для решения которого строятся разностные схемы с весами. Полученная в результате дискретная задача решается с использованием численных методов в зависимости от того получаем ли мы линейную или нелинейную систему алгебраических уравнений.

В библиотеке используются основные классы:

В библиотеке задание математической модели происходит с использованием операторного представления решаемых уравнений, что дает возможность более простого задания дискретной задачи с соблюдением основных ее свойств. Также этот подход в значительной степени упростил реализацию разностных схем с весами для нестационарных задач и дал возможность привязывать вес к каждому конкретному оператору. Следует отметить, что в библиотеке реализованы различные конечно-разностные аппроксимации по пространственным переменным для операторов диффузии, конвекции и реакции. Для решения систем линейных и нелинейных уравнений библиотека SCore использует параллельную вычислительную библиотека Petsc. Отметим, что библиотека SCore имеет возможность расширения другими библиотеками численного анализа или собственными реализациями необходимых численных алгоритмов. Несмотря на то, что SCore в значительной степени упрощает численное моделирование задач математической физики, время счета реализации на PETSc и SCore соизмеримы, т.е. накладные расходы дополнительного абстрактного уровня SCore почти не влияет на общее время счета.

3.1.2 Variable, Storage: Переменные и их хранение


PIC

Рис. 3.2: Класс Variable.



PIC

Рис. 3.3: Классы для хранения переменных.


Задача математического моделирования состоит из нахождения значений некоторых заданных переменных, которые могут быть описаны уравнением или, в простейшем случае, заданы формулой. Для задания искомых переменных используется класс Variable, который характеризует ее именем посредством которого по необходимости можно будет получить значения для, например, анализа численного решения.

При численном моделировании сложных процессов с большим количеством неизвестных переменных, в описании формул или уравнений необходимо получать текущие значения некоторых других переменных. Для того чтобы предоставить подобный доступ к переменным все неизвестные хранятся в класс Storage, который реализован с использованием шаблонов проектирования Одиночка (Singleton) и Фабрика (Factory). Следовательно реализация Storage гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа, что дает следующие достоинства:

В свою очередь класс Storage использует для хранения и представления сеточных данных следующие классы:

Отметим что поскольку библиотека предоставляет возможность решения задач с использованием многосеточного метода, в основе которого лежит иерархия сеток, то реализация класса GridValue хранит значения переменной для всех уровней сеток. Поскольку переменные являются еще и распределенными по запущенным процессам, то класс Grid содержит также информацию и об организации распределения.

Создание сеточных значений переменных инкапсулировано посредством паттерна Фабричный метод (Factory method) в классе Storage, который определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой класс инстанцировать. Такой подход в значительной степени упрощает дальнейшее расширение методов представления трехмерных векторов.

Внутренняя организация и связи вышеупомянутых классов показаны на рисунке 3.3.

3.1.3 Equation, Formula: Вычисляемые переменные


PIC

Рис. 3.4: Иерархия классов используемых при описании операторов, уравнений и формул.


Мы разобрались как представлять и хранить переменные с тем , чтобы иметь возможность обратиться к ним при необходимости. Организация доступа и задание всех зависимых переменных осуществляется посредством наследования интерфейса Preparable, при котором необходимо реализовать метод prepare для задания связей между переменными.

Библиотека проектировалась для решения нестационарных задач в области

Ω = {x  | x = (x1,x2,x3),  xminα ≤ xα ≤ xmaxα, α = 1,2,3},
(3.1)

описываемых уравнением вида:

      ∂u
a(x,t)--+ Au = f (x,t),  x ∈ Ω, Tmin < t ≤ Tmax
      ∂t
(3.2)

где     ∑
A =   ni=1 Ai(t)  сумма дифференциальных операторов. Поскольку задачи решаются методом конечных разностей, дифференциальные операторы аппроксимируются в разностные операторы. В библиотеке реализованы аппроксимации дифференциальных операторов: конвекции, диффузии и реакции. Имеется возможность определения дополнительных операторов через наследование из базового класса Operator. Аппроксимация по времени проводится с помощью стандартной двухслойной схемы с весами, где величина весов для каждого разностного оператора задается по отдельности.

Каждая неизвестная описывается уравнением или же формулой. Рассмотрим конструирование конкретного уравнения или формулы вычисления значения переменной. При формировании формулы алгоритм вычисления переменной инкапсулируется в объекте. В случае уравнения инкапсулируются функция вычисления элементов матрицы и правой части, которые необходимы для дальнейшего численного решения.

Детальная иерархия классов, которые используются при описании операторов, уравнений и формул, показана на рисунке 3.4.

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

Инкапсуляция алгоритма в объект - это назначение паттерна стратегия. Основными участниками паттерна являются объекты-стратегии, инкапсулирующие различные алгоритмы, и контекст, в котором они работают. Композиторы представляют варианты стратегий. Композиция - это контекст для стратегии композитора. Ключ к применению паттерна стратегия - спроектировать интерфейсы стратегии и контекста, достаточно общие для поддержки широкого диапазона алгоритмов. Не должно возникать необходимости изменять интерфейс стратегии или контекста для поддержки нового алгоритма. В нашем примере поддержка доступа к потомкам предоставляемая базовыми интерфейсами класса Formula и Equation, достаточно общая, чтобы подклассы класса SolveCommand могли изменять численный метод решения дискретной задачи независимо от того, с использованием каких формул, матриц это делается. Таким образом применение паттерна стратегия позволяет изменять алгоритмы независимо от клиентов, которые ими пользуются.

Отметим следующие достоинства и недостатки применения этого паттерна:

3.1.4 Command: Решатели и обработчики


PIC

Рис. 3.5: Структура классов реализующая шаблон проектирования Команда (Command).


Уравнения и формулы, описанные с помощью вышеупомянутых классов, решаются через специальные классы решателей. Реализованы всего три класса решателей: линейный (LinearSolver), нелинейный (NonlinearSolver) и решатель формул (FormulaSolver). Для каждого уравнения и формулы создается отдельный решатель, который записывает результат в хранилище неизвестных (Storage). Для организации очередности решаемых уравнений был использован шаблон проектирования Команда (Command), которая реализуется посредством введения интерфейса с методом execute. Паттерн команда используется совместно с паттерном Компоновщик (Composite). Паттерн компоновщик инкапсулирует сущность рекурсивной композиции объектно-ориентированным способом и позволяет единообразно трактовать индивидуальные и составные объекты.

Для сохранения и просмотра определенных характеристик неизвестных используются классы SaveCommand и InformCommand. SaveCommand записывает текущее состояние неизвестного в структурированном формате VTK. InformCommand выводит характеристики, описывающие состояние численного решения: максимум, минимум и среднее значение. Ниже на рисунке 3.5 приведены диаграммы классов-команд.

Отметим достоинства применения паттерна команда и компоновщик:


PIC

Рис. 3.6: Структура классов итераторов.


Для организации послойного счета по времени была добавлена абстракция итераций. Итераторы обрабатываются командой IterateCommand. Структура классов итераторов отображена на рисунке 3.6.

3.1.5 Config, Logger: Задание параметров и выходная информация


PIC

Рис. 3.7: Классы для конфигурации.


Конкретная реализация математической модели представляет собой консольную программу, которую можно запускать как на обычных компьютерах, так и на вычислительных кластерах с распределенной памятью с помощью технологии MPI. Все настраиваемые параметры вынесены в виде консольных опции, для ускорения проведения серий вычислительных экспериментов. Основными общими параметрами для задач моделирования являются: область, время, разностная сетка и декомпозиция области по процессам. Для ведения журнала действий в программе производится логирование с использованием библиотеки log4cpp. Логи записывается в файл, который можно указать с помощью консольного параметра -log_file. Так же можно задавать уровень лога (-log_threashold), который определяет уровень детализации выходной информации. Параметр -log_to_std позволяет дублировать выходную информацию в стандартный поток вывода. Следует заметить, что запись лога ведет только процесс с индексом нуль.