Actual source code: matstruct.c
1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
6: This file is part of SLEPc.
7: SLEPc is distributed under a 2-clause BSD license (see LICENSE).
8: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9: */
11: #include <slepc/private/slepcimpl.h>
13: /*@
14: MatCreateBSE - Create a matrix that can be used to define a structured eigenvalue
15: problem of type BSE (Bethe-Salpeter Equation).
17: Collective
19: Input Parameters:
20: + R - matrix for the diagonal block (resonant)
21: - C - matrix for the off-diagonal block (coupling)
23: Output Parameter:
24: . H - the resulting matrix
26: Notes:
27: The resulting matrix has the block form H = [ R C; -C^H -R^T ], where R is assumed
28: to be (complex) Hermitian and C complex symmetric. Note that this function does
29: not check these properties, so if the matrices provided by the user do not satisfy
30: them, then the solver will not behave as expected.
32: The obtained matrix can be used as an input matrix to EPS eigensolvers via
33: EPSSetOperators() for the case that the problem type is EPS_BSE. Note that the user
34: cannot just build a matrix with the required structure, it must be done via this
35: function.
37: In the current implementation, H is a MATNEST matrix, where R and C form the top
38: block row, while the bottom block row is composed of matrices of type
39: MATTRANSPOSEVIRTUAL and MATHERMITIANTRANSPOSEVIRTUAL scaled by -1.
41: Level: intermediate
43: .seealso: `MatCreateNest()`, `EPSSetOperators()`, `EPSSetProblemType()`, `MatCreateHamiltonian()`
44: @*/
45: PetscErrorCode MatCreateBSE(Mat R,Mat C,Mat *H)
46: {
47: PetscInt Mr,Mc,Nr,Nc,mr,mc,nr,nc;
48: Mat block[4] = { R, C, NULL, NULL };
49: SlepcMatStruct mctx;
51: PetscFunctionBegin;
54: PetscCheckSameTypeAndComm(R,1,C,2);
55: PetscAssertPointer(H,3);
57: /* check sizes */
58: PetscCall(MatGetSize(R,&Mr,&Nr));
59: PetscCall(MatGetLocalSize(R,&mr,&nr));
60: PetscCall(MatGetSize(C,&Mc,&Nc));
61: PetscCall(MatGetLocalSize(C,&mc,&nc));
62: PetscCheck(Mc==Mr && mc==mr,PetscObjectComm((PetscObject)R),PETSC_ERR_ARG_INCOMP,"Incompatible row dimensions");
63: PetscCheck(Nc==Nr && nc==nr,PetscObjectComm((PetscObject)R),PETSC_ERR_ARG_INCOMP,"Incompatible column dimensions");
65: /* bottom block row */
66: PetscCall(MatCreateHermitianTranspose(C,&block[2]));
67: PetscCall(MatScale(block[2],-1.0));
68: PetscCall(MatCreateTranspose(R,&block[3]));
69: PetscCall(MatScale(block[3],-1.0));
71: /* create nest matrix and compose context */
72: PetscCall(MatCreateNest(PetscObjectComm((PetscObject)R),2,NULL,2,NULL,block,H));
73: PetscCall(MatDestroy(&block[2]));
74: PetscCall(MatDestroy(&block[3]));
76: PetscCall(PetscNew(&mctx));
77: mctx->cookie = SLEPC_MAT_STRUCT_BSE;
78: PetscCall(PetscObjectContainerCompose((PetscObject)*H,"SlepcMatStruct",mctx,PetscCtxDestroyDefault));
79: PetscFunctionReturn(PETSC_SUCCESS);
80: }
82: /*@
83: MatCreateHamiltonian - Create a matrix that can be used to define a structured
84: eigenvalue problem of Hamiltonian type.
86: Collective
88: Input Parameters:
89: + A - matrix for the (0,0) block
90: . B - matrix for the (0,1) block, must be real symmetric or Hermitian
91: - C - matrix for the (1,0) block, must be real symmetric or Hermitian
93: Output Parameter:
94: . H - the resulting matrix
96: Notes:
97: The resulting matrix has the block form H = [ A B; C -A^* ], where B and C are
98: assumed to be symmetric in the real case or Hermitian in the comples case. Note
99: that this function does not check this property, so if the matrices provided by
100: the user do not satisfy it, then the solver will not behave as expected.
102: The obtained matrix can be used as an input matrix to EPS eigensolvers via
103: EPSSetOperators() for the case that the problem type is EPS_HAMILT. Note that the
104: user cannot just build a matrix with the required structure, it must be done via
105: this function.
107: In the current implementation, H is a MATNEST matrix, where the (1,1) block is
108: a matrix of type MATHERMITIANTRANSPOSEVIRTUAL obtained from A and scaled by -1.
110: Level: intermediate
112: .seealso: `MatCreateNest()`, `EPSSetOperators()`, `EPSSetProblemType()`, `MatCreateBSE()`
113: @*/
114: PetscErrorCode MatCreateHamiltonian(Mat A,Mat B,Mat C,Mat *H)
115: {
116: PetscInt Ma,Mb,Mc,Na,Nb,Nc,ma,mb,mc,na,nb,nc;
117: Mat block[4] = { A, B, C, NULL };
118: SlepcMatStruct mctx;
120: PetscFunctionBegin;
124: PetscCheckSameTypeAndComm(A,1,B,2);
125: PetscCheckSameTypeAndComm(A,1,C,3);
126: PetscAssertPointer(H,4);
128: /* check sizes */
129: PetscCall(MatGetSize(A,&Ma,&Na));
130: PetscCall(MatGetLocalSize(A,&ma,&na));
131: PetscCall(MatGetSize(B,&Mb,&Nb));
132: PetscCall(MatGetLocalSize(B,&mb,&nb));
133: PetscCall(MatGetSize(C,&Mc,&Nc));
134: PetscCall(MatGetLocalSize(C,&mc,&nc));
135: PetscCheck(Mb==Ma && mb==ma,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"Incompatible row dimensions");
136: PetscCheck(Nc==Na && nc==na,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"Incompatible column dimensions");
138: /* (1,1) block */
139: PetscCall(MatCreateHermitianTranspose(A,&block[3]));
140: PetscCall(MatScale(block[3],-1.0));
142: /* create nest matrix and compose context */
143: PetscCall(MatCreateNest(PetscObjectComm((PetscObject)A),2,NULL,2,NULL,block,H));
144: PetscCall(MatDestroy(&block[3]));
146: PetscCall(PetscNew(&mctx));
147: mctx->cookie = SLEPC_MAT_STRUCT_HAMILT;
148: PetscCall(PetscObjectContainerCompose((PetscObject)*H,"SlepcMatStruct",mctx,PetscCtxDestroyDefault));
149: PetscFunctionReturn(PETSC_SUCCESS);
150: }