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