Actual source code: dmshell.c
petsc-3.3-p5 2012-12-01
1: #include <petscdmshell.h> /*I "petscdmshell.h" I*/
2: #include <petscmat.h> /*I "petscmat.h" I*/
3: #include <petsc-private/dmimpl.h> /*I "petscdm.h" I*/
5: typedef struct {
6: Vec Xglobal;
7: Mat A;
8: } DM_Shell;
12: static PetscErrorCode DMCreateMatrix_Shell(DM dm,const MatType mtype,Mat *J)
13: {
15: DM_Shell *shell = (DM_Shell*)dm->data;
16: Mat A;
21: A = shell->A;
22: if (!A) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_USER,"Must call DMShellSetMatrix() or DMShellSetCreateMatrix()");
23: if (mtype) {
24: PetscBool flg;
25: PetscObjectTypeCompare((PetscObject)A,mtype,&flg);
26: if (!flg) SETERRQ2(((PetscObject)dm)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Requested matrix of type %s, but only %s available",mtype,((PetscObject)A)->type_name);
27: }
28: if (((PetscObject)A)->refct < 2) { /* We have an exclusive reference so we can give it out */
29: PetscObjectReference((PetscObject)A);
30: MatZeroEntries(A);
31: *J = A;
32: } else { /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
33: MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J);
34: MatZeroEntries(*J);
35: }
36: return(0);
37: }
41: PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec)
42: {
44: DM_Shell *shell = (DM_Shell*)dm->data;
45: Vec X;
50: *gvec = 0;
51: X = shell->Xglobal;
52: if (!X) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
53: if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
54: PetscObjectReference((PetscObject)X);
55: VecZeroEntries(X);
56: *gvec = X;
57: } else { /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
58: VecDuplicate(X,gvec);
59: VecZeroEntries(*gvec);
60: }
61: PetscObjectCompose((PetscObject)*gvec,"DM",(PetscObject)dm);
62: return(0);
63: }
67: /*@
68: DMShellSetMatrix - sets a template matrix associated with the DMShell
70: Collective
72: Input Arguments:
73: + dm - shell DM
74: - J - template matrix
76: Level: advanced
78: .seealso: DMCreateMatrix(), DMShellSetCreateMatrix()
79: @*/
80: PetscErrorCode DMShellSetMatrix(DM dm,Mat J)
81: {
82: DM_Shell *shell = (DM_Shell*)dm->data;
84: PetscBool isshell;
89: PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);
90: if (!isshell) return(0);
91: PetscObjectReference((PetscObject)J);
92: MatDestroy(&shell->A);
93: shell->A = J;
94: return(0);
95: }
99: /*@C
100: DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM
102: Logically Collective on DM
104: Input Arguments:
105: + dm - the shell DM
106: - func - the function to create a matrix
108: Level: advanced
110: .seealso: DMCreateMatrix(), DMShellSetMatrix()
111: @*/
112: PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,const MatType,Mat*))
113: {
117: dm->ops->creatematrix = func;
118: return(0);
119: }
123: /*@
124: DMShellSetGlobalVector - sets a template global vector associated with the DMShell
126: Logically Collective on DM
128: Input Arguments:
129: + dm - shell DM
130: - X - template vector
132: Level: advanced
134: .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector()
135: @*/
136: PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X)
137: {
138: DM_Shell *shell = (DM_Shell*)dm->data;
140: PetscBool isshell;
145: PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);
146: if (!isshell) return(0);
147: PetscObjectReference((PetscObject)X);
148: VecDestroy(&shell->Xglobal);
149: shell->Xglobal = X;
150: return(0);
151: }
155: /*@C
156: DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
158: Logically Collective
160: Input Arguments:
161: + dm - the shell DM
162: - func - the creation routine
164: Level: advanced
166: .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix()
167: @*/
168: PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
169: {
173: dm->ops->createglobalvector = func;
174: return(0);
175: }
179: static PetscErrorCode DMDestroy_Shell(DM dm)
180: {
182: DM_Shell *shell = (DM_Shell*)dm->data;
185: MatDestroy(&shell->A);
186: VecDestroy(&shell->Xglobal);
187: PetscFree(dm->data);
188: return(0);
189: }
195: {
197: DM_Shell *shell;
200: PetscNewLog(dm,DM_Shell,&shell);
201: dm->data = shell;
203: PetscObjectChangeTypeName((PetscObject)dm,DMSHELL);
204: dm->ops->destroy = DMDestroy_Shell;
205: dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
206: dm->ops->creatematrix = DMCreateMatrix_Shell;
207: return(0);
208: }
212: /*@
213: DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
215: Collective on MPI_Comm
217: Input Parameter:
218: . comm - the processors that will share the global vector
220: Output Parameters:
221: . shell - the shell DM
223: Level: advanced
225: .seealso DMDestroy(), DMCreateGlobalVector()
226: @*/
227: PetscErrorCode DMShellCreate(MPI_Comm comm,DM *dm)
228: {
233: DMCreate(comm,dm);
234: DMSetType(*dm,DMSHELL);
235: return(0);
236: }