Замените всю строку, используя MatSetValuesStencil, на INSERT_VALUES.

Я использую процедуры Petsc Ksp.
Я строю оператор, используя MatSetValuesStencil, где при каждом вызове этой функции я указываю значения матрицы из одной строки длиной 5.
Есть случай, когда мне иногда нужно полностью заменить строку с трафарета длиной 5 на три длины. Режим INSERT_VALUES оставит два значения на неизмененных позициях или сбросит их на ноль?

0

Решение

Элементы матрицы, которые не указаны в аргументах idxm а также idxn функции MatSetValuesStencil(...) остаются без изменений, даже если INSERT_VALUES используется.

Вот небольшой код, начинающийся с ksp_ex29 чтобы проверить это:

static char help[] = "Does INSERT_VALUES changes the whole row ? No.\n\n";

#include <petscdm.h>
#include <petscdmda.h>
#include <petscksp.h>

extern PetscErrorCode ComputeMatrix42(DM da,Mat jac);
extern PetscErrorCode ComputeMatrix(DM da,Mat jac);

#undef __FUNCT__
#define __FUNCT__ "main"int main(int argc,char **argv)
{

DM             da;
PetscErrorCode ierr;
Mat matrix;

PetscInitialize(&argc,&argv,(char*)0,help);

ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_PERIODIC, DM_BOUNDARY_PERIODIC,DMDA_STENCIL_STAR,-3,-3,PETSC_DECIDE,PETSC_DECIDE,1,1,0,0,&da);CHKERRQ(ierr);

DMCreateMatrix(da,&matrix);

ComputeMatrix(da,matrix);

PetscPrintf(PETSC_COMM_WORLD,"A matrix of negative terms : \n");
MatView(matrix, PETSC_VIEWER_STDOUT_WORLD );

ComputeMatrix42(da,matrix);

PetscPrintf(PETSC_COMM_WORLD,"The diagonal, i-1 and i+1 are set to 42 : \n");
MatView(matrix, PETSC_VIEWER_STDOUT_WORLD );

ierr = DMDestroy(&da);CHKERRQ(ierr);
ierr = MatDestroy(&matrix);CHKERRQ(ierr);
ierr = PetscFinalize();

return 0;
}

#undef __FUNCT__
#define __FUNCT__ "ComputeMatrix"PetscErrorCode ComputeMatrix(DM da,Mat jac)
{
PetscErrorCode ierr;
PetscInt       i,j,mx,my,xm,ym,xs,ys;
PetscScalar    v[5];
MatStencil     row, col[5];

PetscFunctionBeginUser;
ierr      = DMDAGetInfo(da,0,&mx,&my,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
ierr      = DMDAGetCorners(da,&xs,&ys,0,&xm,&ym,0);CHKERRQ(ierr);
for (j=ys; j<ys+ym; j++) {
for (i=xs; i<xs+xm; i++) {
row.i = i; row.j = j;
v[0] = -1;              col[0].i = i;   col[0].j = j-1;
v[1] = -1;              col[1].i = i-1; col[1].j = j;
v[2] = -13; col[2].i = i;   col[2].j = j;
v[3] = -1;              col[3].i = i+1; col[3].j = j;
v[4] = -1;              col[4].i = i;   col[4].j = j+1;
ierr = MatSetValuesStencil(jac,1,&row,5,col,v,INSERT_VALUES);CHKERRQ(ierr);
}
}

ierr = MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
ierr = MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);

PetscFunctionReturn(0);
}

#undef __FUNCT__
#define __FUNCT__ "ComputeMatrix42"PetscErrorCode ComputeMatrix42(DM da,Mat jac)
{
PetscErrorCode ierr;
PetscInt       i,j,mx,my,xm,ym,xs,ys;
PetscScalar    v[3];
MatStencil     row, col[3];

PetscFunctionBeginUser;
ierr      = DMDAGetInfo(da,0,&mx,&my,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
ierr      = DMDAGetCorners(da,&xs,&ys,0,&xm,&ym,0);CHKERRQ(ierr);
for (j=ys; j<ys+ym; j++) {
for (i=xs; i<xs+xm; i++) {
row.i = i; row.j = j;
v[0] = 42;              col[0].i = i-1; col[0].j = j;
v[1] = 42; col[1].i = i;   col[1].j = j;
v[2] = 42;              col[2].i = i+1; col[2].j = j;
ierr = MatSetValuesStencil(jac,1,&row,3,col,v,INSERT_VALUES);CHKERRQ(ierr);
}
}

ierr = MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
ierr = MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);

PetscFunctionReturn(0);
}

Скомпилируйте его с помощью следующего make-файла:

include ${PETSC_DIR}/conf/variables
include ${PETSC_DIR}/conf/rules

main: main.o  chkopts
-${CLINKER} -o main main.o  ${PETSC_LIB}
${RM} main.o

Выход :

A matrix of negative terms :
Mat Object: 1 MPI processes
type: seqaij
row 0: (0, -13)  (1, -1)  (2, -1)  (3, -1)  (6, -1)
row 1: (0, -1)  (1, -13)  (2, -1)  (4, -1)  (7, -1)
row 2: (0, -1)  (1, -1)  (2, -13)  (5, -1)  (8, -1)
row 3: (0, -1)  (3, -13)  (4, -1)  (5, -1)  (6, -1)
row 4: (1, -1)  (3, -1)  (4, -13)  (5, -1)  (7, -1)
row 5: (2, -1)  (3, -1)  (4, -1)  (5, -13)  (8, -1)
row 6: (0, -1)  (3, -1)  (6, -13)  (7, -1)  (8, -1)
row 7: (1, -1)  (4, -1)  (6, -1)  (7, -13)  (8, -1)
row 8: (2, -1)  (5, -1)  (6, -1)  (7, -1)  (8, -13)
The diagonal, i-1 and i+1 are set to 42 :
Mat Object: 1 MPI processes
type: seqaij
row 0: (0, 42)  (1, 42)  (2, 42)  (3, -1)  (6, -1)
row 1: (0, 42)  (1, 42)  (2, 42)  (4, -1)  (7, -1)
row 2: (0, 42)  (1, 42)  (2, 42)  (5, -1)  (8, -1)
row 3: (0, -1)  (3, 42)  (4, 42)  (5, 42)  (6, -1)
row 4: (1, -1)  (3, 42)  (4, 42)  (5, 42)  (7, -1)
row 5: (2, -1)  (3, 42)  (4, 42)  (5, 42)  (8, -1)
row 6: (0, -1)  (3, -1)  (6, 42)  (7, 42)  (8, 42)
row 7: (1, -1)  (4, -1)  (6, 42)  (7, 42)  (8, 42)
row 8: (2, -1)  (5, -1)  (6, 42)  (7, 42)  (8, 42)

Я использую PETSC 3.5.2.

1

Другие решения


По вопросам рекламы [email protected]