Программа, моделирующая одноатомный газ, состоящий из одинаковых молекул с массой m и радиусом r, заключенных в кубический сосуд

Страницы работы

Фрагмент текста работы

Установите необходимое программное обеспечение (компиляторы C, C++, Cilk, среду LAM-MPI). Для выполнения заданий с процессами и нитями ознакомьтесь с примерами программ из соответствующих разделов книги Богачева [1], для выполнения задания Б, - с использованием MPI, рассмотрите примеры из [3] и [4], а также пример выполнения задания, приведенный далее. В случае невозможности организовать виртуальную параллельную машину из реальных компьютеров использовать виртуальные машины на основе VirtualBox или VMWare с установкой на них соответствующего программного обеспечения.

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

Задание A.

Вычислить двукратный интеграл , пределы интегрирования по x от a до b, по y от c до d, число интервалов разбиения по x и по y задано числом N, N>10000; использовать метод параллелепипедов, вычисляя объем i,j-го параллелепипеда по формуле

Построить график зависимости времени выполнения расчета от количества параллельных задач (глубины рекурсии в варианте 6) для многоядерного процессора. Для измерения времени вычислений использовать функцию gettimeofday, позволяющую измерять время с точностью до микросекунд.

Варианты заданий: написать программу

1.  с использованием Cilk

2.  с использованием процессов и передачей данных через канал,

3.  с использованием процессов и передачей данных через разделяемую память

4.  с использованием процессов и передачей данных через именованный канал

5.  с использованием нитей и передачей данных через глобальные переменные

6.  с использованием нитей и рекурсивного способа декомпозиции

7.  с использованием нитей и способа декомпозиции по данным

Задание Б.

Написать программу, моделирующую одноатомный газ, состоящий из одинаковых молекул с массой m и радиусом r, заключенных в кубический сосуд. Центр сосуда совпадает с началом координат. Соударениями молекул пренебречь, столкновения со стенками сосуда считать абсолютно упругими. Каждый процесс рассчитывает отдельную область пространства сосуда, передавая данные о молекуле соседнему процессу в случае перехода молекулы в его область. Начальные данные — случайные значения координат молекул и скорости задаются в головном процессе и доставляются с использованием MPI и широковещательных способов передачи данных. Выходными данными являются: количество соударений молекул со стенками сосуда и переданный стенкам импульс за единицу времени.

Выполнить разработку, используя в качестве исходных данных начальные условия по вариантам:

1.  количество молекул 10000, все сосредоточены в 1/8 части объема, в первом октанте, имеют случайные значения координат и скоростей (от 0 до 400 м/сек).

2.  количество молекул 10000, распределены по всему объему, имеют случайные значения координат и скоростей (от 0 до 400 м/сек).

3.  количество молекул 10000, все сосредоточены в 1/2 части объема, с положительными значениями координаты x, имеют случайные значения координат и скоростей (от 0 до 400 м/сек).

4.  количество молекул 10000, распределены по всему объему, имеют случайные значения координат и одинаковые по модулю (300 м/сек), но случайные по направлению скорости.

5.  количество молекул 10000, распределены по двум диаметрально расположенным октантам, имеют случайные значения координат и скоростей (от 0 до 400 м/сек).

6.  количество молекул 10000, все распределены по объему равномерно, но в 1/8 части объема, в первом октанте, имеют значения скоростей от 300 до 600 м/сек, в то время как в оставшемся объеме — скорости от 0 до 400 м/сек.

7.  количество молекул 10000, все сосредоточены в 1/8 части объема, в первом октанте, имеют одинаковые по модулю значения скоростей, 400 м/сек, но случайные по направлению.

Построить график изменения давления на отдельные стенки сосуда от времени.

Пример составления и запуска MPI-приложения.

Рассмотрим пример использования MPI для решения задачи однократного численного интегрирования методом трапеций. Подготовим исходный файл prog.c:

#include <stdio.h>

#include <math.h>

#include "mpi.h"

main(int argc, char** argv) {

int my_rank; /* номер текущего задания */

int p; /* количество заданий */

double a; /* начало интервала интегр. */

double b; /* верний предел интегр. */

int n; /* количество подинтервалов */

double h; /* ширина интервала */

double local_a; /* нижний предел для задания */

double local_b; /* верхний предел для задания*/

int local_n; /* количество интервалов для */

/* текущего задания */

double integral; /* значение интеграла */

double total; /* итоговое значение */

int source; /* отправитель сообщения */

int dest = 0; /* получатель (корневой проц.)*/

int tag = 0;

MPI_Status status;

void Get_data(double* a_ptr, double* b_ptr,

int* n_ptr, int my_rank, int p);

double Trap(double local_a, double local_b, int local_n,

double h); /* вычисление значения на участке */

/* Входим в коммуникатор MPI */

MPI_Init(&argc, &argv);

/* Узнаем свой порядковый номер */

MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

/* Узнаем количество выполняющихся заданий */

MPI_Comm_size(MPI_COMM_WORLD, &p);

Get_data(&a, &b, &n, my_rank, p);

h = (b-a)/n; /* h вычисляем интервал разбиения */

local_n = n/p; /* и количество интервалов */

/* Подынтервал интегрирования для каждого задания

равен local_n*h. Локальные пределы интегрирования:

*/

local_a = a + my_rank*local_n*h;

local_b = local_a + local_n*h;

integral = Trap(local_a, local_b, local_n, h);

/* Добавляем вклады от каждого из заданий */

if (my_rank == 0) {

total = integral;

for (source = 1; source < p; source++) {

MPI_Recv(&integral, 1, MPI_double, source, tag,

MPI_COMM_WORLD, &status);

total = total + integral;

}

} else {

MPI_Send(&integral, 1, MPI_double, dest,

tag, MPI_COMM_WORLD);

}

/* Вывод результата */

if (my_rank == 0) {

printf("n = %d интервалов\n", n);

printf("интеграл от %lf до %lf = %lf\n",

a, b, total);

}

/* Завершаем работу MPI */

void Get_data(

double* a_ptr /* out */,

double* b_ptr /* out */,

int* n_ptr /* out */,

int my_rank /* in */,

int p /* in */) {

int source = 0; /* Переменные для функций */

int dest; /* MPI_Send и MPI_Recv */

int tag;

MPI_Status status;

if (my_rank == 0){

printf("Введите a, b, и n\n");

scanf("%f %f %d", a_ptr, b_ptr, n_ptr);

for (dest = 1; dest < p; dest++){

tag = 0;

MPI_Send(a_ptr, 1, MPI_double, dest, tag, MPI_COMM_WORLD);

tag = 1;

MPI_Send(b_ptr, 1, MPI_double, dest, tag, MPI_COMM_WORLD);

tag = 2;

MPI_Send(n_ptr, 1, MPI_INT, dest, tag, MPI_COMM_WORLD);

}

} else {

tag = 0;

MPI_Recv(a_ptr,1,MPI_double, source, tag, MPI_COMM_WORLD

Похожие материалы

Информация о работе