Aby go rozwiązać, musimy utworzyć wektory rozwiązania i prawej strony oraz macierz zadania, a następnie spiąć te wszystkie dane ze sobą i zlecić pakietowi rozwiązanie tego układu. Do tego służą właśnie obiekty typu SLES.
Aby utworzyć obiekt typu SLES trzeba, podobnie jak w poprzednich przypadkach, najpierw zadeklarować odpowiednią zmienną:
... SLES MojSles; ...
Pierwszy argument funkcji SLESCreate() to, podobnie jak w przypadku innych obiektów, kanał komunikatora MPI, u nas zawsze będzie to MPI_COMM_WORLD. Drugi to wskaźnik do uprzednio zadeklarowanej zmiennej typu SLES.
Następną czynnością, jaką należy wykonać, jest przekazanie macierzy zadania do SLESu. Robi się to przy pomocy funkcji:
SLESSetOperators(SLES MojSles,Mat A,Mat P, MatStructure flag);
|
|
|
| SAME_PRECONDITIONER | Macierz P jest cały czas taka sama w czasie procesu iteracyjnego. Ta opcja jest dla tych, którzy używają różnych macierzy A i P. Opcja ta np. oszczędza pracę przy niekompletnym rozkładzie Choleskiego stosowanym jako preconditioner: rozkład jest robiony tylko raz. |
| SAME_NONZERO_PATTERN | w trakcie iteracji macierz P ma taką samą strukturę miejsc niezerowych |
| DIFFERENT_NONZERO_PATTERN | w trakcie iteracji macierz P zmienia strukturę |
Powyższe przygotowania wystarczają, aby SLES rozwiązał układ równań z macierzą A i prawą stroną b. W tym celu należy wywołać funkcję SLESSolve(SLES MojSles,Vec b,Vec x,int *its). Wynik zostanie zapisany w wektorze x.
W zmiennej its zostanie zapisana liczba wykonanych iteracji. Po zakończeniu obliczeń należy zwolnić pamięć zajmowaną przez SLES funkcją: SLESDestroy(SLES MojSles), gdzie argumentem jest (niepotrzebny już) obiekt MojSles. Ważne jest, że jeden SLES może służyć do rozwiązania wielu układów równań, na przykład kilku układów z tą samą macierzą i inną prawą stroną.
#include "sles.h"
int main(int argc,char **args)
{
Vec x,b;
Mat A; /* macierz układu równań */
SLES MojSles; /* kontekst SLESu */
int its;
Scalar val;
PetscInitialize(&argc,&args,PETSC_NULL,PETSC_NULL);
/* Tworzenie kontekstu SLES */
SLESCreate(MPI_COMM_WORLD,&MojSles);
/* tutaj trzeba utworzyć wektory (str. 12)
i macierze, (str. 17) */
/*Ustawienie operatorów */
SLESSetOperators(MojSles,A,A,DIFFERENT_NONZERO_PATTERN);
SLESSetFromOptions(MojSles);
/* rozwiązanie układu liniowego */
SLESSolve(MojSles,b,x,&its);
/*Tu z kolei należy zwolnić pamięć*/
SLESDestroy(MojSles);
PetscFinalize();
return(0);
}

na siatce o kroku h. Testuj błąd rozwiązania
w normie max i l2 dla f odpowiadającym
rozwiązaniu dokładnemu
a) sin(x),
b) x2+y2.
Sprawdź, jak zmienia się liczba iteracji w zależnościod h. Obejrzyj
wektory rozwiązania i błędu w okienku graficznym.

Eksperymentuj z różnymi sposobami implementacji macierzy (klasycznie i powłokowo).
![]() |
![]() |
![]() |