xref: /petsc/src/dm/impls/shell/dmshell.c (revision b300e4a8a8bb8e11e98c13d9856034d595e20395)
1fe1899a2SJed Brown #include <petscdmshell.h>       /*I    "petscdmshell.h"  I*/
207475bc1SBarry Smith #include <petscmat.h>
307475bc1SBarry Smith #include <petsc-private/dmimpl.h>
4fe1899a2SJed Brown 
5fe1899a2SJed Brown typedef struct  {
6fe1899a2SJed Brown   Vec Xglobal;
7dc43b69eSJed Brown   Vec Xlocal;
8fe1899a2SJed Brown   Mat A;
981634712SRichard Tran Mills   VecScatter *gtol;
1081634712SRichard Tran Mills   VecScatter *ltog;
11fe1899a2SJed Brown } DM_Shell;
12fe1899a2SJed Brown 
13fe1899a2SJed Brown #undef __FUNCT__
14fe1899a2SJed Brown #define __FUNCT__ "DMCreateMatrix_Shell"
1519fd82e9SBarry Smith static PetscErrorCode DMCreateMatrix_Shell(DM dm,MatType mtype,Mat *J)
16fe1899a2SJed Brown {
17fe1899a2SJed Brown   PetscErrorCode ierr;
18fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
19fe1899a2SJed Brown   Mat            A;
20fe1899a2SJed Brown 
21fe1899a2SJed Brown   PetscFunctionBegin;
22fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
23fe1899a2SJed Brown   PetscValidPointer(J,3);
247bde9f88SJed Brown   if (!shell->A) {
257bde9f88SJed Brown     if (shell->Xglobal) {
267bde9f88SJed Brown       PetscInt m,M;
277bde9f88SJed Brown       ierr = PetscInfo(dm,"Naively creating matrix using global vector distribution without preallocation");CHKERRQ(ierr);
287bde9f88SJed Brown       ierr = VecGetSize(shell->Xglobal,&M);CHKERRQ(ierr);
297bde9f88SJed Brown       ierr = VecGetLocalSize(shell->Xglobal,&m);CHKERRQ(ierr);
30ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)dm),&shell->A);CHKERRQ(ierr);
317bde9f88SJed Brown       ierr = MatSetSizes(shell->A,m,m,M,M);CHKERRQ(ierr);
327bde9f88SJed Brown       if (mtype) {ierr = MatSetType(shell->A,mtype);CHKERRQ(ierr);}
337bde9f88SJed Brown       ierr = MatSetUp(shell->A);CHKERRQ(ierr);
34ce94432eSBarry Smith     } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector");
357bde9f88SJed Brown   }
36fe1899a2SJed Brown   A = shell->A;
37ad6bc421SBarry Smith   /* the check below is tacky and incomplete */
38fe1899a2SJed Brown   if (mtype) {
39ad6bc421SBarry Smith     PetscBool flg,aij,seqaij,mpiaij;
40251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)A,mtype,&flg);CHKERRQ(ierr);
41ad6bc421SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
42ad6bc421SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&mpiaij);CHKERRQ(ierr);
43ad6bc421SBarry Smith     ierr = PetscStrcmp(mtype,MATAIJ,&aij);CHKERRQ(ierr);
44ad6bc421SBarry Smith     if (!flg) {
45ce94432eSBarry Smith       if (!(aij & (seqaij || mpiaij))) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_NOTSAMETYPE,"Requested matrix of type %s, but only %s available",mtype,((PetscObject)A)->type_name);
46ad6bc421SBarry Smith     }
47fe1899a2SJed Brown   }
48fe1899a2SJed Brown   if (((PetscObject)A)->refct < 2) { /* We have an exclusive reference so we can give it out */
49fe1899a2SJed Brown     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
50fe1899a2SJed Brown     ierr = MatZeroEntries(A);CHKERRQ(ierr);
51fe1899a2SJed Brown     *J   = A;
52fe1899a2SJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
53fe1899a2SJed Brown     ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J);CHKERRQ(ierr);
54fe1899a2SJed Brown     ierr = MatZeroEntries(*J);CHKERRQ(ierr);
55fe1899a2SJed Brown   }
56fe1899a2SJed Brown   PetscFunctionReturn(0);
57fe1899a2SJed Brown }
58fe1899a2SJed Brown 
59fe1899a2SJed Brown #undef __FUNCT__
60fe1899a2SJed Brown #define __FUNCT__ "DMCreateGlobalVector_Shell"
61fe1899a2SJed Brown PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec)
62fe1899a2SJed Brown {
63fe1899a2SJed Brown   PetscErrorCode ierr;
64fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
65fe1899a2SJed Brown   Vec            X;
66fe1899a2SJed Brown 
67fe1899a2SJed Brown   PetscFunctionBegin;
68fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
69fe1899a2SJed Brown   PetscValidPointer(gvec,2);
70fe1899a2SJed Brown   *gvec = 0;
71fe1899a2SJed Brown   X     = shell->Xglobal;
72ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
73fe1899a2SJed Brown   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
74fe1899a2SJed Brown     ierr  = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
75fe1899a2SJed Brown     ierr  = VecZeroEntries(X);CHKERRQ(ierr);
76fe1899a2SJed Brown     *gvec = X;
77fe1899a2SJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
78fe1899a2SJed Brown     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
79fe1899a2SJed Brown     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
80fe1899a2SJed Brown   }
81c688c046SMatthew G Knepley   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
82fe1899a2SJed Brown   PetscFunctionReturn(0);
83fe1899a2SJed Brown }
84fe1899a2SJed Brown 
85fe1899a2SJed Brown #undef __FUNCT__
86dc43b69eSJed Brown #define __FUNCT__ "DMCreateLocalVector_Shell"
87dc43b69eSJed Brown PetscErrorCode DMCreateLocalVector_Shell(DM dm,Vec *gvec)
88dc43b69eSJed Brown {
89dc43b69eSJed Brown   PetscErrorCode ierr;
90dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
91dc43b69eSJed Brown   Vec            X;
92dc43b69eSJed Brown 
93dc43b69eSJed Brown   PetscFunctionBegin;
94dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
95dc43b69eSJed Brown   PetscValidPointer(gvec,2);
96dc43b69eSJed Brown   *gvec = 0;
97dc43b69eSJed Brown   X     = shell->Xlocal;
98ce94432eSBarry Smith   if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()");
99dc43b69eSJed Brown   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
100dc43b69eSJed Brown     ierr  = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
101dc43b69eSJed Brown     ierr  = VecZeroEntries(X);CHKERRQ(ierr);
102dc43b69eSJed Brown     *gvec = X;
103dc43b69eSJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
104dc43b69eSJed Brown     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
105dc43b69eSJed Brown     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
106dc43b69eSJed Brown   }
1076e4cbd8bSMark F. Adams   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
108dc43b69eSJed Brown   PetscFunctionReturn(0);
109dc43b69eSJed Brown }
110dc43b69eSJed Brown 
111dc43b69eSJed Brown #undef __FUNCT__
112fe1899a2SJed Brown #define __FUNCT__ "DMShellSetMatrix"
113fe1899a2SJed Brown /*@
114fe1899a2SJed Brown    DMShellSetMatrix - sets a template matrix associated with the DMShell
115fe1899a2SJed Brown 
116fe1899a2SJed Brown    Collective
117fe1899a2SJed Brown 
118fe1899a2SJed Brown    Input Arguments:
119fe1899a2SJed Brown +  dm - shell DM
120fe1899a2SJed Brown -  J - template matrix
121fe1899a2SJed Brown 
122fe1899a2SJed Brown    Level: advanced
123fe1899a2SJed Brown 
124fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetCreateMatrix()
125fe1899a2SJed Brown @*/
126fe1899a2SJed Brown PetscErrorCode DMShellSetMatrix(DM dm,Mat J)
127fe1899a2SJed Brown {
128fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
129fe1899a2SJed Brown   PetscErrorCode ierr;
1308c87107bSJed Brown   PetscBool      isshell;
131fe1899a2SJed Brown 
132fe1899a2SJed Brown   PetscFunctionBegin;
1338c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1348c87107bSJed Brown   PetscValidHeaderSpecific(J,MAT_CLASSID,2);
135251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
1368c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
137fe1899a2SJed Brown   ierr     = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
138fe1899a2SJed Brown   ierr     = MatDestroy(&shell->A);CHKERRQ(ierr);
139fe1899a2SJed Brown   shell->A = J;
140fe1899a2SJed Brown   PetscFunctionReturn(0);
141fe1899a2SJed Brown }
142fe1899a2SJed Brown 
143fe1899a2SJed Brown #undef __FUNCT__
144fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateMatrix"
145fe1899a2SJed Brown /*@C
146fe1899a2SJed Brown    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM
147fe1899a2SJed Brown 
148fe1899a2SJed Brown    Logically Collective on DM
149fe1899a2SJed Brown 
150fe1899a2SJed Brown    Input Arguments:
151fe1899a2SJed Brown +  dm - the shell DM
152fe1899a2SJed Brown -  func - the function to create a matrix
153fe1899a2SJed Brown 
154fe1899a2SJed Brown    Level: advanced
155fe1899a2SJed Brown 
156fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetMatrix()
157fe1899a2SJed Brown @*/
15819fd82e9SBarry Smith PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,MatType,Mat*))
159fe1899a2SJed Brown {
160fe1899a2SJed Brown 
161fe1899a2SJed Brown   PetscFunctionBegin;
162fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
163fe1899a2SJed Brown   dm->ops->creatematrix = func;
164fe1899a2SJed Brown   PetscFunctionReturn(0);
165fe1899a2SJed Brown }
166fe1899a2SJed Brown 
167fe1899a2SJed Brown #undef __FUNCT__
168fe1899a2SJed Brown #define __FUNCT__ "DMShellSetGlobalVector"
169fe1899a2SJed Brown /*@
170fe1899a2SJed Brown    DMShellSetGlobalVector - sets a template global vector associated with the DMShell
171fe1899a2SJed Brown 
172fe1899a2SJed Brown    Logically Collective on DM
173fe1899a2SJed Brown 
174fe1899a2SJed Brown    Input Arguments:
175fe1899a2SJed Brown +  dm - shell DM
176fe1899a2SJed Brown -  X - template vector
177fe1899a2SJed Brown 
178fe1899a2SJed Brown    Level: advanced
179fe1899a2SJed Brown 
180fe1899a2SJed Brown .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector()
181fe1899a2SJed Brown @*/
182fe1899a2SJed Brown PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X)
183fe1899a2SJed Brown {
184fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
185fe1899a2SJed Brown   PetscErrorCode ierr;
1868c87107bSJed Brown   PetscBool      isshell;
187fe1899a2SJed Brown 
188fe1899a2SJed Brown   PetscFunctionBegin;
1898c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1908c87107bSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
191251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
1928c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
193fe1899a2SJed Brown   ierr           = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
194fe1899a2SJed Brown   ierr           = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
195fe1899a2SJed Brown   shell->Xglobal = X;
196fe1899a2SJed Brown   PetscFunctionReturn(0);
197fe1899a2SJed Brown }
198fe1899a2SJed Brown 
199fe1899a2SJed Brown #undef __FUNCT__
200fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateGlobalVector"
201fe1899a2SJed Brown /*@C
202fe1899a2SJed Brown    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
203fe1899a2SJed Brown 
204fe1899a2SJed Brown    Logically Collective
205fe1899a2SJed Brown 
206fe1899a2SJed Brown    Input Arguments:
207fe1899a2SJed Brown +  dm - the shell DM
208fe1899a2SJed Brown -  func - the creation routine
209fe1899a2SJed Brown 
210fe1899a2SJed Brown    Level: advanced
211fe1899a2SJed Brown 
212fe1899a2SJed Brown .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix()
213fe1899a2SJed Brown @*/
214fe1899a2SJed Brown PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
215fe1899a2SJed Brown {
216fe1899a2SJed Brown 
217fe1899a2SJed Brown   PetscFunctionBegin;
218fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
219fe1899a2SJed Brown   dm->ops->createglobalvector = func;
220fe1899a2SJed Brown   PetscFunctionReturn(0);
221fe1899a2SJed Brown }
222fe1899a2SJed Brown 
223fe1899a2SJed Brown #undef __FUNCT__
224dc43b69eSJed Brown #define __FUNCT__ "DMShellSetLocalVector"
225dc43b69eSJed Brown /*@
226dc43b69eSJed Brown    DMShellSetLocalVector - sets a template local vector associated with the DMShell
227dc43b69eSJed Brown 
228dc43b69eSJed Brown    Logically Collective on DM
229dc43b69eSJed Brown 
230dc43b69eSJed Brown    Input Arguments:
231dc43b69eSJed Brown +  dm - shell DM
232dc43b69eSJed Brown -  X - template vector
233dc43b69eSJed Brown 
234dc43b69eSJed Brown    Level: advanced
235dc43b69eSJed Brown 
236dc43b69eSJed Brown .seealso: DMCreateLocalVector(), DMShellSetMatrix(), DMShellSetCreateLocalVector()
237dc43b69eSJed Brown @*/
238dc43b69eSJed Brown PetscErrorCode DMShellSetLocalVector(DM dm,Vec X)
239dc43b69eSJed Brown {
240dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
241dc43b69eSJed Brown   PetscErrorCode ierr;
242dc43b69eSJed Brown   PetscBool      isshell;
243dc43b69eSJed Brown 
244dc43b69eSJed Brown   PetscFunctionBegin;
245dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
246dc43b69eSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
247dc43b69eSJed Brown   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
248dc43b69eSJed Brown   if (!isshell) PetscFunctionReturn(0);
249dc43b69eSJed Brown   ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
250dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
251dc43b69eSJed Brown   shell->Xlocal = X;
252dc43b69eSJed Brown   PetscFunctionReturn(0);
253dc43b69eSJed Brown }
254dc43b69eSJed Brown 
255dc43b69eSJed Brown #undef __FUNCT__
256dc43b69eSJed Brown #define __FUNCT__ "DMShellSetCreateLocalVector"
257dc43b69eSJed Brown /*@C
258dc43b69eSJed Brown    DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM
259dc43b69eSJed Brown 
260dc43b69eSJed Brown    Logically Collective
261dc43b69eSJed Brown 
262dc43b69eSJed Brown    Input Arguments:
263dc43b69eSJed Brown +  dm - the shell DM
264dc43b69eSJed Brown -  func - the creation routine
265dc43b69eSJed Brown 
266dc43b69eSJed Brown    Level: advanced
267dc43b69eSJed Brown 
268dc43b69eSJed Brown .seealso: DMShellSetLocalVector(), DMShellSetCreateMatrix()
269dc43b69eSJed Brown @*/
270dc43b69eSJed Brown PetscErrorCode DMShellSetCreateLocalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
271dc43b69eSJed Brown {
272dc43b69eSJed Brown 
273dc43b69eSJed Brown   PetscFunctionBegin;
274dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
275dc43b69eSJed Brown   dm->ops->createlocalvector = func;
276dc43b69eSJed Brown   PetscFunctionReturn(0);
277dc43b69eSJed Brown }
278dc43b69eSJed Brown 
279dc43b69eSJed Brown #undef __FUNCT__
2808339e6d0SRichard Tran Mills #define __FUNCT__ "DMShellSetGlobalToLocal"
2818339e6d0SRichard Tran Mills /*@C
2828339e6d0SRichard Tran Mills    DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter
2838339e6d0SRichard Tran Mills 
2848339e6d0SRichard Tran Mills    Logically Collective on DM
2858339e6d0SRichard Tran Mills 
2868339e6d0SRichard Tran Mills    Input Arguments
2878339e6d0SRichard Tran Mills +  dm - the shell DM
2888339e6d0SRichard Tran Mills .  begin - the routine that begins the global to local scatter
2898339e6d0SRichard Tran Mills -  end - the routine that ends the global to local scatter
2908339e6d0SRichard Tran Mills 
2918339e6d0SRichard Tran Mills    Level: advanced
2928339e6d0SRichard Tran Mills 
2938339e6d0SRichard Tran Mills .seealso: DMShellSetLocalToGlobal()
2948339e6d0SRichard Tran Mills @*/
2958339e6d0SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
2968339e6d0SRichard Tran Mills   PetscFunctionBegin;
2978339e6d0SRichard Tran Mills   dm->ops->globaltolocalbegin = begin;
2988339e6d0SRichard Tran Mills   dm->ops->globaltolocalend = end;
2998339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
3008339e6d0SRichard Tran Mills }
3018339e6d0SRichard Tran Mills 
3028339e6d0SRichard Tran Mills #undef __FUNCT__
3038339e6d0SRichard Tran Mills #define __FUNCT__ "DMShellSetLocalToGlobal"
3048339e6d0SRichard Tran Mills /*@C
3058339e6d0SRichard Tran Mills    DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter
3068339e6d0SRichard Tran Mills 
3078339e6d0SRichard Tran Mills    Logically Collective on DM
3088339e6d0SRichard Tran Mills 
3098339e6d0SRichard Tran Mills    Input Arguments
3108339e6d0SRichard Tran Mills +  dm - the shell DM
3118339e6d0SRichard Tran Mills .  begin - the routine that begins the local to global scatter
3128339e6d0SRichard Tran Mills -  end - the routine that ends the local to global scatter
3138339e6d0SRichard Tran Mills 
3148339e6d0SRichard Tran Mills    Level: advanced
3158339e6d0SRichard Tran Mills 
3168339e6d0SRichard Tran Mills .seealso: DMShellSetGlobalToLocal()
3178339e6d0SRichard Tran Mills @*/
3188339e6d0SRichard Tran Mills PetscErrorCode DMShellSetLocalToGlobal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) {
3198339e6d0SRichard Tran Mills   PetscFunctionBegin;
3208339e6d0SRichard Tran Mills   dm->ops->localtoglobalbegin = begin;
3218339e6d0SRichard Tran Mills   dm->ops->localtoglobalend = end;
3228339e6d0SRichard Tran Mills   PetscFunctionReturn(0);
3238339e6d0SRichard Tran Mills }
3248339e6d0SRichard Tran Mills 
3258339e6d0SRichard Tran Mills #undef __FUNCT__
32681634712SRichard Tran Mills #define __FUNCT__ "DMShellSetGlobalToLocalVecScatter"
32781634712SRichard Tran Mills /*@
32881634712SRichard Tran Mills    DMShellSetGlobalToLocalVecScatter - Sets a VecScatter context for global to local communication
32981634712SRichard Tran Mills 
33081634712SRichard Tran Mills    Logically Collective on DM
33181634712SRichard Tran Mills 
33281634712SRichard Tran Mills    Input Arguments
33381634712SRichard Tran Mills +  dm - the shell DM
33481634712SRichard Tran Mills -  gtol - the global to local VecScatter context
33581634712SRichard Tran Mills 
33681634712SRichard Tran Mills    Level: advanced
33781634712SRichard Tran Mills 
33881634712SRichard Tran Mills .seealso: DMShellSetGlobalToLocal()
33981634712SRichard Tran Mills @*/
34081634712SRichard Tran Mills PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter *gtol)
34181634712SRichard Tran Mills {
34281634712SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
34381634712SRichard Tran Mills 
344*b300e4a8SRichard Tran Mills   PetscFunctionBegin;
34581634712SRichard Tran Mills   shell->gtol = gtol;
34681634712SRichard Tran Mills   PetscFunctionReturn(0);
34781634712SRichard Tran Mills }
34881634712SRichard Tran Mills 
34981634712SRichard Tran Mills #undef __FUNCT__
350fe1899a2SJed Brown #define __FUNCT__ "DMDestroy_Shell"
351fe1899a2SJed Brown static PetscErrorCode DMDestroy_Shell(DM dm)
352fe1899a2SJed Brown {
353fe1899a2SJed Brown   PetscErrorCode ierr;
354fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
355fe1899a2SJed Brown 
356fe1899a2SJed Brown   PetscFunctionBegin;
357fe1899a2SJed Brown   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
358fe1899a2SJed Brown   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
359dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
3607b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
3617b6ad80cSMatthew G Knepley   ierr = PetscFree(shell);CHKERRQ(ierr);
362fe1899a2SJed Brown   PetscFunctionReturn(0);
363fe1899a2SJed Brown }
364fe1899a2SJed Brown 
3652d53ad75SBarry Smith #undef __FUNCT__
3662d53ad75SBarry Smith #define __FUNCT__ "DMView_Shell"
3672d53ad75SBarry Smith static PetscErrorCode DMView_Shell(DM dm,PetscViewer v)
3682d53ad75SBarry Smith {
3692d53ad75SBarry Smith   PetscErrorCode ierr;
3702d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
3712d53ad75SBarry Smith 
3722d53ad75SBarry Smith   PetscFunctionBegin;
3732d53ad75SBarry Smith   ierr = VecView(shell->Xglobal,v);CHKERRQ(ierr);
3742d53ad75SBarry Smith   PetscFunctionReturn(0);
3752d53ad75SBarry Smith }
3762d53ad75SBarry Smith 
3772d53ad75SBarry Smith #undef __FUNCT__
3782d53ad75SBarry Smith #define __FUNCT__ "DMLoad_Shell"
3792d53ad75SBarry Smith static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v)
3802d53ad75SBarry Smith {
3812d53ad75SBarry Smith   PetscErrorCode ierr;
3822d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
3832d53ad75SBarry Smith 
3842d53ad75SBarry Smith   PetscFunctionBegin;
385ce94432eSBarry Smith   ierr = VecCreate(PetscObjectComm((PetscObject)dm),&shell->Xglobal);CHKERRQ(ierr);
3862d53ad75SBarry Smith   ierr = VecLoad(shell->Xglobal,v);CHKERRQ(ierr);
3872d53ad75SBarry Smith   PetscFunctionReturn(0);
3882d53ad75SBarry Smith }
389fe1899a2SJed Brown 
390fe1899a2SJed Brown #undef __FUNCT__
391fe1899a2SJed Brown #define __FUNCT__ "DMCreate_Shell"
3928c87107bSJed Brown PETSC_EXTERN_C PetscErrorCode  DMCreate_Shell(DM dm)
393fe1899a2SJed Brown {
394fe1899a2SJed Brown   PetscErrorCode ierr;
395fe1899a2SJed Brown   DM_Shell       *shell;
396fe1899a2SJed Brown 
397fe1899a2SJed Brown   PetscFunctionBegin;
3988c87107bSJed Brown   ierr     = PetscNewLog(dm,DM_Shell,&shell);CHKERRQ(ierr);
3998c87107bSJed Brown   dm->data = shell;
400fe1899a2SJed Brown 
4018c87107bSJed Brown   ierr = PetscObjectChangeTypeName((PetscObject)dm,DMSHELL);CHKERRQ(ierr);
4028865f1eaSKarl Rupp 
4038c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
4048c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
405dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
4068c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
4072d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
4082d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
409fe1899a2SJed Brown   PetscFunctionReturn(0);
410fe1899a2SJed Brown }
411fe1899a2SJed Brown 
412fe1899a2SJed Brown #undef __FUNCT__
413fe1899a2SJed Brown #define __FUNCT__ "DMShellCreate"
414fe1899a2SJed Brown /*@
415fe1899a2SJed Brown     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
416fe1899a2SJed Brown 
417fe1899a2SJed Brown     Collective on MPI_Comm
418fe1899a2SJed Brown 
419fe1899a2SJed Brown     Input Parameter:
420fe1899a2SJed Brown .   comm - the processors that will share the global vector
421fe1899a2SJed Brown 
422fe1899a2SJed Brown     Output Parameters:
423fe1899a2SJed Brown .   shell - the shell DM
424fe1899a2SJed Brown 
425fe1899a2SJed Brown     Level: advanced
426fe1899a2SJed Brown 
427dc43b69eSJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateLocalVector()
428fe1899a2SJed Brown @*/
429fe1899a2SJed Brown PetscErrorCode  DMShellCreate(MPI_Comm comm,DM *dm)
430fe1899a2SJed Brown {
431fe1899a2SJed Brown   PetscErrorCode ierr;
432fe1899a2SJed Brown 
433fe1899a2SJed Brown   PetscFunctionBegin;
434fe1899a2SJed Brown   PetscValidPointer(dm,2);
435fe1899a2SJed Brown   ierr = DMCreate(comm,dm);CHKERRQ(ierr);
436fe1899a2SJed Brown   ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr);
437fe1899a2SJed Brown   PetscFunctionReturn(0);
438fe1899a2SJed Brown }
43981634712SRichard Tran Mills 
44081634712SRichard Tran Mills #undef __FUNCT__
44181634712SRichard Tran Mills #define __FUNCT__ "DMShellDefaultGlobalToLocalBegin"
44281634712SRichard Tran Mills /*@
44381634712SRichard Tran Mills    DMShellDefaultGlobalToLocalBegin - Uses the GlobalToLocal VecScatter context set by the user to begin a global to local scatter
44481634712SRichard Tran Mills    Collective
44581634712SRichard Tran Mills 
44681634712SRichard Tran Mills    Input Arguments:
44781634712SRichard Tran Mills +  dm - shell DM
44881634712SRichard Tran Mills .  g - global vector
44981634712SRichard Tran Mills .  mode - InsertMode
45081634712SRichard Tran Mills -  l - local vector
45181634712SRichard Tran Mills 
45281634712SRichard Tran Mills    Level: advanced
45381634712SRichard Tran Mills 
45481634712SRichard Tran Mills .seealso: DMShellDefaultGlobalToLocalEnd()
45581634712SRichard Tran Mills @*/
45681634712SRichard Tran Mills PetscErrorCode DMShellDefaultGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
45781634712SRichard Tran Mills {
45881634712SRichard Tran Mills   PetscErrorCode ierr;
45981634712SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
46081634712SRichard Tran Mills 
46181634712SRichard Tran Mills   PetscFunctionBegin;
46281634712SRichard Tran Mills   ierr = VecScatterBegin(*(shell->gtol),g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
46381634712SRichard Tran Mills   PetscFunctionReturn(0);
46481634712SRichard Tran Mills }
46581634712SRichard Tran Mills 
46681634712SRichard Tran Mills #undef __FUNCT__
46781634712SRichard Tran Mills #define __FUNCT__ "DMShellDefaultGlobalToLocalEnd"
46881634712SRichard Tran Mills /*@
46981634712SRichard Tran Mills    DMShellDefaultGlobalToLocalEnd - Uses the GlobalToLocal VecScatter context set by the user to end a global to local scatter
47081634712SRichard Tran Mills    Collective
47181634712SRichard Tran Mills 
47281634712SRichard Tran Mills    Input Arguments:
47381634712SRichard Tran Mills +  dm - shell DM
47481634712SRichard Tran Mills .  g - global vector
47581634712SRichard Tran Mills .  mode - InsertMode
47681634712SRichard Tran Mills -  l - local vector
47781634712SRichard Tran Mills 
47881634712SRichard Tran Mills    Level: advanced
47981634712SRichard Tran Mills 
48081634712SRichard Tran Mills .seealso: DMShellDefaultGlobalToLocalBegin()
48181634712SRichard Tran Mills @*/
48281634712SRichard Tran Mills PetscErrorCode DMShellDefaultGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
48381634712SRichard Tran Mills {
48481634712SRichard Tran Mills   PetscErrorCode ierr;
48581634712SRichard Tran Mills   DM_Shell       *shell = (DM_Shell*)dm->data;
48681634712SRichard Tran Mills 
48781634712SRichard Tran Mills   PetscFunctionBegin;
48881634712SRichard Tran Mills   ierr = VecScatterEnd(*(shell->gtol),g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
48981634712SRichard Tran Mills   PetscFunctionReturn(0);
49081634712SRichard Tran Mills }
491