Skip to main content
`Ctrl`+`K`

# MatCreateShell

Creates a new matrix of `MatType` `MATSHELL` for use with a user-defined private matrix data storage format.

## Synopsis

    #include "petscmat.h"
    PetscErrorCode MatCreateShell(MPI_Comm comm, PetscInt m, PetscInt n, PetscInt M, PetscInt N, void *ctx, Mat *A)

Collective

## Input Parameters

- comm - MPI communicator

- m - number of local rows (or `PETSC_DECIDE` to have calculated if `M` is given)

- n - number of local columns (or `PETSC_DECIDE` to have calculated if `N` is given)

- M - number of global rows (may be `PETSC_DETERMINE` to have calculated if `m` is given)

- N - number of global columns (may be `PETSC_DETERMINE` to have calculated if `n` is given)

- ctx - pointer to data needed by the shell matrix routines

## Output Parameter

- A - the matrix

## Example Usage

      extern PetscErrorCode mult(Mat, Vec, Vec);

      MatCreateShell(comm, m, n, M, N, ctx, &mat);
      MatShellSetOperation(mat, MATOP_MULT, (void(*)(void))mult);
      MatShellSetContext(mat,ctx);
      // Use matrix for operations that have been set
      MatDestroy(mat);

## Notes

The shell matrix type is intended to provide a simple way for users to write a custom matrix specifically for their application.

`MatCreateShell()` is used in conjunction with `MatShellSetContext()` and `MatShellSetOperation()`.

PETSc requires that matrices and vectors being used for certain operations are partitioned accordingly. For example, when creating a shell matrix, `A`, that supports parallel matrix-vector products using `MatMult`(A,x,y) the user should set the number of local matrix rows to be the number of local elements of the corresponding result vector, y. Note that this is information is required for use of the matrix interface routines, even though the shell matrix may not actually be physically partitioned. For example,

         Vec x, y
         extern PetscErrorCode mult(Mat,Vec,Vec);
         Mat A

         VecCreateMPI(comm,PETSC_DECIDE,M,&y);
         VecCreateMPI(comm,PETSC_DECIDE,N,&x);
         VecGetLocalSize(y,&m);
         VecGetLocalSize(x,&n);
         MatCreateShell(comm,m,n,M,N,ctx,&A);
         MatShellSetOperation(mat,MATOP_MULT,(void(*)(void))mult);
         MatMult(A,x,y);
         MatDestroy(&A);
         VecDestroy(&y);
         VecDestroy(&x);

`MATSHELL` handles `MatShift()`, `MatDiagonalSet()`, `MatDiagonalScale()`, `MatAXPY()`, `MatScale()`, `MatZeroRows()` and `MatZeroRowsColumns()` internally, so these operations cannot be overwritten unless `MatShellSetManageScalingShifts()` is called.

## Developer Notes

For rectangular matrices do all the scalings and shifts make sense?

Regarding shifting and scaling. The general form is

diag(left)(vscale*A + diag(dshift) + vshift I)diag(right)

The order you apply the operations is important. For example if you have a dshift then apply a MatScale(s) you get svscaleA + sdiag(shift). But if you first scale and then shift you get svscale*A + diag(shift)

A is the user provided function.

`KSP`/`PC` uses changes in the `Mat`’s “state” to decide if preconditioners need to be rebuilt `PCSetUp()` only calls the setup() for for the `PC` implementation if the `Mat` state has increased from the previous call. Thus to get changes in a `MATSHELL` to trigger an update in the preconditioner you must call `MatAssemblyBegin()` and `MatAssemblyEnd()` or `PetscObjectStateIncrease`((`PetscObject`)mat); each time the `MATSHELL` matrix has changed.

Matrix-matrix product operations can be specified using `MatShellSetMatProductOperation()`

Calling `MatAssemblyBegin()`/`MatAssemblyEnd()` on a `MATSHELL` removes any previously supplied shift and scales that were provided with `MatDiagonalSet()`, `MatShift()`, `MatScale()`, or `MatDiagonalScale()`.

## Fortran Notes

To use this from Fortran with a `ctx` you must write an interface definition for this function and for `MatShellGetContext()` that tells Fortran the Fortran derived data type you are passing in as the `ctx` argument.

## See Also

Matrices, `Mat`, `MATSHELL`, `MatShellSetOperation()`, `MatHasOperation()`, `MatShellGetContext()`, `MatShellSetContext()`, `MatShellSetManageScalingShifts()`, `MatShellSetMatProductOperation()`

## Level

advanced

## Location

src/mat/impls/shell/shell.c

## Examples

src/snes/tutorials/ex36.c
src/tao/bound/tutorials/plate2.c
src/ksp/ksp/tutorials/ex14f.F90
src/tao/unconstrained/tutorials/eptorsion3.c
src/mat/tutorials/ex6f.F90
src/mat/tutorials/ex20f.F90
src/tao/pde_constrained/tutorials/parabolic.c
src/tao/unconstrained/tutorials/eptorsion1.c
src/tao/pde_constrained/tutorials/hyperbolic.c
src/tao/pde_constrained/tutorials/elliptic.c

Index of all Mat routines
Table of Contents for all manual pages
Index of all manual pages