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: }