======Библиотека вспомогательных утилит ivutils======
это набор утилит C++ для создания численных приложений. ivutils использовались при написании программ EMTL (electromagnetic modeling) и [[https://sites.physics.utoronto.ca/sajeevjohn/software/transport|Microvolt]] (semiconductor device modeling)
Для использования ivutils, нужно их скачать и скомпилировать с вашим кодом: {{:ivutils.zip}}
ivutils включает следующие утилиты:
^ файлы \\ h hpp cpp ^ описание ^
| vector_3 \\ basis_3 | n-ые вектора и линейные преобразования над ними |
| vector_set | упаковщики последовательностей векторов|
| contour | контура |
| plane_3\\ region_2\\ region_3 | 2D и 3D геометрические тела |
| gnudump | рисование геометрических тел в gnuplot и VTK |
| | |
| grid | однородная и неоднородная сетки для хранения и интерполяции данных |
| linsolv | интерфейс для решения системы линейных уравнений с помощью LAPACK и PARDISO |
| | |
| refobj\\ pencil |умные указатели для контроля над памятью, выделяемой под динамические объекты |
| math_utils | полезные математические функции|
| utiltl | полезные итераторы, модификаторы, и т. д.|
| seqpack | упаковщики данных |
| logger| интерфейс для хранения данных по их символическим именам (с расширенной функциональностью чем у map)|
| | |
| logexc | логгеры для записи выходных сообщений во время работы программы и обработки исключений|
| loggerio\\ detector| детекторы для записи данных в двоичные или текстовые файлы во время расчета |
| component | конфигурационные настройки \\ таймеры для измерения машинного времени, затраченного на выбранные функции \\ компоненты для создания численных приложений |
| | |
| string_utils | полезные функции для работы со строками|
| alg_parser |парсеры математических выражений |
| read_ini | парсеры простых ини-файлов|
| | |
| ifmpi \\ implmpi | интерфейс для работы с MPI |
| | |
| qsub.py | Скрипт для запуска задач на произвольном суперкомпьютере |
| Makefile.arch \\ Makefile.target | Makefile для компиляции на произвольной архитектуре |
\\
Ниже мы прилагаем некоторые примеры использования ivutils.
=====Парсер математических выражений=====
Интерфейс для разбора математических выражений. Он позволяет обрабатывать строки, содержащие арифметические операции, скобки и функции, и вычислять значение заданного выражения.
Например
#include "alg_parser.h"
int main(){
AlgebraicParser AP;
double val; // here calculated value will be recorded
int res=AP("sqrt(5+cos(3*pi))", &val); // if res=1 expression is correct
res=AP("1e-5", &val); // if res=1 expression is correct
return 0;
}
Код:
* {{:download/string_utils.h}} {{:download/string_utils.cpp}}
* {{:download/alg_parser.h}} {{:download/alg_parser.cpp}}
Пример работы:
* {{:download/test_alg_parser.cpp}}
=====Геометрические тела=====
Ниже мы вкратце перечислим классы, отвечающие некоторым используемым геометрическим телам. Со всем списком можно ознакомиться в справке для пользователя.
Класс вектор Vector_3. В его конструкторе задаются три координаты x, y и z. Вектора можно складывать, вычитать, умножать на число, умножать скалярно (с помощью оператора *) и векторно (с помощью оператора %). Например,
Vector_3 v1(1,0,0),v2(0,1,0);
Vector_3 v0=a%b-Vector_3(0,0,1); // v0 равен Vector_3(0,0,0)
Если в конструкторе вектора задается меньше трех координат, то незаданные координаты полагаются равными последней заданной. Например, Vector_3(1)=Vector_3(1,1,1). Также Vector_3()=Vector_3(0,0,0), так как первая координата по умолчанию равна нулю.
Векторам с целочисленными координатами отвечает класс iVector_3.
Тела, описывающие геометрические классы, являются наследниками класса Region_3.
Класс Region_3 (а также его наследники) имеет следующую фунциональность:
*он может проверять, находится ли произвольная точка внутри или снаружи
*он может находить ближайшую точку на поверхности от выбранного положения
*он может находить пересечение с произвольной прямой
*он может находить сечение с произвольным плоским контуром
Ниже мы приводии примеры функций, которые могут использоваться для создания некоторых распространенных объектов.
Region_3 *GetHalfSpace(const Vector_3 &n, const Vector_3 &pos);
возвращает полупространство, n - нормаль к граничной плоскости, pos - произвольная точка на этой плоскости. Например,
Region_3 *reg = GetHalfSpace(Vector_3(0,0,1), Vector_3(0,0,0));
возвращает полупространству соответсвующее положительной части оси z.
Region_3 *GetPlate(const Vector_3 &n, const Vector_3 &pos, vec_type width);
возвращает бесконечную пластинку (пространство между двумя параллельным плоскостями), n - нормаль к плоскостям, pos - точка на некоторой плоскости, width - расстояние между этой плоскостью и соседней плоскостью.
Region_3 *getBox(const &Vector_3 a, const &Vector_3 b);
возвращает параллелепипед с ребрами параллельными координатным осям. a и b - противоположные вершины параллелепипеда.
Region_3 *GetSphere(vec_type R, const &Vector_3 center);
возвращает сферу радиуса R и центром center.
Region_3 *GetCylinder(const Vector_3 &origin, Vector_3 n, vec_type R, valtype h);
возвращает цилиндр, origin - точка на оси цилиндра, n - направление оси, R - радиус, h - высота (если h=0, цилиндр считается бесконечным).
Region *GetCone(const Vector_3 &origin, Vector_3 n, vec_type R, vec_type h);
возвращает конус, все параметры имеют такое же значение как и для GetCylinder.
Также имеются многогранник, цилиндр и пирамида с основанием в виде произвольного многоугольника. Тела можно растягивать, поворачивать, брать их пересечения и объединения. Гладкие тела, например конус, можно конструировать как многогранники с большим количеством граней. Все это задокументировано в region.h.
/**Прямоугольный параллелепипед, ребра которого параллельны координатным осям, задается путем указания левого нижнего и правого верхнего векторов.
Box b(Vector_3(),Vector_3(1)); // единичный куб b
Сфера задается путем указания ее радиуса и центра.
Sphere s(1,Vector_3()); // сфера s радиуса 1, центр которой находится в начале координат
*/
======Скрипт для запуска задач на произвольном суперкомпьютере======
Для расчета больших задач используются суперкомьютеры.
Запуск задач на них предполагает:
*создание сценария, в котором вы указываете имя исполняемого файла, требуемое количество процессоров, время исполнения и т. д.
*запуск этого сценария, что приводит к постановке задачи очередь и последущему ее выполнению.
Различные суперкомпьютеры используют различный синтаксис для создания и запуска таких сценариев.
Ручное создание таких сценариев под каждую задачу весьма времезатратно.
Для упрощения этой работы, мы создали специальный скрипт {{:qsub.py}} на языке python.
Он позволяет запускать задачи на произвольном суперкомпьютере, и является переносимым с одного суперкомпьютера на другой.
Для определения, какой суперкомпьютер используется в данный момент, скрипт использует команду UNIX 'hostname'.
Для использования скрипта, нужно написать инструкцию, как создавать сценарий и запускать его на вашем суперкомпьютере в функции make_script.
Это уже сделано для некоторых суперкомпьютеров: SciNet (Канада), суперкомпьютер Курчатовского Института, МВС-100K (МСЦ РАН), СКИФ МГУ и т. д.
После этого вы можете использовать функцию qsub со следующими аргументами:
qsub(workdir,worksubdir,prog,args,time,np,ppn=0,task='',fname='',act=1,skip='')
Эта функция создает директорию workdir/worksubdir, копирует туда исполняемый файл prog, создает там сценарий SCRIPT.sh для запуска исполняемого файла с аргументами командной строки args на np процессорах на количество секунд time (на некоторых суперкомпьютерах время можно не указывать).
Необязательные параметры функции qsub:
ppn - количество процессоров, используемое на узле (значение по умолчанию ppn=0 приводит к тому, что по возможности используется полное число процессоров на узле),
task - имя задачи,
fname - имя файла или список файлов, которые будут копироваться в workdir/worksubdir,
act - 1 (поставить задачу в очередь) или 0 (не делать этого). В любом случае команда для запуска скрипта будет записана в файл QSUB.sh,
skip - если файл с этим именем будет найден в workdir/worksubdir, функция qsub не выполнится.
Например, допустим ваш исполняемый файл 'a.out' находится в текущей папке '.'.
Скопируем в эту папку скрипт 'qsub.py' и создадим в ней 'script.py':
#! /usr/bin/python
from qsub import *
qsub('.','test','a.out','',60*60,8)
Сделаем его исполняемым
chmod u+x script.py
и выполним его
./script.py
В результате в текущей папке будет создана поддиректория test, куда будет перенесен исполняемый файл a.out, а также создан сценарий SCRIPT.sh для запуска этого файла на 8 процессорах на час и файл QSUB.sh, для запуска этого сценария.
Как правило, на разных суперкомпьютерах вы имеете различные пути к домашней директории, где вы компилируете ваш проект, и к рабочей директории, где вы исполняете задачу и сохраняете ее результат. Вы можете прописать такие пути для каждого суперкомпьютера и пользователя (который определяется функцией UNIX 'whoami') в функции getdirs.
После этого вы можете пользоваться функцией qsub_appl:
qsub_appl(workdir,worksubdir,prog,args,time,np,ppn=0,task='',fname='',act=1,skip='')
Аргументы этой функции такие же, как и у функции qsub.
Единственное отличие в том, что директория workdir/worksubdir будет создаваться в вашей рабочей директории, а исполняемый файл prog и вспомогательный файл fname будут искаться в вашей домашней директории.