266
VecSetFromOptions(), указывается только глобальный размер вектора; парал-
лельное разбиение определяется на этапе исполнения. Когда решается линейная
система, векторы и матрицы обязаны быть разбиты соответственно. PETSc авто-
матически генерирует соответствующее разбиение матриц и векторов, когда
MatCreate() и VecCreate() используются с тем же самым коммуникатором. Поль-
зователь может альтернативно описать размеры локальных векторов и матриц,
когда необходимо более сложное разбиение (путем замещения аргумента
PETSC_DECIDE в VecCreate()). */
ierr = VecCreate(PETSC_COMM_WORLD,PETSC_DECIDE,m*n,&u);
CHKERRQ(ierr);
ierr = VecSetFromOptions(u);CHKERRQ(ierr);
ierr = VecDuplicate(u,&b);CHKERRQ(ierr);
ierr = VecDuplicate(b,&x);CHKERRQ(ierr);
/* Установим точное решение, затем вычислим правосторонний вектор. По умол-
чанию используем точное решение вектора для случая, когда все элементы
вектора равны единице. Альтернативно, используя опцию – random_sol, фор-
мируем решение вектора со случайными компонентами. */
ierr = PetscOptionsHasName(PETSC_NULL,"-random_exact_sol",&flg);
CHKERRQ(ierr);
if (flg)
{ ierr = PetscRandomCreate(PETSC_COMM_WORLD,RANDOM_DEFAULT,&rctx);
CHKERRQ(ierr);
ierr = VecSetRandom(rctx,u);CHKERRQ(ierr);
ierr = PetscRandomDestroy(rctx);CHKERRQ(ierr);
}
else ierr = VecSet(&one,u);CHKERRQ(ierr);
ierr = MatMult(A,u,b);CHKERRQ(ierr);
/* Выводим точное решение вектора, если необходимо */
ierr = PetscOptionsHasName(PETSC_NULL,"-view_exact_sol",&flg);
CHKERRQ(ierr);
if (flg)
{ ierr = VecView(u,PETSC_VIEWER_STDOUT_WORLD);
CHKERRQ(ierr);
}
/* Создаем метод решения системы линейных уравнений */
ierr = SLESCreate(PETSC_COMM_WORLD,&sles);CHKERRQ(ierr);
/* Устанавливаем операторы. Здесь матрица, которая определяет линейную
систему, служит как preconditioning матрица. */
ierr = SLESSetOperators(sles,A,A,DIFFERENT_NONZERO_PATTERN);
CHKERRQ(ierr);
/* Устанавливается метод решения */
ierr = SLESGetKSP(sles,&ksp);CHKERRQ(ierr);
ierr = KSPSetTolerances(ksp,1.e-2/((m+1)*(n+1)),1.e-50,