xref: /petsc/src/mat/tests/ex264.c (revision 609caa7c8c030312b00807b4f015fd827bb80932)
1b22c5e46SPierre Jolivet static char help[] = "Test MatConvert() with a MATNEST with scaled and shifted MATTRANSPOSEVIRTUAL blocks.\n\n";
2b22c5e46SPierre Jolivet 
3b22c5e46SPierre Jolivet #include <petscmat.h>
4b22c5e46SPierre Jolivet 
5b22c5e46SPierre Jolivet /*
6b22c5e46SPierre Jolivet    This example builds the matrix
7b22c5e46SPierre Jolivet 
8b22c5e46SPierre Jolivet         H = [  R                    C
9b22c5e46SPierre Jolivet               alpha C^H + beta I    gamma R^T + delta I ],
10b22c5e46SPierre Jolivet 
11b22c5e46SPierre Jolivet    where R is Hermitian and C is complex symmetric. In particular, R and C have the
12b22c5e46SPierre Jolivet    following Toeplitz structure:
13b22c5e46SPierre Jolivet 
14b22c5e46SPierre Jolivet         R = pentadiag{a,b,c,conj(b),conj(a)}
15b22c5e46SPierre Jolivet         C = tridiag{b,d,b}
16b22c5e46SPierre Jolivet 
17b22c5e46SPierre Jolivet    where a,b,d are complex scalars, and c is real.
18b22c5e46SPierre Jolivet */
19b22c5e46SPierre Jolivet 
main(int argc,char ** argv)20b22c5e46SPierre Jolivet int main(int argc, char **argv)
21b22c5e46SPierre Jolivet {
22b22c5e46SPierre Jolivet   Mat         block[4], H, R, C, M;
23b22c5e46SPierre Jolivet   PetscScalar a, b, c, d;
24b22c5e46SPierre Jolivet   PetscInt    n = 13, Istart, Iend, i;
25b22c5e46SPierre Jolivet   PetscBool   flg;
26b22c5e46SPierre Jolivet 
27b22c5e46SPierre Jolivet   PetscFunctionBeginUser;
28c8025a54SPierre Jolivet   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
29b22c5e46SPierre Jolivet 
30b22c5e46SPierre Jolivet   PetscCall(PetscOptionsGetInt(NULL, NULL, "-n", &n, NULL));
31b22c5e46SPierre Jolivet 
32b22c5e46SPierre Jolivet   a = PetscCMPLX(-0.1, 0.2);
33b22c5e46SPierre Jolivet   b = PetscCMPLX(1.0, 0.5);
34b22c5e46SPierre Jolivet   c = 4.5;
35b22c5e46SPierre Jolivet   d = PetscCMPLX(2.0, 0.2);
36b22c5e46SPierre Jolivet 
37b22c5e46SPierre Jolivet   PetscCall(MatCreate(PETSC_COMM_WORLD, &R));
38b22c5e46SPierre Jolivet   PetscCall(MatSetSizes(R, PETSC_DECIDE, PETSC_DECIDE, n, n));
39b22c5e46SPierre Jolivet   PetscCall(MatSetFromOptions(R));
40b22c5e46SPierre Jolivet 
41b22c5e46SPierre Jolivet   PetscCall(MatCreate(PETSC_COMM_WORLD, &C));
42b22c5e46SPierre Jolivet   PetscCall(MatSetSizes(C, PETSC_DECIDE, PETSC_DECIDE, n, n));
43b22c5e46SPierre Jolivet   PetscCall(MatSetFromOptions(C));
44b22c5e46SPierre Jolivet 
45b22c5e46SPierre Jolivet   PetscCall(MatGetOwnershipRange(R, &Istart, &Iend));
46b22c5e46SPierre Jolivet   for (i = Istart; i < Iend; i++) {
47b22c5e46SPierre Jolivet     if (i > 1) PetscCall(MatSetValue(R, i, i - 2, a, INSERT_VALUES));
48b22c5e46SPierre Jolivet     if (i > 0) PetscCall(MatSetValue(R, i, i - 1, b, INSERT_VALUES));
49b22c5e46SPierre Jolivet     PetscCall(MatSetValue(R, i, i, c, INSERT_VALUES));
50b22c5e46SPierre Jolivet     if (i < n - 1) PetscCall(MatSetValue(R, i, i + 1, PetscConj(b), INSERT_VALUES));
51b22c5e46SPierre Jolivet     if (i < n - 2) PetscCall(MatSetValue(R, i, i + 2, PetscConj(a), INSERT_VALUES));
52b22c5e46SPierre Jolivet   }
53b22c5e46SPierre Jolivet 
54b22c5e46SPierre Jolivet   PetscCall(MatGetOwnershipRange(C, &Istart, &Iend));
55b22c5e46SPierre Jolivet   for (i = Istart; i < Iend; i++) {
56b22c5e46SPierre Jolivet     if (i > 0) PetscCall(MatSetValue(C, i, i - 1, b, INSERT_VALUES));
57b22c5e46SPierre Jolivet     PetscCall(MatSetValue(C, i, i, d, INSERT_VALUES));
58b22c5e46SPierre Jolivet     if (i < n - 1) PetscCall(MatSetValue(C, i, i + 1, b, INSERT_VALUES));
59b22c5e46SPierre Jolivet   }
60b22c5e46SPierre Jolivet 
61b22c5e46SPierre Jolivet   PetscCall(MatAssemblyBegin(R, MAT_FINAL_ASSEMBLY));
62b22c5e46SPierre Jolivet   PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY));
63b22c5e46SPierre Jolivet   PetscCall(MatAssemblyEnd(R, MAT_FINAL_ASSEMBLY));
64b22c5e46SPierre Jolivet   PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY));
65b22c5e46SPierre Jolivet 
66b22c5e46SPierre Jolivet   block[0] = R;
67b22c5e46SPierre Jolivet   block[1] = C;
68b22c5e46SPierre Jolivet 
69b22c5e46SPierre Jolivet   PetscCall(MatCreateHermitianTranspose(C, &block[2]));
70b22c5e46SPierre Jolivet   PetscCall(MatScale(block[2], PetscConj(b)));
71b22c5e46SPierre Jolivet   PetscCall(MatShift(block[2], d));
72b22c5e46SPierre Jolivet   PetscCall(MatCreateTranspose(R, &block[3]));
73b22c5e46SPierre Jolivet   PetscCall(MatScale(block[3], PetscConj(d)));
74b22c5e46SPierre Jolivet   PetscCall(MatShift(block[3], b));
75b22c5e46SPierre Jolivet   PetscCall(MatCreateNest(PetscObjectComm((PetscObject)R), 2, NULL, 2, NULL, block, &H));
76b22c5e46SPierre Jolivet   PetscCall(MatDestroy(&block[2]));
77b22c5e46SPierre Jolivet   PetscCall(MatDestroy(&block[3]));
78b22c5e46SPierre Jolivet 
79b22c5e46SPierre Jolivet   PetscCall(MatConvert(H, MATAIJ, MAT_INITIAL_MATRIX, &M));
80b22c5e46SPierre Jolivet   PetscCall(MatMultEqual(H, M, 20, &flg));
81b22c5e46SPierre Jolivet   PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "MatNest != MatAIJ");
82b22c5e46SPierre Jolivet 
83b22c5e46SPierre Jolivet   PetscCall(MatDestroy(&R));
84b22c5e46SPierre Jolivet   PetscCall(MatDestroy(&C));
85b22c5e46SPierre Jolivet   PetscCall(MatDestroy(&H));
86b22c5e46SPierre Jolivet   PetscCall(MatDestroy(&M));
87b22c5e46SPierre Jolivet   PetscCall(PetscFinalize());
88b22c5e46SPierre Jolivet   return 0;
89b22c5e46SPierre Jolivet }
90b22c5e46SPierre Jolivet 
91b22c5e46SPierre Jolivet /*TEST
92b22c5e46SPierre Jolivet 
93b22c5e46SPierre Jolivet    build:
94b22c5e46SPierre Jolivet       requires: complex
95b22c5e46SPierre Jolivet 
96b22c5e46SPierre Jolivet    test:
97*3886731fSPierre Jolivet       output_file: output/empty.out
98b22c5e46SPierre Jolivet       nsize: {{1 4}}
99b22c5e46SPierre Jolivet 
100b22c5e46SPierre Jolivet TEST*/
101