xref: /petsc/src/dm/impls/shell/dmshell.c (revision 69b1f4b7011d0e5bca0c93b0e1d4050951b6a33e)
1 #include <petscdmshell.h>       /*I    "petscdmshell.h"  I*/
2 #include <petscmat.h>           /*I    "petscmat.h"      I*/
3 #include <private/dmimpl.h>     /*I    "petscdm.h"       I*/
4 
5 typedef struct  {
6   Vec Xglobal;
7   Mat A;
8 } DM_Shell;
9 
10 #undef __FUNCT__
11 #define __FUNCT__ "DMCreateMatrix_Shell"
12 static PetscErrorCode DMCreateMatrix_Shell(DM dm,const MatType mtype,Mat *J)
13 {
14   PetscErrorCode ierr;
15   DM_Shell       *shell = (DM_Shell*)dm->data;
16   Mat            A;
17 
18   PetscFunctionBegin;
19   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
20   PetscValidPointer(J,3);
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     ierr = PetscTypeCompare((PetscObject)A,mtype,&flg);CHKERRQ(ierr);
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     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
30     ierr = MatZeroEntries(A);CHKERRQ(ierr);
31     *J = A;
32   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
33     ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J);CHKERRQ(ierr);
34     ierr = MatZeroEntries(*J);CHKERRQ(ierr);
35   }
36   PetscFunctionReturn(0);
37 }
38 
39 #undef __FUNCT__
40 #define __FUNCT__ "DMCreateGlobalVector_Shell"
41 PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec)
42 {
43   PetscErrorCode ierr;
44   DM_Shell       *shell = (DM_Shell*)dm->data;
45   Vec            X;
46 
47   PetscFunctionBegin;
48   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
49   PetscValidPointer(gvec,2);
50   *gvec = 0;
51   X = shell->Xglobal;
52   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
53     ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
54     ierr = VecZeroEntries(X);CHKERRQ(ierr);
55     *gvec = X;
56   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
57     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
58     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
59   }
60   ierr = PetscObjectCompose((PetscObject)*gvec,"DM",(PetscObject)dm);CHKERRQ(ierr);
61   PetscFunctionReturn(0);
62 }
63 
64 #undef __FUNCT__
65 #define __FUNCT__ "DMShellSetMatrix"
66 /*@
67    DMShellSetMatrix - sets a template matrix associated with the DMShell
68 
69    Collective
70 
71    Input Arguments:
72 +  dm - shell DM
73 -  J - template matrix
74 
75    Level: advanced
76 
77 .seealso: DMCreateMatrix(), DMShellSetCreateMatrix()
78 @*/
79 PetscErrorCode DMShellSetMatrix(DM dm,Mat J)
80 {
81   DM_Shell *shell = (DM_Shell*)dm->data;
82   PetscErrorCode ierr;
83 
84   PetscFunctionBegin;
85   ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
86   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
87   shell->A = J;
88   PetscFunctionReturn(0);
89 }
90 
91 #undef __FUNCT__
92 #define __FUNCT__ "DMShellSetCreateMatrix"
93 /*@C
94    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM
95 
96    Logically Collective on DM
97 
98    Input Arguments:
99 +  dm - the shell DM
100 -  func - the function to create a matrix
101 
102    Level: advanced
103 
104 .seealso: DMCreateMatrix(), DMShellSetMatrix()
105 @*/
106 PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,const MatType,Mat*))
107 {
108 
109   PetscFunctionBegin;
110   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
111   dm->ops->creatematrix = func;
112   PetscFunctionReturn(0);
113 }
114 
115 #undef __FUNCT__
116 #define __FUNCT__ "DMShellSetGlobalVector"
117 /*@
118    DMShellSetGlobalVector - sets a template global vector associated with the DMShell
119 
120    Logically Collective on DM
121 
122    Input Arguments:
123 +  dm - shell DM
124 -  X - template vector
125 
126    Level: advanced
127 
128 .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector()
129 @*/
130 PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X)
131 {
132   DM_Shell *shell = (DM_Shell*)dm->data;
133   PetscErrorCode ierr;
134 
135   PetscFunctionBegin;
136   ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
137   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
138   shell->Xglobal = X;
139   PetscFunctionReturn(0);
140 }
141 
142 #undef __FUNCT__
143 #define __FUNCT__ "DMShellSetCreateGlobalVector"
144 /*@C
145    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
146 
147    Logically Collective
148 
149    Input Arguments:
150 +  dm - the shell DM
151 -  func - the creation routine
152 
153    Level: advanced
154 
155 .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix()
156 @*/
157 PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
158 {
159 
160   PetscFunctionBegin;
161   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
162   dm->ops->createglobalvector = func;
163   PetscFunctionReturn(0);
164 }
165 
166 #undef __FUNCT__
167 #define __FUNCT__ "DMDestroy_Shell"
168 static PetscErrorCode DMDestroy_Shell(DM dm)
169 {
170   PetscErrorCode ierr;
171   DM_Shell       *shell = (DM_Shell*)dm->data;
172 
173   PetscFunctionBegin;
174   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
175   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
176   ierr = PetscFree(dm->data);CHKERRQ(ierr);
177   PetscFunctionReturn(0);
178 }
179 
180 
181 #undef __FUNCT__
182 #define __FUNCT__ "DMCreate_Shell"
183 PETSC_EXTERN_C PetscErrorCode  DMCreate_Shell(DM p)
184 {
185   PetscErrorCode ierr;
186   DM_Shell      *shell;
187 
188   PetscFunctionBegin;
189   ierr = PetscNewLog(p,DM_Shell,&shell);CHKERRQ(ierr);
190   p->data = shell;
191 
192   ierr = PetscObjectChangeTypeName((PetscObject)p,DMSHELL);CHKERRQ(ierr);
193   p->ops->createglobalvector = DMCreateGlobalVector_Shell;
194   p->ops->creatematrix       = DMCreateMatrix_Shell;
195   p->ops->destroy            = DMDestroy_Shell;
196   PetscFunctionReturn(0);
197 }
198 
199 #undef __FUNCT__
200 #define __FUNCT__ "DMShellCreate"
201 /*@
202     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
203 
204     Collective on MPI_Comm
205 
206     Input Parameter:
207 .   comm - the processors that will share the global vector
208 
209     Output Parameters:
210 .   shell - the shell DM
211 
212     Level: advanced
213 
214 .seealso DMDestroy(), DMCreateGlobalVector()
215 @*/
216 PetscErrorCode  DMShellCreate(MPI_Comm comm,DM *dm)
217 {
218   PetscErrorCode ierr;
219 
220   PetscFunctionBegin;
221   PetscValidPointer(dm,2);
222   ierr = DMCreate(comm,dm);CHKERRQ(ierr);
223   ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr);
224   PetscFunctionReturn(0);
225 }
226