======Библиотека вспомогательных утилит 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 будут искаться в вашей домашней директории.