xref: /petsc/src/dm/impls/shell/dmshell.c (revision 8d359177c33ddf5f82763e570f2db1a8881cb79a)
1fe1899a2SJed Brown #include <petscdmshell.h>       /*I    "petscdmshell.h"  I*/
207475bc1SBarry Smith #include <petscmat.h>
307475bc1SBarry Smith #include <petsc-private/dmimpl.h>
4fe1899a2SJed Brown 
5fe1899a2SJed Brown typedef struct  {
6fe1899a2SJed Brown   Vec        Xglobal;
7dc43b69eSJed Brown   Vec        Xlocal;
8fe1899a2SJed Brown   Mat        A;
981634712SRichard Tran Mills   VecScatter *gtol;
1081634712SRichard Tran Mills   VecScatter *ltog;
11fe1899a2SJed Brown } DM_Shell;
12fe1899a2SJed Brown 
13fe1899a2SJed Brown #undef __FUNCT__
14*8d359177SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin_Shell_Default"
15*8d359177SBarry Smith /*@C
16*8d359177SBarry Smith    DMGlobalToLocalBegin_Shell_Default - Uses the GlobalToLocal VecScatter context set by the user to begin a global to local scatter
17*8d359177SBarry Smith    Collective
18*8d359177SBarry Smith 
19*8d359177SBarry Smith    Input Arguments:
20*8d359177SBarry Smith +  dm - shell DM
21*8d359177SBarry Smith .  g - global vector
22*8d359177SBarry Smith .  mode - InsertMode
23*8d359177SBarry Smith -  l - local vector
24*8d359177SBarry Smith 
25*8d359177SBarry Smith    Level: developer
26*8d359177SBarry Smith 
27*8d359177SBarry Smith .seealso: DMGlobalToLocalEnd_Shell_Default()
28*8d359177SBarry Smith @*/
29*8d359177SBarry Smith static PetscErrorCode DMGlobalToLocalBegin_Shell_Default(DM dm,Vec g,InsertMode mode,Vec l)
30*8d359177SBarry Smith {
31*8d359177SBarry Smith   PetscErrorCode ierr;
32*8d359177SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
33*8d359177SBarry Smith 
34*8d359177SBarry Smith   PetscFunctionBegin;
35*8d359177SBarry Smith   ierr = VecScatterBegin(*(shell->gtol),g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
36*8d359177SBarry Smith   PetscFunctionReturn(0);
37*8d359177SBarry Smith }
38*8d359177SBarry Smith 
39*8d359177SBarry Smith #undef __FUNCT__
40*8d359177SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd_Shell_Default"
41*8d359177SBarry Smith /*@C
42*8d359177SBarry Smith    DMGlobalToLocalEnd_Shell_Default - Uses the GlobalToLocal VecScatter context set by the user to end a global to local scatter
43*8d359177SBarry Smith    Collective
44*8d359177SBarry Smith 
45*8d359177SBarry Smith    Input Arguments:
46*8d359177SBarry Smith +  dm - shell DM
47*8d359177SBarry Smith .  g - global vector
48*8d359177SBarry Smith .  mode - InsertMode
49*8d359177SBarry Smith -  l - local vector
50*8d359177SBarry Smith 
51*8d359177SBarry Smith    Level: developer
52*8d359177SBarry Smith 
53*8d359177SBarry Smith .seealso: DMGlobalToLocalBegin_Shell_Default()
54*8d359177SBarry Smith @*/
55*8d359177SBarry Smith static PetscErrorCode DMGlobalToLocalEnd_Shell_Default(DM dm,Vec g,InsertMode mode,Vec l)
56*8d359177SBarry Smith {
57*8d359177SBarry Smith   PetscErrorCode ierr;
58*8d359177SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
59*8d359177SBarry Smith 
60*8d359177SBarry Smith   PetscFunctionBegin;
61*8d359177SBarry Smith   ierr = VecScatterEnd(*(shell->gtol),g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
62*8d359177SBarry Smith   PetscFunctionReturn(0);
63*8d359177SBarry Smith }
64*8d359177SBarry Smith 
65*8d359177SBarry Smith #undef __FUNCT__
66fe1899a2SJed Brown #define __FUNCT__ "DMCreateMatrix_Shell"
6719fd82e9SBarry Smith static PetscErrorCode DMCreateMatrix_Shell(DM dm,MatType mtype,Mat *J)
68fe1899a2SJed Brown {
69fe1899a2SJed Brown   PetscErrorCode ierr;
70fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
71fe1899a2SJed Brown   Mat            A;
72fe1899a2SJed Brown 
73fe1899a2SJed Brown   PetscFunctionBegin;
74fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
75fe1899a2SJed Brown   PetscValidPointer(J,3);
767bde9f88SJed Brown   if (!shell->A) {
777bde9f88SJed Brown     if (shell->Xglobal) {
787bde9f88SJed Brown       PetscInt m,M;
797bde9f88SJed Brown       ierr = PetscInfo(dm,"Naively creating matrix using global vector distribution without preallocation");CHKERRQ(ierr);
807bde9f88SJed Brown       ierr = VecGetSize(shell->Xglobal,&M);CHKERRQ(ierr);
817bde9f88SJed Brown       ierr = VecGetLocalSize(shell->Xglobal,&m);CHKERRQ(ierr);
82ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)dm),&shell->A);CHKERRQ(ierr);
837bde9f88SJed Brown       ierr = MatSetSizes(shell->A,m,m,M,M);CHKERRQ(ierr);
847bde9f88SJed Brown       if (mtype) {ierr = MatSetType(shell->A,mtype);CHKERRQ(ierr);}
857bde9f88SJed Brown       ierr = MatSetUp(shell->A);CHKERRQ(ierr);
86ce94432eSBarry Smith     } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector");
877bde9f88SJed Brown   }
88fe1899a2SJed Brown   A = shell->A;
89ad6bc421SBarry Smith   /* the check below is tacky and incomplete */
90fe1899a2SJed Brown   if (mtype) {
91ad6bc421SBarry Smith     PetscBool flg,aij,seqaij,mpiaij;
92251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)A,mtype,&flg);CHKERRQ(ierr);
93ad6bc421SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
94ad6bc421SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&mpiaij);CHKERRQ(ierr);
95ad6bc421SBarry Smith     ierr = PetscStrcmp(mtype,MATAIJ,&aij);CHKERRQ(ierr);
96ad6bc421SBarry Smith     if (!flg) {
97ce94432eSBarry Smith       if (!(aij & (seqaij || mpiaij))) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_NOTSAMETYPE,"Requested matrix of type %s, but only %s available",mtype,((PetscObject)A)->type_name);
98ad6bc421SBarry Smith     }
99fe1899a2SJed Brown   }
100fe1899a2SJed Brown   if (((PetscObject)A)->refct < 2) { /* We have an exclusive reference so we can give it out */
101fe1899a2SJed Brown     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
102fe1899a2SJed Brown     ierr = MatZeroEntries(A);CHKERRQ(ierr);
103fe1899a2SJed Brown     *J   = A;
104fe1899a2SJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
105fe1899a2SJed Brown     ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J);CHKERRQ(ierr);
106fe1899a2SJed Brown     ierr = MatZeroEntries(*J);CHKERRQ(ierr);
107fe1899a2SJed Brown   }
108fe1899a2SJed Brown   PetscFunctionReturn(0);
109fe1899a2SJed Brown }
110fe1899a2SJed Brown 
111fe1899a2SJed Brown #undef __FUNCT__
112fe1899a2SJed Brown #define __FUNCT__ "DMCreateGlobalVector_Shell"
113fe1899a2SJed Brown PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec)
114fe1899a2SJed Brown {
115fe1899a2SJed Brown   PetscErrorCode ierr;
116fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
117fe1899a2SJed Brown   Vec            X;
118fe1899a2SJed Brown 
119fe1899a2SJed Brown   PetscFunctionBegin;
120fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
121fe1899a2SJed Brown   PetscValidPointer(gvec,2);
122fe1899a2SJed Brown   *gvec = 0;
123fe1899a2SJed Brown   X     = shell->Xglobal;
124ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
125fe1899a2SJed Brown   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
126fe1899a2SJed Brown     ierr  = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
127fe1899a2SJed Brown     ierr  = VecZeroEntries(X);CHKERRQ(ierr);
128fe1899a2SJed Brown     *gvec = X;
129fe1899a2SJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
130fe1899a2SJed Brown     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
131fe1899a2SJed Brown     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
132fe1899a2SJed Brown   }
133c688c046SMatthew G Knepley   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
134fe1899a2SJed Brown   PetscFunctionReturn(0);
135fe1899a2SJed Brown }
136fe1899a2SJed Brown 
137fe1899a2SJed Brown #undef __FUNCT__
138dc43b69eSJed Brown #define __FUNCT__ "DMCreateLocalVector_Shell"
139dc43b69eSJed Brown PetscErrorCode DMCreateLocalVector_Shell(DM dm,Vec *gvec)
140dc43b69eSJed Brown {
141dc43b69eSJed Brown   PetscErrorCode ierr;
142dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
143dc43b69eSJed Brown   Vec            X;
144dc43b69eSJed Brown 
145dc43b69eSJed Brown   PetscFunctionBegin;
146dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
147dc43b69eSJed Brown   PetscValidPointer(gvec,2);
148dc43b69eSJed Brown   *gvec = 0;
149dc43b69eSJed Brown   X     = shell->Xlocal;
150ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()");
151dc43b69eSJed Brown   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
152dc43b69eSJed Brown     ierr  = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
153dc43b69eSJed Brown     ierr  = VecZeroEntries(X);CHKERRQ(ierr);
154dc43b69eSJed Brown     *gvec = X;
155dc43b69eSJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
156dc43b69eSJed Brown     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
157dc43b69eSJed Brown     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
158dc43b69eSJed Brown   }
1596e4cbd8bSMark F. Adams   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
160dc43b69eSJed Brown   PetscFunctionReturn(0);
161dc43b69eSJed Brown }
162dc43b69eSJed Brown 
163dc43b69eSJed Brown #undef __FUNCT__
164fe1899a2SJed Brown #define __FUNCT__ "DMShellSetMatrix"
165fe1899a2SJed Brown /*@
166fe1899a2SJed Brown    DMShellSetMatrix - sets a template matrix associated with the DMShell
167fe1899a2SJed Brown 
168fe1899a2SJed Brown    Collective
169fe1899a2SJed Brown 
170fe1899a2SJed Brown    Input Arguments:
171fe1899a2SJed Brown +  dm - shell DM
172fe1899a2SJed Brown -  J - template matrix
173fe1899a2SJed Brown 
174fe1899a2SJed Brown    Level: advanced
175fe1899a2SJed Brown 
176fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetCreateMatrix()
177fe1899a2SJed Brown @*/
178fe1899a2SJed Brown PetscErrorCode DMShellSetMatrix(DM dm,Mat J)
179fe1899a2SJed Brown {
180fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
181fe1899a2SJed Brown   PetscErrorCode ierr;
1828c87107bSJed Brown   PetscBool      isshell;
183fe1899a2SJed Brown 
184fe1899a2SJed Brown   PetscFunctionBegin;
1858c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1868c87107bSJed Brown   PetscValidHeaderSpecific(J,MAT_CLASSID,2);
187251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
1888c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
189fe1899a2SJed Brown   ierr     = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
190fe1899a2SJed Brown   ierr     = MatDestroy(&shell->A);CHKERRQ(ierr);
191fe1899a2SJed Brown   shell->A = J;
192fe1899a2SJed Brown   PetscFunctionReturn(0);
193fe1899a2SJed Brown }
194fe1899a2SJed Brown 
195fe1899a2SJed Brown #undef __FUNCT__
196fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateMatrix"
197fe1899a2SJed Brown /*@C
198fe1899a2SJed Brown    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM
199fe1899a2SJed Brown 
200fe1899a2SJed Brown    Logically Collective on DM
201fe1899a2SJed Brown 
202fe1899a2SJed Brown    Input Arguments:
203fe1899a2SJed Brown +  dm - the shell DM
204fe1899a2SJed Brown -  func - the function to create a matrix
205fe1899a2SJed Brown 
206fe1899a2SJed Brown    Level: advanced
207fe1899a2SJed Brown 
208fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetMatrix()
209fe1899a2SJed Brown @*/
21019fd82e9SBarry Smith PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,MatType,Mat*))
211fe1899a2SJed Brown {
212fe1899a2SJed Brown 
213fe1899a2SJed Brown   PetscFunctionBegin;
214fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
215fe1899a2SJed Brown   dm->ops->creatematrix = func;
216fe1899a2SJed Brown   PetscFunctionReturn(0);
217fe1899a2SJed Brown }
218fe1899a2SJed Brown 
219fe1899a2SJed Brown #undef __FUNCT__
220fe1899a2SJed Brown #define __FUNCT__ "DMShellSetGlobalVector"
221fe1899a2SJed Brown /*@
222fe1899a2SJed Brown    DMShellSetGlobalVector - sets a template global vector associated with the DMShell
223fe1899a2SJed Brown 
224fe1899a2SJed Brown    Logically Collective on DM
225fe1899a2SJed Brown 
226fe1899a2SJed Brown    Input Arguments:
227fe1899a2SJed Brown +  dm - shell DM
228fe1899a2SJed Brown -  X - template vector
229fe1899a2SJed Brown 
230fe1899a2SJed Brown    Level: advanced
231fe1899a2SJed Brown 
232fe1899a2SJed Brown .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector()
233fe1899a2SJed Brown @*/
234fe1899a2SJed Brown PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X)
235fe1899a2SJed Brown {
236fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
237fe1899a2SJed Brown   PetscErrorCode ierr;
2388c87107bSJed Brown   PetscBool      isshell;
239fe1899a2SJed Brown 
240fe1899a2SJed Brown   PetscFunctionBegin;
2418c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2428c87107bSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
243251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
2448c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
245fe1899a2SJed Brown   ierr           = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
246fe1899a2SJed Brown   ierr           = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
247fe1899a2SJed Brown   shell->Xglobal = X;
248fe1899a2SJed Brown   PetscFunctionReturn(0);
249fe1899a2SJed Brown }
250fe1899a2SJed Brown 
251fe1899a2SJed Brown #undef __FUNCT__
252fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateGlobalVector"
253fe1899a2SJed Brown /*@C
254fe1899a2SJed Brown    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
255fe1899a2SJed Brown 
256fe1899a2SJed Brown    Logically Collective
257fe1899a2SJed Brown 
258fe1899a2SJed Brown    Input Arguments:
259fe1899a2SJed Brown +  dm - the shell DM
260fe1899a2SJed Brown -  func - the creation routine
261fe1899a2SJed Brown 
262fe1899a2SJed Brown    Level: advanced
263fe1899a2SJed Brown 
264fe1899a2SJed Brown .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix()
265fe1899a2SJed Brown @*/
266fe1899a2SJed Brown PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
267fe1899a2SJed Brown {
268fe1899a2SJed Brown 
269fe1899a2SJed Brown   PetscFunctionBegin;
270fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
271fe1899a2SJed Brown   dm->ops->createglobalvector = func;
272fe1899a2SJed Brown   PetscFunctionReturn(0);
273fe1899a2SJed Brown }
274fe1899a2SJed Brown 
275fe1899a2SJed Brown #undef __FUNCT__
276dc43b69eSJed Brown #define __FUNCT__ "DMShellSetLocalVector"
277dc43b69eSJed Brown /*@
278dc43b69eSJed Brown    DMShellSetLocalVector - sets a template local vector associated with the DMShell
279dc43b69eSJed Brown 
280dc43b69eSJed Brown    Logically Collective on DM
281dc43b69eSJed Brown 
282dc43b69eSJed Brown    Input Arguments:
283dc43b69eSJed Brown +  dm - shell DM
284dc43b69eSJed Brown -  X - template vector
285dc43b69eSJed Brown 
286dc43b69eSJed Brown    Level: advanced
287dc43b69eSJed Brown 
288dc43b69eSJed Brown .seealso: DMCreateLocalVector(), DMShellSetMatrix(), DMShellSetCreateLocalVector()
289dc43b69eSJed Brown @*/
290dc43b69eSJed Brown PetscErrorCode DMShellSetLocalVector(DM dm,Vec X)
291dc43b69eSJed Brown {
292dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
293dc43b69eSJed Brown   PetscErrorCode ierr;
294dc43b69eSJed Brown   PetscBool      isshell;
295dc43b69eSJed Brown 
296dc43b69eSJed Brown   PetscFunctionBegin;
297dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
298dc43b69eSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
299dc43b69eSJed Brown   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
300dc43b69eSJed Brown   if (!isshell) PetscFunctionReturn(0);
301dc43b69eSJed Brown   ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
302dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
303dc43b69eSJed Brown   shell->Xlocal = X;
304dc43b69eSJed Brown   PetscFunctionReturn(0);
305dc43b69eSJed Brown }
306dc43b69eSJed Brown 
307dc43b69eSJed Brown #undef __FUNCT__
308dc43b69eSJed Brown #define __FUNCT__ "DMShellSetCreateLocalVector"
309dc43b69eSJed Brown /*@C
310dc43b69eSJed Brown    DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM
311dc43b69eSJed Brown 
312dc43b69eSJed Brown    Logically Collective
313dc43b69eSJed Brown 
314dc43b69eSJed Brown    Input Arguments:
315dc43b69eSJed Brown +  dm - the shell DM
316dc43b69eSJed Brown -  func - the creation routine
317dc43b69eSJed Brown 
318dc43b69eSJed Brown    Level: advanced
319dc43b69eSJed Brown 
320dc43b69eSJed Brown .seealso: DMShellSetLocalVector(), DMShellSetCreateMatrix()
321dc43b69eSJed Brown @*/
322dc43b69eSJed Brown PetscErrorCode DMShellSetCreateLocalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
323dc43b69eSJed Brown {
324dc43b69eSJed Brown 
325dc43b69eSJed Brown   PetscFunctionBegin;
326dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
327dc43b69eSJed Brown   dm->ops->createlocalvector = func;
328dc43b69eSJed Brown   PetscFunctionReturn(0);
329dc43b69eSJed Brown }
330dc43b69eSJed Brown 
331dc43b69eSJed Brown #undef __FUNCT__
3328339e6d0SRichard Tran Mills #define __FUNCT__ "DMShellSetGlobalToLocal"
3338339e6d0SRichard Tran Mills /*@C
3348339e6d0SRichard Tran Mills    DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
3358339e6d0SRichard Tran Mills 
3368339e6d0SRichard Tran Mills    Logically Collective on DM
3378339e6d0SRichard Tran Mills 
3388339e6d0SRichard Tran Mills    Input Arguments
3398339e6d0SRichard Tran Mills +  dm - the shell DM
3408339e6d0SRichard Tran Mills .  begin - the routine that begins the global to local scatter
3418339e6d0SRichard Tran Mills -  end - the routine that ends the global to local scatter
3428339e6d0SRichard Tran Mills 
3438339e6d0SRichard Tran Mills    Level: advanced
3448339e6d0SRichard Tran Mills 
3458339e6d0SRichard Tran Mills .seealso: DMShellSetLocalToGlobal()
3468339e6d0SRichard Tran Mills @*/
3478339e6d0SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
3488339e6d0SRichard Tran Mills   PetscFunctionBegin;
3498339e6d0SRichard Tran Mills   dm->ops->globaltolocalbegin = begin;
3508339e6d0SRichard Tran Mills   dm->ops->globaltolocalend = end;
3518339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
3528339e6d0SRichard Tran Mills }
3538339e6d0SRichard Tran Mills 
3548339e6d0SRichard Tran Mills #undef __FUNCT__
3558339e6d0SRichard Tran Mills #define __FUNCT__ "DMShellSetLocalToGlobal"
3568339e6d0SRichard Tran Mills /*@C
3578339e6d0SRichard Tran Mills    DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
3588339e6d0SRichard Tran Mills 
3598339e6d0SRichard Tran Mills    Logically Collective on DM
3608339e6d0SRichard Tran Mills 
3618339e6d0SRichard Tran Mills    Input Arguments
3628339e6d0SRichard Tran Mills +  dm - the shell DM
3638339e6d0SRichard Tran Mills .  begin - the routine that begins the local to global scatter
3648339e6d0SRichard Tran Mills -  end - the routine that ends the local to global scatter
3658339e6d0SRichard Tran Mills 
3668339e6d0SRichard Tran Mills    Level: advanced
3678339e6d0SRichard Tran Mills 
3688339e6d0SRichard Tran Mills .seealso: DMShellSetGlobalToLocal()
3698339e6d0SRichard Tran Mills @*/
3708339e6d0SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
3718339e6d0SRichard Tran Mills   PetscFunctionBegin;
3728339e6d0SRichard Tran Mills   dm->ops->localtoglobalbegin = begin;
3738339e6d0SRichard Tran Mills   dm->ops->localtoglobalend = end;
3748339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
3758339e6d0SRichard Tran Mills }
3768339e6d0SRichard Tran Mills 
3778339e6d0SRichard Tran Mills #undef __FUNCT__
37881634712SRichard Tran Mills #define __FUNCT__ "DMShellSetGlobalToLocalVecScatter"
37981634712SRichard Tran Mills /*@
38081634712SRichard Tran Mills    DMShellSetGlobalToLocalVecScatter - Sets a VecScatter context for global to local communication
38181634712SRichard Tran Mills 
38281634712SRichard Tran Mills    Logically Collective on DM
38381634712SRichard Tran Mills 
38481634712SRichard Tran Mills    Input Arguments
38581634712SRichard Tran Mills +  dm - the shell DM
38681634712SRichard Tran Mills -  gtol - the global to local VecScatter context
38781634712SRichard Tran Mills 
38881634712SRichard Tran Mills    Level: advanced
38981634712SRichard Tran Mills 
39081634712SRichard Tran Mills .seealso: DMShellSetGlobalToLocal()
39181634712SRichard Tran Mills @*/
39281634712SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter *gtol)
39381634712SRichard Tran Mills {
39481634712SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
39581634712SRichard Tran Mills 
396b300e4a8SRichard Tran Mills   PetscFunctionBegin;
39781634712SRichard Tran Mills   shell->gtol = gtol;
39881634712SRichard Tran Mills   PetscFunctionReturn(0);
39981634712SRichard Tran Mills }
40081634712SRichard Tran Mills 
40181634712SRichard Tran Mills #undef __FUNCT__
402fe1899a2SJed Brown #define __FUNCT__ "DMDestroy_Shell"
403fe1899a2SJed Brown static PetscErrorCode DMDestroy_Shell(DM dm)
404fe1899a2SJed Brown {
405fe1899a2SJed Brown   PetscErrorCode ierr;
406fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
407fe1899a2SJed Brown 
408fe1899a2SJed Brown   PetscFunctionBegin;
409fe1899a2SJed Brown   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
410fe1899a2SJed Brown   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
411dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
4127b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
4137b6ad80cSMatthew G Knepley   ierr = PetscFree(shell);CHKERRQ(ierr);
414fe1899a2SJed Brown   PetscFunctionReturn(0);
415fe1899a2SJed Brown }
416fe1899a2SJed Brown 
4172d53ad75SBarry Smith #undef __FUNCT__
4182d53ad75SBarry Smith #define __FUNCT__ "DMView_Shell"
4192d53ad75SBarry Smith static PetscErrorCode DMView_Shell(DM dm,PetscViewer v)
4202d53ad75SBarry Smith {
4212d53ad75SBarry Smith   PetscErrorCode ierr;
4222d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
4232d53ad75SBarry Smith 
4242d53ad75SBarry Smith   PetscFunctionBegin;
4252d53ad75SBarry Smith   ierr = VecView(shell->Xglobal,v);CHKERRQ(ierr);
4262d53ad75SBarry Smith   PetscFunctionReturn(0);
4272d53ad75SBarry Smith }
4282d53ad75SBarry Smith 
4292d53ad75SBarry Smith #undef __FUNCT__
4302d53ad75SBarry Smith #define __FUNCT__ "DMLoad_Shell"
4312d53ad75SBarry Smith static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v)
4322d53ad75SBarry Smith {
4332d53ad75SBarry Smith   PetscErrorCode ierr;
4342d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
4352d53ad75SBarry Smith 
4362d53ad75SBarry Smith   PetscFunctionBegin;
437ce94432eSBarry Smith   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&shell->Xglobal);CHKERRQ(ierr);
4382d53ad75SBarry Smith   ierr = VecLoad(shell->Xglobal,v);CHKERRQ(ierr);
4392d53ad75SBarry Smith   PetscFunctionReturn(0);
4402d53ad75SBarry Smith }
441fe1899a2SJed Brown 
442fe1899a2SJed Brown #undef __FUNCT__
443fe1899a2SJed Brown #define __FUNCT__ "DMCreate_Shell"
4448cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm)
445fe1899a2SJed Brown {
446fe1899a2SJed Brown   PetscErrorCode ierr;
447fe1899a2SJed Brown   DM_Shell       *shell;
448fe1899a2SJed Brown 
449fe1899a2SJed Brown   PetscFunctionBegin;
4508c87107bSJed Brown   ierr     = PetscNewLog(dm,DM_Shell,&shell);CHKERRQ(ierr);
4518c87107bSJed Brown   dm->data = shell;
452fe1899a2SJed Brown 
4538c87107bSJed Brown   ierr = PetscObjectChangeTypeName((PetscObject)dm,DMSHELL);CHKERRQ(ierr);
4548865f1eaSKarl Rupp 
4558c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
4568c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
457dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
4588c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
4592d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
4602d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
461fe1899a2SJed Brown   PetscFunctionReturn(0);
462fe1899a2SJed Brown }
463fe1899a2SJed Brown 
464fe1899a2SJed Brown #undef __FUNCT__
465fe1899a2SJed Brown #define __FUNCT__ "DMShellCreate"
466fe1899a2SJed Brown /*@
467fe1899a2SJed Brown     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
468fe1899a2SJed Brown 
469fe1899a2SJed Brown     Collective on MPI_Comm
470fe1899a2SJed Brown 
471fe1899a2SJed Brown     Input Parameter:
472fe1899a2SJed Brown .   comm - the processors that will share the global vector
473fe1899a2SJed Brown 
474fe1899a2SJed Brown     Output Parameters:
475fe1899a2SJed Brown .   shell - the shell DM
476fe1899a2SJed Brown 
477fe1899a2SJed Brown     Level: advanced
478fe1899a2SJed Brown 
479dc43b69eSJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateLocalVector()
480fe1899a2SJed Brown @*/
481fe1899a2SJed Brown PetscErrorCode  DMShellCreate(MPI_Comm comm,DM *dm)
482fe1899a2SJed Brown {
483fe1899a2SJed Brown   PetscErrorCode ierr;
484fe1899a2SJed Brown 
485fe1899a2SJed Brown   PetscFunctionBegin;
486fe1899a2SJed Brown   PetscValidPointer(dm,2);
487fe1899a2SJed Brown   ierr = DMCreate(comm,dm);CHKERRQ(ierr);
488fe1899a2SJed Brown   ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr);
489fe1899a2SJed Brown   PetscFunctionReturn(0);
490fe1899a2SJed Brown }
49181634712SRichard Tran Mills 
492