Опубликован: 28.07.2007 | Уровень: специалист | Доступ: платный
Лекция 11:

Параллельные методы решения дифференциальных уравнений в частных производных

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

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

Объем выполняемых при этом вычислений обычно является значительным, и использование высокопроизводительных вычислительных систем традиционно для данной области вычислительной математики.

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

Рассмотрим в качестве учебного примера проблему численного решения задачи Дирихле для уравнения Пуассона, которая определяется как задача нахождения функции u=u(x,y), удовлетворяющей в области определения D уравнению

\left\{
\begin{aligned}
& \frac{\partial^2u}{\partial x^2}+\frac{\partial^2 u}{\partial y^2}= f(x,y), & (x,y) \in D, \\
& u(x,y) = g(x,y), & (x,y) \in D^0,
\end{aligned}
\right.
и принимающей значения g(x,y) на границе D0 области D ( f и g являются функциями, задаваемыми при постановке задачи). Подобная модель может применяться для описания установившегося течения жидкости, стационарных тепловых полей, процессов теплопередачи с внутренними источниками тепла и деформации упругих пластин. Данный пример часто используется в качестве учебно-практической задачи при изложении возможных способов организации эффективных параллельных вычислений (см. [ [ 12 ] , [ 60 ] ]).

Для простоты изложения материала в качестве области задания D функции u(x,y) далее будет использоваться единичный квадрат

D=\{ (x,y)\in D:0\le x,y\le 1\}

11.1. Последовательные методы решения задачи Дирихле

Одним из наиболее распространенных подходов к численному решению дифференциальных уравнений является метод конечных разностей ( метод сеток ) (см., например, [ [ 6 ] , [ 13 ] , [ 60 ] ]). Следуя этому подходу, область решения D можно представить в виде дискретного (как правило, равномерного) набора ( сетки ) точек ( узлов ). Так, например, прямоугольная сетка в области D может быть задана в виде (рис. 11.1)

\left\{
\begin{gathered}
D_h=\{(x_i,y_j):x_i=ih, y_i=jh, 0\le i, j\le N+1, \\
h=1/(N+1)
\end{gathered}
\right.
где величина N задает количество внутренних узлов по каждой из координат области D.

Обозначим оцениваемую при подобном дискретном представлении аппроксимацию функции u(x,y) в точках (xi, yj) через uij. Тогда, используя пятиточечный шаблон (см. рис. 11.1) для вычисления значений производных, мы можем представить уравнение Пуассона в конечно-разностной форме

\frac{u_{i-1,j}+u_{i+1,j}+u_{i,j-1}+u_{i,j+1}-4u_{ij}}{h^2} = f_{ij}

Данное уравнение может быть разрешено относительно uij:

uij=0,25(ui-1,j+ui+1,j+ui,j-1-h2fij).

Разностное уравнение, записанное в подобной форме, позволяет определять значение uij по известным значениям функции u(x,y) в соседних узлах используемого шаблона. Данный результат служит основой для построения различных итерационных схем решения задачи Дирихле, в которых в начале вычислений формируется некоторое приближение для значений uij, а затем эти значения последовательно уточняются в соответствии с приведенным соотношением. Так, например, метод Гаусса – Зейделя для проведения итераций уточнения использует правило

u_{ij}^k=0,25(u_{i-1,j}^k + u_{i+1,j}^{k-1}+u_{i,j-1}^{k}+u_{i,j+1}^{k-1}-h^2 f_{ij})
по которому очередное k -е приближение значения uij вычисляется по последнему k -му приближению значений ui-1,j и ui,j-1 и предпоследнему (k-1) -му приближению значений ui+1,j и ui,j+1. Выполнение итераций обычно продолжается до тех пор, пока получаемые в результате итераций изменения значений uij не станут меньше некоторой заданной величины ( требуемой точности вычислений ). Сходимость описанной процедуры (получение решения с любой желаемой точностью) является предметом всестороннего математического анализа (см., например, [ [ 6 ] , [ 13 ] , [ 60 ] ]), здесь же отметим, что последовательность решений, получаемых методом сеток, равномерно сходится к решению задачи Дирихле, а погрешность решения имеет порядок h2.

Прямоугольная сетка в области D (темные точки представляют внутренние узлы сетки, нумерация узлов в строках слева направо, а в столбцах — сверху вниз)

Рис. 11.1. Прямоугольная сетка в области D (темные точки представляют внутренние узлы сетки, нумерация узлов в строках слева направо, а в столбцах — сверху вниз)

Рассмотренный алгоритм (метод Гаусса – Зейделя) на псевдокоде, приближенном к алгоритмическому языку С++, может быть представлен в виде:

Алгоритм 11.1. Последовательный алгоритм Гаусса – Зейделя

// Алгоритм 11.1
do {
  dmax = 0; // максимальное изменение значений u
  for ( i=1; i<N+1; i++ )
    for ( j=1; j<N+1; j++ ) {
      temp = u[i][j];
      u[i][j] = 0.25*(u[i-1][j]+u[i+1][j]+
                u[i][j-1]+u[i][j+1]–h*h*f[i][j]);
      dm = fabs(temp-u[i][j]);
      if ( dmax < dm ) dmax = dm;
    }
} while ( dmax > eps );

(напомним, что значения uij при индексах i,j=0,N+1 являются граничными, задаются при постановке задачи и не изменяются в ходе вычислений).

Вид функции u(x,y) в примере для задачи Дирихле

Рис. 11.2. Вид функции u(x,y) в примере для задачи Дирихле

Для примера на рис. 11.2 приведен вид функции u(x,y), полученной для задачи Дирихле при следующих граничных условиях:

\left\{
\begin{aligned}
&\quad f(x,y)=0, \quad (x,y) \in D, \\
&\quad 100-200x, \quad y=0, \\
&\quad 100-200x, \quad x=0, \\
&-100+200x, \quad y=1, \\
&-100+200x, \quad x=1. \\
\end{aligned}
\right.

Общее количество итераций метода Гаусса – Зейделя составило 210 при точности решения eps=0,1 и N=100 (в качестве начального приближения величин uij использовались значения, сгенерированные датчиком случайных чисел из диапазона [-100, 100]).

Дмитрий Степаненко
Дмитрий Степаненко
Россия
Михаил Бурдаев
Михаил Бурдаев
Россия

( ! ) Warning: include_once(./includes/unicode.entities.inc) [<a href='function.include-once'>function.include-once</a>]: failed to open stream: No such file or directory in /.2/var_www_new.intuit.ru/htdocs/includes/unicode.inc on line 340
Call Stack
#TimeMemoryFunctionLocation
14.0142103359416watchdog( )../bootstrap.inc:0
24.0146103361888module_invoke( )../bootstrap.inc:967
34.0146103363744call_user_func_array ( )../module.inc:462
44.0146103364080devel_watchdog( )../module.inc:462
54.0147103364928decode_entities( )../devel.module:382
64.0148103366848drupal_error_handler( )../devel.module:340
74.0148103370472watchdog( )../common.inc:663
84.0148103372544module_invoke( )../bootstrap.inc:967
94.0148103374400call_user_func_array ( )../module.inc:462
104.0148103374736devel_watchdog( )../module.inc:462
114.0149103375432decode_entities( )../devel.module:382

( ! ) Warning: include_once() [<a href='function.include'>function.include</a>]: Failed opening './includes/unicode.entities.inc' for inclusion (include_path='.:/usr/local/zend/var/libraries/Zend_Framework_1/default/library:/usr/local/zend/share/pear') in /.2/var_www_new.intuit.ru/htdocs/includes/unicode.inc on line 340
Call Stack
#TimeMemoryFunctionLocation
14.0142103359416watchdog( )../bootstrap.inc:0
24.0146103361888module_invoke( )../bootstrap.inc:967
34.0146103363744call_user_func_array ( )../module.inc:462
44.0146103364080devel_watchdog( )../module.inc:462
54.0147103364928decode_entities( )../devel.module:382
64.0148103366848drupal_error_handler( )../devel.module:340
74.0148103370472watchdog( )../common.inc:663
84.0148103372544module_invoke( )../bootstrap.inc:967
94.0148103374400call_user_func_array ( )../module.inc:462
104.0148103374736devel_watchdog( )../module.inc:462
114.0149103375432decode_entities( )../devel.module:382

( ! ) Warning: include_once(./includes/unicode.entities.inc) [<a href='function.include-once'>function.include-once</a>]: failed to open stream: No such file or directory in /.2/var_www_new.intuit.ru/htdocs/includes/unicode.inc on line 340
Call Stack
#TimeMemoryFunctionLocation
14.0142103359416watchdog( )../bootstrap.inc:0
24.0146103361888module_invoke( )../bootstrap.inc:967
34.0146103363744call_user_func_array ( )../module.inc:462
44.0146103364080devel_watchdog( )../module.inc:462
54.0147103364928decode_entities( )../devel.module:382
64.0155103367040drupal_error_handler( )../devel.module:340
74.0155103370728watchdog( )../common.inc:663
84.0155103372800module_invoke( )../bootstrap.inc:967
94.0155103374656call_user_func_array ( )../module.inc:462
104.0155103374992devel_watchdog( )../module.inc:462
114.0155103375768decode_entities( )../devel.module:382

( ! ) Warning: include_once() [<a href='function.include'>function.include</a>]: Failed opening './includes/unicode.entities.inc' for inclusion (include_path='.:/usr/local/zend/var/libraries/Zend_Framework_1/default/library:/usr/local/zend/share/pear') in /.2/var_www_new.intuit.ru/htdocs/includes/unicode.inc on line 340
Call Stack
#TimeMemoryFunctionLocation
14.0142103359416watchdog( )../bootstrap.inc:0
24.0146103361888module_invoke( )../bootstrap.inc:967
34.0146103363744call_user_func_array ( )../module.inc:462
44.0146103364080devel_watchdog( )../module.inc:462
54.0147103364928decode_entities( )../devel.module:382
64.0155103367040drupal_error_handler( )../devel.module:340
74.0155103370728watchdog( )../common.inc:663
84.0155103372800module_invoke( )../bootstrap.inc:967
94.0155103374656call_user_func_array ( )../module.inc:462
104.0155103374992devel_watchdog( )../module.inc:462
114.0155103375768decode_entities( )../devel.module:382

( ! ) Warning: include_once(./includes/unicode.entities.inc) [<a href='function.include-once'>function.include-once</a>]: failed to open stream: No such file or directory in /.2/var_www_new.intuit.ru/htdocs/includes/unicode.inc on line 340
Call Stack
#TimeMemoryFunctionLocation
14.0160103359960watchdog( )../bootstrap.inc:0
24.0160103362032module_invoke( )../bootstrap.inc:967
34.0160103363888call_user_func_array ( )../module.inc:462
44.0160103364224devel_watchdog( )../module.inc:462
54.0161103364928decode_entities( )../devel.module:382
64.0161103366848drupal_error_handler( )../devel.module:340
74.0161103370464watchdog( )../common.inc:663
84.0161103372536module_invoke( )../bootstrap.inc:967
94.0161103374392call_user_func_array ( )../module.inc:462
104.0161103374728devel_watchdog( )../module.inc:462
114.0162103375424decode_entities( )../devel.module:382

( ! ) Warning: include_once() [<a href='function.include'>function.include</a>]: Failed opening './includes/unicode.entities.inc' for inclusion (include_path='.:/usr/local/zend/var/libraries/Zend_Framework_1/default/library:/usr/local/zend/share/pear') in /.2/var_www_new.intuit.ru/htdocs/includes/unicode.inc on line 340
Call Stack
#TimeMemoryFunctionLocation
14.0160103359960watchdog( )../bootstrap.inc:0
24.0160103362032module_invoke( )../bootstrap.inc:967
34.0160103363888call_user_func_array ( )../module.inc:462
44.0160103364224devel_watchdog( )../module.inc:462
54.0161103364928decode_entities( )../devel.module:382
64.0161103366848drupal_error_handler( )../devel.module:340
74.0161103370464watchdog( )../common.inc:663
84.0161103372536module_invoke( )../bootstrap.inc:967
94.0161103374392call_user_func_array ( )../module.inc:462
104.0161103374728devel_watchdog( )../module.inc:462
114.0162103375424decode_entities( )../devel.module:382

( ! ) Warning: include_once(./includes/unicode.entities.inc) [<a href='function.include-once'>function.include-once</a>]: failed to open stream: No such file or directory in /.2/var_www_new.intuit.ru/htdocs/includes/unicode.inc on line 340
Call Stack
#TimeMemoryFunctionLocation
14.0160103359960watchdog( )../bootstrap.inc:0
24.0160103362032module_invoke( )../bootstrap.inc:967
34.0160103363888call_user_func_array ( )../module.inc:462
44.0160103364224devel_watchdog( )../module.inc:462
54.0161103364928decode_entities( )../devel.module:382
64.0167103367040drupal_error_handler( )../devel.module:340
74.0167103370728watchdog( )../common.inc:663
84.0167103372800module_invoke( )../bootstrap.inc:967
94.0167103374656call_user_func_array ( )../module.inc:462
104.0167103374992devel_watchdog( )../module.inc:462
114.0167103375768decode_entities( )../devel.module:382

( ! ) Warning: include_once() [<a href='function.include'>function.include</a>]: Failed opening './includes/unicode.entities.inc' for inclusion (include_path='.:/usr/local/zend/var/libraries/Zend_Framework_1/default/library:/usr/local/zend/share/pear') in /.2/var_www_new.intuit.ru/htdocs/includes/unicode.inc on line 340
Call Stack
#TimeMemoryFunctionLocation
14.0160103359960watchdog( )../bootstrap.inc:0
24.0160103362032module_invoke( )../bootstrap.inc:967
34.0160103363888call_user_func_array ( )../module.inc:462
44.0160103364224devel_watchdog( )../module.inc:462
54.0161103364928decode_entities( )../devel.module:382
64.0167103367040drupal_error_handler( )../devel.module:340
74.0167103370728watchdog( )../common.inc:663
84.0167103372800module_invoke( )../bootstrap.inc:967
94.0167103374656call_user_func_array ( )../module.inc:462
104.0167103374992devel_watchdog( )../module.inc:462
114.0167103375768decode_entities( )../devel.module:382