xref: /petsc/src/dm/dt/fv/interface/fv.c (revision d71ae5a4db6382e7f06317b8d368875286fe9008)
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 @*/
51*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterRegister(const char sname[], PetscErrorCode (*function)(PetscLimiter))
52*d71ae5a4SJacob Faibussowitsch {
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 @*/
74*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterSetType(PetscLimiter lim, PetscLimiterType name)
75*d71ae5a4SJacob Faibussowitsch {
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) {
89dbbe0bcdSBarry Smith     PetscUseTypeMethod(lim, destroy);
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 @*/
112*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterGetType(PetscLimiter lim, PetscLimiterType *name)
113*d71ae5a4SJacob Faibussowitsch {
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 @*/
135*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterViewFromOptions(PetscLimiter A, PetscObject obj, const char name[])
136*d71ae5a4SJacob Faibussowitsch {
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 @*/
156*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterView(PetscLimiter lim, PetscViewer v)
157*d71ae5a4SJacob Faibussowitsch {
158c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
159c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
1609566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lim), &v));
161dbbe0bcdSBarry Smith   PetscTryTypeMethod(lim, view, 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 @*/
177*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterSetFromOptions(PetscLimiter lim)
178*d71ae5a4SJacob Faibussowitsch {
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   }
196dbbe0bcdSBarry Smith   PetscTryTypeMethod(lim, setfromoptions);
197c0ce001eSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
198dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)lim, PetscOptionsObject));
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 @*/
216*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterSetUp(PetscLimiter lim)
217*d71ae5a4SJacob Faibussowitsch {
218c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
219c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
220dbbe0bcdSBarry Smith   PetscTryTypeMethod(lim, setup);
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 @*/
236*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterDestroy(PetscLimiter *lim)
237*d71ae5a4SJacob Faibussowitsch {
238c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
239c0ce001eSMatthew G. Knepley   if (!*lim) PetscFunctionReturn(0);
240c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific((*lim), PETSCLIMITER_CLASSID, 1);
241c0ce001eSMatthew G. Knepley 
2429371c9d4SSatish Balay   if (--((PetscObject)(*lim))->refct > 0) {
2439371c9d4SSatish Balay     *lim = NULL;
2449371c9d4SSatish Balay     PetscFunctionReturn(0);
2459371c9d4SSatish Balay   }
246c0ce001eSMatthew G. Knepley   ((PetscObject)(*lim))->refct = 0;
247c0ce001eSMatthew G. Knepley 
248dbbe0bcdSBarry Smith   PetscTryTypeMethod((*lim), destroy);
2499566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(lim));
250c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
251c0ce001eSMatthew G. Knepley }
252c0ce001eSMatthew G. Knepley 
253c0ce001eSMatthew G. Knepley /*@
254c0ce001eSMatthew G. Knepley   PetscLimiterCreate - Creates an empty PetscLimiter object. The type can then be set with PetscLimiterSetType().
255c0ce001eSMatthew G. Knepley 
256c0ce001eSMatthew G. Knepley   Collective
257c0ce001eSMatthew G. Knepley 
258c0ce001eSMatthew G. Knepley   Input Parameter:
259c0ce001eSMatthew G. Knepley . comm - The communicator for the PetscLimiter object
260c0ce001eSMatthew G. Knepley 
261c0ce001eSMatthew G. Knepley   Output Parameter:
262c0ce001eSMatthew G. Knepley . lim - The PetscLimiter object
263c0ce001eSMatthew G. Knepley 
264c0ce001eSMatthew G. Knepley   Level: beginner
265c0ce001eSMatthew G. Knepley 
266db781477SPatrick Sanan .seealso: `PetscLimiterSetType()`, `PETSCLIMITERSIN`
267c0ce001eSMatthew G. Knepley @*/
268*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterCreate(MPI_Comm comm, PetscLimiter *lim)
269*d71ae5a4SJacob Faibussowitsch {
270c0ce001eSMatthew G. Knepley   PetscLimiter l;
271c0ce001eSMatthew G. Knepley 
272c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
273c0ce001eSMatthew G. Knepley   PetscValidPointer(lim, 2);
2749566063dSJacob Faibussowitsch   PetscCall(PetscCitationsRegister(LimiterCitation, &Limitercite));
275c0ce001eSMatthew G. Knepley   *lim = NULL;
2769566063dSJacob Faibussowitsch   PetscCall(PetscFVInitializePackage());
277c0ce001eSMatthew G. Knepley 
2789566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(l, PETSCLIMITER_CLASSID, "PetscLimiter", "Finite Volume Slope Limiter", "PetscLimiter", comm, PetscLimiterDestroy, PetscLimiterView));
279c0ce001eSMatthew G. Knepley 
280c0ce001eSMatthew G. Knepley   *lim = l;
281c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
282c0ce001eSMatthew G. Knepley }
283c0ce001eSMatthew G. Knepley 
28488f5f89eSMatthew G. Knepley /*@
28588f5f89eSMatthew G. Knepley   PetscLimiterLimit - Limit the flux
28688f5f89eSMatthew G. Knepley 
28788f5f89eSMatthew G. Knepley   Input Parameters:
28888f5f89eSMatthew G. Knepley + lim  - The PetscLimiter
28988f5f89eSMatthew G. Knepley - flim - The input field
29088f5f89eSMatthew G. Knepley 
29188f5f89eSMatthew G. Knepley   Output Parameter:
29288f5f89eSMatthew G. Knepley . phi  - The limited field
29388f5f89eSMatthew G. Knepley 
29488f5f89eSMatthew G. Knepley Note: Limiters given in symmetric form following Berger, Aftosmis, and Murman 2005
29588f5f89eSMatthew G. Knepley $ The classical flux-limited formulation is psi(r) where
29688f5f89eSMatthew G. Knepley $
29788f5f89eSMatthew G. Knepley $ r = (u[0] - u[-1]) / (u[1] - u[0])
29888f5f89eSMatthew G. Knepley $
29988f5f89eSMatthew G. Knepley $ The second order TVD region is bounded by
30088f5f89eSMatthew G. Knepley $
30188f5f89eSMatthew G. Knepley $ psi_minmod(r) = min(r,1)      and        psi_superbee(r) = min(2, 2r, max(1,r))
30288f5f89eSMatthew G. Knepley $
30388f5f89eSMatthew G. Knepley $ where all limiters are implicitly clipped to be non-negative. A more convenient slope-limited form is psi(r) =
30488f5f89eSMatthew G. Knepley $ phi(r)(r+1)/2 in which the reconstructed interface values are
30588f5f89eSMatthew G. Knepley $
30688f5f89eSMatthew G. Knepley $ u(v) = u[0] + phi(r) (grad u)[0] v
30788f5f89eSMatthew G. Knepley $
30888f5f89eSMatthew G. Knepley $ where v is the vector from centroid to quadrature point. In these variables, the usual limiters become
30988f5f89eSMatthew G. Knepley $
31088f5f89eSMatthew 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))
31188f5f89eSMatthew G. Knepley $
31288f5f89eSMatthew G. Knepley $ For a nicer symmetric formulation, rewrite in terms of
31388f5f89eSMatthew G. Knepley $
31488f5f89eSMatthew G. Knepley $ f = (u[0] - u[-1]) / (u[1] - u[-1])
31588f5f89eSMatthew G. Knepley $
31688f5f89eSMatthew G. Knepley $ where r(f) = f/(1-f). Not that r(1-f) = (1-f)/f = 1/r(f) so the symmetry condition
31788f5f89eSMatthew G. Knepley $
31888f5f89eSMatthew G. Knepley $ phi(r) = phi(1/r)
31988f5f89eSMatthew G. Knepley $
32088f5f89eSMatthew G. Knepley $ becomes
32188f5f89eSMatthew G. Knepley $
32288f5f89eSMatthew G. Knepley $ w(f) = w(1-f).
32388f5f89eSMatthew G. Knepley $
32488f5f89eSMatthew G. Knepley $ The limiters below implement this final form w(f). The reference methods are
32588f5f89eSMatthew G. Knepley $
32688f5f89eSMatthew G. Knepley $ w_minmod(f) = 2 min(f,(1-f))             w_superbee(r) = 4 min((1-f), f)
32788f5f89eSMatthew G. Knepley 
32888f5f89eSMatthew G. Knepley   Level: beginner
32988f5f89eSMatthew G. Knepley 
330db781477SPatrick Sanan .seealso: `PetscLimiterSetType()`, `PetscLimiterCreate()`
33188f5f89eSMatthew G. Knepley @*/
332*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterLimit(PetscLimiter lim, PetscReal flim, PetscReal *phi)
333*d71ae5a4SJacob Faibussowitsch {
334c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
335c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
336dadcf809SJacob Faibussowitsch   PetscValidRealPointer(phi, 3);
337dbbe0bcdSBarry Smith   PetscUseTypeMethod(lim, limit, flim, phi);
338c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
339c0ce001eSMatthew G. Knepley }
340c0ce001eSMatthew G. Knepley 
341*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_Sin(PetscLimiter lim)
342*d71ae5a4SJacob Faibussowitsch {
343c0ce001eSMatthew G. Knepley   PetscLimiter_Sin *l = (PetscLimiter_Sin *)lim->data;
344c0ce001eSMatthew G. Knepley 
345c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
3469566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
347c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
348c0ce001eSMatthew G. Knepley }
349c0ce001eSMatthew G. Knepley 
350*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Sin_Ascii(PetscLimiter lim, PetscViewer viewer)
351*d71ae5a4SJacob Faibussowitsch {
352c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
353c0ce001eSMatthew G. Knepley 
354c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
3559566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
3569566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Sin Slope Limiter:\n"));
357c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
358c0ce001eSMatthew G. Knepley }
359c0ce001eSMatthew G. Knepley 
360*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Sin(PetscLimiter lim, PetscViewer viewer)
361*d71ae5a4SJacob Faibussowitsch {
362c0ce001eSMatthew G. Knepley   PetscBool iascii;
363c0ce001eSMatthew G. Knepley 
364c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
365c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
366c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
3679566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
3689566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_Sin_Ascii(lim, viewer));
369c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
370c0ce001eSMatthew G. Knepley }
371c0ce001eSMatthew G. Knepley 
372*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_Sin(PetscLimiter lim, PetscReal f, PetscReal *phi)
373*d71ae5a4SJacob Faibussowitsch {
374c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
375c0ce001eSMatthew G. Knepley   *phi = PetscSinReal(PETSC_PI * PetscMax(0, PetscMin(f, 1)));
376c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
377c0ce001eSMatthew G. Knepley }
378c0ce001eSMatthew G. Knepley 
379*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_Sin(PetscLimiter lim)
380*d71ae5a4SJacob Faibussowitsch {
381c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
382c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Sin;
383c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Sin;
384c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Sin;
385c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
386c0ce001eSMatthew G. Knepley }
387c0ce001eSMatthew G. Knepley 
388c0ce001eSMatthew G. Knepley /*MC
389c0ce001eSMatthew G. Knepley   PETSCLIMITERSIN = "sin" - A PetscLimiter object
390c0ce001eSMatthew G. Knepley 
391c0ce001eSMatthew G. Knepley   Level: intermediate
392c0ce001eSMatthew G. Knepley 
393db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
394c0ce001eSMatthew G. Knepley M*/
395c0ce001eSMatthew G. Knepley 
396*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Sin(PetscLimiter lim)
397*d71ae5a4SJacob Faibussowitsch {
398c0ce001eSMatthew G. Knepley   PetscLimiter_Sin *l;
399c0ce001eSMatthew G. Knepley 
400c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
401c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
4024dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&l));
403c0ce001eSMatthew G. Knepley   lim->data = l;
404c0ce001eSMatthew G. Knepley 
4059566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_Sin(lim));
406c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
407c0ce001eSMatthew G. Knepley }
408c0ce001eSMatthew G. Knepley 
409*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_Zero(PetscLimiter lim)
410*d71ae5a4SJacob Faibussowitsch {
411c0ce001eSMatthew G. Knepley   PetscLimiter_Zero *l = (PetscLimiter_Zero *)lim->data;
412c0ce001eSMatthew G. Knepley 
413c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
4149566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
415c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
416c0ce001eSMatthew G. Knepley }
417c0ce001eSMatthew G. Knepley 
418*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Zero_Ascii(PetscLimiter lim, PetscViewer viewer)
419*d71ae5a4SJacob Faibussowitsch {
420c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
421c0ce001eSMatthew G. Knepley 
422c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
4239566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
4249566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Zero Slope Limiter:\n"));
425c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
426c0ce001eSMatthew G. Knepley }
427c0ce001eSMatthew G. Knepley 
428*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Zero(PetscLimiter lim, PetscViewer viewer)
429*d71ae5a4SJacob Faibussowitsch {
430c0ce001eSMatthew G. Knepley   PetscBool iascii;
431c0ce001eSMatthew G. Knepley 
432c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
433c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
434c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
4359566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
4369566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_Zero_Ascii(lim, viewer));
437c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
438c0ce001eSMatthew G. Knepley }
439c0ce001eSMatthew G. Knepley 
440*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_Zero(PetscLimiter lim, PetscReal f, PetscReal *phi)
441*d71ae5a4SJacob Faibussowitsch {
442c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
443c0ce001eSMatthew G. Knepley   *phi = 0.0;
444c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
445c0ce001eSMatthew G. Knepley }
446c0ce001eSMatthew G. Knepley 
447*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_Zero(PetscLimiter lim)
448*d71ae5a4SJacob Faibussowitsch {
449c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
450c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Zero;
451c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Zero;
452c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Zero;
453c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
454c0ce001eSMatthew G. Knepley }
455c0ce001eSMatthew G. Knepley 
456c0ce001eSMatthew G. Knepley /*MC
457c0ce001eSMatthew G. Knepley   PETSCLIMITERZERO = "zero" - A PetscLimiter object
458c0ce001eSMatthew G. Knepley 
459c0ce001eSMatthew G. Knepley   Level: intermediate
460c0ce001eSMatthew G. Knepley 
461db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
462c0ce001eSMatthew G. Knepley M*/
463c0ce001eSMatthew G. Knepley 
464*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Zero(PetscLimiter lim)
465*d71ae5a4SJacob Faibussowitsch {
466c0ce001eSMatthew G. Knepley   PetscLimiter_Zero *l;
467c0ce001eSMatthew G. Knepley 
468c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
469c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
4704dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&l));
471c0ce001eSMatthew G. Knepley   lim->data = l;
472c0ce001eSMatthew G. Knepley 
4739566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_Zero(lim));
474c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
475c0ce001eSMatthew G. Knepley }
476c0ce001eSMatthew G. Knepley 
477*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_None(PetscLimiter lim)
478*d71ae5a4SJacob Faibussowitsch {
479c0ce001eSMatthew G. Knepley   PetscLimiter_None *l = (PetscLimiter_None *)lim->data;
480c0ce001eSMatthew G. Knepley 
481c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
4829566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
483c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
484c0ce001eSMatthew G. Knepley }
485c0ce001eSMatthew G. Knepley 
486*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_None_Ascii(PetscLimiter lim, PetscViewer viewer)
487*d71ae5a4SJacob Faibussowitsch {
488c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
489c0ce001eSMatthew G. Knepley 
490c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
4919566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
4929566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "None Slope Limiter:\n"));
493c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
494c0ce001eSMatthew G. Knepley }
495c0ce001eSMatthew G. Knepley 
496*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_None(PetscLimiter lim, PetscViewer viewer)
497*d71ae5a4SJacob Faibussowitsch {
498c0ce001eSMatthew G. Knepley   PetscBool iascii;
499c0ce001eSMatthew G. Knepley 
500c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
501c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
502c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
5039566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
5049566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_None_Ascii(lim, viewer));
505c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
506c0ce001eSMatthew G. Knepley }
507c0ce001eSMatthew G. Knepley 
508*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_None(PetscLimiter lim, PetscReal f, PetscReal *phi)
509*d71ae5a4SJacob Faibussowitsch {
510c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
511c0ce001eSMatthew G. Knepley   *phi = 1.0;
512c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
513c0ce001eSMatthew G. Knepley }
514c0ce001eSMatthew G. Knepley 
515*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_None(PetscLimiter lim)
516*d71ae5a4SJacob Faibussowitsch {
517c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
518c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_None;
519c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_None;
520c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_None;
521c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
522c0ce001eSMatthew G. Knepley }
523c0ce001eSMatthew G. Knepley 
524c0ce001eSMatthew G. Knepley /*MC
525c0ce001eSMatthew G. Knepley   PETSCLIMITERNONE = "none" - A PetscLimiter object
526c0ce001eSMatthew G. Knepley 
527c0ce001eSMatthew G. Knepley   Level: intermediate
528c0ce001eSMatthew G. Knepley 
529db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
530c0ce001eSMatthew G. Knepley M*/
531c0ce001eSMatthew G. Knepley 
532*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_None(PetscLimiter lim)
533*d71ae5a4SJacob Faibussowitsch {
534c0ce001eSMatthew G. Knepley   PetscLimiter_None *l;
535c0ce001eSMatthew G. Knepley 
536c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
537c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
5384dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&l));
539c0ce001eSMatthew G. Knepley   lim->data = l;
540c0ce001eSMatthew G. Knepley 
5419566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_None(lim));
542c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
543c0ce001eSMatthew G. Knepley }
544c0ce001eSMatthew G. Knepley 
545*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_Minmod(PetscLimiter lim)
546*d71ae5a4SJacob Faibussowitsch {
547c0ce001eSMatthew G. Knepley   PetscLimiter_Minmod *l = (PetscLimiter_Minmod *)lim->data;
548c0ce001eSMatthew G. Knepley 
549c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
5509566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
551c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
552c0ce001eSMatthew G. Knepley }
553c0ce001eSMatthew G. Knepley 
554*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Minmod_Ascii(PetscLimiter lim, PetscViewer viewer)
555*d71ae5a4SJacob Faibussowitsch {
556c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
557c0ce001eSMatthew G. Knepley 
558c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
5599566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
5609566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Minmod Slope Limiter:\n"));
561c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
562c0ce001eSMatthew G. Knepley }
563c0ce001eSMatthew G. Knepley 
564*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Minmod(PetscLimiter lim, PetscViewer viewer)
565*d71ae5a4SJacob Faibussowitsch {
566c0ce001eSMatthew G. Knepley   PetscBool iascii;
567c0ce001eSMatthew G. Knepley 
568c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
569c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
570c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
5719566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
5729566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_Minmod_Ascii(lim, viewer));
573c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
574c0ce001eSMatthew G. Knepley }
575c0ce001eSMatthew G. Knepley 
576*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_Minmod(PetscLimiter lim, PetscReal f, PetscReal *phi)
577*d71ae5a4SJacob Faibussowitsch {
578c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
579c0ce001eSMatthew G. Knepley   *phi = 2 * PetscMax(0, PetscMin(f, 1 - f));
580c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
581c0ce001eSMatthew G. Knepley }
582c0ce001eSMatthew G. Knepley 
583*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_Minmod(PetscLimiter lim)
584*d71ae5a4SJacob Faibussowitsch {
585c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
586c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Minmod;
587c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Minmod;
588c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Minmod;
589c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
590c0ce001eSMatthew G. Knepley }
591c0ce001eSMatthew G. Knepley 
592c0ce001eSMatthew G. Knepley /*MC
593c0ce001eSMatthew G. Knepley   PETSCLIMITERMINMOD = "minmod" - A PetscLimiter object
594c0ce001eSMatthew G. Knepley 
595c0ce001eSMatthew G. Knepley   Level: intermediate
596c0ce001eSMatthew G. Knepley 
597db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
598c0ce001eSMatthew G. Knepley M*/
599c0ce001eSMatthew G. Knepley 
600*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Minmod(PetscLimiter lim)
601*d71ae5a4SJacob Faibussowitsch {
602c0ce001eSMatthew G. Knepley   PetscLimiter_Minmod *l;
603c0ce001eSMatthew G. Knepley 
604c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
605c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
6064dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&l));
607c0ce001eSMatthew G. Knepley   lim->data = l;
608c0ce001eSMatthew G. Knepley 
6099566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_Minmod(lim));
610c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
611c0ce001eSMatthew G. Knepley }
612c0ce001eSMatthew G. Knepley 
613*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_VanLeer(PetscLimiter lim)
614*d71ae5a4SJacob Faibussowitsch {
615c0ce001eSMatthew G. Knepley   PetscLimiter_VanLeer *l = (PetscLimiter_VanLeer *)lim->data;
616c0ce001eSMatthew G. Knepley 
617c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
6189566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
619c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
620c0ce001eSMatthew G. Knepley }
621c0ce001eSMatthew G. Knepley 
622*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_VanLeer_Ascii(PetscLimiter lim, PetscViewer viewer)
623*d71ae5a4SJacob Faibussowitsch {
624c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
625c0ce001eSMatthew G. Knepley 
626c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
6279566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
6289566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Van Leer Slope Limiter:\n"));
629c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
630c0ce001eSMatthew G. Knepley }
631c0ce001eSMatthew G. Knepley 
632*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_VanLeer(PetscLimiter lim, PetscViewer viewer)
633*d71ae5a4SJacob Faibussowitsch {
634c0ce001eSMatthew G. Knepley   PetscBool iascii;
635c0ce001eSMatthew G. Knepley 
636c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
637c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
638c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
6399566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
6409566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_VanLeer_Ascii(lim, viewer));
641c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
642c0ce001eSMatthew G. Knepley }
643c0ce001eSMatthew G. Knepley 
644*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_VanLeer(PetscLimiter lim, PetscReal f, PetscReal *phi)
645*d71ae5a4SJacob Faibussowitsch {
646c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
647c0ce001eSMatthew G. Knepley   *phi = PetscMax(0, 4 * f * (1 - f));
648c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
649c0ce001eSMatthew G. Knepley }
650c0ce001eSMatthew G. Knepley 
651*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_VanLeer(PetscLimiter lim)
652*d71ae5a4SJacob Faibussowitsch {
653c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
654c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_VanLeer;
655c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_VanLeer;
656c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_VanLeer;
657c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
658c0ce001eSMatthew G. Knepley }
659c0ce001eSMatthew G. Knepley 
660c0ce001eSMatthew G. Knepley /*MC
661c0ce001eSMatthew G. Knepley   PETSCLIMITERVANLEER = "vanleer" - A PetscLimiter object
662c0ce001eSMatthew G. Knepley 
663c0ce001eSMatthew G. Knepley   Level: intermediate
664c0ce001eSMatthew G. Knepley 
665db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
666c0ce001eSMatthew G. Knepley M*/
667c0ce001eSMatthew G. Knepley 
668*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanLeer(PetscLimiter lim)
669*d71ae5a4SJacob Faibussowitsch {
670c0ce001eSMatthew G. Knepley   PetscLimiter_VanLeer *l;
671c0ce001eSMatthew G. Knepley 
672c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
673c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
6744dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&l));
675c0ce001eSMatthew G. Knepley   lim->data = l;
676c0ce001eSMatthew G. Knepley 
6779566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_VanLeer(lim));
678c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
679c0ce001eSMatthew G. Knepley }
680c0ce001eSMatthew G. Knepley 
681*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_VanAlbada(PetscLimiter lim)
682*d71ae5a4SJacob Faibussowitsch {
683c0ce001eSMatthew G. Knepley   PetscLimiter_VanAlbada *l = (PetscLimiter_VanAlbada *)lim->data;
684c0ce001eSMatthew G. Knepley 
685c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
6869566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
687c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
688c0ce001eSMatthew G. Knepley }
689c0ce001eSMatthew G. Knepley 
690*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_VanAlbada_Ascii(PetscLimiter lim, PetscViewer viewer)
691*d71ae5a4SJacob Faibussowitsch {
692c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
693c0ce001eSMatthew G. Knepley 
694c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
6959566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
6969566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Van Albada Slope Limiter:\n"));
697c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
698c0ce001eSMatthew G. Knepley }
699c0ce001eSMatthew G. Knepley 
700*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_VanAlbada(PetscLimiter lim, PetscViewer viewer)
701*d71ae5a4SJacob Faibussowitsch {
702c0ce001eSMatthew G. Knepley   PetscBool iascii;
703c0ce001eSMatthew G. Knepley 
704c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
705c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
706c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
7079566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
7089566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_VanAlbada_Ascii(lim, viewer));
709c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
710c0ce001eSMatthew G. Knepley }
711c0ce001eSMatthew G. Knepley 
712*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_VanAlbada(PetscLimiter lim, PetscReal f, PetscReal *phi)
713*d71ae5a4SJacob Faibussowitsch {
714c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
715c0ce001eSMatthew G. Knepley   *phi = PetscMax(0, 2 * f * (1 - f) / (PetscSqr(f) + PetscSqr(1 - f)));
716c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
717c0ce001eSMatthew G. Knepley }
718c0ce001eSMatthew G. Knepley 
719*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_VanAlbada(PetscLimiter lim)
720*d71ae5a4SJacob Faibussowitsch {
721c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
722c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_VanAlbada;
723c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_VanAlbada;
724c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_VanAlbada;
725c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
726c0ce001eSMatthew G. Knepley }
727c0ce001eSMatthew G. Knepley 
728c0ce001eSMatthew G. Knepley /*MC
729c0ce001eSMatthew G. Knepley   PETSCLIMITERVANALBADA = "vanalbada" - A PetscLimiter object
730c0ce001eSMatthew G. Knepley 
731c0ce001eSMatthew G. Knepley   Level: intermediate
732c0ce001eSMatthew G. Knepley 
733db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
734c0ce001eSMatthew G. Knepley M*/
735c0ce001eSMatthew G. Knepley 
736*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanAlbada(PetscLimiter lim)
737*d71ae5a4SJacob Faibussowitsch {
738c0ce001eSMatthew G. Knepley   PetscLimiter_VanAlbada *l;
739c0ce001eSMatthew G. Knepley 
740c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
741c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
7424dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&l));
743c0ce001eSMatthew G. Knepley   lim->data = l;
744c0ce001eSMatthew G. Knepley 
7459566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_VanAlbada(lim));
746c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
747c0ce001eSMatthew G. Knepley }
748c0ce001eSMatthew G. Knepley 
749*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_Superbee(PetscLimiter lim)
750*d71ae5a4SJacob Faibussowitsch {
751c0ce001eSMatthew G. Knepley   PetscLimiter_Superbee *l = (PetscLimiter_Superbee *)lim->data;
752c0ce001eSMatthew G. Knepley 
753c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
7549566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
755c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
756c0ce001eSMatthew G. Knepley }
757c0ce001eSMatthew G. Knepley 
758*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Superbee_Ascii(PetscLimiter lim, PetscViewer viewer)
759*d71ae5a4SJacob Faibussowitsch {
760c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
761c0ce001eSMatthew G. Knepley 
762c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
7639566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
7649566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Superbee Slope Limiter:\n"));
765c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
766c0ce001eSMatthew G. Knepley }
767c0ce001eSMatthew G. Knepley 
768*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Superbee(PetscLimiter lim, PetscViewer viewer)
769*d71ae5a4SJacob Faibussowitsch {
770c0ce001eSMatthew G. Knepley   PetscBool iascii;
771c0ce001eSMatthew G. Knepley 
772c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
773c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
774c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
7759566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
7769566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_Superbee_Ascii(lim, viewer));
777c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
778c0ce001eSMatthew G. Knepley }
779c0ce001eSMatthew G. Knepley 
780*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_Superbee(PetscLimiter lim, PetscReal f, PetscReal *phi)
781*d71ae5a4SJacob Faibussowitsch {
782c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
783c0ce001eSMatthew G. Knepley   *phi = 4 * PetscMax(0, PetscMin(f, 1 - f));
784c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
785c0ce001eSMatthew G. Knepley }
786c0ce001eSMatthew G. Knepley 
787*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_Superbee(PetscLimiter lim)
788*d71ae5a4SJacob Faibussowitsch {
789c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
790c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Superbee;
791c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Superbee;
792c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Superbee;
793c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
794c0ce001eSMatthew G. Knepley }
795c0ce001eSMatthew G. Knepley 
796c0ce001eSMatthew G. Knepley /*MC
797c0ce001eSMatthew G. Knepley   PETSCLIMITERSUPERBEE = "superbee" - A PetscLimiter object
798c0ce001eSMatthew G. Knepley 
799c0ce001eSMatthew G. Knepley   Level: intermediate
800c0ce001eSMatthew G. Knepley 
801db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
802c0ce001eSMatthew G. Knepley M*/
803c0ce001eSMatthew G. Knepley 
804*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Superbee(PetscLimiter lim)
805*d71ae5a4SJacob Faibussowitsch {
806c0ce001eSMatthew G. Knepley   PetscLimiter_Superbee *l;
807c0ce001eSMatthew G. Knepley 
808c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
809c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
8104dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&l));
811c0ce001eSMatthew G. Knepley   lim->data = l;
812c0ce001eSMatthew G. Knepley 
8139566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_Superbee(lim));
814c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
815c0ce001eSMatthew G. Knepley }
816c0ce001eSMatthew G. Knepley 
817*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_MC(PetscLimiter lim)
818*d71ae5a4SJacob Faibussowitsch {
819c0ce001eSMatthew G. Knepley   PetscLimiter_MC *l = (PetscLimiter_MC *)lim->data;
820c0ce001eSMatthew G. Knepley 
821c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
8229566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
823c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
824c0ce001eSMatthew G. Knepley }
825c0ce001eSMatthew G. Knepley 
826*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_MC_Ascii(PetscLimiter lim, PetscViewer viewer)
827*d71ae5a4SJacob Faibussowitsch {
828c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
829c0ce001eSMatthew G. Knepley 
830c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
8319566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
8329566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "MC Slope Limiter:\n"));
833c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
834c0ce001eSMatthew G. Knepley }
835c0ce001eSMatthew G. Knepley 
836*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_MC(PetscLimiter lim, PetscViewer viewer)
837*d71ae5a4SJacob Faibussowitsch {
838c0ce001eSMatthew G. Knepley   PetscBool iascii;
839c0ce001eSMatthew G. Knepley 
840c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
841c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
842c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
8439566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
8449566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_MC_Ascii(lim, viewer));
845c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
846c0ce001eSMatthew G. Knepley }
847c0ce001eSMatthew G. Knepley 
848c0ce001eSMatthew G. Knepley /* aka Barth-Jespersen */
849*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_MC(PetscLimiter lim, PetscReal f, PetscReal *phi)
850*d71ae5a4SJacob Faibussowitsch {
851c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
852c0ce001eSMatthew G. Knepley   *phi = PetscMin(1, 4 * PetscMax(0, PetscMin(f, 1 - f)));
853c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
854c0ce001eSMatthew G. Knepley }
855c0ce001eSMatthew G. Knepley 
856*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_MC(PetscLimiter lim)
857*d71ae5a4SJacob Faibussowitsch {
858c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
859c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_MC;
860c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_MC;
861c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_MC;
862c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
863c0ce001eSMatthew G. Knepley }
864c0ce001eSMatthew G. Knepley 
865c0ce001eSMatthew G. Knepley /*MC
866c0ce001eSMatthew G. Knepley   PETSCLIMITERMC = "mc" - A PetscLimiter object
867c0ce001eSMatthew G. Knepley 
868c0ce001eSMatthew G. Knepley   Level: intermediate
869c0ce001eSMatthew G. Knepley 
870db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
871c0ce001eSMatthew G. Knepley M*/
872c0ce001eSMatthew G. Knepley 
873*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_MC(PetscLimiter lim)
874*d71ae5a4SJacob Faibussowitsch {
875c0ce001eSMatthew G. Knepley   PetscLimiter_MC *l;
876c0ce001eSMatthew G. Knepley 
877c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
878c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
8794dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&l));
880c0ce001eSMatthew G. Knepley   lim->data = l;
881c0ce001eSMatthew G. Knepley 
8829566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_MC(lim));
883c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
884c0ce001eSMatthew G. Knepley }
885c0ce001eSMatthew G. Knepley 
886c0ce001eSMatthew G. Knepley PetscClassId PETSCFV_CLASSID = 0;
887c0ce001eSMatthew G. Knepley 
888c0ce001eSMatthew G. Knepley PetscFunctionList PetscFVList              = NULL;
889c0ce001eSMatthew G. Knepley PetscBool         PetscFVRegisterAllCalled = PETSC_FALSE;
890c0ce001eSMatthew G. Knepley 
891c0ce001eSMatthew G. Knepley /*@C
892c0ce001eSMatthew G. Knepley   PetscFVRegister - Adds a new PetscFV implementation
893c0ce001eSMatthew G. Knepley 
894c0ce001eSMatthew G. Knepley   Not Collective
895c0ce001eSMatthew G. Knepley 
896c0ce001eSMatthew G. Knepley   Input Parameters:
897c0ce001eSMatthew G. Knepley + name        - The name of a new user-defined creation routine
898c0ce001eSMatthew G. Knepley - create_func - The creation routine itself
899c0ce001eSMatthew G. Knepley 
900c0ce001eSMatthew G. Knepley   Notes:
901c0ce001eSMatthew G. Knepley   PetscFVRegister() may be called multiple times to add several user-defined PetscFVs
902c0ce001eSMatthew G. Knepley 
903c0ce001eSMatthew G. Knepley   Sample usage:
904c0ce001eSMatthew G. Knepley .vb
905c0ce001eSMatthew G. Knepley     PetscFVRegister("my_fv", MyPetscFVCreate);
906c0ce001eSMatthew G. Knepley .ve
907c0ce001eSMatthew G. Knepley 
908c0ce001eSMatthew G. Knepley   Then, your PetscFV type can be chosen with the procedural interface via
909c0ce001eSMatthew G. Knepley .vb
910c0ce001eSMatthew G. Knepley     PetscFVCreate(MPI_Comm, PetscFV *);
911c0ce001eSMatthew G. Knepley     PetscFVSetType(PetscFV, "my_fv");
912c0ce001eSMatthew G. Knepley .ve
913c0ce001eSMatthew G. Knepley    or at runtime via the option
914c0ce001eSMatthew G. Knepley .vb
915c0ce001eSMatthew G. Knepley     -petscfv_type my_fv
916c0ce001eSMatthew G. Knepley .ve
917c0ce001eSMatthew G. Knepley 
918c0ce001eSMatthew G. Knepley   Level: advanced
919c0ce001eSMatthew G. Knepley 
920db781477SPatrick Sanan .seealso: `PetscFVRegisterAll()`, `PetscFVRegisterDestroy()`
921c0ce001eSMatthew G. Knepley 
922c0ce001eSMatthew G. Knepley @*/
923*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVRegister(const char sname[], PetscErrorCode (*function)(PetscFV))
924*d71ae5a4SJacob Faibussowitsch {
925c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
9269566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscFVList, sname, function));
927c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
928c0ce001eSMatthew G. Knepley }
929c0ce001eSMatthew G. Knepley 
930c0ce001eSMatthew G. Knepley /*@C
931c0ce001eSMatthew G. Knepley   PetscFVSetType - Builds a particular PetscFV
932c0ce001eSMatthew G. Knepley 
933c0ce001eSMatthew G. Knepley   Collective on fvm
934c0ce001eSMatthew G. Knepley 
935c0ce001eSMatthew G. Knepley   Input Parameters:
936c0ce001eSMatthew G. Knepley + fvm  - The PetscFV object
937c0ce001eSMatthew G. Knepley - name - The kind of FVM space
938c0ce001eSMatthew G. Knepley 
939c0ce001eSMatthew G. Knepley   Options Database Key:
940c0ce001eSMatthew G. Knepley . -petscfv_type <type> - Sets the PetscFV type; use -help for a list of available types
941c0ce001eSMatthew G. Knepley 
942c0ce001eSMatthew G. Knepley   Level: intermediate
943c0ce001eSMatthew G. Knepley 
944db781477SPatrick Sanan .seealso: `PetscFVGetType()`, `PetscFVCreate()`
945c0ce001eSMatthew G. Knepley @*/
946*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetType(PetscFV fvm, PetscFVType name)
947*d71ae5a4SJacob Faibussowitsch {
948c0ce001eSMatthew G. Knepley   PetscErrorCode (*r)(PetscFV);
949c0ce001eSMatthew G. Knepley   PetscBool match;
950c0ce001eSMatthew G. Knepley 
951c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
952c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
9539566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)fvm, name, &match));
954c0ce001eSMatthew G. Knepley   if (match) PetscFunctionReturn(0);
955c0ce001eSMatthew G. Knepley 
9569566063dSJacob Faibussowitsch   PetscCall(PetscFVRegisterAll());
9579566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscFVList, name, &r));
95828b400f6SJacob Faibussowitsch   PetscCheck(r, PetscObjectComm((PetscObject)fvm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscFV type: %s", name);
959c0ce001eSMatthew G. Knepley 
960dbbe0bcdSBarry Smith   PetscTryTypeMethod(fvm, destroy);
961c0ce001eSMatthew G. Knepley   fvm->ops->destroy = NULL;
962dbbe0bcdSBarry Smith 
9639566063dSJacob Faibussowitsch   PetscCall((*r)(fvm));
9649566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)fvm, name));
965c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
966c0ce001eSMatthew G. Knepley }
967c0ce001eSMatthew G. Knepley 
968c0ce001eSMatthew G. Knepley /*@C
969c0ce001eSMatthew G. Knepley   PetscFVGetType - Gets the PetscFV type name (as a string) from the object.
970c0ce001eSMatthew G. Knepley 
971c0ce001eSMatthew G. Knepley   Not Collective
972c0ce001eSMatthew G. Knepley 
973c0ce001eSMatthew G. Knepley   Input Parameter:
974c0ce001eSMatthew G. Knepley . fvm  - The PetscFV
975c0ce001eSMatthew G. Knepley 
976c0ce001eSMatthew G. Knepley   Output Parameter:
977c0ce001eSMatthew G. Knepley . name - The PetscFV type name
978c0ce001eSMatthew G. Knepley 
979c0ce001eSMatthew G. Knepley   Level: intermediate
980c0ce001eSMatthew G. Knepley 
981db781477SPatrick Sanan .seealso: `PetscFVSetType()`, `PetscFVCreate()`
982c0ce001eSMatthew G. Knepley @*/
983*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetType(PetscFV fvm, PetscFVType *name)
984*d71ae5a4SJacob Faibussowitsch {
985c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
986c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
987c0ce001eSMatthew G. Knepley   PetscValidPointer(name, 2);
9889566063dSJacob Faibussowitsch   PetscCall(PetscFVRegisterAll());
989c0ce001eSMatthew G. Knepley   *name = ((PetscObject)fvm)->type_name;
990c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
991c0ce001eSMatthew G. Knepley }
992c0ce001eSMatthew G. Knepley 
993c0ce001eSMatthew G. Knepley /*@C
994fe2efc57SMark    PetscFVViewFromOptions - View from Options
995fe2efc57SMark 
996fe2efc57SMark    Collective on PetscFV
997fe2efc57SMark 
998fe2efc57SMark    Input Parameters:
999fe2efc57SMark +  A - the PetscFV object
1000736c3998SJose E. Roman .  obj - Optional object
1001736c3998SJose E. Roman -  name - command line option
1002fe2efc57SMark 
1003fe2efc57SMark    Level: intermediate
1004db781477SPatrick Sanan .seealso: `PetscFV`, `PetscFVView`, `PetscObjectViewFromOptions()`, `PetscFVCreate()`
1005fe2efc57SMark @*/
1006*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVViewFromOptions(PetscFV A, PetscObject obj, const char name[])
1007*d71ae5a4SJacob Faibussowitsch {
1008fe2efc57SMark   PetscFunctionBegin;
1009fe2efc57SMark   PetscValidHeaderSpecific(A, PETSCFV_CLASSID, 1);
10109566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
1011fe2efc57SMark   PetscFunctionReturn(0);
1012fe2efc57SMark }
1013fe2efc57SMark 
1014fe2efc57SMark /*@C
1015c0ce001eSMatthew G. Knepley   PetscFVView - Views a PetscFV
1016c0ce001eSMatthew G. Knepley 
1017c0ce001eSMatthew G. Knepley   Collective on fvm
1018c0ce001eSMatthew G. Knepley 
1019d8d19677SJose E. Roman   Input Parameters:
1020c0ce001eSMatthew G. Knepley + fvm - the PetscFV object to view
1021c0ce001eSMatthew G. Knepley - v   - the viewer
1022c0ce001eSMatthew G. Knepley 
102388f5f89eSMatthew G. Knepley   Level: beginner
1024c0ce001eSMatthew G. Knepley 
1025db781477SPatrick Sanan .seealso: `PetscFVDestroy()`
1026c0ce001eSMatthew G. Knepley @*/
1027*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVView(PetscFV fvm, PetscViewer v)
1028*d71ae5a4SJacob Faibussowitsch {
1029c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1030c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
10319566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)fvm), &v));
1032dbbe0bcdSBarry Smith   PetscTryTypeMethod(fvm, view, v);
1033c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1034c0ce001eSMatthew G. Knepley }
1035c0ce001eSMatthew G. Knepley 
1036c0ce001eSMatthew G. Knepley /*@
1037c0ce001eSMatthew G. Knepley   PetscFVSetFromOptions - sets parameters in a PetscFV from the options database
1038c0ce001eSMatthew G. Knepley 
1039c0ce001eSMatthew G. Knepley   Collective on fvm
1040c0ce001eSMatthew G. Knepley 
1041c0ce001eSMatthew G. Knepley   Input Parameter:
1042c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to set options for
1043c0ce001eSMatthew G. Knepley 
1044c0ce001eSMatthew G. Knepley   Options Database Key:
1045c0ce001eSMatthew G. Knepley . -petscfv_compute_gradients <bool> - Determines whether cell gradients are calculated
1046c0ce001eSMatthew G. Knepley 
104788f5f89eSMatthew G. Knepley   Level: intermediate
1048c0ce001eSMatthew G. Knepley 
1049db781477SPatrick Sanan .seealso: `PetscFVView()`
1050c0ce001eSMatthew G. Knepley @*/
1051*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetFromOptions(PetscFV fvm)
1052*d71ae5a4SJacob Faibussowitsch {
1053c0ce001eSMatthew G. Knepley   const char *defaultType;
1054c0ce001eSMatthew G. Knepley   char        name[256];
1055c0ce001eSMatthew G. Knepley   PetscBool   flg;
1056c0ce001eSMatthew G. Knepley 
1057c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1058c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1059c0ce001eSMatthew G. Knepley   if (!((PetscObject)fvm)->type_name) defaultType = PETSCFVUPWIND;
1060c0ce001eSMatthew G. Knepley   else defaultType = ((PetscObject)fvm)->type_name;
10619566063dSJacob Faibussowitsch   PetscCall(PetscFVRegisterAll());
1062c0ce001eSMatthew G. Knepley 
1063d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)fvm);
10649566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petscfv_type", "Finite volume discretization", "PetscFVSetType", PetscFVList, defaultType, name, 256, &flg));
1065c0ce001eSMatthew G. Knepley   if (flg) {
10669566063dSJacob Faibussowitsch     PetscCall(PetscFVSetType(fvm, name));
1067c0ce001eSMatthew G. Knepley   } else if (!((PetscObject)fvm)->type_name) {
10689566063dSJacob Faibussowitsch     PetscCall(PetscFVSetType(fvm, defaultType));
1069c0ce001eSMatthew G. Knepley   }
10709566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-petscfv_compute_gradients", "Compute cell gradients", "PetscFVSetComputeGradients", fvm->computeGradients, &fvm->computeGradients, NULL));
1071dbbe0bcdSBarry Smith   PetscTryTypeMethod(fvm, setfromoptions);
1072c0ce001eSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
1073dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)fvm, PetscOptionsObject));
10749566063dSJacob Faibussowitsch   PetscCall(PetscLimiterSetFromOptions(fvm->limiter));
1075d0609cedSBarry Smith   PetscOptionsEnd();
10769566063dSJacob Faibussowitsch   PetscCall(PetscFVViewFromOptions(fvm, NULL, "-petscfv_view"));
1077c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1078c0ce001eSMatthew G. Knepley }
1079c0ce001eSMatthew G. Knepley 
1080c0ce001eSMatthew G. Knepley /*@
1081c0ce001eSMatthew G. Knepley   PetscFVSetUp - Construct data structures for the PetscFV
1082c0ce001eSMatthew G. Knepley 
1083c0ce001eSMatthew G. Knepley   Collective on fvm
1084c0ce001eSMatthew G. Knepley 
1085c0ce001eSMatthew G. Knepley   Input Parameter:
1086c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to setup
1087c0ce001eSMatthew G. Knepley 
108888f5f89eSMatthew G. Knepley   Level: intermediate
1089c0ce001eSMatthew G. Knepley 
1090db781477SPatrick Sanan .seealso: `PetscFVView()`, `PetscFVDestroy()`
1091c0ce001eSMatthew G. Knepley @*/
1092*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetUp(PetscFV fvm)
1093*d71ae5a4SJacob Faibussowitsch {
1094c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1095c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
10969566063dSJacob Faibussowitsch   PetscCall(PetscLimiterSetUp(fvm->limiter));
1097dbbe0bcdSBarry Smith   PetscTryTypeMethod(fvm, setup);
1098c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1099c0ce001eSMatthew G. Knepley }
1100c0ce001eSMatthew G. Knepley 
1101c0ce001eSMatthew G. Knepley /*@
1102c0ce001eSMatthew G. Knepley   PetscFVDestroy - Destroys a PetscFV object
1103c0ce001eSMatthew G. Knepley 
1104c0ce001eSMatthew G. Knepley   Collective on fvm
1105c0ce001eSMatthew G. Knepley 
1106c0ce001eSMatthew G. Knepley   Input Parameter:
1107c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to destroy
1108c0ce001eSMatthew G. Knepley 
110988f5f89eSMatthew G. Knepley   Level: beginner
1110c0ce001eSMatthew G. Knepley 
1111db781477SPatrick Sanan .seealso: `PetscFVView()`
1112c0ce001eSMatthew G. Knepley @*/
1113*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVDestroy(PetscFV *fvm)
1114*d71ae5a4SJacob Faibussowitsch {
1115c0ce001eSMatthew G. Knepley   PetscInt i;
1116c0ce001eSMatthew G. Knepley 
1117c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1118c0ce001eSMatthew G. Knepley   if (!*fvm) PetscFunctionReturn(0);
1119c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific((*fvm), PETSCFV_CLASSID, 1);
1120c0ce001eSMatthew G. Knepley 
11219371c9d4SSatish Balay   if (--((PetscObject)(*fvm))->refct > 0) {
11229371c9d4SSatish Balay     *fvm = NULL;
11239371c9d4SSatish Balay     PetscFunctionReturn(0);
11249371c9d4SSatish Balay   }
1125c0ce001eSMatthew G. Knepley   ((PetscObject)(*fvm))->refct = 0;
1126c0ce001eSMatthew G. Knepley 
112748a46eb9SPierre Jolivet   for (i = 0; i < (*fvm)->numComponents; i++) PetscCall(PetscFree((*fvm)->componentNames[i]));
11289566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fvm)->componentNames));
11299566063dSJacob Faibussowitsch   PetscCall(PetscLimiterDestroy(&(*fvm)->limiter));
11309566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceDestroy(&(*fvm)->dualSpace));
11319566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fvm)->fluxWork));
11329566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureDestroy(&(*fvm)->quadrature));
11339566063dSJacob Faibussowitsch   PetscCall(PetscTabulationDestroy(&(*fvm)->T));
1134c0ce001eSMatthew G. Knepley 
1135dbbe0bcdSBarry Smith   PetscTryTypeMethod((*fvm), destroy);
11369566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(fvm));
1137c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1138c0ce001eSMatthew G. Knepley }
1139c0ce001eSMatthew G. Knepley 
1140c0ce001eSMatthew G. Knepley /*@
1141c0ce001eSMatthew G. Knepley   PetscFVCreate - Creates an empty PetscFV object. The type can then be set with PetscFVSetType().
1142c0ce001eSMatthew G. Knepley 
1143c0ce001eSMatthew G. Knepley   Collective
1144c0ce001eSMatthew G. Knepley 
1145c0ce001eSMatthew G. Knepley   Input Parameter:
1146c0ce001eSMatthew G. Knepley . comm - The communicator for the PetscFV object
1147c0ce001eSMatthew G. Knepley 
1148c0ce001eSMatthew G. Knepley   Output Parameter:
1149c0ce001eSMatthew G. Knepley . fvm - The PetscFV object
1150c0ce001eSMatthew G. Knepley 
1151c0ce001eSMatthew G. Knepley   Level: beginner
1152c0ce001eSMatthew G. Knepley 
1153db781477SPatrick Sanan .seealso: `PetscFVSetType()`, `PETSCFVUPWIND`
1154c0ce001eSMatthew G. Knepley @*/
1155*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVCreate(MPI_Comm comm, PetscFV *fvm)
1156*d71ae5a4SJacob Faibussowitsch {
1157c0ce001eSMatthew G. Knepley   PetscFV f;
1158c0ce001eSMatthew G. Knepley 
1159c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1160c0ce001eSMatthew G. Knepley   PetscValidPointer(fvm, 2);
1161c0ce001eSMatthew G. Knepley   *fvm = NULL;
11629566063dSJacob Faibussowitsch   PetscCall(PetscFVInitializePackage());
1163c0ce001eSMatthew G. Knepley 
11649566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(f, PETSCFV_CLASSID, "PetscFV", "Finite Volume", "PetscFV", comm, PetscFVDestroy, PetscFVView));
11659566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(f->ops, sizeof(struct _PetscFVOps)));
1166c0ce001eSMatthew G. Knepley 
11679566063dSJacob Faibussowitsch   PetscCall(PetscLimiterCreate(comm, &f->limiter));
1168c0ce001eSMatthew G. Knepley   f->numComponents    = 1;
1169c0ce001eSMatthew G. Knepley   f->dim              = 0;
1170c0ce001eSMatthew G. Knepley   f->computeGradients = PETSC_FALSE;
1171c0ce001eSMatthew G. Knepley   f->fluxWork         = NULL;
11729566063dSJacob Faibussowitsch   PetscCall(PetscCalloc1(f->numComponents, &f->componentNames));
1173c0ce001eSMatthew G. Knepley 
1174c0ce001eSMatthew G. Knepley   *fvm = f;
1175c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1176c0ce001eSMatthew G. Knepley }
1177c0ce001eSMatthew G. Knepley 
1178c0ce001eSMatthew G. Knepley /*@
1179c0ce001eSMatthew G. Knepley   PetscFVSetLimiter - Set the limiter object
1180c0ce001eSMatthew G. Knepley 
1181c0ce001eSMatthew G. Knepley   Logically collective on fvm
1182c0ce001eSMatthew G. Knepley 
1183c0ce001eSMatthew G. Knepley   Input Parameters:
1184c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1185c0ce001eSMatthew G. Knepley - lim - The PetscLimiter
1186c0ce001eSMatthew G. Knepley 
118788f5f89eSMatthew G. Knepley   Level: intermediate
1188c0ce001eSMatthew G. Knepley 
1189db781477SPatrick Sanan .seealso: `PetscFVGetLimiter()`
1190c0ce001eSMatthew G. Knepley @*/
1191*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetLimiter(PetscFV fvm, PetscLimiter lim)
1192*d71ae5a4SJacob Faibussowitsch {
1193c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1194c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1195c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 2);
11969566063dSJacob Faibussowitsch   PetscCall(PetscLimiterDestroy(&fvm->limiter));
11979566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)lim));
1198c0ce001eSMatthew G. Knepley   fvm->limiter = lim;
1199c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1200c0ce001eSMatthew G. Knepley }
1201c0ce001eSMatthew G. Knepley 
1202c0ce001eSMatthew G. Knepley /*@
1203c0ce001eSMatthew G. Knepley   PetscFVGetLimiter - Get the limiter object
1204c0ce001eSMatthew G. Knepley 
1205c0ce001eSMatthew G. Knepley   Not collective
1206c0ce001eSMatthew G. Knepley 
1207c0ce001eSMatthew G. Knepley   Input Parameter:
1208c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1209c0ce001eSMatthew G. Knepley 
1210c0ce001eSMatthew G. Knepley   Output Parameter:
1211c0ce001eSMatthew G. Knepley . lim - The PetscLimiter
1212c0ce001eSMatthew G. Knepley 
121388f5f89eSMatthew G. Knepley   Level: intermediate
1214c0ce001eSMatthew G. Knepley 
1215db781477SPatrick Sanan .seealso: `PetscFVSetLimiter()`
1216c0ce001eSMatthew G. Knepley @*/
1217*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetLimiter(PetscFV fvm, PetscLimiter *lim)
1218*d71ae5a4SJacob Faibussowitsch {
1219c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1220c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1221c0ce001eSMatthew G. Knepley   PetscValidPointer(lim, 2);
1222c0ce001eSMatthew G. Knepley   *lim = fvm->limiter;
1223c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1224c0ce001eSMatthew G. Knepley }
1225c0ce001eSMatthew G. Knepley 
1226c0ce001eSMatthew G. Knepley /*@
1227c0ce001eSMatthew G. Knepley   PetscFVSetNumComponents - Set the number of field components
1228c0ce001eSMatthew G. Knepley 
1229c0ce001eSMatthew G. Knepley   Logically collective on fvm
1230c0ce001eSMatthew G. Knepley 
1231c0ce001eSMatthew G. Knepley   Input Parameters:
1232c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1233c0ce001eSMatthew G. Knepley - comp - The number of components
1234c0ce001eSMatthew G. Knepley 
123588f5f89eSMatthew G. Knepley   Level: intermediate
1236c0ce001eSMatthew G. Knepley 
1237db781477SPatrick Sanan .seealso: `PetscFVGetNumComponents()`
1238c0ce001eSMatthew G. Knepley @*/
1239*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetNumComponents(PetscFV fvm, PetscInt comp)
1240*d71ae5a4SJacob Faibussowitsch {
1241c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1242c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1243c0ce001eSMatthew G. Knepley   if (fvm->numComponents != comp) {
1244c0ce001eSMatthew G. Knepley     PetscInt i;
1245c0ce001eSMatthew G. Knepley 
124648a46eb9SPierre Jolivet     for (i = 0; i < fvm->numComponents; i++) PetscCall(PetscFree(fvm->componentNames[i]));
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 @*/
1271*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetNumComponents(PetscFV fvm, PetscInt *comp)
1272*d71ae5a4SJacob Faibussowitsch {
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 @*/
1293*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetComponentName(PetscFV fvm, PetscInt comp, const char *name)
1294*d71ae5a4SJacob Faibussowitsch {
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 @*/
1316*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetComponentName(PetscFV fvm, PetscInt comp, const char **name)
1317*d71ae5a4SJacob Faibussowitsch {
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 @*/
1336*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetSpatialDimension(PetscFV fvm, PetscInt dim)
1337*d71ae5a4SJacob Faibussowitsch {
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 @*/
1359*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetSpatialDimension(PetscFV fvm, PetscInt *dim)
1360*d71ae5a4SJacob Faibussowitsch {
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 @*/
1381*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetComputeGradients(PetscFV fvm, PetscBool computeGradients)
1382*d71ae5a4SJacob Faibussowitsch {
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 @*/
1404*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetComputeGradients(PetscFV fvm, PetscBool *computeGradients)
1405*d71ae5a4SJacob Faibussowitsch {
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 @*/
1426*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetQuadrature(PetscFV fvm, PetscQuadrature q)
1427*d71ae5a4SJacob Faibussowitsch {
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 @*/
1451*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetQuadrature(PetscFV fvm, PetscQuadrature *q)
1452*d71ae5a4SJacob Faibussowitsch {
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 @*/
1487*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetDualSpace(PetscFV fvm, PetscDualSpace *sp)
1488*d71ae5a4SJacob Faibussowitsch {
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 @*/
1539*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetDualSpace(PetscFV fvm, PetscDualSpace sp)
1540*d71ae5a4SJacob Faibussowitsch {
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 @*/
1570*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetCellTabulation(PetscFV fvm, PetscTabulation *T)
1571*d71ae5a4SJacob Faibussowitsch {
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 @*/
1608*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVCreateTabulation(PetscFV fvm, PetscInt nrepl, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation *T)
1609*d71ae5a4SJacob Faibussowitsch {
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));
163348a46eb9SPierre Jolivet   for (k = 0; k <= (*T)->K; ++k) PetscCall(PetscMalloc1(nrepl * npoints * pdim * Nc * PetscPowInt(cdim, k), &(*T)->T[k]));
16349371c9d4SSatish Balay   if (K >= 0) {
16359371c9d4SSatish Balay     for (p = 0; p < nrepl * npoints; ++p)
16369371c9d4SSatish Balay       for (d = 0; d < pdim; ++d)
16379371c9d4SSatish Balay         for (c = 0; c < Nc; ++c) (*T)->T[0][(p * pdim + d) * Nc + c] = 1.0;
1638ef0bb6c7SMatthew G. Knepley   }
16399371c9d4SSatish Balay   if (K >= 1) {
16409371c9d4SSatish Balay     for (p = 0; p < nrepl * npoints; ++p)
16419371c9d4SSatish Balay       for (d = 0; d < pdim; ++d)
16429371c9d4SSatish Balay         for (c = 0; c < Nc; ++c)
16439371c9d4SSatish Balay           for (e = 0; e < cdim; ++e) (*T)->T[1][((p * pdim + d) * Nc + c) * cdim + e] = 0.0;
16449371c9d4SSatish Balay   }
16459371c9d4SSatish Balay   if (K >= 2) {
16469371c9d4SSatish Balay     for (p = 0; p < nrepl * npoints; ++p)
16479371c9d4SSatish Balay       for (d = 0; d < pdim; ++d)
16489371c9d4SSatish Balay         for (c = 0; c < Nc; ++c)
16499371c9d4SSatish Balay           for (e = 0; e < cdim * cdim; ++e) (*T)->T[2][((p * pdim + d) * Nc + c) * cdim * cdim + e] = 0.0;
16509371c9d4SSatish Balay   }
1651c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1652c0ce001eSMatthew G. Knepley }
1653c0ce001eSMatthew G. Knepley 
1654c0ce001eSMatthew G. Knepley /*@C
1655c0ce001eSMatthew G. Knepley   PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell
1656c0ce001eSMatthew G. Knepley 
1657c0ce001eSMatthew G. Knepley   Input Parameters:
1658c0ce001eSMatthew G. Knepley + fvm      - The PetscFV object
1659c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained
1660c0ce001eSMatthew G. Knepley - dx       - The vector from the cell centroid to the neighboring cell centroid for each face
1661c0ce001eSMatthew G. Knepley 
166288f5f89eSMatthew G. Knepley   Level: advanced
1663c0ce001eSMatthew G. Knepley 
1664db781477SPatrick Sanan .seealso: `PetscFVCreate()`
1665c0ce001eSMatthew G. Knepley @*/
1666*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVComputeGradient(PetscFV fvm, PetscInt numFaces, PetscScalar dx[], PetscScalar grad[])
1667*d71ae5a4SJacob Faibussowitsch {
1668c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1669c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1670dbbe0bcdSBarry Smith   PetscTryTypeMethod(fvm, computegradient, numFaces, dx, grad);
1671c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1672c0ce001eSMatthew G. Knepley }
1673c0ce001eSMatthew G. Knepley 
167488f5f89eSMatthew G. Knepley /*@C
1675c0ce001eSMatthew G. Knepley   PetscFVIntegrateRHSFunction - Produce the cell residual vector for a chunk of elements by quadrature integration
1676c0ce001eSMatthew G. Knepley 
1677c0ce001eSMatthew G. Knepley   Not collective
1678c0ce001eSMatthew G. Knepley 
1679c0ce001eSMatthew G. Knepley   Input Parameters:
1680c0ce001eSMatthew G. Knepley + fvm          - The PetscFV object for the field being integrated
1681c0ce001eSMatthew G. Knepley . prob         - The PetscDS specifing the discretizations and continuum functions
1682c0ce001eSMatthew G. Knepley . field        - The field being integrated
1683c0ce001eSMatthew G. Knepley . Nf           - The number of faces in the chunk
1684c0ce001eSMatthew G. Knepley . fgeom        - The face geometry for each face in the chunk
1685c0ce001eSMatthew G. Knepley . neighborVol  - The volume for each pair of cells in the chunk
1686c0ce001eSMatthew G. Knepley . uL           - The state from the cell on the left
1687c0ce001eSMatthew G. Knepley - uR           - The state from the cell on the right
1688c0ce001eSMatthew G. Knepley 
1689d8d19677SJose E. Roman   Output Parameters:
1690c0ce001eSMatthew G. Knepley + fluxL        - the left fluxes for each face
1691c0ce001eSMatthew G. Knepley - fluxR        - the right fluxes for each face
169288f5f89eSMatthew G. Knepley 
169388f5f89eSMatthew G. Knepley   Level: developer
169488f5f89eSMatthew G. Knepley 
1695db781477SPatrick Sanan .seealso: `PetscFVCreate()`
169688f5f89eSMatthew G. Knepley @*/
1697*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVIntegrateRHSFunction(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[])
1698*d71ae5a4SJacob Faibussowitsch {
1699c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1700c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1701dbbe0bcdSBarry Smith   PetscTryTypeMethod(fvm, integraterhsfunction, prob, field, Nf, fgeom, neighborVol, uL, uR, fluxL, fluxR);
1702c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1703c0ce001eSMatthew G. Knepley }
1704c0ce001eSMatthew G. Knepley 
1705c0ce001eSMatthew G. Knepley /*@
1706c0ce001eSMatthew G. Knepley   PetscFVRefine - Create a "refined" PetscFV object that refines the reference cell into smaller copies. This is typically used
1707c0ce001eSMatthew 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
1708c0ce001eSMatthew G. Knepley   sparsity). It is also used to create an interpolation between regularly refined meshes.
1709c0ce001eSMatthew G. Knepley 
1710c0ce001eSMatthew G. Knepley   Input Parameter:
1711c0ce001eSMatthew G. Knepley . fv - The initial PetscFV
1712c0ce001eSMatthew G. Knepley 
1713c0ce001eSMatthew G. Knepley   Output Parameter:
1714c0ce001eSMatthew G. Knepley . fvRef - The refined PetscFV
1715c0ce001eSMatthew G. Knepley 
171688f5f89eSMatthew G. Knepley   Level: advanced
1717c0ce001eSMatthew G. Knepley 
1718db781477SPatrick Sanan .seealso: `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()`
1719c0ce001eSMatthew G. Knepley @*/
1720*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVRefine(PetscFV fv, PetscFV *fvRef)
1721*d71ae5a4SJacob Faibussowitsch {
1722c0ce001eSMatthew G. Knepley   PetscDualSpace  Q, Qref;
1723c0ce001eSMatthew G. Knepley   DM              K, Kref;
1724c0ce001eSMatthew G. Knepley   PetscQuadrature q, qref;
1725412e9a14SMatthew G. Knepley   DMPolytopeType  ct;
1726012bc364SMatthew G. Knepley   DMPlexTransform tr;
1727c0ce001eSMatthew G. Knepley   PetscReal      *v0;
1728c0ce001eSMatthew G. Knepley   PetscReal      *jac, *invjac;
1729c0ce001eSMatthew G. Knepley   PetscInt        numComp, numSubelements, s;
1730c0ce001eSMatthew G. Knepley 
1731c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
17329566063dSJacob Faibussowitsch   PetscCall(PetscFVGetDualSpace(fv, &Q));
17339566063dSJacob Faibussowitsch   PetscCall(PetscFVGetQuadrature(fv, &q));
17349566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceGetDM(Q, &K));
1735c0ce001eSMatthew G. Knepley   /* Create dual space */
17369566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceDuplicate(Q, &Qref));
17379566063dSJacob Faibussowitsch   PetscCall(DMRefine(K, PetscObjectComm((PetscObject)fv), &Kref));
17389566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceSetDM(Qref, Kref));
17399566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&Kref));
17409566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceSetUp(Qref));
1741c0ce001eSMatthew G. Knepley   /* Create volume */
17429566063dSJacob Faibussowitsch   PetscCall(PetscFVCreate(PetscObjectComm((PetscObject)fv), fvRef));
17439566063dSJacob Faibussowitsch   PetscCall(PetscFVSetDualSpace(*fvRef, Qref));
17449566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fv, &numComp));
17459566063dSJacob Faibussowitsch   PetscCall(PetscFVSetNumComponents(*fvRef, numComp));
17469566063dSJacob Faibussowitsch   PetscCall(PetscFVSetUp(*fvRef));
1747c0ce001eSMatthew G. Knepley   /* Create quadrature */
17489566063dSJacob Faibussowitsch   PetscCall(DMPlexGetCellType(K, 0, &ct));
17499566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformCreate(PETSC_COMM_SELF, &tr));
17509566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR));
17519566063dSJacob Faibussowitsch   PetscCall(DMPlexRefineRegularGetAffineTransforms(tr, ct, &numSubelements, &v0, &jac, &invjac));
17529566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref));
17539566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceSimpleSetDimension(Qref, numSubelements));
1754c0ce001eSMatthew G. Knepley   for (s = 0; s < numSubelements; ++s) {
1755c0ce001eSMatthew G. Knepley     PetscQuadrature  qs;
1756c0ce001eSMatthew G. Knepley     const PetscReal *points, *weights;
1757c0ce001eSMatthew G. Knepley     PetscReal       *p, *w;
1758c0ce001eSMatthew G. Knepley     PetscInt         dim, Nc, npoints, np;
1759c0ce001eSMatthew G. Knepley 
17609566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qs));
17619566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureGetData(q, &dim, &Nc, &npoints, &points, &weights));
1762c0ce001eSMatthew G. Knepley     np = npoints / numSubelements;
17639566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(np * dim, &p));
17649566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(np * Nc, &w));
17659566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(p, &points[s * np * dim], np * dim));
17669566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(w, &weights[s * np * Nc], np * Nc));
17679566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureSetData(qs, dim, Nc, np, p, w));
17689566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSimpleSetFunctional(Qref, s, qs));
17699566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureDestroy(&qs));
1770c0ce001eSMatthew G. Knepley   }
17719566063dSJacob Faibussowitsch   PetscCall(PetscFVSetQuadrature(*fvRef, qref));
17729566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformDestroy(&tr));
17739566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureDestroy(&qref));
17749566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceDestroy(&Qref));
1775c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1776c0ce001eSMatthew G. Knepley }
1777c0ce001eSMatthew G. Knepley 
1778*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVDestroy_Upwind(PetscFV fvm)
1779*d71ae5a4SJacob Faibussowitsch {
1780c0ce001eSMatthew G. Knepley   PetscFV_Upwind *b = (PetscFV_Upwind *)fvm->data;
1781c0ce001eSMatthew G. Knepley 
1782c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
17839566063dSJacob Faibussowitsch   PetscCall(PetscFree(b));
1784c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1785c0ce001eSMatthew G. Knepley }
1786c0ce001eSMatthew G. Knepley 
1787*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_Upwind_Ascii(PetscFV fv, PetscViewer viewer)
1788*d71ae5a4SJacob Faibussowitsch {
1789c0ce001eSMatthew G. Knepley   PetscInt          Nc, c;
1790c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
1791c0ce001eSMatthew G. Knepley 
1792c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
17939566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fv, &Nc));
17949566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
17959566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Upwind Finite Volume:\n"));
179663a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  num components: %" PetscInt_FMT "\n", Nc));
1797c0ce001eSMatthew G. Knepley   for (c = 0; c < Nc; c++) {
179848a46eb9SPierre Jolivet     if (fv->componentNames[c]) PetscCall(PetscViewerASCIIPrintf(viewer, "    component %" PetscInt_FMT ": %s\n", c, fv->componentNames[c]));
1799c0ce001eSMatthew G. Knepley   }
1800c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1801c0ce001eSMatthew G. Knepley }
1802c0ce001eSMatthew G. Knepley 
1803*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_Upwind(PetscFV fv, PetscViewer viewer)
1804*d71ae5a4SJacob Faibussowitsch {
1805c0ce001eSMatthew G. Knepley   PetscBool iascii;
1806c0ce001eSMatthew G. Knepley 
1807c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1808c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1);
1809c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
18109566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
18119566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscFVView_Upwind_Ascii(fv, viewer));
1812c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1813c0ce001eSMatthew G. Knepley }
1814c0ce001eSMatthew G. Knepley 
1815*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVSetUp_Upwind(PetscFV fvm)
1816*d71ae5a4SJacob Faibussowitsch {
1817c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1818c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1819c0ce001eSMatthew G. Knepley }
1820c0ce001eSMatthew G. Knepley 
1821c0ce001eSMatthew G. Knepley /*
1822c0ce001eSMatthew G. Knepley   neighborVol[f*2+0] contains the left  geom
1823c0ce001eSMatthew G. Knepley   neighborVol[f*2+1] contains the right geom
1824c0ce001eSMatthew G. Knepley */
1825*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVIntegrateRHSFunction_Upwind(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[])
1826*d71ae5a4SJacob Faibussowitsch {
1827c0ce001eSMatthew G. Knepley   void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *);
1828c0ce001eSMatthew G. Knepley   void              *rctx;
1829c0ce001eSMatthew G. Knepley   PetscScalar       *flux = fvm->fluxWork;
1830c0ce001eSMatthew G. Knepley   const PetscScalar *constants;
1831c0ce001eSMatthew G. Knepley   PetscInt           dim, numConstants, pdim, totDim, Nc, off, f, d;
1832c0ce001eSMatthew G. Knepley 
1833c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
18349566063dSJacob Faibussowitsch   PetscCall(PetscDSGetTotalComponents(prob, &Nc));
18359566063dSJacob Faibussowitsch   PetscCall(PetscDSGetTotalDimension(prob, &totDim));
18369566063dSJacob Faibussowitsch   PetscCall(PetscDSGetFieldOffset(prob, field, &off));
18379566063dSJacob Faibussowitsch   PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann));
18389566063dSJacob Faibussowitsch   PetscCall(PetscDSGetContext(prob, field, &rctx));
18399566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &numConstants, &constants));
18409566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
18419566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fvm, &pdim));
1842c0ce001eSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
1843c0ce001eSMatthew G. Knepley     (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f * Nc], &uR[f * Nc], numConstants, constants, flux, rctx);
1844c0ce001eSMatthew G. Knepley     for (d = 0; d < pdim; ++d) {
1845c0ce001eSMatthew G. Knepley       fluxL[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 0];
1846c0ce001eSMatthew G. Knepley       fluxR[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 1];
1847c0ce001eSMatthew G. Knepley     }
1848c0ce001eSMatthew G. Knepley   }
1849c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1850c0ce001eSMatthew G. Knepley }
1851c0ce001eSMatthew G. Knepley 
1852*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVInitialize_Upwind(PetscFV fvm)
1853*d71ae5a4SJacob Faibussowitsch {
1854c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1855c0ce001eSMatthew G. Knepley   fvm->ops->setfromoptions       = NULL;
1856c0ce001eSMatthew G. Knepley   fvm->ops->setup                = PetscFVSetUp_Upwind;
1857c0ce001eSMatthew G. Knepley   fvm->ops->view                 = PetscFVView_Upwind;
1858c0ce001eSMatthew G. Knepley   fvm->ops->destroy              = PetscFVDestroy_Upwind;
1859c0ce001eSMatthew G. Knepley   fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_Upwind;
1860c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1861c0ce001eSMatthew G. Knepley }
1862c0ce001eSMatthew G. Knepley 
1863c0ce001eSMatthew G. Knepley /*MC
1864c0ce001eSMatthew G. Knepley   PETSCFVUPWIND = "upwind" - A PetscFV object
1865c0ce001eSMatthew G. Knepley 
1866c0ce001eSMatthew G. Knepley   Level: intermediate
1867c0ce001eSMatthew G. Knepley 
1868db781477SPatrick Sanan .seealso: `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()`
1869c0ce001eSMatthew G. Knepley M*/
1870c0ce001eSMatthew G. Knepley 
1871*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscFVCreate_Upwind(PetscFV fvm)
1872*d71ae5a4SJacob Faibussowitsch {
1873c0ce001eSMatthew G. Knepley   PetscFV_Upwind *b;
1874c0ce001eSMatthew G. Knepley 
1875c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1876c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
18774dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
1878c0ce001eSMatthew G. Knepley   fvm->data = b;
1879c0ce001eSMatthew G. Knepley 
18809566063dSJacob Faibussowitsch   PetscCall(PetscFVInitialize_Upwind(fvm));
1881c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1882c0ce001eSMatthew G. Knepley }
1883c0ce001eSMatthew G. Knepley 
1884c0ce001eSMatthew G. Knepley #include <petscblaslapack.h>
1885c0ce001eSMatthew G. Knepley 
1886*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVDestroy_LeastSquares(PetscFV fvm)
1887*d71ae5a4SJacob Faibussowitsch {
1888c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data;
1889c0ce001eSMatthew G. Knepley 
1890c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
18919566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)fvm, "PetscFVLeastSquaresSetMaxFaces_C", NULL));
18929566063dSJacob Faibussowitsch   PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work));
18939566063dSJacob Faibussowitsch   PetscCall(PetscFree(ls));
1894c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1895c0ce001eSMatthew G. Knepley }
1896c0ce001eSMatthew G. Knepley 
1897*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_LeastSquares_Ascii(PetscFV fv, PetscViewer viewer)
1898*d71ae5a4SJacob Faibussowitsch {
1899c0ce001eSMatthew G. Knepley   PetscInt          Nc, c;
1900c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
1901c0ce001eSMatthew G. Knepley 
1902c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
19039566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fv, &Nc));
19049566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
19059566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Finite Volume with Least Squares Reconstruction:\n"));
190663a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  num components: %" PetscInt_FMT "\n", Nc));
1907c0ce001eSMatthew G. Knepley   for (c = 0; c < Nc; c++) {
190848a46eb9SPierre Jolivet     if (fv->componentNames[c]) PetscCall(PetscViewerASCIIPrintf(viewer, "    component %" PetscInt_FMT ": %s\n", c, fv->componentNames[c]));
1909c0ce001eSMatthew G. Knepley   }
1910c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1911c0ce001eSMatthew G. Knepley }
1912c0ce001eSMatthew G. Knepley 
1913*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_LeastSquares(PetscFV fv, PetscViewer viewer)
1914*d71ae5a4SJacob Faibussowitsch {
1915c0ce001eSMatthew G. Knepley   PetscBool iascii;
1916c0ce001eSMatthew G. Knepley 
1917c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1918c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1);
1919c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
19209566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
19219566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscFVView_LeastSquares_Ascii(fv, viewer));
1922c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1923c0ce001eSMatthew G. Knepley }
1924c0ce001eSMatthew G. Knepley 
1925*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVSetUp_LeastSquares(PetscFV fvm)
1926*d71ae5a4SJacob Faibussowitsch {
1927c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1928c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1929c0ce001eSMatthew G. Knepley }
1930c0ce001eSMatthew G. Knepley 
1931c0ce001eSMatthew G. Knepley /* Overwrites A. Can only handle full-rank problems with m>=n */
1932*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresPseudoInverse_Static(PetscInt m, PetscInt mstride, PetscInt n, PetscScalar *A, PetscScalar *Ainv, PetscScalar *tau, PetscInt worksize, PetscScalar *work)
1933*d71ae5a4SJacob Faibussowitsch {
1934c0ce001eSMatthew G. Knepley   PetscBool    debug = PETSC_FALSE;
1935c0ce001eSMatthew G. Knepley   PetscBLASInt M, N, K, lda, ldb, ldwork, info;
1936c0ce001eSMatthew G. Knepley   PetscScalar *R, *Q, *Aback, Alpha;
1937c0ce001eSMatthew G. Knepley 
1938c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1939c0ce001eSMatthew G. Knepley   if (debug) {
19409566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m * n, &Aback));
19419566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(Aback, A, m * n));
1942c0ce001eSMatthew G. Knepley   }
1943c0ce001eSMatthew G. Knepley 
19449566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m, &M));
19459566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n, &N));
19469566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(mstride, &lda));
19479566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(worksize, &ldwork));
19489566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
1949792fecdfSBarry Smith   PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&M, &N, A, &lda, tau, work, &ldwork, &info));
19509566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
195128b400f6SJacob Faibussowitsch   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xGEQRF error");
1952c0ce001eSMatthew G. Knepley   R = A; /* Upper triangular part of A now contains R, the rest contains the elementary reflectors */
1953c0ce001eSMatthew G. Knepley 
1954c0ce001eSMatthew G. Knepley   /* Extract an explicit representation of Q */
1955c0ce001eSMatthew G. Knepley   Q = Ainv;
19569566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(Q, A, mstride * n));
1957c0ce001eSMatthew G. Knepley   K = N; /* full rank */
1958792fecdfSBarry Smith   PetscCallBLAS("LAPACKorgqr", LAPACKorgqr_(&M, &N, &K, Q, &lda, tau, work, &ldwork, &info));
195928b400f6SJacob Faibussowitsch   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xORGQR/xUNGQR error");
1960c0ce001eSMatthew G. Knepley 
1961c0ce001eSMatthew G. Knepley   /* Compute A^{-T} = (R^{-1} Q^T)^T = Q R^{-T} */
1962c0ce001eSMatthew G. Knepley   Alpha = 1.0;
1963c0ce001eSMatthew G. Knepley   ldb   = lda;
1964c0ce001eSMatthew G. Knepley   BLAStrsm_("Right", "Upper", "ConjugateTranspose", "NotUnitTriangular", &M, &N, &Alpha, R, &lda, Q, &ldb);
1965c0ce001eSMatthew G. Knepley   /* Ainv is Q, overwritten with inverse */
1966c0ce001eSMatthew G. Knepley 
1967c0ce001eSMatthew G. Knepley   if (debug) { /* Check that pseudo-inverse worked */
1968c0ce001eSMatthew G. Knepley     PetscScalar  Beta = 0.0;
1969c0ce001eSMatthew G. Knepley     PetscBLASInt ldc;
1970c0ce001eSMatthew G. Knepley     K   = N;
1971c0ce001eSMatthew G. Knepley     ldc = N;
1972c0ce001eSMatthew G. Knepley     BLASgemm_("ConjugateTranspose", "Normal", &N, &K, &M, &Alpha, Ainv, &lda, Aback, &ldb, &Beta, work, &ldc);
19739566063dSJacob Faibussowitsch     PetscCall(PetscScalarView(n * n, work, PETSC_VIEWER_STDOUT_SELF));
19749566063dSJacob Faibussowitsch     PetscCall(PetscFree(Aback));
1975c0ce001eSMatthew G. Knepley   }
1976c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1977c0ce001eSMatthew G. Knepley }
1978c0ce001eSMatthew G. Knepley 
1979c0ce001eSMatthew G. Knepley /* Overwrites A. Can handle degenerate problems and m<n. */
1980*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresPseudoInverseSVD_Static(PetscInt m, PetscInt mstride, PetscInt n, PetscScalar *A, PetscScalar *Ainv, PetscScalar *tau, PetscInt worksize, PetscScalar *work)
1981*d71ae5a4SJacob Faibussowitsch {
19826bb27163SBarry Smith   PetscScalar *Brhs;
1983c0ce001eSMatthew G. Knepley   PetscScalar *tmpwork;
1984c0ce001eSMatthew G. Knepley   PetscReal    rcond;
1985c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX)
1986c0ce001eSMatthew G. Knepley   PetscInt   rworkSize;
1987c0ce001eSMatthew G. Knepley   PetscReal *rwork;
1988c0ce001eSMatthew G. Knepley #endif
1989c0ce001eSMatthew G. Knepley   PetscInt     i, j, maxmn;
1990c0ce001eSMatthew G. Knepley   PetscBLASInt M, N, lda, ldb, ldwork;
1991c0ce001eSMatthew G. Knepley   PetscBLASInt nrhs, irank, info;
1992c0ce001eSMatthew G. Knepley 
1993c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
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;
2008c0ce001eSMatthew G. Knepley   nrhs  = M;
2009c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX)
2010c0ce001eSMatthew G. Knepley   rworkSize = 5 * PetscMin(M, N);
20119566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(rworkSize, &rwork));
20126bb27163SBarry Smith   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
2013792fecdfSBarry 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;
20186bb27163SBarry Smith   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
2019792fecdfSBarry Smith   PetscCallBLAS("LAPACKgelss", LAPACKgelss_(&M, &N, &nrhs, A, &lda, Brhs, &ldb, (PetscReal *)tau, &rcond, &irank, tmpwork, &ldwork, &info));
20209566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
2021c0ce001eSMatthew G. Knepley #endif
202228b400f6SJacob Faibussowitsch   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xGELSS error");
2023c0ce001eSMatthew G. Knepley   /* The following check should be turned into a diagnostic as soon as someone wants to do this intentionally */
202408401ef6SPierre 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");
2025c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2026c0ce001eSMatthew G. Knepley }
2027c0ce001eSMatthew G. Knepley 
2028c0ce001eSMatthew G. Knepley #if 0
2029c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresDebugCell_Static(PetscFV fvm, PetscInt cell, DM dm, DM dmFace, PetscScalar *fgeom, DM dmCell, PetscScalar *cgeom)
2030c0ce001eSMatthew G. Knepley {
2031c0ce001eSMatthew G. Knepley   PetscReal       grad[2] = {0, 0};
2032c0ce001eSMatthew G. Knepley   const PetscInt *faces;
2033c0ce001eSMatthew G. Knepley   PetscInt        numFaces, f;
2034c0ce001eSMatthew G. Knepley 
2035c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
20369566063dSJacob Faibussowitsch   PetscCall(DMPlexGetConeSize(dm, cell, &numFaces));
20379566063dSJacob Faibussowitsch   PetscCall(DMPlexGetCone(dm, cell, &faces));
2038c0ce001eSMatthew G. Knepley   for (f = 0; f < numFaces; ++f) {
2039c0ce001eSMatthew G. Knepley     const PetscInt *fcells;
2040c0ce001eSMatthew G. Knepley     const CellGeom *cg1;
2041c0ce001eSMatthew G. Knepley     const FaceGeom *fg;
2042c0ce001eSMatthew G. Knepley 
20439566063dSJacob Faibussowitsch     PetscCall(DMPlexGetSupport(dm, faces[f], &fcells));
20449566063dSJacob Faibussowitsch     PetscCall(DMPlexPointLocalRead(dmFace, faces[f], fgeom, &fg));
2045c0ce001eSMatthew G. Knepley     for (i = 0; i < 2; ++i) {
2046c0ce001eSMatthew G. Knepley       PetscScalar du;
2047c0ce001eSMatthew G. Knepley 
2048c0ce001eSMatthew G. Knepley       if (fcells[i] == c) continue;
20499566063dSJacob Faibussowitsch       PetscCall(DMPlexPointLocalRead(dmCell, fcells[i], cgeom, &cg1));
2050c0ce001eSMatthew G. Knepley       du   = cg1->centroid[0] + 3*cg1->centroid[1] - (cg->centroid[0] + 3*cg->centroid[1]);
2051c0ce001eSMatthew G. Knepley       grad[0] += fg->grad[!i][0] * du;
2052c0ce001eSMatthew G. Knepley       grad[1] += fg->grad[!i][1] * du;
2053c0ce001eSMatthew G. Knepley     }
2054c0ce001eSMatthew G. Knepley   }
20559566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_SELF, "cell[%d] grad (%g, %g)\n", cell, grad[0], grad[1]));
2056c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2057c0ce001eSMatthew G. Knepley }
2058c0ce001eSMatthew G. Knepley #endif
2059c0ce001eSMatthew G. Knepley 
2060c0ce001eSMatthew G. Knepley /*
2061c0ce001eSMatthew G. Knepley   PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell
2062c0ce001eSMatthew G. Knepley 
2063c0ce001eSMatthew G. Knepley   Input Parameters:
2064c0ce001eSMatthew G. Knepley + fvm      - The PetscFV object
2065c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained
2066c0ce001eSMatthew G. Knepley . dx       - The vector from the cell centroid to the neighboring cell centroid for each face
2067c0ce001eSMatthew G. Knepley 
2068c0ce001eSMatthew G. Knepley   Level: developer
2069c0ce001eSMatthew G. Knepley 
2070db781477SPatrick Sanan .seealso: `PetscFVCreate()`
2071c0ce001eSMatthew G. Knepley */
2072*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVComputeGradient_LeastSquares(PetscFV fvm, PetscInt numFaces, const PetscScalar dx[], PetscScalar grad[])
2073*d71ae5a4SJacob Faibussowitsch {
2074c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls       = (PetscFV_LeastSquares *)fvm->data;
2075c0ce001eSMatthew G. Knepley   const PetscBool       useSVD   = PETSC_TRUE;
2076c0ce001eSMatthew G. Knepley   const PetscInt        maxFaces = ls->maxFaces;
2077c0ce001eSMatthew G. Knepley   PetscInt              dim, f, d;
2078c0ce001eSMatthew G. Knepley 
2079c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2080c0ce001eSMatthew G. Knepley   if (numFaces > maxFaces) {
208108401ef6SPierre Jolivet     PetscCheck(maxFaces >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Reconstruction has not been initialized, call PetscFVLeastSquaresSetMaxFaces()");
208263a3b9bcSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of input faces %" PetscInt_FMT " > %" PetscInt_FMT " maxfaces", numFaces, maxFaces);
2083c0ce001eSMatthew G. Knepley   }
20849566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
2085c0ce001eSMatthew G. Knepley   for (f = 0; f < numFaces; ++f) {
2086c0ce001eSMatthew G. Knepley     for (d = 0; d < dim; ++d) ls->B[d * maxFaces + f] = dx[f * dim + d];
2087c0ce001eSMatthew G. Knepley   }
2088c0ce001eSMatthew G. Knepley   /* Overwrites B with garbage, returns Binv in row-major format */
2089736d4f42SpierreXVI   if (useSVD) {
2090736d4f42SpierreXVI     PetscInt maxmn = PetscMax(numFaces, dim);
20919566063dSJacob Faibussowitsch     PetscCall(PetscFVLeastSquaresPseudoInverseSVD_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work));
2092736d4f42SpierreXVI     /* Binv shaped in column-major, coldim=maxmn.*/
2093736d4f42SpierreXVI     for (f = 0; f < numFaces; ++f) {
2094736d4f42SpierreXVI       for (d = 0; d < dim; ++d) grad[f * dim + d] = ls->Binv[d + maxmn * f];
2095736d4f42SpierreXVI     }
2096736d4f42SpierreXVI   } else {
20979566063dSJacob Faibussowitsch     PetscCall(PetscFVLeastSquaresPseudoInverse_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work));
2098736d4f42SpierreXVI     /* Binv shaped in row-major, rowdim=maxFaces.*/
2099c0ce001eSMatthew G. Knepley     for (f = 0; f < numFaces; ++f) {
2100c0ce001eSMatthew G. Knepley       for (d = 0; d < dim; ++d) grad[f * dim + d] = ls->Binv[d * maxFaces + f];
2101c0ce001eSMatthew G. Knepley     }
2102736d4f42SpierreXVI   }
2103c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2104c0ce001eSMatthew G. Knepley }
2105c0ce001eSMatthew G. Knepley 
2106c0ce001eSMatthew G. Knepley /*
2107c0ce001eSMatthew G. Knepley   neighborVol[f*2+0] contains the left  geom
2108c0ce001eSMatthew G. Knepley   neighborVol[f*2+1] contains the right geom
2109c0ce001eSMatthew G. Knepley */
2110*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVIntegrateRHSFunction_LeastSquares(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[])
2111*d71ae5a4SJacob Faibussowitsch {
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 
2137*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresSetMaxFaces_LS(PetscFV fvm, PetscInt maxFaces)
2138*d71ae5a4SJacob Faibussowitsch {
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 
2157*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVInitialize_LeastSquares(PetscFV fvm)
2158*d71ae5a4SJacob Faibussowitsch {
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 
2177*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscFVCreate_LeastSquares(PetscFV fvm)
2178*d71ae5a4SJacob Faibussowitsch {
2179c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls;
2180c0ce001eSMatthew G. Knepley 
2181c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2182c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
21834dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&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 @*/
2212*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVLeastSquaresSetMaxFaces(PetscFV fvm, PetscInt maxFaces)
2213*d71ae5a4SJacob Faibussowitsch {
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