xref: /petsc/src/dm/impls/shell/dmshell.c (revision a4a986ddafca55906f08925e92b0ac311fbd5ed3)
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   }
208fe1899a2SJed Brown   if (((PetscObject)A)->refct < 2) { /* We have an exclusive reference so we can give it out */
209fe1899a2SJed Brown     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
210fe1899a2SJed Brown     ierr = MatZeroEntries(A);CHKERRQ(ierr);
211fe1899a2SJed Brown     *J   = A;
212fe1899a2SJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
213fe1899a2SJed Brown     ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J);CHKERRQ(ierr);
214fe1899a2SJed Brown     ierr = MatZeroEntries(*J);CHKERRQ(ierr);
215fe1899a2SJed Brown   }
216fe1899a2SJed Brown   PetscFunctionReturn(0);
217fe1899a2SJed Brown }
218fe1899a2SJed Brown 
219fe1899a2SJed Brown PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec)
220fe1899a2SJed Brown {
221fe1899a2SJed Brown   PetscErrorCode ierr;
222fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
223fe1899a2SJed Brown   Vec            X;
224fe1899a2SJed Brown 
225fe1899a2SJed Brown   PetscFunctionBegin;
226fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
227fe1899a2SJed Brown   PetscValidPointer(gvec,2);
228fe1899a2SJed Brown   *gvec = 0;
229fe1899a2SJed Brown   X     = shell->Xglobal;
230ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
231fe1899a2SJed Brown   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
232fe1899a2SJed Brown     ierr  = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
233fe1899a2SJed Brown     ierr  = VecZeroEntries(X);CHKERRQ(ierr);
234fe1899a2SJed Brown     *gvec = X;
235fe1899a2SJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
236fe1899a2SJed Brown     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
237fe1899a2SJed Brown     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
238fe1899a2SJed Brown   }
239c688c046SMatthew G Knepley   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
240fe1899a2SJed Brown   PetscFunctionReturn(0);
241fe1899a2SJed Brown }
242fe1899a2SJed Brown 
243dc43b69eSJed Brown PetscErrorCode DMCreateLocalVector_Shell(DM dm,Vec *gvec)
244dc43b69eSJed Brown {
245dc43b69eSJed Brown   PetscErrorCode ierr;
246dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
247dc43b69eSJed Brown   Vec            X;
248dc43b69eSJed Brown 
249dc43b69eSJed Brown   PetscFunctionBegin;
250dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
251dc43b69eSJed Brown   PetscValidPointer(gvec,2);
252dc43b69eSJed Brown   *gvec = 0;
253dc43b69eSJed Brown   X     = shell->Xlocal;
254ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()");
255dc43b69eSJed Brown   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
256dc43b69eSJed Brown     ierr  = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
257dc43b69eSJed Brown     ierr  = VecZeroEntries(X);CHKERRQ(ierr);
258dc43b69eSJed Brown     *gvec = X;
259dc43b69eSJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
260dc43b69eSJed Brown     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
261dc43b69eSJed Brown     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
262dc43b69eSJed Brown   }
2636e4cbd8bSMark F. Adams   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
264dc43b69eSJed Brown   PetscFunctionReturn(0);
265dc43b69eSJed Brown }
266dc43b69eSJed Brown 
267fef3a512SBarry Smith /*@
268fef3a512SBarry Smith    DMShellSetContext - set some data to be usable by this DM
269fef3a512SBarry Smith 
270fef3a512SBarry Smith    Collective
271fef3a512SBarry Smith 
272fef3a512SBarry Smith    Input Arguments:
273fef3a512SBarry Smith +  dm - shell DM
274fef3a512SBarry Smith -  ctx - the context
275fef3a512SBarry Smith 
276fef3a512SBarry Smith    Level: advanced
277fef3a512SBarry Smith 
278fef3a512SBarry Smith .seealso: DMCreateMatrix(), DMShellGetContext()
279fef3a512SBarry Smith @*/
280fef3a512SBarry Smith PetscErrorCode DMShellSetContext(DM dm,void *ctx)
281fef3a512SBarry Smith {
282fef3a512SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
283fef3a512SBarry Smith   PetscErrorCode ierr;
284fef3a512SBarry Smith   PetscBool      isshell;
285fef3a512SBarry Smith 
286fef3a512SBarry Smith   PetscFunctionBegin;
287fef3a512SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
288fef3a512SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
289fef3a512SBarry Smith   if (!isshell) PetscFunctionReturn(0);
290fef3a512SBarry Smith   shell->ctx = ctx;
291fef3a512SBarry Smith   PetscFunctionReturn(0);
292fef3a512SBarry Smith }
293fef3a512SBarry Smith 
294fef3a512SBarry Smith /*@
295bf890c61SBoris Boutkov    DMShellGetContext - Returns the user-provided context associated to the DM
296fef3a512SBarry Smith 
297fef3a512SBarry Smith    Collective
298fef3a512SBarry Smith 
299fef3a512SBarry Smith    Input Argument:
300fef3a512SBarry Smith .  dm - shell DM
301fef3a512SBarry Smith 
302fef3a512SBarry Smith    Output Argument:
303fef3a512SBarry Smith .  ctx - the context
304fef3a512SBarry Smith 
305fef3a512SBarry Smith    Level: advanced
306fef3a512SBarry Smith 
307fef3a512SBarry Smith .seealso: DMCreateMatrix(), DMShellSetContext()
308fef3a512SBarry Smith @*/
309fef3a512SBarry Smith PetscErrorCode DMShellGetContext(DM dm,void **ctx)
310fef3a512SBarry Smith {
311fef3a512SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
312fef3a512SBarry Smith   PetscErrorCode ierr;
313fef3a512SBarry Smith   PetscBool      isshell;
314fef3a512SBarry Smith 
315fef3a512SBarry Smith   PetscFunctionBegin;
316fef3a512SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
317fef3a512SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
318fef3a512SBarry Smith   if (!isshell) PetscFunctionReturn(0);
319fef3a512SBarry Smith   *ctx = shell->ctx;
320fef3a512SBarry Smith   PetscFunctionReturn(0);
321fef3a512SBarry Smith }
322fef3a512SBarry Smith 
323fe1899a2SJed Brown /*@
324fe1899a2SJed Brown    DMShellSetMatrix - sets a template matrix associated with the DMShell
325fe1899a2SJed Brown 
326fe1899a2SJed Brown    Collective
327fe1899a2SJed Brown 
328fe1899a2SJed Brown    Input Arguments:
329fe1899a2SJed Brown +  dm - shell DM
330fe1899a2SJed Brown -  J - template matrix
331fe1899a2SJed Brown 
332fe1899a2SJed Brown    Level: advanced
333fe1899a2SJed Brown 
334fef3a512SBarry Smith .seealso: DMCreateMatrix(), DMShellSetCreateMatrix(), DMShellSetContext(), DMShellGetContext()
335fe1899a2SJed Brown @*/
336fe1899a2SJed Brown PetscErrorCode DMShellSetMatrix(DM dm,Mat J)
337fe1899a2SJed Brown {
338fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
339fe1899a2SJed Brown   PetscErrorCode ierr;
3408c87107bSJed Brown   PetscBool      isshell;
341fe1899a2SJed Brown 
342fe1899a2SJed Brown   PetscFunctionBegin;
3438c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3448c87107bSJed Brown   PetscValidHeaderSpecific(J,MAT_CLASSID,2);
345251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
3468c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
347fe1899a2SJed Brown   ierr     = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
348fe1899a2SJed Brown   ierr     = MatDestroy(&shell->A);CHKERRQ(ierr);
349fe1899a2SJed Brown   shell->A = J;
350fe1899a2SJed Brown   PetscFunctionReturn(0);
351fe1899a2SJed Brown }
352fe1899a2SJed Brown 
353fe1899a2SJed Brown /*@C
354fe1899a2SJed Brown    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM
355fe1899a2SJed Brown 
356fe1899a2SJed Brown    Logically Collective on DM
357fe1899a2SJed Brown 
358fe1899a2SJed Brown    Input Arguments:
359fe1899a2SJed Brown +  dm - the shell DM
360fe1899a2SJed Brown -  func - the function to create a matrix
361fe1899a2SJed Brown 
362fe1899a2SJed Brown    Level: advanced
363fe1899a2SJed Brown 
364fef3a512SBarry Smith .seealso: DMCreateMatrix(), DMShellSetMatrix(), DMShellSetContext(), DMShellGetContext()
365fe1899a2SJed Brown @*/
366b412c318SBarry Smith PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,Mat*))
367fe1899a2SJed Brown {
368fe1899a2SJed Brown 
369fe1899a2SJed Brown   PetscFunctionBegin;
370fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
371fe1899a2SJed Brown   dm->ops->creatematrix = func;
372fe1899a2SJed Brown   PetscFunctionReturn(0);
373fe1899a2SJed Brown }
374fe1899a2SJed Brown 
375fe1899a2SJed Brown /*@
376fe1899a2SJed Brown    DMShellSetGlobalVector - sets a template global vector associated with the DMShell
377fe1899a2SJed Brown 
378fe1899a2SJed Brown    Logically Collective on DM
379fe1899a2SJed Brown 
380fe1899a2SJed Brown    Input Arguments:
381fe1899a2SJed Brown +  dm - shell DM
382fe1899a2SJed Brown -  X - template vector
383fe1899a2SJed Brown 
384fe1899a2SJed Brown    Level: advanced
385fe1899a2SJed Brown 
386fe1899a2SJed Brown .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector()
387fe1899a2SJed Brown @*/
388fe1899a2SJed Brown PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X)
389fe1899a2SJed Brown {
390fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
391fe1899a2SJed Brown   PetscErrorCode ierr;
3928c87107bSJed Brown   PetscBool      isshell;
393cca7ec1eSBarry Smith   DM             vdm;
394fe1899a2SJed Brown 
395fe1899a2SJed Brown   PetscFunctionBegin;
3968c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3978c87107bSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
398251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
3998c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
400cca7ec1eSBarry Smith   ierr = VecGetDM(X,&vdm);CHKERRQ(ierr);
401cca7ec1eSBarry Smith   /*
402cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
403cca7ec1eSBarry 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
404cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
405cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
406cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
407cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
408cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
409cca7ec1eSBarry Smith       for pointing out the problem.
410cca7ec1eSBarry Smith    */
411cca7ec1eSBarry Smith   if (vdm == dm) PetscFunctionReturn(0);
412fe1899a2SJed Brown   ierr           = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
413fe1899a2SJed Brown   ierr           = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
414fe1899a2SJed Brown   shell->Xglobal = X;
415fe1899a2SJed Brown   PetscFunctionReturn(0);
416fe1899a2SJed Brown }
417fe1899a2SJed Brown 
418fe1899a2SJed Brown /*@C
419fe1899a2SJed Brown    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
420fe1899a2SJed Brown 
421fe1899a2SJed Brown    Logically Collective
422fe1899a2SJed Brown 
423fe1899a2SJed Brown    Input Arguments:
424fe1899a2SJed Brown +  dm - the shell DM
425fe1899a2SJed Brown -  func - the creation routine
426fe1899a2SJed Brown 
427fe1899a2SJed Brown    Level: advanced
428fe1899a2SJed Brown 
429fef3a512SBarry Smith .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix(), DMShellSetContext(), DMShellGetContext()
430fe1899a2SJed Brown @*/
431fe1899a2SJed Brown PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
432fe1899a2SJed Brown {
433fe1899a2SJed Brown 
434fe1899a2SJed Brown   PetscFunctionBegin;
435fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
436fe1899a2SJed Brown   dm->ops->createglobalvector = func;
437fe1899a2SJed Brown   PetscFunctionReturn(0);
438fe1899a2SJed Brown }
439fe1899a2SJed Brown 
440dc43b69eSJed Brown /*@
441dc43b69eSJed Brown    DMShellSetLocalVector - sets a template local vector associated with the DMShell
442dc43b69eSJed Brown 
443dc43b69eSJed Brown    Logically Collective on DM
444dc43b69eSJed Brown 
445dc43b69eSJed Brown    Input Arguments:
446dc43b69eSJed Brown +  dm - shell DM
447dc43b69eSJed Brown -  X - template vector
448dc43b69eSJed Brown 
449dc43b69eSJed Brown    Level: advanced
450dc43b69eSJed Brown 
451dc43b69eSJed Brown .seealso: DMCreateLocalVector(), DMShellSetMatrix(), DMShellSetCreateLocalVector()
452dc43b69eSJed Brown @*/
453dc43b69eSJed Brown PetscErrorCode DMShellSetLocalVector(DM dm,Vec X)
454dc43b69eSJed Brown {
455dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
456dc43b69eSJed Brown   PetscErrorCode ierr;
457dc43b69eSJed Brown   PetscBool      isshell;
458cca7ec1eSBarry Smith   DM             vdm;
459dc43b69eSJed Brown 
460dc43b69eSJed Brown   PetscFunctionBegin;
461dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
462dc43b69eSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
463dc43b69eSJed Brown   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
464dc43b69eSJed Brown   if (!isshell) PetscFunctionReturn(0);
465cca7ec1eSBarry Smith   ierr           = VecGetDM(X,&vdm);CHKERRQ(ierr);
466cca7ec1eSBarry Smith   /*
467cca7ec1eSBarry Smith       if the vector proposed as the new base global vector for the DM is a DM vector associated
468cca7ec1eSBarry 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
469cca7ec1eSBarry Smith       we get a circular dependency that prevents the DM from being destroy when it should be.
470cca7ec1eSBarry Smith       This occurs when SNESSet/GetNPC() is used with a SNES that does not have a user provided
471cca7ec1eSBarry Smith       DM attached to it since the inner SNES (which shares the DM with the outer SNES) tries
472cca7ec1eSBarry Smith       to set its input vector (which is associated with the DM) as the base global vector.
473cca7ec1eSBarry Smith       Thanks to Juan P. Mendez Granado Re: [petsc-maint] Nonlinear conjugate gradien
474cca7ec1eSBarry Smith       for pointing out the problem.
475cca7ec1eSBarry Smith    */
476cca7ec1eSBarry Smith   if (vdm == dm) PetscFunctionReturn(0);
477dc43b69eSJed Brown   ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
478dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
479dc43b69eSJed Brown   shell->Xlocal = X;
480dc43b69eSJed Brown   PetscFunctionReturn(0);
481dc43b69eSJed Brown }
482dc43b69eSJed Brown 
483dc43b69eSJed Brown /*@C
484dc43b69eSJed Brown    DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM
485dc43b69eSJed Brown 
486dc43b69eSJed Brown    Logically Collective
487dc43b69eSJed Brown 
488dc43b69eSJed Brown    Input Arguments:
489dc43b69eSJed Brown +  dm - the shell DM
490dc43b69eSJed Brown -  func - the creation routine
491dc43b69eSJed Brown 
492dc43b69eSJed Brown    Level: advanced
493dc43b69eSJed Brown 
494fef3a512SBarry Smith .seealso: DMShellSetLocalVector(), DMShellSetCreateMatrix(), DMShellSetContext(), DMShellGetContext()
495dc43b69eSJed Brown @*/
496dc43b69eSJed Brown PetscErrorCode DMShellSetCreateLocalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
497dc43b69eSJed Brown {
498dc43b69eSJed Brown 
499dc43b69eSJed Brown   PetscFunctionBegin;
500dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
501dc43b69eSJed Brown   dm->ops->createlocalvector = func;
502dc43b69eSJed Brown   PetscFunctionReturn(0);
503dc43b69eSJed Brown }
504dc43b69eSJed Brown 
5058339e6d0SRichard Tran Mills /*@C
5068339e6d0SRichard Tran Mills    DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
5078339e6d0SRichard Tran Mills 
5088339e6d0SRichard Tran Mills    Logically Collective on DM
5098339e6d0SRichard Tran Mills 
5108339e6d0SRichard Tran Mills    Input Arguments
5118339e6d0SRichard Tran Mills +  dm - the shell DM
5128339e6d0SRichard Tran Mills .  begin - the routine that begins the global to local scatter
5138339e6d0SRichard Tran Mills -  end - the routine that ends the global to local scatter
5148339e6d0SRichard Tran Mills 
51595452b02SPatrick Sanan    Notes:
51695452b02SPatrick Sanan     If these functions are not provided but DMShellSetGlobalToLocalVecScatter() is called then
517f3db62a7SRichard Tran Mills    DMGlobalToLocalBeginDefaultShell()/DMGlobalToLocalEndDefaultShell() are used to to perform the transfers
5187a108d1dSBarry Smith 
5198339e6d0SRichard Tran Mills    Level: advanced
5208339e6d0SRichard Tran Mills 
5217a108d1dSBarry Smith .seealso: DMShellSetLocalToGlobal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell()
5228339e6d0SRichard Tran Mills @*/
5238339e6d0SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
5248339e6d0SRichard Tran Mills   PetscFunctionBegin;
5258339e6d0SRichard Tran Mills   dm->ops->globaltolocalbegin = begin;
5268339e6d0SRichard Tran Mills   dm->ops->globaltolocalend = end;
5278339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
5288339e6d0SRichard Tran Mills }
5298339e6d0SRichard Tran Mills 
5308339e6d0SRichard Tran Mills /*@C
5318339e6d0SRichard Tran Mills    DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
5328339e6d0SRichard Tran Mills 
5338339e6d0SRichard Tran Mills    Logically Collective on DM
5348339e6d0SRichard Tran Mills 
5358339e6d0SRichard Tran Mills    Input Arguments
5368339e6d0SRichard Tran Mills +  dm - the shell DM
5378339e6d0SRichard Tran Mills .  begin - the routine that begins the local to global scatter
5388339e6d0SRichard Tran Mills -  end - the routine that ends the local to global scatter
5398339e6d0SRichard Tran Mills 
54095452b02SPatrick Sanan    Notes:
54195452b02SPatrick Sanan     If these functions are not provided but DMShellSetLocalToGlobalVecScatter() is called then
542f3db62a7SRichard Tran Mills    DMLocalToGlobalBeginDefaultShell()/DMLocalToGlobalEndDefaultShell() are used to to perform the transfers
543f3db62a7SRichard Tran Mills 
5448339e6d0SRichard Tran Mills    Level: advanced
5458339e6d0SRichard Tran Mills 
5468339e6d0SRichard Tran Mills .seealso: DMShellSetGlobalToLocal()
5478339e6d0SRichard Tran Mills @*/
5488339e6d0SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
5498339e6d0SRichard Tran Mills   PetscFunctionBegin;
5508339e6d0SRichard Tran Mills   dm->ops->localtoglobalbegin = begin;
5518339e6d0SRichard Tran Mills   dm->ops->localtoglobalend = end;
5528339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
5538339e6d0SRichard Tran Mills }
5548339e6d0SRichard Tran Mills 
555f3db62a7SRichard Tran Mills /*@C
556f3db62a7SRichard Tran Mills    DMShellSetLocalToLocal - Sets the routines used to perform a local to local scatter
557f3db62a7SRichard Tran Mills 
558f3db62a7SRichard Tran Mills    Logically Collective on DM
559f3db62a7SRichard Tran Mills 
560f3db62a7SRichard Tran Mills    Input Arguments
561f3db62a7SRichard Tran Mills +  dm - the shell DM
562f3db62a7SRichard Tran Mills .  begin - the routine that begins the local to local scatter
563f3db62a7SRichard Tran Mills -  end - the routine that ends the local to local scatter
564f3db62a7SRichard Tran Mills 
56595452b02SPatrick Sanan    Notes:
56695452b02SPatrick Sanan     If these functions are not provided but DMShellSetLocalToLocalVecScatter() is called then
567f3db62a7SRichard Tran Mills    DMLocalToLocalBeginDefaultShell()/DMLocalToLocalEndDefaultShell() are used to to perform the transfers
568f3db62a7SRichard Tran Mills 
569f3db62a7SRichard Tran Mills    Level: advanced
570f3db62a7SRichard Tran Mills 
571f3db62a7SRichard Tran Mills .seealso: DMShellSetGlobalToLocal(), DMLocalToLocalBeginDefaultShell(), DMLocalToLocalEndDefaultShell()
572f3db62a7SRichard Tran Mills @*/
573f3db62a7SRichard Tran Mills PetscErrorCode DMShellSetLocalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
574f3db62a7SRichard Tran Mills   PetscFunctionBegin;
575f3db62a7SRichard Tran Mills   dm->ops->localtolocalbegin = begin;
576f3db62a7SRichard Tran Mills   dm->ops->localtolocalend = end;
577f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
578f3db62a7SRichard Tran Mills }
579f3db62a7SRichard Tran Mills 
58081634712SRichard Tran Mills /*@
58181634712SRichard Tran Mills    DMShellSetGlobalToLocalVecScatter - Sets a VecScatter context for global to local communication
58281634712SRichard Tran Mills 
58381634712SRichard Tran Mills    Logically Collective on DM
58481634712SRichard Tran Mills 
58581634712SRichard Tran Mills    Input Arguments
58681634712SRichard Tran Mills +  dm - the shell DM
58781634712SRichard Tran Mills -  gtol - the global to local VecScatter context
58881634712SRichard Tran Mills 
58981634712SRichard Tran Mills    Level: advanced
59081634712SRichard Tran Mills 
591f3db62a7SRichard Tran Mills .seealso: DMShellSetGlobalToLocal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell()
59281634712SRichard Tran Mills @*/
593a94b16f6SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter gtol)
59481634712SRichard Tran Mills {
59581634712SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
596d885d199SRichard Tran Mills   PetscErrorCode ierr;
59781634712SRichard Tran Mills 
598b300e4a8SRichard Tran Mills   PetscFunctionBegin;
599d885d199SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)gtol);CHKERRQ(ierr);
600d885d199SRichard Tran Mills   /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */
601d885d199SRichard Tran Mills   ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr);
60281634712SRichard Tran Mills   shell->gtol = gtol;
60381634712SRichard Tran Mills   PetscFunctionReturn(0);
60481634712SRichard Tran Mills }
60581634712SRichard Tran Mills 
606988ea7d6SRichard Tran Mills /*@
607988ea7d6SRichard Tran Mills    DMShellSetLocalToGlobalVecScatter - Sets a VecScatter context for local to global communication
608988ea7d6SRichard Tran Mills 
609988ea7d6SRichard Tran Mills    Logically Collective on DM
610988ea7d6SRichard Tran Mills 
611988ea7d6SRichard Tran Mills    Input Arguments
612988ea7d6SRichard Tran Mills +  dm - the shell DM
613988ea7d6SRichard Tran Mills -  ltog - the local to global VecScatter context
614988ea7d6SRichard Tran Mills 
615988ea7d6SRichard Tran Mills    Level: advanced
616988ea7d6SRichard Tran Mills 
617f3db62a7SRichard Tran Mills .seealso: DMShellSetLocalToGlobal(), DMLocalToGlobalBeginDefaultShell(), DMLocalToGlobalEndDefaultShell()
618988ea7d6SRichard Tran Mills @*/
619a94b16f6SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter ltog)
620988ea7d6SRichard Tran Mills {
621988ea7d6SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
622d885d199SRichard Tran Mills   PetscErrorCode ierr;
623988ea7d6SRichard Tran Mills 
624988ea7d6SRichard Tran Mills   PetscFunctionBegin;
625d885d199SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr);
626d885d199SRichard Tran Mills   /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */
627d885d199SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr);
628988ea7d6SRichard Tran Mills   shell->ltog = ltog;
629988ea7d6SRichard Tran Mills   PetscFunctionReturn(0);
630988ea7d6SRichard Tran Mills }
631988ea7d6SRichard Tran Mills 
632f3db62a7SRichard Tran Mills /*@
633f3db62a7SRichard Tran Mills    DMShellSetLocalToLocalVecScatter - Sets a VecScatter context for local to local communication
634f3db62a7SRichard Tran Mills 
635f3db62a7SRichard Tran Mills    Logically Collective on DM
636f3db62a7SRichard Tran Mills 
637f3db62a7SRichard Tran Mills    Input Arguments
638f3db62a7SRichard Tran Mills +  dm - the shell DM
639f3db62a7SRichard Tran Mills -  ltol - the local to local VecScatter context
640f3db62a7SRichard Tran Mills 
641f3db62a7SRichard Tran Mills    Level: advanced
642f3db62a7SRichard Tran Mills 
643f3db62a7SRichard Tran Mills .seealso: DMShellSetLocalToLocal(), DMLocalToLocalBeginDefaultShell(), DMLocalToLocalEndDefaultShell()
644f3db62a7SRichard Tran Mills @*/
645f3db62a7SRichard Tran Mills PetscErrorCode DMShellSetLocalToLocalVecScatter(DM dm, VecScatter ltol)
646f3db62a7SRichard Tran Mills {
647f3db62a7SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
648f3db62a7SRichard Tran Mills   PetscErrorCode ierr;
649f3db62a7SRichard Tran Mills 
650f3db62a7SRichard Tran Mills   PetscFunctionBegin;
651f3db62a7SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)ltol);CHKERRQ(ierr);
652f3db62a7SRichard Tran Mills   /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */
653f3db62a7SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltol);CHKERRQ(ierr);
654f3db62a7SRichard Tran Mills   shell->ltol = ltol;
655f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
656f3db62a7SRichard Tran Mills }
657f3db62a7SRichard Tran Mills 
6589bf9660cSLawrence Mitchell /*@C
6599bf9660cSLawrence Mitchell    DMShellSetCoarsen - Set the routine used to coarsen the shell DM
6609bf9660cSLawrence Mitchell 
6619bf9660cSLawrence Mitchell    Logically Collective on DM
6629bf9660cSLawrence Mitchell 
6639bf9660cSLawrence Mitchell    Input Arguments
6649bf9660cSLawrence Mitchell +  dm - the shell DM
6659bf9660cSLawrence Mitchell -  coarsen - the routine that coarsens the DM
6669bf9660cSLawrence Mitchell 
6679bf9660cSLawrence Mitchell    Level: advanced
6689bf9660cSLawrence Mitchell 
669bf890c61SBoris Boutkov .seealso: DMShellSetRefine(), DMCoarsen(), DMShellGetCoarsen(), DMShellSetContext(), DMShellGetContext()
6709bf9660cSLawrence Mitchell @*/
671f572501eSLawrence Mitchell PetscErrorCode DMShellSetCoarsen(DM dm, PetscErrorCode (*coarsen)(DM,MPI_Comm,DM*))
672f572501eSLawrence Mitchell {
673f572501eSLawrence Mitchell   PetscErrorCode ierr;
674f572501eSLawrence Mitchell   PetscBool      isshell;
675f572501eSLawrence Mitchell 
676f572501eSLawrence Mitchell   PetscFunctionBegin;
677f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
678f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
679f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
680f572501eSLawrence Mitchell   dm->ops->coarsen = coarsen;
681f572501eSLawrence Mitchell   PetscFunctionReturn(0);
682f572501eSLawrence Mitchell }
683f572501eSLawrence Mitchell 
6849bf9660cSLawrence Mitchell /*@C
6854363ddcaSBoris Boutkov    DMShellGetCoarsen - Get the routine used to coarsen the shell DM
6864363ddcaSBoris Boutkov 
6874363ddcaSBoris Boutkov    Logically Collective on DM
6884363ddcaSBoris Boutkov 
689*a4a986ddSBoris Boutkov    Input Argument:
6904363ddcaSBoris Boutkov .  dm - the shell DM
6914363ddcaSBoris Boutkov 
692*a4a986ddSBoris Boutkov    Output Argument:
6934363ddcaSBoris Boutkov .  coarsen - the routine that coarsens the DM
6944363ddcaSBoris Boutkov 
6954363ddcaSBoris Boutkov    Level: advanced
6964363ddcaSBoris Boutkov 
6974363ddcaSBoris Boutkov .seealso: DMShellSetCoarsen(), DMCoarsen(), DMShellSetRefine(), DMRefine()
6984363ddcaSBoris Boutkov @*/
6994363ddcaSBoris Boutkov PetscErrorCode DMShellGetCoarsen(DM dm, PetscErrorCode (**coarsen)(DM,MPI_Comm,DM*))
7004363ddcaSBoris Boutkov {
7014363ddcaSBoris Boutkov   PetscErrorCode ierr;
7024363ddcaSBoris Boutkov   PetscBool      isshell;
7034363ddcaSBoris Boutkov 
7044363ddcaSBoris Boutkov   PetscFunctionBegin;
7054363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7064363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
7074363ddcaSBoris Boutkov   if (!isshell) PetscFunctionReturn(0);
7084363ddcaSBoris Boutkov   *coarsen = dm->ops->coarsen;
7094363ddcaSBoris Boutkov   PetscFunctionReturn(0);
7104363ddcaSBoris Boutkov }
7114363ddcaSBoris Boutkov 
7124363ddcaSBoris Boutkov /*@C
7139bf9660cSLawrence Mitchell    DMShellSetRefine - Set the routine used to refine the shell DM
7149bf9660cSLawrence Mitchell 
7159bf9660cSLawrence Mitchell    Logically Collective on DM
7169bf9660cSLawrence Mitchell 
7179bf9660cSLawrence Mitchell    Input Arguments
7189bf9660cSLawrence Mitchell +  dm - the shell DM
7199bf9660cSLawrence Mitchell -  refine - the routine that refines the DM
7209bf9660cSLawrence Mitchell 
7219bf9660cSLawrence Mitchell    Level: advanced
7229bf9660cSLawrence Mitchell 
723bf890c61SBoris Boutkov .seealso: DMShellSetCoarsen(), DMRefine(), DMShellGetRefine(), DMShellSetContext(), DMShellGetContext()
7249bf9660cSLawrence Mitchell @*/
725f572501eSLawrence Mitchell PetscErrorCode DMShellSetRefine(DM dm, PetscErrorCode (*refine)(DM,MPI_Comm,DM*))
726f572501eSLawrence Mitchell {
727f572501eSLawrence Mitchell   PetscErrorCode ierr;
728f572501eSLawrence Mitchell   PetscBool      isshell;
729f572501eSLawrence Mitchell 
730f572501eSLawrence Mitchell   PetscFunctionBegin;
731f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
732f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
733f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
734f572501eSLawrence Mitchell   dm->ops->refine = refine;
735f572501eSLawrence Mitchell   PetscFunctionReturn(0);
736f572501eSLawrence Mitchell }
737f572501eSLawrence Mitchell 
7389bf9660cSLawrence Mitchell /*@C
7394363ddcaSBoris Boutkov    DMShellGetRefine - Get the routine used to refine the shell DM
7404363ddcaSBoris Boutkov 
7414363ddcaSBoris Boutkov    Logically Collective on DM
7424363ddcaSBoris Boutkov 
743*a4a986ddSBoris Boutkov    Input Argument:
7444363ddcaSBoris Boutkov .  dm - the shell DM
7454363ddcaSBoris Boutkov 
746*a4a986ddSBoris Boutkov    Output Argument:
7474363ddcaSBoris Boutkov .  refine - the routine that refines the DM
7484363ddcaSBoris Boutkov 
7494363ddcaSBoris Boutkov    Level: advanced
7504363ddcaSBoris Boutkov 
7514363ddcaSBoris Boutkov .seealso: DMShellSetCoarsen(), DMCoarsen(), DMShellSetRefine(), DMRefine()
7524363ddcaSBoris Boutkov @*/
7534363ddcaSBoris Boutkov PetscErrorCode DMShellGetRefine(DM dm, PetscErrorCode (**refine)(DM,MPI_Comm,DM*))
7544363ddcaSBoris Boutkov {
7554363ddcaSBoris Boutkov   PetscErrorCode ierr;
7564363ddcaSBoris Boutkov   PetscBool      isshell;
7574363ddcaSBoris Boutkov 
7584363ddcaSBoris Boutkov   PetscFunctionBegin;
7594363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7604363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
7614363ddcaSBoris Boutkov   if (!isshell) PetscFunctionReturn(0);
7624363ddcaSBoris Boutkov   *refine = dm->ops->refine;
7634363ddcaSBoris Boutkov   PetscFunctionReturn(0);
7644363ddcaSBoris Boutkov }
7654363ddcaSBoris Boutkov 
7664363ddcaSBoris Boutkov /*@C
7679bf9660cSLawrence Mitchell    DMShellSetCreateInterpolation - Set the routine used to create the interpolation operator
7689bf9660cSLawrence Mitchell 
7699bf9660cSLawrence Mitchell    Logically Collective on DM
7709bf9660cSLawrence Mitchell 
7719bf9660cSLawrence Mitchell    Input Arguments
7729bf9660cSLawrence Mitchell +  dm - the shell DM
7739bf9660cSLawrence Mitchell -  interp - the routine to create the interpolation
7749bf9660cSLawrence Mitchell 
7759bf9660cSLawrence Mitchell    Level: advanced
7769bf9660cSLawrence Mitchell 
777bf890c61SBoris Boutkov .seealso: DMShellSetCreateInjection(), DMCreateInterpolation(), DMShellGetCreateInterpolation(), DMShellSetCreateRestriction(), DMShellSetContext(), DMShellGetContext()
7789bf9660cSLawrence Mitchell @*/
779f572501eSLawrence Mitchell PetscErrorCode DMShellSetCreateInterpolation(DM dm, PetscErrorCode (*interp)(DM,DM,Mat*,Vec*))
780f572501eSLawrence Mitchell {
781f572501eSLawrence Mitchell   PetscErrorCode ierr;
782f572501eSLawrence Mitchell   PetscBool      isshell;
783f572501eSLawrence Mitchell 
784f572501eSLawrence Mitchell   PetscFunctionBegin;
785f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
786f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
787f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
788f572501eSLawrence Mitchell   dm->ops->createinterpolation = interp;
789f572501eSLawrence Mitchell   PetscFunctionReturn(0);
790f572501eSLawrence Mitchell }
791f572501eSLawrence Mitchell 
7923ad4599aSBarry Smith /*@C
7934363ddcaSBoris Boutkov    DMShellGetCreateInterpolation - Get the routine used to create the interpolation operator
7944363ddcaSBoris Boutkov 
7954363ddcaSBoris Boutkov    Logically Collective on DM
7964363ddcaSBoris Boutkov 
797*a4a986ddSBoris Boutkov    Input Argument:
7984363ddcaSBoris Boutkov +  dm - the shell DM
799*a4a986ddSBoris Boutkov 
800*a4a986ddSBoris Boutkov    Output Argument:
8014363ddcaSBoris Boutkov -  interp - the routine to create the interpolation
8024363ddcaSBoris Boutkov 
8034363ddcaSBoris Boutkov    Level: advanced
8044363ddcaSBoris Boutkov 
8054363ddcaSBoris Boutkov .seealso: DMShellGetCreateInjection(), DMCreateInterpolation(), DMShellGetCreateRestriction(), DMShellSetContext(), DMShellGetContext()
8064363ddcaSBoris Boutkov @*/
8074363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateInterpolation(DM dm, PetscErrorCode (**interp)(DM,DM,Mat*,Vec*))
8084363ddcaSBoris Boutkov {
8094363ddcaSBoris Boutkov   PetscErrorCode ierr;
8104363ddcaSBoris Boutkov   PetscBool      isshell;
8114363ddcaSBoris Boutkov 
8124363ddcaSBoris Boutkov   PetscFunctionBegin;
8134363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8144363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
8154363ddcaSBoris Boutkov   if (!isshell) PetscFunctionReturn(0);
8164363ddcaSBoris Boutkov   *interp = dm->ops->createinterpolation;
8174363ddcaSBoris Boutkov   PetscFunctionReturn(0);
8184363ddcaSBoris Boutkov }
8194363ddcaSBoris Boutkov 
8204363ddcaSBoris Boutkov /*@C
8213ad4599aSBarry Smith    DMShellSetCreateRestriction - Set the routine used to create the restriction operator
8223ad4599aSBarry Smith 
8233ad4599aSBarry Smith    Logically Collective on DM
8243ad4599aSBarry Smith 
8253ad4599aSBarry Smith    Input Arguments
8263ad4599aSBarry Smith +  dm - the shell DM
8273ad4599aSBarry Smith -  striction- the routine to create the restriction
8283ad4599aSBarry Smith 
8293ad4599aSBarry Smith    Level: advanced
8303ad4599aSBarry Smith 
831bf890c61SBoris Boutkov .seealso: DMShellSetCreateInjection(), DMCreateInterpolation(), DMShellGetCreateRestriction(), DMShellSetContext(), DMShellGetContext()
8323ad4599aSBarry Smith @*/
8333ad4599aSBarry Smith PetscErrorCode DMShellSetCreateRestriction(DM dm, PetscErrorCode (*restriction)(DM,DM,Mat*))
8343ad4599aSBarry Smith {
8353ad4599aSBarry Smith   PetscErrorCode ierr;
8363ad4599aSBarry Smith   PetscBool      isshell;
8373ad4599aSBarry Smith 
8383ad4599aSBarry Smith   PetscFunctionBegin;
8393ad4599aSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8403ad4599aSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
8413ad4599aSBarry Smith   if (!isshell) PetscFunctionReturn(0);
8423ad4599aSBarry Smith   dm->ops->createrestriction = restriction;
8433ad4599aSBarry Smith   PetscFunctionReturn(0);
8443ad4599aSBarry Smith }
8453ad4599aSBarry Smith 
8469bf9660cSLawrence Mitchell /*@C
8474363ddcaSBoris Boutkov    DMShellGetCreateRestriction - Get the routine used to create the restriction operator
8484363ddcaSBoris Boutkov 
8494363ddcaSBoris Boutkov    Logically Collective on DM
8504363ddcaSBoris Boutkov 
851*a4a986ddSBoris Boutkov    Input Argument:
8524363ddcaSBoris Boutkov +  dm - the shell DM
853*a4a986ddSBoris Boutkov 
854*a4a986ddSBoris Boutkov    Output Argument:
855*a4a986ddSBoris Boutkov -  restriction - the routine to create the restriction
8564363ddcaSBoris Boutkov 
8574363ddcaSBoris Boutkov    Level: advanced
8584363ddcaSBoris Boutkov 
8594363ddcaSBoris Boutkov .seealso: DMShellSetCreateInjection(), DMCreateInterpolation(), DMShellSetContext(), DMShellGetContext()
8604363ddcaSBoris Boutkov @*/
8614363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateRestriction(DM dm, PetscErrorCode (**restriction)(DM,DM,Mat*))
8624363ddcaSBoris Boutkov {
8634363ddcaSBoris Boutkov   PetscErrorCode ierr;
8644363ddcaSBoris Boutkov   PetscBool      isshell;
8654363ddcaSBoris Boutkov 
8664363ddcaSBoris Boutkov   PetscFunctionBegin;
8674363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8684363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
8694363ddcaSBoris Boutkov   if (!isshell) PetscFunctionReturn(0);
8704363ddcaSBoris Boutkov   *restriction = dm->ops->createrestriction;
8714363ddcaSBoris Boutkov   PetscFunctionReturn(0);
8724363ddcaSBoris Boutkov }
8734363ddcaSBoris Boutkov 
8744363ddcaSBoris Boutkov /*@C
8759bf9660cSLawrence Mitchell    DMShellSetCreateInjection - Set the routine used to create the injection operator
8769bf9660cSLawrence Mitchell 
8779bf9660cSLawrence Mitchell    Logically Collective on DM
8789bf9660cSLawrence Mitchell 
8799bf9660cSLawrence Mitchell    Input Arguments
8809bf9660cSLawrence Mitchell +  dm - the shell DM
8819bf9660cSLawrence Mitchell -  inject - the routine to create the injection
8829bf9660cSLawrence Mitchell 
8839bf9660cSLawrence Mitchell    Level: advanced
8849bf9660cSLawrence Mitchell 
885bf890c61SBoris Boutkov .seealso: DMShellSetCreateInterpolation(), DMCreateInjection(), DMShellGetCreateInjection(), DMShellSetContext(), DMShellGetContext()
8869bf9660cSLawrence Mitchell @*/
887f572501eSLawrence Mitchell PetscErrorCode DMShellSetCreateInjection(DM dm, PetscErrorCode (*inject)(DM,DM,Mat*))
888f572501eSLawrence Mitchell {
889f572501eSLawrence Mitchell   PetscErrorCode ierr;
890f572501eSLawrence Mitchell   PetscBool      isshell;
891f572501eSLawrence Mitchell 
892f572501eSLawrence Mitchell   PetscFunctionBegin;
893f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
894f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
895f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
896f572501eSLawrence Mitchell   dm->ops->getinjection = inject;
897f572501eSLawrence Mitchell   PetscFunctionReturn(0);
898f572501eSLawrence Mitchell }
899f572501eSLawrence Mitchell 
9004363ddcaSBoris Boutkov /*@C
9014363ddcaSBoris Boutkov    DMShellGetCreateInjection - Get the routine used to create the injection operator
9024363ddcaSBoris Boutkov 
9034363ddcaSBoris Boutkov    Logically Collective on DM
9044363ddcaSBoris Boutkov 
905*a4a986ddSBoris Boutkov    Input Argument:
9064363ddcaSBoris Boutkov +  dm - the shell DM
907*a4a986ddSBoris Boutkov 
908*a4a986ddSBoris Boutkov    Output Argument:
9094363ddcaSBoris Boutkov -  inject - the routine to create the injection
9104363ddcaSBoris Boutkov 
9114363ddcaSBoris Boutkov    Level: advanced
9124363ddcaSBoris Boutkov 
9134363ddcaSBoris Boutkov .seealso: DMShellGetCreateInterpolation(), DMCreateInjection(), DMShellSetContext(), DMShellGetContext()
9144363ddcaSBoris Boutkov @*/
9154363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateInjection(DM dm, PetscErrorCode (**inject)(DM,DM,Mat*))
9164363ddcaSBoris Boutkov {
9174363ddcaSBoris Boutkov   PetscErrorCode ierr;
9184363ddcaSBoris Boutkov   PetscBool      isshell;
9194363ddcaSBoris Boutkov 
9204363ddcaSBoris Boutkov   PetscFunctionBegin;
9214363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9224363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
9234363ddcaSBoris Boutkov   if (!isshell) PetscFunctionReturn(0);
9244363ddcaSBoris Boutkov   *inject = dm->ops->getinjection;
9254363ddcaSBoris Boutkov   PetscFunctionReturn(0);
9264363ddcaSBoris Boutkov }
9274363ddcaSBoris Boutkov 
928bf483bb6SLawrence Mitchell static PetscErrorCode DMHasCreateInjection_Shell(DM dm, PetscBool *flg)
929bf483bb6SLawrence Mitchell {
930bf483bb6SLawrence Mitchell   PetscErrorCode ierr;
931bf483bb6SLawrence Mitchell   PetscBool      isshell;
932bf483bb6SLawrence Mitchell 
933bf483bb6SLawrence Mitchell   PetscFunctionBegin;
934bf483bb6SLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
935bf483bb6SLawrence Mitchell   PetscValidPointer(flg,2);
936bf483bb6SLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
937bf483bb6SLawrence Mitchell   if (!isshell) {
938bf483bb6SLawrence Mitchell     *flg = PETSC_FALSE;
939bf483bb6SLawrence Mitchell   } else {
940bf483bb6SLawrence Mitchell     *flg = dm->ops->getinjection ? PETSC_TRUE : PETSC_FALSE;
941bf483bb6SLawrence Mitchell   }
942bf483bb6SLawrence Mitchell   PetscFunctionReturn(0);
943bf483bb6SLawrence Mitchell }
9449bf9660cSLawrence Mitchell /*@C
9459bf9660cSLawrence Mitchell    DMShellSetCreateFieldDecomposition - Set the routine used to create a decomposition of fields for the shell DM
9469bf9660cSLawrence Mitchell 
9479bf9660cSLawrence Mitchell    Logically Collective on DM
9489bf9660cSLawrence Mitchell 
9499bf9660cSLawrence Mitchell    Input Arguments
9509bf9660cSLawrence Mitchell +  dm - the shell DM
9519bf9660cSLawrence Mitchell -  decomp - the routine to create the decomposition
9529bf9660cSLawrence Mitchell 
9539bf9660cSLawrence Mitchell    Level: advanced
9549bf9660cSLawrence Mitchell 
955fef3a512SBarry Smith .seealso: DMCreateFieldDecomposition(), DMShellSetContext(), DMShellGetContext()
9569bf9660cSLawrence Mitchell @*/
9575e2259d5SLawrence Mitchell PetscErrorCode DMShellSetCreateFieldDecomposition(DM dm, PetscErrorCode (*decomp)(DM,PetscInt*,char***, IS**,DM**))
9585e2259d5SLawrence Mitchell {
9595e2259d5SLawrence Mitchell   PetscErrorCode ierr;
9605e2259d5SLawrence Mitchell   PetscBool      isshell;
9615e2259d5SLawrence Mitchell 
9625e2259d5SLawrence Mitchell   PetscFunctionBegin;
9635e2259d5SLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9645e2259d5SLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
9655e2259d5SLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
9665e2259d5SLawrence Mitchell   dm->ops->createfielddecomposition = decomp;
9675e2259d5SLawrence Mitchell   PetscFunctionReturn(0);
9685e2259d5SLawrence Mitchell }
9695e2259d5SLawrence Mitchell 
970c00061e5SLawrence Mitchell /*@C
971e734121bSPatrick Farrell    DMShellSetCreateDomainDecomposition - Set the routine used to create a domain decomposition for the shell DM
972e734121bSPatrick Farrell 
973e734121bSPatrick Farrell    Logically Collective on DM
974e734121bSPatrick Farrell 
975e734121bSPatrick Farrell    Input Arguments
976e734121bSPatrick Farrell +  dm - the shell DM
977e734121bSPatrick Farrell -  decomp - the routine to create the decomposition
978e734121bSPatrick Farrell 
979e734121bSPatrick Farrell    Level: advanced
980e734121bSPatrick Farrell 
981e734121bSPatrick Farrell .seealso: DMCreateDomainDecomposition(), DMShellSetContext(), DMShellGetContext()
982e734121bSPatrick Farrell @*/
983e734121bSPatrick Farrell PetscErrorCode DMShellSetCreateDomainDecomposition(DM dm, PetscErrorCode (*decomp)(DM,PetscInt*,char***, IS**,IS**,DM**))
984e734121bSPatrick Farrell {
985e734121bSPatrick Farrell   PetscErrorCode ierr;
986e734121bSPatrick Farrell   PetscBool      isshell;
987e734121bSPatrick Farrell 
988e734121bSPatrick Farrell   PetscFunctionBegin;
989e734121bSPatrick Farrell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
990e734121bSPatrick Farrell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
991e734121bSPatrick Farrell   if (!isshell) PetscFunctionReturn(0);
992e734121bSPatrick Farrell   dm->ops->createdomaindecomposition = decomp;
993e734121bSPatrick Farrell   PetscFunctionReturn(0);
994e734121bSPatrick Farrell }
995e734121bSPatrick Farrell 
996e734121bSPatrick Farrell /*@C
997eef9d6cdSPatrick Farrell    DMShellSetCreateDomainDecompositionScatters - Set the routine used to create the scatter contexts for domain decomposition with a shell DM
998eef9d6cdSPatrick Farrell 
999eef9d6cdSPatrick Farrell    Logically Collective on DM
1000eef9d6cdSPatrick Farrell 
1001eef9d6cdSPatrick Farrell    Input Arguments
1002eef9d6cdSPatrick Farrell +  dm - the shell DM
1003eef9d6cdSPatrick Farrell -  scatter - the routine to create the scatters
1004eef9d6cdSPatrick Farrell 
1005eef9d6cdSPatrick Farrell    Level: advanced
1006eef9d6cdSPatrick Farrell 
1007448b6425SPatrick Farrell .seealso: DMCreateDomainDecompositionScatters(), DMShellSetContext(), DMShellGetContext()
1008eef9d6cdSPatrick Farrell @*/
1009eef9d6cdSPatrick Farrell PetscErrorCode DMShellSetCreateDomainDecompositionScatters(DM dm, PetscErrorCode (*scatter)(DM,PetscInt,DM*,VecScatter**,VecScatter**,VecScatter**))
1010eef9d6cdSPatrick Farrell {
1011eef9d6cdSPatrick Farrell   PetscErrorCode ierr;
1012eef9d6cdSPatrick Farrell   PetscBool      isshell;
1013eef9d6cdSPatrick Farrell 
1014eef9d6cdSPatrick Farrell   PetscFunctionBegin;
1015eef9d6cdSPatrick Farrell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1016eef9d6cdSPatrick Farrell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
1017eef9d6cdSPatrick Farrell   if (!isshell) PetscFunctionReturn(0);
1018eef9d6cdSPatrick Farrell   dm->ops->createddscatters = scatter;
1019eef9d6cdSPatrick Farrell   PetscFunctionReturn(0);
1020eef9d6cdSPatrick Farrell }
1021eef9d6cdSPatrick Farrell 
1022eef9d6cdSPatrick Farrell /*@C
1023c00061e5SLawrence Mitchell    DMShellSetCreateSubDM - Set the routine used to create a sub DM from the shell DM
1024c00061e5SLawrence Mitchell 
1025c00061e5SLawrence Mitchell    Logically Collective on DM
1026c00061e5SLawrence Mitchell 
1027c00061e5SLawrence Mitchell    Input Arguments
1028c00061e5SLawrence Mitchell +  dm - the shell DM
1029c00061e5SLawrence Mitchell -  subdm - the routine to create the decomposition
1030c00061e5SLawrence Mitchell 
1031c00061e5SLawrence Mitchell    Level: advanced
1032c00061e5SLawrence Mitchell 
1033bf890c61SBoris Boutkov .seealso: DMCreateSubDM(), DMShellGetCreateSubDM(), DMShellSetContext(), DMShellGetContext()
1034c00061e5SLawrence Mitchell @*/
1035276c5506SMatthew G. Knepley PetscErrorCode DMShellSetCreateSubDM(DM dm, PetscErrorCode (*subdm)(DM,PetscInt,const PetscInt[],IS*,DM*))
1036c00061e5SLawrence Mitchell {
1037c00061e5SLawrence Mitchell   PetscErrorCode ierr;
1038c00061e5SLawrence Mitchell   PetscBool      isshell;
1039c00061e5SLawrence Mitchell 
1040c00061e5SLawrence Mitchell   PetscFunctionBegin;
1041c00061e5SLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1042c00061e5SLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
1043c00061e5SLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
1044c00061e5SLawrence Mitchell   dm->ops->createsubdm = subdm;
1045c00061e5SLawrence Mitchell   PetscFunctionReturn(0);
1046c00061e5SLawrence Mitchell }
1047c00061e5SLawrence Mitchell 
10484363ddcaSBoris Boutkov /*@C
10494363ddcaSBoris Boutkov    DMShellGetCreateSubDM - Get the routine used to create a sub DM from the shell DM
10504363ddcaSBoris Boutkov 
10514363ddcaSBoris Boutkov    Logically Collective on DM
10524363ddcaSBoris Boutkov 
1053*a4a986ddSBoris Boutkov    Input Argument:
10544363ddcaSBoris Boutkov +  dm - the shell DM
1055*a4a986ddSBoris Boutkov 
1056*a4a986ddSBoris Boutkov    Output Argument:
10574363ddcaSBoris Boutkov -  subdm - the routine to create the decomposition
10584363ddcaSBoris Boutkov 
10594363ddcaSBoris Boutkov    Level: advanced
10604363ddcaSBoris Boutkov 
10614363ddcaSBoris Boutkov .seealso: DMCreateSubDM(), DMShellSetCreateSubDM(), DMShellSetContext(), DMShellGetContext()
10624363ddcaSBoris Boutkov @*/
10634363ddcaSBoris Boutkov PetscErrorCode DMShellGetCreateSubDM(DM dm, PetscErrorCode (**subdm)(DM,PetscInt,const PetscInt[],IS*,DM*))
10644363ddcaSBoris Boutkov {
10654363ddcaSBoris Boutkov   PetscErrorCode ierr;
10664363ddcaSBoris Boutkov   PetscBool      isshell;
10674363ddcaSBoris Boutkov 
10684363ddcaSBoris Boutkov   PetscFunctionBegin;
10694363ddcaSBoris Boutkov   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10704363ddcaSBoris Boutkov   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
10714363ddcaSBoris Boutkov   if (!isshell) PetscFunctionReturn(0);
10724363ddcaSBoris Boutkov   *subdm = dm->ops->createsubdm;
10734363ddcaSBoris Boutkov   PetscFunctionReturn(0);
10744363ddcaSBoris Boutkov }
10754363ddcaSBoris Boutkov 
1076fe1899a2SJed Brown static PetscErrorCode DMDestroy_Shell(DM dm)
1077fe1899a2SJed Brown {
1078fe1899a2SJed Brown   PetscErrorCode ierr;
1079fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
1080fe1899a2SJed Brown 
1081fe1899a2SJed Brown   PetscFunctionBegin;
1082fe1899a2SJed Brown   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
1083fe1899a2SJed Brown   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
1084dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
1085a94b16f6SRichard Tran Mills   ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr);
1086a94b16f6SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr);
1087294a6417SLawrence Mitchell   ierr = VecScatterDestroy(&shell->ltol);CHKERRQ(ierr);
10887b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
10897b6ad80cSMatthew G Knepley   ierr = PetscFree(shell);CHKERRQ(ierr);
1090fe1899a2SJed Brown   PetscFunctionReturn(0);
1091fe1899a2SJed Brown }
1092fe1899a2SJed Brown 
10932d53ad75SBarry Smith static PetscErrorCode DMView_Shell(DM dm,PetscViewer v)
10942d53ad75SBarry Smith {
10952d53ad75SBarry Smith   PetscErrorCode ierr;
10962d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
10972d53ad75SBarry Smith 
10982d53ad75SBarry Smith   PetscFunctionBegin;
10992d53ad75SBarry Smith   ierr = VecView(shell->Xglobal,v);CHKERRQ(ierr);
11002d53ad75SBarry Smith   PetscFunctionReturn(0);
11012d53ad75SBarry Smith }
11022d53ad75SBarry Smith 
11032d53ad75SBarry Smith static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v)
11042d53ad75SBarry Smith {
11052d53ad75SBarry Smith   PetscErrorCode ierr;
11062d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
11072d53ad75SBarry Smith 
11082d53ad75SBarry Smith   PetscFunctionBegin;
1109ce94432eSBarry Smith   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&shell->Xglobal);CHKERRQ(ierr);
11102d53ad75SBarry Smith   ierr = VecLoad(shell->Xglobal,v);CHKERRQ(ierr);
11112d53ad75SBarry Smith   PetscFunctionReturn(0);
11122d53ad75SBarry Smith }
1113fe1899a2SJed Brown 
1114276c5506SMatthew G. Knepley PetscErrorCode DMCreateSubDM_Shell(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
11156e44b4cfSMatthew G. Knepley {
11166e44b4cfSMatthew G. Knepley   PetscErrorCode ierr;
11176e44b4cfSMatthew G. Knepley 
11186e44b4cfSMatthew G. Knepley   PetscFunctionBegin;
11196e44b4cfSMatthew G. Knepley   if (subdm) {ierr = DMShellCreate(PetscObjectComm((PetscObject) dm), subdm);CHKERRQ(ierr);}
1120792b654fSMatthew G. Knepley   ierr = DMCreateSectionSubDM(dm, numFields, fields, is, subdm);CHKERRQ(ierr);
11216e44b4cfSMatthew G. Knepley   PetscFunctionReturn(0);
11226e44b4cfSMatthew G. Knepley }
11236e44b4cfSMatthew G. Knepley 
11248cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm)
1125fe1899a2SJed Brown {
1126fe1899a2SJed Brown   PetscErrorCode ierr;
1127fe1899a2SJed Brown   DM_Shell       *shell;
1128fe1899a2SJed Brown 
1129fe1899a2SJed Brown   PetscFunctionBegin;
1130b00a9115SJed Brown   ierr     = PetscNewLog(dm,&shell);CHKERRQ(ierr);
11318c87107bSJed Brown   dm->data = shell;
1132fe1899a2SJed Brown 
11338c87107bSJed Brown   ierr = PetscObjectChangeTypeName((PetscObject)dm,DMSHELL);CHKERRQ(ierr);
11348865f1eaSKarl Rupp 
11358c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
11368c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
1137dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
11388c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
11392d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
11402d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
11417a108d1dSBarry Smith   dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell;
11427a108d1dSBarry Smith   dm->ops->globaltolocalend   = DMGlobalToLocalEndDefaultShell;
114355daaa54SRichard Tran Mills   dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell;
114455daaa54SRichard Tran Mills   dm->ops->localtoglobalend   = DMLocalToGlobalEndDefaultShell;
114563731094SRichard Tran Mills   dm->ops->localtolocalbegin  = DMLocalToLocalBeginDefaultShell;
114663731094SRichard Tran Mills   dm->ops->localtolocalend    = DMLocalToLocalEndDefaultShell;
11476e44b4cfSMatthew G. Knepley   dm->ops->createsubdm        = DMCreateSubDM_Shell;
1148bf483bb6SLawrence Mitchell   dm->ops->hascreateinjection = DMHasCreateInjection_Shell;
1149fe1899a2SJed Brown   PetscFunctionReturn(0);
1150fe1899a2SJed Brown }
1151fe1899a2SJed Brown 
1152fe1899a2SJed Brown /*@
1153fe1899a2SJed Brown     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
1154fe1899a2SJed Brown 
1155fe1899a2SJed Brown     Collective on MPI_Comm
1156fe1899a2SJed Brown 
1157fe1899a2SJed Brown     Input Parameter:
1158fe1899a2SJed Brown .   comm - the processors that will share the global vector
1159fe1899a2SJed Brown 
1160fe1899a2SJed Brown     Output Parameters:
1161fe1899a2SJed Brown .   shell - the shell DM
1162fe1899a2SJed Brown 
1163fe1899a2SJed Brown     Level: advanced
1164fe1899a2SJed Brown 
1165fef3a512SBarry Smith .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateLocalVector(), DMShellSetContext(), DMShellGetContext()
1166fe1899a2SJed Brown @*/
1167fe1899a2SJed Brown PetscErrorCode  DMShellCreate(MPI_Comm comm,DM *dm)
1168fe1899a2SJed Brown {
1169fe1899a2SJed Brown   PetscErrorCode ierr;
1170fe1899a2SJed Brown 
1171fe1899a2SJed Brown   PetscFunctionBegin;
1172fe1899a2SJed Brown   PetscValidPointer(dm,2);
1173fe1899a2SJed Brown   ierr = DMCreate(comm,dm);CHKERRQ(ierr);
1174fe1899a2SJed Brown   ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr);
117581a566bfSMatthew G. Knepley   ierr = DMSetUp(*dm);CHKERRQ(ierr);
1176fe1899a2SJed Brown   PetscFunctionReturn(0);
1177fe1899a2SJed Brown }
1178