xref: /petsc/src/dm/dt/fv/interface/fv.c (revision 02a061ebd9e5b6a884908c37a797d6556f37b08b)
1c0ce001eSMatthew G. Knepley #include <petsc/private/petscfvimpl.h> /*I "petscfv.h" I*/
2c0ce001eSMatthew G. Knepley #include <petsc/private/dmpleximpl.h> /* For CellRefiner */
3c0ce001eSMatthew G. Knepley #include <petscds.h>
4c0ce001eSMatthew G. Knepley 
5c0ce001eSMatthew G. Knepley PetscClassId PETSCLIMITER_CLASSID = 0;
6c0ce001eSMatthew G. Knepley 
7c0ce001eSMatthew G. Knepley PetscFunctionList PetscLimiterList              = NULL;
8c0ce001eSMatthew G. Knepley PetscBool         PetscLimiterRegisterAllCalled = PETSC_FALSE;
9c0ce001eSMatthew G. Knepley 
10c0ce001eSMatthew G. Knepley PetscBool Limitercite = PETSC_FALSE;
11c0ce001eSMatthew G. Knepley const char LimiterCitation[] = "@article{BergerAftosmisMurman2005,\n"
12c0ce001eSMatthew G. Knepley                                "  title   = {Analysis of slope limiters on irregular grids},\n"
13c0ce001eSMatthew G. Knepley                                "  journal = {AIAA paper},\n"
14c0ce001eSMatthew G. Knepley                                "  author  = {Marsha Berger and Michael J. Aftosmis and Scott M. Murman},\n"
15c0ce001eSMatthew G. Knepley                                "  volume  = {490},\n"
16c0ce001eSMatthew G. Knepley                                "  year    = {2005}\n}\n";
17c0ce001eSMatthew G. Knepley 
18c0ce001eSMatthew G. Knepley /*@C
19c0ce001eSMatthew G. Knepley   PetscLimiterRegister - Adds a new PetscLimiter implementation
20c0ce001eSMatthew G. Knepley 
21c0ce001eSMatthew G. Knepley   Not Collective
22c0ce001eSMatthew G. Knepley 
23c0ce001eSMatthew G. Knepley   Input Parameters:
24c0ce001eSMatthew G. Knepley + name        - The name of a new user-defined creation routine
25c0ce001eSMatthew G. Knepley - create_func - The creation routine itself
26c0ce001eSMatthew G. Knepley 
27c0ce001eSMatthew G. Knepley   Notes:
28c0ce001eSMatthew G. Knepley   PetscLimiterRegister() may be called multiple times to add several user-defined PetscLimiters
29c0ce001eSMatthew G. Knepley 
30c0ce001eSMatthew G. Knepley   Sample usage:
31c0ce001eSMatthew G. Knepley .vb
32c0ce001eSMatthew G. Knepley     PetscLimiterRegister("my_lim", MyPetscLimiterCreate);
33c0ce001eSMatthew G. Knepley .ve
34c0ce001eSMatthew G. Knepley 
35c0ce001eSMatthew G. Knepley   Then, your PetscLimiter type can be chosen with the procedural interface via
36c0ce001eSMatthew G. Knepley .vb
37c0ce001eSMatthew G. Knepley     PetscLimiterCreate(MPI_Comm, PetscLimiter *);
38c0ce001eSMatthew G. Knepley     PetscLimiterSetType(PetscLimiter, "my_lim");
39c0ce001eSMatthew G. Knepley .ve
40c0ce001eSMatthew G. Knepley    or at runtime via the option
41c0ce001eSMatthew G. Knepley .vb
42c0ce001eSMatthew G. Knepley     -petsclimiter_type my_lim
43c0ce001eSMatthew G. Knepley .ve
44c0ce001eSMatthew G. Knepley 
45c0ce001eSMatthew G. Knepley   Level: advanced
46c0ce001eSMatthew G. Knepley 
47c0ce001eSMatthew G. Knepley .seealso: PetscLimiterRegisterAll(), PetscLimiterRegisterDestroy()
48c0ce001eSMatthew G. Knepley 
49c0ce001eSMatthew G. Knepley @*/
50c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterRegister(const char sname[], PetscErrorCode (*function)(PetscLimiter))
51c0ce001eSMatthew G. Knepley {
52c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
53c0ce001eSMatthew G. Knepley 
54c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
55c0ce001eSMatthew G. Knepley   ierr = PetscFunctionListAdd(&PetscLimiterList, sname, function);CHKERRQ(ierr);
56c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
57c0ce001eSMatthew G. Knepley }
58c0ce001eSMatthew G. Knepley 
59c0ce001eSMatthew G. Knepley /*@C
60c0ce001eSMatthew G. Knepley   PetscLimiterSetType - Builds a particular PetscLimiter
61c0ce001eSMatthew G. Knepley 
62c0ce001eSMatthew G. Knepley   Collective on lim
63c0ce001eSMatthew G. Knepley 
64c0ce001eSMatthew G. Knepley   Input Parameters:
65c0ce001eSMatthew G. Knepley + lim  - The PetscLimiter object
66c0ce001eSMatthew G. Knepley - name - The kind of limiter
67c0ce001eSMatthew G. Knepley 
68c0ce001eSMatthew G. Knepley   Options Database Key:
69c0ce001eSMatthew G. Knepley . -petsclimiter_type <type> - Sets the PetscLimiter type; use -help for a list of available types
70c0ce001eSMatthew G. Knepley 
71c0ce001eSMatthew G. Knepley   Level: intermediate
72c0ce001eSMatthew G. Knepley 
73c0ce001eSMatthew G. Knepley .seealso: PetscLimiterGetType(), PetscLimiterCreate()
74c0ce001eSMatthew G. Knepley @*/
75c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterSetType(PetscLimiter lim, PetscLimiterType name)
76c0ce001eSMatthew G. Knepley {
77c0ce001eSMatthew G. Knepley   PetscErrorCode (*r)(PetscLimiter);
78c0ce001eSMatthew G. Knepley   PetscBool      match;
79c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
80c0ce001eSMatthew G. Knepley 
81c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
82c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
83c0ce001eSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) lim, name, &match);CHKERRQ(ierr);
84c0ce001eSMatthew G. Knepley   if (match) PetscFunctionReturn(0);
85c0ce001eSMatthew G. Knepley 
86c0ce001eSMatthew G. Knepley   ierr = PetscLimiterRegisterAll();CHKERRQ(ierr);
87c0ce001eSMatthew G. Knepley   ierr = PetscFunctionListFind(PetscLimiterList, name, &r);CHKERRQ(ierr);
88c0ce001eSMatthew G. Knepley   if (!r) SETERRQ1(PetscObjectComm((PetscObject) lim), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscLimiter type: %s", name);
89c0ce001eSMatthew G. Knepley 
90c0ce001eSMatthew G. Knepley   if (lim->ops->destroy) {
91c0ce001eSMatthew G. Knepley     ierr              = (*lim->ops->destroy)(lim);CHKERRQ(ierr);
92c0ce001eSMatthew G. Knepley     lim->ops->destroy = NULL;
93c0ce001eSMatthew G. Knepley   }
94c0ce001eSMatthew G. Knepley   ierr = (*r)(lim);CHKERRQ(ierr);
95c0ce001eSMatthew G. Knepley   ierr = PetscObjectChangeTypeName((PetscObject) lim, name);CHKERRQ(ierr);
96c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
97c0ce001eSMatthew G. Knepley }
98c0ce001eSMatthew G. Knepley 
99c0ce001eSMatthew G. Knepley /*@C
100c0ce001eSMatthew G. Knepley   PetscLimiterGetType - Gets the PetscLimiter type name (as a string) from the object.
101c0ce001eSMatthew G. Knepley 
102c0ce001eSMatthew G. Knepley   Not Collective
103c0ce001eSMatthew G. Knepley 
104c0ce001eSMatthew G. Knepley   Input Parameter:
105c0ce001eSMatthew G. Knepley . lim  - The PetscLimiter
106c0ce001eSMatthew G. Knepley 
107c0ce001eSMatthew G. Knepley   Output Parameter:
108c0ce001eSMatthew G. Knepley . name - The PetscLimiter type name
109c0ce001eSMatthew G. Knepley 
110c0ce001eSMatthew G. Knepley   Level: intermediate
111c0ce001eSMatthew G. Knepley 
112c0ce001eSMatthew G. Knepley .seealso: PetscLimiterSetType(), PetscLimiterCreate()
113c0ce001eSMatthew G. Knepley @*/
114c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterGetType(PetscLimiter lim, PetscLimiterType *name)
115c0ce001eSMatthew G. Knepley {
116c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
117c0ce001eSMatthew G. Knepley 
118c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
119c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
120c0ce001eSMatthew G. Knepley   PetscValidPointer(name, 2);
121c0ce001eSMatthew G. Knepley   ierr = PetscLimiterRegisterAll();CHKERRQ(ierr);
122c0ce001eSMatthew G. Knepley   *name = ((PetscObject) lim)->type_name;
123c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
124c0ce001eSMatthew G. Knepley }
125c0ce001eSMatthew G. Knepley 
126c0ce001eSMatthew G. Knepley /*@C
127c0ce001eSMatthew G. Knepley   PetscLimiterView - Views a PetscLimiter
128c0ce001eSMatthew G. Knepley 
129c0ce001eSMatthew G. Knepley   Collective on lim
130c0ce001eSMatthew G. Knepley 
131c0ce001eSMatthew G. Knepley   Input Parameter:
132c0ce001eSMatthew G. Knepley + lim - the PetscLimiter object to view
133c0ce001eSMatthew G. Knepley - v   - the viewer
134c0ce001eSMatthew G. Knepley 
13588f5f89eSMatthew G. Knepley   Level: beginner
136c0ce001eSMatthew G. Knepley 
137c0ce001eSMatthew G. Knepley .seealso: PetscLimiterDestroy()
138c0ce001eSMatthew G. Knepley @*/
139c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterView(PetscLimiter lim, PetscViewer v)
140c0ce001eSMatthew G. Knepley {
141c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
142c0ce001eSMatthew G. Knepley 
143c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
144c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
145c0ce001eSMatthew G. Knepley   if (!v) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) lim), &v);CHKERRQ(ierr);}
146c0ce001eSMatthew G. Knepley   if (lim->ops->view) {ierr = (*lim->ops->view)(lim, v);CHKERRQ(ierr);}
147c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
148c0ce001eSMatthew G. Knepley }
149c0ce001eSMatthew G. Knepley 
150c0ce001eSMatthew G. Knepley /*@
151c0ce001eSMatthew G. Knepley   PetscLimiterSetFromOptions - sets parameters in a PetscLimiter from the options database
152c0ce001eSMatthew G. Knepley 
153c0ce001eSMatthew G. Knepley   Collective on lim
154c0ce001eSMatthew G. Knepley 
155c0ce001eSMatthew G. Knepley   Input Parameter:
156c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to set options for
157c0ce001eSMatthew G. Knepley 
15888f5f89eSMatthew G. Knepley   Level: intermediate
159c0ce001eSMatthew G. Knepley 
160c0ce001eSMatthew G. Knepley .seealso: PetscLimiterView()
161c0ce001eSMatthew G. Knepley @*/
162c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterSetFromOptions(PetscLimiter lim)
163c0ce001eSMatthew G. Knepley {
164c0ce001eSMatthew G. Knepley   const char    *defaultType;
165c0ce001eSMatthew G. Knepley   char           name[256];
166c0ce001eSMatthew G. Knepley   PetscBool      flg;
167c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
168c0ce001eSMatthew G. Knepley 
169c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
170c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
171c0ce001eSMatthew G. Knepley   if (!((PetscObject) lim)->type_name) defaultType = PETSCLIMITERSIN;
172c0ce001eSMatthew G. Knepley   else                                 defaultType = ((PetscObject) lim)->type_name;
173c0ce001eSMatthew G. Knepley   ierr = PetscLimiterRegisterAll();CHKERRQ(ierr);
174c0ce001eSMatthew G. Knepley 
175c0ce001eSMatthew G. Knepley   ierr = PetscObjectOptionsBegin((PetscObject) lim);CHKERRQ(ierr);
176c0ce001eSMatthew G. Knepley   ierr = PetscOptionsFList("-petsclimiter_type", "Finite volume slope limiter", "PetscLimiterSetType", PetscLimiterList, defaultType, name, 256, &flg);CHKERRQ(ierr);
177c0ce001eSMatthew G. Knepley   if (flg) {
178c0ce001eSMatthew G. Knepley     ierr = PetscLimiterSetType(lim, name);CHKERRQ(ierr);
179c0ce001eSMatthew G. Knepley   } else if (!((PetscObject) lim)->type_name) {
180c0ce001eSMatthew G. Knepley     ierr = PetscLimiterSetType(lim, defaultType);CHKERRQ(ierr);
181c0ce001eSMatthew G. Knepley   }
182c0ce001eSMatthew G. Knepley   if (lim->ops->setfromoptions) {ierr = (*lim->ops->setfromoptions)(lim);CHKERRQ(ierr);}
183c0ce001eSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
184c0ce001eSMatthew G. Knepley   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) lim);CHKERRQ(ierr);
185c0ce001eSMatthew G. Knepley   ierr = PetscOptionsEnd();CHKERRQ(ierr);
186c0ce001eSMatthew G. Knepley   ierr = PetscLimiterViewFromOptions(lim, NULL, "-petsclimiter_view");CHKERRQ(ierr);
187c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
188c0ce001eSMatthew G. Knepley }
189c0ce001eSMatthew G. Knepley 
190c0ce001eSMatthew G. Knepley /*@C
191c0ce001eSMatthew G. Knepley   PetscLimiterSetUp - Construct data structures for the PetscLimiter
192c0ce001eSMatthew G. Knepley 
193c0ce001eSMatthew G. Knepley   Collective on lim
194c0ce001eSMatthew G. Knepley 
195c0ce001eSMatthew G. Knepley   Input Parameter:
196c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to setup
197c0ce001eSMatthew G. Knepley 
19888f5f89eSMatthew G. Knepley   Level: intermediate
199c0ce001eSMatthew G. Knepley 
200c0ce001eSMatthew G. Knepley .seealso: PetscLimiterView(), PetscLimiterDestroy()
201c0ce001eSMatthew G. Knepley @*/
202c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterSetUp(PetscLimiter lim)
203c0ce001eSMatthew G. Knepley {
204c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
205c0ce001eSMatthew G. Knepley 
206c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
207c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
208c0ce001eSMatthew G. Knepley   if (lim->ops->setup) {ierr = (*lim->ops->setup)(lim);CHKERRQ(ierr);}
209c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
210c0ce001eSMatthew G. Knepley }
211c0ce001eSMatthew G. Knepley 
212c0ce001eSMatthew G. Knepley /*@
213c0ce001eSMatthew G. Knepley   PetscLimiterDestroy - Destroys a PetscLimiter object
214c0ce001eSMatthew G. Knepley 
215c0ce001eSMatthew G. Knepley   Collective on lim
216c0ce001eSMatthew G. Knepley 
217c0ce001eSMatthew G. Knepley   Input Parameter:
218c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to destroy
219c0ce001eSMatthew G. Knepley 
22088f5f89eSMatthew G. Knepley   Level: beginner
221c0ce001eSMatthew G. Knepley 
222c0ce001eSMatthew G. Knepley .seealso: PetscLimiterView()
223c0ce001eSMatthew G. Knepley @*/
224c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterDestroy(PetscLimiter *lim)
225c0ce001eSMatthew G. Knepley {
226c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
227c0ce001eSMatthew G. Knepley 
228c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
229c0ce001eSMatthew G. Knepley   if (!*lim) PetscFunctionReturn(0);
230c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific((*lim), PETSCLIMITER_CLASSID, 1);
231c0ce001eSMatthew G. Knepley 
232c0ce001eSMatthew G. Knepley   if (--((PetscObject)(*lim))->refct > 0) {*lim = 0; PetscFunctionReturn(0);}
233c0ce001eSMatthew G. Knepley   ((PetscObject) (*lim))->refct = 0;
234c0ce001eSMatthew G. Knepley 
235c0ce001eSMatthew G. Knepley   if ((*lim)->ops->destroy) {ierr = (*(*lim)->ops->destroy)(*lim);CHKERRQ(ierr);}
236c0ce001eSMatthew G. Knepley   ierr = PetscHeaderDestroy(lim);CHKERRQ(ierr);
237c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
238c0ce001eSMatthew G. Knepley }
239c0ce001eSMatthew G. Knepley 
240c0ce001eSMatthew G. Knepley /*@
241c0ce001eSMatthew G. Knepley   PetscLimiterCreate - Creates an empty PetscLimiter object. The type can then be set with PetscLimiterSetType().
242c0ce001eSMatthew G. Knepley 
243c0ce001eSMatthew G. Knepley   Collective
244c0ce001eSMatthew G. Knepley 
245c0ce001eSMatthew G. Knepley   Input Parameter:
246c0ce001eSMatthew G. Knepley . comm - The communicator for the PetscLimiter object
247c0ce001eSMatthew G. Knepley 
248c0ce001eSMatthew G. Knepley   Output Parameter:
249c0ce001eSMatthew G. Knepley . lim - The PetscLimiter object
250c0ce001eSMatthew G. Knepley 
251c0ce001eSMatthew G. Knepley   Level: beginner
252c0ce001eSMatthew G. Knepley 
253c0ce001eSMatthew G. Knepley .seealso: PetscLimiterSetType(), PETSCLIMITERSIN
254c0ce001eSMatthew G. Knepley @*/
255c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterCreate(MPI_Comm comm, PetscLimiter *lim)
256c0ce001eSMatthew G. Knepley {
257c0ce001eSMatthew G. Knepley   PetscLimiter   l;
258c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
259c0ce001eSMatthew G. Knepley 
260c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
261c0ce001eSMatthew G. Knepley   PetscValidPointer(lim, 2);
262c0ce001eSMatthew G. Knepley   ierr = PetscCitationsRegister(LimiterCitation,&Limitercite);CHKERRQ(ierr);
263c0ce001eSMatthew G. Knepley   *lim = NULL;
264c0ce001eSMatthew G. Knepley   ierr = PetscFVInitializePackage();CHKERRQ(ierr);
265c0ce001eSMatthew G. Knepley 
266c0ce001eSMatthew G. Knepley   ierr = PetscHeaderCreate(l, PETSCLIMITER_CLASSID, "PetscLimiter", "Finite Volume Slope Limiter", "PetscLimiter", comm, PetscLimiterDestroy, PetscLimiterView);CHKERRQ(ierr);
267c0ce001eSMatthew G. Knepley 
268c0ce001eSMatthew G. Knepley   *lim = l;
269c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
270c0ce001eSMatthew G. Knepley }
271c0ce001eSMatthew G. Knepley 
27288f5f89eSMatthew G. Knepley /*@
27388f5f89eSMatthew G. Knepley   PetscLimiterLimit - Limit the flux
27488f5f89eSMatthew G. Knepley 
27588f5f89eSMatthew G. Knepley   Input Parameters:
27688f5f89eSMatthew G. Knepley + lim  - The PetscLimiter
27788f5f89eSMatthew G. Knepley - flim - The input field
27888f5f89eSMatthew G. Knepley 
27988f5f89eSMatthew G. Knepley   Output Parameter:
28088f5f89eSMatthew G. Knepley . phi  - The limited field
28188f5f89eSMatthew G. Knepley 
28288f5f89eSMatthew G. Knepley Note: Limiters given in symmetric form following Berger, Aftosmis, and Murman 2005
28388f5f89eSMatthew G. Knepley $ The classical flux-limited formulation is psi(r) where
28488f5f89eSMatthew G. Knepley $
28588f5f89eSMatthew G. Knepley $ r = (u[0] - u[-1]) / (u[1] - u[0])
28688f5f89eSMatthew G. Knepley $
28788f5f89eSMatthew G. Knepley $ The second order TVD region is bounded by
28888f5f89eSMatthew G. Knepley $
28988f5f89eSMatthew G. Knepley $ psi_minmod(r) = min(r,1)      and        psi_superbee(r) = min(2, 2r, max(1,r))
29088f5f89eSMatthew G. Knepley $
29188f5f89eSMatthew G. Knepley $ where all limiters are implicitly clipped to be non-negative. A more convenient slope-limited form is psi(r) =
29288f5f89eSMatthew G. Knepley $ phi(r)(r+1)/2 in which the reconstructed interface values are
29388f5f89eSMatthew G. Knepley $
29488f5f89eSMatthew G. Knepley $ u(v) = u[0] + phi(r) (grad u)[0] v
29588f5f89eSMatthew G. Knepley $
29688f5f89eSMatthew G. Knepley $ where v is the vector from centroid to quadrature point. In these variables, the usual limiters become
29788f5f89eSMatthew G. Knepley $
29888f5f89eSMatthew G. Knepley $ phi_minmod(r) = 2 min(1/(1+r),r/(1+r))   phi_superbee(r) = 2 min(2/(1+r), 2r/(1+r), max(1,r)/(1+r))
29988f5f89eSMatthew G. Knepley $
30088f5f89eSMatthew G. Knepley $ For a nicer symmetric formulation, rewrite in terms of
30188f5f89eSMatthew G. Knepley $
30288f5f89eSMatthew G. Knepley $ f = (u[0] - u[-1]) / (u[1] - u[-1])
30388f5f89eSMatthew G. Knepley $
30488f5f89eSMatthew G. Knepley $ where r(f) = f/(1-f). Not that r(1-f) = (1-f)/f = 1/r(f) so the symmetry condition
30588f5f89eSMatthew G. Knepley $
30688f5f89eSMatthew G. Knepley $ phi(r) = phi(1/r)
30788f5f89eSMatthew G. Knepley $
30888f5f89eSMatthew G. Knepley $ becomes
30988f5f89eSMatthew G. Knepley $
31088f5f89eSMatthew G. Knepley $ w(f) = w(1-f).
31188f5f89eSMatthew G. Knepley $
31288f5f89eSMatthew G. Knepley $ The limiters below implement this final form w(f). The reference methods are
31388f5f89eSMatthew G. Knepley $
31488f5f89eSMatthew G. Knepley $ w_minmod(f) = 2 min(f,(1-f))             w_superbee(r) = 4 min((1-f), f)
31588f5f89eSMatthew G. Knepley 
31688f5f89eSMatthew G. Knepley   Level: beginner
31788f5f89eSMatthew G. Knepley 
31888f5f89eSMatthew G. Knepley .seealso: PetscLimiterSetType(), PetscLimiterCreate()
31988f5f89eSMatthew G. Knepley @*/
320c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterLimit(PetscLimiter lim, PetscReal flim, PetscReal *phi)
321c0ce001eSMatthew G. Knepley {
322c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
323c0ce001eSMatthew G. Knepley 
324c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
325c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
326c0ce001eSMatthew G. Knepley   PetscValidPointer(phi, 3);
327c0ce001eSMatthew G. Knepley   ierr = (*lim->ops->limit)(lim, flim, phi);CHKERRQ(ierr);
328c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
329c0ce001eSMatthew G. Knepley }
330c0ce001eSMatthew G. Knepley 
33188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Sin(PetscLimiter lim)
332c0ce001eSMatthew G. Knepley {
333c0ce001eSMatthew G. Knepley   PetscLimiter_Sin *l = (PetscLimiter_Sin *) lim->data;
334c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
335c0ce001eSMatthew G. Knepley 
336c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
337c0ce001eSMatthew G. Knepley   ierr = PetscFree(l);CHKERRQ(ierr);
338c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
339c0ce001eSMatthew G. Knepley }
340c0ce001eSMatthew G. Knepley 
34188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Sin_Ascii(PetscLimiter lim, PetscViewer viewer)
342c0ce001eSMatthew G. Knepley {
343c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
344c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
345c0ce001eSMatthew G. Knepley 
346c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
347c0ce001eSMatthew G. Knepley   ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr);
348c0ce001eSMatthew G. Knepley   ierr = PetscViewerASCIIPrintf(viewer, "Sin Slope Limiter:\n");CHKERRQ(ierr);
349c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
350c0ce001eSMatthew G. Knepley }
351c0ce001eSMatthew G. Knepley 
35288f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Sin(PetscLimiter lim, PetscViewer viewer)
353c0ce001eSMatthew G. Knepley {
354c0ce001eSMatthew G. Knepley   PetscBool      iascii;
355c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
356c0ce001eSMatthew G. Knepley 
357c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
358c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
359c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
360c0ce001eSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
361c0ce001eSMatthew G. Knepley   if (iascii) {ierr = PetscLimiterView_Sin_Ascii(lim, viewer);CHKERRQ(ierr);}
362c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
363c0ce001eSMatthew G. Knepley }
364c0ce001eSMatthew G. Knepley 
36588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Sin(PetscLimiter lim, PetscReal f, PetscReal *phi)
366c0ce001eSMatthew G. Knepley {
367c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
368c0ce001eSMatthew G. Knepley   *phi = PetscSinReal(PETSC_PI*PetscMax(0, PetscMin(f, 1)));
369c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
370c0ce001eSMatthew G. Knepley }
371c0ce001eSMatthew G. Knepley 
37288f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Sin(PetscLimiter lim)
373c0ce001eSMatthew G. Knepley {
374c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
375c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Sin;
376c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Sin;
377c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Sin;
378c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
379c0ce001eSMatthew G. Knepley }
380c0ce001eSMatthew G. Knepley 
381c0ce001eSMatthew G. Knepley /*MC
382c0ce001eSMatthew G. Knepley   PETSCLIMITERSIN = "sin" - A PetscLimiter object
383c0ce001eSMatthew G. Knepley 
384c0ce001eSMatthew G. Knepley   Level: intermediate
385c0ce001eSMatthew G. Knepley 
386c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType()
387c0ce001eSMatthew G. Knepley M*/
388c0ce001eSMatthew G. Knepley 
389c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Sin(PetscLimiter lim)
390c0ce001eSMatthew G. Knepley {
391c0ce001eSMatthew G. Knepley   PetscLimiter_Sin *l;
392c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
393c0ce001eSMatthew G. Knepley 
394c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
395c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
396c0ce001eSMatthew G. Knepley   ierr      = PetscNewLog(lim, &l);CHKERRQ(ierr);
397c0ce001eSMatthew G. Knepley   lim->data = l;
398c0ce001eSMatthew G. Knepley 
399c0ce001eSMatthew G. Knepley   ierr = PetscLimiterInitialize_Sin(lim);CHKERRQ(ierr);
400c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
401c0ce001eSMatthew G. Knepley }
402c0ce001eSMatthew G. Knepley 
40388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Zero(PetscLimiter lim)
404c0ce001eSMatthew G. Knepley {
405c0ce001eSMatthew G. Knepley   PetscLimiter_Zero *l = (PetscLimiter_Zero *) lim->data;
406c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
407c0ce001eSMatthew G. Knepley 
408c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
409c0ce001eSMatthew G. Knepley   ierr = PetscFree(l);CHKERRQ(ierr);
410c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
411c0ce001eSMatthew G. Knepley }
412c0ce001eSMatthew G. Knepley 
41388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Zero_Ascii(PetscLimiter lim, PetscViewer viewer)
414c0ce001eSMatthew G. Knepley {
415c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
416c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
417c0ce001eSMatthew G. Knepley 
418c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
419c0ce001eSMatthew G. Knepley   ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr);
420c0ce001eSMatthew G. Knepley   ierr = PetscViewerASCIIPrintf(viewer, "Zero Slope Limiter:\n");CHKERRQ(ierr);
421c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
422c0ce001eSMatthew G. Knepley }
423c0ce001eSMatthew G. Knepley 
42488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Zero(PetscLimiter lim, PetscViewer viewer)
425c0ce001eSMatthew G. Knepley {
426c0ce001eSMatthew G. Knepley   PetscBool      iascii;
427c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
428c0ce001eSMatthew G. Knepley 
429c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
430c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
431c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
432c0ce001eSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
433c0ce001eSMatthew G. Knepley   if (iascii) {ierr = PetscLimiterView_Zero_Ascii(lim, viewer);CHKERRQ(ierr);}
434c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
435c0ce001eSMatthew G. Knepley }
436c0ce001eSMatthew G. Knepley 
43788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Zero(PetscLimiter lim, PetscReal f, PetscReal *phi)
438c0ce001eSMatthew G. Knepley {
439c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
440c0ce001eSMatthew G. Knepley   *phi = 0.0;
441c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
442c0ce001eSMatthew G. Knepley }
443c0ce001eSMatthew G. Knepley 
44488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Zero(PetscLimiter lim)
445c0ce001eSMatthew G. Knepley {
446c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
447c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Zero;
448c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Zero;
449c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Zero;
450c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
451c0ce001eSMatthew G. Knepley }
452c0ce001eSMatthew G. Knepley 
453c0ce001eSMatthew G. Knepley /*MC
454c0ce001eSMatthew G. Knepley   PETSCLIMITERZERO = "zero" - A PetscLimiter object
455c0ce001eSMatthew G. Knepley 
456c0ce001eSMatthew G. Knepley   Level: intermediate
457c0ce001eSMatthew G. Knepley 
458c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType()
459c0ce001eSMatthew G. Knepley M*/
460c0ce001eSMatthew G. Knepley 
461c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Zero(PetscLimiter lim)
462c0ce001eSMatthew G. Knepley {
463c0ce001eSMatthew G. Knepley   PetscLimiter_Zero *l;
464c0ce001eSMatthew G. Knepley   PetscErrorCode     ierr;
465c0ce001eSMatthew G. Knepley 
466c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
467c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
468c0ce001eSMatthew G. Knepley   ierr      = PetscNewLog(lim, &l);CHKERRQ(ierr);
469c0ce001eSMatthew G. Knepley   lim->data = l;
470c0ce001eSMatthew G. Knepley 
471c0ce001eSMatthew G. Knepley   ierr = PetscLimiterInitialize_Zero(lim);CHKERRQ(ierr);
472c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
473c0ce001eSMatthew G. Knepley }
474c0ce001eSMatthew G. Knepley 
47588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_None(PetscLimiter lim)
476c0ce001eSMatthew G. Knepley {
477c0ce001eSMatthew G. Knepley   PetscLimiter_None *l = (PetscLimiter_None *) lim->data;
478c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
479c0ce001eSMatthew G. Knepley 
480c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
481c0ce001eSMatthew G. Knepley   ierr = PetscFree(l);CHKERRQ(ierr);
482c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
483c0ce001eSMatthew G. Knepley }
484c0ce001eSMatthew G. Knepley 
48588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_None_Ascii(PetscLimiter lim, PetscViewer viewer)
486c0ce001eSMatthew G. Knepley {
487c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
488c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
489c0ce001eSMatthew G. Knepley 
490c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
491c0ce001eSMatthew G. Knepley   ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr);
492c0ce001eSMatthew G. Knepley   ierr = PetscViewerASCIIPrintf(viewer, "None Slope Limiter:\n");CHKERRQ(ierr);
493c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
494c0ce001eSMatthew G. Knepley }
495c0ce001eSMatthew G. Knepley 
49688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_None(PetscLimiter lim, PetscViewer viewer)
497c0ce001eSMatthew G. Knepley {
498c0ce001eSMatthew G. Knepley   PetscBool      iascii;
499c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
500c0ce001eSMatthew G. Knepley 
501c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
502c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
503c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
504c0ce001eSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
505c0ce001eSMatthew G. Knepley   if (iascii) {ierr = PetscLimiterView_None_Ascii(lim, viewer);CHKERRQ(ierr);}
506c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
507c0ce001eSMatthew G. Knepley }
508c0ce001eSMatthew G. Knepley 
50988f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_None(PetscLimiter lim, PetscReal f, PetscReal *phi)
510c0ce001eSMatthew G. Knepley {
511c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
512c0ce001eSMatthew G. Knepley   *phi = 1.0;
513c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
514c0ce001eSMatthew G. Knepley }
515c0ce001eSMatthew G. Knepley 
51688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_None(PetscLimiter lim)
517c0ce001eSMatthew G. Knepley {
518c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
519c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_None;
520c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_None;
521c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_None;
522c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
523c0ce001eSMatthew G. Knepley }
524c0ce001eSMatthew G. Knepley 
525c0ce001eSMatthew G. Knepley /*MC
526c0ce001eSMatthew G. Knepley   PETSCLIMITERNONE = "none" - A PetscLimiter object
527c0ce001eSMatthew G. Knepley 
528c0ce001eSMatthew G. Knepley   Level: intermediate
529c0ce001eSMatthew G. Knepley 
530c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType()
531c0ce001eSMatthew G. Knepley M*/
532c0ce001eSMatthew G. Knepley 
533c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_None(PetscLimiter lim)
534c0ce001eSMatthew G. Knepley {
535c0ce001eSMatthew G. Knepley   PetscLimiter_None *l;
536c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
537c0ce001eSMatthew G. Knepley 
538c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
539c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
540c0ce001eSMatthew G. Knepley   ierr      = PetscNewLog(lim, &l);CHKERRQ(ierr);
541c0ce001eSMatthew G. Knepley   lim->data = l;
542c0ce001eSMatthew G. Knepley 
543c0ce001eSMatthew G. Knepley   ierr = PetscLimiterInitialize_None(lim);CHKERRQ(ierr);
544c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
545c0ce001eSMatthew G. Knepley }
546c0ce001eSMatthew G. Knepley 
54788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Minmod(PetscLimiter lim)
548c0ce001eSMatthew G. Knepley {
549c0ce001eSMatthew G. Knepley   PetscLimiter_Minmod *l = (PetscLimiter_Minmod *) lim->data;
550c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
551c0ce001eSMatthew G. Knepley 
552c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
553c0ce001eSMatthew G. Knepley   ierr = PetscFree(l);CHKERRQ(ierr);
554c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
555c0ce001eSMatthew G. Knepley }
556c0ce001eSMatthew G. Knepley 
55788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Minmod_Ascii(PetscLimiter lim, PetscViewer viewer)
558c0ce001eSMatthew G. Knepley {
559c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
560c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
561c0ce001eSMatthew G. Knepley 
562c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
563c0ce001eSMatthew G. Knepley   ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr);
564c0ce001eSMatthew G. Knepley   ierr = PetscViewerASCIIPrintf(viewer, "Minmod Slope Limiter:\n");CHKERRQ(ierr);
565c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
566c0ce001eSMatthew G. Knepley }
567c0ce001eSMatthew G. Knepley 
56888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Minmod(PetscLimiter lim, PetscViewer viewer)
569c0ce001eSMatthew G. Knepley {
570c0ce001eSMatthew G. Knepley   PetscBool      iascii;
571c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
572c0ce001eSMatthew G. Knepley 
573c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
574c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
575c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
576c0ce001eSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
577c0ce001eSMatthew G. Knepley   if (iascii) {ierr = PetscLimiterView_Minmod_Ascii(lim, viewer);CHKERRQ(ierr);}
578c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
579c0ce001eSMatthew G. Knepley }
580c0ce001eSMatthew G. Knepley 
58188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Minmod(PetscLimiter lim, PetscReal f, PetscReal *phi)
582c0ce001eSMatthew G. Knepley {
583c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
584c0ce001eSMatthew G. Knepley   *phi = 2*PetscMax(0, PetscMin(f, 1-f));
585c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
586c0ce001eSMatthew G. Knepley }
587c0ce001eSMatthew G. Knepley 
58888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Minmod(PetscLimiter lim)
589c0ce001eSMatthew G. Knepley {
590c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
591c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Minmod;
592c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Minmod;
593c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Minmod;
594c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
595c0ce001eSMatthew G. Knepley }
596c0ce001eSMatthew G. Knepley 
597c0ce001eSMatthew G. Knepley /*MC
598c0ce001eSMatthew G. Knepley   PETSCLIMITERMINMOD = "minmod" - A PetscLimiter object
599c0ce001eSMatthew G. Knepley 
600c0ce001eSMatthew G. Knepley   Level: intermediate
601c0ce001eSMatthew G. Knepley 
602c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType()
603c0ce001eSMatthew G. Knepley M*/
604c0ce001eSMatthew G. Knepley 
605c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Minmod(PetscLimiter lim)
606c0ce001eSMatthew G. Knepley {
607c0ce001eSMatthew G. Knepley   PetscLimiter_Minmod *l;
608c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
609c0ce001eSMatthew G. Knepley 
610c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
611c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
612c0ce001eSMatthew G. Knepley   ierr      = PetscNewLog(lim, &l);CHKERRQ(ierr);
613c0ce001eSMatthew G. Knepley   lim->data = l;
614c0ce001eSMatthew G. Knepley 
615c0ce001eSMatthew G. Knepley   ierr = PetscLimiterInitialize_Minmod(lim);CHKERRQ(ierr);
616c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
617c0ce001eSMatthew G. Knepley }
618c0ce001eSMatthew G. Knepley 
61988f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_VanLeer(PetscLimiter lim)
620c0ce001eSMatthew G. Knepley {
621c0ce001eSMatthew G. Knepley   PetscLimiter_VanLeer *l = (PetscLimiter_VanLeer *) lim->data;
622c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
623c0ce001eSMatthew G. Knepley 
624c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
625c0ce001eSMatthew G. Knepley   ierr = PetscFree(l);CHKERRQ(ierr);
626c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
627c0ce001eSMatthew G. Knepley }
628c0ce001eSMatthew G. Knepley 
62988f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanLeer_Ascii(PetscLimiter lim, PetscViewer viewer)
630c0ce001eSMatthew G. Knepley {
631c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
632c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
633c0ce001eSMatthew G. Knepley 
634c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
635c0ce001eSMatthew G. Knepley   ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr);
636c0ce001eSMatthew G. Knepley   ierr = PetscViewerASCIIPrintf(viewer, "Van Leer Slope Limiter:\n");CHKERRQ(ierr);
637c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
638c0ce001eSMatthew G. Knepley }
639c0ce001eSMatthew G. Knepley 
64088f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanLeer(PetscLimiter lim, PetscViewer viewer)
641c0ce001eSMatthew G. Knepley {
642c0ce001eSMatthew G. Knepley   PetscBool      iascii;
643c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
644c0ce001eSMatthew G. Knepley 
645c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
646c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
647c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
648c0ce001eSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
649c0ce001eSMatthew G. Knepley   if (iascii) {ierr = PetscLimiterView_VanLeer_Ascii(lim, viewer);CHKERRQ(ierr);}
650c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
651c0ce001eSMatthew G. Knepley }
652c0ce001eSMatthew G. Knepley 
65388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_VanLeer(PetscLimiter lim, PetscReal f, PetscReal *phi)
654c0ce001eSMatthew G. Knepley {
655c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
656c0ce001eSMatthew G. Knepley   *phi = PetscMax(0, 4*f*(1-f));
657c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
658c0ce001eSMatthew G. Knepley }
659c0ce001eSMatthew G. Knepley 
66088f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_VanLeer(PetscLimiter lim)
661c0ce001eSMatthew G. Knepley {
662c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
663c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_VanLeer;
664c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_VanLeer;
665c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_VanLeer;
666c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
667c0ce001eSMatthew G. Knepley }
668c0ce001eSMatthew G. Knepley 
669c0ce001eSMatthew G. Knepley /*MC
670c0ce001eSMatthew G. Knepley   PETSCLIMITERVANLEER = "vanleer" - A PetscLimiter object
671c0ce001eSMatthew G. Knepley 
672c0ce001eSMatthew G. Knepley   Level: intermediate
673c0ce001eSMatthew G. Knepley 
674c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType()
675c0ce001eSMatthew G. Knepley M*/
676c0ce001eSMatthew G. Knepley 
677c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanLeer(PetscLimiter lim)
678c0ce001eSMatthew G. Knepley {
679c0ce001eSMatthew G. Knepley   PetscLimiter_VanLeer *l;
680c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
681c0ce001eSMatthew G. Knepley 
682c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
683c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
684c0ce001eSMatthew G. Knepley   ierr      = PetscNewLog(lim, &l);CHKERRQ(ierr);
685c0ce001eSMatthew G. Knepley   lim->data = l;
686c0ce001eSMatthew G. Knepley 
687c0ce001eSMatthew G. Knepley   ierr = PetscLimiterInitialize_VanLeer(lim);CHKERRQ(ierr);
688c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
689c0ce001eSMatthew G. Knepley }
690c0ce001eSMatthew G. Knepley 
69188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_VanAlbada(PetscLimiter lim)
692c0ce001eSMatthew G. Knepley {
693c0ce001eSMatthew G. Knepley   PetscLimiter_VanAlbada *l = (PetscLimiter_VanAlbada *) lim->data;
694c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
695c0ce001eSMatthew G. Knepley 
696c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
697c0ce001eSMatthew G. Knepley   ierr = PetscFree(l);CHKERRQ(ierr);
698c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
699c0ce001eSMatthew G. Knepley }
700c0ce001eSMatthew G. Knepley 
70188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanAlbada_Ascii(PetscLimiter lim, PetscViewer viewer)
702c0ce001eSMatthew G. Knepley {
703c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
704c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
705c0ce001eSMatthew G. Knepley 
706c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
707c0ce001eSMatthew G. Knepley   ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr);
708c0ce001eSMatthew G. Knepley   ierr = PetscViewerASCIIPrintf(viewer, "Van Albada Slope Limiter:\n");CHKERRQ(ierr);
709c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
710c0ce001eSMatthew G. Knepley }
711c0ce001eSMatthew G. Knepley 
71288f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanAlbada(PetscLimiter lim, PetscViewer viewer)
713c0ce001eSMatthew G. Knepley {
714c0ce001eSMatthew G. Knepley   PetscBool      iascii;
715c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
716c0ce001eSMatthew G. Knepley 
717c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
718c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
719c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
720c0ce001eSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
721c0ce001eSMatthew G. Knepley   if (iascii) {ierr = PetscLimiterView_VanAlbada_Ascii(lim, viewer);CHKERRQ(ierr);}
722c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
723c0ce001eSMatthew G. Knepley }
724c0ce001eSMatthew G. Knepley 
72588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_VanAlbada(PetscLimiter lim, PetscReal f, PetscReal *phi)
726c0ce001eSMatthew G. Knepley {
727c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
728c0ce001eSMatthew G. Knepley   *phi = PetscMax(0, 2*f*(1-f) / (PetscSqr(f) + PetscSqr(1-f)));
729c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
730c0ce001eSMatthew G. Knepley }
731c0ce001eSMatthew G. Knepley 
73288f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_VanAlbada(PetscLimiter lim)
733c0ce001eSMatthew G. Knepley {
734c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
735c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_VanAlbada;
736c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_VanAlbada;
737c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_VanAlbada;
738c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
739c0ce001eSMatthew G. Knepley }
740c0ce001eSMatthew G. Knepley 
741c0ce001eSMatthew G. Knepley /*MC
742c0ce001eSMatthew G. Knepley   PETSCLIMITERVANALBADA = "vanalbada" - A PetscLimiter object
743c0ce001eSMatthew G. Knepley 
744c0ce001eSMatthew G. Knepley   Level: intermediate
745c0ce001eSMatthew G. Knepley 
746c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType()
747c0ce001eSMatthew G. Knepley M*/
748c0ce001eSMatthew G. Knepley 
749c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanAlbada(PetscLimiter lim)
750c0ce001eSMatthew G. Knepley {
751c0ce001eSMatthew G. Knepley   PetscLimiter_VanAlbada *l;
752c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
753c0ce001eSMatthew G. Knepley 
754c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
755c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
756c0ce001eSMatthew G. Knepley   ierr      = PetscNewLog(lim, &l);CHKERRQ(ierr);
757c0ce001eSMatthew G. Knepley   lim->data = l;
758c0ce001eSMatthew G. Knepley 
759c0ce001eSMatthew G. Knepley   ierr = PetscLimiterInitialize_VanAlbada(lim);CHKERRQ(ierr);
760c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
761c0ce001eSMatthew G. Knepley }
762c0ce001eSMatthew G. Knepley 
76388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Superbee(PetscLimiter lim)
764c0ce001eSMatthew G. Knepley {
765c0ce001eSMatthew G. Knepley   PetscLimiter_Superbee *l = (PetscLimiter_Superbee *) lim->data;
766c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
767c0ce001eSMatthew G. Knepley 
768c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
769c0ce001eSMatthew G. Knepley   ierr = PetscFree(l);CHKERRQ(ierr);
770c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
771c0ce001eSMatthew G. Knepley }
772c0ce001eSMatthew G. Knepley 
77388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Superbee_Ascii(PetscLimiter lim, PetscViewer viewer)
774c0ce001eSMatthew G. Knepley {
775c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
776c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
777c0ce001eSMatthew G. Knepley 
778c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
779c0ce001eSMatthew G. Knepley   ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr);
780c0ce001eSMatthew G. Knepley   ierr = PetscViewerASCIIPrintf(viewer, "Superbee Slope Limiter:\n");CHKERRQ(ierr);
781c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
782c0ce001eSMatthew G. Knepley }
783c0ce001eSMatthew G. Knepley 
78488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Superbee(PetscLimiter lim, PetscViewer viewer)
785c0ce001eSMatthew G. Knepley {
786c0ce001eSMatthew G. Knepley   PetscBool      iascii;
787c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
788c0ce001eSMatthew G. Knepley 
789c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
790c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
791c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
792c0ce001eSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
793c0ce001eSMatthew G. Knepley   if (iascii) {ierr = PetscLimiterView_Superbee_Ascii(lim, viewer);CHKERRQ(ierr);}
794c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
795c0ce001eSMatthew G. Knepley }
796c0ce001eSMatthew G. Knepley 
79788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Superbee(PetscLimiter lim, PetscReal f, PetscReal *phi)
798c0ce001eSMatthew G. Knepley {
799c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
800c0ce001eSMatthew G. Knepley   *phi = 4*PetscMax(0, PetscMin(f, 1-f));
801c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
802c0ce001eSMatthew G. Knepley }
803c0ce001eSMatthew G. Knepley 
80488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Superbee(PetscLimiter lim)
805c0ce001eSMatthew G. Knepley {
806c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
807c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Superbee;
808c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Superbee;
809c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Superbee;
810c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
811c0ce001eSMatthew G. Knepley }
812c0ce001eSMatthew G. Knepley 
813c0ce001eSMatthew G. Knepley /*MC
814c0ce001eSMatthew G. Knepley   PETSCLIMITERSUPERBEE = "superbee" - A PetscLimiter object
815c0ce001eSMatthew G. Knepley 
816c0ce001eSMatthew G. Knepley   Level: intermediate
817c0ce001eSMatthew G. Knepley 
818c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType()
819c0ce001eSMatthew G. Knepley M*/
820c0ce001eSMatthew G. Knepley 
821c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Superbee(PetscLimiter lim)
822c0ce001eSMatthew G. Knepley {
823c0ce001eSMatthew G. Knepley   PetscLimiter_Superbee *l;
824c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
825c0ce001eSMatthew G. Knepley 
826c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
827c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
828c0ce001eSMatthew G. Knepley   ierr      = PetscNewLog(lim, &l);CHKERRQ(ierr);
829c0ce001eSMatthew G. Knepley   lim->data = l;
830c0ce001eSMatthew G. Knepley 
831c0ce001eSMatthew G. Knepley   ierr = PetscLimiterInitialize_Superbee(lim);CHKERRQ(ierr);
832c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
833c0ce001eSMatthew G. Knepley }
834c0ce001eSMatthew G. Knepley 
83588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_MC(PetscLimiter lim)
836c0ce001eSMatthew G. Knepley {
837c0ce001eSMatthew G. Knepley   PetscLimiter_MC *l = (PetscLimiter_MC *) lim->data;
838c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
839c0ce001eSMatthew G. Knepley 
840c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
841c0ce001eSMatthew G. Knepley   ierr = PetscFree(l);CHKERRQ(ierr);
842c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
843c0ce001eSMatthew G. Knepley }
844c0ce001eSMatthew G. Knepley 
84588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_MC_Ascii(PetscLimiter lim, PetscViewer viewer)
846c0ce001eSMatthew G. Knepley {
847c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
848c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
849c0ce001eSMatthew G. Knepley 
850c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
851c0ce001eSMatthew G. Knepley   ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr);
852c0ce001eSMatthew G. Knepley   ierr = PetscViewerASCIIPrintf(viewer, "MC Slope Limiter:\n");CHKERRQ(ierr);
853c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
854c0ce001eSMatthew G. Knepley }
855c0ce001eSMatthew G. Knepley 
85688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_MC(PetscLimiter lim, PetscViewer viewer)
857c0ce001eSMatthew G. Knepley {
858c0ce001eSMatthew G. Knepley   PetscBool      iascii;
859c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
860c0ce001eSMatthew G. Knepley 
861c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
862c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
863c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
864c0ce001eSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
865c0ce001eSMatthew G. Knepley   if (iascii) {ierr = PetscLimiterView_MC_Ascii(lim, viewer);CHKERRQ(ierr);}
866c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
867c0ce001eSMatthew G. Knepley }
868c0ce001eSMatthew G. Knepley 
869c0ce001eSMatthew G. Knepley /* aka Barth-Jespersen */
87088f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_MC(PetscLimiter lim, PetscReal f, PetscReal *phi)
871c0ce001eSMatthew G. Knepley {
872c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
873c0ce001eSMatthew G. Knepley   *phi = PetscMin(1, 4*PetscMax(0, PetscMin(f, 1-f)));
874c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
875c0ce001eSMatthew G. Knepley }
876c0ce001eSMatthew G. Knepley 
87788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_MC(PetscLimiter lim)
878c0ce001eSMatthew G. Knepley {
879c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
880c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_MC;
881c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_MC;
882c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_MC;
883c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
884c0ce001eSMatthew G. Knepley }
885c0ce001eSMatthew G. Knepley 
886c0ce001eSMatthew G. Knepley /*MC
887c0ce001eSMatthew G. Knepley   PETSCLIMITERMC = "mc" - A PetscLimiter object
888c0ce001eSMatthew G. Knepley 
889c0ce001eSMatthew G. Knepley   Level: intermediate
890c0ce001eSMatthew G. Knepley 
891c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType()
892c0ce001eSMatthew G. Knepley M*/
893c0ce001eSMatthew G. Knepley 
894c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_MC(PetscLimiter lim)
895c0ce001eSMatthew G. Knepley {
896c0ce001eSMatthew G. Knepley   PetscLimiter_MC *l;
897c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
898c0ce001eSMatthew G. Knepley 
899c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
900c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
901c0ce001eSMatthew G. Knepley   ierr      = PetscNewLog(lim, &l);CHKERRQ(ierr);
902c0ce001eSMatthew G. Knepley   lim->data = l;
903c0ce001eSMatthew G. Knepley 
904c0ce001eSMatthew G. Knepley   ierr = PetscLimiterInitialize_MC(lim);CHKERRQ(ierr);
905c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
906c0ce001eSMatthew G. Knepley }
907c0ce001eSMatthew G. Knepley 
908c0ce001eSMatthew G. Knepley PetscClassId PETSCFV_CLASSID = 0;
909c0ce001eSMatthew G. Knepley 
910c0ce001eSMatthew G. Knepley PetscFunctionList PetscFVList              = NULL;
911c0ce001eSMatthew G. Knepley PetscBool         PetscFVRegisterAllCalled = PETSC_FALSE;
912c0ce001eSMatthew G. Knepley 
913c0ce001eSMatthew G. Knepley /*@C
914c0ce001eSMatthew G. Knepley   PetscFVRegister - Adds a new PetscFV implementation
915c0ce001eSMatthew G. Knepley 
916c0ce001eSMatthew G. Knepley   Not Collective
917c0ce001eSMatthew G. Knepley 
918c0ce001eSMatthew G. Knepley   Input Parameters:
919c0ce001eSMatthew G. Knepley + name        - The name of a new user-defined creation routine
920c0ce001eSMatthew G. Knepley - create_func - The creation routine itself
921c0ce001eSMatthew G. Knepley 
922c0ce001eSMatthew G. Knepley   Notes:
923c0ce001eSMatthew G. Knepley   PetscFVRegister() may be called multiple times to add several user-defined PetscFVs
924c0ce001eSMatthew G. Knepley 
925c0ce001eSMatthew G. Knepley   Sample usage:
926c0ce001eSMatthew G. Knepley .vb
927c0ce001eSMatthew G. Knepley     PetscFVRegister("my_fv", MyPetscFVCreate);
928c0ce001eSMatthew G. Knepley .ve
929c0ce001eSMatthew G. Knepley 
930c0ce001eSMatthew G. Knepley   Then, your PetscFV type can be chosen with the procedural interface via
931c0ce001eSMatthew G. Knepley .vb
932c0ce001eSMatthew G. Knepley     PetscFVCreate(MPI_Comm, PetscFV *);
933c0ce001eSMatthew G. Knepley     PetscFVSetType(PetscFV, "my_fv");
934c0ce001eSMatthew G. Knepley .ve
935c0ce001eSMatthew G. Knepley    or at runtime via the option
936c0ce001eSMatthew G. Knepley .vb
937c0ce001eSMatthew G. Knepley     -petscfv_type my_fv
938c0ce001eSMatthew G. Knepley .ve
939c0ce001eSMatthew G. Knepley 
940c0ce001eSMatthew G. Knepley   Level: advanced
941c0ce001eSMatthew G. Knepley 
942c0ce001eSMatthew G. Knepley .seealso: PetscFVRegisterAll(), PetscFVRegisterDestroy()
943c0ce001eSMatthew G. Knepley 
944c0ce001eSMatthew G. Knepley @*/
945c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVRegister(const char sname[], PetscErrorCode (*function)(PetscFV))
946c0ce001eSMatthew G. Knepley {
947c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
948c0ce001eSMatthew G. Knepley 
949c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
950c0ce001eSMatthew G. Knepley   ierr = PetscFunctionListAdd(&PetscFVList, sname, function);CHKERRQ(ierr);
951c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
952c0ce001eSMatthew G. Knepley }
953c0ce001eSMatthew G. Knepley 
954c0ce001eSMatthew G. Knepley /*@C
955c0ce001eSMatthew G. Knepley   PetscFVSetType - Builds a particular PetscFV
956c0ce001eSMatthew G. Knepley 
957c0ce001eSMatthew G. Knepley   Collective on fvm
958c0ce001eSMatthew G. Knepley 
959c0ce001eSMatthew G. Knepley   Input Parameters:
960c0ce001eSMatthew G. Knepley + fvm  - The PetscFV object
961c0ce001eSMatthew G. Knepley - name - The kind of FVM space
962c0ce001eSMatthew G. Knepley 
963c0ce001eSMatthew G. Knepley   Options Database Key:
964c0ce001eSMatthew G. Knepley . -petscfv_type <type> - Sets the PetscFV type; use -help for a list of available types
965c0ce001eSMatthew G. Knepley 
966c0ce001eSMatthew G. Knepley   Level: intermediate
967c0ce001eSMatthew G. Knepley 
968c0ce001eSMatthew G. Knepley .seealso: PetscFVGetType(), PetscFVCreate()
969c0ce001eSMatthew G. Knepley @*/
970c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetType(PetscFV fvm, PetscFVType name)
971c0ce001eSMatthew G. Knepley {
972c0ce001eSMatthew G. Knepley   PetscErrorCode (*r)(PetscFV);
973c0ce001eSMatthew G. Knepley   PetscBool      match;
974c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
975c0ce001eSMatthew G. Knepley 
976c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
977c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
978c0ce001eSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) fvm, name, &match);CHKERRQ(ierr);
979c0ce001eSMatthew G. Knepley   if (match) PetscFunctionReturn(0);
980c0ce001eSMatthew G. Knepley 
981c0ce001eSMatthew G. Knepley   ierr = PetscFVRegisterAll();CHKERRQ(ierr);
982c0ce001eSMatthew G. Knepley   ierr = PetscFunctionListFind(PetscFVList, name, &r);CHKERRQ(ierr);
983c0ce001eSMatthew G. Knepley   if (!r) SETERRQ1(PetscObjectComm((PetscObject) fvm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscFV type: %s", name);
984c0ce001eSMatthew G. Knepley 
985c0ce001eSMatthew G. Knepley   if (fvm->ops->destroy) {
986c0ce001eSMatthew G. Knepley     ierr              = (*fvm->ops->destroy)(fvm);CHKERRQ(ierr);
987c0ce001eSMatthew G. Knepley     fvm->ops->destroy = NULL;
988c0ce001eSMatthew G. Knepley   }
989c0ce001eSMatthew G. Knepley   ierr = (*r)(fvm);CHKERRQ(ierr);
990c0ce001eSMatthew G. Knepley   ierr = PetscObjectChangeTypeName((PetscObject) fvm, name);CHKERRQ(ierr);
991c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
992c0ce001eSMatthew G. Knepley }
993c0ce001eSMatthew G. Knepley 
994c0ce001eSMatthew G. Knepley /*@C
995c0ce001eSMatthew G. Knepley   PetscFVGetType - Gets the PetscFV type name (as a string) from the object.
996c0ce001eSMatthew G. Knepley 
997c0ce001eSMatthew G. Knepley   Not Collective
998c0ce001eSMatthew G. Knepley 
999c0ce001eSMatthew G. Knepley   Input Parameter:
1000c0ce001eSMatthew G. Knepley . fvm  - The PetscFV
1001c0ce001eSMatthew G. Knepley 
1002c0ce001eSMatthew G. Knepley   Output Parameter:
1003c0ce001eSMatthew G. Knepley . name - The PetscFV type name
1004c0ce001eSMatthew G. Knepley 
1005c0ce001eSMatthew G. Knepley   Level: intermediate
1006c0ce001eSMatthew G. Knepley 
1007c0ce001eSMatthew G. Knepley .seealso: PetscFVSetType(), PetscFVCreate()
1008c0ce001eSMatthew G. Knepley @*/
1009c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetType(PetscFV fvm, PetscFVType *name)
1010c0ce001eSMatthew G. Knepley {
1011c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1012c0ce001eSMatthew G. Knepley 
1013c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1014c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1015c0ce001eSMatthew G. Knepley   PetscValidPointer(name, 2);
1016c0ce001eSMatthew G. Knepley   ierr = PetscFVRegisterAll();CHKERRQ(ierr);
1017c0ce001eSMatthew G. Knepley   *name = ((PetscObject) fvm)->type_name;
1018c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1019c0ce001eSMatthew G. Knepley }
1020c0ce001eSMatthew G. Knepley 
1021c0ce001eSMatthew G. Knepley /*@C
1022c0ce001eSMatthew G. Knepley   PetscFVView - Views a PetscFV
1023c0ce001eSMatthew G. Knepley 
1024c0ce001eSMatthew G. Knepley   Collective on fvm
1025c0ce001eSMatthew G. Knepley 
1026c0ce001eSMatthew G. Knepley   Input Parameter:
1027c0ce001eSMatthew G. Knepley + fvm - the PetscFV object to view
1028c0ce001eSMatthew G. Knepley - v   - the viewer
1029c0ce001eSMatthew G. Knepley 
103088f5f89eSMatthew G. Knepley   Level: beginner
1031c0ce001eSMatthew G. Knepley 
1032c0ce001eSMatthew G. Knepley .seealso: PetscFVDestroy()
1033c0ce001eSMatthew G. Knepley @*/
1034c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVView(PetscFV fvm, PetscViewer v)
1035c0ce001eSMatthew G. Knepley {
1036c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1037c0ce001eSMatthew G. Knepley 
1038c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1039c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1040c0ce001eSMatthew G. Knepley   if (!v) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) fvm), &v);CHKERRQ(ierr);}
1041c0ce001eSMatthew G. Knepley   if (fvm->ops->view) {ierr = (*fvm->ops->view)(fvm, v);CHKERRQ(ierr);}
1042c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1043c0ce001eSMatthew G. Knepley }
1044c0ce001eSMatthew G. Knepley 
1045c0ce001eSMatthew G. Knepley /*@
1046c0ce001eSMatthew G. Knepley   PetscFVSetFromOptions - sets parameters in a PetscFV from the options database
1047c0ce001eSMatthew G. Knepley 
1048c0ce001eSMatthew G. Knepley   Collective on fvm
1049c0ce001eSMatthew G. Knepley 
1050c0ce001eSMatthew G. Knepley   Input Parameter:
1051c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to set options for
1052c0ce001eSMatthew G. Knepley 
1053c0ce001eSMatthew G. Knepley   Options Database Key:
1054c0ce001eSMatthew G. Knepley . -petscfv_compute_gradients <bool> - Determines whether cell gradients are calculated
1055c0ce001eSMatthew G. Knepley 
105688f5f89eSMatthew G. Knepley   Level: intermediate
1057c0ce001eSMatthew G. Knepley 
1058c0ce001eSMatthew G. Knepley .seealso: PetscFVView()
1059c0ce001eSMatthew G. Knepley @*/
1060c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetFromOptions(PetscFV fvm)
1061c0ce001eSMatthew G. Knepley {
1062c0ce001eSMatthew G. Knepley   const char    *defaultType;
1063c0ce001eSMatthew G. Knepley   char           name[256];
1064c0ce001eSMatthew G. Knepley   PetscBool      flg;
1065c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1066c0ce001eSMatthew G. Knepley 
1067c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1068c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1069c0ce001eSMatthew G. Knepley   if (!((PetscObject) fvm)->type_name) defaultType = PETSCFVUPWIND;
1070c0ce001eSMatthew G. Knepley   else                                 defaultType = ((PetscObject) fvm)->type_name;
1071c0ce001eSMatthew G. Knepley   ierr = PetscFVRegisterAll();CHKERRQ(ierr);
1072c0ce001eSMatthew G. Knepley 
1073c0ce001eSMatthew G. Knepley   ierr = PetscObjectOptionsBegin((PetscObject) fvm);CHKERRQ(ierr);
1074c0ce001eSMatthew G. Knepley   ierr = PetscOptionsFList("-petscfv_type", "Finite volume discretization", "PetscFVSetType", PetscFVList, defaultType, name, 256, &flg);CHKERRQ(ierr);
1075c0ce001eSMatthew G. Knepley   if (flg) {
1076c0ce001eSMatthew G. Knepley     ierr = PetscFVSetType(fvm, name);CHKERRQ(ierr);
1077c0ce001eSMatthew G. Knepley   } else if (!((PetscObject) fvm)->type_name) {
1078c0ce001eSMatthew G. Knepley     ierr = PetscFVSetType(fvm, defaultType);CHKERRQ(ierr);
1079c0ce001eSMatthew G. Knepley 
1080c0ce001eSMatthew G. Knepley   }
1081c0ce001eSMatthew G. Knepley   ierr = PetscOptionsBool("-petscfv_compute_gradients", "Compute cell gradients", "PetscFVSetComputeGradients", fvm->computeGradients, &fvm->computeGradients, NULL);CHKERRQ(ierr);
1082c0ce001eSMatthew G. Knepley   if (fvm->ops->setfromoptions) {ierr = (*fvm->ops->setfromoptions)(fvm);CHKERRQ(ierr);}
1083c0ce001eSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
1084c0ce001eSMatthew G. Knepley   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) fvm);CHKERRQ(ierr);
1085c0ce001eSMatthew G. Knepley   ierr = PetscLimiterSetFromOptions(fvm->limiter);CHKERRQ(ierr);
1086c0ce001eSMatthew G. Knepley   ierr = PetscOptionsEnd();CHKERRQ(ierr);
1087c0ce001eSMatthew G. Knepley   ierr = PetscFVViewFromOptions(fvm, NULL, "-petscfv_view");CHKERRQ(ierr);
1088c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1089c0ce001eSMatthew G. Knepley }
1090c0ce001eSMatthew G. Knepley 
1091c0ce001eSMatthew G. Knepley /*@
1092c0ce001eSMatthew G. Knepley   PetscFVSetUp - Construct data structures for the PetscFV
1093c0ce001eSMatthew G. Knepley 
1094c0ce001eSMatthew G. Knepley   Collective on fvm
1095c0ce001eSMatthew G. Knepley 
1096c0ce001eSMatthew G. Knepley   Input Parameter:
1097c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to setup
1098c0ce001eSMatthew G. Knepley 
109988f5f89eSMatthew G. Knepley   Level: intermediate
1100c0ce001eSMatthew G. Knepley 
1101c0ce001eSMatthew G. Knepley .seealso: PetscFVView(), PetscFVDestroy()
1102c0ce001eSMatthew G. Knepley @*/
1103c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetUp(PetscFV fvm)
1104c0ce001eSMatthew G. Knepley {
1105c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1106c0ce001eSMatthew G. Knepley 
1107c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1108c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1109c0ce001eSMatthew G. Knepley   ierr = PetscLimiterSetUp(fvm->limiter);CHKERRQ(ierr);
1110c0ce001eSMatthew G. Knepley   if (fvm->ops->setup) {ierr = (*fvm->ops->setup)(fvm);CHKERRQ(ierr);}
1111c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1112c0ce001eSMatthew G. Knepley }
1113c0ce001eSMatthew G. Knepley 
1114c0ce001eSMatthew G. Knepley /*@
1115c0ce001eSMatthew G. Knepley   PetscFVDestroy - Destroys a PetscFV object
1116c0ce001eSMatthew G. Knepley 
1117c0ce001eSMatthew G. Knepley   Collective on fvm
1118c0ce001eSMatthew G. Knepley 
1119c0ce001eSMatthew G. Knepley   Input Parameter:
1120c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to destroy
1121c0ce001eSMatthew G. Knepley 
112288f5f89eSMatthew G. Knepley   Level: beginner
1123c0ce001eSMatthew G. Knepley 
1124c0ce001eSMatthew G. Knepley .seealso: PetscFVView()
1125c0ce001eSMatthew G. Knepley @*/
1126c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVDestroy(PetscFV *fvm)
1127c0ce001eSMatthew G. Knepley {
1128c0ce001eSMatthew G. Knepley   PetscInt       i;
1129c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1130c0ce001eSMatthew G. Knepley 
1131c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1132c0ce001eSMatthew G. Knepley   if (!*fvm) PetscFunctionReturn(0);
1133c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific((*fvm), PETSCFV_CLASSID, 1);
1134c0ce001eSMatthew G. Knepley 
1135c0ce001eSMatthew G. Knepley   if (--((PetscObject)(*fvm))->refct > 0) {*fvm = 0; PetscFunctionReturn(0);}
1136c0ce001eSMatthew G. Knepley   ((PetscObject) (*fvm))->refct = 0;
1137c0ce001eSMatthew G. Knepley 
1138c0ce001eSMatthew G. Knepley   for (i = 0; i < (*fvm)->numComponents; i++) {
1139c0ce001eSMatthew G. Knepley     ierr = PetscFree((*fvm)->componentNames[i]);CHKERRQ(ierr);
1140c0ce001eSMatthew G. Knepley   }
1141c0ce001eSMatthew G. Knepley   ierr = PetscFree((*fvm)->componentNames);CHKERRQ(ierr);
1142c0ce001eSMatthew G. Knepley   ierr = PetscLimiterDestroy(&(*fvm)->limiter);CHKERRQ(ierr);
1143c0ce001eSMatthew G. Knepley   ierr = PetscDualSpaceDestroy(&(*fvm)->dualSpace);CHKERRQ(ierr);
1144c0ce001eSMatthew G. Knepley   ierr = PetscFree((*fvm)->fluxWork);CHKERRQ(ierr);
1145c0ce001eSMatthew G. Knepley   ierr = PetscQuadratureDestroy(&(*fvm)->quadrature);CHKERRQ(ierr);
1146c0ce001eSMatthew G. Knepley   ierr = PetscFVRestoreTabulation((*fvm), 0, NULL, &(*fvm)->B, &(*fvm)->D, NULL /*&(*fvm)->H*/);CHKERRQ(ierr);
1147c0ce001eSMatthew G. Knepley 
1148c0ce001eSMatthew G. Knepley   if ((*fvm)->ops->destroy) {ierr = (*(*fvm)->ops->destroy)(*fvm);CHKERRQ(ierr);}
1149c0ce001eSMatthew G. Knepley   ierr = PetscHeaderDestroy(fvm);CHKERRQ(ierr);
1150c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1151c0ce001eSMatthew G. Knepley }
1152c0ce001eSMatthew G. Knepley 
1153c0ce001eSMatthew G. Knepley /*@
1154c0ce001eSMatthew G. Knepley   PetscFVCreate - Creates an empty PetscFV object. The type can then be set with PetscFVSetType().
1155c0ce001eSMatthew G. Knepley 
1156c0ce001eSMatthew G. Knepley   Collective
1157c0ce001eSMatthew G. Knepley 
1158c0ce001eSMatthew G. Knepley   Input Parameter:
1159c0ce001eSMatthew G. Knepley . comm - The communicator for the PetscFV object
1160c0ce001eSMatthew G. Knepley 
1161c0ce001eSMatthew G. Knepley   Output Parameter:
1162c0ce001eSMatthew G. Knepley . fvm - The PetscFV object
1163c0ce001eSMatthew G. Knepley 
1164c0ce001eSMatthew G. Knepley   Level: beginner
1165c0ce001eSMatthew G. Knepley 
1166c0ce001eSMatthew G. Knepley .seealso: PetscFVSetType(), PETSCFVUPWIND
1167c0ce001eSMatthew G. Knepley @*/
1168c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVCreate(MPI_Comm comm, PetscFV *fvm)
1169c0ce001eSMatthew G. Knepley {
1170c0ce001eSMatthew G. Knepley   PetscFV        f;
1171c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1172c0ce001eSMatthew G. Knepley 
1173c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1174c0ce001eSMatthew G. Knepley   PetscValidPointer(fvm, 2);
1175c0ce001eSMatthew G. Knepley   *fvm = NULL;
1176c0ce001eSMatthew G. Knepley   ierr = PetscFVInitializePackage();CHKERRQ(ierr);
1177c0ce001eSMatthew G. Knepley 
1178c0ce001eSMatthew G. Knepley   ierr = PetscHeaderCreate(f, PETSCFV_CLASSID, "PetscFV", "Finite Volume", "PetscFV", comm, PetscFVDestroy, PetscFVView);CHKERRQ(ierr);
1179c0ce001eSMatthew G. Knepley   ierr = PetscMemzero(f->ops, sizeof(struct _PetscFVOps));CHKERRQ(ierr);
1180c0ce001eSMatthew G. Knepley 
1181c0ce001eSMatthew G. Knepley   ierr = PetscLimiterCreate(comm, &f->limiter);CHKERRQ(ierr);
1182c0ce001eSMatthew G. Knepley   f->numComponents    = 1;
1183c0ce001eSMatthew G. Knepley   f->dim              = 0;
1184c0ce001eSMatthew G. Knepley   f->computeGradients = PETSC_FALSE;
1185c0ce001eSMatthew G. Knepley   f->fluxWork         = NULL;
1186c0ce001eSMatthew G. Knepley   ierr = PetscCalloc1(f->numComponents,&f->componentNames);CHKERRQ(ierr);
1187c0ce001eSMatthew G. Knepley 
1188c0ce001eSMatthew G. Knepley   *fvm = f;
1189c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1190c0ce001eSMatthew G. Knepley }
1191c0ce001eSMatthew G. Knepley 
1192c0ce001eSMatthew G. Knepley /*@
1193c0ce001eSMatthew G. Knepley   PetscFVSetLimiter - Set the limiter object
1194c0ce001eSMatthew G. Knepley 
1195c0ce001eSMatthew G. Knepley   Logically collective on fvm
1196c0ce001eSMatthew G. Knepley 
1197c0ce001eSMatthew G. Knepley   Input Parameters:
1198c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1199c0ce001eSMatthew G. Knepley - lim - The PetscLimiter
1200c0ce001eSMatthew G. Knepley 
120188f5f89eSMatthew G. Knepley   Level: intermediate
1202c0ce001eSMatthew G. Knepley 
1203c0ce001eSMatthew G. Knepley .seealso: PetscFVGetLimiter()
1204c0ce001eSMatthew G. Knepley @*/
1205c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetLimiter(PetscFV fvm, PetscLimiter lim)
1206c0ce001eSMatthew G. Knepley {
1207c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1208c0ce001eSMatthew G. Knepley 
1209c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1210c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1211c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 2);
1212c0ce001eSMatthew G. Knepley   ierr = PetscLimiterDestroy(&fvm->limiter);CHKERRQ(ierr);
1213c0ce001eSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) lim);CHKERRQ(ierr);
1214c0ce001eSMatthew G. Knepley   fvm->limiter = lim;
1215c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1216c0ce001eSMatthew G. Knepley }
1217c0ce001eSMatthew G. Knepley 
1218c0ce001eSMatthew G. Knepley /*@
1219c0ce001eSMatthew G. Knepley   PetscFVGetLimiter - Get the limiter object
1220c0ce001eSMatthew G. Knepley 
1221c0ce001eSMatthew G. Knepley   Not collective
1222c0ce001eSMatthew G. Knepley 
1223c0ce001eSMatthew G. Knepley   Input Parameter:
1224c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1225c0ce001eSMatthew G. Knepley 
1226c0ce001eSMatthew G. Knepley   Output Parameter:
1227c0ce001eSMatthew G. Knepley . lim - The PetscLimiter
1228c0ce001eSMatthew G. Knepley 
122988f5f89eSMatthew G. Knepley   Level: intermediate
1230c0ce001eSMatthew G. Knepley 
1231c0ce001eSMatthew G. Knepley .seealso: PetscFVSetLimiter()
1232c0ce001eSMatthew G. Knepley @*/
1233c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetLimiter(PetscFV fvm, PetscLimiter *lim)
1234c0ce001eSMatthew G. Knepley {
1235c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1236c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1237c0ce001eSMatthew G. Knepley   PetscValidPointer(lim, 2);
1238c0ce001eSMatthew G. Knepley   *lim = fvm->limiter;
1239c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1240c0ce001eSMatthew G. Knepley }
1241c0ce001eSMatthew G. Knepley 
1242c0ce001eSMatthew G. Knepley /*@
1243c0ce001eSMatthew G. Knepley   PetscFVSetNumComponents - Set the number of field components
1244c0ce001eSMatthew G. Knepley 
1245c0ce001eSMatthew G. Knepley   Logically collective on fvm
1246c0ce001eSMatthew G. Knepley 
1247c0ce001eSMatthew G. Knepley   Input Parameters:
1248c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1249c0ce001eSMatthew G. Knepley - comp - The number of components
1250c0ce001eSMatthew G. Knepley 
125188f5f89eSMatthew G. Knepley   Level: intermediate
1252c0ce001eSMatthew G. Knepley 
1253c0ce001eSMatthew G. Knepley .seealso: PetscFVGetNumComponents()
1254c0ce001eSMatthew G. Knepley @*/
1255c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetNumComponents(PetscFV fvm, PetscInt comp)
1256c0ce001eSMatthew G. Knepley {
1257c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1258c0ce001eSMatthew G. Knepley 
1259c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1260c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1261c0ce001eSMatthew G. Knepley   if (fvm->numComponents != comp) {
1262c0ce001eSMatthew G. Knepley     PetscInt i;
1263c0ce001eSMatthew G. Knepley 
1264c0ce001eSMatthew G. Knepley     for (i = 0; i < fvm->numComponents; i++) {
1265c0ce001eSMatthew G. Knepley       ierr = PetscFree(fvm->componentNames[i]);CHKERRQ(ierr);
1266c0ce001eSMatthew G. Knepley     }
1267c0ce001eSMatthew G. Knepley     ierr = PetscFree(fvm->componentNames);CHKERRQ(ierr);
1268c0ce001eSMatthew G. Knepley     ierr = PetscCalloc1(comp,&fvm->componentNames);CHKERRQ(ierr);
1269c0ce001eSMatthew G. Knepley   }
1270c0ce001eSMatthew G. Knepley   fvm->numComponents = comp;
1271c0ce001eSMatthew G. Knepley   ierr = PetscFree(fvm->fluxWork);CHKERRQ(ierr);
1272c0ce001eSMatthew G. Knepley   ierr = PetscMalloc1(comp, &fvm->fluxWork);CHKERRQ(ierr);
1273c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1274c0ce001eSMatthew G. Knepley }
1275c0ce001eSMatthew G. Knepley 
1276c0ce001eSMatthew G. Knepley /*@
1277c0ce001eSMatthew G. Knepley   PetscFVGetNumComponents - Get the number of field components
1278c0ce001eSMatthew G. Knepley 
1279c0ce001eSMatthew G. Knepley   Not collective
1280c0ce001eSMatthew G. Knepley 
1281c0ce001eSMatthew G. Knepley   Input Parameter:
1282c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1283c0ce001eSMatthew G. Knepley 
1284c0ce001eSMatthew G. Knepley   Output Parameter:
1285c0ce001eSMatthew G. Knepley , comp - The number of components
1286c0ce001eSMatthew G. Knepley 
128788f5f89eSMatthew G. Knepley   Level: intermediate
1288c0ce001eSMatthew G. Knepley 
1289c0ce001eSMatthew G. Knepley .seealso: PetscFVSetNumComponents()
1290c0ce001eSMatthew G. Knepley @*/
1291c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetNumComponents(PetscFV fvm, PetscInt *comp)
1292c0ce001eSMatthew G. Knepley {
1293c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1294c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1295c0ce001eSMatthew G. Knepley   PetscValidPointer(comp, 2);
1296c0ce001eSMatthew G. Knepley   *comp = fvm->numComponents;
1297c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1298c0ce001eSMatthew G. Knepley }
1299c0ce001eSMatthew G. Knepley 
1300c0ce001eSMatthew G. Knepley /*@C
1301c0ce001eSMatthew G. Knepley   PetscFVSetComponentName - Set the name of a component (used in output and viewing)
1302c0ce001eSMatthew G. Knepley 
1303c0ce001eSMatthew G. Knepley   Logically collective on fvm
1304c0ce001eSMatthew G. Knepley   Input Parameters:
1305c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1306c0ce001eSMatthew G. Knepley . comp - the component number
1307c0ce001eSMatthew G. Knepley - name - the component name
1308c0ce001eSMatthew G. Knepley 
130988f5f89eSMatthew G. Knepley   Level: intermediate
1310c0ce001eSMatthew G. Knepley 
1311c0ce001eSMatthew G. Knepley .seealso: PetscFVGetComponentName()
1312c0ce001eSMatthew G. Knepley @*/
1313c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetComponentName(PetscFV fvm, PetscInt comp, const char *name)
1314c0ce001eSMatthew G. Knepley {
1315c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1316c0ce001eSMatthew G. Knepley 
1317c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1318c0ce001eSMatthew G. Knepley   ierr = PetscFree(fvm->componentNames[comp]);CHKERRQ(ierr);
1319c0ce001eSMatthew G. Knepley   ierr = PetscStrallocpy(name,&fvm->componentNames[comp]);CHKERRQ(ierr);
1320c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1321c0ce001eSMatthew G. Knepley }
1322c0ce001eSMatthew G. Knepley 
1323c0ce001eSMatthew G. Knepley /*@C
1324c0ce001eSMatthew G. Knepley   PetscFVGetComponentName - Get the name of a component (used in output and viewing)
1325c0ce001eSMatthew G. Knepley 
1326c0ce001eSMatthew G. Knepley   Logically collective on fvm
1327c0ce001eSMatthew G. Knepley   Input Parameters:
1328c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1329c0ce001eSMatthew G. Knepley - comp - the component number
1330c0ce001eSMatthew G. Knepley 
1331c0ce001eSMatthew G. Knepley   Output Parameter:
1332c0ce001eSMatthew G. Knepley . name - the component name
1333c0ce001eSMatthew G. Knepley 
133488f5f89eSMatthew G. Knepley   Level: intermediate
1335c0ce001eSMatthew G. Knepley 
1336c0ce001eSMatthew G. Knepley .seealso: PetscFVSetComponentName()
1337c0ce001eSMatthew G. Knepley @*/
1338c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetComponentName(PetscFV fvm, PetscInt comp, const char **name)
1339c0ce001eSMatthew G. Knepley {
1340c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1341c0ce001eSMatthew G. Knepley   *name = fvm->componentNames[comp];
1342c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1343c0ce001eSMatthew G. Knepley }
1344c0ce001eSMatthew G. Knepley 
1345c0ce001eSMatthew G. Knepley /*@
1346c0ce001eSMatthew G. Knepley   PetscFVSetSpatialDimension - Set the spatial dimension
1347c0ce001eSMatthew G. Knepley 
1348c0ce001eSMatthew G. Knepley   Logically collective on fvm
1349c0ce001eSMatthew G. Knepley 
1350c0ce001eSMatthew G. Knepley   Input Parameters:
1351c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1352c0ce001eSMatthew G. Knepley - dim - The spatial dimension
1353c0ce001eSMatthew G. Knepley 
135488f5f89eSMatthew G. Knepley   Level: intermediate
1355c0ce001eSMatthew G. Knepley 
1356c0ce001eSMatthew G. Knepley .seealso: PetscFVGetSpatialDimension()
1357c0ce001eSMatthew G. Knepley @*/
1358c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetSpatialDimension(PetscFV fvm, PetscInt dim)
1359c0ce001eSMatthew G. Knepley {
1360c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1361c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1362c0ce001eSMatthew G. Knepley   fvm->dim = dim;
1363c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1364c0ce001eSMatthew G. Knepley }
1365c0ce001eSMatthew G. Knepley 
1366c0ce001eSMatthew G. Knepley /*@
1367c0ce001eSMatthew G. Knepley   PetscFVGetSpatialDimension - Get the spatial dimension
1368c0ce001eSMatthew G. Knepley 
1369c0ce001eSMatthew G. Knepley   Logically collective on fvm
1370c0ce001eSMatthew G. Knepley 
1371c0ce001eSMatthew G. Knepley   Input Parameter:
1372c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1373c0ce001eSMatthew G. Knepley 
1374c0ce001eSMatthew G. Knepley   Output Parameter:
1375c0ce001eSMatthew G. Knepley . dim - The spatial dimension
1376c0ce001eSMatthew G. Knepley 
137788f5f89eSMatthew G. Knepley   Level: intermediate
1378c0ce001eSMatthew G. Knepley 
1379c0ce001eSMatthew G. Knepley .seealso: PetscFVSetSpatialDimension()
1380c0ce001eSMatthew G. Knepley @*/
1381c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetSpatialDimension(PetscFV fvm, PetscInt *dim)
1382c0ce001eSMatthew G. Knepley {
1383c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1384c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1385c0ce001eSMatthew G. Knepley   PetscValidPointer(dim, 2);
1386c0ce001eSMatthew G. Knepley   *dim = fvm->dim;
1387c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1388c0ce001eSMatthew G. Knepley }
1389c0ce001eSMatthew G. Knepley 
1390c0ce001eSMatthew G. Knepley /*@
1391c0ce001eSMatthew G. Knepley   PetscFVSetComputeGradients - Toggle computation of cell gradients
1392c0ce001eSMatthew G. Knepley 
1393c0ce001eSMatthew G. Knepley   Logically collective on fvm
1394c0ce001eSMatthew G. Knepley 
1395c0ce001eSMatthew G. Knepley   Input Parameters:
1396c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1397c0ce001eSMatthew G. Knepley - computeGradients - Flag to compute cell gradients
1398c0ce001eSMatthew G. Knepley 
139988f5f89eSMatthew G. Knepley   Level: intermediate
1400c0ce001eSMatthew G. Knepley 
1401c0ce001eSMatthew G. Knepley .seealso: PetscFVGetComputeGradients()
1402c0ce001eSMatthew G. Knepley @*/
1403c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetComputeGradients(PetscFV fvm, PetscBool computeGradients)
1404c0ce001eSMatthew G. Knepley {
1405c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1406c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1407c0ce001eSMatthew G. Knepley   fvm->computeGradients = computeGradients;
1408c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1409c0ce001eSMatthew G. Knepley }
1410c0ce001eSMatthew G. Knepley 
1411c0ce001eSMatthew G. Knepley /*@
1412c0ce001eSMatthew G. Knepley   PetscFVGetComputeGradients - Return flag for computation of cell gradients
1413c0ce001eSMatthew G. Knepley 
1414c0ce001eSMatthew G. Knepley   Not collective
1415c0ce001eSMatthew G. Knepley 
1416c0ce001eSMatthew G. Knepley   Input Parameter:
1417c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1418c0ce001eSMatthew G. Knepley 
1419c0ce001eSMatthew G. Knepley   Output Parameter:
1420c0ce001eSMatthew G. Knepley . computeGradients - Flag to compute cell gradients
1421c0ce001eSMatthew G. Knepley 
142288f5f89eSMatthew G. Knepley   Level: intermediate
1423c0ce001eSMatthew G. Knepley 
1424c0ce001eSMatthew G. Knepley .seealso: PetscFVSetComputeGradients()
1425c0ce001eSMatthew G. Knepley @*/
1426c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetComputeGradients(PetscFV fvm, PetscBool *computeGradients)
1427c0ce001eSMatthew G. Knepley {
1428c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1429c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1430c0ce001eSMatthew G. Knepley   PetscValidPointer(computeGradients, 2);
1431c0ce001eSMatthew G. Knepley   *computeGradients = fvm->computeGradients;
1432c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1433c0ce001eSMatthew G. Knepley }
1434c0ce001eSMatthew G. Knepley 
1435c0ce001eSMatthew G. Knepley /*@
1436c0ce001eSMatthew G. Knepley   PetscFVSetQuadrature - Set the quadrature object
1437c0ce001eSMatthew G. Knepley 
1438c0ce001eSMatthew G. Knepley   Logically collective on fvm
1439c0ce001eSMatthew G. Knepley 
1440c0ce001eSMatthew G. Knepley   Input Parameters:
1441c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1442c0ce001eSMatthew G. Knepley - q - The PetscQuadrature
1443c0ce001eSMatthew G. Knepley 
144488f5f89eSMatthew G. Knepley   Level: intermediate
1445c0ce001eSMatthew G. Knepley 
1446c0ce001eSMatthew G. Knepley .seealso: PetscFVGetQuadrature()
1447c0ce001eSMatthew G. Knepley @*/
1448c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetQuadrature(PetscFV fvm, PetscQuadrature q)
1449c0ce001eSMatthew G. Knepley {
1450c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1451c0ce001eSMatthew G. Knepley 
1452c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1453c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1454c0ce001eSMatthew G. Knepley   ierr = PetscQuadratureDestroy(&fvm->quadrature);CHKERRQ(ierr);
1455c0ce001eSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) q);CHKERRQ(ierr);
1456c0ce001eSMatthew G. Knepley   fvm->quadrature = q;
1457c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1458c0ce001eSMatthew G. Knepley }
1459c0ce001eSMatthew G. Knepley 
1460c0ce001eSMatthew G. Knepley /*@
1461c0ce001eSMatthew G. Knepley   PetscFVGetQuadrature - Get the quadrature object
1462c0ce001eSMatthew G. Knepley 
1463c0ce001eSMatthew G. Knepley   Not collective
1464c0ce001eSMatthew G. Knepley 
1465c0ce001eSMatthew G. Knepley   Input Parameter:
1466c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1467c0ce001eSMatthew G. Knepley 
1468c0ce001eSMatthew G. Knepley   Output Parameter:
1469c0ce001eSMatthew G. Knepley . lim - The PetscQuadrature
1470c0ce001eSMatthew G. Knepley 
147188f5f89eSMatthew G. Knepley   Level: intermediate
1472c0ce001eSMatthew G. Knepley 
1473c0ce001eSMatthew G. Knepley .seealso: PetscFVSetQuadrature()
1474c0ce001eSMatthew G. Knepley @*/
1475c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetQuadrature(PetscFV fvm, PetscQuadrature *q)
1476c0ce001eSMatthew G. Knepley {
1477c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1478c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1479c0ce001eSMatthew G. Knepley   PetscValidPointer(q, 2);
1480c0ce001eSMatthew G. Knepley   if (!fvm->quadrature) {
1481c0ce001eSMatthew G. Knepley     /* Create default 1-point quadrature */
1482c0ce001eSMatthew G. Knepley     PetscReal     *points, *weights;
1483c0ce001eSMatthew G. Knepley     PetscErrorCode ierr;
1484c0ce001eSMatthew G. Knepley 
1485c0ce001eSMatthew G. Knepley     ierr = PetscQuadratureCreate(PETSC_COMM_SELF, &fvm->quadrature);CHKERRQ(ierr);
1486c0ce001eSMatthew G. Knepley     ierr = PetscCalloc1(fvm->dim, &points);CHKERRQ(ierr);
1487c0ce001eSMatthew G. Knepley     ierr = PetscMalloc1(1, &weights);CHKERRQ(ierr);
1488c0ce001eSMatthew G. Knepley     weights[0] = 1.0;
1489c0ce001eSMatthew G. Knepley     ierr = PetscQuadratureSetData(fvm->quadrature, fvm->dim, 1, 1, points, weights);CHKERRQ(ierr);
1490c0ce001eSMatthew G. Knepley   }
1491c0ce001eSMatthew G. Knepley   *q = fvm->quadrature;
1492c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1493c0ce001eSMatthew G. Knepley }
1494c0ce001eSMatthew G. Knepley 
1495c0ce001eSMatthew G. Knepley /*@
1496c0ce001eSMatthew G. Knepley   PetscFVGetDualSpace - Returns the PetscDualSpace used to define the inner product
1497c0ce001eSMatthew G. Knepley 
1498c0ce001eSMatthew G. Knepley   Not collective
1499c0ce001eSMatthew G. Knepley 
1500c0ce001eSMatthew G. Knepley   Input Parameter:
1501c0ce001eSMatthew G. Knepley . fvm - The PetscFV object
1502c0ce001eSMatthew G. Knepley 
1503c0ce001eSMatthew G. Knepley   Output Parameter:
1504c0ce001eSMatthew G. Knepley . sp - The PetscDualSpace object
1505c0ce001eSMatthew G. Knepley 
1506c0ce001eSMatthew G. Knepley   Note: A simple dual space is provided automatically, and the user typically will not need to override it.
1507c0ce001eSMatthew G. Knepley 
150888f5f89eSMatthew G. Knepley   Level: intermediate
1509c0ce001eSMatthew G. Knepley 
1510c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate()
1511c0ce001eSMatthew G. Knepley @*/
1512c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetDualSpace(PetscFV fvm, PetscDualSpace *sp)
1513c0ce001eSMatthew G. Knepley {
1514c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1515c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1516c0ce001eSMatthew G. Knepley   PetscValidPointer(sp, 2);
1517c0ce001eSMatthew G. Knepley   if (!fvm->dualSpace) {
1518c0ce001eSMatthew G. Knepley     DM              K;
1519c0ce001eSMatthew G. Knepley     PetscInt        dim, Nc, c;
1520c0ce001eSMatthew G. Knepley     PetscErrorCode  ierr;
1521c0ce001eSMatthew G. Knepley 
1522c0ce001eSMatthew G. Knepley     ierr = PetscFVGetSpatialDimension(fvm, &dim);CHKERRQ(ierr);
1523c0ce001eSMatthew G. Knepley     ierr = PetscFVGetNumComponents(fvm, &Nc);CHKERRQ(ierr);
1524c0ce001eSMatthew G. Knepley     ierr = PetscDualSpaceCreate(PetscObjectComm((PetscObject) fvm), &fvm->dualSpace);CHKERRQ(ierr);
1525c0ce001eSMatthew G. Knepley     ierr = PetscDualSpaceSetType(fvm->dualSpace, PETSCDUALSPACESIMPLE);CHKERRQ(ierr);
1526c0ce001eSMatthew G. Knepley     ierr = PetscDualSpaceCreateReferenceCell(fvm->dualSpace, dim, PETSC_FALSE, &K);CHKERRQ(ierr); /* TODO: The reference cell type should be held by the discretization object */
1527c0ce001eSMatthew G. Knepley     ierr = PetscDualSpaceSetNumComponents(fvm->dualSpace, Nc);CHKERRQ(ierr);
1528c0ce001eSMatthew G. Knepley     ierr = PetscDualSpaceSetDM(fvm->dualSpace, K);CHKERRQ(ierr);
1529c0ce001eSMatthew G. Knepley     ierr = DMDestroy(&K);CHKERRQ(ierr);
1530c0ce001eSMatthew G. Knepley     ierr = PetscDualSpaceSimpleSetDimension(fvm->dualSpace, Nc);CHKERRQ(ierr);
1531c0ce001eSMatthew G. Knepley     /* Should we be using PetscFVGetQuadrature() here? */
1532c0ce001eSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
1533c0ce001eSMatthew G. Knepley       PetscQuadrature qc;
1534c0ce001eSMatthew G. Knepley       PetscReal      *points, *weights;
1535c0ce001eSMatthew G. Knepley       PetscErrorCode  ierr;
1536c0ce001eSMatthew G. Knepley 
1537c0ce001eSMatthew G. Knepley       ierr = PetscQuadratureCreate(PETSC_COMM_SELF, &qc);CHKERRQ(ierr);
1538c0ce001eSMatthew G. Knepley       ierr = PetscCalloc1(dim, &points);CHKERRQ(ierr);
1539c0ce001eSMatthew G. Knepley       ierr = PetscCalloc1(Nc, &weights);CHKERRQ(ierr);
1540c0ce001eSMatthew G. Knepley       weights[c] = 1.0;
1541c0ce001eSMatthew G. Knepley       ierr = PetscQuadratureSetData(qc, dim, Nc, 1, points, weights);CHKERRQ(ierr);
1542c0ce001eSMatthew G. Knepley       ierr = PetscDualSpaceSimpleSetFunctional(fvm->dualSpace, c, qc);CHKERRQ(ierr);
1543c0ce001eSMatthew G. Knepley       ierr = PetscQuadratureDestroy(&qc);CHKERRQ(ierr);
1544c0ce001eSMatthew G. Knepley     }
1545c0ce001eSMatthew G. Knepley   }
1546c0ce001eSMatthew G. Knepley   *sp = fvm->dualSpace;
1547c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1548c0ce001eSMatthew G. Knepley }
1549c0ce001eSMatthew G. Knepley 
1550c0ce001eSMatthew G. Knepley /*@
1551c0ce001eSMatthew G. Knepley   PetscFVSetDualSpace - Sets the PetscDualSpace used to define the inner product
1552c0ce001eSMatthew G. Knepley 
1553c0ce001eSMatthew G. Knepley   Not collective
1554c0ce001eSMatthew G. Knepley 
1555c0ce001eSMatthew G. Knepley   Input Parameters:
1556c0ce001eSMatthew G. Knepley + fvm - The PetscFV object
1557c0ce001eSMatthew G. Knepley - sp  - The PetscDualSpace object
1558c0ce001eSMatthew G. Knepley 
1559c0ce001eSMatthew G. Knepley   Level: intermediate
1560c0ce001eSMatthew G. Knepley 
1561c0ce001eSMatthew G. Knepley   Note: A simple dual space is provided automatically, and the user typically will not need to override it.
1562c0ce001eSMatthew G. Knepley 
1563c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate()
1564c0ce001eSMatthew G. Knepley @*/
1565c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetDualSpace(PetscFV fvm, PetscDualSpace sp)
1566c0ce001eSMatthew G. Knepley {
1567c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1568c0ce001eSMatthew G. Knepley 
1569c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1570c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1571c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 2);
1572c0ce001eSMatthew G. Knepley   ierr = PetscDualSpaceDestroy(&fvm->dualSpace);CHKERRQ(ierr);
1573c0ce001eSMatthew G. Knepley   fvm->dualSpace = sp;
1574c0ce001eSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) fvm->dualSpace);CHKERRQ(ierr);
1575c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1576c0ce001eSMatthew G. Knepley }
1577c0ce001eSMatthew G. Knepley 
157888f5f89eSMatthew G. Knepley /*@C
157988f5f89eSMatthew G. Knepley   PetscFVGetDefaultTabulation - Returns the tabulation of the basis functions at the quadrature points
158088f5f89eSMatthew G. Knepley 
158188f5f89eSMatthew G. Knepley   Not collective
158288f5f89eSMatthew G. Knepley 
158388f5f89eSMatthew G. Knepley   Input Parameter:
158488f5f89eSMatthew G. Knepley . fvm - The PetscFV object
158588f5f89eSMatthew G. Knepley 
158688f5f89eSMatthew G. Knepley   Output Parameters:
158788f5f89eSMatthew G. Knepley + B - The basis function values at quadrature points
158888f5f89eSMatthew G. Knepley . D - The basis function derivatives at quadrature points
158988f5f89eSMatthew G. Knepley - H - The basis function second derivatives at quadrature points
159088f5f89eSMatthew G. Knepley 
159188f5f89eSMatthew G. Knepley   Note:
159288f5f89eSMatthew G. Knepley $ B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c
159388f5f89eSMatthew G. Knepley $ D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d
159488f5f89eSMatthew G. Knepley $ H[(((p*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point p for basis function i, component c, in directions d and e
159588f5f89eSMatthew G. Knepley 
159688f5f89eSMatthew G. Knepley   Level: intermediate
159788f5f89eSMatthew G. Knepley 
1598*02a061ebSMatthew G. Knepley .seealso: PetscFEGetDefaultTabulation(), PetscFEGetTabulation(), PetscFERestoreTabulation(), PetscFVGetQuadrature(), PetscQuadratureGetData()
159988f5f89eSMatthew G. Knepley @*/
1600c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetDefaultTabulation(PetscFV fvm, PetscReal **B, PetscReal **D, PetscReal **H)
1601c0ce001eSMatthew G. Knepley {
1602c0ce001eSMatthew G. Knepley   PetscInt         npoints;
1603c0ce001eSMatthew G. Knepley   const PetscReal *points;
1604c0ce001eSMatthew G. Knepley   PetscErrorCode   ierr;
1605c0ce001eSMatthew G. Knepley 
1606c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1607c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1608c0ce001eSMatthew G. Knepley   if (B) PetscValidPointer(B, 2);
1609c0ce001eSMatthew G. Knepley   if (D) PetscValidPointer(D, 3);
1610c0ce001eSMatthew G. Knepley   if (H) PetscValidPointer(H, 4);
1611c0ce001eSMatthew G. Knepley   ierr = PetscQuadratureGetData(fvm->quadrature, NULL, NULL, &npoints, &points, NULL);CHKERRQ(ierr);
1612c0ce001eSMatthew G. Knepley   if (!fvm->B) {ierr = PetscFVGetTabulation(fvm, npoints, points, &fvm->B, &fvm->D, NULL/*&fvm->H*/);CHKERRQ(ierr);}
1613c0ce001eSMatthew G. Knepley   if (B) *B = fvm->B;
1614c0ce001eSMatthew G. Knepley   if (D) *D = fvm->D;
1615c0ce001eSMatthew G. Knepley   if (H) *H = fvm->H;
1616c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1617c0ce001eSMatthew G. Knepley }
1618c0ce001eSMatthew G. Knepley 
161988f5f89eSMatthew G. Knepley /*@C
162088f5f89eSMatthew G. Knepley   PetscFVGetTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided.
162188f5f89eSMatthew G. Knepley 
162288f5f89eSMatthew G. Knepley   Not collective
162388f5f89eSMatthew G. Knepley 
162488f5f89eSMatthew G. Knepley   Input Parameters:
162588f5f89eSMatthew G. Knepley + fvm     - The PetscFV object
162688f5f89eSMatthew G. Knepley . npoints - The number of tabulation points
162788f5f89eSMatthew G. Knepley - points  - The tabulation point coordinates
162888f5f89eSMatthew G. Knepley 
162988f5f89eSMatthew G. Knepley   Output Parameters:
163088f5f89eSMatthew G. Knepley + B - The basis function values at tabulation points
163188f5f89eSMatthew G. Knepley . D - The basis function derivatives at tabulation points
163288f5f89eSMatthew G. Knepley - H - The basis function second derivatives at tabulation points
163388f5f89eSMatthew G. Knepley 
163488f5f89eSMatthew G. Knepley   Note:
163588f5f89eSMatthew G. Knepley $ B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c
163688f5f89eSMatthew G. Knepley $ D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d
163788f5f89eSMatthew G. Knepley $ H[(((p*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point p for basis function i, component c, in directions d and e
163888f5f89eSMatthew G. Knepley 
163988f5f89eSMatthew G. Knepley   Level: intermediate
164088f5f89eSMatthew G. Knepley 
164188f5f89eSMatthew G. Knepley .seealso: PetscFEGetTabulation(), PetscFERestoreTabulation(), PetscFEGetDefaultTabulation()
164288f5f89eSMatthew G. Knepley @*/
1643c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetTabulation(PetscFV fvm, PetscInt npoints, const PetscReal points[], PetscReal **B, PetscReal **D, PetscReal **H)
1644c0ce001eSMatthew G. Knepley {
1645c0ce001eSMatthew G. Knepley   PetscInt         pdim = 1; /* Dimension of approximation space P */
1646c0ce001eSMatthew G. Knepley   PetscInt         dim;      /* Spatial dimension */
1647c0ce001eSMatthew G. Knepley   PetscInt         comp;     /* Field components */
1648c0ce001eSMatthew G. Knepley   PetscInt         p, d, c, e;
1649c0ce001eSMatthew G. Knepley   PetscErrorCode   ierr;
1650c0ce001eSMatthew G. Knepley 
1651c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1652c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1653c0ce001eSMatthew G. Knepley   PetscValidPointer(points, 3);
1654c0ce001eSMatthew G. Knepley   if (B) PetscValidPointer(B, 4);
1655c0ce001eSMatthew G. Knepley   if (D) PetscValidPointer(D, 5);
1656c0ce001eSMatthew G. Knepley   if (H) PetscValidPointer(H, 6);
1657c0ce001eSMatthew G. Knepley   ierr = PetscFVGetSpatialDimension(fvm, &dim);CHKERRQ(ierr);
1658c0ce001eSMatthew G. Knepley   ierr = PetscFVGetNumComponents(fvm, &comp);CHKERRQ(ierr);
1659c0ce001eSMatthew G. Knepley   if (B) {ierr = PetscMalloc1(npoints*pdim*comp, B);CHKERRQ(ierr);}
1660c0ce001eSMatthew G. Knepley   if (D) {ierr = PetscMalloc1(npoints*pdim*comp*dim, D);CHKERRQ(ierr);}
1661c0ce001eSMatthew G. Knepley   if (H) {ierr = PetscMalloc1(npoints*pdim*comp*dim*dim, H);CHKERRQ(ierr);}
1662c0ce001eSMatthew G. Knepley   if (B) {for (p = 0; p < npoints; ++p) for (d = 0; d < pdim; ++d) for (c = 0; c < comp; ++c) (*B)[(p*pdim + d)*comp + c] = 1.0;}
1663c0ce001eSMatthew G. Knepley   if (D) {for (p = 0; p < npoints; ++p) for (d = 0; d < pdim; ++d) for (c = 0; c < comp; ++c) for (e = 0; e < dim; ++e) (*D)[((p*pdim + d)*comp + c)*dim + e] = 0.0;}
1664c0ce001eSMatthew G. Knepley   if (H) {for (p = 0; p < npoints; ++p) for (d = 0; d < pdim; ++d) for (c = 0; c < comp; ++c) for (e = 0; e < dim*dim; ++e) (*H)[((p*pdim + d)*comp + c)*dim*dim + e] = 0.0;}
1665c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1666c0ce001eSMatthew G. Knepley }
1667c0ce001eSMatthew G. Knepley 
166888f5f89eSMatthew G. Knepley /*@C
166988f5f89eSMatthew G. Knepley   PetscFVRestoreTabulation - Frees memory from the associated tabulation.
167088f5f89eSMatthew G. Knepley 
167188f5f89eSMatthew G. Knepley   Not collective
167288f5f89eSMatthew G. Knepley 
167388f5f89eSMatthew G. Knepley   Input Parameters:
167488f5f89eSMatthew G. Knepley + fvm     - The PetscFV object
167588f5f89eSMatthew G. Knepley . npoints - The number of tabulation points
167688f5f89eSMatthew G. Knepley . points  - The tabulation point coordinates
167788f5f89eSMatthew G. Knepley . B - The basis function values at tabulation points
167888f5f89eSMatthew G. Knepley . D - The basis function derivatives at tabulation points
167988f5f89eSMatthew G. Knepley - H - The basis function second derivatives at tabulation points
168088f5f89eSMatthew G. Knepley 
168188f5f89eSMatthew G. Knepley   Note:
168288f5f89eSMatthew G. Knepley $ B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c
168388f5f89eSMatthew G. Knepley $ D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d
168488f5f89eSMatthew G. Knepley $ H[(((p*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point p for basis function i, component c, in directions d and e
168588f5f89eSMatthew G. Knepley 
168688f5f89eSMatthew G. Knepley   Level: intermediate
168788f5f89eSMatthew G. Knepley 
168888f5f89eSMatthew G. Knepley .seealso: PetscFVGetTabulation(), PetscFVGetDefaultTabulation()
168988f5f89eSMatthew G. Knepley @*/
1690c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVRestoreTabulation(PetscFV fvm, PetscInt npoints, const PetscReal points[], PetscReal **B, PetscReal **D, PetscReal **H)
1691c0ce001eSMatthew G. Knepley {
1692c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1693c0ce001eSMatthew G. Knepley 
1694c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1695c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1696c0ce001eSMatthew G. Knepley   if (B && *B) {ierr = PetscFree(*B);CHKERRQ(ierr);}
1697c0ce001eSMatthew G. Knepley   if (D && *D) {ierr = PetscFree(*D);CHKERRQ(ierr);}
1698c0ce001eSMatthew G. Knepley   if (H && *H) {ierr = PetscFree(*H);CHKERRQ(ierr);}
1699c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1700c0ce001eSMatthew G. Knepley }
1701c0ce001eSMatthew G. Knepley 
1702c0ce001eSMatthew G. Knepley /*@C
1703c0ce001eSMatthew G. Knepley   PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell
1704c0ce001eSMatthew G. Knepley 
1705c0ce001eSMatthew G. Knepley   Input Parameters:
1706c0ce001eSMatthew G. Knepley + fvm      - The PetscFV object
1707c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained
1708c0ce001eSMatthew G. Knepley - dx       - The vector from the cell centroid to the neighboring cell centroid for each face
1709c0ce001eSMatthew G. Knepley 
171088f5f89eSMatthew G. Knepley   Level: advanced
1711c0ce001eSMatthew G. Knepley 
1712c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate()
1713c0ce001eSMatthew G. Knepley @*/
1714c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVComputeGradient(PetscFV fvm, PetscInt numFaces, PetscScalar dx[], PetscScalar grad[])
1715c0ce001eSMatthew G. Knepley {
1716c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1717c0ce001eSMatthew G. Knepley 
1718c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1719c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1720c0ce001eSMatthew G. Knepley   if (fvm->ops->computegradient) {ierr = (*fvm->ops->computegradient)(fvm, numFaces, dx, grad);CHKERRQ(ierr);}
1721c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1722c0ce001eSMatthew G. Knepley }
1723c0ce001eSMatthew G. Knepley 
172488f5f89eSMatthew G. Knepley /*@C
1725c0ce001eSMatthew G. Knepley   PetscFVIntegrateRHSFunction - Produce the cell residual vector for a chunk of elements by quadrature integration
1726c0ce001eSMatthew G. Knepley 
1727c0ce001eSMatthew G. Knepley   Not collective
1728c0ce001eSMatthew G. Knepley 
1729c0ce001eSMatthew G. Knepley   Input Parameters:
1730c0ce001eSMatthew G. Knepley + fvm          - The PetscFV object for the field being integrated
1731c0ce001eSMatthew G. Knepley . prob         - The PetscDS specifing the discretizations and continuum functions
1732c0ce001eSMatthew G. Knepley . field        - The field being integrated
1733c0ce001eSMatthew G. Knepley . Nf           - The number of faces in the chunk
1734c0ce001eSMatthew G. Knepley . fgeom        - The face geometry for each face in the chunk
1735c0ce001eSMatthew G. Knepley . neighborVol  - The volume for each pair of cells in the chunk
1736c0ce001eSMatthew G. Knepley . uL           - The state from the cell on the left
1737c0ce001eSMatthew G. Knepley - uR           - The state from the cell on the right
1738c0ce001eSMatthew G. Knepley 
1739c0ce001eSMatthew G. Knepley   Output Parameter
1740c0ce001eSMatthew G. Knepley + fluxL        - the left fluxes for each face
1741c0ce001eSMatthew G. Knepley - fluxR        - the right fluxes for each face
174288f5f89eSMatthew G. Knepley 
174388f5f89eSMatthew G. Knepley   Level: developer
174488f5f89eSMatthew G. Knepley 
174588f5f89eSMatthew G. Knepley .seealso: PetscFVCreate()
174688f5f89eSMatthew G. Knepley @*/
1747c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVIntegrateRHSFunction(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol,
1748c0ce001eSMatthew G. Knepley                                            PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[])
1749c0ce001eSMatthew G. Knepley {
1750c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1751c0ce001eSMatthew G. Knepley 
1752c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1753c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1754c0ce001eSMatthew G. Knepley   if (fvm->ops->integraterhsfunction) {ierr = (*fvm->ops->integraterhsfunction)(fvm, prob, field, Nf, fgeom, neighborVol, uL, uR, fluxL, fluxR);CHKERRQ(ierr);}
1755c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1756c0ce001eSMatthew G. Knepley }
1757c0ce001eSMatthew G. Knepley 
1758c0ce001eSMatthew G. Knepley /*@
1759c0ce001eSMatthew G. Knepley   PetscFVRefine - Create a "refined" PetscFV object that refines the reference cell into smaller copies. This is typically used
1760c0ce001eSMatthew G. Knepley   to precondition a higher order method with a lower order method on a refined mesh having the same number of dofs (but more
1761c0ce001eSMatthew G. Knepley   sparsity). It is also used to create an interpolation between regularly refined meshes.
1762c0ce001eSMatthew G. Knepley 
1763c0ce001eSMatthew G. Knepley   Input Parameter:
1764c0ce001eSMatthew G. Knepley . fv - The initial PetscFV
1765c0ce001eSMatthew G. Knepley 
1766c0ce001eSMatthew G. Knepley   Output Parameter:
1767c0ce001eSMatthew G. Knepley . fvRef - The refined PetscFV
1768c0ce001eSMatthew G. Knepley 
176988f5f89eSMatthew G. Knepley   Level: advanced
1770c0ce001eSMatthew G. Knepley 
1771c0ce001eSMatthew G. Knepley .seealso: PetscFVType, PetscFVCreate(), PetscFVSetType()
1772c0ce001eSMatthew G. Knepley @*/
1773c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVRefine(PetscFV fv, PetscFV *fvRef)
1774c0ce001eSMatthew G. Knepley {
1775c0ce001eSMatthew G. Knepley   PetscDualSpace   Q, Qref;
1776c0ce001eSMatthew G. Knepley   DM               K, Kref;
1777c0ce001eSMatthew G. Knepley   PetscQuadrature  q, qref;
1778c0ce001eSMatthew G. Knepley   CellRefiner      cellRefiner;
1779c0ce001eSMatthew G. Knepley   PetscReal       *v0;
1780c0ce001eSMatthew G. Knepley   PetscReal       *jac, *invjac;
1781c0ce001eSMatthew G. Knepley   PetscInt         numComp, numSubelements, s;
1782c0ce001eSMatthew G. Knepley   PetscErrorCode   ierr;
1783c0ce001eSMatthew G. Knepley 
1784c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1785c0ce001eSMatthew G. Knepley   ierr = PetscFVGetDualSpace(fv, &Q);CHKERRQ(ierr);
1786c0ce001eSMatthew G. Knepley   ierr = PetscFVGetQuadrature(fv, &q);CHKERRQ(ierr);
1787c0ce001eSMatthew G. Knepley   ierr = PetscDualSpaceGetDM(Q, &K);CHKERRQ(ierr);
1788c0ce001eSMatthew G. Knepley   /* Create dual space */
1789c0ce001eSMatthew G. Knepley   ierr = PetscDualSpaceDuplicate(Q, &Qref);CHKERRQ(ierr);
1790c0ce001eSMatthew G. Knepley   ierr = DMRefine(K, PetscObjectComm((PetscObject) fv), &Kref);CHKERRQ(ierr);
1791c0ce001eSMatthew G. Knepley   ierr = PetscDualSpaceSetDM(Qref, Kref);CHKERRQ(ierr);
1792c0ce001eSMatthew G. Knepley   ierr = DMDestroy(&Kref);CHKERRQ(ierr);
1793c0ce001eSMatthew G. Knepley   ierr = PetscDualSpaceSetUp(Qref);CHKERRQ(ierr);
1794c0ce001eSMatthew G. Knepley   /* Create volume */
1795c0ce001eSMatthew G. Knepley   ierr = PetscFVCreate(PetscObjectComm((PetscObject) fv), fvRef);CHKERRQ(ierr);
1796c0ce001eSMatthew G. Knepley   ierr = PetscFVSetDualSpace(*fvRef, Qref);CHKERRQ(ierr);
1797c0ce001eSMatthew G. Knepley   ierr = PetscFVGetNumComponents(fv,    &numComp);CHKERRQ(ierr);
1798c0ce001eSMatthew G. Knepley   ierr = PetscFVSetNumComponents(*fvRef, numComp);CHKERRQ(ierr);
1799c0ce001eSMatthew G. Knepley   ierr = PetscFVSetUp(*fvRef);CHKERRQ(ierr);
1800c0ce001eSMatthew G. Knepley   /* Create quadrature */
1801c0ce001eSMatthew G. Knepley   ierr = DMPlexGetCellRefiner_Internal(K, &cellRefiner);CHKERRQ(ierr);
1802c0ce001eSMatthew G. Knepley   ierr = CellRefinerGetAffineTransforms_Internal(cellRefiner, &numSubelements, &v0, &jac, &invjac);CHKERRQ(ierr);
1803c0ce001eSMatthew G. Knepley   ierr = PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref);CHKERRQ(ierr);
1804c0ce001eSMatthew G. Knepley   ierr = PetscDualSpaceSimpleSetDimension(Qref, numSubelements);CHKERRQ(ierr);
1805c0ce001eSMatthew G. Knepley   for (s = 0; s < numSubelements; ++s) {
1806c0ce001eSMatthew G. Knepley     PetscQuadrature  qs;
1807c0ce001eSMatthew G. Knepley     const PetscReal *points, *weights;
1808c0ce001eSMatthew G. Knepley     PetscReal       *p, *w;
1809c0ce001eSMatthew G. Knepley     PetscInt         dim, Nc, npoints, np;
1810c0ce001eSMatthew G. Knepley 
1811c0ce001eSMatthew G. Knepley     ierr = PetscQuadratureCreate(PETSC_COMM_SELF, &qs);CHKERRQ(ierr);
1812c0ce001eSMatthew G. Knepley     ierr = PetscQuadratureGetData(q, &dim, &Nc, &npoints, &points, &weights);CHKERRQ(ierr);
1813c0ce001eSMatthew G. Knepley     np   = npoints/numSubelements;
1814c0ce001eSMatthew G. Knepley     ierr = PetscMalloc1(np*dim,&p);CHKERRQ(ierr);
1815c0ce001eSMatthew G. Knepley     ierr = PetscMalloc1(np*Nc,&w);CHKERRQ(ierr);
1816c0ce001eSMatthew G. Knepley     ierr = PetscArraycpy(p, &points[s*np*dim], np*dim);CHKERRQ(ierr);
1817c0ce001eSMatthew G. Knepley     ierr = PetscArraycpy(w, &weights[s*np*Nc], np*Nc);CHKERRQ(ierr);
1818c0ce001eSMatthew G. Knepley     ierr = PetscQuadratureSetData(qs, dim, Nc, np, p, w);CHKERRQ(ierr);
1819c0ce001eSMatthew G. Knepley     ierr = PetscDualSpaceSimpleSetFunctional(Qref, s, qs);CHKERRQ(ierr);
1820c0ce001eSMatthew G. Knepley     ierr = PetscQuadratureDestroy(&qs);CHKERRQ(ierr);
1821c0ce001eSMatthew G. Knepley   }
1822c0ce001eSMatthew G. Knepley   ierr = CellRefinerRestoreAffineTransforms_Internal(cellRefiner, &numSubelements, &v0, &jac, &invjac);CHKERRQ(ierr);
1823c0ce001eSMatthew G. Knepley   ierr = PetscFVSetQuadrature(*fvRef, qref);CHKERRQ(ierr);
1824c0ce001eSMatthew G. Knepley   ierr = PetscQuadratureDestroy(&qref);CHKERRQ(ierr);
1825c0ce001eSMatthew G. Knepley   ierr = PetscDualSpaceDestroy(&Qref);CHKERRQ(ierr);
1826c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1827c0ce001eSMatthew G. Knepley }
1828c0ce001eSMatthew G. Knepley 
182988f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVDestroy_Upwind(PetscFV fvm)
1830c0ce001eSMatthew G. Knepley {
1831c0ce001eSMatthew G. Knepley   PetscFV_Upwind *b = (PetscFV_Upwind *) fvm->data;
1832c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1833c0ce001eSMatthew G. Knepley 
1834c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1835c0ce001eSMatthew G. Knepley   ierr = PetscFree(b);CHKERRQ(ierr);
1836c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1837c0ce001eSMatthew G. Knepley }
1838c0ce001eSMatthew G. Knepley 
183988f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_Upwind_Ascii(PetscFV fv, PetscViewer viewer)
1840c0ce001eSMatthew G. Knepley {
1841c0ce001eSMatthew G. Knepley   PetscInt          Nc, c;
1842c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
1843c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
1844c0ce001eSMatthew G. Knepley 
1845c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1846c0ce001eSMatthew G. Knepley   ierr = PetscFVGetNumComponents(fv, &Nc);CHKERRQ(ierr);
1847c0ce001eSMatthew G. Knepley   ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr);
1848c0ce001eSMatthew G. Knepley   ierr = PetscViewerASCIIPrintf(viewer, "Upwind Finite Volume:\n");CHKERRQ(ierr);
1849c0ce001eSMatthew G. Knepley   ierr = PetscViewerASCIIPrintf(viewer, "  num components: %d\n", Nc);CHKERRQ(ierr);
1850c0ce001eSMatthew G. Knepley   for (c = 0; c < Nc; c++) {
1851c0ce001eSMatthew G. Knepley     if (fv->componentNames[c]) {
1852c0ce001eSMatthew G. Knepley       ierr = PetscViewerASCIIPrintf(viewer, "    component %d: %s\n", c, fv->componentNames[c]);CHKERRQ(ierr);
1853c0ce001eSMatthew G. Knepley     }
1854c0ce001eSMatthew G. Knepley   }
1855c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1856c0ce001eSMatthew G. Knepley }
1857c0ce001eSMatthew G. Knepley 
185888f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_Upwind(PetscFV fv, PetscViewer viewer)
1859c0ce001eSMatthew G. Knepley {
1860c0ce001eSMatthew G. Knepley   PetscBool      iascii;
1861c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1862c0ce001eSMatthew G. Knepley 
1863c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1864c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1);
1865c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1866c0ce001eSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
1867c0ce001eSMatthew G. Knepley   if (iascii) {ierr = PetscFVView_Upwind_Ascii(fv, viewer);CHKERRQ(ierr);}
1868c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1869c0ce001eSMatthew G. Knepley }
1870c0ce001eSMatthew G. Knepley 
187188f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVSetUp_Upwind(PetscFV fvm)
1872c0ce001eSMatthew G. Knepley {
1873c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1874c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1875c0ce001eSMatthew G. Knepley }
1876c0ce001eSMatthew G. Knepley 
1877c0ce001eSMatthew G. Knepley /*
1878c0ce001eSMatthew G. Knepley   neighborVol[f*2+0] contains the left  geom
1879c0ce001eSMatthew G. Knepley   neighborVol[f*2+1] contains the right geom
1880c0ce001eSMatthew G. Knepley */
188188f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVIntegrateRHSFunction_Upwind(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol,
1882c0ce001eSMatthew G. Knepley                                                          PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[])
1883c0ce001eSMatthew G. Knepley {
1884c0ce001eSMatthew G. Knepley   void             (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *);
1885c0ce001eSMatthew G. Knepley   void              *rctx;
1886c0ce001eSMatthew G. Knepley   PetscScalar       *flux = fvm->fluxWork;
1887c0ce001eSMatthew G. Knepley   const PetscScalar *constants;
1888c0ce001eSMatthew G. Knepley   PetscInt           dim, numConstants, pdim, totDim, Nc, off, f, d;
1889c0ce001eSMatthew G. Knepley   PetscErrorCode     ierr;
1890c0ce001eSMatthew G. Knepley 
1891c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1892c0ce001eSMatthew G. Knepley   ierr = PetscDSGetTotalComponents(prob, &Nc);CHKERRQ(ierr);
1893c0ce001eSMatthew G. Knepley   ierr = PetscDSGetTotalDimension(prob, &totDim);CHKERRQ(ierr);
1894c0ce001eSMatthew G. Knepley   ierr = PetscDSGetFieldOffset(prob, field, &off);CHKERRQ(ierr);
1895c0ce001eSMatthew G. Knepley   ierr = PetscDSGetRiemannSolver(prob, field, &riemann);CHKERRQ(ierr);
1896c0ce001eSMatthew G. Knepley   ierr = PetscDSGetContext(prob, field, &rctx);CHKERRQ(ierr);
1897c0ce001eSMatthew G. Knepley   ierr = PetscDSGetConstants(prob, &numConstants, &constants);CHKERRQ(ierr);
1898c0ce001eSMatthew G. Knepley   ierr = PetscFVGetSpatialDimension(fvm, &dim);CHKERRQ(ierr);
1899c0ce001eSMatthew G. Knepley   ierr = PetscFVGetNumComponents(fvm, &pdim);CHKERRQ(ierr);
1900c0ce001eSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
1901c0ce001eSMatthew G. Knepley     (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f*Nc], &uR[f*Nc], numConstants, constants, flux, rctx);
1902c0ce001eSMatthew G. Knepley     for (d = 0; d < pdim; ++d) {
1903c0ce001eSMatthew G. Knepley       fluxL[f*totDim+off+d] = flux[d] / neighborVol[f*2+0];
1904c0ce001eSMatthew G. Knepley       fluxR[f*totDim+off+d] = flux[d] / neighborVol[f*2+1];
1905c0ce001eSMatthew G. Knepley     }
1906c0ce001eSMatthew G. Knepley   }
1907c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1908c0ce001eSMatthew G. Knepley }
1909c0ce001eSMatthew G. Knepley 
191088f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVInitialize_Upwind(PetscFV fvm)
1911c0ce001eSMatthew G. Knepley {
1912c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1913c0ce001eSMatthew G. Knepley   fvm->ops->setfromoptions          = NULL;
1914c0ce001eSMatthew G. Knepley   fvm->ops->setup                   = PetscFVSetUp_Upwind;
1915c0ce001eSMatthew G. Knepley   fvm->ops->view                    = PetscFVView_Upwind;
1916c0ce001eSMatthew G. Knepley   fvm->ops->destroy                 = PetscFVDestroy_Upwind;
1917c0ce001eSMatthew G. Knepley   fvm->ops->integraterhsfunction    = PetscFVIntegrateRHSFunction_Upwind;
1918c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1919c0ce001eSMatthew G. Knepley }
1920c0ce001eSMatthew G. Knepley 
1921c0ce001eSMatthew G. Knepley /*MC
1922c0ce001eSMatthew G. Knepley   PETSCFVUPWIND = "upwind" - A PetscFV object
1923c0ce001eSMatthew G. Knepley 
1924c0ce001eSMatthew G. Knepley   Level: intermediate
1925c0ce001eSMatthew G. Knepley 
1926c0ce001eSMatthew G. Knepley .seealso: PetscFVType, PetscFVCreate(), PetscFVSetType()
1927c0ce001eSMatthew G. Knepley M*/
1928c0ce001eSMatthew G. Knepley 
1929c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscFVCreate_Upwind(PetscFV fvm)
1930c0ce001eSMatthew G. Knepley {
1931c0ce001eSMatthew G. Knepley   PetscFV_Upwind *b;
1932c0ce001eSMatthew G. Knepley   PetscErrorCode  ierr;
1933c0ce001eSMatthew G. Knepley 
1934c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1935c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1936c0ce001eSMatthew G. Knepley   ierr      = PetscNewLog(fvm,&b);CHKERRQ(ierr);
1937c0ce001eSMatthew G. Knepley   fvm->data = b;
1938c0ce001eSMatthew G. Knepley 
1939c0ce001eSMatthew G. Knepley   ierr = PetscFVInitialize_Upwind(fvm);CHKERRQ(ierr);
1940c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1941c0ce001eSMatthew G. Knepley }
1942c0ce001eSMatthew G. Knepley 
1943c0ce001eSMatthew G. Knepley #include <petscblaslapack.h>
1944c0ce001eSMatthew G. Knepley 
194588f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVDestroy_LeastSquares(PetscFV fvm)
1946c0ce001eSMatthew G. Knepley {
1947c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *) fvm->data;
1948c0ce001eSMatthew G. Knepley   PetscErrorCode        ierr;
1949c0ce001eSMatthew G. Knepley 
1950c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1951c0ce001eSMatthew G. Knepley   ierr = PetscObjectComposeFunction((PetscObject) fvm, "PetscFVLeastSquaresSetMaxFaces_C", NULL);CHKERRQ(ierr);
1952c0ce001eSMatthew G. Knepley   ierr = PetscFree4(ls->B, ls->Binv, ls->tau, ls->work);CHKERRQ(ierr);
1953c0ce001eSMatthew G. Knepley   ierr = PetscFree(ls);CHKERRQ(ierr);
1954c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1955c0ce001eSMatthew G. Knepley }
1956c0ce001eSMatthew G. Knepley 
195788f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_LeastSquares_Ascii(PetscFV fv, PetscViewer viewer)
1958c0ce001eSMatthew G. Knepley {
1959c0ce001eSMatthew G. Knepley   PetscInt          Nc, c;
1960c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
1961c0ce001eSMatthew G. Knepley   PetscErrorCode    ierr;
1962c0ce001eSMatthew G. Knepley 
1963c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1964c0ce001eSMatthew G. Knepley   ierr = PetscFVGetNumComponents(fv, &Nc);CHKERRQ(ierr);
1965c0ce001eSMatthew G. Knepley   ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr);
1966c0ce001eSMatthew G. Knepley   ierr = PetscViewerASCIIPrintf(viewer, "Finite Volume with Least Squares Reconstruction:\n");CHKERRQ(ierr);
1967c0ce001eSMatthew G. Knepley   ierr = PetscViewerASCIIPrintf(viewer, "  num components: %d\n", Nc);CHKERRQ(ierr);
1968c0ce001eSMatthew G. Knepley   for (c = 0; c < Nc; c++) {
1969c0ce001eSMatthew G. Knepley     if (fv->componentNames[c]) {
1970c0ce001eSMatthew G. Knepley       ierr = PetscViewerASCIIPrintf(viewer, "    component %d: %s\n", c, fv->componentNames[c]);CHKERRQ(ierr);
1971c0ce001eSMatthew G. Knepley     }
1972c0ce001eSMatthew G. Knepley   }
1973c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1974c0ce001eSMatthew G. Knepley }
1975c0ce001eSMatthew G. Knepley 
197688f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_LeastSquares(PetscFV fv, PetscViewer viewer)
1977c0ce001eSMatthew G. Knepley {
1978c0ce001eSMatthew G. Knepley   PetscBool      iascii;
1979c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1980c0ce001eSMatthew G. Knepley 
1981c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1982c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1);
1983c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1984c0ce001eSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
1985c0ce001eSMatthew G. Knepley   if (iascii) {ierr = PetscFVView_LeastSquares_Ascii(fv, viewer);CHKERRQ(ierr);}
1986c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1987c0ce001eSMatthew G. Knepley }
1988c0ce001eSMatthew G. Knepley 
198988f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVSetUp_LeastSquares(PetscFV fvm)
1990c0ce001eSMatthew G. Knepley {
1991c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1992c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1993c0ce001eSMatthew G. Knepley }
1994c0ce001eSMatthew G. Knepley 
1995c0ce001eSMatthew G. Knepley /* Overwrites A. Can only handle full-rank problems with m>=n */
1996c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresPseudoInverse_Static(PetscInt m,PetscInt mstride,PetscInt n,PetscScalar *A,PetscScalar *Ainv,PetscScalar *tau,PetscInt worksize,PetscScalar *work)
1997c0ce001eSMatthew G. Knepley {
1998c0ce001eSMatthew G. Knepley   PetscBool      debug = PETSC_FALSE;
1999c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
2000c0ce001eSMatthew G. Knepley   PetscBLASInt   M,N,K,lda,ldb,ldwork,info;
2001c0ce001eSMatthew G. Knepley   PetscScalar    *R,*Q,*Aback,Alpha;
2002c0ce001eSMatthew G. Knepley 
2003c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2004c0ce001eSMatthew G. Knepley   if (debug) {
2005c0ce001eSMatthew G. Knepley     ierr = PetscMalloc1(m*n,&Aback);CHKERRQ(ierr);
2006c0ce001eSMatthew G. Knepley     ierr = PetscArraycpy(Aback,A,m*n);CHKERRQ(ierr);
2007c0ce001eSMatthew G. Knepley   }
2008c0ce001eSMatthew G. Knepley 
2009c0ce001eSMatthew G. Knepley   ierr = PetscBLASIntCast(m,&M);CHKERRQ(ierr);
2010c0ce001eSMatthew G. Knepley   ierr = PetscBLASIntCast(n,&N);CHKERRQ(ierr);
2011c0ce001eSMatthew G. Knepley   ierr = PetscBLASIntCast(mstride,&lda);CHKERRQ(ierr);
2012c0ce001eSMatthew G. Knepley   ierr = PetscBLASIntCast(worksize,&ldwork);CHKERRQ(ierr);
2013c0ce001eSMatthew G. Knepley   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
2014c0ce001eSMatthew G. Knepley   LAPACKgeqrf_(&M,&N,A,&lda,tau,work,&ldwork,&info);
2015c0ce001eSMatthew G. Knepley   ierr = PetscFPTrapPop();CHKERRQ(ierr);
2016c0ce001eSMatthew G. Knepley   if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"xGEQRF error");
2017c0ce001eSMatthew G. Knepley   R = A; /* Upper triangular part of A now contains R, the rest contains the elementary reflectors */
2018c0ce001eSMatthew G. Knepley 
2019c0ce001eSMatthew G. Knepley   /* Extract an explicit representation of Q */
2020c0ce001eSMatthew G. Knepley   Q    = Ainv;
2021c0ce001eSMatthew G. Knepley   ierr = PetscArraycpy(Q,A,mstride*n);CHKERRQ(ierr);
2022c0ce001eSMatthew G. Knepley   K    = N;                     /* full rank */
2023c0ce001eSMatthew G. Knepley   PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&M,&N,&K,Q,&lda,tau,work,&ldwork,&info));
2024c0ce001eSMatthew G. Knepley   if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"xORGQR/xUNGQR error");
2025c0ce001eSMatthew G. Knepley 
2026c0ce001eSMatthew G. Knepley   /* Compute A^{-T} = (R^{-1} Q^T)^T = Q R^{-T} */
2027c0ce001eSMatthew G. Knepley   Alpha = 1.0;
2028c0ce001eSMatthew G. Knepley   ldb   = lda;
2029c0ce001eSMatthew G. Knepley   BLAStrsm_("Right","Upper","ConjugateTranspose","NotUnitTriangular",&M,&N,&Alpha,R,&lda,Q,&ldb);
2030c0ce001eSMatthew G. Knepley   /* Ainv is Q, overwritten with inverse */
2031c0ce001eSMatthew G. Knepley 
2032c0ce001eSMatthew G. Knepley   if (debug) {                      /* Check that pseudo-inverse worked */
2033c0ce001eSMatthew G. Knepley     PetscScalar  Beta = 0.0;
2034c0ce001eSMatthew G. Knepley     PetscBLASInt ldc;
2035c0ce001eSMatthew G. Knepley     K   = N;
2036c0ce001eSMatthew G. Knepley     ldc = N;
2037c0ce001eSMatthew G. Knepley     BLASgemm_("ConjugateTranspose","Normal",&N,&K,&M,&Alpha,Ainv,&lda,Aback,&ldb,&Beta,work,&ldc);
2038c0ce001eSMatthew G. Knepley     ierr = PetscScalarView(n*n,work,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr);
2039c0ce001eSMatthew G. Knepley     ierr = PetscFree(Aback);CHKERRQ(ierr);
2040c0ce001eSMatthew G. Knepley   }
2041c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2042c0ce001eSMatthew G. Knepley }
2043c0ce001eSMatthew G. Knepley 
2044c0ce001eSMatthew G. Knepley /* Overwrites A. Can handle degenerate problems and m<n. */
2045c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresPseudoInverseSVD_Static(PetscInt m,PetscInt mstride,PetscInt n,PetscScalar *A,PetscScalar *Ainv,PetscScalar *tau,PetscInt worksize,PetscScalar *work)
2046c0ce001eSMatthew G. Knepley {
2047c0ce001eSMatthew G. Knepley   PetscBool      debug = PETSC_FALSE;
2048c0ce001eSMatthew G. Knepley   PetscScalar   *Brhs, *Aback;
2049c0ce001eSMatthew G. Knepley   PetscScalar   *tmpwork;
2050c0ce001eSMatthew G. Knepley   PetscReal      rcond;
2051c0ce001eSMatthew G. Knepley #if defined (PETSC_USE_COMPLEX)
2052c0ce001eSMatthew G. Knepley   PetscInt       rworkSize;
2053c0ce001eSMatthew G. Knepley   PetscReal     *rwork;
2054c0ce001eSMatthew G. Knepley #endif
2055c0ce001eSMatthew G. Knepley   PetscInt       i, j, maxmn;
2056c0ce001eSMatthew G. Knepley   PetscBLASInt   M, N, lda, ldb, ldwork;
2057c0ce001eSMatthew G. Knepley   PetscBLASInt   nrhs, irank, info;
2058c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
2059c0ce001eSMatthew G. Knepley 
2060c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2061c0ce001eSMatthew G. Knepley   if (debug) {
2062c0ce001eSMatthew G. Knepley     ierr = PetscMalloc1(m*n,&Aback);CHKERRQ(ierr);
2063c0ce001eSMatthew G. Knepley     ierr = PetscArraycpy(Aback,A,m*n);CHKERRQ(ierr);
2064c0ce001eSMatthew G. Knepley   }
2065c0ce001eSMatthew G. Knepley 
2066c0ce001eSMatthew G. Knepley   /* initialize to identity */
2067c0ce001eSMatthew G. Knepley   tmpwork = Ainv;
2068c0ce001eSMatthew G. Knepley   Brhs = work;
2069c0ce001eSMatthew G. Knepley   maxmn = PetscMax(m,n);
2070c0ce001eSMatthew G. Knepley   for (j=0; j<maxmn; j++) {
2071c0ce001eSMatthew G. Knepley     for (i=0; i<maxmn; i++) Brhs[i + j*maxmn] = 1.0*(i == j);
2072c0ce001eSMatthew G. Knepley   }
2073c0ce001eSMatthew G. Knepley 
2074c0ce001eSMatthew G. Knepley   ierr  = PetscBLASIntCast(m,&M);CHKERRQ(ierr);
2075c0ce001eSMatthew G. Knepley   ierr  = PetscBLASIntCast(n,&N);CHKERRQ(ierr);
2076c0ce001eSMatthew G. Knepley   ierr  = PetscBLASIntCast(mstride,&lda);CHKERRQ(ierr);
2077c0ce001eSMatthew G. Knepley   ierr  = PetscBLASIntCast(maxmn,&ldb);CHKERRQ(ierr);
2078c0ce001eSMatthew G. Knepley   ierr  = PetscBLASIntCast(worksize,&ldwork);CHKERRQ(ierr);
2079c0ce001eSMatthew G. Knepley   rcond = -1;
2080c0ce001eSMatthew G. Knepley   ierr  = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
2081c0ce001eSMatthew G. Knepley   nrhs  = M;
2082c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX)
2083c0ce001eSMatthew G. Knepley   rworkSize = 5 * PetscMin(M,N);
2084c0ce001eSMatthew G. Knepley   ierr  = PetscMalloc1(rworkSize,&rwork);CHKERRQ(ierr);
2085c0ce001eSMatthew G. Knepley   LAPACKgelss_(&M,&N,&nrhs,A,&lda,Brhs,&ldb, (PetscReal *) tau,&rcond,&irank,tmpwork,&ldwork,rwork,&info);
2086c0ce001eSMatthew G. Knepley   ierr = PetscFPTrapPop();CHKERRQ(ierr);
2087c0ce001eSMatthew G. Knepley   ierr = PetscFree(rwork);CHKERRQ(ierr);
2088c0ce001eSMatthew G. Knepley #else
2089c0ce001eSMatthew G. Knepley   nrhs  = M;
2090c0ce001eSMatthew G. Knepley   LAPACKgelss_(&M,&N,&nrhs,A,&lda,Brhs,&ldb, (PetscReal *) tau,&rcond,&irank,tmpwork,&ldwork,&info);
2091c0ce001eSMatthew G. Knepley   ierr = PetscFPTrapPop();CHKERRQ(ierr);
2092c0ce001eSMatthew G. Knepley #endif
2093c0ce001eSMatthew G. Knepley   if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"xGELSS error");
2094c0ce001eSMatthew G. Knepley   /* The following check should be turned into a diagnostic as soon as someone wants to do this intentionally */
2095c0ce001eSMatthew G. Knepley   if (irank < PetscMin(M,N)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Rank deficient least squares fit, indicates an isolated cell with two colinear points");
2096c0ce001eSMatthew G. Knepley 
2097c0ce001eSMatthew G. Knepley   /* Brhs shaped (M,nrhs) column-major coldim=mstride was overwritten by Ainv shaped (N,nrhs) column-major coldim=maxmn.
2098c0ce001eSMatthew G. Knepley    * Here we transpose to (N,nrhs) row-major rowdim=mstride. */
2099c0ce001eSMatthew G. Knepley   for (i=0; i<n; i++) {
2100c0ce001eSMatthew G. Knepley     for (j=0; j<nrhs; j++) Ainv[i*mstride+j] = Brhs[i + j*maxmn];
2101c0ce001eSMatthew G. Knepley   }
2102c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2103c0ce001eSMatthew G. Knepley }
2104c0ce001eSMatthew G. Knepley 
2105c0ce001eSMatthew G. Knepley #if 0
2106c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresDebugCell_Static(PetscFV fvm, PetscInt cell, DM dm, DM dmFace, PetscScalar *fgeom, DM dmCell, PetscScalar *cgeom)
2107c0ce001eSMatthew G. Knepley {
2108c0ce001eSMatthew G. Knepley   PetscReal       grad[2] = {0, 0};
2109c0ce001eSMatthew G. Knepley   const PetscInt *faces;
2110c0ce001eSMatthew G. Knepley   PetscInt        numFaces, f;
2111c0ce001eSMatthew G. Knepley   PetscErrorCode  ierr;
2112c0ce001eSMatthew G. Knepley 
2113c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2114c0ce001eSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cell, &numFaces);CHKERRQ(ierr);
2115c0ce001eSMatthew G. Knepley   ierr = DMPlexGetCone(dm, cell, &faces);CHKERRQ(ierr);
2116c0ce001eSMatthew G. Knepley   for (f = 0; f < numFaces; ++f) {
2117c0ce001eSMatthew G. Knepley     const PetscInt *fcells;
2118c0ce001eSMatthew G. Knepley     const CellGeom *cg1;
2119c0ce001eSMatthew G. Knepley     const FaceGeom *fg;
2120c0ce001eSMatthew G. Knepley 
2121c0ce001eSMatthew G. Knepley     ierr = DMPlexGetSupport(dm, faces[f], &fcells);CHKERRQ(ierr);
2122c0ce001eSMatthew G. Knepley     ierr = DMPlexPointLocalRead(dmFace, faces[f], fgeom, &fg);CHKERRQ(ierr);
2123c0ce001eSMatthew G. Knepley     for (i = 0; i < 2; ++i) {
2124c0ce001eSMatthew G. Knepley       PetscScalar du;
2125c0ce001eSMatthew G. Knepley 
2126c0ce001eSMatthew G. Knepley       if (fcells[i] == c) continue;
2127c0ce001eSMatthew G. Knepley       ierr = DMPlexPointLocalRead(dmCell, fcells[i], cgeom, &cg1);CHKERRQ(ierr);
2128c0ce001eSMatthew G. Knepley       du   = cg1->centroid[0] + 3*cg1->centroid[1] - (cg->centroid[0] + 3*cg->centroid[1]);
2129c0ce001eSMatthew G. Knepley       grad[0] += fg->grad[!i][0] * du;
2130c0ce001eSMatthew G. Knepley       grad[1] += fg->grad[!i][1] * du;
2131c0ce001eSMatthew G. Knepley     }
2132c0ce001eSMatthew G. Knepley   }
2133c0ce001eSMatthew G. Knepley   PetscPrintf(PETSC_COMM_SELF, "cell[%d] grad (%g, %g)\n", cell, grad[0], grad[1]);CHKERRQ(ierr);
2134c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2135c0ce001eSMatthew G. Knepley }
2136c0ce001eSMatthew G. Knepley #endif
2137c0ce001eSMatthew G. Knepley 
2138c0ce001eSMatthew G. Knepley /*
2139c0ce001eSMatthew G. Knepley   PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell
2140c0ce001eSMatthew G. Knepley 
2141c0ce001eSMatthew G. Knepley   Input Parameters:
2142c0ce001eSMatthew G. Knepley + fvm      - The PetscFV object
2143c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained
2144c0ce001eSMatthew G. Knepley . dx       - The vector from the cell centroid to the neighboring cell centroid for each face
2145c0ce001eSMatthew G. Knepley 
2146c0ce001eSMatthew G. Knepley   Level: developer
2147c0ce001eSMatthew G. Knepley 
2148c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate()
2149c0ce001eSMatthew G. Knepley */
215088f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVComputeGradient_LeastSquares(PetscFV fvm, PetscInt numFaces, const PetscScalar dx[], PetscScalar grad[])
2151c0ce001eSMatthew G. Knepley {
2152c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls       = (PetscFV_LeastSquares *) fvm->data;
2153c0ce001eSMatthew G. Knepley   const PetscBool       useSVD   = PETSC_TRUE;
2154c0ce001eSMatthew G. Knepley   const PetscInt        maxFaces = ls->maxFaces;
2155c0ce001eSMatthew G. Knepley   PetscInt              dim, f, d;
2156c0ce001eSMatthew G. Knepley   PetscErrorCode        ierr;
2157c0ce001eSMatthew G. Knepley 
2158c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2159c0ce001eSMatthew G. Knepley   if (numFaces > maxFaces) {
2160c0ce001eSMatthew G. Knepley     if (maxFaces < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Reconstruction has not been initialized, call PetscFVLeastSquaresSetMaxFaces()");
2161c0ce001eSMatthew G. Knepley     SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of input faces %D > %D maxfaces", numFaces, maxFaces);
2162c0ce001eSMatthew G. Knepley   }
2163c0ce001eSMatthew G. Knepley   ierr = PetscFVGetSpatialDimension(fvm, &dim);CHKERRQ(ierr);
2164c0ce001eSMatthew G. Knepley   for (f = 0; f < numFaces; ++f) {
2165c0ce001eSMatthew G. Knepley     for (d = 0; d < dim; ++d) ls->B[d*maxFaces+f] = dx[f*dim+d];
2166c0ce001eSMatthew G. Knepley   }
2167c0ce001eSMatthew G. Knepley   /* Overwrites B with garbage, returns Binv in row-major format */
2168c0ce001eSMatthew G. Knepley   if (useSVD) {ierr = PetscFVLeastSquaresPseudoInverseSVD_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work);CHKERRQ(ierr);}
2169c0ce001eSMatthew G. Knepley   else        {ierr = PetscFVLeastSquaresPseudoInverse_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work);CHKERRQ(ierr);}
2170c0ce001eSMatthew G. Knepley   for (f = 0; f < numFaces; ++f) {
2171c0ce001eSMatthew G. Knepley     for (d = 0; d < dim; ++d) grad[f*dim+d] = ls->Binv[d*maxFaces+f];
2172c0ce001eSMatthew G. Knepley   }
2173c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2174c0ce001eSMatthew G. Knepley }
2175c0ce001eSMatthew G. Knepley 
2176c0ce001eSMatthew G. Knepley /*
2177c0ce001eSMatthew G. Knepley   neighborVol[f*2+0] contains the left  geom
2178c0ce001eSMatthew G. Knepley   neighborVol[f*2+1] contains the right geom
2179c0ce001eSMatthew G. Knepley */
218088f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVIntegrateRHSFunction_LeastSquares(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol,
2181c0ce001eSMatthew G. Knepley                                                                PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[])
2182c0ce001eSMatthew G. Knepley {
2183c0ce001eSMatthew G. Knepley   void             (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *);
2184c0ce001eSMatthew G. Knepley   void              *rctx;
2185c0ce001eSMatthew G. Knepley   PetscScalar       *flux = fvm->fluxWork;
2186c0ce001eSMatthew G. Knepley   const PetscScalar *constants;
2187c0ce001eSMatthew G. Knepley   PetscInt           dim, numConstants, pdim, Nc, totDim, off, f, d;
2188c0ce001eSMatthew G. Knepley   PetscErrorCode     ierr;
2189c0ce001eSMatthew G. Knepley 
2190c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2191c0ce001eSMatthew G. Knepley   ierr = PetscDSGetTotalComponents(prob, &Nc);CHKERRQ(ierr);
2192c0ce001eSMatthew G. Knepley   ierr = PetscDSGetTotalDimension(prob, &totDim);CHKERRQ(ierr);
2193c0ce001eSMatthew G. Knepley   ierr = PetscDSGetFieldOffset(prob, field, &off);CHKERRQ(ierr);
2194c0ce001eSMatthew G. Knepley   ierr = PetscDSGetRiemannSolver(prob, field, &riemann);CHKERRQ(ierr);
2195c0ce001eSMatthew G. Knepley   ierr = PetscDSGetContext(prob, field, &rctx);CHKERRQ(ierr);
2196c0ce001eSMatthew G. Knepley   ierr = PetscDSGetConstants(prob, &numConstants, &constants);CHKERRQ(ierr);
2197c0ce001eSMatthew G. Knepley   ierr = PetscFVGetSpatialDimension(fvm, &dim);CHKERRQ(ierr);
2198c0ce001eSMatthew G. Knepley   ierr = PetscFVGetNumComponents(fvm, &pdim);CHKERRQ(ierr);
2199c0ce001eSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
2200c0ce001eSMatthew G. Knepley     (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f*Nc], &uR[f*Nc], numConstants, constants, flux, rctx);
2201c0ce001eSMatthew G. Knepley     for (d = 0; d < pdim; ++d) {
2202c0ce001eSMatthew G. Knepley       fluxL[f*totDim+off+d] = flux[d] / neighborVol[f*2+0];
2203c0ce001eSMatthew G. Knepley       fluxR[f*totDim+off+d] = flux[d] / neighborVol[f*2+1];
2204c0ce001eSMatthew G. Knepley     }
2205c0ce001eSMatthew G. Knepley   }
2206c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2207c0ce001eSMatthew G. Knepley }
2208c0ce001eSMatthew G. Knepley 
2209c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresSetMaxFaces_LS(PetscFV fvm, PetscInt maxFaces)
2210c0ce001eSMatthew G. Knepley {
2211c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *) fvm->data;
2212c0ce001eSMatthew G. Knepley   PetscInt              dim, m, n, nrhs, minwork;
2213c0ce001eSMatthew G. Knepley   PetscErrorCode        ierr;
2214c0ce001eSMatthew G. Knepley 
2215c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2216c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
2217c0ce001eSMatthew G. Knepley   ierr = PetscFVGetSpatialDimension(fvm, &dim);CHKERRQ(ierr);
2218c0ce001eSMatthew G. Knepley   ierr = PetscFree4(ls->B, ls->Binv, ls->tau, ls->work);CHKERRQ(ierr);
2219c0ce001eSMatthew G. Knepley   ls->maxFaces = maxFaces;
2220c0ce001eSMatthew G. Knepley   m       = ls->maxFaces;
2221c0ce001eSMatthew G. Knepley   n       = dim;
2222c0ce001eSMatthew G. Knepley   nrhs    = ls->maxFaces;
2223c0ce001eSMatthew G. Knepley   minwork = 3*PetscMin(m,n) + PetscMax(2*PetscMin(m,n), PetscMax(PetscMax(m,n), nrhs)); /* required by LAPACK */
2224c0ce001eSMatthew G. Knepley   ls->workSize = 5*minwork; /* We can afford to be extra generous */
2225c0ce001eSMatthew G. Knepley   ierr = PetscMalloc4(ls->maxFaces*dim,&ls->B,ls->workSize,&ls->Binv,ls->maxFaces,&ls->tau,ls->workSize,&ls->work);CHKERRQ(ierr);
2226c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2227c0ce001eSMatthew G. Knepley }
2228c0ce001eSMatthew G. Knepley 
2229c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVInitialize_LeastSquares(PetscFV fvm)
2230c0ce001eSMatthew G. Knepley {
2231c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2232c0ce001eSMatthew G. Knepley   fvm->ops->setfromoptions          = NULL;
2233c0ce001eSMatthew G. Knepley   fvm->ops->setup                   = PetscFVSetUp_LeastSquares;
2234c0ce001eSMatthew G. Knepley   fvm->ops->view                    = PetscFVView_LeastSquares;
2235c0ce001eSMatthew G. Knepley   fvm->ops->destroy                 = PetscFVDestroy_LeastSquares;
2236c0ce001eSMatthew G. Knepley   fvm->ops->computegradient         = PetscFVComputeGradient_LeastSquares;
2237c0ce001eSMatthew G. Knepley   fvm->ops->integraterhsfunction    = PetscFVIntegrateRHSFunction_LeastSquares;
2238c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2239c0ce001eSMatthew G. Knepley }
2240c0ce001eSMatthew G. Knepley 
2241c0ce001eSMatthew G. Knepley /*MC
2242c0ce001eSMatthew G. Knepley   PETSCFVLEASTSQUARES = "leastsquares" - A PetscFV object
2243c0ce001eSMatthew G. Knepley 
2244c0ce001eSMatthew G. Knepley   Level: intermediate
2245c0ce001eSMatthew G. Knepley 
2246c0ce001eSMatthew G. Knepley .seealso: PetscFVType, PetscFVCreate(), PetscFVSetType()
2247c0ce001eSMatthew G. Knepley M*/
2248c0ce001eSMatthew G. Knepley 
2249c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscFVCreate_LeastSquares(PetscFV fvm)
2250c0ce001eSMatthew G. Knepley {
2251c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls;
2252c0ce001eSMatthew G. Knepley   PetscErrorCode        ierr;
2253c0ce001eSMatthew G. Knepley 
2254c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2255c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
2256c0ce001eSMatthew G. Knepley   ierr      = PetscNewLog(fvm, &ls);CHKERRQ(ierr);
2257c0ce001eSMatthew G. Knepley   fvm->data = ls;
2258c0ce001eSMatthew G. Knepley 
2259c0ce001eSMatthew G. Knepley   ls->maxFaces = -1;
2260c0ce001eSMatthew G. Knepley   ls->workSize = -1;
2261c0ce001eSMatthew G. Knepley   ls->B        = NULL;
2262c0ce001eSMatthew G. Knepley   ls->Binv     = NULL;
2263c0ce001eSMatthew G. Knepley   ls->tau      = NULL;
2264c0ce001eSMatthew G. Knepley   ls->work     = NULL;
2265c0ce001eSMatthew G. Knepley 
2266c0ce001eSMatthew G. Knepley   ierr = PetscFVSetComputeGradients(fvm, PETSC_TRUE);CHKERRQ(ierr);
2267c0ce001eSMatthew G. Knepley   ierr = PetscFVInitialize_LeastSquares(fvm);CHKERRQ(ierr);
2268c0ce001eSMatthew G. Knepley   ierr = PetscObjectComposeFunction((PetscObject) fvm, "PetscFVLeastSquaresSetMaxFaces_C", PetscFVLeastSquaresSetMaxFaces_LS);CHKERRQ(ierr);
2269c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2270c0ce001eSMatthew G. Knepley }
2271c0ce001eSMatthew G. Knepley 
2272c0ce001eSMatthew G. Knepley /*@
2273c0ce001eSMatthew G. Knepley   PetscFVLeastSquaresSetMaxFaces - Set the maximum number of cell faces for gradient reconstruction
2274c0ce001eSMatthew G. Knepley 
2275c0ce001eSMatthew G. Knepley   Not collective
2276c0ce001eSMatthew G. Knepley 
2277c0ce001eSMatthew G. Knepley   Input parameters:
2278c0ce001eSMatthew G. Knepley + fvm      - The PetscFV object
2279c0ce001eSMatthew G. Knepley - maxFaces - The maximum number of cell faces
2280c0ce001eSMatthew G. Knepley 
2281c0ce001eSMatthew G. Knepley   Level: intermediate
2282c0ce001eSMatthew G. Knepley 
2283c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate(), PETSCFVLEASTSQUARES
2284c0ce001eSMatthew G. Knepley @*/
2285c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVLeastSquaresSetMaxFaces(PetscFV fvm, PetscInt maxFaces)
2286c0ce001eSMatthew G. Knepley {
2287c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
2288c0ce001eSMatthew G. Knepley 
2289c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2290c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
2291c0ce001eSMatthew G. Knepley   ierr = PetscTryMethod(fvm, "PetscFVLeastSquaresSetMaxFaces_C", (PetscFV,PetscInt), (fvm,maxFaces));CHKERRQ(ierr);
2292c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2293c0ce001eSMatthew G. Knepley }
2294