xref: /petsc/src/dm/impls/shell/dmshell.c (revision 3ad4599a42e9c85bdaf3228acb15d805000068aa)
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;
12fe1899a2SJed Brown } DM_Shell;
13fe1899a2SJed Brown 
14fe1899a2SJed Brown #undef __FUNCT__
157a108d1dSBarry Smith #define __FUNCT__ "DMGlobalToLocalBeginDefaultShell"
167a108d1dSBarry Smith /*@
177a108d1dSBarry Smith    DMGlobalToLocalBeginDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to begin a global to local scatter
188d359177SBarry Smith    Collective
198d359177SBarry Smith 
208d359177SBarry Smith    Input Arguments:
218d359177SBarry Smith +  dm - shell DM
228d359177SBarry Smith .  g - global vector
238d359177SBarry Smith .  mode - InsertMode
248d359177SBarry Smith -  l - local vector
258d359177SBarry Smith 
267a108d1dSBarry Smith    Level: advanced
278d359177SBarry Smith 
287a108d1dSBarry 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.
297a108d1dSBarry Smith 
307a108d1dSBarry Smith .seealso: DMGlobalToLocalEndDefaultShell()
318d359177SBarry Smith @*/
327a108d1dSBarry Smith PetscErrorCode DMGlobalToLocalBeginDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
338d359177SBarry Smith {
348d359177SBarry Smith   PetscErrorCode ierr;
358d359177SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
368d359177SBarry Smith 
378d359177SBarry Smith   PetscFunctionBegin;
387a108d1dSBarry Smith   if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
39a94b16f6SRichard Tran Mills   ierr = VecScatterBegin(shell->gtol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
408d359177SBarry Smith   PetscFunctionReturn(0);
418d359177SBarry Smith }
428d359177SBarry Smith 
438d359177SBarry Smith #undef __FUNCT__
447a108d1dSBarry Smith #define __FUNCT__ "DMGlobalToLocalEndDefaultShell"
457a108d1dSBarry Smith /*@
467a108d1dSBarry Smith    DMGlobalToLocalEndDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to end a global to local scatter
478d359177SBarry Smith    Collective
488d359177SBarry Smith 
498d359177SBarry Smith    Input Arguments:
508d359177SBarry Smith +  dm - shell DM
518d359177SBarry Smith .  g - global vector
528d359177SBarry Smith .  mode - InsertMode
538d359177SBarry Smith -  l - local vector
548d359177SBarry Smith 
557a108d1dSBarry Smith    Level: advanced
568d359177SBarry Smith 
577a108d1dSBarry Smith .seealso: DMGlobalToLocalBeginDefaultShell()
588d359177SBarry Smith @*/
597a108d1dSBarry Smith PetscErrorCode DMGlobalToLocalEndDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
608d359177SBarry Smith {
618d359177SBarry Smith   PetscErrorCode ierr;
628d359177SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
638d359177SBarry Smith 
648d359177SBarry Smith   PetscFunctionBegin;
657a108d1dSBarry Smith    if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
66a94b16f6SRichard Tran Mills   ierr = VecScatterEnd(shell->gtol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
678d359177SBarry Smith   PetscFunctionReturn(0);
688d359177SBarry Smith }
698d359177SBarry Smith 
708d359177SBarry Smith #undef __FUNCT__
71c5076b69SRichard Tran Mills #define __FUNCT__ "DMLocalToGlobalBeginDefaultShell"
72c5076b69SRichard Tran Mills /*@
73c5076b69SRichard Tran Mills    DMLocalToGlobalBeginDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to begin a local to global scatter
74c5076b69SRichard Tran Mills    Collective
75c5076b69SRichard Tran Mills 
76c5076b69SRichard Tran Mills    Input Arguments:
77c5076b69SRichard Tran Mills +  dm - shell DM
78c5076b69SRichard Tran Mills .  l - local vector
79c5076b69SRichard Tran Mills .  mode - InsertMode
80c5076b69SRichard Tran Mills -  g - global vector
81c5076b69SRichard Tran Mills 
82c5076b69SRichard Tran Mills    Level: advanced
83c5076b69SRichard Tran Mills 
84c5076b69SRichard 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.
85c5076b69SRichard Tran Mills 
86c5076b69SRichard Tran Mills .seealso: DMLocalToGlobalEndDefaultShell()
87c5076b69SRichard Tran Mills @*/
88c5076b69SRichard Tran Mills PetscErrorCode DMLocalToGlobalBeginDefaultShell(DM dm,Vec l,InsertMode mode,Vec g)
89c5076b69SRichard Tran Mills {
90c5076b69SRichard Tran Mills   PetscErrorCode ierr;
91c5076b69SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
92c5076b69SRichard Tran Mills 
93c5076b69SRichard Tran Mills   PetscFunctionBegin;
94c5076b69SRichard Tran Mills   if (!shell->ltog) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
95a94b16f6SRichard Tran Mills   ierr = VecScatterBegin(shell->ltog,l,g,mode,SCATTER_FORWARD);CHKERRQ(ierr);
96c5076b69SRichard Tran Mills   PetscFunctionReturn(0);
97c5076b69SRichard Tran Mills }
98c5076b69SRichard Tran Mills 
99c5076b69SRichard Tran Mills #undef __FUNCT__
100c5076b69SRichard Tran Mills #define __FUNCT__ "DMLocalToGlobalEndDefaultShell"
101c5076b69SRichard Tran Mills /*@
102c5076b69SRichard Tran Mills    DMLocalToGlobalEndDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to end a local to global scatter
103c5076b69SRichard Tran Mills    Collective
104c5076b69SRichard Tran Mills 
105c5076b69SRichard Tran Mills    Input Arguments:
106c5076b69SRichard Tran Mills +  dm - shell DM
107c5076b69SRichard Tran Mills .  l - local vector
108c5076b69SRichard Tran Mills .  mode - InsertMode
109c5076b69SRichard Tran Mills -  g - global vector
110c5076b69SRichard Tran Mills 
111c5076b69SRichard Tran Mills    Level: advanced
112c5076b69SRichard Tran Mills 
113c5076b69SRichard Tran Mills .seealso: DMLocalToGlobalBeginDefaultShell()
114c5076b69SRichard Tran Mills @*/
115c5076b69SRichard Tran Mills PetscErrorCode DMLocalToGlobalEndDefaultShell(DM dm,Vec l,InsertMode mode,Vec g)
116c5076b69SRichard Tran Mills {
117c5076b69SRichard Tran Mills   PetscErrorCode ierr;
118c5076b69SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
119c5076b69SRichard Tran Mills 
120c5076b69SRichard Tran Mills   PetscFunctionBegin;
121c5076b69SRichard Tran Mills    if (!shell->ltog) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
122a94b16f6SRichard Tran Mills   ierr = VecScatterEnd(shell->ltog,l,g,mode,SCATTER_FORWARD);CHKERRQ(ierr);
123c5076b69SRichard Tran Mills   PetscFunctionReturn(0);
124c5076b69SRichard Tran Mills }
125c5076b69SRichard Tran Mills 
126f3db62a7SRichard Tran Mills #undef __FUNCT__
127f3db62a7SRichard Tran Mills #define __FUNCT__ "DMLocalToLocalBeginDefaultShell"
128f3db62a7SRichard Tran Mills /*@
129f3db62a7SRichard Tran Mills    DMLocalToLocalBeginDefaultShell - Uses the LocalToLocal VecScatter context set by the user to begin a local to local scatter
130f3db62a7SRichard Tran Mills    Collective
131f3db62a7SRichard Tran Mills 
132f3db62a7SRichard Tran Mills    Input Arguments:
133f3db62a7SRichard Tran Mills +  dm - shell DM
134f3db62a7SRichard Tran Mills .  g - the original local vector
135f3db62a7SRichard Tran Mills -  mode - InsertMode
136f3db62a7SRichard Tran Mills 
137f3db62a7SRichard Tran Mills    Output Parameter:
138f3db62a7SRichard Tran Mills .  l  - the local vector with correct ghost values
139f3db62a7SRichard Tran Mills 
140f3db62a7SRichard Tran Mills    Level: advanced
141f3db62a7SRichard Tran Mills 
142f3db62a7SRichard 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.
143f3db62a7SRichard Tran Mills 
144f3db62a7SRichard Tran Mills .seealso: DMLocalToLocalEndDefaultShell()
145f3db62a7SRichard Tran Mills @*/
146f3db62a7SRichard Tran Mills PetscErrorCode DMLocalToLocalBeginDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
147f3db62a7SRichard Tran Mills {
148f3db62a7SRichard Tran Mills   PetscErrorCode ierr;
149f3db62a7SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
150f3db62a7SRichard Tran Mills 
151f3db62a7SRichard Tran Mills   PetscFunctionBegin;
152f3db62a7SRichard Tran Mills   if (!shell->ltol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToLocalVecScatter()");
153f3db62a7SRichard Tran Mills   ierr = VecScatterBegin(shell->ltol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
154f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
155f3db62a7SRichard Tran Mills }
156f3db62a7SRichard Tran Mills 
157f3db62a7SRichard Tran Mills #undef __FUNCT__
158f3db62a7SRichard Tran Mills #define __FUNCT__ "DMLocalToLocalEndDefaultShell"
159f3db62a7SRichard Tran Mills /*@
160f3db62a7SRichard Tran Mills    DMLocalToLocalEndDefaultShell - Uses the LocalToLocal VecScatter context set by the user to end a local to local scatter
161f3db62a7SRichard Tran Mills    Collective
162f3db62a7SRichard Tran Mills 
163f3db62a7SRichard Tran Mills    Input Arguments:
164f3db62a7SRichard Tran Mills +  dm - shell DM
165f3db62a7SRichard Tran Mills .  g - the original local vector
166f3db62a7SRichard Tran Mills -  mode - InsertMode
167f3db62a7SRichard Tran Mills 
168f3db62a7SRichard Tran Mills    Output Parameter:
169f3db62a7SRichard Tran Mills .  l  - the local vector with correct ghost values
170f3db62a7SRichard Tran Mills 
171f3db62a7SRichard Tran Mills    Level: advanced
172f3db62a7SRichard Tran Mills 
173f3db62a7SRichard Tran Mills .seealso: DMLocalToLocalBeginDefaultShell()
174f3db62a7SRichard Tran Mills @*/
175f3db62a7SRichard Tran Mills PetscErrorCode DMLocalToLocalEndDefaultShell(DM dm,Vec g,InsertMode mode,Vec l)
176f3db62a7SRichard Tran Mills {
177f3db62a7SRichard Tran Mills   PetscErrorCode ierr;
178f3db62a7SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
179f3db62a7SRichard Tran Mills 
180f3db62a7SRichard Tran Mills   PetscFunctionBegin;
181f3db62a7SRichard Tran Mills    if (!shell->ltol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
182f3db62a7SRichard Tran Mills   ierr = VecScatterEnd(shell->ltol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
183f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
184f3db62a7SRichard Tran Mills }
185c5076b69SRichard Tran Mills 
186c5076b69SRichard Tran Mills #undef __FUNCT__
187fe1899a2SJed Brown #define __FUNCT__ "DMCreateMatrix_Shell"
188b412c318SBarry Smith static PetscErrorCode DMCreateMatrix_Shell(DM dm,Mat *J)
189fe1899a2SJed Brown {
190fe1899a2SJed Brown   PetscErrorCode ierr;
191fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
192fe1899a2SJed Brown   Mat            A;
193fe1899a2SJed Brown 
194fe1899a2SJed Brown   PetscFunctionBegin;
195fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
196fe1899a2SJed Brown   PetscValidPointer(J,3);
1977bde9f88SJed Brown   if (!shell->A) {
1987bde9f88SJed Brown     if (shell->Xglobal) {
1997bde9f88SJed Brown       PetscInt m,M;
200955c1f14SBarry Smith       ierr = PetscInfo(dm,"Naively creating matrix using global vector distribution without preallocation\n");CHKERRQ(ierr);
2017bde9f88SJed Brown       ierr = VecGetSize(shell->Xglobal,&M);CHKERRQ(ierr);
2027bde9f88SJed Brown       ierr = VecGetLocalSize(shell->Xglobal,&m);CHKERRQ(ierr);
203ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)dm),&shell->A);CHKERRQ(ierr);
2047bde9f88SJed Brown       ierr = MatSetSizes(shell->A,m,m,M,M);CHKERRQ(ierr);
205b412c318SBarry Smith       ierr = MatSetType(shell->A,dm->mattype);CHKERRQ(ierr);
2067bde9f88SJed Brown       ierr = MatSetUp(shell->A);CHKERRQ(ierr);
207ce94432eSBarry Smith     } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector");
2087bde9f88SJed Brown   }
209fe1899a2SJed Brown   A = shell->A;
210ad6bc421SBarry Smith   /* the check below is tacky and incomplete */
211b412c318SBarry Smith   if (dm->mattype) {
212ad6bc421SBarry Smith     PetscBool flg,aij,seqaij,mpiaij;
213b412c318SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,dm->mattype,&flg);CHKERRQ(ierr);
214ad6bc421SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
215ad6bc421SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&mpiaij);CHKERRQ(ierr);
216b412c318SBarry Smith     ierr = PetscStrcmp(dm->mattype,MATAIJ,&aij);CHKERRQ(ierr);
217ad6bc421SBarry Smith     if (!flg) {
218b412c318SBarry 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);
219ad6bc421SBarry Smith     }
220fe1899a2SJed Brown   }
221fe1899a2SJed Brown   if (((PetscObject)A)->refct < 2) { /* We have an exclusive reference so we can give it out */
222fe1899a2SJed Brown     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
223fe1899a2SJed Brown     ierr = MatZeroEntries(A);CHKERRQ(ierr);
224fe1899a2SJed Brown     *J   = A;
225fe1899a2SJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
226fe1899a2SJed Brown     ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J);CHKERRQ(ierr);
227fe1899a2SJed Brown     ierr = MatZeroEntries(*J);CHKERRQ(ierr);
228fe1899a2SJed Brown   }
229fe1899a2SJed Brown   PetscFunctionReturn(0);
230fe1899a2SJed Brown }
231fe1899a2SJed Brown 
232fe1899a2SJed Brown #undef __FUNCT__
233fe1899a2SJed Brown #define __FUNCT__ "DMCreateGlobalVector_Shell"
234fe1899a2SJed Brown PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec)
235fe1899a2SJed Brown {
236fe1899a2SJed Brown   PetscErrorCode ierr;
237fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
238fe1899a2SJed Brown   Vec            X;
239fe1899a2SJed Brown 
240fe1899a2SJed Brown   PetscFunctionBegin;
241fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
242fe1899a2SJed Brown   PetscValidPointer(gvec,2);
243fe1899a2SJed Brown   *gvec = 0;
244fe1899a2SJed Brown   X     = shell->Xglobal;
245ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
246fe1899a2SJed Brown   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
247fe1899a2SJed Brown     ierr  = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
248fe1899a2SJed Brown     ierr  = VecZeroEntries(X);CHKERRQ(ierr);
249fe1899a2SJed Brown     *gvec = X;
250fe1899a2SJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
251fe1899a2SJed Brown     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
252fe1899a2SJed Brown     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
253fe1899a2SJed Brown   }
254c688c046SMatthew G Knepley   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
255fe1899a2SJed Brown   PetscFunctionReturn(0);
256fe1899a2SJed Brown }
257fe1899a2SJed Brown 
258fe1899a2SJed Brown #undef __FUNCT__
259dc43b69eSJed Brown #define __FUNCT__ "DMCreateLocalVector_Shell"
260dc43b69eSJed Brown PetscErrorCode DMCreateLocalVector_Shell(DM dm,Vec *gvec)
261dc43b69eSJed Brown {
262dc43b69eSJed Brown   PetscErrorCode ierr;
263dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
264dc43b69eSJed Brown   Vec            X;
265dc43b69eSJed Brown 
266dc43b69eSJed Brown   PetscFunctionBegin;
267dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
268dc43b69eSJed Brown   PetscValidPointer(gvec,2);
269dc43b69eSJed Brown   *gvec = 0;
270dc43b69eSJed Brown   X     = shell->Xlocal;
271ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()");
272dc43b69eSJed Brown   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
273dc43b69eSJed Brown     ierr  = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
274dc43b69eSJed Brown     ierr  = VecZeroEntries(X);CHKERRQ(ierr);
275dc43b69eSJed Brown     *gvec = X;
276dc43b69eSJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
277dc43b69eSJed Brown     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
278dc43b69eSJed Brown     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
279dc43b69eSJed Brown   }
2806e4cbd8bSMark F. Adams   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
281dc43b69eSJed Brown   PetscFunctionReturn(0);
282dc43b69eSJed Brown }
283dc43b69eSJed Brown 
284dc43b69eSJed Brown #undef __FUNCT__
285fe1899a2SJed Brown #define __FUNCT__ "DMShellSetMatrix"
286fe1899a2SJed Brown /*@
287fe1899a2SJed Brown    DMShellSetMatrix - sets a template matrix associated with the DMShell
288fe1899a2SJed Brown 
289fe1899a2SJed Brown    Collective
290fe1899a2SJed Brown 
291fe1899a2SJed Brown    Input Arguments:
292fe1899a2SJed Brown +  dm - shell DM
293fe1899a2SJed Brown -  J - template matrix
294fe1899a2SJed Brown 
295fe1899a2SJed Brown    Level: advanced
296fe1899a2SJed Brown 
297fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetCreateMatrix()
298fe1899a2SJed Brown @*/
299fe1899a2SJed Brown PetscErrorCode DMShellSetMatrix(DM dm,Mat J)
300fe1899a2SJed Brown {
301fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
302fe1899a2SJed Brown   PetscErrorCode ierr;
3038c87107bSJed Brown   PetscBool      isshell;
304fe1899a2SJed Brown 
305fe1899a2SJed Brown   PetscFunctionBegin;
3068c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3078c87107bSJed Brown   PetscValidHeaderSpecific(J,MAT_CLASSID,2);
308251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
3098c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
310fe1899a2SJed Brown   ierr     = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
311fe1899a2SJed Brown   ierr     = MatDestroy(&shell->A);CHKERRQ(ierr);
312fe1899a2SJed Brown   shell->A = J;
313fe1899a2SJed Brown   PetscFunctionReturn(0);
314fe1899a2SJed Brown }
315fe1899a2SJed Brown 
316fe1899a2SJed Brown #undef __FUNCT__
317fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateMatrix"
318fe1899a2SJed Brown /*@C
319fe1899a2SJed Brown    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM
320fe1899a2SJed Brown 
321fe1899a2SJed Brown    Logically Collective on DM
322fe1899a2SJed Brown 
323fe1899a2SJed Brown    Input Arguments:
324fe1899a2SJed Brown +  dm - the shell DM
325fe1899a2SJed Brown -  func - the function to create a matrix
326fe1899a2SJed Brown 
327fe1899a2SJed Brown    Level: advanced
328fe1899a2SJed Brown 
329fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetMatrix()
330fe1899a2SJed Brown @*/
331b412c318SBarry Smith PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,Mat*))
332fe1899a2SJed Brown {
333fe1899a2SJed Brown 
334fe1899a2SJed Brown   PetscFunctionBegin;
335fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
336fe1899a2SJed Brown   dm->ops->creatematrix = func;
337fe1899a2SJed Brown   PetscFunctionReturn(0);
338fe1899a2SJed Brown }
339fe1899a2SJed Brown 
340fe1899a2SJed Brown #undef __FUNCT__
341fe1899a2SJed Brown #define __FUNCT__ "DMShellSetGlobalVector"
342fe1899a2SJed Brown /*@
343fe1899a2SJed Brown    DMShellSetGlobalVector - sets a template global vector associated with the DMShell
344fe1899a2SJed Brown 
345fe1899a2SJed Brown    Logically Collective on DM
346fe1899a2SJed Brown 
347fe1899a2SJed Brown    Input Arguments:
348fe1899a2SJed Brown +  dm - shell DM
349fe1899a2SJed Brown -  X - template vector
350fe1899a2SJed Brown 
351fe1899a2SJed Brown    Level: advanced
352fe1899a2SJed Brown 
353fe1899a2SJed Brown .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector()
354fe1899a2SJed Brown @*/
355fe1899a2SJed Brown PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X)
356fe1899a2SJed Brown {
357fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
358fe1899a2SJed Brown   PetscErrorCode ierr;
3598c87107bSJed Brown   PetscBool      isshell;
360fe1899a2SJed Brown 
361fe1899a2SJed Brown   PetscFunctionBegin;
3628c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3638c87107bSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
364251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
3658c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
366fe1899a2SJed Brown   ierr           = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
367fe1899a2SJed Brown   ierr           = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
368fe1899a2SJed Brown   shell->Xglobal = X;
369fe1899a2SJed Brown   PetscFunctionReturn(0);
370fe1899a2SJed Brown }
371fe1899a2SJed Brown 
372fe1899a2SJed Brown #undef __FUNCT__
373fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateGlobalVector"
374fe1899a2SJed Brown /*@C
375fe1899a2SJed Brown    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
376fe1899a2SJed Brown 
377fe1899a2SJed Brown    Logically Collective
378fe1899a2SJed Brown 
379fe1899a2SJed Brown    Input Arguments:
380fe1899a2SJed Brown +  dm - the shell DM
381fe1899a2SJed Brown -  func - the creation routine
382fe1899a2SJed Brown 
383fe1899a2SJed Brown    Level: advanced
384fe1899a2SJed Brown 
385fe1899a2SJed Brown .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix()
386fe1899a2SJed Brown @*/
387fe1899a2SJed Brown PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
388fe1899a2SJed Brown {
389fe1899a2SJed Brown 
390fe1899a2SJed Brown   PetscFunctionBegin;
391fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
392fe1899a2SJed Brown   dm->ops->createglobalvector = func;
393fe1899a2SJed Brown   PetscFunctionReturn(0);
394fe1899a2SJed Brown }
395fe1899a2SJed Brown 
396fe1899a2SJed Brown #undef __FUNCT__
397dc43b69eSJed Brown #define __FUNCT__ "DMShellSetLocalVector"
398dc43b69eSJed Brown /*@
399dc43b69eSJed Brown    DMShellSetLocalVector - sets a template local vector associated with the DMShell
400dc43b69eSJed Brown 
401dc43b69eSJed Brown    Logically Collective on DM
402dc43b69eSJed Brown 
403dc43b69eSJed Brown    Input Arguments:
404dc43b69eSJed Brown +  dm - shell DM
405dc43b69eSJed Brown -  X - template vector
406dc43b69eSJed Brown 
407dc43b69eSJed Brown    Level: advanced
408dc43b69eSJed Brown 
409dc43b69eSJed Brown .seealso: DMCreateLocalVector(), DMShellSetMatrix(), DMShellSetCreateLocalVector()
410dc43b69eSJed Brown @*/
411dc43b69eSJed Brown PetscErrorCode DMShellSetLocalVector(DM dm,Vec X)
412dc43b69eSJed Brown {
413dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
414dc43b69eSJed Brown   PetscErrorCode ierr;
415dc43b69eSJed Brown   PetscBool      isshell;
416dc43b69eSJed Brown 
417dc43b69eSJed Brown   PetscFunctionBegin;
418dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
419dc43b69eSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
420dc43b69eSJed Brown   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
421dc43b69eSJed Brown   if (!isshell) PetscFunctionReturn(0);
422dc43b69eSJed Brown   ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
423dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
424dc43b69eSJed Brown   shell->Xlocal = X;
425dc43b69eSJed Brown   PetscFunctionReturn(0);
426dc43b69eSJed Brown }
427dc43b69eSJed Brown 
428dc43b69eSJed Brown #undef __FUNCT__
429dc43b69eSJed Brown #define __FUNCT__ "DMShellSetCreateLocalVector"
430dc43b69eSJed Brown /*@C
431dc43b69eSJed Brown    DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM
432dc43b69eSJed Brown 
433dc43b69eSJed Brown    Logically Collective
434dc43b69eSJed Brown 
435dc43b69eSJed Brown    Input Arguments:
436dc43b69eSJed Brown +  dm - the shell DM
437dc43b69eSJed Brown -  func - the creation routine
438dc43b69eSJed Brown 
439dc43b69eSJed Brown    Level: advanced
440dc43b69eSJed Brown 
441dc43b69eSJed Brown .seealso: DMShellSetLocalVector(), DMShellSetCreateMatrix()
442dc43b69eSJed Brown @*/
443dc43b69eSJed Brown PetscErrorCode DMShellSetCreateLocalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
444dc43b69eSJed Brown {
445dc43b69eSJed Brown 
446dc43b69eSJed Brown   PetscFunctionBegin;
447dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
448dc43b69eSJed Brown   dm->ops->createlocalvector = func;
449dc43b69eSJed Brown   PetscFunctionReturn(0);
450dc43b69eSJed Brown }
451dc43b69eSJed Brown 
452dc43b69eSJed Brown #undef __FUNCT__
4538339e6d0SRichard Tran Mills #define __FUNCT__ "DMShellSetGlobalToLocal"
4548339e6d0SRichard Tran Mills /*@C
4558339e6d0SRichard Tran Mills    DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
4568339e6d0SRichard Tran Mills 
4578339e6d0SRichard Tran Mills    Logically Collective on DM
4588339e6d0SRichard Tran Mills 
4598339e6d0SRichard Tran Mills    Input Arguments
4608339e6d0SRichard Tran Mills +  dm - the shell DM
4618339e6d0SRichard Tran Mills .  begin - the routine that begins the global to local scatter
4628339e6d0SRichard Tran Mills -  end - the routine that ends the global to local scatter
4638339e6d0SRichard Tran Mills 
4647a108d1dSBarry Smith    Notes: If these functions are not provided but DMShellSetGlobalToLocalVecScatter() is called then
465f3db62a7SRichard Tran Mills    DMGlobalToLocalBeginDefaultShell()/DMGlobalToLocalEndDefaultShell() are used to to perform the transfers
4667a108d1dSBarry Smith 
4678339e6d0SRichard Tran Mills    Level: advanced
4688339e6d0SRichard Tran Mills 
4697a108d1dSBarry Smith .seealso: DMShellSetLocalToGlobal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell()
4708339e6d0SRichard Tran Mills @*/
4718339e6d0SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
4728339e6d0SRichard Tran Mills   PetscFunctionBegin;
4738339e6d0SRichard Tran Mills   dm->ops->globaltolocalbegin = begin;
4748339e6d0SRichard Tran Mills   dm->ops->globaltolocalend = end;
4758339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
4768339e6d0SRichard Tran Mills }
4778339e6d0SRichard Tran Mills 
4788339e6d0SRichard Tran Mills #undef __FUNCT__
4798339e6d0SRichard Tran Mills #define __FUNCT__ "DMShellSetLocalToGlobal"
4808339e6d0SRichard Tran Mills /*@C
4818339e6d0SRichard Tran Mills    DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
4828339e6d0SRichard Tran Mills 
4838339e6d0SRichard Tran Mills    Logically Collective on DM
4848339e6d0SRichard Tran Mills 
4858339e6d0SRichard Tran Mills    Input Arguments
4868339e6d0SRichard Tran Mills +  dm - the shell DM
4878339e6d0SRichard Tran Mills .  begin - the routine that begins the local to global scatter
4888339e6d0SRichard Tran Mills -  end - the routine that ends the local to global scatter
4898339e6d0SRichard Tran Mills 
490f3db62a7SRichard Tran Mills    Notes: If these functions are not provided but DMShellSetLocalToGlobalVecScatter() is called then
491f3db62a7SRichard Tran Mills    DMLocalToGlobalBeginDefaultShell()/DMLocalToGlobalEndDefaultShell() are used to to perform the transfers
492f3db62a7SRichard Tran Mills 
4938339e6d0SRichard Tran Mills    Level: advanced
4948339e6d0SRichard Tran Mills 
4958339e6d0SRichard Tran Mills .seealso: DMShellSetGlobalToLocal()
4968339e6d0SRichard Tran Mills @*/
4978339e6d0SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
4988339e6d0SRichard Tran Mills   PetscFunctionBegin;
4998339e6d0SRichard Tran Mills   dm->ops->localtoglobalbegin = begin;
5008339e6d0SRichard Tran Mills   dm->ops->localtoglobalend = end;
5018339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
5028339e6d0SRichard Tran Mills }
5038339e6d0SRichard Tran Mills 
5048339e6d0SRichard Tran Mills #undef __FUNCT__
505f3db62a7SRichard Tran Mills #define __FUNCT__ "DMShellSetLocalToLocal"
506f3db62a7SRichard Tran Mills /*@C
507f3db62a7SRichard Tran Mills    DMShellSetLocalToLocal - Sets the routines used to perform a local to local scatter
508f3db62a7SRichard Tran Mills 
509f3db62a7SRichard Tran Mills    Logically Collective on DM
510f3db62a7SRichard Tran Mills 
511f3db62a7SRichard Tran Mills    Input Arguments
512f3db62a7SRichard Tran Mills +  dm - the shell DM
513f3db62a7SRichard Tran Mills .  begin - the routine that begins the local to local scatter
514f3db62a7SRichard Tran Mills -  end - the routine that ends the local to local scatter
515f3db62a7SRichard Tran Mills 
516f3db62a7SRichard Tran Mills    Notes: If these functions are not provided but DMShellSetLocalToLocalVecScatter() is called then
517f3db62a7SRichard Tran Mills    DMLocalToLocalBeginDefaultShell()/DMLocalToLocalEndDefaultShell() are used to to perform the transfers
518f3db62a7SRichard Tran Mills 
519f3db62a7SRichard Tran Mills    Level: advanced
520f3db62a7SRichard Tran Mills 
521f3db62a7SRichard Tran Mills .seealso: DMShellSetGlobalToLocal(), DMLocalToLocalBeginDefaultShell(), DMLocalToLocalEndDefaultShell()
522f3db62a7SRichard Tran Mills @*/
523f3db62a7SRichard Tran Mills PetscErrorCode DMShellSetLocalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
524f3db62a7SRichard Tran Mills   PetscFunctionBegin;
525f3db62a7SRichard Tran Mills   dm->ops->localtolocalbegin = begin;
526f3db62a7SRichard Tran Mills   dm->ops->localtolocalend = end;
527f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
528f3db62a7SRichard Tran Mills }
529f3db62a7SRichard Tran Mills 
530f3db62a7SRichard Tran Mills #undef __FUNCT__
53181634712SRichard Tran Mills #define __FUNCT__ "DMShellSetGlobalToLocalVecScatter"
53281634712SRichard Tran Mills /*@
53381634712SRichard Tran Mills    DMShellSetGlobalToLocalVecScatter - Sets a VecScatter context for global to local communication
53481634712SRichard Tran Mills 
53581634712SRichard Tran Mills    Logically Collective on DM
53681634712SRichard Tran Mills 
53781634712SRichard Tran Mills    Input Arguments
53881634712SRichard Tran Mills +  dm - the shell DM
53981634712SRichard Tran Mills -  gtol - the global to local VecScatter context
54081634712SRichard Tran Mills 
54181634712SRichard Tran Mills    Level: advanced
54281634712SRichard Tran Mills 
543f3db62a7SRichard Tran Mills .seealso: DMShellSetGlobalToLocal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell()
54481634712SRichard Tran Mills @*/
545a94b16f6SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter gtol)
54681634712SRichard Tran Mills {
54781634712SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
548d885d199SRichard Tran Mills   PetscErrorCode ierr;
54981634712SRichard Tran Mills 
550b300e4a8SRichard Tran Mills   PetscFunctionBegin;
551d885d199SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)gtol);CHKERRQ(ierr);
552d885d199SRichard Tran Mills   /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */
553d885d199SRichard Tran Mills   ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr);
55481634712SRichard Tran Mills   shell->gtol = gtol;
55581634712SRichard Tran Mills   PetscFunctionReturn(0);
55681634712SRichard Tran Mills }
55781634712SRichard Tran Mills 
55881634712SRichard Tran Mills #undef __FUNCT__
559988ea7d6SRichard Tran Mills #define __FUNCT__ "DMShellSetLocalToGlobalVecScatter"
560988ea7d6SRichard Tran Mills /*@
561988ea7d6SRichard Tran Mills    DMShellSetLocalToGlobalVecScatter - Sets a VecScatter context for local to global communication
562988ea7d6SRichard Tran Mills 
563988ea7d6SRichard Tran Mills    Logically Collective on DM
564988ea7d6SRichard Tran Mills 
565988ea7d6SRichard Tran Mills    Input Arguments
566988ea7d6SRichard Tran Mills +  dm - the shell DM
567988ea7d6SRichard Tran Mills -  ltog - the local to global VecScatter context
568988ea7d6SRichard Tran Mills 
569988ea7d6SRichard Tran Mills    Level: advanced
570988ea7d6SRichard Tran Mills 
571f3db62a7SRichard Tran Mills .seealso: DMShellSetLocalToGlobal(), DMLocalToGlobalBeginDefaultShell(), DMLocalToGlobalEndDefaultShell()
572988ea7d6SRichard Tran Mills @*/
573a94b16f6SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter ltog)
574988ea7d6SRichard Tran Mills {
575988ea7d6SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
576d885d199SRichard Tran Mills   PetscErrorCode ierr;
577988ea7d6SRichard Tran Mills 
578988ea7d6SRichard Tran Mills   PetscFunctionBegin;
579d885d199SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr);
580d885d199SRichard Tran Mills   /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */
581d885d199SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr);
582988ea7d6SRichard Tran Mills   shell->ltog = ltog;
583988ea7d6SRichard Tran Mills   PetscFunctionReturn(0);
584988ea7d6SRichard Tran Mills }
585988ea7d6SRichard Tran Mills 
586988ea7d6SRichard Tran Mills #undef __FUNCT__
587f3db62a7SRichard Tran Mills #define __FUNCT__ "DMShellSetLocalToLocalVecScatter"
588f3db62a7SRichard Tran Mills /*@
589f3db62a7SRichard Tran Mills    DMShellSetLocalToLocalVecScatter - Sets a VecScatter context for local to local communication
590f3db62a7SRichard Tran Mills 
591f3db62a7SRichard Tran Mills    Logically Collective on DM
592f3db62a7SRichard Tran Mills 
593f3db62a7SRichard Tran Mills    Input Arguments
594f3db62a7SRichard Tran Mills +  dm - the shell DM
595f3db62a7SRichard Tran Mills -  ltol - the local to local VecScatter context
596f3db62a7SRichard Tran Mills 
597f3db62a7SRichard Tran Mills    Level: advanced
598f3db62a7SRichard Tran Mills 
599f3db62a7SRichard Tran Mills .seealso: DMShellSetLocalToLocal(), DMLocalToLocalBeginDefaultShell(), DMLocalToLocalEndDefaultShell()
600f3db62a7SRichard Tran Mills @*/
601f3db62a7SRichard Tran Mills PetscErrorCode DMShellSetLocalToLocalVecScatter(DM dm, VecScatter ltol)
602f3db62a7SRichard Tran Mills {
603f3db62a7SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
604f3db62a7SRichard Tran Mills   PetscErrorCode ierr;
605f3db62a7SRichard Tran Mills 
606f3db62a7SRichard Tran Mills   PetscFunctionBegin;
607f3db62a7SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)ltol);CHKERRQ(ierr);
608f3db62a7SRichard Tran Mills   /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */
609f3db62a7SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltol);CHKERRQ(ierr);
610f3db62a7SRichard Tran Mills   shell->ltol = ltol;
611f3db62a7SRichard Tran Mills   PetscFunctionReturn(0);
612f3db62a7SRichard Tran Mills }
613f3db62a7SRichard Tran Mills 
614f3db62a7SRichard Tran Mills #undef __FUNCT__
615f572501eSLawrence Mitchell #define __FUNCT__ "DMShellSetCoarsen"
6169bf9660cSLawrence Mitchell /*@C
6179bf9660cSLawrence Mitchell    DMShellSetCoarsen - Set the routine used to coarsen the shell DM
6189bf9660cSLawrence Mitchell 
6199bf9660cSLawrence Mitchell    Logically Collective on DM
6209bf9660cSLawrence Mitchell 
6219bf9660cSLawrence Mitchell    Input Arguments
6229bf9660cSLawrence Mitchell +  dm - the shell DM
6239bf9660cSLawrence Mitchell -  coarsen - the routine that coarsens the DM
6249bf9660cSLawrence Mitchell 
6259bf9660cSLawrence Mitchell    Level: advanced
6269bf9660cSLawrence Mitchell 
6279bf9660cSLawrence Mitchell .seealso: DMShellSetRefine(), DMCoarsen()
6289bf9660cSLawrence Mitchell @*/
629f572501eSLawrence Mitchell PetscErrorCode DMShellSetCoarsen(DM dm, PetscErrorCode (*coarsen)(DM,MPI_Comm,DM*))
630f572501eSLawrence Mitchell {
631f572501eSLawrence Mitchell   PetscErrorCode ierr;
632f572501eSLawrence Mitchell   PetscBool      isshell;
633f572501eSLawrence Mitchell 
634f572501eSLawrence Mitchell   PetscFunctionBegin;
635f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
636f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
637f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
638f572501eSLawrence Mitchell   dm->ops->coarsen = coarsen;
639f572501eSLawrence Mitchell   PetscFunctionReturn(0);
640f572501eSLawrence Mitchell }
641f572501eSLawrence Mitchell 
642f572501eSLawrence Mitchell #undef __FUNCT__
643f572501eSLawrence Mitchell #define __FUNCT__ "DMShellSetRefine"
6449bf9660cSLawrence Mitchell /*@C
6459bf9660cSLawrence Mitchell    DMShellSetRefine - Set the routine used to refine the shell DM
6469bf9660cSLawrence Mitchell 
6479bf9660cSLawrence Mitchell    Logically Collective on DM
6489bf9660cSLawrence Mitchell 
6499bf9660cSLawrence Mitchell    Input Arguments
6509bf9660cSLawrence Mitchell +  dm - the shell DM
6519bf9660cSLawrence Mitchell -  refine - the routine that refines the DM
6529bf9660cSLawrence Mitchell 
6539bf9660cSLawrence Mitchell    Level: advanced
6549bf9660cSLawrence Mitchell 
6559bf9660cSLawrence Mitchell .seealso: DMShellSetCoarsen(), DMRefine()
6569bf9660cSLawrence Mitchell @*/
657f572501eSLawrence Mitchell PetscErrorCode DMShellSetRefine(DM dm, PetscErrorCode (*refine)(DM,MPI_Comm,DM*))
658f572501eSLawrence Mitchell {
659f572501eSLawrence Mitchell   PetscErrorCode ierr;
660f572501eSLawrence Mitchell   PetscBool      isshell;
661f572501eSLawrence Mitchell 
662f572501eSLawrence Mitchell   PetscFunctionBegin;
663f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
664f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
665f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
666f572501eSLawrence Mitchell   dm->ops->refine = refine;
667f572501eSLawrence Mitchell   PetscFunctionReturn(0);
668f572501eSLawrence Mitchell }
669f572501eSLawrence Mitchell 
670f572501eSLawrence Mitchell #undef __FUNCT__
671f572501eSLawrence Mitchell #define __FUNCT__ "DMShellSetCreateInterpolation"
6729bf9660cSLawrence Mitchell /*@C
6739bf9660cSLawrence Mitchell    DMShellSetCreateInterpolation - Set the routine used to create the interpolation operator
6749bf9660cSLawrence Mitchell 
6759bf9660cSLawrence Mitchell    Logically Collective on DM
6769bf9660cSLawrence Mitchell 
6779bf9660cSLawrence Mitchell    Input Arguments
6789bf9660cSLawrence Mitchell +  dm - the shell DM
6799bf9660cSLawrence Mitchell -  interp - the routine to create the interpolation
6809bf9660cSLawrence Mitchell 
6819bf9660cSLawrence Mitchell    Level: advanced
6829bf9660cSLawrence Mitchell 
683*3ad4599aSBarry Smith .seealso: DMShellSetCreateInjection(), DMCreateInterpolation(), DMShellSetCreateRestriction()
6849bf9660cSLawrence Mitchell @*/
685f572501eSLawrence Mitchell PetscErrorCode DMShellSetCreateInterpolation(DM dm, PetscErrorCode (*interp)(DM,DM,Mat*,Vec*))
686f572501eSLawrence Mitchell {
687f572501eSLawrence Mitchell   PetscErrorCode ierr;
688f572501eSLawrence Mitchell   PetscBool      isshell;
689f572501eSLawrence Mitchell 
690f572501eSLawrence Mitchell   PetscFunctionBegin;
691f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
692f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
693f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
694f572501eSLawrence Mitchell   dm->ops->createinterpolation = interp;
695f572501eSLawrence Mitchell   PetscFunctionReturn(0);
696f572501eSLawrence Mitchell }
697f572501eSLawrence Mitchell 
698f572501eSLawrence Mitchell #undef __FUNCT__
699*3ad4599aSBarry Smith #define __FUNCT__ "DMShellSetCreateRestriction"
700*3ad4599aSBarry Smith /*@C
701*3ad4599aSBarry Smith    DMShellSetCreateRestriction - Set the routine used to create the restriction operator
702*3ad4599aSBarry Smith 
703*3ad4599aSBarry Smith    Logically Collective on DM
704*3ad4599aSBarry Smith 
705*3ad4599aSBarry Smith    Input Arguments
706*3ad4599aSBarry Smith +  dm - the shell DM
707*3ad4599aSBarry Smith -  striction- the routine to create the restriction
708*3ad4599aSBarry Smith 
709*3ad4599aSBarry Smith    Level: advanced
710*3ad4599aSBarry Smith 
711*3ad4599aSBarry Smith .seealso: DMShellSetCreateInjection(), DMCreateInterpolation()
712*3ad4599aSBarry Smith @*/
713*3ad4599aSBarry Smith PetscErrorCode DMShellSetCreateRestriction(DM dm, PetscErrorCode (*restriction)(DM,DM,Mat*))
714*3ad4599aSBarry Smith {
715*3ad4599aSBarry Smith   PetscErrorCode ierr;
716*3ad4599aSBarry Smith   PetscBool      isshell;
717*3ad4599aSBarry Smith 
718*3ad4599aSBarry Smith   PetscFunctionBegin;
719*3ad4599aSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
720*3ad4599aSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
721*3ad4599aSBarry Smith   if (!isshell) PetscFunctionReturn(0);
722*3ad4599aSBarry Smith   dm->ops->createrestriction = restriction;
723*3ad4599aSBarry Smith   PetscFunctionReturn(0);
724*3ad4599aSBarry Smith }
725*3ad4599aSBarry Smith 
726*3ad4599aSBarry Smith #undef __FUNCT__
727f572501eSLawrence Mitchell #define __FUNCT__ "DMShellSetCreateInjection"
7289bf9660cSLawrence Mitchell /*@C
7299bf9660cSLawrence Mitchell    DMShellSetCreateInjection - Set the routine used to create the injection operator
7309bf9660cSLawrence Mitchell 
7319bf9660cSLawrence Mitchell    Logically Collective on DM
7329bf9660cSLawrence Mitchell 
7339bf9660cSLawrence Mitchell    Input Arguments
7349bf9660cSLawrence Mitchell +  dm - the shell DM
7359bf9660cSLawrence Mitchell -  inject - the routine to create the injection
7369bf9660cSLawrence Mitchell 
7379bf9660cSLawrence Mitchell    Level: advanced
7389bf9660cSLawrence Mitchell 
7399bf9660cSLawrence Mitchell .seealso: DMShellSetCreateInterpolation(), DMCreateInjection()
7409bf9660cSLawrence Mitchell @*/
741f572501eSLawrence Mitchell PetscErrorCode DMShellSetCreateInjection(DM dm, PetscErrorCode (*inject)(DM,DM,Mat*))
742f572501eSLawrence Mitchell {
743f572501eSLawrence Mitchell   PetscErrorCode ierr;
744f572501eSLawrence Mitchell   PetscBool      isshell;
745f572501eSLawrence Mitchell 
746f572501eSLawrence Mitchell   PetscFunctionBegin;
747f572501eSLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
748f572501eSLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
749f572501eSLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
750f572501eSLawrence Mitchell   dm->ops->getinjection = inject;
751f572501eSLawrence Mitchell   PetscFunctionReturn(0);
752f572501eSLawrence Mitchell }
753f572501eSLawrence Mitchell 
754f572501eSLawrence Mitchell #undef __FUNCT__
7555e2259d5SLawrence Mitchell #define __FUNCT__ "DMShellSetCreateFieldDecomposition"
7569bf9660cSLawrence Mitchell /*@C
7579bf9660cSLawrence Mitchell    DMShellSetCreateFieldDecomposition - Set the routine used to create a decomposition of fields for the shell DM
7589bf9660cSLawrence Mitchell 
7599bf9660cSLawrence Mitchell    Logically Collective on DM
7609bf9660cSLawrence Mitchell 
7619bf9660cSLawrence Mitchell    Input Arguments
7629bf9660cSLawrence Mitchell +  dm - the shell DM
7639bf9660cSLawrence Mitchell -  decomp - the routine to create the decomposition
7649bf9660cSLawrence Mitchell 
7659bf9660cSLawrence Mitchell    Level: advanced
7669bf9660cSLawrence Mitchell 
7679bf9660cSLawrence Mitchell .seealso: DMCreateFieldDecomposition()
7689bf9660cSLawrence Mitchell @*/
7695e2259d5SLawrence Mitchell PetscErrorCode DMShellSetCreateFieldDecomposition(DM dm, PetscErrorCode (*decomp)(DM,PetscInt*,char***, IS**,DM**))
7705e2259d5SLawrence Mitchell {
7715e2259d5SLawrence Mitchell   PetscErrorCode ierr;
7725e2259d5SLawrence Mitchell   PetscBool      isshell;
7735e2259d5SLawrence Mitchell 
7745e2259d5SLawrence Mitchell   PetscFunctionBegin;
7755e2259d5SLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7765e2259d5SLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
7775e2259d5SLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
7785e2259d5SLawrence Mitchell   dm->ops->createfielddecomposition = decomp;
7795e2259d5SLawrence Mitchell   PetscFunctionReturn(0);
7805e2259d5SLawrence Mitchell }
7815e2259d5SLawrence Mitchell 
782c00061e5SLawrence Mitchell /*@C
783c00061e5SLawrence Mitchell    DMShellSetCreateSubDM - Set the routine used to create a sub DM from the shell DM
784c00061e5SLawrence Mitchell 
785c00061e5SLawrence Mitchell    Logically Collective on DM
786c00061e5SLawrence Mitchell 
787c00061e5SLawrence Mitchell    Input Arguments
788c00061e5SLawrence Mitchell +  dm - the shell DM
789c00061e5SLawrence Mitchell -  subdm - the routine to create the decomposition
790c00061e5SLawrence Mitchell 
791c00061e5SLawrence Mitchell    Level: advanced
792c00061e5SLawrence Mitchell 
793c00061e5SLawrence Mitchell .seealso: DMCreateSubDM()
794c00061e5SLawrence Mitchell @*/
795c00061e5SLawrence Mitchell #undef __FUNCT__
796c00061e5SLawrence Mitchell #define __FUNCT__ "DMShellSetCreateSubDM"
797c00061e5SLawrence Mitchell PetscErrorCode DMShellSetCreateSubDM(DM dm, PetscErrorCode (*subdm)(DM,PetscInt,PetscInt[],IS*,DM*))
798c00061e5SLawrence Mitchell {
799c00061e5SLawrence Mitchell   PetscErrorCode ierr;
800c00061e5SLawrence Mitchell   PetscBool      isshell;
801c00061e5SLawrence Mitchell 
802c00061e5SLawrence Mitchell   PetscFunctionBegin;
803c00061e5SLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
804c00061e5SLawrence Mitchell   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
805c00061e5SLawrence Mitchell   if (!isshell) PetscFunctionReturn(0);
806c00061e5SLawrence Mitchell   dm->ops->createsubdm = subdm;
807c00061e5SLawrence Mitchell   PetscFunctionReturn(0);
808c00061e5SLawrence Mitchell }
809c00061e5SLawrence Mitchell 
8105e2259d5SLawrence Mitchell #undef __FUNCT__
811fe1899a2SJed Brown #define __FUNCT__ "DMDestroy_Shell"
812fe1899a2SJed Brown static PetscErrorCode DMDestroy_Shell(DM dm)
813fe1899a2SJed Brown {
814fe1899a2SJed Brown   PetscErrorCode ierr;
815fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
816fe1899a2SJed Brown 
817fe1899a2SJed Brown   PetscFunctionBegin;
818fe1899a2SJed Brown   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
819fe1899a2SJed Brown   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
820dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
821a94b16f6SRichard Tran Mills   ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr);
822a94b16f6SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr);
823294a6417SLawrence Mitchell   ierr = VecScatterDestroy(&shell->ltol);CHKERRQ(ierr);
8247b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
8257b6ad80cSMatthew G Knepley   ierr = PetscFree(shell);CHKERRQ(ierr);
826fe1899a2SJed Brown   PetscFunctionReturn(0);
827fe1899a2SJed Brown }
828fe1899a2SJed Brown 
8292d53ad75SBarry Smith #undef __FUNCT__
8302d53ad75SBarry Smith #define __FUNCT__ "DMView_Shell"
8312d53ad75SBarry Smith static PetscErrorCode DMView_Shell(DM dm,PetscViewer v)
8322d53ad75SBarry Smith {
8332d53ad75SBarry Smith   PetscErrorCode ierr;
8342d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
8352d53ad75SBarry Smith 
8362d53ad75SBarry Smith   PetscFunctionBegin;
8372d53ad75SBarry Smith   ierr = VecView(shell->Xglobal,v);CHKERRQ(ierr);
8382d53ad75SBarry Smith   PetscFunctionReturn(0);
8392d53ad75SBarry Smith }
8402d53ad75SBarry Smith 
8412d53ad75SBarry Smith #undef __FUNCT__
8422d53ad75SBarry Smith #define __FUNCT__ "DMLoad_Shell"
8432d53ad75SBarry Smith static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v)
8442d53ad75SBarry Smith {
8452d53ad75SBarry Smith   PetscErrorCode ierr;
8462d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
8472d53ad75SBarry Smith 
8482d53ad75SBarry Smith   PetscFunctionBegin;
849ce94432eSBarry Smith   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&shell->Xglobal);CHKERRQ(ierr);
8502d53ad75SBarry Smith   ierr = VecLoad(shell->Xglobal,v);CHKERRQ(ierr);
8512d53ad75SBarry Smith   PetscFunctionReturn(0);
8522d53ad75SBarry Smith }
853fe1899a2SJed Brown 
854fe1899a2SJed Brown #undef __FUNCT__
8556e44b4cfSMatthew G. Knepley #define __FUNCT__ "DMCreateSubDM_Shell"
8566e44b4cfSMatthew G. Knepley PetscErrorCode DMCreateSubDM_Shell(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm)
8576e44b4cfSMatthew G. Knepley {
8586e44b4cfSMatthew G. Knepley   PetscErrorCode ierr;
8596e44b4cfSMatthew G. Knepley 
8606e44b4cfSMatthew G. Knepley   PetscFunctionBegin;
8616e44b4cfSMatthew G. Knepley   if (subdm) {ierr = DMShellCreate(PetscObjectComm((PetscObject) dm), subdm);CHKERRQ(ierr);}
8626e44b4cfSMatthew G. Knepley   ierr = DMCreateSubDM_Section_Private(dm, numFields, fields, is, subdm);CHKERRQ(ierr);
8636e44b4cfSMatthew G. Knepley   PetscFunctionReturn(0);
8646e44b4cfSMatthew G. Knepley }
8656e44b4cfSMatthew G. Knepley 
8666e44b4cfSMatthew G. Knepley #undef __FUNCT__
867fe1899a2SJed Brown #define __FUNCT__ "DMCreate_Shell"
8688cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm)
869fe1899a2SJed Brown {
870fe1899a2SJed Brown   PetscErrorCode ierr;
871fe1899a2SJed Brown   DM_Shell       *shell;
872fe1899a2SJed Brown 
873fe1899a2SJed Brown   PetscFunctionBegin;
874b00a9115SJed Brown   ierr     = PetscNewLog(dm,&shell);CHKERRQ(ierr);
8758c87107bSJed Brown   dm->data = shell;
876fe1899a2SJed Brown 
8778c87107bSJed Brown   ierr = PetscObjectChangeTypeName((PetscObject)dm,DMSHELL);CHKERRQ(ierr);
8788865f1eaSKarl Rupp 
8798c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
8808c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
881dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
8828c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
8832d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
8842d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
8857a108d1dSBarry Smith   dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell;
8867a108d1dSBarry Smith   dm->ops->globaltolocalend   = DMGlobalToLocalEndDefaultShell;
88755daaa54SRichard Tran Mills   dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell;
88855daaa54SRichard Tran Mills   dm->ops->localtoglobalend   = DMLocalToGlobalEndDefaultShell;
88963731094SRichard Tran Mills   dm->ops->localtolocalbegin  = DMLocalToLocalBeginDefaultShell;
89063731094SRichard Tran Mills   dm->ops->localtolocalend    = DMLocalToLocalEndDefaultShell;
8916e44b4cfSMatthew G. Knepley   dm->ops->createsubdm        = DMCreateSubDM_Shell;
892fe1899a2SJed Brown   PetscFunctionReturn(0);
893fe1899a2SJed Brown }
894fe1899a2SJed Brown 
895fe1899a2SJed Brown #undef __FUNCT__
896fe1899a2SJed Brown #define __FUNCT__ "DMShellCreate"
897fe1899a2SJed Brown /*@
898fe1899a2SJed Brown     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
899fe1899a2SJed Brown 
900fe1899a2SJed Brown     Collective on MPI_Comm
901fe1899a2SJed Brown 
902fe1899a2SJed Brown     Input Parameter:
903fe1899a2SJed Brown .   comm - the processors that will share the global vector
904fe1899a2SJed Brown 
905fe1899a2SJed Brown     Output Parameters:
906fe1899a2SJed Brown .   shell - the shell DM
907fe1899a2SJed Brown 
908fe1899a2SJed Brown     Level: advanced
909fe1899a2SJed Brown 
910dc43b69eSJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateLocalVector()
911fe1899a2SJed Brown @*/
912fe1899a2SJed Brown PetscErrorCode  DMShellCreate(MPI_Comm comm,DM *dm)
913fe1899a2SJed Brown {
914fe1899a2SJed Brown   PetscErrorCode ierr;
915fe1899a2SJed Brown 
916fe1899a2SJed Brown   PetscFunctionBegin;
917fe1899a2SJed Brown   PetscValidPointer(dm,2);
918fe1899a2SJed Brown   ierr = DMCreate(comm,dm);CHKERRQ(ierr);
919fe1899a2SJed Brown   ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr);
92081a566bfSMatthew G. Knepley   ierr = DMSetUp(*dm);CHKERRQ(ierr);
921fe1899a2SJed Brown   PetscFunctionReturn(0);
922fe1899a2SJed Brown }
92381634712SRichard Tran Mills 
924