xref: /petsc/src/dm/impls/shell/dmshell.c (revision f089877a000c0949609bd4a1bfd01a0aa8158bb4)
1fe1899a2SJed Brown #include <petscdmshell.h>       /*I    "petscdmshell.h"  I*/
207475bc1SBarry Smith #include <petscmat.h>
307475bc1SBarry Smith #include <petsc-private/dmimpl.h>
4fe1899a2SJed Brown 
5fe1899a2SJed Brown typedef struct  {
6fe1899a2SJed Brown   Vec        Xglobal;
7dc43b69eSJed Brown   Vec        Xlocal;
8fe1899a2SJed Brown   Mat        A;
9a94b16f6SRichard Tran Mills   VecScatter gtol;
10a94b16f6SRichard Tran Mills   VecScatter ltog;
11*f089877aSRichard 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 
126c5076b69SRichard Tran Mills 
127c5076b69SRichard Tran Mills #undef __FUNCT__
128fe1899a2SJed Brown #define __FUNCT__ "DMCreateMatrix_Shell"
12919fd82e9SBarry Smith static PetscErrorCode DMCreateMatrix_Shell(DM dm,MatType mtype,Mat *J)
130fe1899a2SJed Brown {
131fe1899a2SJed Brown   PetscErrorCode ierr;
132fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
133fe1899a2SJed Brown   Mat            A;
134fe1899a2SJed Brown 
135fe1899a2SJed Brown   PetscFunctionBegin;
136fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
137fe1899a2SJed Brown   PetscValidPointer(J,3);
1387bde9f88SJed Brown   if (!shell->A) {
1397bde9f88SJed Brown     if (shell->Xglobal) {
1407bde9f88SJed Brown       PetscInt m,M;
1417bde9f88SJed Brown       ierr = PetscInfo(dm,"Naively creating matrix using global vector distribution without preallocation");CHKERRQ(ierr);
1427bde9f88SJed Brown       ierr = VecGetSize(shell->Xglobal,&M);CHKERRQ(ierr);
1437bde9f88SJed Brown       ierr = VecGetLocalSize(shell->Xglobal,&m);CHKERRQ(ierr);
144ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)dm),&shell->A);CHKERRQ(ierr);
1457bde9f88SJed Brown       ierr = MatSetSizes(shell->A,m,m,M,M);CHKERRQ(ierr);
1467bde9f88SJed Brown       if (mtype) {ierr = MatSetType(shell->A,mtype);CHKERRQ(ierr);}
1477bde9f88SJed Brown       ierr = MatSetUp(shell->A);CHKERRQ(ierr);
148ce94432eSBarry Smith     } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector");
1497bde9f88SJed Brown   }
150fe1899a2SJed Brown   A = shell->A;
151ad6bc421SBarry Smith   /* the check below is tacky and incomplete */
152fe1899a2SJed Brown   if (mtype) {
153ad6bc421SBarry Smith     PetscBool flg,aij,seqaij,mpiaij;
154251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)A,mtype,&flg);CHKERRQ(ierr);
155ad6bc421SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
156ad6bc421SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&mpiaij);CHKERRQ(ierr);
157ad6bc421SBarry Smith     ierr = PetscStrcmp(mtype,MATAIJ,&aij);CHKERRQ(ierr);
158ad6bc421SBarry Smith     if (!flg) {
159b4640e9aSSatish Balay       if (!(aij && (seqaij || mpiaij))) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_NOTSAMETYPE,"Requested matrix of type %s, but only %s available",mtype,((PetscObject)A)->type_name);
160ad6bc421SBarry Smith     }
161fe1899a2SJed Brown   }
162fe1899a2SJed Brown   if (((PetscObject)A)->refct < 2) { /* We have an exclusive reference so we can give it out */
163fe1899a2SJed Brown     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
164fe1899a2SJed Brown     ierr = MatZeroEntries(A);CHKERRQ(ierr);
165fe1899a2SJed Brown     *J   = A;
166fe1899a2SJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
167fe1899a2SJed Brown     ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J);CHKERRQ(ierr);
168fe1899a2SJed Brown     ierr = MatZeroEntries(*J);CHKERRQ(ierr);
169fe1899a2SJed Brown   }
170fe1899a2SJed Brown   PetscFunctionReturn(0);
171fe1899a2SJed Brown }
172fe1899a2SJed Brown 
173fe1899a2SJed Brown #undef __FUNCT__
174fe1899a2SJed Brown #define __FUNCT__ "DMCreateGlobalVector_Shell"
175fe1899a2SJed Brown PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec)
176fe1899a2SJed Brown {
177fe1899a2SJed Brown   PetscErrorCode ierr;
178fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
179fe1899a2SJed Brown   Vec            X;
180fe1899a2SJed Brown 
181fe1899a2SJed Brown   PetscFunctionBegin;
182fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
183fe1899a2SJed Brown   PetscValidPointer(gvec,2);
184fe1899a2SJed Brown   *gvec = 0;
185fe1899a2SJed Brown   X     = shell->Xglobal;
186ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
187fe1899a2SJed Brown   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
188fe1899a2SJed Brown     ierr  = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
189fe1899a2SJed Brown     ierr  = VecZeroEntries(X);CHKERRQ(ierr);
190fe1899a2SJed Brown     *gvec = X;
191fe1899a2SJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
192fe1899a2SJed Brown     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
193fe1899a2SJed Brown     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
194fe1899a2SJed Brown   }
195c688c046SMatthew G Knepley   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
196fe1899a2SJed Brown   PetscFunctionReturn(0);
197fe1899a2SJed Brown }
198fe1899a2SJed Brown 
199fe1899a2SJed Brown #undef __FUNCT__
200dc43b69eSJed Brown #define __FUNCT__ "DMCreateLocalVector_Shell"
201dc43b69eSJed Brown PetscErrorCode DMCreateLocalVector_Shell(DM dm,Vec *gvec)
202dc43b69eSJed Brown {
203dc43b69eSJed Brown   PetscErrorCode ierr;
204dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
205dc43b69eSJed Brown   Vec            X;
206dc43b69eSJed Brown 
207dc43b69eSJed Brown   PetscFunctionBegin;
208dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
209dc43b69eSJed Brown   PetscValidPointer(gvec,2);
210dc43b69eSJed Brown   *gvec = 0;
211dc43b69eSJed Brown   X     = shell->Xlocal;
212ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()");
213dc43b69eSJed Brown   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
214dc43b69eSJed Brown     ierr  = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
215dc43b69eSJed Brown     ierr  = VecZeroEntries(X);CHKERRQ(ierr);
216dc43b69eSJed Brown     *gvec = X;
217dc43b69eSJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
218dc43b69eSJed Brown     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
219dc43b69eSJed Brown     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
220dc43b69eSJed Brown   }
2216e4cbd8bSMark F. Adams   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
222dc43b69eSJed Brown   PetscFunctionReturn(0);
223dc43b69eSJed Brown }
224dc43b69eSJed Brown 
225dc43b69eSJed Brown #undef __FUNCT__
226fe1899a2SJed Brown #define __FUNCT__ "DMShellSetMatrix"
227fe1899a2SJed Brown /*@
228fe1899a2SJed Brown    DMShellSetMatrix - sets a template matrix associated with the DMShell
229fe1899a2SJed Brown 
230fe1899a2SJed Brown    Collective
231fe1899a2SJed Brown 
232fe1899a2SJed Brown    Input Arguments:
233fe1899a2SJed Brown +  dm - shell DM
234fe1899a2SJed Brown -  J - template matrix
235fe1899a2SJed Brown 
236fe1899a2SJed Brown    Level: advanced
237fe1899a2SJed Brown 
238fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetCreateMatrix()
239fe1899a2SJed Brown @*/
240fe1899a2SJed Brown PetscErrorCode DMShellSetMatrix(DM dm,Mat J)
241fe1899a2SJed Brown {
242fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
243fe1899a2SJed Brown   PetscErrorCode ierr;
2448c87107bSJed Brown   PetscBool      isshell;
245fe1899a2SJed Brown 
246fe1899a2SJed Brown   PetscFunctionBegin;
2478c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2488c87107bSJed Brown   PetscValidHeaderSpecific(J,MAT_CLASSID,2);
249251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
2508c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
251fe1899a2SJed Brown   ierr     = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
252fe1899a2SJed Brown   ierr     = MatDestroy(&shell->A);CHKERRQ(ierr);
253fe1899a2SJed Brown   shell->A = J;
254fe1899a2SJed Brown   PetscFunctionReturn(0);
255fe1899a2SJed Brown }
256fe1899a2SJed Brown 
257fe1899a2SJed Brown #undef __FUNCT__
258fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateMatrix"
259fe1899a2SJed Brown /*@C
260fe1899a2SJed Brown    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM
261fe1899a2SJed Brown 
262fe1899a2SJed Brown    Logically Collective on DM
263fe1899a2SJed Brown 
264fe1899a2SJed Brown    Input Arguments:
265fe1899a2SJed Brown +  dm - the shell DM
266fe1899a2SJed Brown -  func - the function to create a matrix
267fe1899a2SJed Brown 
268fe1899a2SJed Brown    Level: advanced
269fe1899a2SJed Brown 
270fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetMatrix()
271fe1899a2SJed Brown @*/
27219fd82e9SBarry Smith PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,MatType,Mat*))
273fe1899a2SJed Brown {
274fe1899a2SJed Brown 
275fe1899a2SJed Brown   PetscFunctionBegin;
276fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
277fe1899a2SJed Brown   dm->ops->creatematrix = func;
278fe1899a2SJed Brown   PetscFunctionReturn(0);
279fe1899a2SJed Brown }
280fe1899a2SJed Brown 
281fe1899a2SJed Brown #undef __FUNCT__
282fe1899a2SJed Brown #define __FUNCT__ "DMShellSetGlobalVector"
283fe1899a2SJed Brown /*@
284fe1899a2SJed Brown    DMShellSetGlobalVector - sets a template global vector associated with the DMShell
285fe1899a2SJed Brown 
286fe1899a2SJed Brown    Logically Collective on DM
287fe1899a2SJed Brown 
288fe1899a2SJed Brown    Input Arguments:
289fe1899a2SJed Brown +  dm - shell DM
290fe1899a2SJed Brown -  X - template vector
291fe1899a2SJed Brown 
292fe1899a2SJed Brown    Level: advanced
293fe1899a2SJed Brown 
294fe1899a2SJed Brown .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector()
295fe1899a2SJed Brown @*/
296fe1899a2SJed Brown PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X)
297fe1899a2SJed Brown {
298fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
299fe1899a2SJed Brown   PetscErrorCode ierr;
3008c87107bSJed Brown   PetscBool      isshell;
301fe1899a2SJed Brown 
302fe1899a2SJed Brown   PetscFunctionBegin;
3038c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3048c87107bSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
305251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
3068c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
307fe1899a2SJed Brown   ierr           = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
308fe1899a2SJed Brown   ierr           = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
309fe1899a2SJed Brown   shell->Xglobal = X;
310fe1899a2SJed Brown   PetscFunctionReturn(0);
311fe1899a2SJed Brown }
312fe1899a2SJed Brown 
313fe1899a2SJed Brown #undef __FUNCT__
314fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateGlobalVector"
315fe1899a2SJed Brown /*@C
316fe1899a2SJed Brown    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
317fe1899a2SJed Brown 
318fe1899a2SJed Brown    Logically Collective
319fe1899a2SJed Brown 
320fe1899a2SJed Brown    Input Arguments:
321fe1899a2SJed Brown +  dm - the shell DM
322fe1899a2SJed Brown -  func - the creation routine
323fe1899a2SJed Brown 
324fe1899a2SJed Brown    Level: advanced
325fe1899a2SJed Brown 
326fe1899a2SJed Brown .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix()
327fe1899a2SJed Brown @*/
328fe1899a2SJed Brown PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
329fe1899a2SJed Brown {
330fe1899a2SJed Brown 
331fe1899a2SJed Brown   PetscFunctionBegin;
332fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
333fe1899a2SJed Brown   dm->ops->createglobalvector = func;
334fe1899a2SJed Brown   PetscFunctionReturn(0);
335fe1899a2SJed Brown }
336fe1899a2SJed Brown 
337fe1899a2SJed Brown #undef __FUNCT__
338dc43b69eSJed Brown #define __FUNCT__ "DMShellSetLocalVector"
339dc43b69eSJed Brown /*@
340dc43b69eSJed Brown    DMShellSetLocalVector - sets a template local vector associated with the DMShell
341dc43b69eSJed Brown 
342dc43b69eSJed Brown    Logically Collective on DM
343dc43b69eSJed Brown 
344dc43b69eSJed Brown    Input Arguments:
345dc43b69eSJed Brown +  dm - shell DM
346dc43b69eSJed Brown -  X - template vector
347dc43b69eSJed Brown 
348dc43b69eSJed Brown    Level: advanced
349dc43b69eSJed Brown 
350dc43b69eSJed Brown .seealso: DMCreateLocalVector(), DMShellSetMatrix(), DMShellSetCreateLocalVector()
351dc43b69eSJed Brown @*/
352dc43b69eSJed Brown PetscErrorCode DMShellSetLocalVector(DM dm,Vec X)
353dc43b69eSJed Brown {
354dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
355dc43b69eSJed Brown   PetscErrorCode ierr;
356dc43b69eSJed Brown   PetscBool      isshell;
357dc43b69eSJed Brown 
358dc43b69eSJed Brown   PetscFunctionBegin;
359dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
360dc43b69eSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
361dc43b69eSJed Brown   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
362dc43b69eSJed Brown   if (!isshell) PetscFunctionReturn(0);
363dc43b69eSJed Brown   ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
364dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
365dc43b69eSJed Brown   shell->Xlocal = X;
366dc43b69eSJed Brown   PetscFunctionReturn(0);
367dc43b69eSJed Brown }
368dc43b69eSJed Brown 
369dc43b69eSJed Brown #undef __FUNCT__
370dc43b69eSJed Brown #define __FUNCT__ "DMShellSetCreateLocalVector"
371dc43b69eSJed Brown /*@C
372dc43b69eSJed Brown    DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM
373dc43b69eSJed Brown 
374dc43b69eSJed Brown    Logically Collective
375dc43b69eSJed Brown 
376dc43b69eSJed Brown    Input Arguments:
377dc43b69eSJed Brown +  dm - the shell DM
378dc43b69eSJed Brown -  func - the creation routine
379dc43b69eSJed Brown 
380dc43b69eSJed Brown    Level: advanced
381dc43b69eSJed Brown 
382dc43b69eSJed Brown .seealso: DMShellSetLocalVector(), DMShellSetCreateMatrix()
383dc43b69eSJed Brown @*/
384dc43b69eSJed Brown PetscErrorCode DMShellSetCreateLocalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
385dc43b69eSJed Brown {
386dc43b69eSJed Brown 
387dc43b69eSJed Brown   PetscFunctionBegin;
388dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
389dc43b69eSJed Brown   dm->ops->createlocalvector = func;
390dc43b69eSJed Brown   PetscFunctionReturn(0);
391dc43b69eSJed Brown }
392dc43b69eSJed Brown 
393dc43b69eSJed Brown #undef __FUNCT__
3948339e6d0SRichard Tran Mills #define __FUNCT__ "DMShellSetGlobalToLocal"
3958339e6d0SRichard Tran Mills /*@C
3968339e6d0SRichard Tran Mills    DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
3978339e6d0SRichard Tran Mills 
3988339e6d0SRichard Tran Mills    Logically Collective on DM
3998339e6d0SRichard Tran Mills 
4008339e6d0SRichard Tran Mills    Input Arguments
4018339e6d0SRichard Tran Mills +  dm - the shell DM
4028339e6d0SRichard Tran Mills .  begin - the routine that begins the global to local scatter
4038339e6d0SRichard Tran Mills -  end - the routine that ends the global to local scatter
4048339e6d0SRichard Tran Mills 
4057a108d1dSBarry Smith    Notes: If these functions are not provided but DMShellSetGlobalToLocalVecScatter() is called then
4067a108d1dSBarry Smith    DMGlobalToLocalBeginDefaultShell() are used to to perform the transfers DMGlobalToLocalEndDefaultShell()
4077a108d1dSBarry Smith 
4088339e6d0SRichard Tran Mills    Level: advanced
4098339e6d0SRichard Tran Mills 
4107a108d1dSBarry Smith .seealso: DMShellSetLocalToGlobal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell()
4118339e6d0SRichard Tran Mills @*/
4128339e6d0SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
4138339e6d0SRichard Tran Mills   PetscFunctionBegin;
4148339e6d0SRichard Tran Mills   dm->ops->globaltolocalbegin = begin;
4158339e6d0SRichard Tran Mills   dm->ops->globaltolocalend = end;
4168339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
4178339e6d0SRichard Tran Mills }
4188339e6d0SRichard Tran Mills 
4198339e6d0SRichard Tran Mills #undef __FUNCT__
4208339e6d0SRichard Tran Mills #define __FUNCT__ "DMShellSetLocalToGlobal"
4218339e6d0SRichard Tran Mills /*@C
4228339e6d0SRichard Tran Mills    DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
4238339e6d0SRichard Tran Mills 
4248339e6d0SRichard Tran Mills    Logically Collective on DM
4258339e6d0SRichard Tran Mills 
4268339e6d0SRichard Tran Mills    Input Arguments
4278339e6d0SRichard Tran Mills +  dm - the shell DM
4288339e6d0SRichard Tran Mills .  begin - the routine that begins the local to global scatter
4298339e6d0SRichard Tran Mills -  end - the routine that ends the local to global scatter
4308339e6d0SRichard Tran Mills 
4318339e6d0SRichard Tran Mills    Level: advanced
4328339e6d0SRichard Tran Mills 
4338339e6d0SRichard Tran Mills .seealso: DMShellSetGlobalToLocal()
4348339e6d0SRichard Tran Mills @*/
4358339e6d0SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
4368339e6d0SRichard Tran Mills   PetscFunctionBegin;
4378339e6d0SRichard Tran Mills   dm->ops->localtoglobalbegin = begin;
4388339e6d0SRichard Tran Mills   dm->ops->localtoglobalend = end;
4398339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
4408339e6d0SRichard Tran Mills }
4418339e6d0SRichard Tran Mills 
4428339e6d0SRichard Tran Mills #undef __FUNCT__
44381634712SRichard Tran Mills #define __FUNCT__ "DMShellSetGlobalToLocalVecScatter"
44481634712SRichard Tran Mills /*@
44581634712SRichard Tran Mills    DMShellSetGlobalToLocalVecScatter - Sets a VecScatter context for global to local communication
44681634712SRichard Tran Mills 
44781634712SRichard Tran Mills    Logically Collective on DM
44881634712SRichard Tran Mills 
44981634712SRichard Tran Mills    Input Arguments
45081634712SRichard Tran Mills +  dm - the shell DM
45181634712SRichard Tran Mills -  gtol - the global to local VecScatter context
45281634712SRichard Tran Mills 
45381634712SRichard Tran Mills    Level: advanced
45481634712SRichard Tran Mills 
45581634712SRichard Tran Mills .seealso: DMShellSetGlobalToLocal()
45681634712SRichard Tran Mills @*/
457a94b16f6SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter gtol)
45881634712SRichard Tran Mills {
45981634712SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
460d885d199SRichard Tran Mills   PetscErrorCode ierr;
46181634712SRichard Tran Mills 
462b300e4a8SRichard Tran Mills   PetscFunctionBegin;
463d885d199SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)gtol);CHKERRQ(ierr);
464d885d199SRichard Tran Mills   /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */
465d885d199SRichard Tran Mills   ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr);
46681634712SRichard Tran Mills   shell->gtol = gtol;
46781634712SRichard Tran Mills   PetscFunctionReturn(0);
46881634712SRichard Tran Mills }
46981634712SRichard Tran Mills 
47081634712SRichard Tran Mills #undef __FUNCT__
471988ea7d6SRichard Tran Mills #define __FUNCT__ "DMShellSetLocalToGlobalVecScatter"
472988ea7d6SRichard Tran Mills /*@
473988ea7d6SRichard Tran Mills    DMShellSetLocalToGlobalVecScatter - Sets a VecScatter context for local to global communication
474988ea7d6SRichard Tran Mills 
475988ea7d6SRichard Tran Mills    Logically Collective on DM
476988ea7d6SRichard Tran Mills 
477988ea7d6SRichard Tran Mills    Input Arguments
478988ea7d6SRichard Tran Mills +  dm - the shell DM
479988ea7d6SRichard Tran Mills -  ltog - the local to global VecScatter context
480988ea7d6SRichard Tran Mills 
481988ea7d6SRichard Tran Mills    Level: advanced
482988ea7d6SRichard Tran Mills 
483988ea7d6SRichard Tran Mills .seealso: DMShellSetLocalToGlobal()
484988ea7d6SRichard Tran Mills @*/
485a94b16f6SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter ltog)
486988ea7d6SRichard Tran Mills {
487988ea7d6SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
488d885d199SRichard Tran Mills   PetscErrorCode ierr;
489988ea7d6SRichard Tran Mills 
490988ea7d6SRichard Tran Mills   PetscFunctionBegin;
491d885d199SRichard Tran Mills   ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr);
492d885d199SRichard Tran Mills   /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */
493d885d199SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr);
494988ea7d6SRichard Tran Mills   shell->ltog = ltog;
495988ea7d6SRichard Tran Mills   PetscFunctionReturn(0);
496988ea7d6SRichard Tran Mills }
497988ea7d6SRichard Tran Mills 
498988ea7d6SRichard Tran Mills #undef __FUNCT__
499fe1899a2SJed Brown #define __FUNCT__ "DMDestroy_Shell"
500fe1899a2SJed Brown static PetscErrorCode DMDestroy_Shell(DM dm)
501fe1899a2SJed Brown {
502fe1899a2SJed Brown   PetscErrorCode ierr;
503fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
504fe1899a2SJed Brown 
505fe1899a2SJed Brown   PetscFunctionBegin;
506fe1899a2SJed Brown   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
507fe1899a2SJed Brown   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
508dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
509a94b16f6SRichard Tran Mills   ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr);
510a94b16f6SRichard Tran Mills   ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr);
5117b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
5127b6ad80cSMatthew G Knepley   ierr = PetscFree(shell);CHKERRQ(ierr);
513fe1899a2SJed Brown   PetscFunctionReturn(0);
514fe1899a2SJed Brown }
515fe1899a2SJed Brown 
5162d53ad75SBarry Smith #undef __FUNCT__
5172d53ad75SBarry Smith #define __FUNCT__ "DMView_Shell"
5182d53ad75SBarry Smith static PetscErrorCode DMView_Shell(DM dm,PetscViewer v)
5192d53ad75SBarry Smith {
5202d53ad75SBarry Smith   PetscErrorCode ierr;
5212d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
5222d53ad75SBarry Smith 
5232d53ad75SBarry Smith   PetscFunctionBegin;
5242d53ad75SBarry Smith   ierr = VecView(shell->Xglobal,v);CHKERRQ(ierr);
5252d53ad75SBarry Smith   PetscFunctionReturn(0);
5262d53ad75SBarry Smith }
5272d53ad75SBarry Smith 
5282d53ad75SBarry Smith #undef __FUNCT__
5292d53ad75SBarry Smith #define __FUNCT__ "DMLoad_Shell"
5302d53ad75SBarry Smith static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v)
5312d53ad75SBarry Smith {
5322d53ad75SBarry Smith   PetscErrorCode ierr;
5332d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
5342d53ad75SBarry Smith 
5352d53ad75SBarry Smith   PetscFunctionBegin;
536ce94432eSBarry Smith   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&shell->Xglobal);CHKERRQ(ierr);
5372d53ad75SBarry Smith   ierr = VecLoad(shell->Xglobal,v);CHKERRQ(ierr);
5382d53ad75SBarry Smith   PetscFunctionReturn(0);
5392d53ad75SBarry Smith }
540fe1899a2SJed Brown 
541fe1899a2SJed Brown #undef __FUNCT__
542fe1899a2SJed Brown #define __FUNCT__ "DMCreate_Shell"
5438cc058d9SJed Brown PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm)
544fe1899a2SJed Brown {
545fe1899a2SJed Brown   PetscErrorCode ierr;
546fe1899a2SJed Brown   DM_Shell       *shell;
547fe1899a2SJed Brown 
548fe1899a2SJed Brown   PetscFunctionBegin;
5498c87107bSJed Brown   ierr     = PetscNewLog(dm,DM_Shell,&shell);CHKERRQ(ierr);
5508c87107bSJed Brown   dm->data = shell;
551fe1899a2SJed Brown 
5528c87107bSJed Brown   ierr = PetscObjectChangeTypeName((PetscObject)dm,DMSHELL);CHKERRQ(ierr);
5538865f1eaSKarl Rupp 
5548c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
5558c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
556dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
5578c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
5582d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
5592d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
5607a108d1dSBarry Smith   dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell;
5617a108d1dSBarry Smith   dm->ops->globaltolocalend   = DMGlobalToLocalEndDefaultShell;
56255daaa54SRichard Tran Mills   dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell;
56355daaa54SRichard Tran Mills   dm->ops->localtoglobalend   = DMLocalToGlobalEndDefaultShell;
564fe1899a2SJed Brown   PetscFunctionReturn(0);
565fe1899a2SJed Brown }
566fe1899a2SJed Brown 
567fe1899a2SJed Brown #undef __FUNCT__
568fe1899a2SJed Brown #define __FUNCT__ "DMShellCreate"
569fe1899a2SJed Brown /*@
570fe1899a2SJed Brown     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
571fe1899a2SJed Brown 
572fe1899a2SJed Brown     Collective on MPI_Comm
573fe1899a2SJed Brown 
574fe1899a2SJed Brown     Input Parameter:
575fe1899a2SJed Brown .   comm - the processors that will share the global vector
576fe1899a2SJed Brown 
577fe1899a2SJed Brown     Output Parameters:
578fe1899a2SJed Brown .   shell - the shell DM
579fe1899a2SJed Brown 
580fe1899a2SJed Brown     Level: advanced
581fe1899a2SJed Brown 
582dc43b69eSJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateLocalVector()
583fe1899a2SJed Brown @*/
584fe1899a2SJed Brown PetscErrorCode  DMShellCreate(MPI_Comm comm,DM *dm)
585fe1899a2SJed Brown {
586fe1899a2SJed Brown   PetscErrorCode ierr;
587fe1899a2SJed Brown 
588fe1899a2SJed Brown   PetscFunctionBegin;
589fe1899a2SJed Brown   PetscValidPointer(dm,2);
590fe1899a2SJed Brown   ierr = DMCreate(comm,dm);CHKERRQ(ierr);
591fe1899a2SJed Brown   ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr);
592fe1899a2SJed Brown   PetscFunctionReturn(0);
593fe1899a2SJed Brown }
59481634712SRichard Tran Mills 
595