xref: /petsc/src/dm/dt/fv/interface/fv.c (revision 792fecdfe9134cce4d631112660ddd34f063bc17)
1c0ce001eSMatthew G. Knepley #include <petsc/private/petscfvimpl.h> /*I "petscfv.h" I*/
2412e9a14SMatthew G. Knepley #include <petscdmplex.h>
3012bc364SMatthew G. Knepley #include <petscdmplextransform.h>
4c0ce001eSMatthew G. Knepley #include <petscds.h>
5c0ce001eSMatthew G. Knepley 
6c0ce001eSMatthew G. Knepley PetscClassId PETSCLIMITER_CLASSID = 0;
7c0ce001eSMatthew G. Knepley 
8c0ce001eSMatthew G. Knepley PetscFunctionList PetscLimiterList              = NULL;
9c0ce001eSMatthew G. Knepley PetscBool         PetscLimiterRegisterAllCalled = PETSC_FALSE;
10c0ce001eSMatthew G. Knepley 
11c0ce001eSMatthew G. Knepley PetscBool Limitercite = PETSC_FALSE;
12c0ce001eSMatthew G. Knepley const char LimiterCitation[] = "@article{BergerAftosmisMurman2005,\n"
13c0ce001eSMatthew G. Knepley                                "  title   = {Analysis of slope limiters on irregular grids},\n"
14c0ce001eSMatthew G. Knepley                                "  journal = {AIAA paper},\n"
15c0ce001eSMatthew G. Knepley                                "  author  = {Marsha Berger and Michael J. Aftosmis and Scott M. Murman},\n"
16c0ce001eSMatthew G. Knepley                                "  volume  = {490},\n"
17c0ce001eSMatthew G. Knepley                                "  year    = {2005}\n}\n";
18c0ce001eSMatthew G. Knepley 
19c0ce001eSMatthew G. Knepley /*@C
20c0ce001eSMatthew G. Knepley   PetscLimiterRegister - Adds a new PetscLimiter implementation
21c0ce001eSMatthew G. Knepley 
22c0ce001eSMatthew G. Knepley   Not Collective
23c0ce001eSMatthew G. Knepley 
24c0ce001eSMatthew G. Knepley   Input Parameters:
25c0ce001eSMatthew G. Knepley + name        - The name of a new user-defined creation routine
26c0ce001eSMatthew G. Knepley - create_func - The creation routine itself
27c0ce001eSMatthew G. Knepley 
28c0ce001eSMatthew G. Knepley   Notes:
29c0ce001eSMatthew G. Knepley   PetscLimiterRegister() may be called multiple times to add several user-defined PetscLimiters
30c0ce001eSMatthew G. Knepley 
31c0ce001eSMatthew G. Knepley   Sample usage:
32c0ce001eSMatthew G. Knepley .vb
33c0ce001eSMatthew G. Knepley     PetscLimiterRegister("my_lim", MyPetscLimiterCreate);
34c0ce001eSMatthew G. Knepley .ve
35c0ce001eSMatthew G. Knepley 
36c0ce001eSMatthew G. Knepley   Then, your PetscLimiter type can be chosen with the procedural interface via
37c0ce001eSMatthew G. Knepley .vb
38c0ce001eSMatthew G. Knepley     PetscLimiterCreate(MPI_Comm, PetscLimiter *);
39c0ce001eSMatthew G. Knepley     PetscLimiterSetType(PetscLimiter, "my_lim");
40c0ce001eSMatthew G. Knepley .ve
41c0ce001eSMatthew G. Knepley    or at runtime via the option
42c0ce001eSMatthew G. Knepley .vb
43c0ce001eSMatthew G. Knepley     -petsclimiter_type my_lim
44c0ce001eSMatthew G. Knepley .ve
45c0ce001eSMatthew G. Knepley 
46c0ce001eSMatthew G. Knepley   Level: advanced
47c0ce001eSMatthew G. Knepley 
48db781477SPatrick Sanan .seealso: `PetscLimiterRegisterAll()`, `PetscLimiterRegisterDestroy()`
49c0ce001eSMatthew G. Knepley 
50c0ce001eSMatthew G. Knepley @*/
51c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterRegister(const char sname[], PetscErrorCode (*function)(PetscLimiter))
52c0ce001eSMatthew G. Knepley {
53c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
549566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscLimiterList, sname, function));
55c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
56c0ce001eSMatthew G. Knepley }
57c0ce001eSMatthew G. Knepley 
58c0ce001eSMatthew G. Knepley /*@C
59c0ce001eSMatthew G. Knepley   PetscLimiterSetType - Builds a particular PetscLimiter
60c0ce001eSMatthew G. Knepley 
61c0ce001eSMatthew G. Knepley   Collective on lim
62c0ce001eSMatthew G. Knepley 
63c0ce001eSMatthew G. Knepley   Input Parameters:
64c0ce001eSMatthew G. Knepley + lim  - The PetscLimiter object
65c0ce001eSMatthew G. Knepley - name - The kind of limiter
66c0ce001eSMatthew G. Knepley 
67c0ce001eSMatthew G. Knepley   Options Database Key:
68c0ce001eSMatthew G. Knepley . -petsclimiter_type <type> - Sets the PetscLimiter type; use -help for a list of available types
69c0ce001eSMatthew G. Knepley 
70c0ce001eSMatthew G. Knepley   Level: intermediate
71c0ce001eSMatthew G. Knepley 
72db781477SPatrick Sanan .seealso: `PetscLimiterGetType()`, `PetscLimiterCreate()`
73c0ce001eSMatthew G. Knepley @*/
74c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterSetType(PetscLimiter lim, PetscLimiterType name)
75c0ce001eSMatthew G. Knepley {
76c0ce001eSMatthew G. Knepley   PetscErrorCode (*r)(PetscLimiter);
77c0ce001eSMatthew G. Knepley   PetscBool      match;
78c0ce001eSMatthew G. Knepley 
79c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
80c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
819566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) lim, name, &match));
82c0ce001eSMatthew G. Knepley   if (match) PetscFunctionReturn(0);
83c0ce001eSMatthew G. Knepley 
849566063dSJacob Faibussowitsch   PetscCall(PetscLimiterRegisterAll());
859566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscLimiterList, name, &r));
8628b400f6SJacob Faibussowitsch   PetscCheck(r,PetscObjectComm((PetscObject) lim), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscLimiter type: %s", name);
87c0ce001eSMatthew G. Knepley 
88c0ce001eSMatthew G. Knepley   if (lim->ops->destroy) {
899566063dSJacob Faibussowitsch     PetscCall((*lim->ops->destroy)(lim));
90c0ce001eSMatthew G. Knepley     lim->ops->destroy = NULL;
91c0ce001eSMatthew G. Knepley   }
929566063dSJacob Faibussowitsch   PetscCall((*r)(lim));
939566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject) lim, name));
94c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
95c0ce001eSMatthew G. Knepley }
96c0ce001eSMatthew G. Knepley 
97c0ce001eSMatthew G. Knepley /*@C
98c0ce001eSMatthew G. Knepley   PetscLimiterGetType - Gets the PetscLimiter type name (as a string) from the object.
99c0ce001eSMatthew G. Knepley 
100c0ce001eSMatthew G. Knepley   Not Collective
101c0ce001eSMatthew G. Knepley 
102c0ce001eSMatthew G. Knepley   Input Parameter:
103c0ce001eSMatthew G. Knepley . lim  - The PetscLimiter
104c0ce001eSMatthew G. Knepley 
105c0ce001eSMatthew G. Knepley   Output Parameter:
106c0ce001eSMatthew G. Knepley . name - The PetscLimiter type name
107c0ce001eSMatthew G. Knepley 
108c0ce001eSMatthew G. Knepley   Level: intermediate
109c0ce001eSMatthew G. Knepley 
110db781477SPatrick Sanan .seealso: `PetscLimiterSetType()`, `PetscLimiterCreate()`
111c0ce001eSMatthew G. Knepley @*/
112c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterGetType(PetscLimiter lim, PetscLimiterType *name)
113c0ce001eSMatthew G. Knepley {
114c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
115c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
116c0ce001eSMatthew G. Knepley   PetscValidPointer(name, 2);
1179566063dSJacob Faibussowitsch   PetscCall(PetscLimiterRegisterAll());
118c0ce001eSMatthew G. Knepley   *name = ((PetscObject) lim)->type_name;
119c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
120c0ce001eSMatthew G. Knepley }
121c0ce001eSMatthew G. Knepley 
122c0ce001eSMatthew G. Knepley /*@C
123fe2efc57SMark    PetscLimiterViewFromOptions - View from Options
124fe2efc57SMark 
125fe2efc57SMark    Collective on PetscLimiter
126fe2efc57SMark 
127fe2efc57SMark    Input Parameters:
128fe2efc57SMark +  A - the PetscLimiter object to view
129736c3998SJose E. Roman .  obj - Optional object
130736c3998SJose E. Roman -  name - command line option
131fe2efc57SMark 
132fe2efc57SMark    Level: intermediate
133db781477SPatrick Sanan .seealso: `PetscLimiter`, `PetscLimiterView`, `PetscObjectViewFromOptions()`, `PetscLimiterCreate()`
134fe2efc57SMark @*/
135fe2efc57SMark PetscErrorCode  PetscLimiterViewFromOptions(PetscLimiter A,PetscObject obj,const char name[])
136fe2efc57SMark {
137fe2efc57SMark   PetscFunctionBegin;
138fe2efc57SMark   PetscValidHeaderSpecific(A,PETSCLIMITER_CLASSID,1);
1399566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name));
140fe2efc57SMark   PetscFunctionReturn(0);
141fe2efc57SMark }
142fe2efc57SMark 
143fe2efc57SMark /*@C
144c0ce001eSMatthew G. Knepley   PetscLimiterView - Views a PetscLimiter
145c0ce001eSMatthew G. Knepley 
146c0ce001eSMatthew G. Knepley   Collective on lim
147c0ce001eSMatthew G. Knepley 
148d8d19677SJose E. Roman   Input Parameters:
149c0ce001eSMatthew G. Knepley + lim - the PetscLimiter object to view
150c0ce001eSMatthew G. Knepley - v   - the viewer
151c0ce001eSMatthew G. Knepley 
15288f5f89eSMatthew G. Knepley   Level: beginner
153c0ce001eSMatthew G. Knepley 
154db781477SPatrick Sanan .seealso: `PetscLimiterDestroy()`
155c0ce001eSMatthew G. Knepley @*/
156c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterView(PetscLimiter lim, PetscViewer v)
157c0ce001eSMatthew G. Knepley {
158c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
159c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
1609566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) lim), &v));
1619566063dSJacob Faibussowitsch   if (lim->ops->view) PetscCall((*lim->ops->view)(lim, v));
162c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
163c0ce001eSMatthew G. Knepley }
164c0ce001eSMatthew G. Knepley 
165c0ce001eSMatthew G. Knepley /*@
166c0ce001eSMatthew G. Knepley   PetscLimiterSetFromOptions - sets parameters in a PetscLimiter from the options database
167c0ce001eSMatthew G. Knepley 
168c0ce001eSMatthew G. Knepley   Collective on lim
169c0ce001eSMatthew G. Knepley 
170c0ce001eSMatthew G. Knepley   Input Parameter:
171c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to set options for
172c0ce001eSMatthew G. Knepley 
17388f5f89eSMatthew G. Knepley   Level: intermediate
174c0ce001eSMatthew G. Knepley 
175db781477SPatrick Sanan .seealso: `PetscLimiterView()`
176c0ce001eSMatthew G. Knepley @*/
177c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterSetFromOptions(PetscLimiter lim)
178c0ce001eSMatthew G. Knepley {
179c0ce001eSMatthew G. Knepley   const char    *defaultType;
180c0ce001eSMatthew G. Knepley   char           name[256];
181c0ce001eSMatthew G. Knepley   PetscBool      flg;
182c0ce001eSMatthew G. Knepley 
183c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
184c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
185c0ce001eSMatthew G. Knepley   if (!((PetscObject) lim)->type_name) defaultType = PETSCLIMITERSIN;
186c0ce001eSMatthew G. Knepley   else                                 defaultType = ((PetscObject) lim)->type_name;
1879566063dSJacob Faibussowitsch   PetscCall(PetscLimiterRegisterAll());
188c0ce001eSMatthew G. Knepley 
189d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject) lim);
1909566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petsclimiter_type", "Finite volume slope limiter", "PetscLimiterSetType", PetscLimiterList, defaultType, name, 256, &flg));
191c0ce001eSMatthew G. Knepley   if (flg) {
1929566063dSJacob Faibussowitsch     PetscCall(PetscLimiterSetType(lim, name));
193c0ce001eSMatthew G. Knepley   } else if (!((PetscObject) lim)->type_name) {
1949566063dSJacob Faibussowitsch     PetscCall(PetscLimiterSetType(lim, defaultType));
195c0ce001eSMatthew G. Knepley   }
1969566063dSJacob Faibussowitsch   if (lim->ops->setfromoptions) PetscCall((*lim->ops->setfromoptions)(lim));
197c0ce001eSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
1989566063dSJacob Faibussowitsch   PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) lim));
199d0609cedSBarry Smith   PetscOptionsEnd();
2009566063dSJacob Faibussowitsch   PetscCall(PetscLimiterViewFromOptions(lim, NULL, "-petsclimiter_view"));
201c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
202c0ce001eSMatthew G. Knepley }
203c0ce001eSMatthew G. Knepley 
204c0ce001eSMatthew G. Knepley /*@C
205c0ce001eSMatthew G. Knepley   PetscLimiterSetUp - Construct data structures for the PetscLimiter
206c0ce001eSMatthew G. Knepley 
207c0ce001eSMatthew G. Knepley   Collective on lim
208c0ce001eSMatthew G. Knepley 
209c0ce001eSMatthew G. Knepley   Input Parameter:
210c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to setup
211c0ce001eSMatthew G. Knepley 
21288f5f89eSMatthew G. Knepley   Level: intermediate
213c0ce001eSMatthew G. Knepley 
214db781477SPatrick Sanan .seealso: `PetscLimiterView()`, `PetscLimiterDestroy()`
215c0ce001eSMatthew G. Knepley @*/
216c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterSetUp(PetscLimiter lim)
217c0ce001eSMatthew G. Knepley {
218c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
219c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
2209566063dSJacob Faibussowitsch   if (lim->ops->setup) PetscCall((*lim->ops->setup)(lim));
221c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
222c0ce001eSMatthew G. Knepley }
223c0ce001eSMatthew G. Knepley 
224c0ce001eSMatthew G. Knepley /*@
225c0ce001eSMatthew G. Knepley   PetscLimiterDestroy - Destroys a PetscLimiter object
226c0ce001eSMatthew G. Knepley 
227c0ce001eSMatthew G. Knepley   Collective on lim
228c0ce001eSMatthew G. Knepley 
229c0ce001eSMatthew G. Knepley   Input Parameter:
230c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to destroy
231c0ce001eSMatthew G. Knepley 
23288f5f89eSMatthew G. Knepley   Level: beginner
233c0ce001eSMatthew G. Knepley 
234db781477SPatrick Sanan .seealso: `PetscLimiterView()`
235c0ce001eSMatthew G. Knepley @*/
236c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterDestroy(PetscLimiter *lim)
237c0ce001eSMatthew G. Knepley {
238c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
239c0ce001eSMatthew G. Knepley   if (!*lim) PetscFunctionReturn(0);
240c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific((*lim), PETSCLIMITER_CLASSID, 1);
241c0ce001eSMatthew G. Knepley 
242ea78f98cSLisandro Dalcin   if (--((PetscObject)(*lim))->refct > 0) {*lim = NULL; PetscFunctionReturn(0);}
243c0ce001eSMatthew G. Knepley   ((PetscObject) (*lim))->refct = 0;
244c0ce001eSMatthew G. Knepley 
2459566063dSJacob Faibussowitsch   if ((*lim)->ops->destroy) PetscCall((*(*lim)->ops->destroy)(*lim));
2469566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(lim));
247c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
248c0ce001eSMatthew G. Knepley }
249c0ce001eSMatthew G. Knepley 
250c0ce001eSMatthew G. Knepley /*@
251c0ce001eSMatthew G. Knepley   PetscLimiterCreate - Creates an empty PetscLimiter object. The type can then be set with PetscLimiterSetType().
252c0ce001eSMatthew G. Knepley 
253c0ce001eSMatthew G. Knepley   Collective
254c0ce001eSMatthew G. Knepley 
255c0ce001eSMatthew G. Knepley   Input Parameter:
256c0ce001eSMatthew G. Knepley . comm - The communicator for the PetscLimiter object
257c0ce001eSMatthew G. Knepley 
258c0ce001eSMatthew G. Knepley   Output Parameter:
259c0ce001eSMatthew G. Knepley . lim - The PetscLimiter object
260c0ce001eSMatthew G. Knepley 
261c0ce001eSMatthew G. Knepley   Level: beginner
262c0ce001eSMatthew G. Knepley 
263db781477SPatrick Sanan .seealso: `PetscLimiterSetType()`, `PETSCLIMITERSIN`
264c0ce001eSMatthew G. Knepley @*/
265c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterCreate(MPI_Comm comm, PetscLimiter *lim)
266c0ce001eSMatthew G. Knepley {
267c0ce001eSMatthew G. Knepley   PetscLimiter   l;
268c0ce001eSMatthew G. Knepley 
269c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
270c0ce001eSMatthew G. Knepley   PetscValidPointer(lim, 2);
2719566063dSJacob Faibussowitsch   PetscCall(PetscCitationsRegister(LimiterCitation,&Limitercite));
272c0ce001eSMatthew G. Knepley   *lim = NULL;
2739566063dSJacob Faibussowitsch   PetscCall(PetscFVInitializePackage());
274c0ce001eSMatthew G. Knepley 
2759566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(l, PETSCLIMITER_CLASSID, "PetscLimiter", "Finite Volume Slope Limiter", "PetscLimiter", comm, PetscLimiterDestroy, PetscLimiterView));
276c0ce001eSMatthew G. Knepley 
277c0ce001eSMatthew G. Knepley   *lim = l;
278c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
279c0ce001eSMatthew G. Knepley }
280c0ce001eSMatthew G. Knepley 
28188f5f89eSMatthew G. Knepley /*@
28288f5f89eSMatthew G. Knepley   PetscLimiterLimit - Limit the flux
28388f5f89eSMatthew G. Knepley 
28488f5f89eSMatthew G. Knepley   Input Parameters:
28588f5f89eSMatthew G. Knepley + lim  - The PetscLimiter
28688f5f89eSMatthew G. Knepley - flim - The input field
28788f5f89eSMatthew G. Knepley 
28888f5f89eSMatthew G. Knepley   Output Parameter:
28988f5f89eSMatthew G. Knepley . phi  - The limited field
29088f5f89eSMatthew G. Knepley 
29188f5f89eSMatthew G. Knepley Note: Limiters given in symmetric form following Berger, Aftosmis, and Murman 2005
29288f5f89eSMatthew G. Knepley $ The classical flux-limited formulation is psi(r) where
29388f5f89eSMatthew G. Knepley $
29488f5f89eSMatthew G. Knepley $ r = (u[0] - u[-1]) / (u[1] - u[0])
29588f5f89eSMatthew G. Knepley $
29688f5f89eSMatthew G. Knepley $ The second order TVD region is bounded by
29788f5f89eSMatthew G. Knepley $
29888f5f89eSMatthew G. Knepley $ psi_minmod(r) = min(r,1)      and        psi_superbee(r) = min(2, 2r, max(1,r))
29988f5f89eSMatthew G. Knepley $
30088f5f89eSMatthew G. Knepley $ where all limiters are implicitly clipped to be non-negative. A more convenient slope-limited form is psi(r) =
30188f5f89eSMatthew G. Knepley $ phi(r)(r+1)/2 in which the reconstructed interface values are
30288f5f89eSMatthew G. Knepley $
30388f5f89eSMatthew G. Knepley $ u(v) = u[0] + phi(r) (grad u)[0] v
30488f5f89eSMatthew G. Knepley $
30588f5f89eSMatthew G. Knepley $ where v is the vector from centroid to quadrature point. In these variables, the usual limiters become
30688f5f89eSMatthew G. Knepley $
30788f5f89eSMatthew 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))
30888f5f89eSMatthew G. Knepley $
30988f5f89eSMatthew G. Knepley $ For a nicer symmetric formulation, rewrite in terms of
31088f5f89eSMatthew G. Knepley $
31188f5f89eSMatthew G. Knepley $ f = (u[0] - u[-1]) / (u[1] - u[-1])
31288f5f89eSMatthew G. Knepley $
31388f5f89eSMatthew G. Knepley $ where r(f) = f/(1-f). Not that r(1-f) = (1-f)/f = 1/r(f) so the symmetry condition
31488f5f89eSMatthew G. Knepley $
31588f5f89eSMatthew G. Knepley $ phi(r) = phi(1/r)
31688f5f89eSMatthew G. Knepley $
31788f5f89eSMatthew G. Knepley $ becomes
31888f5f89eSMatthew G. Knepley $
31988f5f89eSMatthew G. Knepley $ w(f) = w(1-f).
32088f5f89eSMatthew G. Knepley $
32188f5f89eSMatthew G. Knepley $ The limiters below implement this final form w(f). The reference methods are
32288f5f89eSMatthew G. Knepley $
32388f5f89eSMatthew G. Knepley $ w_minmod(f) = 2 min(f,(1-f))             w_superbee(r) = 4 min((1-f), f)
32488f5f89eSMatthew G. Knepley 
32588f5f89eSMatthew G. Knepley   Level: beginner
32688f5f89eSMatthew G. Knepley 
327db781477SPatrick Sanan .seealso: `PetscLimiterSetType()`, `PetscLimiterCreate()`
32888f5f89eSMatthew G. Knepley @*/
329c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterLimit(PetscLimiter lim, PetscReal flim, PetscReal *phi)
330c0ce001eSMatthew G. Knepley {
331c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
332c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
333dadcf809SJacob Faibussowitsch   PetscValidRealPointer(phi, 3);
3349566063dSJacob Faibussowitsch   PetscCall((*lim->ops->limit)(lim, flim, phi));
335c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
336c0ce001eSMatthew G. Knepley }
337c0ce001eSMatthew G. Knepley 
33888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Sin(PetscLimiter lim)
339c0ce001eSMatthew G. Knepley {
340c0ce001eSMatthew G. Knepley   PetscLimiter_Sin *l = (PetscLimiter_Sin *) lim->data;
341c0ce001eSMatthew G. Knepley 
342c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
3439566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
344c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
345c0ce001eSMatthew G. Knepley }
346c0ce001eSMatthew G. Knepley 
34788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Sin_Ascii(PetscLimiter lim, PetscViewer viewer)
348c0ce001eSMatthew G. Knepley {
349c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
350c0ce001eSMatthew G. Knepley 
351c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
3529566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
3539566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Sin Slope Limiter:\n"));
354c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
355c0ce001eSMatthew G. Knepley }
356c0ce001eSMatthew G. Knepley 
35788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Sin(PetscLimiter lim, PetscViewer viewer)
358c0ce001eSMatthew G. Knepley {
359c0ce001eSMatthew G. Knepley   PetscBool      iascii;
360c0ce001eSMatthew G. Knepley 
361c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
362c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
363c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
3649566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
3659566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_Sin_Ascii(lim, viewer));
366c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
367c0ce001eSMatthew G. Knepley }
368c0ce001eSMatthew G. Knepley 
36988f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Sin(PetscLimiter lim, PetscReal f, PetscReal *phi)
370c0ce001eSMatthew G. Knepley {
371c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
372c0ce001eSMatthew G. Knepley   *phi = PetscSinReal(PETSC_PI*PetscMax(0, PetscMin(f, 1)));
373c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
374c0ce001eSMatthew G. Knepley }
375c0ce001eSMatthew G. Knepley 
37688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Sin(PetscLimiter lim)
377c0ce001eSMatthew G. Knepley {
378c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
379c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Sin;
380c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Sin;
381c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Sin;
382c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
383c0ce001eSMatthew G. Knepley }
384c0ce001eSMatthew G. Knepley 
385c0ce001eSMatthew G. Knepley /*MC
386c0ce001eSMatthew G. Knepley   PETSCLIMITERSIN = "sin" - A PetscLimiter object
387c0ce001eSMatthew G. Knepley 
388c0ce001eSMatthew G. Knepley   Level: intermediate
389c0ce001eSMatthew G. Knepley 
390db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
391c0ce001eSMatthew G. Knepley M*/
392c0ce001eSMatthew G. Knepley 
393c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Sin(PetscLimiter lim)
394c0ce001eSMatthew G. Knepley {
395c0ce001eSMatthew G. Knepley   PetscLimiter_Sin *l;
396c0ce001eSMatthew G. Knepley 
397c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
398c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
3999566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(lim, &l));
400c0ce001eSMatthew G. Knepley   lim->data = l;
401c0ce001eSMatthew G. Knepley 
4029566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_Sin(lim));
403c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
404c0ce001eSMatthew G. Knepley }
405c0ce001eSMatthew G. Knepley 
40688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Zero(PetscLimiter lim)
407c0ce001eSMatthew G. Knepley {
408c0ce001eSMatthew G. Knepley   PetscLimiter_Zero *l = (PetscLimiter_Zero *) lim->data;
409c0ce001eSMatthew G. Knepley 
410c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
4119566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
412c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
413c0ce001eSMatthew G. Knepley }
414c0ce001eSMatthew G. Knepley 
41588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Zero_Ascii(PetscLimiter lim, PetscViewer viewer)
416c0ce001eSMatthew G. Knepley {
417c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
418c0ce001eSMatthew G. Knepley 
419c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
4209566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
4219566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Zero Slope Limiter:\n"));
422c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
423c0ce001eSMatthew G. Knepley }
424c0ce001eSMatthew G. Knepley 
42588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Zero(PetscLimiter lim, PetscViewer viewer)
426c0ce001eSMatthew G. Knepley {
427c0ce001eSMatthew G. Knepley   PetscBool      iascii;
428c0ce001eSMatthew G. Knepley 
429c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
430c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
431c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
4329566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
4339566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_Zero_Ascii(lim, viewer));
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 
458db781477SPatrick Sanan .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 
465c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
466c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
4679566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(lim, &l));
468c0ce001eSMatthew G. Knepley   lim->data = l;
469c0ce001eSMatthew G. Knepley 
4709566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_Zero(lim));
471c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
472c0ce001eSMatthew G. Knepley }
473c0ce001eSMatthew G. Knepley 
47488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_None(PetscLimiter lim)
475c0ce001eSMatthew G. Knepley {
476c0ce001eSMatthew G. Knepley   PetscLimiter_None *l = (PetscLimiter_None *) lim->data;
477c0ce001eSMatthew G. Knepley 
478c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
4799566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
480c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
481c0ce001eSMatthew G. Knepley }
482c0ce001eSMatthew G. Knepley 
48388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_None_Ascii(PetscLimiter lim, PetscViewer viewer)
484c0ce001eSMatthew G. Knepley {
485c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
486c0ce001eSMatthew G. Knepley 
487c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
4889566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
4899566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "None Slope Limiter:\n"));
490c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
491c0ce001eSMatthew G. Knepley }
492c0ce001eSMatthew G. Knepley 
49388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_None(PetscLimiter lim, PetscViewer viewer)
494c0ce001eSMatthew G. Knepley {
495c0ce001eSMatthew G. Knepley   PetscBool      iascii;
496c0ce001eSMatthew G. Knepley 
497c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
498c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
499c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
5009566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
5019566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_None_Ascii(lim, viewer));
502c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
503c0ce001eSMatthew G. Knepley }
504c0ce001eSMatthew G. Knepley 
50588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_None(PetscLimiter lim, PetscReal f, PetscReal *phi)
506c0ce001eSMatthew G. Knepley {
507c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
508c0ce001eSMatthew G. Knepley   *phi = 1.0;
509c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
510c0ce001eSMatthew G. Knepley }
511c0ce001eSMatthew G. Knepley 
51288f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_None(PetscLimiter lim)
513c0ce001eSMatthew G. Knepley {
514c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
515c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_None;
516c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_None;
517c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_None;
518c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
519c0ce001eSMatthew G. Knepley }
520c0ce001eSMatthew G. Knepley 
521c0ce001eSMatthew G. Knepley /*MC
522c0ce001eSMatthew G. Knepley   PETSCLIMITERNONE = "none" - A PetscLimiter object
523c0ce001eSMatthew G. Knepley 
524c0ce001eSMatthew G. Knepley   Level: intermediate
525c0ce001eSMatthew G. Knepley 
526db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
527c0ce001eSMatthew G. Knepley M*/
528c0ce001eSMatthew G. Knepley 
529c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_None(PetscLimiter lim)
530c0ce001eSMatthew G. Knepley {
531c0ce001eSMatthew G. Knepley   PetscLimiter_None *l;
532c0ce001eSMatthew G. Knepley 
533c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
534c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
5359566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(lim, &l));
536c0ce001eSMatthew G. Knepley   lim->data = l;
537c0ce001eSMatthew G. Knepley 
5389566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_None(lim));
539c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
540c0ce001eSMatthew G. Knepley }
541c0ce001eSMatthew G. Knepley 
54288f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Minmod(PetscLimiter lim)
543c0ce001eSMatthew G. Knepley {
544c0ce001eSMatthew G. Knepley   PetscLimiter_Minmod *l = (PetscLimiter_Minmod *) lim->data;
545c0ce001eSMatthew G. Knepley 
546c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
5479566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
548c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
549c0ce001eSMatthew G. Knepley }
550c0ce001eSMatthew G. Knepley 
55188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Minmod_Ascii(PetscLimiter lim, PetscViewer viewer)
552c0ce001eSMatthew G. Knepley {
553c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
554c0ce001eSMatthew G. Knepley 
555c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
5569566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
5579566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Minmod Slope Limiter:\n"));
558c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
559c0ce001eSMatthew G. Knepley }
560c0ce001eSMatthew G. Knepley 
56188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Minmod(PetscLimiter lim, PetscViewer viewer)
562c0ce001eSMatthew G. Knepley {
563c0ce001eSMatthew G. Knepley   PetscBool      iascii;
564c0ce001eSMatthew G. Knepley 
565c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
566c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
567c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
5689566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
5699566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_Minmod_Ascii(lim, viewer));
570c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
571c0ce001eSMatthew G. Knepley }
572c0ce001eSMatthew G. Knepley 
57388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Minmod(PetscLimiter lim, PetscReal f, PetscReal *phi)
574c0ce001eSMatthew G. Knepley {
575c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
576c0ce001eSMatthew G. Knepley   *phi = 2*PetscMax(0, PetscMin(f, 1-f));
577c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
578c0ce001eSMatthew G. Knepley }
579c0ce001eSMatthew G. Knepley 
58088f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Minmod(PetscLimiter lim)
581c0ce001eSMatthew G. Knepley {
582c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
583c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Minmod;
584c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Minmod;
585c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Minmod;
586c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
587c0ce001eSMatthew G. Knepley }
588c0ce001eSMatthew G. Knepley 
589c0ce001eSMatthew G. Knepley /*MC
590c0ce001eSMatthew G. Knepley   PETSCLIMITERMINMOD = "minmod" - A PetscLimiter object
591c0ce001eSMatthew G. Knepley 
592c0ce001eSMatthew G. Knepley   Level: intermediate
593c0ce001eSMatthew G. Knepley 
594db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
595c0ce001eSMatthew G. Knepley M*/
596c0ce001eSMatthew G. Knepley 
597c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Minmod(PetscLimiter lim)
598c0ce001eSMatthew G. Knepley {
599c0ce001eSMatthew G. Knepley   PetscLimiter_Minmod *l;
600c0ce001eSMatthew G. Knepley 
601c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
602c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
6039566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(lim, &l));
604c0ce001eSMatthew G. Knepley   lim->data = l;
605c0ce001eSMatthew G. Knepley 
6069566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_Minmod(lim));
607c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
608c0ce001eSMatthew G. Knepley }
609c0ce001eSMatthew G. Knepley 
61088f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_VanLeer(PetscLimiter lim)
611c0ce001eSMatthew G. Knepley {
612c0ce001eSMatthew G. Knepley   PetscLimiter_VanLeer *l = (PetscLimiter_VanLeer *) lim->data;
613c0ce001eSMatthew G. Knepley 
614c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
6159566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
616c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
617c0ce001eSMatthew G. Knepley }
618c0ce001eSMatthew G. Knepley 
61988f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanLeer_Ascii(PetscLimiter lim, PetscViewer viewer)
620c0ce001eSMatthew G. Knepley {
621c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
622c0ce001eSMatthew G. Knepley 
623c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
6249566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
6259566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Van Leer Slope Limiter:\n"));
626c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
627c0ce001eSMatthew G. Knepley }
628c0ce001eSMatthew G. Knepley 
62988f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanLeer(PetscLimiter lim, PetscViewer viewer)
630c0ce001eSMatthew G. Knepley {
631c0ce001eSMatthew G. Knepley   PetscBool      iascii;
632c0ce001eSMatthew G. Knepley 
633c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
634c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
635c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
6369566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
6379566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_VanLeer_Ascii(lim, viewer));
638c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
639c0ce001eSMatthew G. Knepley }
640c0ce001eSMatthew G. Knepley 
64188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_VanLeer(PetscLimiter lim, PetscReal f, PetscReal *phi)
642c0ce001eSMatthew G. Knepley {
643c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
644c0ce001eSMatthew G. Knepley   *phi = PetscMax(0, 4*f*(1-f));
645c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
646c0ce001eSMatthew G. Knepley }
647c0ce001eSMatthew G. Knepley 
64888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_VanLeer(PetscLimiter lim)
649c0ce001eSMatthew G. Knepley {
650c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
651c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_VanLeer;
652c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_VanLeer;
653c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_VanLeer;
654c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
655c0ce001eSMatthew G. Knepley }
656c0ce001eSMatthew G. Knepley 
657c0ce001eSMatthew G. Knepley /*MC
658c0ce001eSMatthew G. Knepley   PETSCLIMITERVANLEER = "vanleer" - A PetscLimiter object
659c0ce001eSMatthew G. Knepley 
660c0ce001eSMatthew G. Knepley   Level: intermediate
661c0ce001eSMatthew G. Knepley 
662db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
663c0ce001eSMatthew G. Knepley M*/
664c0ce001eSMatthew G. Knepley 
665c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanLeer(PetscLimiter lim)
666c0ce001eSMatthew G. Knepley {
667c0ce001eSMatthew G. Knepley   PetscLimiter_VanLeer *l;
668c0ce001eSMatthew G. Knepley 
669c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
670c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
6719566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(lim, &l));
672c0ce001eSMatthew G. Knepley   lim->data = l;
673c0ce001eSMatthew G. Knepley 
6749566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_VanLeer(lim));
675c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
676c0ce001eSMatthew G. Knepley }
677c0ce001eSMatthew G. Knepley 
67888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_VanAlbada(PetscLimiter lim)
679c0ce001eSMatthew G. Knepley {
680c0ce001eSMatthew G. Knepley   PetscLimiter_VanAlbada *l = (PetscLimiter_VanAlbada *) lim->data;
681c0ce001eSMatthew G. Knepley 
682c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
6839566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
684c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
685c0ce001eSMatthew G. Knepley }
686c0ce001eSMatthew G. Knepley 
68788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanAlbada_Ascii(PetscLimiter lim, PetscViewer viewer)
688c0ce001eSMatthew G. Knepley {
689c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
690c0ce001eSMatthew G. Knepley 
691c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
6929566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
6939566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Van Albada Slope Limiter:\n"));
694c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
695c0ce001eSMatthew G. Knepley }
696c0ce001eSMatthew G. Knepley 
69788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanAlbada(PetscLimiter lim, PetscViewer viewer)
698c0ce001eSMatthew G. Knepley {
699c0ce001eSMatthew G. Knepley   PetscBool      iascii;
700c0ce001eSMatthew G. Knepley 
701c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
702c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
703c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
7049566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
7059566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_VanAlbada_Ascii(lim, viewer));
706c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
707c0ce001eSMatthew G. Knepley }
708c0ce001eSMatthew G. Knepley 
70988f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_VanAlbada(PetscLimiter lim, PetscReal f, PetscReal *phi)
710c0ce001eSMatthew G. Knepley {
711c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
712c0ce001eSMatthew G. Knepley   *phi = PetscMax(0, 2*f*(1-f) / (PetscSqr(f) + PetscSqr(1-f)));
713c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
714c0ce001eSMatthew G. Knepley }
715c0ce001eSMatthew G. Knepley 
71688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_VanAlbada(PetscLimiter lim)
717c0ce001eSMatthew G. Knepley {
718c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
719c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_VanAlbada;
720c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_VanAlbada;
721c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_VanAlbada;
722c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
723c0ce001eSMatthew G. Knepley }
724c0ce001eSMatthew G. Knepley 
725c0ce001eSMatthew G. Knepley /*MC
726c0ce001eSMatthew G. Knepley   PETSCLIMITERVANALBADA = "vanalbada" - A PetscLimiter object
727c0ce001eSMatthew G. Knepley 
728c0ce001eSMatthew G. Knepley   Level: intermediate
729c0ce001eSMatthew G. Knepley 
730db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
731c0ce001eSMatthew G. Knepley M*/
732c0ce001eSMatthew G. Knepley 
733c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanAlbada(PetscLimiter lim)
734c0ce001eSMatthew G. Knepley {
735c0ce001eSMatthew G. Knepley   PetscLimiter_VanAlbada *l;
736c0ce001eSMatthew G. Knepley 
737c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
738c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
7399566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(lim, &l));
740c0ce001eSMatthew G. Knepley   lim->data = l;
741c0ce001eSMatthew G. Knepley 
7429566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_VanAlbada(lim));
743c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
744c0ce001eSMatthew G. Knepley }
745c0ce001eSMatthew G. Knepley 
74688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Superbee(PetscLimiter lim)
747c0ce001eSMatthew G. Knepley {
748c0ce001eSMatthew G. Knepley   PetscLimiter_Superbee *l = (PetscLimiter_Superbee *) lim->data;
749c0ce001eSMatthew G. Knepley 
750c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
7519566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
752c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
753c0ce001eSMatthew G. Knepley }
754c0ce001eSMatthew G. Knepley 
75588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Superbee_Ascii(PetscLimiter lim, PetscViewer viewer)
756c0ce001eSMatthew G. Knepley {
757c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
758c0ce001eSMatthew G. Knepley 
759c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
7609566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
7619566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Superbee Slope Limiter:\n"));
762c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
763c0ce001eSMatthew G. Knepley }
764c0ce001eSMatthew G. Knepley 
76588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Superbee(PetscLimiter lim, PetscViewer viewer)
766c0ce001eSMatthew G. Knepley {
767c0ce001eSMatthew G. Knepley   PetscBool      iascii;
768c0ce001eSMatthew G. Knepley 
769c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
770c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
771c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
7729566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
7739566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_Superbee_Ascii(lim, viewer));
774c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
775c0ce001eSMatthew G. Knepley }
776c0ce001eSMatthew G. Knepley 
77788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Superbee(PetscLimiter lim, PetscReal f, PetscReal *phi)
778c0ce001eSMatthew G. Knepley {
779c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
780c0ce001eSMatthew G. Knepley   *phi = 4*PetscMax(0, PetscMin(f, 1-f));
781c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
782c0ce001eSMatthew G. Knepley }
783c0ce001eSMatthew G. Knepley 
78488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Superbee(PetscLimiter lim)
785c0ce001eSMatthew G. Knepley {
786c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
787c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Superbee;
788c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Superbee;
789c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Superbee;
790c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
791c0ce001eSMatthew G. Knepley }
792c0ce001eSMatthew G. Knepley 
793c0ce001eSMatthew G. Knepley /*MC
794c0ce001eSMatthew G. Knepley   PETSCLIMITERSUPERBEE = "superbee" - A PetscLimiter object
795c0ce001eSMatthew G. Knepley 
796c0ce001eSMatthew G. Knepley   Level: intermediate
797c0ce001eSMatthew G. Knepley 
798db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
799c0ce001eSMatthew G. Knepley M*/
800c0ce001eSMatthew G. Knepley 
801c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Superbee(PetscLimiter lim)
802c0ce001eSMatthew G. Knepley {
803c0ce001eSMatthew G. Knepley   PetscLimiter_Superbee *l;
804c0ce001eSMatthew G. Knepley 
805c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
806c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
8079566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(lim, &l));
808c0ce001eSMatthew G. Knepley   lim->data = l;
809c0ce001eSMatthew G. Knepley 
8109566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_Superbee(lim));
811c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
812c0ce001eSMatthew G. Knepley }
813c0ce001eSMatthew G. Knepley 
81488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_MC(PetscLimiter lim)
815c0ce001eSMatthew G. Knepley {
816c0ce001eSMatthew G. Knepley   PetscLimiter_MC *l = (PetscLimiter_MC *) lim->data;
817c0ce001eSMatthew G. Knepley 
818c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
8199566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
820c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
821c0ce001eSMatthew G. Knepley }
822c0ce001eSMatthew G. Knepley 
82388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_MC_Ascii(PetscLimiter lim, PetscViewer viewer)
824c0ce001eSMatthew G. Knepley {
825c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
826c0ce001eSMatthew G. Knepley 
827c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
8289566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
8299566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "MC Slope Limiter:\n"));
830c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
831c0ce001eSMatthew G. Knepley }
832c0ce001eSMatthew G. Knepley 
83388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_MC(PetscLimiter lim, PetscViewer viewer)
834c0ce001eSMatthew G. Knepley {
835c0ce001eSMatthew G. Knepley   PetscBool      iascii;
836c0ce001eSMatthew G. Knepley 
837c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
838c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
839c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
8409566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
8419566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_MC_Ascii(lim, viewer));
842c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
843c0ce001eSMatthew G. Knepley }
844c0ce001eSMatthew G. Knepley 
845c0ce001eSMatthew G. Knepley /* aka Barth-Jespersen */
84688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_MC(PetscLimiter lim, PetscReal f, PetscReal *phi)
847c0ce001eSMatthew G. Knepley {
848c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
849c0ce001eSMatthew G. Knepley   *phi = PetscMin(1, 4*PetscMax(0, PetscMin(f, 1-f)));
850c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
851c0ce001eSMatthew G. Knepley }
852c0ce001eSMatthew G. Knepley 
85388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_MC(PetscLimiter lim)
854c0ce001eSMatthew G. Knepley {
855c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
856c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_MC;
857c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_MC;
858c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_MC;
859c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
860c0ce001eSMatthew G. Knepley }
861c0ce001eSMatthew G. Knepley 
862c0ce001eSMatthew G. Knepley /*MC
863c0ce001eSMatthew G. Knepley   PETSCLIMITERMC = "mc" - A PetscLimiter object
864c0ce001eSMatthew G. Knepley 
865c0ce001eSMatthew G. Knepley   Level: intermediate
866c0ce001eSMatthew G. Knepley 
867db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
868c0ce001eSMatthew G. Knepley M*/
869c0ce001eSMatthew G. Knepley 
870c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_MC(PetscLimiter lim)
871c0ce001eSMatthew G. Knepley {
872c0ce001eSMatthew G. Knepley   PetscLimiter_MC *l;
873c0ce001eSMatthew G. Knepley 
874c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
875c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
8769566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(lim, &l));
877c0ce001eSMatthew G. Knepley   lim->data = l;
878c0ce001eSMatthew G. Knepley 
8799566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_MC(lim));
880c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
881c0ce001eSMatthew G. Knepley }
882c0ce001eSMatthew G. Knepley 
883c0ce001eSMatthew G. Knepley PetscClassId PETSCFV_CLASSID = 0;
884c0ce001eSMatthew G. Knepley 
885c0ce001eSMatthew G. Knepley PetscFunctionList PetscFVList              = NULL;
886c0ce001eSMatthew G. Knepley PetscBool         PetscFVRegisterAllCalled = PETSC_FALSE;
887c0ce001eSMatthew G. Knepley 
888c0ce001eSMatthew G. Knepley /*@C
889c0ce001eSMatthew G. Knepley   PetscFVRegister - Adds a new PetscFV implementation
890c0ce001eSMatthew G. Knepley 
891c0ce001eSMatthew G. Knepley   Not Collective
892c0ce001eSMatthew G. Knepley 
893c0ce001eSMatthew G. Knepley   Input Parameters:
894c0ce001eSMatthew G. Knepley + name        - The name of a new user-defined creation routine
895c0ce001eSMatthew G. Knepley - create_func - The creation routine itself
896c0ce001eSMatthew G. Knepley 
897c0ce001eSMatthew G. Knepley   Notes:
898c0ce001eSMatthew G. Knepley   PetscFVRegister() may be called multiple times to add several user-defined PetscFVs
899c0ce001eSMatthew G. Knepley 
900c0ce001eSMatthew G. Knepley   Sample usage:
901c0ce001eSMatthew G. Knepley .vb
902c0ce001eSMatthew G. Knepley     PetscFVRegister("my_fv", MyPetscFVCreate);
903c0ce001eSMatthew G. Knepley .ve
904c0ce001eSMatthew G. Knepley 
905c0ce001eSMatthew G. Knepley   Then, your PetscFV type can be chosen with the procedural interface via
906c0ce001eSMatthew G. Knepley .vb
907c0ce001eSMatthew G. Knepley     PetscFVCreate(MPI_Comm, PetscFV *);
908c0ce001eSMatthew G. Knepley     PetscFVSetType(PetscFV, "my_fv");
909c0ce001eSMatthew G. Knepley .ve
910c0ce001eSMatthew G. Knepley    or at runtime via the option
911c0ce001eSMatthew G. Knepley .vb
912c0ce001eSMatthew G. Knepley     -petscfv_type my_fv
913c0ce001eSMatthew G. Knepley .ve
914c0ce001eSMatthew G. Knepley 
915c0ce001eSMatthew G. Knepley   Level: advanced
916c0ce001eSMatthew G. Knepley 
917db781477SPatrick Sanan .seealso: `PetscFVRegisterAll()`, `PetscFVRegisterDestroy()`
918c0ce001eSMatthew G. Knepley 
919c0ce001eSMatthew G. Knepley @*/
920c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVRegister(const char sname[], PetscErrorCode (*function)(PetscFV))
921c0ce001eSMatthew G. Knepley {
922c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
9239566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscFVList, sname, function));
924c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
925c0ce001eSMatthew G. Knepley }
926c0ce001eSMatthew G. Knepley 
927c0ce001eSMatthew G. Knepley /*@C
928c0ce001eSMatthew G. Knepley   PetscFVSetType - Builds a particular PetscFV
929c0ce001eSMatthew G. Knepley 
930c0ce001eSMatthew G. Knepley   Collective on fvm
931c0ce001eSMatthew G. Knepley 
932c0ce001eSMatthew G. Knepley   Input Parameters:
933c0ce001eSMatthew G. Knepley + fvm  - The PetscFV object
934c0ce001eSMatthew G. Knepley - name - The kind of FVM space
935c0ce001eSMatthew G. Knepley 
936c0ce001eSMatthew G. Knepley   Options Database Key:
937c0ce001eSMatthew G. Knepley . -petscfv_type <type> - Sets the PetscFV type; use -help for a list of available types
938c0ce001eSMatthew G. Knepley 
939c0ce001eSMatthew G. Knepley   Level: intermediate
940c0ce001eSMatthew G. Knepley 
941db781477SPatrick Sanan .seealso: `PetscFVGetType()`, `PetscFVCreate()`
942c0ce001eSMatthew G. Knepley @*/
943c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetType(PetscFV fvm, PetscFVType name)
944c0ce001eSMatthew G. Knepley {
945c0ce001eSMatthew G. Knepley   PetscErrorCode (*r)(PetscFV);
946c0ce001eSMatthew G. Knepley   PetscBool      match;
947c0ce001eSMatthew G. Knepley 
948c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
949c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
9509566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) fvm, name, &match));
951c0ce001eSMatthew G. Knepley   if (match) PetscFunctionReturn(0);
952c0ce001eSMatthew G. Knepley 
9539566063dSJacob Faibussowitsch   PetscCall(PetscFVRegisterAll());
9549566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscFVList, name, &r));
95528b400f6SJacob Faibussowitsch   PetscCheck(r,PetscObjectComm((PetscObject) fvm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscFV type: %s", name);
956c0ce001eSMatthew G. Knepley 
957c0ce001eSMatthew G. Knepley   if (fvm->ops->destroy) {
9589566063dSJacob Faibussowitsch     PetscCall((*fvm->ops->destroy)(fvm));
959c0ce001eSMatthew G. Knepley     fvm->ops->destroy = NULL;
960c0ce001eSMatthew G. Knepley   }
9619566063dSJacob Faibussowitsch   PetscCall((*r)(fvm));
9629566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject) fvm, name));
963c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
964c0ce001eSMatthew G. Knepley }
965c0ce001eSMatthew G. Knepley 
966c0ce001eSMatthew G. Knepley /*@C
967c0ce001eSMatthew G. Knepley   PetscFVGetType - Gets the PetscFV type name (as a string) from the object.
968c0ce001eSMatthew G. Knepley 
969c0ce001eSMatthew G. Knepley   Not Collective
970c0ce001eSMatthew G. Knepley 
971c0ce001eSMatthew G. Knepley   Input Parameter:
972c0ce001eSMatthew G. Knepley . fvm  - The PetscFV
973c0ce001eSMatthew G. Knepley 
974c0ce001eSMatthew G. Knepley   Output Parameter:
975c0ce001eSMatthew G. Knepley . name - The PetscFV type name
976c0ce001eSMatthew G. Knepley 
977c0ce001eSMatthew G. Knepley   Level: intermediate
978c0ce001eSMatthew G. Knepley 
979db781477SPatrick Sanan .seealso: `PetscFVSetType()`, `PetscFVCreate()`
980c0ce001eSMatthew G. Knepley @*/
981c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetType(PetscFV fvm, PetscFVType *name)
982c0ce001eSMatthew G. Knepley {
983c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
984c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
985c0ce001eSMatthew G. Knepley   PetscValidPointer(name, 2);
9869566063dSJacob Faibussowitsch   PetscCall(PetscFVRegisterAll());
987c0ce001eSMatthew G. Knepley   *name = ((PetscObject) fvm)->type_name;
988c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
989c0ce001eSMatthew G. Knepley }
990c0ce001eSMatthew G. Knepley 
991c0ce001eSMatthew G. Knepley /*@C
992fe2efc57SMark    PetscFVViewFromOptions - View from Options
993fe2efc57SMark 
994fe2efc57SMark    Collective on PetscFV
995fe2efc57SMark 
996fe2efc57SMark    Input Parameters:
997fe2efc57SMark +  A - the PetscFV object
998736c3998SJose E. Roman .  obj - Optional object
999736c3998SJose E. Roman -  name - command line option
1000fe2efc57SMark 
1001fe2efc57SMark    Level: intermediate
1002db781477SPatrick Sanan .seealso: `PetscFV`, `PetscFVView`, `PetscObjectViewFromOptions()`, `PetscFVCreate()`
1003fe2efc57SMark @*/
1004fe2efc57SMark PetscErrorCode  PetscFVViewFromOptions(PetscFV A,PetscObject obj,const char name[])
1005fe2efc57SMark {
1006fe2efc57SMark   PetscFunctionBegin;
1007fe2efc57SMark   PetscValidHeaderSpecific(A,PETSCFV_CLASSID,1);
10089566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name));
1009fe2efc57SMark   PetscFunctionReturn(0);
1010fe2efc57SMark }
1011fe2efc57SMark 
1012fe2efc57SMark /*@C
1013c0ce001eSMatthew G. Knepley   PetscFVView - Views a PetscFV
1014c0ce001eSMatthew G. Knepley 
1015c0ce001eSMatthew G. Knepley   Collective on fvm
1016c0ce001eSMatthew G. Knepley 
1017d8d19677SJose E. Roman   Input Parameters:
1018c0ce001eSMatthew G. Knepley + fvm - the PetscFV object to view
1019c0ce001eSMatthew G. Knepley - v   - the viewer
1020c0ce001eSMatthew G. Knepley 
102188f5f89eSMatthew G. Knepley   Level: beginner
1022c0ce001eSMatthew G. Knepley 
1023db781477SPatrick Sanan .seealso: `PetscFVDestroy()`
1024c0ce001eSMatthew G. Knepley @*/
1025c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVView(PetscFV fvm, PetscViewer v)
1026c0ce001eSMatthew G. Knepley {
1027c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1028c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
10299566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) fvm), &v));
10309566063dSJacob Faibussowitsch   if (fvm->ops->view) PetscCall((*fvm->ops->view)(fvm, v));
1031c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1032c0ce001eSMatthew G. Knepley }
1033c0ce001eSMatthew G. Knepley 
1034c0ce001eSMatthew G. Knepley /*@
1035c0ce001eSMatthew G. Knepley   PetscFVSetFromOptions - sets parameters in a PetscFV from the options database
1036c0ce001eSMatthew G. Knepley 
1037c0ce001eSMatthew G. Knepley   Collective on fvm
1038c0ce001eSMatthew G. Knepley 
1039c0ce001eSMatthew G. Knepley   Input Parameter:
1040c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to set options for
1041c0ce001eSMatthew G. Knepley 
1042c0ce001eSMatthew G. Knepley   Options Database Key:
1043c0ce001eSMatthew G. Knepley . -petscfv_compute_gradients <bool> - Determines whether cell gradients are calculated
1044c0ce001eSMatthew G. Knepley 
104588f5f89eSMatthew G. Knepley   Level: intermediate
1046c0ce001eSMatthew G. Knepley 
1047db781477SPatrick Sanan .seealso: `PetscFVView()`
1048c0ce001eSMatthew G. Knepley @*/
1049c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetFromOptions(PetscFV fvm)
1050c0ce001eSMatthew G. Knepley {
1051c0ce001eSMatthew G. Knepley   const char    *defaultType;
1052c0ce001eSMatthew G. Knepley   char           name[256];
1053c0ce001eSMatthew G. Knepley   PetscBool      flg;
1054c0ce001eSMatthew G. Knepley 
1055c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1056c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1057c0ce001eSMatthew G. Knepley   if (!((PetscObject) fvm)->type_name) defaultType = PETSCFVUPWIND;
1058c0ce001eSMatthew G. Knepley   else                                 defaultType = ((PetscObject) fvm)->type_name;
10599566063dSJacob Faibussowitsch   PetscCall(PetscFVRegisterAll());
1060c0ce001eSMatthew G. Knepley 
1061d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject) fvm);
10629566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petscfv_type", "Finite volume discretization", "PetscFVSetType", PetscFVList, defaultType, name, 256, &flg));
1063c0ce001eSMatthew G. Knepley   if (flg) {
10649566063dSJacob Faibussowitsch     PetscCall(PetscFVSetType(fvm, name));
1065c0ce001eSMatthew G. Knepley   } else if (!((PetscObject) fvm)->type_name) {
10669566063dSJacob Faibussowitsch     PetscCall(PetscFVSetType(fvm, defaultType));
1067c0ce001eSMatthew G. Knepley 
1068c0ce001eSMatthew G. Knepley   }
10699566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-petscfv_compute_gradients", "Compute cell gradients", "PetscFVSetComputeGradients", fvm->computeGradients, &fvm->computeGradients, NULL));
10709566063dSJacob Faibussowitsch   if (fvm->ops->setfromoptions) PetscCall((*fvm->ops->setfromoptions)(fvm));
1071c0ce001eSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
10729566063dSJacob Faibussowitsch   PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) fvm));
10739566063dSJacob Faibussowitsch   PetscCall(PetscLimiterSetFromOptions(fvm->limiter));
1074d0609cedSBarry Smith   PetscOptionsEnd();
10759566063dSJacob Faibussowitsch   PetscCall(PetscFVViewFromOptions(fvm, NULL, "-petscfv_view"));
1076c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1077c0ce001eSMatthew G. Knepley }
1078c0ce001eSMatthew G. Knepley 
1079c0ce001eSMatthew G. Knepley /*@
1080c0ce001eSMatthew G. Knepley   PetscFVSetUp - Construct data structures for the PetscFV
1081c0ce001eSMatthew G. Knepley 
1082c0ce001eSMatthew G. Knepley   Collective on fvm
1083c0ce001eSMatthew G. Knepley 
1084c0ce001eSMatthew G. Knepley   Input Parameter:
1085c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to setup
1086c0ce001eSMatthew G. Knepley 
108788f5f89eSMatthew G. Knepley   Level: intermediate
1088c0ce001eSMatthew G. Knepley 
1089db781477SPatrick Sanan .seealso: `PetscFVView()`, `PetscFVDestroy()`
1090c0ce001eSMatthew G. Knepley @*/
1091c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetUp(PetscFV fvm)
1092c0ce001eSMatthew G. Knepley {
1093c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1094c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
10959566063dSJacob Faibussowitsch   PetscCall(PetscLimiterSetUp(fvm->limiter));
10969566063dSJacob Faibussowitsch   if (fvm->ops->setup) PetscCall((*fvm->ops->setup)(fvm));
1097c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1098c0ce001eSMatthew G. Knepley }
1099c0ce001eSMatthew G. Knepley 
1100c0ce001eSMatthew G. Knepley /*@
1101c0ce001eSMatthew G. Knepley   PetscFVDestroy - Destroys a PetscFV object
1102c0ce001eSMatthew G. Knepley 
1103c0ce001eSMatthew G. Knepley   Collective on fvm
1104c0ce001eSMatthew G. Knepley 
1105c0ce001eSMatthew G. Knepley   Input Parameter:
1106c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to destroy
1107c0ce001eSMatthew G. Knepley 
110888f5f89eSMatthew G. Knepley   Level: beginner
1109c0ce001eSMatthew G. Knepley 
1110db781477SPatrick Sanan .seealso: `PetscFVView()`
1111c0ce001eSMatthew G. Knepley @*/
1112c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVDestroy(PetscFV *fvm)
1113c0ce001eSMatthew G. Knepley {
1114c0ce001eSMatthew G. Knepley   PetscInt       i;
1115c0ce001eSMatthew G. Knepley 
1116c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1117c0ce001eSMatthew G. Knepley   if (!*fvm) PetscFunctionReturn(0);
1118c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific((*fvm), PETSCFV_CLASSID, 1);
1119c0ce001eSMatthew G. Knepley 
1120ea78f98cSLisandro Dalcin   if (--((PetscObject)(*fvm))->refct > 0) {*fvm = NULL; PetscFunctionReturn(0);}
1121c0ce001eSMatthew G. Knepley   ((PetscObject) (*fvm))->refct = 0;
1122c0ce001eSMatthew G. Knepley 
1123c0ce001eSMatthew G. Knepley   for (i = 0; i < (*fvm)->numComponents; i++) {
11249566063dSJacob Faibussowitsch     PetscCall(PetscFree((*fvm)->componentNames[i]));
1125c0ce001eSMatthew G. Knepley   }
11269566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fvm)->componentNames));
11279566063dSJacob Faibussowitsch   PetscCall(PetscLimiterDestroy(&(*fvm)->limiter));
11289566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceDestroy(&(*fvm)->dualSpace));
11299566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fvm)->fluxWork));
11309566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureDestroy(&(*fvm)->quadrature));
11319566063dSJacob Faibussowitsch   PetscCall(PetscTabulationDestroy(&(*fvm)->T));
1132c0ce001eSMatthew G. Knepley 
11339566063dSJacob Faibussowitsch   if ((*fvm)->ops->destroy) PetscCall((*(*fvm)->ops->destroy)(*fvm));
11349566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(fvm));
1135c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1136c0ce001eSMatthew G. Knepley }
1137c0ce001eSMatthew G. Knepley 
1138c0ce001eSMatthew G. Knepley /*@
1139c0ce001eSMatthew G. Knepley   PetscFVCreate - Creates an empty PetscFV object. The type can then be set with PetscFVSetType().
1140c0ce001eSMatthew G. Knepley 
1141c0ce001eSMatthew G. Knepley   Collective
1142c0ce001eSMatthew G. Knepley 
1143c0ce001eSMatthew G. Knepley   Input Parameter:
1144c0ce001eSMatthew G. Knepley . comm - The communicator for the PetscFV object
1145c0ce001eSMatthew G. Knepley 
1146c0ce001eSMatthew G. Knepley   Output Parameter:
1147c0ce001eSMatthew G. Knepley . fvm - The PetscFV object
1148c0ce001eSMatthew G. Knepley 
1149c0ce001eSMatthew G. Knepley   Level: beginner
1150c0ce001eSMatthew G. Knepley 
1151db781477SPatrick Sanan .seealso: `PetscFVSetType()`, `PETSCFVUPWIND`
1152c0ce001eSMatthew G. Knepley @*/
1153c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVCreate(MPI_Comm comm, PetscFV *fvm)
1154c0ce001eSMatthew G. Knepley {
1155c0ce001eSMatthew G. Knepley   PetscFV        f;
1156c0ce001eSMatthew G. Knepley 
1157c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1158c0ce001eSMatthew G. Knepley   PetscValidPointer(fvm, 2);
1159c0ce001eSMatthew G. Knepley   *fvm = NULL;
11609566063dSJacob Faibussowitsch   PetscCall(PetscFVInitializePackage());
1161c0ce001eSMatthew G. Knepley 
11629566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(f, PETSCFV_CLASSID, "PetscFV", "Finite Volume", "PetscFV", comm, PetscFVDestroy, PetscFVView));
11639566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(f->ops, sizeof(struct _PetscFVOps)));
1164c0ce001eSMatthew G. Knepley 
11659566063dSJacob Faibussowitsch   PetscCall(PetscLimiterCreate(comm, &f->limiter));
1166c0ce001eSMatthew G. Knepley   f->numComponents    = 1;
1167c0ce001eSMatthew G. Knepley   f->dim              = 0;
1168c0ce001eSMatthew G. Knepley   f->computeGradients = PETSC_FALSE;
1169c0ce001eSMatthew G. Knepley   f->fluxWork         = NULL;
11709566063dSJacob Faibussowitsch   PetscCall(PetscCalloc1(f->numComponents,&f->componentNames));
1171c0ce001eSMatthew G. Knepley 
1172c0ce001eSMatthew G. Knepley   *fvm = f;
1173c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1174c0ce001eSMatthew G. Knepley }
1175c0ce001eSMatthew G. Knepley 
1176c0ce001eSMatthew G. Knepley /*@
1177c0ce001eSMatthew G. Knepley   PetscFVSetLimiter - Set the limiter object
1178c0ce001eSMatthew G. Knepley 
1179c0ce001eSMatthew G. Knepley   Logically collective on fvm
1180c0ce001eSMatthew G. Knepley 
1181c0ce001eSMatthew G. Knepley   Input Parameters:
1182c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1183c0ce001eSMatthew G. Knepley - lim - The PetscLimiter
1184c0ce001eSMatthew G. Knepley 
118588f5f89eSMatthew G. Knepley   Level: intermediate
1186c0ce001eSMatthew G. Knepley 
1187db781477SPatrick Sanan .seealso: `PetscFVGetLimiter()`
1188c0ce001eSMatthew G. Knepley @*/
1189c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetLimiter(PetscFV fvm, PetscLimiter lim)
1190c0ce001eSMatthew G. Knepley {
1191c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1192c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1193c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 2);
11949566063dSJacob Faibussowitsch   PetscCall(PetscLimiterDestroy(&fvm->limiter));
11959566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject) lim));
1196c0ce001eSMatthew G. Knepley   fvm->limiter = lim;
1197c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1198c0ce001eSMatthew G. Knepley }
1199c0ce001eSMatthew G. Knepley 
1200c0ce001eSMatthew G. Knepley /*@
1201c0ce001eSMatthew G. Knepley   PetscFVGetLimiter - Get the limiter object
1202c0ce001eSMatthew G. Knepley 
1203c0ce001eSMatthew G. Knepley   Not collective
1204c0ce001eSMatthew G. Knepley 
1205c0ce001eSMatthew G. Knepley   Input Parameter:
1206c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1207c0ce001eSMatthew G. Knepley 
1208c0ce001eSMatthew G. Knepley   Output Parameter:
1209c0ce001eSMatthew G. Knepley . lim - The PetscLimiter
1210c0ce001eSMatthew G. Knepley 
121188f5f89eSMatthew G. Knepley   Level: intermediate
1212c0ce001eSMatthew G. Knepley 
1213db781477SPatrick Sanan .seealso: `PetscFVSetLimiter()`
1214c0ce001eSMatthew G. Knepley @*/
1215c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetLimiter(PetscFV fvm, PetscLimiter *lim)
1216c0ce001eSMatthew G. Knepley {
1217c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1218c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1219c0ce001eSMatthew G. Knepley   PetscValidPointer(lim, 2);
1220c0ce001eSMatthew G. Knepley   *lim = fvm->limiter;
1221c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1222c0ce001eSMatthew G. Knepley }
1223c0ce001eSMatthew G. Knepley 
1224c0ce001eSMatthew G. Knepley /*@
1225c0ce001eSMatthew G. Knepley   PetscFVSetNumComponents - Set the number of field components
1226c0ce001eSMatthew G. Knepley 
1227c0ce001eSMatthew G. Knepley   Logically collective on fvm
1228c0ce001eSMatthew G. Knepley 
1229c0ce001eSMatthew G. Knepley   Input Parameters:
1230c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1231c0ce001eSMatthew G. Knepley - comp - The number of components
1232c0ce001eSMatthew G. Knepley 
123388f5f89eSMatthew G. Knepley   Level: intermediate
1234c0ce001eSMatthew G. Knepley 
1235db781477SPatrick Sanan .seealso: `PetscFVGetNumComponents()`
1236c0ce001eSMatthew G. Knepley @*/
1237c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetNumComponents(PetscFV fvm, PetscInt comp)
1238c0ce001eSMatthew G. Knepley {
1239c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1240c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1241c0ce001eSMatthew G. Knepley   if (fvm->numComponents != comp) {
1242c0ce001eSMatthew G. Knepley     PetscInt i;
1243c0ce001eSMatthew G. Knepley 
1244c0ce001eSMatthew G. Knepley     for (i = 0; i < fvm->numComponents; i++) {
12459566063dSJacob Faibussowitsch       PetscCall(PetscFree(fvm->componentNames[i]));
1246c0ce001eSMatthew G. Knepley     }
12479566063dSJacob Faibussowitsch     PetscCall(PetscFree(fvm->componentNames));
12489566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(comp,&fvm->componentNames));
1249c0ce001eSMatthew G. Knepley   }
1250c0ce001eSMatthew G. Knepley   fvm->numComponents = comp;
12519566063dSJacob Faibussowitsch   PetscCall(PetscFree(fvm->fluxWork));
12529566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(comp, &fvm->fluxWork));
1253c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1254c0ce001eSMatthew G. Knepley }
1255c0ce001eSMatthew G. Knepley 
1256c0ce001eSMatthew G. Knepley /*@
1257c0ce001eSMatthew G. Knepley   PetscFVGetNumComponents - Get the number of field components
1258c0ce001eSMatthew G. Knepley 
1259c0ce001eSMatthew G. Knepley   Not collective
1260c0ce001eSMatthew G. Knepley 
1261c0ce001eSMatthew G. Knepley   Input Parameter:
1262c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1263c0ce001eSMatthew G. Knepley 
1264c0ce001eSMatthew G. Knepley   Output Parameter:
1265c0ce001eSMatthew G. Knepley , comp - The number of components
1266c0ce001eSMatthew G. Knepley 
126788f5f89eSMatthew G. Knepley   Level: intermediate
1268c0ce001eSMatthew G. Knepley 
1269db781477SPatrick Sanan .seealso: `PetscFVSetNumComponents()`
1270c0ce001eSMatthew G. Knepley @*/
1271c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetNumComponents(PetscFV fvm, PetscInt *comp)
1272c0ce001eSMatthew G. Knepley {
1273c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1274c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1275dadcf809SJacob Faibussowitsch   PetscValidIntPointer(comp, 2);
1276c0ce001eSMatthew G. Knepley   *comp = fvm->numComponents;
1277c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1278c0ce001eSMatthew G. Knepley }
1279c0ce001eSMatthew G. Knepley 
1280c0ce001eSMatthew G. Knepley /*@C
1281c0ce001eSMatthew G. Knepley   PetscFVSetComponentName - Set the name of a component (used in output and viewing)
1282c0ce001eSMatthew G. Knepley 
1283c0ce001eSMatthew G. Knepley   Logically collective on fvm
1284c0ce001eSMatthew G. Knepley   Input Parameters:
1285c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1286c0ce001eSMatthew G. Knepley . comp - the component number
1287c0ce001eSMatthew G. Knepley - name - the component name
1288c0ce001eSMatthew G. Knepley 
128988f5f89eSMatthew G. Knepley   Level: intermediate
1290c0ce001eSMatthew G. Knepley 
1291db781477SPatrick Sanan .seealso: `PetscFVGetComponentName()`
1292c0ce001eSMatthew G. Knepley @*/
1293c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetComponentName(PetscFV fvm, PetscInt comp, const char *name)
1294c0ce001eSMatthew G. Knepley {
1295c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
12969566063dSJacob Faibussowitsch   PetscCall(PetscFree(fvm->componentNames[comp]));
12979566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name,&fvm->componentNames[comp]));
1298c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1299c0ce001eSMatthew G. Knepley }
1300c0ce001eSMatthew G. Knepley 
1301c0ce001eSMatthew G. Knepley /*@C
1302c0ce001eSMatthew G. Knepley   PetscFVGetComponentName - Get the name of a component (used in output and viewing)
1303c0ce001eSMatthew G. Knepley 
1304c0ce001eSMatthew G. Knepley   Logically collective on fvm
1305c0ce001eSMatthew G. Knepley   Input Parameters:
1306c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1307c0ce001eSMatthew G. Knepley - comp - the component number
1308c0ce001eSMatthew G. Knepley 
1309c0ce001eSMatthew G. Knepley   Output Parameter:
1310c0ce001eSMatthew G. Knepley . name - the component name
1311c0ce001eSMatthew G. Knepley 
131288f5f89eSMatthew G. Knepley   Level: intermediate
1313c0ce001eSMatthew G. Knepley 
1314db781477SPatrick Sanan .seealso: `PetscFVSetComponentName()`
1315c0ce001eSMatthew G. Knepley @*/
1316c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetComponentName(PetscFV fvm, PetscInt comp, const char **name)
1317c0ce001eSMatthew G. Knepley {
1318c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1319c0ce001eSMatthew G. Knepley   *name = fvm->componentNames[comp];
1320c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1321c0ce001eSMatthew G. Knepley }
1322c0ce001eSMatthew G. Knepley 
1323c0ce001eSMatthew G. Knepley /*@
1324c0ce001eSMatthew G. Knepley   PetscFVSetSpatialDimension - Set the spatial dimension
1325c0ce001eSMatthew G. Knepley 
1326c0ce001eSMatthew G. Knepley   Logically collective on fvm
1327c0ce001eSMatthew G. Knepley 
1328c0ce001eSMatthew G. Knepley   Input Parameters:
1329c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1330c0ce001eSMatthew G. Knepley - dim - The spatial dimension
1331c0ce001eSMatthew G. Knepley 
133288f5f89eSMatthew G. Knepley   Level: intermediate
1333c0ce001eSMatthew G. Knepley 
1334db781477SPatrick Sanan .seealso: `PetscFVGetSpatialDimension()`
1335c0ce001eSMatthew G. Knepley @*/
1336c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetSpatialDimension(PetscFV fvm, PetscInt dim)
1337c0ce001eSMatthew G. Knepley {
1338c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1339c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1340c0ce001eSMatthew G. Knepley   fvm->dim = dim;
1341c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1342c0ce001eSMatthew G. Knepley }
1343c0ce001eSMatthew G. Knepley 
1344c0ce001eSMatthew G. Knepley /*@
1345c0ce001eSMatthew G. Knepley   PetscFVGetSpatialDimension - Get the spatial dimension
1346c0ce001eSMatthew G. Knepley 
1347c0ce001eSMatthew G. Knepley   Logically collective on fvm
1348c0ce001eSMatthew G. Knepley 
1349c0ce001eSMatthew G. Knepley   Input Parameter:
1350c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1351c0ce001eSMatthew G. Knepley 
1352c0ce001eSMatthew G. Knepley   Output Parameter:
1353c0ce001eSMatthew G. Knepley . dim - The spatial dimension
1354c0ce001eSMatthew G. Knepley 
135588f5f89eSMatthew G. Knepley   Level: intermediate
1356c0ce001eSMatthew G. Knepley 
1357db781477SPatrick Sanan .seealso: `PetscFVSetSpatialDimension()`
1358c0ce001eSMatthew G. Knepley @*/
1359c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetSpatialDimension(PetscFV fvm, PetscInt *dim)
1360c0ce001eSMatthew G. Knepley {
1361c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1362c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1363dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
1364c0ce001eSMatthew G. Knepley   *dim = fvm->dim;
1365c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1366c0ce001eSMatthew G. Knepley }
1367c0ce001eSMatthew G. Knepley 
1368c0ce001eSMatthew G. Knepley /*@
1369c0ce001eSMatthew G. Knepley   PetscFVSetComputeGradients - Toggle computation of cell gradients
1370c0ce001eSMatthew G. Knepley 
1371c0ce001eSMatthew G. Knepley   Logically collective on fvm
1372c0ce001eSMatthew G. Knepley 
1373c0ce001eSMatthew G. Knepley   Input Parameters:
1374c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1375c0ce001eSMatthew G. Knepley - computeGradients - Flag to compute cell gradients
1376c0ce001eSMatthew G. Knepley 
137788f5f89eSMatthew G. Knepley   Level: intermediate
1378c0ce001eSMatthew G. Knepley 
1379db781477SPatrick Sanan .seealso: `PetscFVGetComputeGradients()`
1380c0ce001eSMatthew G. Knepley @*/
1381c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetComputeGradients(PetscFV fvm, PetscBool computeGradients)
1382c0ce001eSMatthew G. Knepley {
1383c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1384c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1385c0ce001eSMatthew G. Knepley   fvm->computeGradients = computeGradients;
1386c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1387c0ce001eSMatthew G. Knepley }
1388c0ce001eSMatthew G. Knepley 
1389c0ce001eSMatthew G. Knepley /*@
1390c0ce001eSMatthew G. Knepley   PetscFVGetComputeGradients - Return flag for computation of cell gradients
1391c0ce001eSMatthew G. Knepley 
1392c0ce001eSMatthew G. Knepley   Not collective
1393c0ce001eSMatthew G. Knepley 
1394c0ce001eSMatthew G. Knepley   Input Parameter:
1395c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1396c0ce001eSMatthew G. Knepley 
1397c0ce001eSMatthew G. Knepley   Output Parameter:
1398c0ce001eSMatthew G. Knepley . computeGradients - Flag to compute cell gradients
1399c0ce001eSMatthew G. Knepley 
140088f5f89eSMatthew G. Knepley   Level: intermediate
1401c0ce001eSMatthew G. Knepley 
1402db781477SPatrick Sanan .seealso: `PetscFVSetComputeGradients()`
1403c0ce001eSMatthew G. Knepley @*/
1404c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetComputeGradients(PetscFV fvm, PetscBool *computeGradients)
1405c0ce001eSMatthew G. Knepley {
1406c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1407c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1408dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(computeGradients, 2);
1409c0ce001eSMatthew G. Knepley   *computeGradients = fvm->computeGradients;
1410c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1411c0ce001eSMatthew G. Knepley }
1412c0ce001eSMatthew G. Knepley 
1413c0ce001eSMatthew G. Knepley /*@
1414c0ce001eSMatthew G. Knepley   PetscFVSetQuadrature - Set the quadrature object
1415c0ce001eSMatthew G. Knepley 
1416c0ce001eSMatthew G. Knepley   Logically collective on fvm
1417c0ce001eSMatthew G. Knepley 
1418c0ce001eSMatthew G. Knepley   Input Parameters:
1419c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1420c0ce001eSMatthew G. Knepley - q - The PetscQuadrature
1421c0ce001eSMatthew G. Knepley 
142288f5f89eSMatthew G. Knepley   Level: intermediate
1423c0ce001eSMatthew G. Knepley 
1424db781477SPatrick Sanan .seealso: `PetscFVGetQuadrature()`
1425c0ce001eSMatthew G. Knepley @*/
1426c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetQuadrature(PetscFV fvm, PetscQuadrature q)
1427c0ce001eSMatthew G. Knepley {
1428c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1429c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
14309566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureDestroy(&fvm->quadrature));
14319566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject) q));
1432c0ce001eSMatthew G. Knepley   fvm->quadrature = q;
1433c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1434c0ce001eSMatthew G. Knepley }
1435c0ce001eSMatthew G. Knepley 
1436c0ce001eSMatthew G. Knepley /*@
1437c0ce001eSMatthew G. Knepley   PetscFVGetQuadrature - Get the quadrature object
1438c0ce001eSMatthew G. Knepley 
1439c0ce001eSMatthew G. Knepley   Not collective
1440c0ce001eSMatthew G. Knepley 
1441c0ce001eSMatthew G. Knepley   Input Parameter:
1442c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1443c0ce001eSMatthew G. Knepley 
1444c0ce001eSMatthew G. Knepley   Output Parameter:
1445c0ce001eSMatthew G. Knepley . lim - The PetscQuadrature
1446c0ce001eSMatthew G. Knepley 
144788f5f89eSMatthew G. Knepley   Level: intermediate
1448c0ce001eSMatthew G. Knepley 
1449db781477SPatrick Sanan .seealso: `PetscFVSetQuadrature()`
1450c0ce001eSMatthew G. Knepley @*/
1451c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetQuadrature(PetscFV fvm, PetscQuadrature *q)
1452c0ce001eSMatthew G. Knepley {
1453c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1454c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1455c0ce001eSMatthew G. Knepley   PetscValidPointer(q, 2);
1456c0ce001eSMatthew G. Knepley   if (!fvm->quadrature) {
1457c0ce001eSMatthew G. Knepley     /* Create default 1-point quadrature */
1458c0ce001eSMatthew G. Knepley     PetscReal     *points, *weights;
1459c0ce001eSMatthew G. Knepley 
14609566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &fvm->quadrature));
14619566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(fvm->dim, &points));
14629566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(1, &weights));
1463c0ce001eSMatthew G. Knepley     weights[0] = 1.0;
14649566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureSetData(fvm->quadrature, fvm->dim, 1, 1, points, weights));
1465c0ce001eSMatthew G. Knepley   }
1466c0ce001eSMatthew G. Knepley   *q = fvm->quadrature;
1467c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1468c0ce001eSMatthew G. Knepley }
1469c0ce001eSMatthew G. Knepley 
1470c0ce001eSMatthew G. Knepley /*@
1471c0ce001eSMatthew G. Knepley   PetscFVGetDualSpace - Returns the PetscDualSpace used to define the inner product
1472c0ce001eSMatthew G. Knepley 
1473c0ce001eSMatthew G. Knepley   Not collective
1474c0ce001eSMatthew G. Knepley 
1475c0ce001eSMatthew G. Knepley   Input Parameter:
1476c0ce001eSMatthew G. Knepley . fvm - The PetscFV object
1477c0ce001eSMatthew G. Knepley 
1478c0ce001eSMatthew G. Knepley   Output Parameter:
1479c0ce001eSMatthew G. Knepley . sp - The PetscDualSpace object
1480c0ce001eSMatthew G. Knepley 
1481c0ce001eSMatthew G. Knepley   Note: A simple dual space is provided automatically, and the user typically will not need to override it.
1482c0ce001eSMatthew G. Knepley 
148388f5f89eSMatthew G. Knepley   Level: intermediate
1484c0ce001eSMatthew G. Knepley 
1485db781477SPatrick Sanan .seealso: `PetscFVCreate()`
1486c0ce001eSMatthew G. Knepley @*/
1487c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetDualSpace(PetscFV fvm, PetscDualSpace *sp)
1488c0ce001eSMatthew G. Knepley {
1489c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1490c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1491c0ce001eSMatthew G. Knepley   PetscValidPointer(sp, 2);
1492c0ce001eSMatthew G. Knepley   if (!fvm->dualSpace) {
1493c0ce001eSMatthew G. Knepley     DM              K;
1494c0ce001eSMatthew G. Knepley     PetscInt        dim, Nc, c;
1495c0ce001eSMatthew G. Knepley 
14969566063dSJacob Faibussowitsch     PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
14979566063dSJacob Faibussowitsch     PetscCall(PetscFVGetNumComponents(fvm, &Nc));
14989566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceCreate(PetscObjectComm((PetscObject) fvm), &fvm->dualSpace));
14999566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSetType(fvm->dualSpace, PETSCDUALSPACESIMPLE));
15009566063dSJacob Faibussowitsch     PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, DMPolytopeTypeSimpleShape(dim, PETSC_FALSE), &K));
15019566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSetNumComponents(fvm->dualSpace, Nc));
15029566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSetDM(fvm->dualSpace, K));
15039566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&K));
15049566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSimpleSetDimension(fvm->dualSpace, Nc));
1505c0ce001eSMatthew G. Knepley     /* Should we be using PetscFVGetQuadrature() here? */
1506c0ce001eSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
1507c0ce001eSMatthew G. Knepley       PetscQuadrature qc;
1508c0ce001eSMatthew G. Knepley       PetscReal      *points, *weights;
1509c0ce001eSMatthew G. Knepley 
15109566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qc));
15119566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(dim, &points));
15129566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(Nc, &weights));
1513c0ce001eSMatthew G. Knepley       weights[c] = 1.0;
15149566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureSetData(qc, dim, Nc, 1, points, weights));
15159566063dSJacob Faibussowitsch       PetscCall(PetscDualSpaceSimpleSetFunctional(fvm->dualSpace, c, qc));
15169566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureDestroy(&qc));
1517c0ce001eSMatthew G. Knepley     }
15189566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSetUp(fvm->dualSpace));
1519c0ce001eSMatthew G. Knepley   }
1520c0ce001eSMatthew G. Knepley   *sp = fvm->dualSpace;
1521c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1522c0ce001eSMatthew G. Knepley }
1523c0ce001eSMatthew G. Knepley 
1524c0ce001eSMatthew G. Knepley /*@
1525c0ce001eSMatthew G. Knepley   PetscFVSetDualSpace - Sets the PetscDualSpace used to define the inner product
1526c0ce001eSMatthew G. Knepley 
1527c0ce001eSMatthew G. Knepley   Not collective
1528c0ce001eSMatthew G. Knepley 
1529c0ce001eSMatthew G. Knepley   Input Parameters:
1530c0ce001eSMatthew G. Knepley + fvm - The PetscFV object
1531c0ce001eSMatthew G. Knepley - sp  - The PetscDualSpace object
1532c0ce001eSMatthew G. Knepley 
1533c0ce001eSMatthew G. Knepley   Level: intermediate
1534c0ce001eSMatthew G. Knepley 
1535c0ce001eSMatthew G. Knepley   Note: A simple dual space is provided automatically, and the user typically will not need to override it.
1536c0ce001eSMatthew G. Knepley 
1537db781477SPatrick Sanan .seealso: `PetscFVCreate()`
1538c0ce001eSMatthew G. Knepley @*/
1539c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetDualSpace(PetscFV fvm, PetscDualSpace sp)
1540c0ce001eSMatthew G. Knepley {
1541c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1542c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1543c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 2);
15449566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceDestroy(&fvm->dualSpace));
1545c0ce001eSMatthew G. Knepley   fvm->dualSpace = sp;
15469566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject) fvm->dualSpace));
1547c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1548c0ce001eSMatthew G. Knepley }
1549c0ce001eSMatthew G. Knepley 
155088f5f89eSMatthew G. Knepley /*@C
1551ef0bb6c7SMatthew G. Knepley   PetscFVGetCellTabulation - Returns the tabulation of the basis functions at the quadrature points
155288f5f89eSMatthew G. Knepley 
155388f5f89eSMatthew G. Knepley   Not collective
155488f5f89eSMatthew G. Knepley 
155588f5f89eSMatthew G. Knepley   Input Parameter:
155688f5f89eSMatthew G. Knepley . fvm - The PetscFV object
155788f5f89eSMatthew G. Knepley 
1558ef0bb6c7SMatthew G. Knepley   Output Parameter:
1559a5b23f4aSJose E. Roman . T - The basis function values and derivatives at quadrature points
156088f5f89eSMatthew G. Knepley 
156188f5f89eSMatthew G. Knepley   Note:
1562ef0bb6c7SMatthew G. Knepley $ T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c
1563ef0bb6c7SMatthew G. Knepley $ T->T[1] = D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d
1564ef0bb6c7SMatthew G. Knepley $ T->T[2] = 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
156588f5f89eSMatthew G. Knepley 
156688f5f89eSMatthew G. Knepley   Level: intermediate
156788f5f89eSMatthew G. Knepley 
1568db781477SPatrick Sanan .seealso: `PetscFEGetCellTabulation()`, `PetscFVCreateTabulation()`, `PetscFVGetQuadrature()`, `PetscQuadratureGetData()`
156988f5f89eSMatthew G. Knepley @*/
1570ef0bb6c7SMatthew G. Knepley PetscErrorCode PetscFVGetCellTabulation(PetscFV fvm, PetscTabulation *T)
1571c0ce001eSMatthew G. Knepley {
1572c0ce001eSMatthew G. Knepley   PetscInt         npoints;
1573c0ce001eSMatthew G. Knepley   const PetscReal *points;
1574c0ce001eSMatthew G. Knepley 
1575c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1576c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1577ef0bb6c7SMatthew G. Knepley   PetscValidPointer(T, 2);
15789566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureGetData(fvm->quadrature, NULL, NULL, &npoints, &points, NULL));
15799566063dSJacob Faibussowitsch   if (!fvm->T) PetscCall(PetscFVCreateTabulation(fvm, 1, npoints, points, 1, &fvm->T));
1580ef0bb6c7SMatthew G. Knepley   *T = fvm->T;
1581c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1582c0ce001eSMatthew G. Knepley }
1583c0ce001eSMatthew G. Knepley 
158488f5f89eSMatthew G. Knepley /*@C
1585ef0bb6c7SMatthew G. Knepley   PetscFVCreateTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided.
158688f5f89eSMatthew G. Knepley 
158788f5f89eSMatthew G. Knepley   Not collective
158888f5f89eSMatthew G. Knepley 
158988f5f89eSMatthew G. Knepley   Input Parameters:
159088f5f89eSMatthew G. Knepley + fvm     - The PetscFV object
1591ef0bb6c7SMatthew G. Knepley . nrepl   - The number of replicas
1592ef0bb6c7SMatthew G. Knepley . npoints - The number of tabulation points in a replica
1593ef0bb6c7SMatthew G. Knepley . points  - The tabulation point coordinates
1594ef0bb6c7SMatthew G. Knepley - K       - The order of derivative to tabulate
159588f5f89eSMatthew G. Knepley 
1596ef0bb6c7SMatthew G. Knepley   Output Parameter:
1597a5b23f4aSJose E. Roman . T - The basis function values and derivative at tabulation points
159888f5f89eSMatthew G. Knepley 
159988f5f89eSMatthew G. Knepley   Note:
1600ef0bb6c7SMatthew G. Knepley $ T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c
1601ef0bb6c7SMatthew G. Knepley $ T->T[1] = D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d
1602ef0bb6c7SMatthew G. Knepley $ T->T[2] = 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
160388f5f89eSMatthew G. Knepley 
160488f5f89eSMatthew G. Knepley   Level: intermediate
160588f5f89eSMatthew G. Knepley 
1606db781477SPatrick Sanan .seealso: `PetscFECreateTabulation()`, `PetscTabulationDestroy()`, `PetscFEGetCellTabulation()`
160788f5f89eSMatthew G. Knepley @*/
1608ef0bb6c7SMatthew G. Knepley PetscErrorCode PetscFVCreateTabulation(PetscFV fvm, PetscInt nrepl, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation *T)
1609c0ce001eSMatthew G. Knepley {
1610c0ce001eSMatthew G. Knepley   PetscInt         pdim = 1; /* Dimension of approximation space P */
1611ef0bb6c7SMatthew G. Knepley   PetscInt         cdim;     /* Spatial dimension */
1612ef0bb6c7SMatthew G. Knepley   PetscInt         Nc;       /* Field components */
1613ef0bb6c7SMatthew G. Knepley   PetscInt         k, p, d, c, e;
1614c0ce001eSMatthew G. Knepley 
1615c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1616ef0bb6c7SMatthew G. Knepley   if (!npoints || K < 0) {
1617ef0bb6c7SMatthew G. Knepley     *T = NULL;
1618c0ce001eSMatthew G. Knepley     PetscFunctionReturn(0);
1619c0ce001eSMatthew G. Knepley   }
1620c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1621dadcf809SJacob Faibussowitsch   PetscValidRealPointer(points, 4);
162240a2aa30SMatthew G. Knepley   PetscValidPointer(T, 6);
16239566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &cdim));
16249566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fvm, &Nc));
16259566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(1, T));
1626ef0bb6c7SMatthew G. Knepley   (*T)->K    = !cdim ? 0 : K;
1627ef0bb6c7SMatthew G. Knepley   (*T)->Nr   = nrepl;
1628ef0bb6c7SMatthew G. Knepley   (*T)->Np   = npoints;
1629ef0bb6c7SMatthew G. Knepley   (*T)->Nb   = pdim;
1630ef0bb6c7SMatthew G. Knepley   (*T)->Nc   = Nc;
1631ef0bb6c7SMatthew G. Knepley   (*T)->cdim = cdim;
16329566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1((*T)->K+1, &(*T)->T));
1633ef0bb6c7SMatthew G. Knepley   for (k = 0; k <= (*T)->K; ++k) {
16349566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nrepl*npoints*pdim*Nc*PetscPowInt(cdim, k), &(*T)->T[k]));
1635ef0bb6c7SMatthew G. Knepley   }
1636ef0bb6c7SMatthew G. Knepley   if (K >= 0) {for (p = 0; p < nrepl*npoints; ++p) for (d = 0; d < pdim; ++d) for (c = 0; c < Nc; ++c) (*T)->T[0][(p*pdim + d)*Nc + c] = 1.0;}
1637ef0bb6c7SMatthew G. Knepley   if (K >= 1) {for (p = 0; p < nrepl*npoints; ++p) for (d = 0; d < pdim; ++d) for (c = 0; c < Nc; ++c) for (e = 0; e < cdim; ++e) (*T)->T[1][((p*pdim + d)*Nc + c)*cdim + e] = 0.0;}
1638ef0bb6c7SMatthew G. Knepley   if (K >= 2) {for (p = 0; p < nrepl*npoints; ++p) for (d = 0; d < pdim; ++d) for (c = 0; c < Nc; ++c) for (e = 0; e < cdim*cdim; ++e) (*T)->T[2][((p*pdim + d)*Nc + c)*cdim*cdim + e] = 0.0;}
1639c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1640c0ce001eSMatthew G. Knepley }
1641c0ce001eSMatthew G. Knepley 
1642c0ce001eSMatthew G. Knepley /*@C
1643c0ce001eSMatthew G. Knepley   PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell
1644c0ce001eSMatthew G. Knepley 
1645c0ce001eSMatthew G. Knepley   Input Parameters:
1646c0ce001eSMatthew G. Knepley + fvm      - The PetscFV object
1647c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained
1648c0ce001eSMatthew G. Knepley - dx       - The vector from the cell centroid to the neighboring cell centroid for each face
1649c0ce001eSMatthew G. Knepley 
165088f5f89eSMatthew G. Knepley   Level: advanced
1651c0ce001eSMatthew G. Knepley 
1652db781477SPatrick Sanan .seealso: `PetscFVCreate()`
1653c0ce001eSMatthew G. Knepley @*/
1654c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVComputeGradient(PetscFV fvm, PetscInt numFaces, PetscScalar dx[], PetscScalar grad[])
1655c0ce001eSMatthew G. Knepley {
1656c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1657c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
16589566063dSJacob Faibussowitsch   if (fvm->ops->computegradient) PetscCall((*fvm->ops->computegradient)(fvm, numFaces, dx, grad));
1659c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1660c0ce001eSMatthew G. Knepley }
1661c0ce001eSMatthew G. Knepley 
166288f5f89eSMatthew G. Knepley /*@C
1663c0ce001eSMatthew G. Knepley   PetscFVIntegrateRHSFunction - Produce the cell residual vector for a chunk of elements by quadrature integration
1664c0ce001eSMatthew G. Knepley 
1665c0ce001eSMatthew G. Knepley   Not collective
1666c0ce001eSMatthew G. Knepley 
1667c0ce001eSMatthew G. Knepley   Input Parameters:
1668c0ce001eSMatthew G. Knepley + fvm          - The PetscFV object for the field being integrated
1669c0ce001eSMatthew G. Knepley . prob         - The PetscDS specifing the discretizations and continuum functions
1670c0ce001eSMatthew G. Knepley . field        - The field being integrated
1671c0ce001eSMatthew G. Knepley . Nf           - The number of faces in the chunk
1672c0ce001eSMatthew G. Knepley . fgeom        - The face geometry for each face in the chunk
1673c0ce001eSMatthew G. Knepley . neighborVol  - The volume for each pair of cells in the chunk
1674c0ce001eSMatthew G. Knepley . uL           - The state from the cell on the left
1675c0ce001eSMatthew G. Knepley - uR           - The state from the cell on the right
1676c0ce001eSMatthew G. Knepley 
1677d8d19677SJose E. Roman   Output Parameters:
1678c0ce001eSMatthew G. Knepley + fluxL        - the left fluxes for each face
1679c0ce001eSMatthew G. Knepley - fluxR        - the right fluxes for each face
168088f5f89eSMatthew G. Knepley 
168188f5f89eSMatthew G. Knepley   Level: developer
168288f5f89eSMatthew G. Knepley 
1683db781477SPatrick Sanan .seealso: `PetscFVCreate()`
168488f5f89eSMatthew G. Knepley @*/
1685c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVIntegrateRHSFunction(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol,
1686c0ce001eSMatthew G. Knepley                                            PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[])
1687c0ce001eSMatthew G. Knepley {
1688c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1689c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
16909566063dSJacob Faibussowitsch   if (fvm->ops->integraterhsfunction) PetscCall((*fvm->ops->integraterhsfunction)(fvm, prob, field, Nf, fgeom, neighborVol, uL, uR, fluxL, fluxR));
1691c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1692c0ce001eSMatthew G. Knepley }
1693c0ce001eSMatthew G. Knepley 
1694c0ce001eSMatthew G. Knepley /*@
1695c0ce001eSMatthew G. Knepley   PetscFVRefine - Create a "refined" PetscFV object that refines the reference cell into smaller copies. This is typically used
1696c0ce001eSMatthew 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
1697c0ce001eSMatthew G. Knepley   sparsity). It is also used to create an interpolation between regularly refined meshes.
1698c0ce001eSMatthew G. Knepley 
1699c0ce001eSMatthew G. Knepley   Input Parameter:
1700c0ce001eSMatthew G. Knepley . fv - The initial PetscFV
1701c0ce001eSMatthew G. Knepley 
1702c0ce001eSMatthew G. Knepley   Output Parameter:
1703c0ce001eSMatthew G. Knepley . fvRef - The refined PetscFV
1704c0ce001eSMatthew G. Knepley 
170588f5f89eSMatthew G. Knepley   Level: advanced
1706c0ce001eSMatthew G. Knepley 
1707db781477SPatrick Sanan .seealso: `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()`
1708c0ce001eSMatthew G. Knepley @*/
1709c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVRefine(PetscFV fv, PetscFV *fvRef)
1710c0ce001eSMatthew G. Knepley {
1711c0ce001eSMatthew G. Knepley   PetscDualSpace    Q, Qref;
1712c0ce001eSMatthew G. Knepley   DM                K, Kref;
1713c0ce001eSMatthew G. Knepley   PetscQuadrature   q, qref;
1714412e9a14SMatthew G. Knepley   DMPolytopeType    ct;
1715012bc364SMatthew G. Knepley   DMPlexTransform   tr;
1716c0ce001eSMatthew G. Knepley   PetscReal        *v0;
1717c0ce001eSMatthew G. Knepley   PetscReal        *jac, *invjac;
1718c0ce001eSMatthew G. Knepley   PetscInt          numComp, numSubelements, s;
1719c0ce001eSMatthew G. Knepley 
1720c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
17219566063dSJacob Faibussowitsch   PetscCall(PetscFVGetDualSpace(fv, &Q));
17229566063dSJacob Faibussowitsch   PetscCall(PetscFVGetQuadrature(fv, &q));
17239566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceGetDM(Q, &K));
1724c0ce001eSMatthew G. Knepley   /* Create dual space */
17259566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceDuplicate(Q, &Qref));
17269566063dSJacob Faibussowitsch   PetscCall(DMRefine(K, PetscObjectComm((PetscObject) fv), &Kref));
17279566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceSetDM(Qref, Kref));
17289566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&Kref));
17299566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceSetUp(Qref));
1730c0ce001eSMatthew G. Knepley   /* Create volume */
17319566063dSJacob Faibussowitsch   PetscCall(PetscFVCreate(PetscObjectComm((PetscObject) fv), fvRef));
17329566063dSJacob Faibussowitsch   PetscCall(PetscFVSetDualSpace(*fvRef, Qref));
17339566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fv,    &numComp));
17349566063dSJacob Faibussowitsch   PetscCall(PetscFVSetNumComponents(*fvRef, numComp));
17359566063dSJacob Faibussowitsch   PetscCall(PetscFVSetUp(*fvRef));
1736c0ce001eSMatthew G. Knepley   /* Create quadrature */
17379566063dSJacob Faibussowitsch   PetscCall(DMPlexGetCellType(K, 0, &ct));
17389566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformCreate(PETSC_COMM_SELF, &tr));
17399566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR));
17409566063dSJacob Faibussowitsch   PetscCall(DMPlexRefineRegularGetAffineTransforms(tr, ct, &numSubelements, &v0, &jac, &invjac));
17419566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref));
17429566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceSimpleSetDimension(Qref, numSubelements));
1743c0ce001eSMatthew G. Knepley   for (s = 0; s < numSubelements; ++s) {
1744c0ce001eSMatthew G. Knepley     PetscQuadrature  qs;
1745c0ce001eSMatthew G. Knepley     const PetscReal *points, *weights;
1746c0ce001eSMatthew G. Knepley     PetscReal       *p, *w;
1747c0ce001eSMatthew G. Knepley     PetscInt         dim, Nc, npoints, np;
1748c0ce001eSMatthew G. Knepley 
17499566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qs));
17509566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureGetData(q, &dim, &Nc, &npoints, &points, &weights));
1751c0ce001eSMatthew G. Knepley     np   = npoints/numSubelements;
17529566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(np*dim,&p));
17539566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(np*Nc,&w));
17549566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(p, &points[s*np*dim], np*dim));
17559566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(w, &weights[s*np*Nc], np*Nc));
17569566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureSetData(qs, dim, Nc, np, p, w));
17579566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSimpleSetFunctional(Qref, s, qs));
17589566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureDestroy(&qs));
1759c0ce001eSMatthew G. Knepley   }
17609566063dSJacob Faibussowitsch   PetscCall(PetscFVSetQuadrature(*fvRef, qref));
17619566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformDestroy(&tr));
17629566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureDestroy(&qref));
17639566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceDestroy(&Qref));
1764c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1765c0ce001eSMatthew G. Knepley }
1766c0ce001eSMatthew G. Knepley 
176788f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVDestroy_Upwind(PetscFV fvm)
1768c0ce001eSMatthew G. Knepley {
1769c0ce001eSMatthew G. Knepley   PetscFV_Upwind *b = (PetscFV_Upwind *) fvm->data;
1770c0ce001eSMatthew G. Knepley 
1771c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
17729566063dSJacob Faibussowitsch   PetscCall(PetscFree(b));
1773c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1774c0ce001eSMatthew G. Knepley }
1775c0ce001eSMatthew G. Knepley 
177688f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_Upwind_Ascii(PetscFV fv, PetscViewer viewer)
1777c0ce001eSMatthew G. Knepley {
1778c0ce001eSMatthew G. Knepley   PetscInt          Nc, c;
1779c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
1780c0ce001eSMatthew G. Knepley 
1781c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
17829566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fv, &Nc));
17839566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
17849566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Upwind Finite Volume:\n"));
178563a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  num components: %" PetscInt_FMT "\n", Nc));
1786c0ce001eSMatthew G. Knepley   for (c = 0; c < Nc; c++) {
1787c0ce001eSMatthew G. Knepley     if (fv->componentNames[c]) {
178863a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "    component %" PetscInt_FMT ": %s\n", c, fv->componentNames[c]));
1789c0ce001eSMatthew G. Knepley     }
1790c0ce001eSMatthew G. Knepley   }
1791c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1792c0ce001eSMatthew G. Knepley }
1793c0ce001eSMatthew G. Knepley 
179488f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_Upwind(PetscFV fv, PetscViewer viewer)
1795c0ce001eSMatthew G. Knepley {
1796c0ce001eSMatthew G. Knepley   PetscBool      iascii;
1797c0ce001eSMatthew G. Knepley 
1798c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1799c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1);
1800c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
18019566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
18029566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscFVView_Upwind_Ascii(fv, viewer));
1803c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1804c0ce001eSMatthew G. Knepley }
1805c0ce001eSMatthew G. Knepley 
180688f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVSetUp_Upwind(PetscFV fvm)
1807c0ce001eSMatthew G. Knepley {
1808c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1809c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1810c0ce001eSMatthew G. Knepley }
1811c0ce001eSMatthew G. Knepley 
1812c0ce001eSMatthew G. Knepley /*
1813c0ce001eSMatthew G. Knepley   neighborVol[f*2+0] contains the left  geom
1814c0ce001eSMatthew G. Knepley   neighborVol[f*2+1] contains the right geom
1815c0ce001eSMatthew G. Knepley */
181688f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVIntegrateRHSFunction_Upwind(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol,
1817c0ce001eSMatthew G. Knepley                                                          PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[])
1818c0ce001eSMatthew G. Knepley {
1819c0ce001eSMatthew G. Knepley   void             (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *);
1820c0ce001eSMatthew G. Knepley   void              *rctx;
1821c0ce001eSMatthew G. Knepley   PetscScalar       *flux = fvm->fluxWork;
1822c0ce001eSMatthew G. Knepley   const PetscScalar *constants;
1823c0ce001eSMatthew G. Knepley   PetscInt           dim, numConstants, pdim, totDim, Nc, off, f, d;
1824c0ce001eSMatthew G. Knepley 
1825c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
18269566063dSJacob Faibussowitsch   PetscCall(PetscDSGetTotalComponents(prob, &Nc));
18279566063dSJacob Faibussowitsch   PetscCall(PetscDSGetTotalDimension(prob, &totDim));
18289566063dSJacob Faibussowitsch   PetscCall(PetscDSGetFieldOffset(prob, field, &off));
18299566063dSJacob Faibussowitsch   PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann));
18309566063dSJacob Faibussowitsch   PetscCall(PetscDSGetContext(prob, field, &rctx));
18319566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &numConstants, &constants));
18329566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
18339566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fvm, &pdim));
1834c0ce001eSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
1835c0ce001eSMatthew G. Knepley     (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f*Nc], &uR[f*Nc], numConstants, constants, flux, rctx);
1836c0ce001eSMatthew G. Knepley     for (d = 0; d < pdim; ++d) {
1837c0ce001eSMatthew G. Knepley       fluxL[f*totDim+off+d] = flux[d] / neighborVol[f*2+0];
1838c0ce001eSMatthew G. Knepley       fluxR[f*totDim+off+d] = flux[d] / neighborVol[f*2+1];
1839c0ce001eSMatthew G. Knepley     }
1840c0ce001eSMatthew G. Knepley   }
1841c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1842c0ce001eSMatthew G. Knepley }
1843c0ce001eSMatthew G. Knepley 
184488f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVInitialize_Upwind(PetscFV fvm)
1845c0ce001eSMatthew G. Knepley {
1846c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1847c0ce001eSMatthew G. Knepley   fvm->ops->setfromoptions          = NULL;
1848c0ce001eSMatthew G. Knepley   fvm->ops->setup                   = PetscFVSetUp_Upwind;
1849c0ce001eSMatthew G. Knepley   fvm->ops->view                    = PetscFVView_Upwind;
1850c0ce001eSMatthew G. Knepley   fvm->ops->destroy                 = PetscFVDestroy_Upwind;
1851c0ce001eSMatthew G. Knepley   fvm->ops->integraterhsfunction    = PetscFVIntegrateRHSFunction_Upwind;
1852c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1853c0ce001eSMatthew G. Knepley }
1854c0ce001eSMatthew G. Knepley 
1855c0ce001eSMatthew G. Knepley /*MC
1856c0ce001eSMatthew G. Knepley   PETSCFVUPWIND = "upwind" - A PetscFV object
1857c0ce001eSMatthew G. Knepley 
1858c0ce001eSMatthew G. Knepley   Level: intermediate
1859c0ce001eSMatthew G. Knepley 
1860db781477SPatrick Sanan .seealso: `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()`
1861c0ce001eSMatthew G. Knepley M*/
1862c0ce001eSMatthew G. Knepley 
1863c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscFVCreate_Upwind(PetscFV fvm)
1864c0ce001eSMatthew G. Knepley {
1865c0ce001eSMatthew G. Knepley   PetscFV_Upwind *b;
1866c0ce001eSMatthew G. Knepley 
1867c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1868c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
18699566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(fvm,&b));
1870c0ce001eSMatthew G. Knepley   fvm->data = b;
1871c0ce001eSMatthew G. Knepley 
18729566063dSJacob Faibussowitsch   PetscCall(PetscFVInitialize_Upwind(fvm));
1873c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1874c0ce001eSMatthew G. Knepley }
1875c0ce001eSMatthew G. Knepley 
1876c0ce001eSMatthew G. Knepley #include <petscblaslapack.h>
1877c0ce001eSMatthew G. Knepley 
187888f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVDestroy_LeastSquares(PetscFV fvm)
1879c0ce001eSMatthew G. Knepley {
1880c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *) fvm->data;
1881c0ce001eSMatthew G. Knepley 
1882c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
18839566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject) fvm, "PetscFVLeastSquaresSetMaxFaces_C", NULL));
18849566063dSJacob Faibussowitsch   PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work));
18859566063dSJacob Faibussowitsch   PetscCall(PetscFree(ls));
1886c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1887c0ce001eSMatthew G. Knepley }
1888c0ce001eSMatthew G. Knepley 
188988f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_LeastSquares_Ascii(PetscFV fv, PetscViewer viewer)
1890c0ce001eSMatthew G. Knepley {
1891c0ce001eSMatthew G. Knepley   PetscInt          Nc, c;
1892c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
1893c0ce001eSMatthew G. Knepley 
1894c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
18959566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fv, &Nc));
18969566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
18979566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Finite Volume with Least Squares Reconstruction:\n"));
189863a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  num components: %" PetscInt_FMT "\n", Nc));
1899c0ce001eSMatthew G. Knepley   for (c = 0; c < Nc; c++) {
1900c0ce001eSMatthew G. Knepley     if (fv->componentNames[c]) {
190163a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "    component %" PetscInt_FMT ": %s\n", c, fv->componentNames[c]));
1902c0ce001eSMatthew G. Knepley     }
1903c0ce001eSMatthew G. Knepley   }
1904c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1905c0ce001eSMatthew G. Knepley }
1906c0ce001eSMatthew G. Knepley 
190788f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_LeastSquares(PetscFV fv, PetscViewer viewer)
1908c0ce001eSMatthew G. Knepley {
1909c0ce001eSMatthew G. Knepley   PetscBool      iascii;
1910c0ce001eSMatthew G. Knepley 
1911c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1912c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1);
1913c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
19149566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
19159566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscFVView_LeastSquares_Ascii(fv, viewer));
1916c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1917c0ce001eSMatthew G. Knepley }
1918c0ce001eSMatthew G. Knepley 
191988f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVSetUp_LeastSquares(PetscFV fvm)
1920c0ce001eSMatthew G. Knepley {
1921c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1922c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1923c0ce001eSMatthew G. Knepley }
1924c0ce001eSMatthew G. Knepley 
1925c0ce001eSMatthew G. Knepley /* Overwrites A. Can only handle full-rank problems with m>=n */
1926c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresPseudoInverse_Static(PetscInt m,PetscInt mstride,PetscInt n,PetscScalar *A,PetscScalar *Ainv,PetscScalar *tau,PetscInt worksize,PetscScalar *work)
1927c0ce001eSMatthew G. Knepley {
1928c0ce001eSMatthew G. Knepley   PetscBool      debug = PETSC_FALSE;
1929c0ce001eSMatthew G. Knepley   PetscBLASInt   M,N,K,lda,ldb,ldwork,info;
1930c0ce001eSMatthew G. Knepley   PetscScalar    *R,*Q,*Aback,Alpha;
1931c0ce001eSMatthew G. Knepley 
1932c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1933c0ce001eSMatthew G. Knepley   if (debug) {
19349566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m*n,&Aback));
19359566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(Aback,A,m*n));
1936c0ce001eSMatthew G. Knepley   }
1937c0ce001eSMatthew G. Knepley 
19389566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m,&M));
19399566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n,&N));
19409566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(mstride,&lda));
19419566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(worksize,&ldwork));
19429566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
1943*792fecdfSBarry Smith   PetscCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&M,&N,A,&lda,tau,work,&ldwork,&info));
19449566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
194528b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"xGEQRF error");
1946c0ce001eSMatthew G. Knepley   R = A; /* Upper triangular part of A now contains R, the rest contains the elementary reflectors */
1947c0ce001eSMatthew G. Knepley 
1948c0ce001eSMatthew G. Knepley   /* Extract an explicit representation of Q */
1949c0ce001eSMatthew G. Knepley   Q    = Ainv;
19509566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(Q,A,mstride*n));
1951c0ce001eSMatthew G. Knepley   K    = N;                     /* full rank */
1952*792fecdfSBarry Smith   PetscCallBLAS("LAPACKorgqr",LAPACKorgqr_(&M,&N,&K,Q,&lda,tau,work,&ldwork,&info));
195328b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"xORGQR/xUNGQR error");
1954c0ce001eSMatthew G. Knepley 
1955c0ce001eSMatthew G. Knepley   /* Compute A^{-T} = (R^{-1} Q^T)^T = Q R^{-T} */
1956c0ce001eSMatthew G. Knepley   Alpha = 1.0;
1957c0ce001eSMatthew G. Knepley   ldb   = lda;
1958c0ce001eSMatthew G. Knepley   BLAStrsm_("Right","Upper","ConjugateTranspose","NotUnitTriangular",&M,&N,&Alpha,R,&lda,Q,&ldb);
1959c0ce001eSMatthew G. Knepley   /* Ainv is Q, overwritten with inverse */
1960c0ce001eSMatthew G. Knepley 
1961c0ce001eSMatthew G. Knepley   if (debug) {                      /* Check that pseudo-inverse worked */
1962c0ce001eSMatthew G. Knepley     PetscScalar  Beta = 0.0;
1963c0ce001eSMatthew G. Knepley     PetscBLASInt ldc;
1964c0ce001eSMatthew G. Knepley     K   = N;
1965c0ce001eSMatthew G. Knepley     ldc = N;
1966c0ce001eSMatthew G. Knepley     BLASgemm_("ConjugateTranspose","Normal",&N,&K,&M,&Alpha,Ainv,&lda,Aback,&ldb,&Beta,work,&ldc);
19679566063dSJacob Faibussowitsch     PetscCall(PetscScalarView(n*n,work,PETSC_VIEWER_STDOUT_SELF));
19689566063dSJacob Faibussowitsch     PetscCall(PetscFree(Aback));
1969c0ce001eSMatthew G. Knepley   }
1970c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1971c0ce001eSMatthew G. Knepley }
1972c0ce001eSMatthew G. Knepley 
1973c0ce001eSMatthew G. Knepley /* Overwrites A. Can handle degenerate problems and m<n. */
1974c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresPseudoInverseSVD_Static(PetscInt m,PetscInt mstride,PetscInt n,PetscScalar *A,PetscScalar *Ainv,PetscScalar *tau,PetscInt worksize,PetscScalar *work)
1975c0ce001eSMatthew G. Knepley {
1976c0ce001eSMatthew G. Knepley   PetscBool      debug = PETSC_FALSE;
1977c0ce001eSMatthew G. Knepley   PetscScalar   *Brhs, *Aback;
1978c0ce001eSMatthew G. Knepley   PetscScalar   *tmpwork;
1979c0ce001eSMatthew G. Knepley   PetscReal      rcond;
1980c0ce001eSMatthew G. Knepley #if defined (PETSC_USE_COMPLEX)
1981c0ce001eSMatthew G. Knepley   PetscInt       rworkSize;
1982c0ce001eSMatthew G. Knepley   PetscReal     *rwork;
1983c0ce001eSMatthew G. Knepley #endif
1984c0ce001eSMatthew G. Knepley   PetscInt       i, j, maxmn;
1985c0ce001eSMatthew G. Knepley   PetscBLASInt   M, N, lda, ldb, ldwork;
1986c0ce001eSMatthew G. Knepley   PetscBLASInt   nrhs, irank, info;
1987c0ce001eSMatthew G. Knepley 
1988c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1989c0ce001eSMatthew G. Knepley   if (debug) {
19909566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m*n,&Aback));
19919566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(Aback,A,m*n));
1992c0ce001eSMatthew G. Knepley   }
1993c0ce001eSMatthew G. Knepley 
1994c0ce001eSMatthew G. Knepley   /* initialize to identity */
1995736d4f42SpierreXVI   tmpwork = work;
1996736d4f42SpierreXVI   Brhs = Ainv;
1997c0ce001eSMatthew G. Knepley   maxmn = PetscMax(m,n);
1998c0ce001eSMatthew G. Knepley   for (j=0; j<maxmn; j++) {
1999c0ce001eSMatthew G. Knepley     for (i=0; i<maxmn; i++) Brhs[i + j*maxmn] = 1.0*(i == j);
2000c0ce001eSMatthew G. Knepley   }
2001c0ce001eSMatthew G. Knepley 
20029566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m,&M));
20039566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n,&N));
20049566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(mstride,&lda));
20059566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(maxmn,&ldb));
20069566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(worksize,&ldwork));
2007c0ce001eSMatthew G. Knepley   rcond = -1;
20089566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
2009c0ce001eSMatthew G. Knepley   nrhs  = M;
2010c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX)
2011c0ce001eSMatthew G. Knepley   rworkSize = 5 * PetscMin(M,N);
20129566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(rworkSize,&rwork));
2013*792fecdfSBarry Smith   PetscCallBLAS("LAPACKgelss",LAPACKgelss_(&M,&N,&nrhs,A,&lda,Brhs,&ldb, (PetscReal *) tau,&rcond,&irank,tmpwork,&ldwork,rwork,&info));
20149566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
20159566063dSJacob Faibussowitsch   PetscCall(PetscFree(rwork));
2016c0ce001eSMatthew G. Knepley #else
2017c0ce001eSMatthew G. Knepley   nrhs  = M;
2018*792fecdfSBarry Smith   PetscCallBLAS("LAPACKgelss",LAPACKgelss_(&M,&N,&nrhs,A,&lda,Brhs,&ldb, (PetscReal *) tau,&rcond,&irank,tmpwork,&ldwork,&info));
20199566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
2020c0ce001eSMatthew G. Knepley #endif
202128b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"xGELSS error");
2022c0ce001eSMatthew G. Knepley   /* The following check should be turned into a diagnostic as soon as someone wants to do this intentionally */
202308401ef6SPierre Jolivet   PetscCheck(irank >= PetscMin(M,N),PETSC_COMM_SELF,PETSC_ERR_USER,"Rank deficient least squares fit, indicates an isolated cell with two colinear points");
2024c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2025c0ce001eSMatthew G. Knepley }
2026c0ce001eSMatthew G. Knepley 
2027c0ce001eSMatthew G. Knepley #if 0
2028c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresDebugCell_Static(PetscFV fvm, PetscInt cell, DM dm, DM dmFace, PetscScalar *fgeom, DM dmCell, PetscScalar *cgeom)
2029c0ce001eSMatthew G. Knepley {
2030c0ce001eSMatthew G. Knepley   PetscReal       grad[2] = {0, 0};
2031c0ce001eSMatthew G. Knepley   const PetscInt *faces;
2032c0ce001eSMatthew G. Knepley   PetscInt        numFaces, f;
2033c0ce001eSMatthew G. Knepley 
2034c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
20359566063dSJacob Faibussowitsch   PetscCall(DMPlexGetConeSize(dm, cell, &numFaces));
20369566063dSJacob Faibussowitsch   PetscCall(DMPlexGetCone(dm, cell, &faces));
2037c0ce001eSMatthew G. Knepley   for (f = 0; f < numFaces; ++f) {
2038c0ce001eSMatthew G. Knepley     const PetscInt *fcells;
2039c0ce001eSMatthew G. Knepley     const CellGeom *cg1;
2040c0ce001eSMatthew G. Knepley     const FaceGeom *fg;
2041c0ce001eSMatthew G. Knepley 
20429566063dSJacob Faibussowitsch     PetscCall(DMPlexGetSupport(dm, faces[f], &fcells));
20439566063dSJacob Faibussowitsch     PetscCall(DMPlexPointLocalRead(dmFace, faces[f], fgeom, &fg));
2044c0ce001eSMatthew G. Knepley     for (i = 0; i < 2; ++i) {
2045c0ce001eSMatthew G. Knepley       PetscScalar du;
2046c0ce001eSMatthew G. Knepley 
2047c0ce001eSMatthew G. Knepley       if (fcells[i] == c) continue;
20489566063dSJacob Faibussowitsch       PetscCall(DMPlexPointLocalRead(dmCell, fcells[i], cgeom, &cg1));
2049c0ce001eSMatthew G. Knepley       du   = cg1->centroid[0] + 3*cg1->centroid[1] - (cg->centroid[0] + 3*cg->centroid[1]);
2050c0ce001eSMatthew G. Knepley       grad[0] += fg->grad[!i][0] * du;
2051c0ce001eSMatthew G. Knepley       grad[1] += fg->grad[!i][1] * du;
2052c0ce001eSMatthew G. Knepley     }
2053c0ce001eSMatthew G. Knepley   }
20549566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_SELF, "cell[%d] grad (%g, %g)\n", cell, grad[0], grad[1]));
2055c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2056c0ce001eSMatthew G. Knepley }
2057c0ce001eSMatthew G. Knepley #endif
2058c0ce001eSMatthew G. Knepley 
2059c0ce001eSMatthew G. Knepley /*
2060c0ce001eSMatthew G. Knepley   PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell
2061c0ce001eSMatthew G. Knepley 
2062c0ce001eSMatthew G. Knepley   Input Parameters:
2063c0ce001eSMatthew G. Knepley + fvm      - The PetscFV object
2064c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained
2065c0ce001eSMatthew G. Knepley . dx       - The vector from the cell centroid to the neighboring cell centroid for each face
2066c0ce001eSMatthew G. Knepley 
2067c0ce001eSMatthew G. Knepley   Level: developer
2068c0ce001eSMatthew G. Knepley 
2069db781477SPatrick Sanan .seealso: `PetscFVCreate()`
2070c0ce001eSMatthew G. Knepley */
207188f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVComputeGradient_LeastSquares(PetscFV fvm, PetscInt numFaces, const PetscScalar dx[], PetscScalar grad[])
2072c0ce001eSMatthew G. Knepley {
2073c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls       = (PetscFV_LeastSquares *) fvm->data;
2074c0ce001eSMatthew G. Knepley   const PetscBool       useSVD   = PETSC_TRUE;
2075c0ce001eSMatthew G. Knepley   const PetscInt        maxFaces = ls->maxFaces;
2076c0ce001eSMatthew G. Knepley   PetscInt              dim, f, d;
2077c0ce001eSMatthew G. Knepley 
2078c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2079c0ce001eSMatthew G. Knepley   if (numFaces > maxFaces) {
208008401ef6SPierre Jolivet     PetscCheck(maxFaces >= 0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Reconstruction has not been initialized, call PetscFVLeastSquaresSetMaxFaces()");
208163a3b9bcSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of input faces %" PetscInt_FMT " > %" PetscInt_FMT " maxfaces", numFaces, maxFaces);
2082c0ce001eSMatthew G. Knepley   }
20839566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
2084c0ce001eSMatthew G. Knepley   for (f = 0; f < numFaces; ++f) {
2085c0ce001eSMatthew G. Knepley     for (d = 0; d < dim; ++d) ls->B[d*maxFaces+f] = dx[f*dim+d];
2086c0ce001eSMatthew G. Knepley   }
2087c0ce001eSMatthew G. Knepley   /* Overwrites B with garbage, returns Binv in row-major format */
2088736d4f42SpierreXVI   if (useSVD) {
2089736d4f42SpierreXVI     PetscInt maxmn = PetscMax(numFaces, dim);
20909566063dSJacob Faibussowitsch     PetscCall(PetscFVLeastSquaresPseudoInverseSVD_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work));
2091736d4f42SpierreXVI     /* Binv shaped in column-major, coldim=maxmn.*/
2092736d4f42SpierreXVI     for (f = 0; f < numFaces; ++f) {
2093736d4f42SpierreXVI       for (d = 0; d < dim; ++d) grad[f*dim+d] = ls->Binv[d + maxmn*f];
2094736d4f42SpierreXVI     }
2095736d4f42SpierreXVI   } else {
20969566063dSJacob Faibussowitsch     PetscCall(PetscFVLeastSquaresPseudoInverse_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work));
2097736d4f42SpierreXVI     /* Binv shaped in row-major, rowdim=maxFaces.*/
2098c0ce001eSMatthew G. Knepley     for (f = 0; f < numFaces; ++f) {
2099c0ce001eSMatthew G. Knepley       for (d = 0; d < dim; ++d) grad[f*dim+d] = ls->Binv[d*maxFaces + f];
2100c0ce001eSMatthew G. Knepley     }
2101736d4f42SpierreXVI   }
2102c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2103c0ce001eSMatthew G. Knepley }
2104c0ce001eSMatthew G. Knepley 
2105c0ce001eSMatthew G. Knepley /*
2106c0ce001eSMatthew G. Knepley   neighborVol[f*2+0] contains the left  geom
2107c0ce001eSMatthew G. Knepley   neighborVol[f*2+1] contains the right geom
2108c0ce001eSMatthew G. Knepley */
210988f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVIntegrateRHSFunction_LeastSquares(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol,
2110c0ce001eSMatthew G. Knepley                                                                PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[])
2111c0ce001eSMatthew G. Knepley {
2112c0ce001eSMatthew G. Knepley   void             (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *);
2113c0ce001eSMatthew G. Knepley   void              *rctx;
2114c0ce001eSMatthew G. Knepley   PetscScalar       *flux = fvm->fluxWork;
2115c0ce001eSMatthew G. Knepley   const PetscScalar *constants;
2116c0ce001eSMatthew G. Knepley   PetscInt           dim, numConstants, pdim, Nc, totDim, off, f, d;
2117c0ce001eSMatthew G. Knepley 
2118c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
21199566063dSJacob Faibussowitsch   PetscCall(PetscDSGetTotalComponents(prob, &Nc));
21209566063dSJacob Faibussowitsch   PetscCall(PetscDSGetTotalDimension(prob, &totDim));
21219566063dSJacob Faibussowitsch   PetscCall(PetscDSGetFieldOffset(prob, field, &off));
21229566063dSJacob Faibussowitsch   PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann));
21239566063dSJacob Faibussowitsch   PetscCall(PetscDSGetContext(prob, field, &rctx));
21249566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &numConstants, &constants));
21259566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
21269566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fvm, &pdim));
2127c0ce001eSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
2128c0ce001eSMatthew G. Knepley     (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f*Nc], &uR[f*Nc], numConstants, constants, flux, rctx);
2129c0ce001eSMatthew G. Knepley     for (d = 0; d < pdim; ++d) {
2130c0ce001eSMatthew G. Knepley       fluxL[f*totDim+off+d] = flux[d] / neighborVol[f*2+0];
2131c0ce001eSMatthew G. Knepley       fluxR[f*totDim+off+d] = flux[d] / neighborVol[f*2+1];
2132c0ce001eSMatthew G. Knepley     }
2133c0ce001eSMatthew G. Knepley   }
2134c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2135c0ce001eSMatthew G. Knepley }
2136c0ce001eSMatthew G. Knepley 
2137c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresSetMaxFaces_LS(PetscFV fvm, PetscInt maxFaces)
2138c0ce001eSMatthew G. Knepley {
2139c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *) fvm->data;
2140736d4f42SpierreXVI   PetscInt              dim,m,n,nrhs,minmn,maxmn;
2141c0ce001eSMatthew G. Knepley 
2142c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2143c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
21449566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
21459566063dSJacob Faibussowitsch   PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work));
2146c0ce001eSMatthew G. Knepley   ls->maxFaces = maxFaces;
2147c0ce001eSMatthew G. Knepley   m       = ls->maxFaces;
2148c0ce001eSMatthew G. Knepley   n       = dim;
2149c0ce001eSMatthew G. Knepley   nrhs    = ls->maxFaces;
2150736d4f42SpierreXVI   minmn   = PetscMin(m,n);
2151736d4f42SpierreXVI   maxmn   = PetscMax(m,n);
2152736d4f42SpierreXVI   ls->workSize = 3*minmn + PetscMax(2*minmn, PetscMax(maxmn, nrhs)); /* required by LAPACK */
21539566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(m*n,&ls->B,maxmn*maxmn,&ls->Binv,minmn,&ls->tau,ls->workSize,&ls->work));
2154c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2155c0ce001eSMatthew G. Knepley }
2156c0ce001eSMatthew G. Knepley 
2157c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVInitialize_LeastSquares(PetscFV fvm)
2158c0ce001eSMatthew G. Knepley {
2159c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2160c0ce001eSMatthew G. Knepley   fvm->ops->setfromoptions          = NULL;
2161c0ce001eSMatthew G. Knepley   fvm->ops->setup                   = PetscFVSetUp_LeastSquares;
2162c0ce001eSMatthew G. Knepley   fvm->ops->view                    = PetscFVView_LeastSquares;
2163c0ce001eSMatthew G. Knepley   fvm->ops->destroy                 = PetscFVDestroy_LeastSquares;
2164c0ce001eSMatthew G. Knepley   fvm->ops->computegradient         = PetscFVComputeGradient_LeastSquares;
2165c0ce001eSMatthew G. Knepley   fvm->ops->integraterhsfunction    = PetscFVIntegrateRHSFunction_LeastSquares;
2166c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2167c0ce001eSMatthew G. Knepley }
2168c0ce001eSMatthew G. Knepley 
2169c0ce001eSMatthew G. Knepley /*MC
2170c0ce001eSMatthew G. Knepley   PETSCFVLEASTSQUARES = "leastsquares" - A PetscFV object
2171c0ce001eSMatthew G. Knepley 
2172c0ce001eSMatthew G. Knepley   Level: intermediate
2173c0ce001eSMatthew G. Knepley 
2174db781477SPatrick Sanan .seealso: `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()`
2175c0ce001eSMatthew G. Knepley M*/
2176c0ce001eSMatthew G. Knepley 
2177c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscFVCreate_LeastSquares(PetscFV fvm)
2178c0ce001eSMatthew G. Knepley {
2179c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls;
2180c0ce001eSMatthew G. Knepley 
2181c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2182c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
21839566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(fvm, &ls));
2184c0ce001eSMatthew G. Knepley   fvm->data = ls;
2185c0ce001eSMatthew G. Knepley 
2186c0ce001eSMatthew G. Knepley   ls->maxFaces = -1;
2187c0ce001eSMatthew G. Knepley   ls->workSize = -1;
2188c0ce001eSMatthew G. Knepley   ls->B        = NULL;
2189c0ce001eSMatthew G. Knepley   ls->Binv     = NULL;
2190c0ce001eSMatthew G. Knepley   ls->tau      = NULL;
2191c0ce001eSMatthew G. Knepley   ls->work     = NULL;
2192c0ce001eSMatthew G. Knepley 
21939566063dSJacob Faibussowitsch   PetscCall(PetscFVSetComputeGradients(fvm, PETSC_TRUE));
21949566063dSJacob Faibussowitsch   PetscCall(PetscFVInitialize_LeastSquares(fvm));
21959566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject) fvm, "PetscFVLeastSquaresSetMaxFaces_C", PetscFVLeastSquaresSetMaxFaces_LS));
2196c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2197c0ce001eSMatthew G. Knepley }
2198c0ce001eSMatthew G. Knepley 
2199c0ce001eSMatthew G. Knepley /*@
2200c0ce001eSMatthew G. Knepley   PetscFVLeastSquaresSetMaxFaces - Set the maximum number of cell faces for gradient reconstruction
2201c0ce001eSMatthew G. Knepley 
2202c0ce001eSMatthew G. Knepley   Not collective
2203c0ce001eSMatthew G. Knepley 
2204c0ce001eSMatthew G. Knepley   Input parameters:
2205c0ce001eSMatthew G. Knepley + fvm      - The PetscFV object
2206c0ce001eSMatthew G. Knepley - maxFaces - The maximum number of cell faces
2207c0ce001eSMatthew G. Knepley 
2208c0ce001eSMatthew G. Knepley   Level: intermediate
2209c0ce001eSMatthew G. Knepley 
2210db781477SPatrick Sanan .seealso: `PetscFVCreate()`, `PETSCFVLEASTSQUARES`
2211c0ce001eSMatthew G. Knepley @*/
2212c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVLeastSquaresSetMaxFaces(PetscFV fvm, PetscInt maxFaces)
2213c0ce001eSMatthew G. Knepley {
2214c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2215c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
2216cac4c232SBarry Smith   PetscTryMethod(fvm, "PetscFVLeastSquaresSetMaxFaces_C", (PetscFV,PetscInt), (fvm,maxFaces));
2217c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2218c0ce001eSMatthew G. Knepley }
2219