xref: /petsc/src/dm/impls/shell/dmshell.c (revision ea78f98c112368f404cd6d4fff6d4dfe73e5a1e7)
1fe1899a2SJed Brown #include <petscdmshell.h>       /*I    "petscdmshell.h"  I*/
207475bc1SBarry Smith #include <petscmat.h>
3af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
4fe1899a2SJed Brown 
5fe1899a2SJed Brown typedef struct  {
6fe1899a2SJed Brown   Vec        Xglobal;
7dc43b69eSJed Brown   Vec        Xlocal;
8fe1899a2SJed Brown   Mat        A;
9a94b16f6SRichard Tran Mills   VecScatter gtol;
10a94b16f6SRichard Tran Mills   VecScatter ltog;
11f089877aSRichard Tran Mills   VecScatter ltol;
12fef3a512SBarry Smith   void       *ctx;
13fe1899a2SJed Brown } DM_Shell;
14fe1899a2SJed Brown 
157a108d1dSBarry Smith /*@
167a108d1dSBarry Smith    DMGlobalToLocalBeginDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to begin a global to local scatter
178d359177SBarry Smith    Collective
188d359177SBarry Smith 
198d359177SBarry Smith    Input Arguments:
208d359177SBarry Smith +  dm - shell DM
218d359177SBarry Smith .  g - global vector
228d359177SBarry Smith .  mode - InsertMode
238d359177SBarry Smith -  l - local vector
248d359177SBarry Smith 
257a108d1dSBarry Smith    Level: advanced
268d359177SBarry Smith 
277a108d1dSBarry Smith    Note:  This is not normally called directly by user code, generally user code calls DMGlobalToLocalBegin() and DMGlobalToLocalEnd(). If the user provides their own custom routines to DMShellSetLocalToGlobal() then those routines might have reason to call this function.
287a108d1dSBarry Smith 
297a108d1dSBarry Smith .seealso: DMGlobalToLocalEndDefaultShell()
308d359177SBarry Smith @*/
317a108d1dSBarry Smith PetscErrorCode DMGlobalToLocalBeginDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
328d359177SBarry Smith {
338d359177SBarry Smith   PetscErrorCode ierr;
348d359177SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
358d359177SBarry Smith 
368d359177SBarry Smith   PetscFunctionBegin;
377a108d1dSBarry Smith   if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
38a94b16f6SRichard Tran Mills   ierr = VecScatterBegin(shell->gtol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
398d359177SBarry Smith   PetscFunctionReturn(0);
408d359177SBarry Smith }
418d359177SBarry Smith 
427a108d1dSBarry Smith /*@
437a108d1dSBarry Smith    DMGlobalToLocalEndDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to end a global to local scatter
448d359177SBarry Smith    Collective
458d359177SBarry Smith 
468d359177SBarry Smith    Input Arguments:
478d359177SBarry Smith +  dm - shell DM
488d359177SBarry Smith .  g - global vector
498d359177SBarry Smith .  mode - InsertMode
508d359177SBarry Smith -  l - local vector
518d359177SBarry Smith 
527a108d1dSBarry Smith    Level: advanced
538d359177SBarry Smith 
547a108d1dSBarry Smith .seealso: DMGlobalToLocalBeginDefaultShell()
558d359177SBarry Smith @*/
567a108d1dSBarry Smith PetscErrorCode DMGlobalToLocalEndDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
578d359177SBarry Smith {
588d359177SBarry Smith   PetscErrorCode ierr;
598d359177SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
608d359177SBarry Smith 
618d359177SBarry Smith   PetscFunctionBegin;
627a108d1dSBarry Smith    if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
63a94b16f6SRichard Tran Mills   ierr = VecScatterEnd(shell->gtol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
648d359177SBarry Smith   PetscFunctionReturn(0);
658d359177SBarry Smith }
668d359177SBarry Smith 
67c5076b69SRichard Tran Mills /*@
68c5076b69SRichard Tran Mills    DMLocalToGlobalBeginDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to begin a local to global scatter
69c5076b69SRichard Tran Mills    Collective
70c5076b69SRichard Tran Mills 
71c5076b69SRichard Tran Mills    Input Arguments:
72c5076b69SRichard Tran Mills +  dm - shell DM
73c5076b69SRichard Tran Mills .  l - local vector
74c5076b69SRichard Tran Mills .  mode - InsertMode
75c5076b69SRichard Tran Mills -  g - global vector
76c5076b69SRichard Tran Mills 
77c5076b69SRichard Tran Mills    Level: advanced
78c5076b69SRichard Tran Mills 
79c5076b69SRichard Tran Mills    Note:  This is not normally called directly by user code, generally user code calls DMLocalToGlobalBegin() and DMLocalToGlobalEnd(). If the user provides their own custom routines to DMShellSetLocalToGlobal() then those routines might have reason to call this function.
80c5076b69SRichard Tran Mills 
81c5076b69SRichard Tran Mills .seealso: DMLocalToGlobalEndDefaultShell()
82c5076b69SRichard Tran Mills @*/
83c5076b69SRichard Tran Mills PetscErrorCode DMLocalToGlobalBeginDefaultShell(DM dm,Vec l,InsertMode mode,Vec g)
84c5076b69SRichard Tran Mills {
85c5076b69SRichard Tran Mills   PetscErrorCode ierr;
86c5076b69SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
87c5076b69SRichard Tran Mills 
88c5076b69SRichard Tran Mills   PetscFunctionBegin;
89c5076b69SRichard Tran Mills   if (!shell->ltog) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
90a94b16f6SRichard Tran Mills   ierr = VecScatterBegin(shell->ltog,l,g,mode,SCATTER_FORWARD);CHKERRQ(ierr);
91c5076b69SRichard Tran Mills   PetscFunctionReturn(0);
92c5076b69SRichard Tran Mills }
93c5076b69SRichard Tran Mills 
94c5076b69SRichard Tran Mills /*@
95c5076b69SRichard Tran Mills    DMLocalToGlobalEndDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to end a local to global scatter
96c5076b69SRichard Tran Mills    Collective
97c5076b69SRichard Tran Mills 
98c5076b69SRichard Tran Mills    Input Arguments:
99c5076b69SRichard Tran Mills +  dm - shell DM
100c5076b69SRichard Tran Mills .  l - local vector
101c5076b69SRichard Tran Mills .  mode - InsertMode
102c5076b69SRichard Tran Mills -  g - global vector
103c5076b69SRichard Tran Mills 
104c5076b69SRichard Tran Mills    Level: advanced
105c5076b69SRichard Tran Mills 
106c5076b69SRichard Tran Mills .seealso: DMLocalToGlobalBeginDefaultShell()
107c5076b69SRichard Tran Mills @*/
108c5076b69SRichard Tran Mills PetscErrorCode DMLocalToGlobalEndDefaultShell(DM dm,Vec l,InsertMode mode,Vec g)
109c5076b69SRichard Tran Mills {
110c5076b69SRichard Tran Mills   PetscErrorCode ierr;
111c5076b69SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
112c5076b69SRichard Tran Mills 
113c5076b69SRichard Tran Mills   PetscFunctionBegin;
114c5076b69SRichard Tran Mills    if (!shell->ltog) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
115a94b16f6SRichard Tran Mills   ierr = VecScatterEnd(shell->ltog,l,g,mode,SCATTER_FORWARD);CHKERRQ(ierr);
116c5076b69SRichard Tran Mills   PetscFunctionReturn(0);
117c5076b69SRichard Tran Mills }
118c5076b69SRichard Tran Mills 
119f3db62a7SRichard Tran Mills /*@
120f3db62a7SRichard Tran Mills    DMLocalToLocalBeginDefaultShell - Uses the LocalToLocal VecScatter context set by the user to begin a local to local scatter
121f3db62a7SRichard Tran Mills    Collective
122f3db62a7SRichard Tran Mills 
123f3db62a7SRichard Tran Mills    Input Arguments:
124f3db62a7SRichard Tran Mills +  dm - shell DM
125f3db62a7SRichard Tran Mills .  g - the original local vector
126f3db62a7SRichard Tran Mills -  mode - InsertMode
127f3db62a7SRichard Tran Mills 
128f3db62a7SRichard Tran Mills    Output Parameter:
129f3db62a7SRichard Tran Mills .  l  - the local vector with correct ghost values
130f3db62a7SRichard Tran Mills 
131f3db62a7SRichard Tran Mills    Level: advanced
132f3db62a7SRichard Tran Mills 
133f3db62a7SRichard Tran Mills    Note:  This is not normally called directly by user code, generally user code calls DMLocalToLocalBegin() and DMLocalToLocalEnd(). If the user provides their own custom routines to DMShellSetLocalToLocal() then those routines might have reason to call this function.
134f3db62a7SRichard Tran Mills 
135f3db62a7SRichard Tran Mills .seealso: DMLocalToLocalEndDefaultShell()
136f3db62a7SRichard Tran Mills @*/
137f3db62a7SRichard Tran Mills PetscErrorCode DMLocalToLocalBeginDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
138f3db62a7SRichard Tran Mills {
139f3db62a7SRichard Tran Mills   PetscErrorCode ierr;
140f3db62a7SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
141f3db62a7SRichard Tran Mills 
142f3db62a7SRichard Tran Mills   PetscFunctionBegin;
143f3db62a7SRichard Tran Mills   if (!shell->ltol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToLocalVecScatter()");
144f3db62a7SRichard Tran Mills   ierr = VecScatterBegin(shell->ltol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
145f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
146f3db62a7SRichard Tran Mills }
147f3db62a7SRichard Tran Mills 
148f3db62a7SRichard Tran Mills /*@
149f3db62a7SRichard Tran Mills    DMLocalToLocalEndDefaultShell - Uses the LocalToLocal VecScatter context set by the user to end a local to local scatter
150f3db62a7SRichard Tran Mills    Collective
151f3db62a7SRichard Tran Mills 
152f3db62a7SRichard Tran Mills    Input Arguments:
153f3db62a7SRichard Tran Mills +  dm - shell DM
154f3db62a7SRichard Tran Mills .  g - the original local vector
155f3db62a7SRichard Tran Mills -  mode - InsertMode
156f3db62a7SRichard Tran Mills 
157f3db62a7SRichard Tran Mills    Output Parameter:
158f3db62a7SRichard Tran Mills .  l  - the local vector with correct ghost values
159f3db62a7SRichard Tran Mills 
160f3db62a7SRichard Tran Mills    Level: advanced
161f3db62a7SRichard Tran Mills 
162f3db62a7SRichard Tran Mills .seealso: DMLocalToLocalBeginDefaultShell()
163f3db62a7SRichard Tran Mills @*/
164f3db62a7SRichard Tran Mills PetscErrorCode DMLocalToLocalEndDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
165f3db62a7SRichard Tran Mills {
166f3db62a7SRichard Tran Mills   PetscErrorCode ierr;
167f3db62a7SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
168f3db62a7SRichard Tran Mills 
169f3db62a7SRichard Tran Mills   PetscFunctionBegin;
170f3db62a7SRichard Tran Mills    if (!shell->ltol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
171f3db62a7SRichard Tran Mills   ierr = VecScatterEnd(shell->ltol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
172f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
173f3db62a7SRichard Tran Mills }
174c5076b69SRichard Tran Mills 
175b412c318SBarry Smith static PetscErrorCode DMCreateMatrix_Shell(DM dm,Mat *J)
176fe1899a2SJed Brown {
177fe1899a2SJed Brown   PetscErrorCode ierr;
178fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
179fe1899a2SJed Brown   Mat            A;
180fe1899a2SJed Brown 
181fe1899a2SJed Brown   PetscFunctionBegin;
182fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
183fe1899a2SJed Brown   PetscValidPointer(J,3);
1847bde9f88SJed Brown   if (!shell->A) {
1857bde9f88SJed Brown     if (shell->Xglobal) {
1867bde9f88SJed Brown       PetscInt m,M;
187955c1f14SBarry Smith       ierr = PetscInfo(dm,"Naively creating matrix using global vector distribution without preallocation\n");CHKERRQ(ierr);
1887bde9f88SJed Brown       ierr = VecGetSize(shell->Xglobal,&M);CHKERRQ(ierr);
1897bde9f88SJed Brown       ierr = VecGetLocalSize(shell->Xglobal,&m);CHKERRQ(ierr);
190ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)dm),&shell->A);CHKERRQ(ierr);
1917bde9f88SJed Brown       ierr = MatSetSizes(shell->A,m,m,M,M);CHKERRQ(ierr);
192b412c318SBarry Smith       ierr = MatSetType(shell->A,dm->mattype);CHKERRQ(ierr);
1937bde9f88SJed Brown       ierr = MatSetUp(shell->A);CHKERRQ(ierr);
194ce94432eSBarry Smith     } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector");
1957bde9f88SJed Brown   }
196fe1899a2SJed Brown   A = shell->A;
197ad6bc421SBarry Smith   /* the check below is tacky and incomplete */
198b412c318SBarry Smith   if (dm->mattype) {
199ad6bc421SBarry Smith     PetscBool flg,aij,seqaij,mpiaij;
200b412c318SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,dm->mattype,&flg);CHKERRQ(ierr);
201ad6bc421SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
202ad6bc421SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&mpiaij);CHKERRQ(ierr);
203b412c318SBarry Smith     ierr = PetscStrcmp(dm->mattype,MATAIJ,&aij);CHKERRQ(ierr);
204ad6bc421SBarry Smith     if (!flg) {
205b412c318SBarry Smith       if (!(aij && (seqaij || mpiaij))) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_NOTSAMETYPE,"Requested matrix of type %s, but only %s available",dm->mattype,((PetscObject)A)->type_name);
206ad6bc421SBarry Smith     }
207fe1899a2SJed Brown   }
20806f803f6SStefano Zampini   /* Need to create a copy in order to attach the DM to the matrix */
20906f803f6SStefano Zampini   ierr = MatDuplicate(A,MAT_SHARE_NONZERO_PATTERN,J);CHKERRQ(ierr);
21006f803f6SStefano Zampini   ierr = MatSetDM(*J,dm);CHKERRQ(ierr);
211fe1899a2SJed Brown   PetscFunctionReturn(0);
212fe1899a2SJed Brown }
213fe1899a2SJed Brown 
214fe1899a2SJed Brown PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec)
215fe1899a2SJed Brown {
216fe1899a2SJed Brown   PetscErrorCode ierr;
217fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
218fe1899a2SJed Brown   Vec            X;
219fe1899a2SJed Brown 
220fe1899a2SJed Brown   PetscFunctionBegin;
221fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
222fe1899a2SJed Brown   PetscValidPointer(gvec,2);
223*ea78f98cSLisandro Dalcin   *gvec = NULL;
224fe1899a2SJed Brown   X     = shell->Xglobal;
225ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
22606f803f6SStefano Zampini   /* Need to create a copy in order to attach the DM to the vector */
227fe1899a2SJed Brown   ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
228fe1899a2SJed Brown   ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
229c688c046SMatthew G Knepley   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
230fe1899a2SJed Brown   PetscFunctionReturn(0);
231fe1899a2SJed Brown }
232fe1899a2SJed Brown 
233dc43b69eSJed Brown PetscErrorCode DMCreateLocalVector_Shell(DM dm,Vec *gvec)
234dc43b69eSJed Brown {
235dc43b69eSJed Brown   PetscErrorCode ierr;
236dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
237dc43b69eSJed Brown   Vec            X;
238dc43b69eSJed Brown 
239dc43b69eSJed Brown   PetscFunctionBegin;
240dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
241dc43b69eSJed Brown   PetscValidPointer(gvec,2);
242*ea78f98cSLisandro Dalcin   *gvec = NULL;
243dc43b69eSJed Brown   X     = shell->Xlocal;
244ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()");
24506f803f6SStefano Zampini   /* Need to create a copy in order to attach the DM to the vector */
246dc43b69eSJed Brown   ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
247dc43b69eSJed Brown   ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
2486e4cbd8bSMark F. Adams   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
249dc43b69eSJed Brown   PetscFunctionReturn(0);
250dc43b69eSJed Brown }
251dc43b69eSJed Brown 
252fef3a512SBarry Smith /*@
253fef3a512SBarry Smith    DMShellSetContext - set some data to be usable by this DM
254fef3a512SBarry Smith 
255fef3a512SBarry Smith    Collective
256fef3a512SBarry Smith 
257fef3a512SBarry Smith    Input Arguments:
258fef3a512SBarry Smith +  dm - shell DM
259fef3a512SBarry Smith -  ctx - the context
260fef3a512SBarry Smith 
261fef3a512SBarry Smith    Level: advanced
262fef3a512SBarry Smith 
263fef3a512SBarry Smith .seealso: DMCreateMatrix(), DMShellGetContext()
264fef3a512SBarry Smith @*/
265fef3a512SBarry Smith PetscErrorCode DMShellSetContext(DM dm,void *ctx)
266fef3a512SBarry Smith {
267fef3a512SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
268fef3a512SBarry Smith   PetscErrorCode ierr;
269fef3a512SBarry Smith   PetscBool      isshell;
270fef3a512SBarry Smith 
271fef3a512SBarry Smith   PetscFunctionBegin;
272fef3a512SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
273fef3a512SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
274fef3a512SBarry Smith   if (!isshell) PetscFunctionReturn(0);
275fef3a512SBarry Smith   shell->ctx = ctx;
276fef3a512SBarry Smith   PetscFunctionReturn(0);
277fef3a512SBarry Smith }
278fef3a512SBarry Smith 
279fef3a512SBarry Smith /*@
280bf890c61SBoris Boutkov    DMShellGetContext - Returns the user-provided context associated to the DM
281fef3a512SBarry Smith 
282fef3a512SBarry Smith    Collective
283fef3a512SBarry Smith 
284fef3a512SBarry Smith    Input Argument:
285fef3a512SBarry Smith .  dm - shell DM
286fef3a512SBarry Smith 
287fef3a512SBarry Smith    Output Argument:
288fef3a512SBarry Smith .  ctx - the context
289fef3a512SBarry Smith 
290fef3a512SBarry Smith    Level: advanced
291fef3a512SBarry Smith 
292fef3a512SBarry Smith .seealso: DMCreateMatrix(), DMShellSetContext()
293fef3a512SBarry Smith @*/
294fef3a512SBarry Smith PetscErrorCode DMShellGetContext(DM dm,void **ctx)
295fef3a512SBarry Smith {
296fef3a512SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
297fef3a512SBarry Smith   PetscErrorCode ierr;
298fef3a512SBarry Smith   PetscBool      isshell;
299fef3a512SBarry Smith 
300fef3a512SBarry Smith   PetscFunctionBegin;
301fef3a512SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
302fef3a512SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
3038dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
304fef3a512SBarry Smith   *ctx = shell->ctx;
305fef3a512SBarry Smith   PetscFunctionReturn(0);
306fef3a512SBarry Smith }
307fef3a512SBarry Smith 
308fe1899a2SJed Brown /*@
309fe1899a2SJed Brown    DMShellSetMatrix - sets a template matrix associated with the DMShell
310fe1899a2SJed Brown 
311fe1899a2SJed Brown    Collective
312fe1899a2SJed Brown 
313fe1899a2SJed Brown    Input Arguments:
314fe1899a2SJed Brown +  dm - shell DM
315fe1899a2SJed Brown -  J - template matrix
316fe1899a2SJed Brown 
317fe1899a2SJed Brown    Level: advanced
318fe1899a2SJed Brown 
31906f803f6SStefano Zampini    Developer Notes:
32006f803f6SStefano Zampini     To avoid circular references, if J is already associated to the same DM, then MatDuplicate(SHARE_NONZERO_PATTERN) is called, followed by removing the DM reference from the private template.
32106f803f6SStefano Zampini 
322fef3a512SBarry Smith .seealso: DMCreateMatrix(), DMShellSetCreateMatrix(), DMShellSetContext(), DMShellGetContext()
323fe1899a2SJed Brown @*/
324fe1899a2SJed Brown PetscErrorCode DMShellSetMatrix(DM dm,Mat J)
325fe1899a2SJed Brown {
326fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
327fe1899a2SJed Brown   PetscErrorCode ierr;
3288c87107bSJed Brown   PetscBool      isshell;
32906f803f6SStefano Zampini   DM             mdm;
330fe1899a2SJed Brown 
331fe1899a2SJed Brown   PetscFunctionBegin;
3328c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3338c87107bSJed Brown   PetscValidHeaderSpecific(J,MAT_CLASSID,2);
334251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
3358c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
33606f803f6SStefano Zampini   if (J == shell->A) PetscFunctionReturn(0);
33706f803f6SStefano Zampini   ierr = MatGetDM(J,&mdm);CHKERRQ(ierr);
338fe1899a2SJed Brown   ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
339fe1899a2SJed Brown   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
34006f803f6SStefano Zampini   if (mdm == dm) {
34106f803f6SStefano Zampini     ierr = MatDuplicate(J,MAT_SHARE_NONZERO_PATTERN,&shell->A);CHKERRQ(ierr);
34206f803f6SStefano Zampini     ierr = MatSetDM(shell->A,NULL);CHKERRQ(ierr);
34306f803f6SStefano Zampini   } else shell->A = J;
344fe1899a2SJed Brown   PetscFunctionReturn(0);
345fe1899a2SJed Brown }
346fe1899a2SJed Brown 
347fe1899a2SJed Brown /*@C
348fe1899a2SJed Brown    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM
349fe1899a2SJed Brown 
350d083f849SBarry Smith    Logically Collective on dm
351fe1899a2SJed Brown 
352fe1899a2SJed Brown    Input Arguments:
353fe1899a2SJed Brown +  dm - the shell DM
354fe1899a2SJed Brown -  func - the function to create a matrix
355fe1899a2SJed Brown 
356fe1899a2SJed Brown    Level: advanced
357fe1899a2SJed Brown 
358fef3a512SBarry Smith .seealso: DMCreateMatrix(), DMShellSetMatrix(), DMShellSetContext(), DMShellGetContext()
359fe1899a2SJed Brown @*/
360b412c318SBarry Smith PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,Mat*))
361fe1899a2SJed Brown {
362fe1899a2SJed Brown   PetscFunctionBegin;
363fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
364fe1899a2SJed Brown   dm->ops->creatematrix = func;
365fe1899a2SJed Brown   PetscFunctionReturn(0);
366fe1899a2SJed Brown }
367fe1899a2SJed Brown 
368fe1899a2SJed Brown /*@
369fe1899a2SJed Brown    DMShellSetGlobalVector - sets a template global vector associated with the DMShell
370fe1899a2SJed Brown 
371d083f849SBarry Smith    Logically Collective on dm
372fe1899a2SJed Brown 
373fe1899a2SJed Brown    Input Arguments:
374fe1899a2SJed Brown +  dm - shell DM
375fe1899a2SJed Brown -  X - template vector
376fe1899a2SJed Brown 
377fe1899a2SJed Brown    Level: advanced
378fe1899a2SJed Brown 
379fe1899a2SJed Brown .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector()
380fe1899a2SJed Brown @*/
381fe1899a2SJed Brown PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X)
382fe1899a2SJed Brown {
383fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
384fe1899a2SJed Brown   PetscErrorCode ierr;
3858c87107bSJed Brown   PetscBool      isshell;
386cca7ec1eSBarry Smith   DM             vdm;
387fe1899a2SJed Brown 
388fe1899a2SJed Brown   PetscFunctionBegin;
3898c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3908c87107bSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
391251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
3928c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
393cca7ec1eSBarry Smith   ierr = VecGetDM(X,&vdm);CHKERRQ(ierr);
394cca7ec1eSBarry Smith   /*
395cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
396cca7ec1eSBarry Smith       with the same DM then the current base global vector for the DM is ok and if we replace it with the new one
397cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
398cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
399cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
400cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
401cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
402cca7ec1eSBarry Smith       for pointing out the problem.
403cca7ec1eSBarry Smith    */
404cca7ec1eSBarry Smith   if (vdm == dm) PetscFunctionReturn(0);
405fe1899a2SJed Brown   ierr           = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
406fe1899a2SJed Brown   ierr           = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
407fe1899a2SJed Brown   shell->Xglobal = X;
408fe1899a2SJed Brown   PetscFunctionReturn(0);
409fe1899a2SJed Brown }
410fe1899a2SJed Brown 
411fe1899a2SJed Brown /*@C
412fe1899a2SJed Brown    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
413fe1899a2SJed Brown 
414fe1899a2SJed Brown    Logically Collective
415fe1899a2SJed Brown 
416fe1899a2SJed Brown    Input Arguments:
417fe1899a2SJed Brown +  dm - the shell DM
418fe1899a2SJed Brown -  func - the creation routine
419fe1899a2SJed Brown 
420fe1899a2SJed Brown    Level: advanced
421fe1899a2SJed Brown 
422fef3a512SBarry Smith .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix(), DMShellSetContext(), DMShellGetContext()
423fe1899a2SJed Brown @*/
424fe1899a2SJed Brown PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
425fe1899a2SJed Brown {
426fe1899a2SJed Brown   PetscFunctionBegin;
427fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
428fe1899a2SJed Brown   dm->ops->createglobalvector = func;
429fe1899a2SJed Brown   PetscFunctionReturn(0);
430fe1899a2SJed Brown }
431fe1899a2SJed Brown 
432dc43b69eSJed Brown /*@
433dc43b69eSJed Brown    DMShellSetLocalVector - sets a template local vector associated with the DMShell
434dc43b69eSJed Brown 
435d083f849SBarry Smith    Logically Collective on dm
436dc43b69eSJed Brown 
437dc43b69eSJed Brown    Input Arguments:
438dc43b69eSJed Brown +  dm - shell DM
439dc43b69eSJed Brown -  X - template vector
440dc43b69eSJed Brown 
441dc43b69eSJed Brown    Level: advanced
442dc43b69eSJed Brown 
443dc43b69eSJed Brown .seealso: DMCreateLocalVector(), DMShellSetMatrix(), DMShellSetCreateLocalVector()
444dc43b69eSJed Brown @*/
445dc43b69eSJed Brown PetscErrorCode DMShellSetLocalVector(DM dm,Vec X)
446dc43b69eSJed Brown {
447dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
448dc43b69eSJed Brown   PetscErrorCode ierr;
449dc43b69eSJed Brown   PetscBool      isshell;
450cca7ec1eSBarry Smith   DM             vdm;
451dc43b69eSJed Brown 
452dc43b69eSJed Brown   PetscFunctionBegin;
453dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
454dc43b69eSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
455dc43b69eSJed Brown   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
456dc43b69eSJed Brown   if (!isshell) PetscFunctionReturn(0);
457cca7ec1eSBarry Smith   ierr = VecGetDM(X,&vdm);CHKERRQ(ierr);
458cca7ec1eSBarry Smith   /*
459cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
460cca7ec1eSBarry Smith       with the same DM then the current base global vector for the DM is ok and if we replace it with the new one
461cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
462cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
463cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
464cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
465cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
466cca7ec1eSBarry Smith       for pointing out the problem.
467cca7ec1eSBarry Smith    */
468cca7ec1eSBarry Smith   if (vdm == dm) PetscFunctionReturn(0);
469dc43b69eSJed Brown   ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
470dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
471dc43b69eSJed Brown   shell->Xlocal = X;
472dc43b69eSJed Brown   PetscFunctionReturn(0);
473dc43b69eSJed Brown }
474dc43b69eSJed Brown 
475dc43b69eSJed Brown /*@C
476dc43b69eSJed Brown    DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM
477dc43b69eSJed Brown 
478dc43b69eSJed Brown    Logically Collective
479dc43b69eSJed Brown 
480dc43b69eSJed Brown    Input Arguments:
481dc43b69eSJed Brown +  dm - the shell DM
482dc43b69eSJed Brown -  func - the creation routine
483dc43b69eSJed Brown 
484dc43b69eSJed Brown    Level: advanced
485dc43b69eSJed Brown 
486fef3a512SBarry Smith .seealso: DMShellSetLocalVector(), DMShellSetCreateMatrix(), DMShellSetContext(), DMShellGetContext()
487dc43b69eSJed Brown @*/
488dc43b69eSJed Brown PetscErrorCode DMShellSetCreateLocalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
489dc43b69eSJed Brown {
490dc43b69eSJed Brown   PetscFunctionBegin;
491dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
492dc43b69eSJed Brown   dm->ops->createlocalvector = func;
493dc43b69eSJed Brown   PetscFunctionReturn(0);
494dc43b69eSJed Brown }
495dc43b69eSJed Brown 
4968339e6d0SRichard Tran Mills /*@C
4978339e6d0SRichard Tran Mills    DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
4988339e6d0SRichard Tran Mills 
499d083f849SBarry Smith    Logically Collective on dm
5008339e6d0SRichard Tran Mills 
5018339e6d0SRichard Tran Mills    Input Arguments
5028339e6d0SRichard Tran Mills +  dm - the shell DM
5038339e6d0SRichard Tran Mills .  begin - the routine that begins the global to local scatter
5048339e6d0SRichard Tran Mills -  end - the routine that ends the global to local scatter
5058339e6d0SRichard Tran Mills 
50695452b02SPatrick Sanan    Notes:
50795452b02SPatrick Sanan     If these functions are not provided but DMShellSetGlobalToLocalVecScatter() is called then
508f3db62a7SRichard Tran Mills    DMGlobalToLocalBeginDefaultShell()/DMGlobalToLocalEndDefaultShell() are used to to perform the transfers
5097a108d1dSBarry Smith 
5108339e6d0SRichard Tran Mills    Level: advanced
5118339e6d0SRichard Tran Mills 
5127a108d1dSBarry Smith .seealso: DMShellSetLocalToGlobal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell()
5138339e6d0SRichard Tran Mills @*/
5148339e6d0SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
5158339e6d0SRichard Tran Mills   PetscFunctionBegin;
5162d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5178339e6d0SRichard Tran Mills   dm->ops->globaltolocalbegin = begin;
5188339e6d0SRichard Tran Mills   dm->ops->globaltolocalend = end;
5198339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
5208339e6d0SRichard Tran Mills }
5218339e6d0SRichard Tran Mills 
5228339e6d0SRichard Tran Mills /*@C
5238339e6d0SRichard Tran Mills    DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
5248339e6d0SRichard Tran Mills 
525d083f849SBarry Smith    Logically Collective on dm
5268339e6d0SRichard Tran Mills 
5278339e6d0SRichard Tran Mills    Input Arguments
5288339e6d0SRichard Tran Mills +  dm - the shell DM
5298339e6d0SRichard Tran Mills .  begin - the routine that begins the local to global scatter
5308339e6d0SRichard Tran Mills -  end - the routine that ends the local to global scatter
5318339e6d0SRichard Tran Mills 
53295452b02SPatrick Sanan    Notes:
53395452b02SPatrick Sanan     If these functions are not provided but DMShellSetLocalToGlobalVecScatter() is called then
534f3db62a7SRichard Tran Mills    DMLocalToGlobalBeginDefaultShell()/DMLocalToGlobalEndDefaultShell() are used to to perform the transfers
535f3db62a7SRichard Tran Mills 
5368339e6d0SRichard Tran Mills    Level: advanced
5378339e6d0SRichard Tran Mills 
5388339e6d0SRichard Tran Mills .seealso: DMShellSetGlobalToLocal()
5398339e6d0SRichard Tran Mills @*/
5408339e6d0SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
5418339e6d0SRichard Tran Mills   PetscFunctionBegin;
5422d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5438339e6d0SRichard Tran Mills   dm->ops->localtoglobalbegin = begin;
5448339e6d0SRichard Tran Mills   dm->ops->localtoglobalend = end;
5458339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
5468339e6d0SRichard Tran Mills }
5478339e6d0SRichard Tran Mills 
548f3db62a7SRichard Tran Mills /*@C
549f3db62a7SRichard Tran Mills    DMShellSetLocalToLocal - Sets the routines used to perform a local to local scatter
550f3db62a7SRichard Tran Mills 
551d083f849SBarry Smith    Logically Collective on dm
552f3db62a7SRichard Tran Mills 
553f3db62a7SRichard Tran Mills    Input Arguments
554f3db62a7SRichard Tran Mills +  dm - the shell DM
555f3db62a7SRichard Tran Mills .  begin - the routine that begins the local to local scatter
556f3db62a7SRichard Tran Mills -  end - the routine that ends the local to local scatter
557f3db62a7SRichard Tran Mills 
55895452b02SPatrick Sanan    Notes:
55995452b02SPatrick Sanan     If these functions are not provided but DMShellSetLocalToLocalVecScatter() is called then
560f3db62a7SRichard Tran Mills    DMLocalToLocalBeginDefaultShell()/DMLocalToLocalEndDefaultShell() are used to to perform the transfers
561f3db62a7SRichard Tran Mills 
562f3db62a7SRichard Tran Mills    Level: advanced
563f3db62a7SRichard Tran Mills 
564f3db62a7SRichard Tran Mills .seealso: DMShellSetGlobalToLocal(), DMLocalToLocalBeginDefaultShell(), DMLocalToLocalEndDefaultShell()
565f3db62a7SRichard Tran Mills @*/
566f3db62a7SRichard Tran Mills PetscErrorCode DMShellSetLocalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
567f3db62a7SRichard Tran Mills   PetscFunctionBegin;
5682d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
569f3db62a7SRichard Tran Mills   dm->ops->localtolocalbegin = begin;
570f3db62a7SRichard Tran Mills   dm->ops->localtolocalend = end;
571f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
572f3db62a7SRichard Tran Mills }
573f3db62a7SRichard Tran Mills 
57481634712SRichard Tran Mills /*@
57581634712SRichard Tran Mills    DMShellSetGlobalToLocalVecScatter - Sets a VecScatter context for global to local communication
57681634712SRichard Tran Mills 
577d083f849SBarry Smith    Logically Collective on dm
57881634712SRichard Tran Mills 
57981634712SRichard Tran Mills    Input Arguments
58081634712SRichard Tran Mills +  dm - the shell DM
58181634712SRichard Tran Mills -  gtol - the global to local VecScatter context
58281634712SRichard Tran Mills 
58381634712SRichard Tran Mills    Level: advanced
58481634712SRichard Tran Mills 
585f3db62a7SRichard Tran Mills .seealso: DMShellSetGlobalToLocal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell()
58681634712SRichard Tran Mills @*/
587a94b16f6SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter gtol)
58881634712SRichard Tran Mills {
58981634712SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
590d885d199SRichard Tran Mills   PetscErrorCode ierr;
59181634712SRichard Tran Mills 
592b300e4a8SRichard Tran Mills   PetscFunctionBegin;
5932d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5942d1bcd87SStefano Zampini   PetscValidHeaderSpecific(gtol,VEC_SCATTER_CLASSID,2);
595d885d199SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)gtol);CHKERRQ(ierr);
596d885d199SRichard Tran Mills   ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr);
59781634712SRichard Tran Mills   shell->gtol = gtol;
59881634712SRichard Tran Mills   PetscFunctionReturn(0);
59981634712SRichard Tran Mills }
60081634712SRichard Tran Mills 
601988ea7d6SRichard Tran Mills /*@
602988ea7d6SRichard Tran Mills    DMShellSetLocalToGlobalVecScatter - Sets a VecScatter context for local to global communication
603988ea7d6SRichard Tran Mills 
604d083f849SBarry Smith    Logically Collective on dm
605988ea7d6SRichard Tran Mills 
606988ea7d6SRichard Tran Mills    Input Arguments
607988ea7d6SRichard Tran Mills +  dm - the shell DM
608988ea7d6SRichard Tran Mills -  ltog - the local to global VecScatter context
609988ea7d6SRichard Tran Mills 
610988ea7d6SRichard Tran Mills    Level: advanced
611988ea7d6SRichard Tran Mills 
612f3db62a7SRichard Tran Mills .seealso: DMShellSetLocalToGlobal(), DMLocalToGlobalBeginDefaultShell(), DMLocalToGlobalEndDefaultShell()
613988ea7d6SRichard Tran Mills @*/
614a94b16f6SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter ltog)
615988ea7d6SRichard Tran Mills {
616988ea7d6SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
617d885d199SRichard Tran Mills   PetscErrorCode ierr;
618988ea7d6SRichard Tran Mills 
619988ea7d6SRichard Tran Mills   PetscFunctionBegin;
6202d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6212d1bcd87SStefano Zampini   PetscValidHeaderSpecific(ltog,VEC_SCATTER_CLASSID,2);
622d885d199SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr);
623d885d199SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr);
624988ea7d6SRichard Tran Mills   shell->ltog = ltog;
625988ea7d6SRichard Tran Mills   PetscFunctionReturn(0);
626988ea7d6SRichard Tran Mills }
627988ea7d6SRichard Tran Mills 
628f3db62a7SRichard Tran Mills /*@
629f3db62a7SRichard Tran Mills    DMShellSetLocalToLocalVecScatter - Sets a VecScatter context for local to local communication
630f3db62a7SRichard Tran Mills 
631d083f849SBarry Smith    Logically Collective on dm
632f3db62a7SRichard Tran Mills 
633f3db62a7SRichard Tran Mills    Input Arguments
634f3db62a7SRichard Tran Mills +  dm - the shell DM
635f3db62a7SRichard Tran Mills -  ltol - the local to local VecScatter context
636f3db62a7SRichard Tran Mills 
637f3db62a7SRichard Tran Mills    Level: advanced
638f3db62a7SRichard Tran Mills 
639f3db62a7SRichard Tran Mills .seealso: DMShellSetLocalToLocal(), DMLocalToLocalBeginDefaultShell(), DMLocalToLocalEndDefaultShell()
640f3db62a7SRichard Tran Mills @*/
641f3db62a7SRichard Tran Mills PetscErrorCode DMShellSetLocalToLocalVecScatter(DM dm, VecScatter ltol)
642f3db62a7SRichard Tran Mills {
643f3db62a7SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
644f3db62a7SRichard Tran Mills   PetscErrorCode ierr;
645f3db62a7SRichard Tran Mills 
646f3db62a7SRichard Tran Mills   PetscFunctionBegin;
6472d1bcd87SStefano Zampini   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6482d1bcd87SStefano Zampini   PetscValidHeaderSpecific(ltol,VEC_SCATTER_CLASSID,2);
649f3db62a7SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)ltol);CHKERRQ(ierr);
650f3db62a7SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltol);CHKERRQ(ierr);
651f3db62a7SRichard Tran Mills   shell->ltol = ltol;
652f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
653f3db62a7SRichard Tran Mills }
654f3db62a7SRichard Tran Mills 
6559bf9660cSLawrence Mitchell /*@C
6569bf9660cSLawrence Mitchell    DMShellSetCoarsen - Set the routine used to coarsen the shell DM
6579bf9660cSLawrence Mitchell 
658d083f849SBarry Smith    Logically Collective on dm
6599bf9660cSLawrence Mitchell 
6609bf9660cSLawrence Mitchell    Input Arguments
6619bf9660cSLawrence Mitchell +  dm - the shell DM
6629bf9660cSLawrence Mitchell -  coarsen - the routine that coarsens the DM
6639bf9660cSLawrence Mitchell 
6649bf9660cSLawrence Mitchell    Level: advanced
6659bf9660cSLawrence Mitchell 
666bf890c61SBoris Boutkov .seealso: DMShellSetRefine(), DMCoarsen(), DMShellGetCoarsen(), DMShellSetContext(), DMShellGetContext()
6679bf9660cSLawrence Mitchell @*/
668f572501eSLawrence Mitchell PetscErrorCode DMShellSetCoarsen(DM dm, PetscErrorCode (*coarsen)(DM,MPI_Comm,DM*))
669f572501eSLawrence Mitchell {
670f572501eSLawrence Mitchell   PetscErrorCode ierr;
671f572501eSLawrence Mitchell   PetscBool      isshell;
672f572501eSLawrence Mitchell 
673f572501eSLawrence Mitchell   PetscFunctionBegin;
674f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
675f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
676f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
677f572501eSLawrence Mitchell   dm->ops->coarsen = coarsen;
678f572501eSLawrence Mitchell   PetscFunctionReturn(0);
679f572501eSLawrence Mitchell }
680f572501eSLawrence Mitchell 
6819bf9660cSLawrence Mitchell /*@C
6824363ddcaSBoris Boutkov    DMShellGetCoarsen - Get the routine used to coarsen the shell DM
6834363ddcaSBoris Boutkov 
684d083f849SBarry Smith    Logically Collective on dm
6854363ddcaSBoris Boutkov 
686a4a986ddSBoris Boutkov    Input Argument:
6874363ddcaSBoris Boutkov .  dm - the shell DM
6884363ddcaSBoris Boutkov 
689a4a986ddSBoris Boutkov    Output Argument:
6904363ddcaSBoris Boutkov .  coarsen - the routine that coarsens the DM
6914363ddcaSBoris Boutkov 
6924363ddcaSBoris Boutkov    Level: advanced
6934363ddcaSBoris Boutkov 
6944363ddcaSBoris Boutkov .seealso: DMShellSetCoarsen(), DMCoarsen(), DMShellSetRefine(), DMRefine()
6954363ddcaSBoris Boutkov @*/
6964363ddcaSBoris Boutkov PetscErrorCode DMShellGetCoarsen(DM dm, PetscErrorCode (**coarsen)(DM,MPI_Comm,DM*))
6974363ddcaSBoris Boutkov {
6984363ddcaSBoris Boutkov   PetscErrorCode ierr;
6994363ddcaSBoris Boutkov   PetscBool      isshell;
7004363ddcaSBoris Boutkov 
7014363ddcaSBoris Boutkov   PetscFunctionBegin;
7024363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7034363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
7048dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
7054363ddcaSBoris Boutkov   *coarsen = dm->ops->coarsen;
7064363ddcaSBoris Boutkov   PetscFunctionReturn(0);
7074363ddcaSBoris Boutkov }
7084363ddcaSBoris Boutkov 
7094363ddcaSBoris Boutkov /*@C
7109bf9660cSLawrence Mitchell    DMShellSetRefine - Set the routine used to refine the shell DM
7119bf9660cSLawrence Mitchell 
712d083f849SBarry Smith    Logically Collective on dm
7139bf9660cSLawrence Mitchell 
7149bf9660cSLawrence Mitchell    Input Arguments
7159bf9660cSLawrence Mitchell +  dm - the shell DM
7169bf9660cSLawrence Mitchell -  refine - the routine that refines the DM
7179bf9660cSLawrence Mitchell 
7189bf9660cSLawrence Mitchell    Level: advanced
7199bf9660cSLawrence Mitchell 
720bf890c61SBoris Boutkov .seealso: DMShellSetCoarsen(), DMRefine(), DMShellGetRefine(), DMShellSetContext(), DMShellGetContext()
7219bf9660cSLawrence Mitchell @*/
722f572501eSLawrence Mitchell PetscErrorCode DMShellSetRefine(DM dm, PetscErrorCode (*refine)(DM,MPI_Comm,DM*))
723f572501eSLawrence Mitchell {
724f572501eSLawrence Mitchell   PetscErrorCode ierr;
725f572501eSLawrence Mitchell   PetscBool      isshell;
726f572501eSLawrence Mitchell 
727f572501eSLawrence Mitchell   PetscFunctionBegin;
728f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
729f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
730f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
731f572501eSLawrence Mitchell   dm->ops->refine = refine;
732f572501eSLawrence Mitchell   PetscFunctionReturn(0);
733f572501eSLawrence Mitchell }
734f572501eSLawrence Mitchell 
7359bf9660cSLawrence Mitchell /*@C
7364363ddcaSBoris Boutkov    DMShellGetRefine - Get the routine used to refine the shell DM
7374363ddcaSBoris Boutkov 
738d083f849SBarry Smith    Logically Collective on dm
7394363ddcaSBoris Boutkov 
740a4a986ddSBoris Boutkov    Input Argument:
7414363ddcaSBoris Boutkov .  dm - the shell DM
7424363ddcaSBoris Boutkov 
743a4a986ddSBoris Boutkov    Output Argument:
7444363ddcaSBoris Boutkov .  refine - the routine that refines the DM
7454363ddcaSBoris Boutkov 
7464363ddcaSBoris Boutkov    Level: advanced
7474363ddcaSBoris Boutkov 
7484363ddcaSBoris Boutkov .seealso: DMShellSetCoarsen(), DMCoarsen(), DMShellSetRefine(), DMRefine()
7494363ddcaSBoris Boutkov @*/
7504363ddcaSBoris Boutkov PetscErrorCode DMShellGetRefine(DM dm, PetscErrorCode (**refine)(DM,MPI_Comm,DM*))
7514363ddcaSBoris Boutkov {
7524363ddcaSBoris Boutkov   PetscErrorCode ierr;
7534363ddcaSBoris Boutkov   PetscBool      isshell;
7544363ddcaSBoris Boutkov 
7554363ddcaSBoris Boutkov   PetscFunctionBegin;
7564363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7574363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
7588dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
7594363ddcaSBoris Boutkov   *refine = dm->ops->refine;
7604363ddcaSBoris Boutkov   PetscFunctionReturn(0);
7614363ddcaSBoris Boutkov }
7624363ddcaSBoris Boutkov 
7634363ddcaSBoris Boutkov /*@C
7649bf9660cSLawrence Mitchell    DMShellSetCreateInterpolation - Set the routine used to create the interpolation operator
7659bf9660cSLawrence Mitchell 
766d083f849SBarry Smith    Logically Collective on dm
7679bf9660cSLawrence Mitchell 
7689bf9660cSLawrence Mitchell    Input Arguments
7699bf9660cSLawrence Mitchell +  dm - the shell DM
7709bf9660cSLawrence Mitchell -  interp - the routine to create the interpolation
7719bf9660cSLawrence Mitchell 
7729bf9660cSLawrence Mitchell    Level: advanced
7739bf9660cSLawrence Mitchell 
774bf890c61SBoris Boutkov .seealso: DMShellSetCreateInjection(), DMCreateInterpolation(), DMShellGetCreateInterpolation(), DMShellSetCreateRestriction(), DMShellSetContext(), DMShellGetContext()
7759bf9660cSLawrence Mitchell @*/
776f572501eSLawrence Mitchell PetscErrorCode DMShellSetCreateInterpolation(DM dm, PetscErrorCode (*interp)(DM,DM,Mat*,Vec*))
777f572501eSLawrence Mitchell {
778f572501eSLawrence Mitchell   PetscErrorCode ierr;
779f572501eSLawrence Mitchell   PetscBool      isshell;
780f572501eSLawrence Mitchell 
781f572501eSLawrence Mitchell   PetscFunctionBegin;
782f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
783f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
784f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
785f572501eSLawrence Mitchell   dm->ops->createinterpolation = interp;
786f572501eSLawrence Mitchell   PetscFunctionReturn(0);
787f572501eSLawrence Mitchell }
788f572501eSLawrence Mitchell 
7893ad4599aSBarry Smith /*@C
7904363ddcaSBoris Boutkov    DMShellGetCreateInterpolation - Get the routine used to create the interpolation operator
7914363ddcaSBoris Boutkov 
792d083f849SBarry Smith    Logically Collective on dm
7934363ddcaSBoris Boutkov 
794a4a986ddSBoris Boutkov    Input Argument:
7954363ddcaSBoris Boutkov +  dm - the shell DM
796a4a986ddSBoris Boutkov 
797a4a986ddSBoris Boutkov    Output Argument:
7984363ddcaSBoris Boutkov -  interp - the routine to create the interpolation
7994363ddcaSBoris Boutkov 
8004363ddcaSBoris Boutkov    Level: advanced
8014363ddcaSBoris Boutkov 
8024363ddcaSBoris Boutkov .seealso: DMShellGetCreateInjection(), DMCreateInterpolation(), DMShellGetCreateRestriction(), DMShellSetContext(), DMShellGetContext()
8034363ddcaSBoris Boutkov @*/
8044363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateInterpolation(DM dm, PetscErrorCode (**interp)(DM,DM,Mat*,Vec*))
8054363ddcaSBoris Boutkov {
8064363ddcaSBoris Boutkov   PetscErrorCode ierr;
8074363ddcaSBoris Boutkov   PetscBool      isshell;
8084363ddcaSBoris Boutkov 
8094363ddcaSBoris Boutkov   PetscFunctionBegin;
8104363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8114363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
8128dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
8134363ddcaSBoris Boutkov   *interp = dm->ops->createinterpolation;
8144363ddcaSBoris Boutkov   PetscFunctionReturn(0);
8154363ddcaSBoris Boutkov }
8164363ddcaSBoris Boutkov 
8174363ddcaSBoris Boutkov /*@C
8183ad4599aSBarry Smith    DMShellSetCreateRestriction - Set the routine used to create the restriction operator
8193ad4599aSBarry Smith 
820d083f849SBarry Smith    Logically Collective on dm
8213ad4599aSBarry Smith 
8223ad4599aSBarry Smith    Input Arguments
8233ad4599aSBarry Smith +  dm - the shell DM
8243ad4599aSBarry Smith -  striction- the routine to create the restriction
8253ad4599aSBarry Smith 
8263ad4599aSBarry Smith    Level: advanced
8273ad4599aSBarry Smith 
828bf890c61SBoris Boutkov .seealso: DMShellSetCreateInjection(), DMCreateInterpolation(), DMShellGetCreateRestriction(), DMShellSetContext(), DMShellGetContext()
8293ad4599aSBarry Smith @*/
8303ad4599aSBarry Smith PetscErrorCode DMShellSetCreateRestriction(DM dm, PetscErrorCode (*restriction)(DM,DM,Mat*))
8313ad4599aSBarry Smith {
8323ad4599aSBarry Smith   PetscErrorCode ierr;
8333ad4599aSBarry Smith   PetscBool      isshell;
8343ad4599aSBarry Smith 
8353ad4599aSBarry Smith   PetscFunctionBegin;
8363ad4599aSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8373ad4599aSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
8383ad4599aSBarry Smith   if (!isshell) PetscFunctionReturn(0);
8393ad4599aSBarry Smith   dm->ops->createrestriction = restriction;
8403ad4599aSBarry Smith   PetscFunctionReturn(0);
8413ad4599aSBarry Smith }
8423ad4599aSBarry Smith 
8439bf9660cSLawrence Mitchell /*@C
8444363ddcaSBoris Boutkov    DMShellGetCreateRestriction - Get the routine used to create the restriction operator
8454363ddcaSBoris Boutkov 
846d083f849SBarry Smith    Logically Collective on dm
8474363ddcaSBoris Boutkov 
848a4a986ddSBoris Boutkov    Input Argument:
8494363ddcaSBoris Boutkov +  dm - the shell DM
850a4a986ddSBoris Boutkov 
851a4a986ddSBoris Boutkov    Output Argument:
852a4a986ddSBoris Boutkov -  restriction - the routine to create the restriction
8534363ddcaSBoris Boutkov 
8544363ddcaSBoris Boutkov    Level: advanced
8554363ddcaSBoris Boutkov 
8564363ddcaSBoris Boutkov .seealso: DMShellSetCreateInjection(), DMCreateInterpolation(), DMShellSetContext(), DMShellGetContext()
8574363ddcaSBoris Boutkov @*/
8584363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateRestriction(DM dm, PetscErrorCode (**restriction)(DM,DM,Mat*))
8594363ddcaSBoris Boutkov {
8604363ddcaSBoris Boutkov   PetscErrorCode ierr;
8614363ddcaSBoris Boutkov   PetscBool      isshell;
8624363ddcaSBoris Boutkov 
8634363ddcaSBoris Boutkov   PetscFunctionBegin;
8644363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8654363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
8668dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
8674363ddcaSBoris Boutkov   *restriction = dm->ops->createrestriction;
8684363ddcaSBoris Boutkov   PetscFunctionReturn(0);
8694363ddcaSBoris Boutkov }
8704363ddcaSBoris Boutkov 
8714363ddcaSBoris Boutkov /*@C
8729bf9660cSLawrence Mitchell    DMShellSetCreateInjection - Set the routine used to create the injection operator
8739bf9660cSLawrence Mitchell 
874d083f849SBarry Smith    Logically Collective on dm
8759bf9660cSLawrence Mitchell 
8769bf9660cSLawrence Mitchell    Input Arguments
8779bf9660cSLawrence Mitchell +  dm - the shell DM
8789bf9660cSLawrence Mitchell -  inject - the routine to create the injection
8799bf9660cSLawrence Mitchell 
8809bf9660cSLawrence Mitchell    Level: advanced
8819bf9660cSLawrence Mitchell 
882bf890c61SBoris Boutkov .seealso: DMShellSetCreateInterpolation(), DMCreateInjection(), DMShellGetCreateInjection(), DMShellSetContext(), DMShellGetContext()
8839bf9660cSLawrence Mitchell @*/
884f572501eSLawrence Mitchell PetscErrorCode DMShellSetCreateInjection(DM dm, PetscErrorCode (*inject)(DM,DM,Mat*))
885f572501eSLawrence Mitchell {
886f572501eSLawrence Mitchell   PetscErrorCode ierr;
887f572501eSLawrence Mitchell   PetscBool      isshell;
888f572501eSLawrence Mitchell 
889f572501eSLawrence Mitchell   PetscFunctionBegin;
890f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
891f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
892f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
8935a84ad33SLisandro Dalcin   dm->ops->createinjection = inject;
894f572501eSLawrence Mitchell   PetscFunctionReturn(0);
895f572501eSLawrence Mitchell }
896f572501eSLawrence Mitchell 
8974363ddcaSBoris Boutkov /*@C
8984363ddcaSBoris Boutkov    DMShellGetCreateInjection - Get the routine used to create the injection operator
8994363ddcaSBoris Boutkov 
900d083f849SBarry Smith    Logically Collective on dm
9014363ddcaSBoris Boutkov 
902a4a986ddSBoris Boutkov    Input Argument:
9034363ddcaSBoris Boutkov +  dm - the shell DM
904a4a986ddSBoris Boutkov 
905a4a986ddSBoris Boutkov    Output Argument:
9064363ddcaSBoris Boutkov -  inject - the routine to create the injection
9074363ddcaSBoris Boutkov 
9084363ddcaSBoris Boutkov    Level: advanced
9094363ddcaSBoris Boutkov 
9104363ddcaSBoris Boutkov .seealso: DMShellGetCreateInterpolation(), DMCreateInjection(), DMShellSetContext(), DMShellGetContext()
9114363ddcaSBoris Boutkov @*/
9124363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateInjection(DM dm, PetscErrorCode (**inject)(DM,DM,Mat*))
9134363ddcaSBoris Boutkov {
9144363ddcaSBoris Boutkov   PetscErrorCode ierr;
9154363ddcaSBoris Boutkov   PetscBool      isshell;
9164363ddcaSBoris Boutkov 
9174363ddcaSBoris Boutkov   PetscFunctionBegin;
9184363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9194363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
9208dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
9215a84ad33SLisandro Dalcin   *inject = dm->ops->createinjection;
9224363ddcaSBoris Boutkov   PetscFunctionReturn(0);
9234363ddcaSBoris Boutkov }
9244363ddcaSBoris Boutkov 
9259bf9660cSLawrence Mitchell /*@C
9269bf9660cSLawrence Mitchell    DMShellSetCreateFieldDecomposition - Set the routine used to create a decomposition of fields for the shell DM
9279bf9660cSLawrence Mitchell 
928d083f849SBarry Smith    Logically Collective on dm
9299bf9660cSLawrence Mitchell 
9309bf9660cSLawrence Mitchell    Input Arguments
9319bf9660cSLawrence Mitchell +  dm - the shell DM
9329bf9660cSLawrence Mitchell -  decomp - the routine to create the decomposition
9339bf9660cSLawrence Mitchell 
9349bf9660cSLawrence Mitchell    Level: advanced
9359bf9660cSLawrence Mitchell 
936fef3a512SBarry Smith .seealso: DMCreateFieldDecomposition(), DMShellSetContext(), DMShellGetContext()
9379bf9660cSLawrence Mitchell @*/
9385e2259d5SLawrence Mitchell PetscErrorCode DMShellSetCreateFieldDecomposition(DM dm, PetscErrorCode (*decomp)(DM,PetscInt*,char***, IS**,DM**))
9395e2259d5SLawrence Mitchell {
9405e2259d5SLawrence Mitchell   PetscErrorCode ierr;
9415e2259d5SLawrence Mitchell   PetscBool      isshell;
9425e2259d5SLawrence Mitchell 
9435e2259d5SLawrence Mitchell   PetscFunctionBegin;
9445e2259d5SLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9455e2259d5SLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
9465e2259d5SLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
9475e2259d5SLawrence Mitchell   dm->ops->createfielddecomposition = decomp;
9485e2259d5SLawrence Mitchell   PetscFunctionReturn(0);
9495e2259d5SLawrence Mitchell }
9505e2259d5SLawrence Mitchell 
951c00061e5SLawrence Mitchell /*@C
952e734121bSPatrick Farrell    DMShellSetCreateDomainDecomposition - Set the routine used to create a domain decomposition for the shell DM
953e734121bSPatrick Farrell 
954d083f849SBarry Smith    Logically Collective on dm
955e734121bSPatrick Farrell 
956e734121bSPatrick Farrell    Input Arguments
957e734121bSPatrick Farrell +  dm - the shell DM
958e734121bSPatrick Farrell -  decomp - the routine to create the decomposition
959e734121bSPatrick Farrell 
960e734121bSPatrick Farrell    Level: advanced
961e734121bSPatrick Farrell 
962e734121bSPatrick Farrell .seealso: DMCreateDomainDecomposition(), DMShellSetContext(), DMShellGetContext()
963e734121bSPatrick Farrell @*/
964e734121bSPatrick Farrell PetscErrorCode DMShellSetCreateDomainDecomposition(DM dm, PetscErrorCode (*decomp)(DM,PetscInt*,char***, IS**,IS**,DM**))
965e734121bSPatrick Farrell {
966e734121bSPatrick Farrell   PetscErrorCode ierr;
967e734121bSPatrick Farrell   PetscBool      isshell;
968e734121bSPatrick Farrell 
969e734121bSPatrick Farrell   PetscFunctionBegin;
970e734121bSPatrick Farrell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
971e734121bSPatrick Farrell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
972e734121bSPatrick Farrell   if (!isshell) PetscFunctionReturn(0);
973e734121bSPatrick Farrell   dm->ops->createdomaindecomposition = decomp;
974e734121bSPatrick Farrell   PetscFunctionReturn(0);
975e734121bSPatrick Farrell }
976e734121bSPatrick Farrell 
977e734121bSPatrick Farrell /*@C
978eef9d6cdSPatrick Farrell    DMShellSetCreateDomainDecompositionScatters - Set the routine used to create the scatter contexts for domain decomposition with a shell DM
979eef9d6cdSPatrick Farrell 
980d083f849SBarry Smith    Logically Collective on dm
981eef9d6cdSPatrick Farrell 
982eef9d6cdSPatrick Farrell    Input Arguments
983eef9d6cdSPatrick Farrell +  dm - the shell DM
984eef9d6cdSPatrick Farrell -  scatter - the routine to create the scatters
985eef9d6cdSPatrick Farrell 
986eef9d6cdSPatrick Farrell    Level: advanced
987eef9d6cdSPatrick Farrell 
988448b6425SPatrick Farrell .seealso: DMCreateDomainDecompositionScatters(), DMShellSetContext(), DMShellGetContext()
989eef9d6cdSPatrick Farrell @*/
990eef9d6cdSPatrick Farrell PetscErrorCode DMShellSetCreateDomainDecompositionScatters(DM dm, PetscErrorCode (*scatter)(DM,PetscInt,DM*,VecScatter**,VecScatter**,VecScatter**))
991eef9d6cdSPatrick Farrell {
992eef9d6cdSPatrick Farrell   PetscErrorCode ierr;
993eef9d6cdSPatrick Farrell   PetscBool      isshell;
994eef9d6cdSPatrick Farrell 
995eef9d6cdSPatrick Farrell   PetscFunctionBegin;
996eef9d6cdSPatrick Farrell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
997eef9d6cdSPatrick Farrell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
998eef9d6cdSPatrick Farrell   if (!isshell) PetscFunctionReturn(0);
999eef9d6cdSPatrick Farrell   dm->ops->createddscatters = scatter;
1000eef9d6cdSPatrick Farrell   PetscFunctionReturn(0);
1001eef9d6cdSPatrick Farrell }
1002eef9d6cdSPatrick Farrell 
1003eef9d6cdSPatrick Farrell /*@C
1004c00061e5SLawrence Mitchell    DMShellSetCreateSubDM - Set the routine used to create a sub DM from the shell DM
1005c00061e5SLawrence Mitchell 
1006d083f849SBarry Smith    Logically Collective on dm
1007c00061e5SLawrence Mitchell 
1008c00061e5SLawrence Mitchell    Input Arguments
1009c00061e5SLawrence Mitchell +  dm - the shell DM
1010c00061e5SLawrence Mitchell -  subdm - the routine to create the decomposition
1011c00061e5SLawrence Mitchell 
1012c00061e5SLawrence Mitchell    Level: advanced
1013c00061e5SLawrence Mitchell 
1014bf890c61SBoris Boutkov .seealso: DMCreateSubDM(), DMShellGetCreateSubDM(), DMShellSetContext(), DMShellGetContext()
1015c00061e5SLawrence Mitchell @*/
1016276c5506SMatthew G. Knepley PetscErrorCode DMShellSetCreateSubDM(DM dm, PetscErrorCode (*subdm)(DM,PetscInt,const PetscInt[],IS*,DM*))
1017c00061e5SLawrence Mitchell {
1018c00061e5SLawrence Mitchell   PetscErrorCode ierr;
1019c00061e5SLawrence Mitchell   PetscBool      isshell;
1020c00061e5SLawrence Mitchell 
1021c00061e5SLawrence Mitchell   PetscFunctionBegin;
1022c00061e5SLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1023c00061e5SLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
1024c00061e5SLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
1025c00061e5SLawrence Mitchell   dm->ops->createsubdm = subdm;
1026c00061e5SLawrence Mitchell   PetscFunctionReturn(0);
1027c00061e5SLawrence Mitchell }
1028c00061e5SLawrence Mitchell 
10294363ddcaSBoris Boutkov /*@C
10304363ddcaSBoris Boutkov    DMShellGetCreateSubDM - Get the routine used to create a sub DM from the shell DM
10314363ddcaSBoris Boutkov 
1032d083f849SBarry Smith    Logically Collective on dm
10334363ddcaSBoris Boutkov 
1034a4a986ddSBoris Boutkov    Input Argument:
10354363ddcaSBoris Boutkov +  dm - the shell DM
1036a4a986ddSBoris Boutkov 
1037a4a986ddSBoris Boutkov    Output Argument:
10384363ddcaSBoris Boutkov -  subdm - the routine to create the decomposition
10394363ddcaSBoris Boutkov 
10404363ddcaSBoris Boutkov    Level: advanced
10414363ddcaSBoris Boutkov 
10424363ddcaSBoris Boutkov .seealso: DMCreateSubDM(), DMShellSetCreateSubDM(), DMShellSetContext(), DMShellGetContext()
10434363ddcaSBoris Boutkov @*/
10444363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateSubDM(DM dm, PetscErrorCode (**subdm)(DM,PetscInt,const PetscInt[],IS*,DM*))
10454363ddcaSBoris Boutkov {
10464363ddcaSBoris Boutkov   PetscErrorCode ierr;
10474363ddcaSBoris Boutkov   PetscBool      isshell;
10484363ddcaSBoris Boutkov 
10494363ddcaSBoris Boutkov   PetscFunctionBegin;
10504363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10514363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
10528dd90dd5SBoris Boutkov   if (!isshell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only use with DMSHELL type DMs");
10534363ddcaSBoris Boutkov   *subdm = dm->ops->createsubdm;
10544363ddcaSBoris Boutkov   PetscFunctionReturn(0);
10554363ddcaSBoris Boutkov }
10564363ddcaSBoris Boutkov 
1057fe1899a2SJed Brown static PetscErrorCode DMDestroy_Shell(DM dm)
1058fe1899a2SJed Brown {
1059fe1899a2SJed Brown   PetscErrorCode ierr;
1060fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
1061fe1899a2SJed Brown 
1062fe1899a2SJed Brown   PetscFunctionBegin;
1063fe1899a2SJed Brown   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
1064fe1899a2SJed Brown   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
1065dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
1066a94b16f6SRichard Tran Mills   ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr);
1067a94b16f6SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr);
1068294a6417SLawrence Mitchell   ierr = VecScatterDestroy(&shell->ltol);CHKERRQ(ierr);
10697b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
10707b6ad80cSMatthew G Knepley   ierr = PetscFree(shell);CHKERRQ(ierr);
1071fe1899a2SJed Brown   PetscFunctionReturn(0);
1072fe1899a2SJed Brown }
1073fe1899a2SJed Brown 
10742d53ad75SBarry Smith static PetscErrorCode DMView_Shell(DM dm,PetscViewer v)
10752d53ad75SBarry Smith {
10762d53ad75SBarry Smith   PetscErrorCode ierr;
10772d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
10782d53ad75SBarry Smith 
10792d53ad75SBarry Smith   PetscFunctionBegin;
10802d53ad75SBarry Smith   ierr = VecView(shell->Xglobal,v);CHKERRQ(ierr);
10812d53ad75SBarry Smith   PetscFunctionReturn(0);
10822d53ad75SBarry Smith }
10832d53ad75SBarry Smith 
10842d53ad75SBarry Smith static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v)
10852d53ad75SBarry Smith {
10862d53ad75SBarry Smith   PetscErrorCode ierr;
10872d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
10882d53ad75SBarry Smith 
10892d53ad75SBarry Smith   PetscFunctionBegin;
1090ce94432eSBarry Smith   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&shell->Xglobal);CHKERRQ(ierr);
10912d53ad75SBarry Smith   ierr = VecLoad(shell->Xglobal,v);CHKERRQ(ierr);
10922d53ad75SBarry Smith   PetscFunctionReturn(0);
10932d53ad75SBarry Smith }
1094fe1899a2SJed Brown 
1095276c5506SMatthew G. Knepley PetscErrorCode DMCreateSubDM_Shell(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
10966e44b4cfSMatthew G. Knepley {
10976e44b4cfSMatthew G. Knepley   PetscErrorCode ierr;
10986e44b4cfSMatthew G. Knepley 
10996e44b4cfSMatthew G. Knepley   PetscFunctionBegin;
11006e44b4cfSMatthew G. Knepley   if (subdm) {ierr = DMShellCreate(PetscObjectComm((PetscObject) dm), subdm);CHKERRQ(ierr);}
1101792b654fSMatthew G. Knepley   ierr = DMCreateSectionSubDM(dm, numFields, fields, is, subdm);CHKERRQ(ierr);
11026e44b4cfSMatthew G. Knepley   PetscFunctionReturn(0);
11036e44b4cfSMatthew G. Knepley }
11046e44b4cfSMatthew G. Knepley 
11058cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm)
1106fe1899a2SJed Brown {
1107fe1899a2SJed Brown   PetscErrorCode ierr;
1108fe1899a2SJed Brown   DM_Shell       *shell;
1109fe1899a2SJed Brown 
1110fe1899a2SJed Brown   PetscFunctionBegin;
1111b00a9115SJed Brown   ierr     = PetscNewLog(dm,&shell);CHKERRQ(ierr);
11128c87107bSJed Brown   dm->data = shell;
1113fe1899a2SJed Brown 
11148c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
11158c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
1116dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
11178c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
11182d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
11192d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
11207a108d1dSBarry Smith   dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell;
11217a108d1dSBarry Smith   dm->ops->globaltolocalend   = DMGlobalToLocalEndDefaultShell;
112255daaa54SRichard Tran Mills   dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell;
112355daaa54SRichard Tran Mills   dm->ops->localtoglobalend   = DMLocalToGlobalEndDefaultShell;
112463731094SRichard Tran Mills   dm->ops->localtolocalbegin  = DMLocalToLocalBeginDefaultShell;
112563731094SRichard Tran Mills   dm->ops->localtolocalend    = DMLocalToLocalEndDefaultShell;
11266e44b4cfSMatthew G. Knepley   dm->ops->createsubdm        = DMCreateSubDM_Shell;
1127fe1899a2SJed Brown   PetscFunctionReturn(0);
1128fe1899a2SJed Brown }
1129fe1899a2SJed Brown 
1130fe1899a2SJed Brown /*@
1131fe1899a2SJed Brown     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
1132fe1899a2SJed Brown 
1133d083f849SBarry Smith     Collective
1134fe1899a2SJed Brown 
1135fe1899a2SJed Brown     Input Parameter:
1136fe1899a2SJed Brown .   comm - the processors that will share the global vector
1137fe1899a2SJed Brown 
1138fe1899a2SJed Brown     Output Parameters:
1139fe1899a2SJed Brown .   shell - the shell DM
1140fe1899a2SJed Brown 
1141fe1899a2SJed Brown     Level: advanced
1142fe1899a2SJed Brown 
1143fef3a512SBarry Smith .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateLocalVector(), DMShellSetContext(), DMShellGetContext()
1144fe1899a2SJed Brown @*/
1145fe1899a2SJed Brown PetscErrorCode  DMShellCreate(MPI_Comm comm,DM *dm)
1146fe1899a2SJed Brown {
1147fe1899a2SJed Brown   PetscErrorCode ierr;
1148fe1899a2SJed Brown 
1149fe1899a2SJed Brown   PetscFunctionBegin;
1150fe1899a2SJed Brown   PetscValidPointer(dm,2);
1151fe1899a2SJed Brown   ierr = DMCreate(comm,dm);CHKERRQ(ierr);
1152fe1899a2SJed Brown   ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr);
115381a566bfSMatthew G. Knepley   ierr = DMSetUp(*dm);CHKERRQ(ierr);
1154fe1899a2SJed Brown   PetscFunctionReturn(0);
1155fe1899a2SJed Brown }
1156