xref: /petsc/src/dm/dt/fv/interface/fv.c (revision 4dfa11a44d5adf2389f1d3acbc8f3c1116dc6c3a)
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 @*/
519371c9d4SSatish Balay PetscErrorCode PetscLimiterRegister(const char sname[], PetscErrorCode (*function)(PetscLimiter)) {
52c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
539566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscLimiterList, sname, function));
54c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
55c0ce001eSMatthew G. Knepley }
56c0ce001eSMatthew G. Knepley 
57c0ce001eSMatthew G. Knepley /*@C
58c0ce001eSMatthew G. Knepley   PetscLimiterSetType - Builds a particular PetscLimiter
59c0ce001eSMatthew G. Knepley 
60c0ce001eSMatthew G. Knepley   Collective on lim
61c0ce001eSMatthew G. Knepley 
62c0ce001eSMatthew G. Knepley   Input Parameters:
63c0ce001eSMatthew G. Knepley + lim  - The PetscLimiter object
64c0ce001eSMatthew G. Knepley - name - The kind of limiter
65c0ce001eSMatthew G. Knepley 
66c0ce001eSMatthew G. Knepley   Options Database Key:
67c0ce001eSMatthew G. Knepley . -petsclimiter_type <type> - Sets the PetscLimiter type; use -help for a list of available types
68c0ce001eSMatthew G. Knepley 
69c0ce001eSMatthew G. Knepley   Level: intermediate
70c0ce001eSMatthew G. Knepley 
71db781477SPatrick Sanan .seealso: `PetscLimiterGetType()`, `PetscLimiterCreate()`
72c0ce001eSMatthew G. Knepley @*/
739371c9d4SSatish Balay PetscErrorCode PetscLimiterSetType(PetscLimiter lim, PetscLimiterType name) {
74c0ce001eSMatthew G. Knepley   PetscErrorCode (*r)(PetscLimiter);
75c0ce001eSMatthew G. Knepley   PetscBool match;
76c0ce001eSMatthew G. Knepley 
77c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
78c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
799566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)lim, name, &match));
80c0ce001eSMatthew G. Knepley   if (match) PetscFunctionReturn(0);
81c0ce001eSMatthew G. Knepley 
829566063dSJacob Faibussowitsch   PetscCall(PetscLimiterRegisterAll());
839566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscLimiterList, name, &r));
8428b400f6SJacob Faibussowitsch   PetscCheck(r, PetscObjectComm((PetscObject)lim), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscLimiter type: %s", name);
85c0ce001eSMatthew G. Knepley 
86c0ce001eSMatthew G. Knepley   if (lim->ops->destroy) {
87dbbe0bcdSBarry Smith     PetscUseTypeMethod(lim, destroy);
88c0ce001eSMatthew G. Knepley     lim->ops->destroy = NULL;
89c0ce001eSMatthew G. Knepley   }
909566063dSJacob Faibussowitsch   PetscCall((*r)(lim));
919566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)lim, name));
92c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
93c0ce001eSMatthew G. Knepley }
94c0ce001eSMatthew G. Knepley 
95c0ce001eSMatthew G. Knepley /*@C
96c0ce001eSMatthew G. Knepley   PetscLimiterGetType - Gets the PetscLimiter type name (as a string) from the object.
97c0ce001eSMatthew G. Knepley 
98c0ce001eSMatthew G. Knepley   Not Collective
99c0ce001eSMatthew G. Knepley 
100c0ce001eSMatthew G. Knepley   Input Parameter:
101c0ce001eSMatthew G. Knepley . lim  - The PetscLimiter
102c0ce001eSMatthew G. Knepley 
103c0ce001eSMatthew G. Knepley   Output Parameter:
104c0ce001eSMatthew G. Knepley . name - The PetscLimiter type name
105c0ce001eSMatthew G. Knepley 
106c0ce001eSMatthew G. Knepley   Level: intermediate
107c0ce001eSMatthew G. Knepley 
108db781477SPatrick Sanan .seealso: `PetscLimiterSetType()`, `PetscLimiterCreate()`
109c0ce001eSMatthew G. Knepley @*/
1109371c9d4SSatish Balay PetscErrorCode PetscLimiterGetType(PetscLimiter lim, PetscLimiterType *name) {
111c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
112c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
113c0ce001eSMatthew G. Knepley   PetscValidPointer(name, 2);
1149566063dSJacob Faibussowitsch   PetscCall(PetscLimiterRegisterAll());
115c0ce001eSMatthew G. Knepley   *name = ((PetscObject)lim)->type_name;
116c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
117c0ce001eSMatthew G. Knepley }
118c0ce001eSMatthew G. Knepley 
119c0ce001eSMatthew G. Knepley /*@C
120fe2efc57SMark    PetscLimiterViewFromOptions - View from Options
121fe2efc57SMark 
122fe2efc57SMark    Collective on PetscLimiter
123fe2efc57SMark 
124fe2efc57SMark    Input Parameters:
125fe2efc57SMark +  A - the PetscLimiter object to view
126736c3998SJose E. Roman .  obj - Optional object
127736c3998SJose E. Roman -  name - command line option
128fe2efc57SMark 
129fe2efc57SMark    Level: intermediate
130db781477SPatrick Sanan .seealso: `PetscLimiter`, `PetscLimiterView`, `PetscObjectViewFromOptions()`, `PetscLimiterCreate()`
131fe2efc57SMark @*/
1329371c9d4SSatish Balay PetscErrorCode PetscLimiterViewFromOptions(PetscLimiter A, PetscObject obj, const char name[]) {
133fe2efc57SMark   PetscFunctionBegin;
134fe2efc57SMark   PetscValidHeaderSpecific(A, PETSCLIMITER_CLASSID, 1);
1359566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
136fe2efc57SMark   PetscFunctionReturn(0);
137fe2efc57SMark }
138fe2efc57SMark 
139fe2efc57SMark /*@C
140c0ce001eSMatthew G. Knepley   PetscLimiterView - Views a PetscLimiter
141c0ce001eSMatthew G. Knepley 
142c0ce001eSMatthew G. Knepley   Collective on lim
143c0ce001eSMatthew G. Knepley 
144d8d19677SJose E. Roman   Input Parameters:
145c0ce001eSMatthew G. Knepley + lim - the PetscLimiter object to view
146c0ce001eSMatthew G. Knepley - v   - the viewer
147c0ce001eSMatthew G. Knepley 
14888f5f89eSMatthew G. Knepley   Level: beginner
149c0ce001eSMatthew G. Knepley 
150db781477SPatrick Sanan .seealso: `PetscLimiterDestroy()`
151c0ce001eSMatthew G. Knepley @*/
1529371c9d4SSatish Balay PetscErrorCode PetscLimiterView(PetscLimiter lim, PetscViewer v) {
153c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
154c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
1559566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lim), &v));
156dbbe0bcdSBarry Smith   PetscTryTypeMethod(lim, view, v);
157c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
158c0ce001eSMatthew G. Knepley }
159c0ce001eSMatthew G. Knepley 
160c0ce001eSMatthew G. Knepley /*@
161c0ce001eSMatthew G. Knepley   PetscLimiterSetFromOptions - sets parameters in a PetscLimiter from the options database
162c0ce001eSMatthew G. Knepley 
163c0ce001eSMatthew G. Knepley   Collective on lim
164c0ce001eSMatthew G. Knepley 
165c0ce001eSMatthew G. Knepley   Input Parameter:
166c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to set options for
167c0ce001eSMatthew G. Knepley 
16888f5f89eSMatthew G. Knepley   Level: intermediate
169c0ce001eSMatthew G. Knepley 
170db781477SPatrick Sanan .seealso: `PetscLimiterView()`
171c0ce001eSMatthew G. Knepley @*/
1729371c9d4SSatish Balay PetscErrorCode PetscLimiterSetFromOptions(PetscLimiter lim) {
173c0ce001eSMatthew G. Knepley   const char *defaultType;
174c0ce001eSMatthew G. Knepley   char        name[256];
175c0ce001eSMatthew G. Knepley   PetscBool   flg;
176c0ce001eSMatthew G. Knepley 
177c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
178c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
179c0ce001eSMatthew G. Knepley   if (!((PetscObject)lim)->type_name) defaultType = PETSCLIMITERSIN;
180c0ce001eSMatthew G. Knepley   else defaultType = ((PetscObject)lim)->type_name;
1819566063dSJacob Faibussowitsch   PetscCall(PetscLimiterRegisterAll());
182c0ce001eSMatthew G. Knepley 
183d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)lim);
1849566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petsclimiter_type", "Finite volume slope limiter", "PetscLimiterSetType", PetscLimiterList, defaultType, name, 256, &flg));
185c0ce001eSMatthew G. Knepley   if (flg) {
1869566063dSJacob Faibussowitsch     PetscCall(PetscLimiterSetType(lim, name));
187c0ce001eSMatthew G. Knepley   } else if (!((PetscObject)lim)->type_name) {
1889566063dSJacob Faibussowitsch     PetscCall(PetscLimiterSetType(lim, defaultType));
189c0ce001eSMatthew G. Knepley   }
190dbbe0bcdSBarry Smith   PetscTryTypeMethod(lim, setfromoptions);
191c0ce001eSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
192dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)lim, PetscOptionsObject));
193d0609cedSBarry Smith   PetscOptionsEnd();
1949566063dSJacob Faibussowitsch   PetscCall(PetscLimiterViewFromOptions(lim, NULL, "-petsclimiter_view"));
195c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
196c0ce001eSMatthew G. Knepley }
197c0ce001eSMatthew G. Knepley 
198c0ce001eSMatthew G. Knepley /*@C
199c0ce001eSMatthew G. Knepley   PetscLimiterSetUp - Construct data structures for the PetscLimiter
200c0ce001eSMatthew G. Knepley 
201c0ce001eSMatthew G. Knepley   Collective on lim
202c0ce001eSMatthew G. Knepley 
203c0ce001eSMatthew G. Knepley   Input Parameter:
204c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to setup
205c0ce001eSMatthew G. Knepley 
20688f5f89eSMatthew G. Knepley   Level: intermediate
207c0ce001eSMatthew G. Knepley 
208db781477SPatrick Sanan .seealso: `PetscLimiterView()`, `PetscLimiterDestroy()`
209c0ce001eSMatthew G. Knepley @*/
2109371c9d4SSatish Balay PetscErrorCode PetscLimiterSetUp(PetscLimiter lim) {
211c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
212c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
213dbbe0bcdSBarry Smith   PetscTryTypeMethod(lim, setup);
214c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
215c0ce001eSMatthew G. Knepley }
216c0ce001eSMatthew G. Knepley 
217c0ce001eSMatthew G. Knepley /*@
218c0ce001eSMatthew G. Knepley   PetscLimiterDestroy - Destroys a PetscLimiter object
219c0ce001eSMatthew G. Knepley 
220c0ce001eSMatthew G. Knepley   Collective on lim
221c0ce001eSMatthew G. Knepley 
222c0ce001eSMatthew G. Knepley   Input Parameter:
223c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to destroy
224c0ce001eSMatthew G. Knepley 
22588f5f89eSMatthew G. Knepley   Level: beginner
226c0ce001eSMatthew G. Knepley 
227db781477SPatrick Sanan .seealso: `PetscLimiterView()`
228c0ce001eSMatthew G. Knepley @*/
2299371c9d4SSatish Balay PetscErrorCode PetscLimiterDestroy(PetscLimiter *lim) {
230c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
231c0ce001eSMatthew G. Knepley   if (!*lim) PetscFunctionReturn(0);
232c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific((*lim), PETSCLIMITER_CLASSID, 1);
233c0ce001eSMatthew G. Knepley 
2349371c9d4SSatish Balay   if (--((PetscObject)(*lim))->refct > 0) {
2359371c9d4SSatish Balay     *lim = NULL;
2369371c9d4SSatish Balay     PetscFunctionReturn(0);
2379371c9d4SSatish Balay   }
238c0ce001eSMatthew G. Knepley   ((PetscObject)(*lim))->refct = 0;
239c0ce001eSMatthew G. Knepley 
240dbbe0bcdSBarry Smith   PetscTryTypeMethod((*lim), destroy);
2419566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(lim));
242c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
243c0ce001eSMatthew G. Knepley }
244c0ce001eSMatthew G. Knepley 
245c0ce001eSMatthew G. Knepley /*@
246c0ce001eSMatthew G. Knepley   PetscLimiterCreate - Creates an empty PetscLimiter object. The type can then be set with PetscLimiterSetType().
247c0ce001eSMatthew G. Knepley 
248c0ce001eSMatthew G. Knepley   Collective
249c0ce001eSMatthew G. Knepley 
250c0ce001eSMatthew G. Knepley   Input Parameter:
251c0ce001eSMatthew G. Knepley . comm - The communicator for the PetscLimiter object
252c0ce001eSMatthew G. Knepley 
253c0ce001eSMatthew G. Knepley   Output Parameter:
254c0ce001eSMatthew G. Knepley . lim - The PetscLimiter object
255c0ce001eSMatthew G. Knepley 
256c0ce001eSMatthew G. Knepley   Level: beginner
257c0ce001eSMatthew G. Knepley 
258db781477SPatrick Sanan .seealso: `PetscLimiterSetType()`, `PETSCLIMITERSIN`
259c0ce001eSMatthew G. Knepley @*/
2609371c9d4SSatish Balay PetscErrorCode PetscLimiterCreate(MPI_Comm comm, PetscLimiter *lim) {
261c0ce001eSMatthew G. Knepley   PetscLimiter l;
262c0ce001eSMatthew G. Knepley 
263c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
264c0ce001eSMatthew G. Knepley   PetscValidPointer(lim, 2);
2659566063dSJacob Faibussowitsch   PetscCall(PetscCitationsRegister(LimiterCitation, &Limitercite));
266c0ce001eSMatthew G. Knepley   *lim = NULL;
2679566063dSJacob Faibussowitsch   PetscCall(PetscFVInitializePackage());
268c0ce001eSMatthew G. Knepley 
2699566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(l, PETSCLIMITER_CLASSID, "PetscLimiter", "Finite Volume Slope Limiter", "PetscLimiter", comm, PetscLimiterDestroy, PetscLimiterView));
270c0ce001eSMatthew G. Knepley 
271c0ce001eSMatthew G. Knepley   *lim = l;
272c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
273c0ce001eSMatthew G. Knepley }
274c0ce001eSMatthew G. Knepley 
27588f5f89eSMatthew G. Knepley /*@
27688f5f89eSMatthew G. Knepley   PetscLimiterLimit - Limit the flux
27788f5f89eSMatthew G. Knepley 
27888f5f89eSMatthew G. Knepley   Input Parameters:
27988f5f89eSMatthew G. Knepley + lim  - The PetscLimiter
28088f5f89eSMatthew G. Knepley - flim - The input field
28188f5f89eSMatthew G. Knepley 
28288f5f89eSMatthew G. Knepley   Output Parameter:
28388f5f89eSMatthew G. Knepley . phi  - The limited field
28488f5f89eSMatthew G. Knepley 
28588f5f89eSMatthew G. Knepley Note: Limiters given in symmetric form following Berger, Aftosmis, and Murman 2005
28688f5f89eSMatthew G. Knepley $ The classical flux-limited formulation is psi(r) where
28788f5f89eSMatthew G. Knepley $
28888f5f89eSMatthew G. Knepley $ r = (u[0] - u[-1]) / (u[1] - u[0])
28988f5f89eSMatthew G. Knepley $
29088f5f89eSMatthew G. Knepley $ The second order TVD region is bounded by
29188f5f89eSMatthew G. Knepley $
29288f5f89eSMatthew G. Knepley $ psi_minmod(r) = min(r,1)      and        psi_superbee(r) = min(2, 2r, max(1,r))
29388f5f89eSMatthew G. Knepley $
29488f5f89eSMatthew G. Knepley $ where all limiters are implicitly clipped to be non-negative. A more convenient slope-limited form is psi(r) =
29588f5f89eSMatthew G. Knepley $ phi(r)(r+1)/2 in which the reconstructed interface values are
29688f5f89eSMatthew G. Knepley $
29788f5f89eSMatthew G. Knepley $ u(v) = u[0] + phi(r) (grad u)[0] v
29888f5f89eSMatthew G. Knepley $
29988f5f89eSMatthew G. Knepley $ where v is the vector from centroid to quadrature point. In these variables, the usual limiters become
30088f5f89eSMatthew G. Knepley $
30188f5f89eSMatthew 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))
30288f5f89eSMatthew G. Knepley $
30388f5f89eSMatthew G. Knepley $ For a nicer symmetric formulation, rewrite in terms of
30488f5f89eSMatthew G. Knepley $
30588f5f89eSMatthew G. Knepley $ f = (u[0] - u[-1]) / (u[1] - u[-1])
30688f5f89eSMatthew G. Knepley $
30788f5f89eSMatthew G. Knepley $ where r(f) = f/(1-f). Not that r(1-f) = (1-f)/f = 1/r(f) so the symmetry condition
30888f5f89eSMatthew G. Knepley $
30988f5f89eSMatthew G. Knepley $ phi(r) = phi(1/r)
31088f5f89eSMatthew G. Knepley $
31188f5f89eSMatthew G. Knepley $ becomes
31288f5f89eSMatthew G. Knepley $
31388f5f89eSMatthew G. Knepley $ w(f) = w(1-f).
31488f5f89eSMatthew G. Knepley $
31588f5f89eSMatthew G. Knepley $ The limiters below implement this final form w(f). The reference methods are
31688f5f89eSMatthew G. Knepley $
31788f5f89eSMatthew G. Knepley $ w_minmod(f) = 2 min(f,(1-f))             w_superbee(r) = 4 min((1-f), f)
31888f5f89eSMatthew G. Knepley 
31988f5f89eSMatthew G. Knepley   Level: beginner
32088f5f89eSMatthew G. Knepley 
321db781477SPatrick Sanan .seealso: `PetscLimiterSetType()`, `PetscLimiterCreate()`
32288f5f89eSMatthew G. Knepley @*/
3239371c9d4SSatish Balay PetscErrorCode PetscLimiterLimit(PetscLimiter lim, PetscReal flim, PetscReal *phi) {
324c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
325c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
326dadcf809SJacob Faibussowitsch   PetscValidRealPointer(phi, 3);
327dbbe0bcdSBarry Smith   PetscUseTypeMethod(lim, limit, flim, phi);
328c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
329c0ce001eSMatthew G. Knepley }
330c0ce001eSMatthew G. Knepley 
3319371c9d4SSatish Balay static PetscErrorCode PetscLimiterDestroy_Sin(PetscLimiter lim) {
332c0ce001eSMatthew G. Knepley   PetscLimiter_Sin *l = (PetscLimiter_Sin *)lim->data;
333c0ce001eSMatthew G. Knepley 
334c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
3359566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
336c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
337c0ce001eSMatthew G. Knepley }
338c0ce001eSMatthew G. Knepley 
3399371c9d4SSatish Balay static PetscErrorCode PetscLimiterView_Sin_Ascii(PetscLimiter lim, PetscViewer viewer) {
340c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
341c0ce001eSMatthew G. Knepley 
342c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
3439566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
3449566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Sin Slope Limiter:\n"));
345c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
346c0ce001eSMatthew G. Knepley }
347c0ce001eSMatthew G. Knepley 
3489371c9d4SSatish Balay static PetscErrorCode PetscLimiterView_Sin(PetscLimiter lim, PetscViewer viewer) {
349c0ce001eSMatthew G. Knepley   PetscBool iascii;
350c0ce001eSMatthew G. Knepley 
351c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
352c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
353c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
3549566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
3559566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_Sin_Ascii(lim, viewer));
356c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
357c0ce001eSMatthew G. Knepley }
358c0ce001eSMatthew G. Knepley 
3599371c9d4SSatish Balay static PetscErrorCode PetscLimiterLimit_Sin(PetscLimiter lim, PetscReal f, PetscReal *phi) {
360c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
361c0ce001eSMatthew G. Knepley   *phi = PetscSinReal(PETSC_PI * PetscMax(0, PetscMin(f, 1)));
362c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
363c0ce001eSMatthew G. Knepley }
364c0ce001eSMatthew G. Knepley 
3659371c9d4SSatish Balay static PetscErrorCode PetscLimiterInitialize_Sin(PetscLimiter lim) {
366c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
367c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Sin;
368c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Sin;
369c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Sin;
370c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
371c0ce001eSMatthew G. Knepley }
372c0ce001eSMatthew G. Knepley 
373c0ce001eSMatthew G. Knepley /*MC
374c0ce001eSMatthew G. Knepley   PETSCLIMITERSIN = "sin" - A PetscLimiter object
375c0ce001eSMatthew G. Knepley 
376c0ce001eSMatthew G. Knepley   Level: intermediate
377c0ce001eSMatthew G. Knepley 
378db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
379c0ce001eSMatthew G. Knepley M*/
380c0ce001eSMatthew G. Knepley 
3819371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Sin(PetscLimiter lim) {
382c0ce001eSMatthew G. Knepley   PetscLimiter_Sin *l;
383c0ce001eSMatthew G. Knepley 
384c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
385c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
386*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&l));
387c0ce001eSMatthew G. Knepley   lim->data = l;
388c0ce001eSMatthew G. Knepley 
3899566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_Sin(lim));
390c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
391c0ce001eSMatthew G. Knepley }
392c0ce001eSMatthew G. Knepley 
3939371c9d4SSatish Balay static PetscErrorCode PetscLimiterDestroy_Zero(PetscLimiter lim) {
394c0ce001eSMatthew G. Knepley   PetscLimiter_Zero *l = (PetscLimiter_Zero *)lim->data;
395c0ce001eSMatthew G. Knepley 
396c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
3979566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
398c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
399c0ce001eSMatthew G. Knepley }
400c0ce001eSMatthew G. Knepley 
4019371c9d4SSatish Balay static PetscErrorCode PetscLimiterView_Zero_Ascii(PetscLimiter lim, PetscViewer viewer) {
402c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
403c0ce001eSMatthew G. Knepley 
404c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
4059566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
4069566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Zero Slope Limiter:\n"));
407c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
408c0ce001eSMatthew G. Knepley }
409c0ce001eSMatthew G. Knepley 
4109371c9d4SSatish Balay static PetscErrorCode PetscLimiterView_Zero(PetscLimiter lim, PetscViewer viewer) {
411c0ce001eSMatthew G. Knepley   PetscBool iascii;
412c0ce001eSMatthew G. Knepley 
413c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
414c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
415c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
4169566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
4179566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_Zero_Ascii(lim, viewer));
418c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
419c0ce001eSMatthew G. Knepley }
420c0ce001eSMatthew G. Knepley 
4219371c9d4SSatish Balay static PetscErrorCode PetscLimiterLimit_Zero(PetscLimiter lim, PetscReal f, PetscReal *phi) {
422c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
423c0ce001eSMatthew G. Knepley   *phi = 0.0;
424c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
425c0ce001eSMatthew G. Knepley }
426c0ce001eSMatthew G. Knepley 
4279371c9d4SSatish Balay static PetscErrorCode PetscLimiterInitialize_Zero(PetscLimiter lim) {
428c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
429c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Zero;
430c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Zero;
431c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Zero;
432c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
433c0ce001eSMatthew G. Knepley }
434c0ce001eSMatthew G. Knepley 
435c0ce001eSMatthew G. Knepley /*MC
436c0ce001eSMatthew G. Knepley   PETSCLIMITERZERO = "zero" - A PetscLimiter object
437c0ce001eSMatthew G. Knepley 
438c0ce001eSMatthew G. Knepley   Level: intermediate
439c0ce001eSMatthew G. Knepley 
440db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
441c0ce001eSMatthew G. Knepley M*/
442c0ce001eSMatthew G. Knepley 
4439371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Zero(PetscLimiter lim) {
444c0ce001eSMatthew G. Knepley   PetscLimiter_Zero *l;
445c0ce001eSMatthew G. Knepley 
446c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
447c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
448*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&l));
449c0ce001eSMatthew G. Knepley   lim->data = l;
450c0ce001eSMatthew G. Knepley 
4519566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_Zero(lim));
452c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
453c0ce001eSMatthew G. Knepley }
454c0ce001eSMatthew G. Knepley 
4559371c9d4SSatish Balay static PetscErrorCode PetscLimiterDestroy_None(PetscLimiter lim) {
456c0ce001eSMatthew G. Knepley   PetscLimiter_None *l = (PetscLimiter_None *)lim->data;
457c0ce001eSMatthew G. Knepley 
458c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
4599566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
460c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
461c0ce001eSMatthew G. Knepley }
462c0ce001eSMatthew G. Knepley 
4639371c9d4SSatish Balay static PetscErrorCode PetscLimiterView_None_Ascii(PetscLimiter lim, PetscViewer viewer) {
464c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
465c0ce001eSMatthew G. Knepley 
466c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
4679566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
4689566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "None Slope Limiter:\n"));
469c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
470c0ce001eSMatthew G. Knepley }
471c0ce001eSMatthew G. Knepley 
4729371c9d4SSatish Balay static PetscErrorCode PetscLimiterView_None(PetscLimiter lim, PetscViewer viewer) {
473c0ce001eSMatthew G. Knepley   PetscBool iascii;
474c0ce001eSMatthew G. Knepley 
475c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
476c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
477c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
4789566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
4799566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_None_Ascii(lim, viewer));
480c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
481c0ce001eSMatthew G. Knepley }
482c0ce001eSMatthew G. Knepley 
4839371c9d4SSatish Balay static PetscErrorCode PetscLimiterLimit_None(PetscLimiter lim, PetscReal f, PetscReal *phi) {
484c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
485c0ce001eSMatthew G. Knepley   *phi = 1.0;
486c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
487c0ce001eSMatthew G. Knepley }
488c0ce001eSMatthew G. Knepley 
4899371c9d4SSatish Balay static PetscErrorCode PetscLimiterInitialize_None(PetscLimiter lim) {
490c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
491c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_None;
492c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_None;
493c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_None;
494c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
495c0ce001eSMatthew G. Knepley }
496c0ce001eSMatthew G. Knepley 
497c0ce001eSMatthew G. Knepley /*MC
498c0ce001eSMatthew G. Knepley   PETSCLIMITERNONE = "none" - A PetscLimiter object
499c0ce001eSMatthew G. Knepley 
500c0ce001eSMatthew G. Knepley   Level: intermediate
501c0ce001eSMatthew G. Knepley 
502db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
503c0ce001eSMatthew G. Knepley M*/
504c0ce001eSMatthew G. Knepley 
5059371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscLimiterCreate_None(PetscLimiter lim) {
506c0ce001eSMatthew G. Knepley   PetscLimiter_None *l;
507c0ce001eSMatthew G. Knepley 
508c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
509c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
510*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&l));
511c0ce001eSMatthew G. Knepley   lim->data = l;
512c0ce001eSMatthew G. Knepley 
5139566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_None(lim));
514c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
515c0ce001eSMatthew G. Knepley }
516c0ce001eSMatthew G. Knepley 
5179371c9d4SSatish Balay static PetscErrorCode PetscLimiterDestroy_Minmod(PetscLimiter lim) {
518c0ce001eSMatthew G. Knepley   PetscLimiter_Minmod *l = (PetscLimiter_Minmod *)lim->data;
519c0ce001eSMatthew G. Knepley 
520c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
5219566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
522c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
523c0ce001eSMatthew G. Knepley }
524c0ce001eSMatthew G. Knepley 
5259371c9d4SSatish Balay static PetscErrorCode PetscLimiterView_Minmod_Ascii(PetscLimiter lim, PetscViewer viewer) {
526c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
527c0ce001eSMatthew G. Knepley 
528c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
5299566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
5309566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Minmod Slope Limiter:\n"));
531c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
532c0ce001eSMatthew G. Knepley }
533c0ce001eSMatthew G. Knepley 
5349371c9d4SSatish Balay static PetscErrorCode PetscLimiterView_Minmod(PetscLimiter lim, PetscViewer viewer) {
535c0ce001eSMatthew G. Knepley   PetscBool iascii;
536c0ce001eSMatthew G. Knepley 
537c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
538c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
539c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
5409566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
5419566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_Minmod_Ascii(lim, viewer));
542c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
543c0ce001eSMatthew G. Knepley }
544c0ce001eSMatthew G. Knepley 
5459371c9d4SSatish Balay static PetscErrorCode PetscLimiterLimit_Minmod(PetscLimiter lim, PetscReal f, PetscReal *phi) {
546c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
547c0ce001eSMatthew G. Knepley   *phi = 2 * PetscMax(0, PetscMin(f, 1 - f));
548c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
549c0ce001eSMatthew G. Knepley }
550c0ce001eSMatthew G. Knepley 
5519371c9d4SSatish Balay static PetscErrorCode PetscLimiterInitialize_Minmod(PetscLimiter lim) {
552c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
553c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Minmod;
554c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Minmod;
555c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Minmod;
556c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
557c0ce001eSMatthew G. Knepley }
558c0ce001eSMatthew G. Knepley 
559c0ce001eSMatthew G. Knepley /*MC
560c0ce001eSMatthew G. Knepley   PETSCLIMITERMINMOD = "minmod" - A PetscLimiter object
561c0ce001eSMatthew G. Knepley 
562c0ce001eSMatthew G. Knepley   Level: intermediate
563c0ce001eSMatthew G. Knepley 
564db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
565c0ce001eSMatthew G. Knepley M*/
566c0ce001eSMatthew G. Knepley 
5679371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Minmod(PetscLimiter lim) {
568c0ce001eSMatthew G. Knepley   PetscLimiter_Minmod *l;
569c0ce001eSMatthew G. Knepley 
570c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
571c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
572*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&l));
573c0ce001eSMatthew G. Knepley   lim->data = l;
574c0ce001eSMatthew G. Knepley 
5759566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_Minmod(lim));
576c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
577c0ce001eSMatthew G. Knepley }
578c0ce001eSMatthew G. Knepley 
5799371c9d4SSatish Balay static PetscErrorCode PetscLimiterDestroy_VanLeer(PetscLimiter lim) {
580c0ce001eSMatthew G. Knepley   PetscLimiter_VanLeer *l = (PetscLimiter_VanLeer *)lim->data;
581c0ce001eSMatthew G. Knepley 
582c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
5839566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
584c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
585c0ce001eSMatthew G. Knepley }
586c0ce001eSMatthew G. Knepley 
5879371c9d4SSatish Balay static PetscErrorCode PetscLimiterView_VanLeer_Ascii(PetscLimiter lim, PetscViewer viewer) {
588c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
589c0ce001eSMatthew G. Knepley 
590c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
5919566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
5929566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Van Leer Slope Limiter:\n"));
593c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
594c0ce001eSMatthew G. Knepley }
595c0ce001eSMatthew G. Knepley 
5969371c9d4SSatish Balay static PetscErrorCode PetscLimiterView_VanLeer(PetscLimiter lim, PetscViewer viewer) {
597c0ce001eSMatthew G. Knepley   PetscBool iascii;
598c0ce001eSMatthew G. Knepley 
599c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
600c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
601c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
6029566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
6039566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_VanLeer_Ascii(lim, viewer));
604c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
605c0ce001eSMatthew G. Knepley }
606c0ce001eSMatthew G. Knepley 
6079371c9d4SSatish Balay static PetscErrorCode PetscLimiterLimit_VanLeer(PetscLimiter lim, PetscReal f, PetscReal *phi) {
608c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
609c0ce001eSMatthew G. Knepley   *phi = PetscMax(0, 4 * f * (1 - f));
610c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
611c0ce001eSMatthew G. Knepley }
612c0ce001eSMatthew G. Knepley 
6139371c9d4SSatish Balay static PetscErrorCode PetscLimiterInitialize_VanLeer(PetscLimiter lim) {
614c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
615c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_VanLeer;
616c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_VanLeer;
617c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_VanLeer;
618c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
619c0ce001eSMatthew G. Knepley }
620c0ce001eSMatthew G. Knepley 
621c0ce001eSMatthew G. Knepley /*MC
622c0ce001eSMatthew G. Knepley   PETSCLIMITERVANLEER = "vanleer" - A PetscLimiter object
623c0ce001eSMatthew G. Knepley 
624c0ce001eSMatthew G. Knepley   Level: intermediate
625c0ce001eSMatthew G. Knepley 
626db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
627c0ce001eSMatthew G. Knepley M*/
628c0ce001eSMatthew G. Knepley 
6299371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanLeer(PetscLimiter lim) {
630c0ce001eSMatthew G. Knepley   PetscLimiter_VanLeer *l;
631c0ce001eSMatthew G. Knepley 
632c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
633c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
634*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&l));
635c0ce001eSMatthew G. Knepley   lim->data = l;
636c0ce001eSMatthew G. Knepley 
6379566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_VanLeer(lim));
638c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
639c0ce001eSMatthew G. Knepley }
640c0ce001eSMatthew G. Knepley 
6419371c9d4SSatish Balay static PetscErrorCode PetscLimiterDestroy_VanAlbada(PetscLimiter lim) {
642c0ce001eSMatthew G. Knepley   PetscLimiter_VanAlbada *l = (PetscLimiter_VanAlbada *)lim->data;
643c0ce001eSMatthew G. Knepley 
644c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
6459566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
646c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
647c0ce001eSMatthew G. Knepley }
648c0ce001eSMatthew G. Knepley 
6499371c9d4SSatish Balay static PetscErrorCode PetscLimiterView_VanAlbada_Ascii(PetscLimiter lim, PetscViewer viewer) {
650c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
651c0ce001eSMatthew G. Knepley 
652c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
6539566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
6549566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Van Albada Slope Limiter:\n"));
655c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
656c0ce001eSMatthew G. Knepley }
657c0ce001eSMatthew G. Knepley 
6589371c9d4SSatish Balay static PetscErrorCode PetscLimiterView_VanAlbada(PetscLimiter lim, PetscViewer viewer) {
659c0ce001eSMatthew G. Knepley   PetscBool iascii;
660c0ce001eSMatthew G. Knepley 
661c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
662c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
663c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
6649566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
6659566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_VanAlbada_Ascii(lim, viewer));
666c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
667c0ce001eSMatthew G. Knepley }
668c0ce001eSMatthew G. Knepley 
6699371c9d4SSatish Balay static PetscErrorCode PetscLimiterLimit_VanAlbada(PetscLimiter lim, PetscReal f, PetscReal *phi) {
670c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
671c0ce001eSMatthew G. Knepley   *phi = PetscMax(0, 2 * f * (1 - f) / (PetscSqr(f) + PetscSqr(1 - f)));
672c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
673c0ce001eSMatthew G. Knepley }
674c0ce001eSMatthew G. Knepley 
6759371c9d4SSatish Balay static PetscErrorCode PetscLimiterInitialize_VanAlbada(PetscLimiter lim) {
676c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
677c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_VanAlbada;
678c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_VanAlbada;
679c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_VanAlbada;
680c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
681c0ce001eSMatthew G. Knepley }
682c0ce001eSMatthew G. Knepley 
683c0ce001eSMatthew G. Knepley /*MC
684c0ce001eSMatthew G. Knepley   PETSCLIMITERVANALBADA = "vanalbada" - A PetscLimiter object
685c0ce001eSMatthew G. Knepley 
686c0ce001eSMatthew G. Knepley   Level: intermediate
687c0ce001eSMatthew G. Knepley 
688db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
689c0ce001eSMatthew G. Knepley M*/
690c0ce001eSMatthew G. Knepley 
6919371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanAlbada(PetscLimiter lim) {
692c0ce001eSMatthew G. Knepley   PetscLimiter_VanAlbada *l;
693c0ce001eSMatthew G. Knepley 
694c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
695c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
696*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&l));
697c0ce001eSMatthew G. Knepley   lim->data = l;
698c0ce001eSMatthew G. Knepley 
6999566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_VanAlbada(lim));
700c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
701c0ce001eSMatthew G. Knepley }
702c0ce001eSMatthew G. Knepley 
7039371c9d4SSatish Balay static PetscErrorCode PetscLimiterDestroy_Superbee(PetscLimiter lim) {
704c0ce001eSMatthew G. Knepley   PetscLimiter_Superbee *l = (PetscLimiter_Superbee *)lim->data;
705c0ce001eSMatthew G. Knepley 
706c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
7079566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
708c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
709c0ce001eSMatthew G. Knepley }
710c0ce001eSMatthew G. Knepley 
7119371c9d4SSatish Balay static PetscErrorCode PetscLimiterView_Superbee_Ascii(PetscLimiter lim, PetscViewer viewer) {
712c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
713c0ce001eSMatthew G. Knepley 
714c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
7159566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
7169566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Superbee Slope Limiter:\n"));
717c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
718c0ce001eSMatthew G. Knepley }
719c0ce001eSMatthew G. Knepley 
7209371c9d4SSatish Balay static PetscErrorCode PetscLimiterView_Superbee(PetscLimiter lim, PetscViewer viewer) {
721c0ce001eSMatthew G. Knepley   PetscBool iascii;
722c0ce001eSMatthew G. Knepley 
723c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
724c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
725c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
7269566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
7279566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_Superbee_Ascii(lim, viewer));
728c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
729c0ce001eSMatthew G. Knepley }
730c0ce001eSMatthew G. Knepley 
7319371c9d4SSatish Balay static PetscErrorCode PetscLimiterLimit_Superbee(PetscLimiter lim, PetscReal f, PetscReal *phi) {
732c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
733c0ce001eSMatthew G. Knepley   *phi = 4 * PetscMax(0, PetscMin(f, 1 - f));
734c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
735c0ce001eSMatthew G. Knepley }
736c0ce001eSMatthew G. Knepley 
7379371c9d4SSatish Balay static PetscErrorCode PetscLimiterInitialize_Superbee(PetscLimiter lim) {
738c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
739c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Superbee;
740c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Superbee;
741c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Superbee;
742c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
743c0ce001eSMatthew G. Knepley }
744c0ce001eSMatthew G. Knepley 
745c0ce001eSMatthew G. Knepley /*MC
746c0ce001eSMatthew G. Knepley   PETSCLIMITERSUPERBEE = "superbee" - A PetscLimiter object
747c0ce001eSMatthew G. Knepley 
748c0ce001eSMatthew G. Knepley   Level: intermediate
749c0ce001eSMatthew G. Knepley 
750db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
751c0ce001eSMatthew G. Knepley M*/
752c0ce001eSMatthew G. Knepley 
7539371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Superbee(PetscLimiter lim) {
754c0ce001eSMatthew G. Knepley   PetscLimiter_Superbee *l;
755c0ce001eSMatthew G. Knepley 
756c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
757c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
758*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&l));
759c0ce001eSMatthew G. Knepley   lim->data = l;
760c0ce001eSMatthew G. Knepley 
7619566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_Superbee(lim));
762c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
763c0ce001eSMatthew G. Knepley }
764c0ce001eSMatthew G. Knepley 
7659371c9d4SSatish Balay static PetscErrorCode PetscLimiterDestroy_MC(PetscLimiter lim) {
766c0ce001eSMatthew G. Knepley   PetscLimiter_MC *l = (PetscLimiter_MC *)lim->data;
767c0ce001eSMatthew G. Knepley 
768c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
7699566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
770c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
771c0ce001eSMatthew G. Knepley }
772c0ce001eSMatthew G. Knepley 
7739371c9d4SSatish Balay static PetscErrorCode PetscLimiterView_MC_Ascii(PetscLimiter lim, PetscViewer viewer) {
774c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
775c0ce001eSMatthew G. Knepley 
776c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
7779566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
7789566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "MC Slope Limiter:\n"));
779c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
780c0ce001eSMatthew G. Knepley }
781c0ce001eSMatthew G. Knepley 
7829371c9d4SSatish Balay static PetscErrorCode PetscLimiterView_MC(PetscLimiter lim, PetscViewer viewer) {
783c0ce001eSMatthew G. Knepley   PetscBool iascii;
784c0ce001eSMatthew G. Knepley 
785c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
786c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
787c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
7889566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
7899566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_MC_Ascii(lim, viewer));
790c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
791c0ce001eSMatthew G. Knepley }
792c0ce001eSMatthew G. Knepley 
793c0ce001eSMatthew G. Knepley /* aka Barth-Jespersen */
7949371c9d4SSatish Balay static PetscErrorCode PetscLimiterLimit_MC(PetscLimiter lim, PetscReal f, PetscReal *phi) {
795c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
796c0ce001eSMatthew G. Knepley   *phi = PetscMin(1, 4 * PetscMax(0, PetscMin(f, 1 - f)));
797c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
798c0ce001eSMatthew G. Knepley }
799c0ce001eSMatthew G. Knepley 
8009371c9d4SSatish Balay static PetscErrorCode PetscLimiterInitialize_MC(PetscLimiter lim) {
801c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
802c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_MC;
803c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_MC;
804c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_MC;
805c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
806c0ce001eSMatthew G. Knepley }
807c0ce001eSMatthew G. Knepley 
808c0ce001eSMatthew G. Knepley /*MC
809c0ce001eSMatthew G. Knepley   PETSCLIMITERMC = "mc" - A PetscLimiter object
810c0ce001eSMatthew G. Knepley 
811c0ce001eSMatthew G. Knepley   Level: intermediate
812c0ce001eSMatthew G. Knepley 
813db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()`
814c0ce001eSMatthew G. Knepley M*/
815c0ce001eSMatthew G. Knepley 
8169371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscLimiterCreate_MC(PetscLimiter lim) {
817c0ce001eSMatthew G. Knepley   PetscLimiter_MC *l;
818c0ce001eSMatthew G. Knepley 
819c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
820c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
821*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&l));
822c0ce001eSMatthew G. Knepley   lim->data = l;
823c0ce001eSMatthew G. Knepley 
8249566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_MC(lim));
825c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
826c0ce001eSMatthew G. Knepley }
827c0ce001eSMatthew G. Knepley 
828c0ce001eSMatthew G. Knepley PetscClassId PETSCFV_CLASSID = 0;
829c0ce001eSMatthew G. Knepley 
830c0ce001eSMatthew G. Knepley PetscFunctionList PetscFVList              = NULL;
831c0ce001eSMatthew G. Knepley PetscBool         PetscFVRegisterAllCalled = PETSC_FALSE;
832c0ce001eSMatthew G. Knepley 
833c0ce001eSMatthew G. Knepley /*@C
834c0ce001eSMatthew G. Knepley   PetscFVRegister - Adds a new PetscFV implementation
835c0ce001eSMatthew G. Knepley 
836c0ce001eSMatthew G. Knepley   Not Collective
837c0ce001eSMatthew G. Knepley 
838c0ce001eSMatthew G. Knepley   Input Parameters:
839c0ce001eSMatthew G. Knepley + name        - The name of a new user-defined creation routine
840c0ce001eSMatthew G. Knepley - create_func - The creation routine itself
841c0ce001eSMatthew G. Knepley 
842c0ce001eSMatthew G. Knepley   Notes:
843c0ce001eSMatthew G. Knepley   PetscFVRegister() may be called multiple times to add several user-defined PetscFVs
844c0ce001eSMatthew G. Knepley 
845c0ce001eSMatthew G. Knepley   Sample usage:
846c0ce001eSMatthew G. Knepley .vb
847c0ce001eSMatthew G. Knepley     PetscFVRegister("my_fv", MyPetscFVCreate);
848c0ce001eSMatthew G. Knepley .ve
849c0ce001eSMatthew G. Knepley 
850c0ce001eSMatthew G. Knepley   Then, your PetscFV type can be chosen with the procedural interface via
851c0ce001eSMatthew G. Knepley .vb
852c0ce001eSMatthew G. Knepley     PetscFVCreate(MPI_Comm, PetscFV *);
853c0ce001eSMatthew G. Knepley     PetscFVSetType(PetscFV, "my_fv");
854c0ce001eSMatthew G. Knepley .ve
855c0ce001eSMatthew G. Knepley    or at runtime via the option
856c0ce001eSMatthew G. Knepley .vb
857c0ce001eSMatthew G. Knepley     -petscfv_type my_fv
858c0ce001eSMatthew G. Knepley .ve
859c0ce001eSMatthew G. Knepley 
860c0ce001eSMatthew G. Knepley   Level: advanced
861c0ce001eSMatthew G. Knepley 
862db781477SPatrick Sanan .seealso: `PetscFVRegisterAll()`, `PetscFVRegisterDestroy()`
863c0ce001eSMatthew G. Knepley 
864c0ce001eSMatthew G. Knepley @*/
8659371c9d4SSatish Balay PetscErrorCode PetscFVRegister(const char sname[], PetscErrorCode (*function)(PetscFV)) {
866c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
8679566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscFVList, sname, function));
868c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
869c0ce001eSMatthew G. Knepley }
870c0ce001eSMatthew G. Knepley 
871c0ce001eSMatthew G. Knepley /*@C
872c0ce001eSMatthew G. Knepley   PetscFVSetType - Builds a particular PetscFV
873c0ce001eSMatthew G. Knepley 
874c0ce001eSMatthew G. Knepley   Collective on fvm
875c0ce001eSMatthew G. Knepley 
876c0ce001eSMatthew G. Knepley   Input Parameters:
877c0ce001eSMatthew G. Knepley + fvm  - The PetscFV object
878c0ce001eSMatthew G. Knepley - name - The kind of FVM space
879c0ce001eSMatthew G. Knepley 
880c0ce001eSMatthew G. Knepley   Options Database Key:
881c0ce001eSMatthew G. Knepley . -petscfv_type <type> - Sets the PetscFV type; use -help for a list of available types
882c0ce001eSMatthew G. Knepley 
883c0ce001eSMatthew G. Knepley   Level: intermediate
884c0ce001eSMatthew G. Knepley 
885db781477SPatrick Sanan .seealso: `PetscFVGetType()`, `PetscFVCreate()`
886c0ce001eSMatthew G. Knepley @*/
8879371c9d4SSatish Balay PetscErrorCode PetscFVSetType(PetscFV fvm, PetscFVType name) {
888c0ce001eSMatthew G. Knepley   PetscErrorCode (*r)(PetscFV);
889c0ce001eSMatthew G. Knepley   PetscBool match;
890c0ce001eSMatthew G. Knepley 
891c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
892c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
8939566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)fvm, name, &match));
894c0ce001eSMatthew G. Knepley   if (match) PetscFunctionReturn(0);
895c0ce001eSMatthew G. Knepley 
8969566063dSJacob Faibussowitsch   PetscCall(PetscFVRegisterAll());
8979566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscFVList, name, &r));
89828b400f6SJacob Faibussowitsch   PetscCheck(r, PetscObjectComm((PetscObject)fvm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscFV type: %s", name);
899c0ce001eSMatthew G. Knepley 
900dbbe0bcdSBarry Smith   PetscTryTypeMethod(fvm, destroy);
901c0ce001eSMatthew G. Knepley   fvm->ops->destroy = NULL;
902dbbe0bcdSBarry Smith 
9039566063dSJacob Faibussowitsch   PetscCall((*r)(fvm));
9049566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)fvm, name));
905c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
906c0ce001eSMatthew G. Knepley }
907c0ce001eSMatthew G. Knepley 
908c0ce001eSMatthew G. Knepley /*@C
909c0ce001eSMatthew G. Knepley   PetscFVGetType - Gets the PetscFV type name (as a string) from the object.
910c0ce001eSMatthew G. Knepley 
911c0ce001eSMatthew G. Knepley   Not Collective
912c0ce001eSMatthew G. Knepley 
913c0ce001eSMatthew G. Knepley   Input Parameter:
914c0ce001eSMatthew G. Knepley . fvm  - The PetscFV
915c0ce001eSMatthew G. Knepley 
916c0ce001eSMatthew G. Knepley   Output Parameter:
917c0ce001eSMatthew G. Knepley . name - The PetscFV type name
918c0ce001eSMatthew G. Knepley 
919c0ce001eSMatthew G. Knepley   Level: intermediate
920c0ce001eSMatthew G. Knepley 
921db781477SPatrick Sanan .seealso: `PetscFVSetType()`, `PetscFVCreate()`
922c0ce001eSMatthew G. Knepley @*/
9239371c9d4SSatish Balay PetscErrorCode PetscFVGetType(PetscFV fvm, PetscFVType *name) {
924c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
925c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
926c0ce001eSMatthew G. Knepley   PetscValidPointer(name, 2);
9279566063dSJacob Faibussowitsch   PetscCall(PetscFVRegisterAll());
928c0ce001eSMatthew G. Knepley   *name = ((PetscObject)fvm)->type_name;
929c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
930c0ce001eSMatthew G. Knepley }
931c0ce001eSMatthew G. Knepley 
932c0ce001eSMatthew G. Knepley /*@C
933fe2efc57SMark    PetscFVViewFromOptions - View from Options
934fe2efc57SMark 
935fe2efc57SMark    Collective on PetscFV
936fe2efc57SMark 
937fe2efc57SMark    Input Parameters:
938fe2efc57SMark +  A - the PetscFV object
939736c3998SJose E. Roman .  obj - Optional object
940736c3998SJose E. Roman -  name - command line option
941fe2efc57SMark 
942fe2efc57SMark    Level: intermediate
943db781477SPatrick Sanan .seealso: `PetscFV`, `PetscFVView`, `PetscObjectViewFromOptions()`, `PetscFVCreate()`
944fe2efc57SMark @*/
9459371c9d4SSatish Balay PetscErrorCode PetscFVViewFromOptions(PetscFV A, PetscObject obj, const char name[]) {
946fe2efc57SMark   PetscFunctionBegin;
947fe2efc57SMark   PetscValidHeaderSpecific(A, PETSCFV_CLASSID, 1);
9489566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
949fe2efc57SMark   PetscFunctionReturn(0);
950fe2efc57SMark }
951fe2efc57SMark 
952fe2efc57SMark /*@C
953c0ce001eSMatthew G. Knepley   PetscFVView - Views a PetscFV
954c0ce001eSMatthew G. Knepley 
955c0ce001eSMatthew G. Knepley   Collective on fvm
956c0ce001eSMatthew G. Knepley 
957d8d19677SJose E. Roman   Input Parameters:
958c0ce001eSMatthew G. Knepley + fvm - the PetscFV object to view
959c0ce001eSMatthew G. Knepley - v   - the viewer
960c0ce001eSMatthew G. Knepley 
96188f5f89eSMatthew G. Knepley   Level: beginner
962c0ce001eSMatthew G. Knepley 
963db781477SPatrick Sanan .seealso: `PetscFVDestroy()`
964c0ce001eSMatthew G. Knepley @*/
9659371c9d4SSatish Balay PetscErrorCode PetscFVView(PetscFV fvm, PetscViewer v) {
966c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
967c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
9689566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)fvm), &v));
969dbbe0bcdSBarry Smith   PetscTryTypeMethod(fvm, view, v);
970c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
971c0ce001eSMatthew G. Knepley }
972c0ce001eSMatthew G. Knepley 
973c0ce001eSMatthew G. Knepley /*@
974c0ce001eSMatthew G. Knepley   PetscFVSetFromOptions - sets parameters in a PetscFV from the options database
975c0ce001eSMatthew G. Knepley 
976c0ce001eSMatthew G. Knepley   Collective on fvm
977c0ce001eSMatthew G. Knepley 
978c0ce001eSMatthew G. Knepley   Input Parameter:
979c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to set options for
980c0ce001eSMatthew G. Knepley 
981c0ce001eSMatthew G. Knepley   Options Database Key:
982c0ce001eSMatthew G. Knepley . -petscfv_compute_gradients <bool> - Determines whether cell gradients are calculated
983c0ce001eSMatthew G. Knepley 
98488f5f89eSMatthew G. Knepley   Level: intermediate
985c0ce001eSMatthew G. Knepley 
986db781477SPatrick Sanan .seealso: `PetscFVView()`
987c0ce001eSMatthew G. Knepley @*/
9889371c9d4SSatish Balay PetscErrorCode PetscFVSetFromOptions(PetscFV fvm) {
989c0ce001eSMatthew G. Knepley   const char *defaultType;
990c0ce001eSMatthew G. Knepley   char        name[256];
991c0ce001eSMatthew G. Knepley   PetscBool   flg;
992c0ce001eSMatthew G. Knepley 
993c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
994c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
995c0ce001eSMatthew G. Knepley   if (!((PetscObject)fvm)->type_name) defaultType = PETSCFVUPWIND;
996c0ce001eSMatthew G. Knepley   else defaultType = ((PetscObject)fvm)->type_name;
9979566063dSJacob Faibussowitsch   PetscCall(PetscFVRegisterAll());
998c0ce001eSMatthew G. Knepley 
999d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)fvm);
10009566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petscfv_type", "Finite volume discretization", "PetscFVSetType", PetscFVList, defaultType, name, 256, &flg));
1001c0ce001eSMatthew G. Knepley   if (flg) {
10029566063dSJacob Faibussowitsch     PetscCall(PetscFVSetType(fvm, name));
1003c0ce001eSMatthew G. Knepley   } else if (!((PetscObject)fvm)->type_name) {
10049566063dSJacob Faibussowitsch     PetscCall(PetscFVSetType(fvm, defaultType));
1005c0ce001eSMatthew G. Knepley   }
10069566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-petscfv_compute_gradients", "Compute cell gradients", "PetscFVSetComputeGradients", fvm->computeGradients, &fvm->computeGradients, NULL));
1007dbbe0bcdSBarry Smith   PetscTryTypeMethod(fvm, setfromoptions);
1008c0ce001eSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
1009dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)fvm, PetscOptionsObject));
10109566063dSJacob Faibussowitsch   PetscCall(PetscLimiterSetFromOptions(fvm->limiter));
1011d0609cedSBarry Smith   PetscOptionsEnd();
10129566063dSJacob Faibussowitsch   PetscCall(PetscFVViewFromOptions(fvm, NULL, "-petscfv_view"));
1013c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1014c0ce001eSMatthew G. Knepley }
1015c0ce001eSMatthew G. Knepley 
1016c0ce001eSMatthew G. Knepley /*@
1017c0ce001eSMatthew G. Knepley   PetscFVSetUp - Construct data structures for the PetscFV
1018c0ce001eSMatthew G. Knepley 
1019c0ce001eSMatthew G. Knepley   Collective on fvm
1020c0ce001eSMatthew G. Knepley 
1021c0ce001eSMatthew G. Knepley   Input Parameter:
1022c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to setup
1023c0ce001eSMatthew G. Knepley 
102488f5f89eSMatthew G. Knepley   Level: intermediate
1025c0ce001eSMatthew G. Knepley 
1026db781477SPatrick Sanan .seealso: `PetscFVView()`, `PetscFVDestroy()`
1027c0ce001eSMatthew G. Knepley @*/
10289371c9d4SSatish Balay PetscErrorCode PetscFVSetUp(PetscFV fvm) {
1029c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1030c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
10319566063dSJacob Faibussowitsch   PetscCall(PetscLimiterSetUp(fvm->limiter));
1032dbbe0bcdSBarry Smith   PetscTryTypeMethod(fvm, setup);
1033c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1034c0ce001eSMatthew G. Knepley }
1035c0ce001eSMatthew G. Knepley 
1036c0ce001eSMatthew G. Knepley /*@
1037c0ce001eSMatthew G. Knepley   PetscFVDestroy - Destroys a PetscFV object
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 destroy
1043c0ce001eSMatthew G. Knepley 
104488f5f89eSMatthew G. Knepley   Level: beginner
1045c0ce001eSMatthew G. Knepley 
1046db781477SPatrick Sanan .seealso: `PetscFVView()`
1047c0ce001eSMatthew G. Knepley @*/
10489371c9d4SSatish Balay PetscErrorCode PetscFVDestroy(PetscFV *fvm) {
1049c0ce001eSMatthew G. Knepley   PetscInt i;
1050c0ce001eSMatthew G. Knepley 
1051c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1052c0ce001eSMatthew G. Knepley   if (!*fvm) PetscFunctionReturn(0);
1053c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific((*fvm), PETSCFV_CLASSID, 1);
1054c0ce001eSMatthew G. Knepley 
10559371c9d4SSatish Balay   if (--((PetscObject)(*fvm))->refct > 0) {
10569371c9d4SSatish Balay     *fvm = NULL;
10579371c9d4SSatish Balay     PetscFunctionReturn(0);
10589371c9d4SSatish Balay   }
1059c0ce001eSMatthew G. Knepley   ((PetscObject)(*fvm))->refct = 0;
1060c0ce001eSMatthew G. Knepley 
106148a46eb9SPierre Jolivet   for (i = 0; i < (*fvm)->numComponents; i++) PetscCall(PetscFree((*fvm)->componentNames[i]));
10629566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fvm)->componentNames));
10639566063dSJacob Faibussowitsch   PetscCall(PetscLimiterDestroy(&(*fvm)->limiter));
10649566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceDestroy(&(*fvm)->dualSpace));
10659566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fvm)->fluxWork));
10669566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureDestroy(&(*fvm)->quadrature));
10679566063dSJacob Faibussowitsch   PetscCall(PetscTabulationDestroy(&(*fvm)->T));
1068c0ce001eSMatthew G. Knepley 
1069dbbe0bcdSBarry Smith   PetscTryTypeMethod((*fvm), destroy);
10709566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(fvm));
1071c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1072c0ce001eSMatthew G. Knepley }
1073c0ce001eSMatthew G. Knepley 
1074c0ce001eSMatthew G. Knepley /*@
1075c0ce001eSMatthew G. Knepley   PetscFVCreate - Creates an empty PetscFV object. The type can then be set with PetscFVSetType().
1076c0ce001eSMatthew G. Knepley 
1077c0ce001eSMatthew G. Knepley   Collective
1078c0ce001eSMatthew G. Knepley 
1079c0ce001eSMatthew G. Knepley   Input Parameter:
1080c0ce001eSMatthew G. Knepley . comm - The communicator for the PetscFV object
1081c0ce001eSMatthew G. Knepley 
1082c0ce001eSMatthew G. Knepley   Output Parameter:
1083c0ce001eSMatthew G. Knepley . fvm - The PetscFV object
1084c0ce001eSMatthew G. Knepley 
1085c0ce001eSMatthew G. Knepley   Level: beginner
1086c0ce001eSMatthew G. Knepley 
1087db781477SPatrick Sanan .seealso: `PetscFVSetType()`, `PETSCFVUPWIND`
1088c0ce001eSMatthew G. Knepley @*/
10899371c9d4SSatish Balay PetscErrorCode PetscFVCreate(MPI_Comm comm, PetscFV *fvm) {
1090c0ce001eSMatthew G. Knepley   PetscFV f;
1091c0ce001eSMatthew G. Knepley 
1092c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1093c0ce001eSMatthew G. Knepley   PetscValidPointer(fvm, 2);
1094c0ce001eSMatthew G. Knepley   *fvm = NULL;
10959566063dSJacob Faibussowitsch   PetscCall(PetscFVInitializePackage());
1096c0ce001eSMatthew G. Knepley 
10979566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(f, PETSCFV_CLASSID, "PetscFV", "Finite Volume", "PetscFV", comm, PetscFVDestroy, PetscFVView));
10989566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(f->ops, sizeof(struct _PetscFVOps)));
1099c0ce001eSMatthew G. Knepley 
11009566063dSJacob Faibussowitsch   PetscCall(PetscLimiterCreate(comm, &f->limiter));
1101c0ce001eSMatthew G. Knepley   f->numComponents    = 1;
1102c0ce001eSMatthew G. Knepley   f->dim              = 0;
1103c0ce001eSMatthew G. Knepley   f->computeGradients = PETSC_FALSE;
1104c0ce001eSMatthew G. Knepley   f->fluxWork         = NULL;
11059566063dSJacob Faibussowitsch   PetscCall(PetscCalloc1(f->numComponents, &f->componentNames));
1106c0ce001eSMatthew G. Knepley 
1107c0ce001eSMatthew G. Knepley   *fvm = f;
1108c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1109c0ce001eSMatthew G. Knepley }
1110c0ce001eSMatthew G. Knepley 
1111c0ce001eSMatthew G. Knepley /*@
1112c0ce001eSMatthew G. Knepley   PetscFVSetLimiter - Set the limiter object
1113c0ce001eSMatthew G. Knepley 
1114c0ce001eSMatthew G. Knepley   Logically collective on fvm
1115c0ce001eSMatthew G. Knepley 
1116c0ce001eSMatthew G. Knepley   Input Parameters:
1117c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1118c0ce001eSMatthew G. Knepley - lim - The PetscLimiter
1119c0ce001eSMatthew G. Knepley 
112088f5f89eSMatthew G. Knepley   Level: intermediate
1121c0ce001eSMatthew G. Knepley 
1122db781477SPatrick Sanan .seealso: `PetscFVGetLimiter()`
1123c0ce001eSMatthew G. Knepley @*/
11249371c9d4SSatish Balay PetscErrorCode PetscFVSetLimiter(PetscFV fvm, PetscLimiter lim) {
1125c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1126c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1127c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 2);
11289566063dSJacob Faibussowitsch   PetscCall(PetscLimiterDestroy(&fvm->limiter));
11299566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)lim));
1130c0ce001eSMatthew G. Knepley   fvm->limiter = lim;
1131c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1132c0ce001eSMatthew G. Knepley }
1133c0ce001eSMatthew G. Knepley 
1134c0ce001eSMatthew G. Knepley /*@
1135c0ce001eSMatthew G. Knepley   PetscFVGetLimiter - Get the limiter object
1136c0ce001eSMatthew G. Knepley 
1137c0ce001eSMatthew G. Knepley   Not collective
1138c0ce001eSMatthew G. Knepley 
1139c0ce001eSMatthew G. Knepley   Input Parameter:
1140c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1141c0ce001eSMatthew G. Knepley 
1142c0ce001eSMatthew G. Knepley   Output Parameter:
1143c0ce001eSMatthew G. Knepley . lim - The PetscLimiter
1144c0ce001eSMatthew G. Knepley 
114588f5f89eSMatthew G. Knepley   Level: intermediate
1146c0ce001eSMatthew G. Knepley 
1147db781477SPatrick Sanan .seealso: `PetscFVSetLimiter()`
1148c0ce001eSMatthew G. Knepley @*/
11499371c9d4SSatish Balay PetscErrorCode PetscFVGetLimiter(PetscFV fvm, PetscLimiter *lim) {
1150c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1151c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1152c0ce001eSMatthew G. Knepley   PetscValidPointer(lim, 2);
1153c0ce001eSMatthew G. Knepley   *lim = fvm->limiter;
1154c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1155c0ce001eSMatthew G. Knepley }
1156c0ce001eSMatthew G. Knepley 
1157c0ce001eSMatthew G. Knepley /*@
1158c0ce001eSMatthew G. Knepley   PetscFVSetNumComponents - Set the number of field components
1159c0ce001eSMatthew G. Knepley 
1160c0ce001eSMatthew G. Knepley   Logically collective on fvm
1161c0ce001eSMatthew G. Knepley 
1162c0ce001eSMatthew G. Knepley   Input Parameters:
1163c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1164c0ce001eSMatthew G. Knepley - comp - The number of components
1165c0ce001eSMatthew G. Knepley 
116688f5f89eSMatthew G. Knepley   Level: intermediate
1167c0ce001eSMatthew G. Knepley 
1168db781477SPatrick Sanan .seealso: `PetscFVGetNumComponents()`
1169c0ce001eSMatthew G. Knepley @*/
11709371c9d4SSatish Balay PetscErrorCode PetscFVSetNumComponents(PetscFV fvm, PetscInt comp) {
1171c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1172c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1173c0ce001eSMatthew G. Knepley   if (fvm->numComponents != comp) {
1174c0ce001eSMatthew G. Knepley     PetscInt i;
1175c0ce001eSMatthew G. Knepley 
117648a46eb9SPierre Jolivet     for (i = 0; i < fvm->numComponents; i++) PetscCall(PetscFree(fvm->componentNames[i]));
11779566063dSJacob Faibussowitsch     PetscCall(PetscFree(fvm->componentNames));
11789566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(comp, &fvm->componentNames));
1179c0ce001eSMatthew G. Knepley   }
1180c0ce001eSMatthew G. Knepley   fvm->numComponents = comp;
11819566063dSJacob Faibussowitsch   PetscCall(PetscFree(fvm->fluxWork));
11829566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(comp, &fvm->fluxWork));
1183c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1184c0ce001eSMatthew G. Knepley }
1185c0ce001eSMatthew G. Knepley 
1186c0ce001eSMatthew G. Knepley /*@
1187c0ce001eSMatthew G. Knepley   PetscFVGetNumComponents - Get the number of field components
1188c0ce001eSMatthew G. Knepley 
1189c0ce001eSMatthew G. Knepley   Not collective
1190c0ce001eSMatthew G. Knepley 
1191c0ce001eSMatthew G. Knepley   Input Parameter:
1192c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1193c0ce001eSMatthew G. Knepley 
1194c0ce001eSMatthew G. Knepley   Output Parameter:
1195c0ce001eSMatthew G. Knepley , comp - The number of components
1196c0ce001eSMatthew G. Knepley 
119788f5f89eSMatthew G. Knepley   Level: intermediate
1198c0ce001eSMatthew G. Knepley 
1199db781477SPatrick Sanan .seealso: `PetscFVSetNumComponents()`
1200c0ce001eSMatthew G. Knepley @*/
12019371c9d4SSatish Balay PetscErrorCode PetscFVGetNumComponents(PetscFV fvm, PetscInt *comp) {
1202c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1203c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1204dadcf809SJacob Faibussowitsch   PetscValidIntPointer(comp, 2);
1205c0ce001eSMatthew G. Knepley   *comp = fvm->numComponents;
1206c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1207c0ce001eSMatthew G. Knepley }
1208c0ce001eSMatthew G. Knepley 
1209c0ce001eSMatthew G. Knepley /*@C
1210c0ce001eSMatthew G. Knepley   PetscFVSetComponentName - Set the name of a component (used in output and viewing)
1211c0ce001eSMatthew G. Knepley 
1212c0ce001eSMatthew G. Knepley   Logically collective on fvm
1213c0ce001eSMatthew G. Knepley   Input Parameters:
1214c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1215c0ce001eSMatthew G. Knepley . comp - the component number
1216c0ce001eSMatthew G. Knepley - name - the component name
1217c0ce001eSMatthew G. Knepley 
121888f5f89eSMatthew G. Knepley   Level: intermediate
1219c0ce001eSMatthew G. Knepley 
1220db781477SPatrick Sanan .seealso: `PetscFVGetComponentName()`
1221c0ce001eSMatthew G. Knepley @*/
12229371c9d4SSatish Balay PetscErrorCode PetscFVSetComponentName(PetscFV fvm, PetscInt comp, const char *name) {
1223c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
12249566063dSJacob Faibussowitsch   PetscCall(PetscFree(fvm->componentNames[comp]));
12259566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &fvm->componentNames[comp]));
1226c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1227c0ce001eSMatthew G. Knepley }
1228c0ce001eSMatthew G. Knepley 
1229c0ce001eSMatthew G. Knepley /*@C
1230c0ce001eSMatthew G. Knepley   PetscFVGetComponentName - Get the name of a component (used in output and viewing)
1231c0ce001eSMatthew G. Knepley 
1232c0ce001eSMatthew G. Knepley   Logically collective on fvm
1233c0ce001eSMatthew G. Knepley   Input Parameters:
1234c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1235c0ce001eSMatthew G. Knepley - comp - the component number
1236c0ce001eSMatthew G. Knepley 
1237c0ce001eSMatthew G. Knepley   Output Parameter:
1238c0ce001eSMatthew G. Knepley . name - the component name
1239c0ce001eSMatthew G. Knepley 
124088f5f89eSMatthew G. Knepley   Level: intermediate
1241c0ce001eSMatthew G. Knepley 
1242db781477SPatrick Sanan .seealso: `PetscFVSetComponentName()`
1243c0ce001eSMatthew G. Knepley @*/
12449371c9d4SSatish Balay PetscErrorCode PetscFVGetComponentName(PetscFV fvm, PetscInt comp, const char **name) {
1245c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1246c0ce001eSMatthew G. Knepley   *name = fvm->componentNames[comp];
1247c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1248c0ce001eSMatthew G. Knepley }
1249c0ce001eSMatthew G. Knepley 
1250c0ce001eSMatthew G. Knepley /*@
1251c0ce001eSMatthew G. Knepley   PetscFVSetSpatialDimension - Set the spatial dimension
1252c0ce001eSMatthew G. Knepley 
1253c0ce001eSMatthew G. Knepley   Logically collective on fvm
1254c0ce001eSMatthew G. Knepley 
1255c0ce001eSMatthew G. Knepley   Input Parameters:
1256c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1257c0ce001eSMatthew G. Knepley - dim - The spatial dimension
1258c0ce001eSMatthew G. Knepley 
125988f5f89eSMatthew G. Knepley   Level: intermediate
1260c0ce001eSMatthew G. Knepley 
1261db781477SPatrick Sanan .seealso: `PetscFVGetSpatialDimension()`
1262c0ce001eSMatthew G. Knepley @*/
12639371c9d4SSatish Balay PetscErrorCode PetscFVSetSpatialDimension(PetscFV fvm, PetscInt dim) {
1264c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1265c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1266c0ce001eSMatthew G. Knepley   fvm->dim = dim;
1267c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1268c0ce001eSMatthew G. Knepley }
1269c0ce001eSMatthew G. Knepley 
1270c0ce001eSMatthew G. Knepley /*@
1271c0ce001eSMatthew G. Knepley   PetscFVGetSpatialDimension - Get the spatial dimension
1272c0ce001eSMatthew G. Knepley 
1273c0ce001eSMatthew G. Knepley   Logically collective on fvm
1274c0ce001eSMatthew G. Knepley 
1275c0ce001eSMatthew G. Knepley   Input Parameter:
1276c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1277c0ce001eSMatthew G. Knepley 
1278c0ce001eSMatthew G. Knepley   Output Parameter:
1279c0ce001eSMatthew G. Knepley . dim - The spatial dimension
1280c0ce001eSMatthew G. Knepley 
128188f5f89eSMatthew G. Knepley   Level: intermediate
1282c0ce001eSMatthew G. Knepley 
1283db781477SPatrick Sanan .seealso: `PetscFVSetSpatialDimension()`
1284c0ce001eSMatthew G. Knepley @*/
12859371c9d4SSatish Balay PetscErrorCode PetscFVGetSpatialDimension(PetscFV fvm, PetscInt *dim) {
1286c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1287c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1288dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
1289c0ce001eSMatthew G. Knepley   *dim = fvm->dim;
1290c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1291c0ce001eSMatthew G. Knepley }
1292c0ce001eSMatthew G. Knepley 
1293c0ce001eSMatthew G. Knepley /*@
1294c0ce001eSMatthew G. Knepley   PetscFVSetComputeGradients - Toggle computation of cell gradients
1295c0ce001eSMatthew G. Knepley 
1296c0ce001eSMatthew G. Knepley   Logically collective on fvm
1297c0ce001eSMatthew G. Knepley 
1298c0ce001eSMatthew G. Knepley   Input Parameters:
1299c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1300c0ce001eSMatthew G. Knepley - computeGradients - Flag to compute cell gradients
1301c0ce001eSMatthew G. Knepley 
130288f5f89eSMatthew G. Knepley   Level: intermediate
1303c0ce001eSMatthew G. Knepley 
1304db781477SPatrick Sanan .seealso: `PetscFVGetComputeGradients()`
1305c0ce001eSMatthew G. Knepley @*/
13069371c9d4SSatish Balay PetscErrorCode PetscFVSetComputeGradients(PetscFV fvm, PetscBool computeGradients) {
1307c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1308c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1309c0ce001eSMatthew G. Knepley   fvm->computeGradients = computeGradients;
1310c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1311c0ce001eSMatthew G. Knepley }
1312c0ce001eSMatthew G. Knepley 
1313c0ce001eSMatthew G. Knepley /*@
1314c0ce001eSMatthew G. Knepley   PetscFVGetComputeGradients - Return flag for computation of cell gradients
1315c0ce001eSMatthew G. Knepley 
1316c0ce001eSMatthew G. Knepley   Not collective
1317c0ce001eSMatthew G. Knepley 
1318c0ce001eSMatthew G. Knepley   Input Parameter:
1319c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1320c0ce001eSMatthew G. Knepley 
1321c0ce001eSMatthew G. Knepley   Output Parameter:
1322c0ce001eSMatthew G. Knepley . computeGradients - Flag to compute cell gradients
1323c0ce001eSMatthew G. Knepley 
132488f5f89eSMatthew G. Knepley   Level: intermediate
1325c0ce001eSMatthew G. Knepley 
1326db781477SPatrick Sanan .seealso: `PetscFVSetComputeGradients()`
1327c0ce001eSMatthew G. Knepley @*/
13289371c9d4SSatish Balay PetscErrorCode PetscFVGetComputeGradients(PetscFV fvm, PetscBool *computeGradients) {
1329c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1330c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1331dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(computeGradients, 2);
1332c0ce001eSMatthew G. Knepley   *computeGradients = fvm->computeGradients;
1333c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1334c0ce001eSMatthew G. Knepley }
1335c0ce001eSMatthew G. Knepley 
1336c0ce001eSMatthew G. Knepley /*@
1337c0ce001eSMatthew G. Knepley   PetscFVSetQuadrature - Set the quadrature object
1338c0ce001eSMatthew G. Knepley 
1339c0ce001eSMatthew G. Knepley   Logically collective on fvm
1340c0ce001eSMatthew G. Knepley 
1341c0ce001eSMatthew G. Knepley   Input Parameters:
1342c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1343c0ce001eSMatthew G. Knepley - q - The PetscQuadrature
1344c0ce001eSMatthew G. Knepley 
134588f5f89eSMatthew G. Knepley   Level: intermediate
1346c0ce001eSMatthew G. Knepley 
1347db781477SPatrick Sanan .seealso: `PetscFVGetQuadrature()`
1348c0ce001eSMatthew G. Knepley @*/
13499371c9d4SSatish Balay PetscErrorCode PetscFVSetQuadrature(PetscFV fvm, PetscQuadrature q) {
1350c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1351c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
13529566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureDestroy(&fvm->quadrature));
13539566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)q));
1354c0ce001eSMatthew G. Knepley   fvm->quadrature = q;
1355c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1356c0ce001eSMatthew G. Knepley }
1357c0ce001eSMatthew G. Knepley 
1358c0ce001eSMatthew G. Knepley /*@
1359c0ce001eSMatthew G. Knepley   PetscFVGetQuadrature - Get the quadrature object
1360c0ce001eSMatthew G. Knepley 
1361c0ce001eSMatthew G. Knepley   Not collective
1362c0ce001eSMatthew G. Knepley 
1363c0ce001eSMatthew G. Knepley   Input Parameter:
1364c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1365c0ce001eSMatthew G. Knepley 
1366c0ce001eSMatthew G. Knepley   Output Parameter:
1367c0ce001eSMatthew G. Knepley . lim - The PetscQuadrature
1368c0ce001eSMatthew G. Knepley 
136988f5f89eSMatthew G. Knepley   Level: intermediate
1370c0ce001eSMatthew G. Knepley 
1371db781477SPatrick Sanan .seealso: `PetscFVSetQuadrature()`
1372c0ce001eSMatthew G. Knepley @*/
13739371c9d4SSatish Balay PetscErrorCode PetscFVGetQuadrature(PetscFV fvm, PetscQuadrature *q) {
1374c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1375c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1376c0ce001eSMatthew G. Knepley   PetscValidPointer(q, 2);
1377c0ce001eSMatthew G. Knepley   if (!fvm->quadrature) {
1378c0ce001eSMatthew G. Knepley     /* Create default 1-point quadrature */
1379c0ce001eSMatthew G. Knepley     PetscReal *points, *weights;
1380c0ce001eSMatthew G. Knepley 
13819566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &fvm->quadrature));
13829566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(fvm->dim, &points));
13839566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(1, &weights));
1384c0ce001eSMatthew G. Knepley     weights[0] = 1.0;
13859566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureSetData(fvm->quadrature, fvm->dim, 1, 1, points, weights));
1386c0ce001eSMatthew G. Knepley   }
1387c0ce001eSMatthew G. Knepley   *q = fvm->quadrature;
1388c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1389c0ce001eSMatthew G. Knepley }
1390c0ce001eSMatthew G. Knepley 
1391c0ce001eSMatthew G. Knepley /*@
1392c0ce001eSMatthew G. Knepley   PetscFVGetDualSpace - Returns the PetscDualSpace used to define the inner product
1393c0ce001eSMatthew G. Knepley 
1394c0ce001eSMatthew G. Knepley   Not collective
1395c0ce001eSMatthew G. Knepley 
1396c0ce001eSMatthew G. Knepley   Input Parameter:
1397c0ce001eSMatthew G. Knepley . fvm - The PetscFV object
1398c0ce001eSMatthew G. Knepley 
1399c0ce001eSMatthew G. Knepley   Output Parameter:
1400c0ce001eSMatthew G. Knepley . sp - The PetscDualSpace object
1401c0ce001eSMatthew G. Knepley 
1402c0ce001eSMatthew G. Knepley   Note: A simple dual space is provided automatically, and the user typically will not need to override it.
1403c0ce001eSMatthew G. Knepley 
140488f5f89eSMatthew G. Knepley   Level: intermediate
1405c0ce001eSMatthew G. Knepley 
1406db781477SPatrick Sanan .seealso: `PetscFVCreate()`
1407c0ce001eSMatthew G. Knepley @*/
14089371c9d4SSatish Balay PetscErrorCode PetscFVGetDualSpace(PetscFV fvm, PetscDualSpace *sp) {
1409c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1410c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1411c0ce001eSMatthew G. Knepley   PetscValidPointer(sp, 2);
1412c0ce001eSMatthew G. Knepley   if (!fvm->dualSpace) {
1413c0ce001eSMatthew G. Knepley     DM       K;
1414c0ce001eSMatthew G. Knepley     PetscInt dim, Nc, c;
1415c0ce001eSMatthew G. Knepley 
14169566063dSJacob Faibussowitsch     PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
14179566063dSJacob Faibussowitsch     PetscCall(PetscFVGetNumComponents(fvm, &Nc));
14189566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceCreate(PetscObjectComm((PetscObject)fvm), &fvm->dualSpace));
14199566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSetType(fvm->dualSpace, PETSCDUALSPACESIMPLE));
14209566063dSJacob Faibussowitsch     PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, DMPolytopeTypeSimpleShape(dim, PETSC_FALSE), &K));
14219566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSetNumComponents(fvm->dualSpace, Nc));
14229566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSetDM(fvm->dualSpace, K));
14239566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&K));
14249566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSimpleSetDimension(fvm->dualSpace, Nc));
1425c0ce001eSMatthew G. Knepley     /* Should we be using PetscFVGetQuadrature() here? */
1426c0ce001eSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
1427c0ce001eSMatthew G. Knepley       PetscQuadrature qc;
1428c0ce001eSMatthew G. Knepley       PetscReal      *points, *weights;
1429c0ce001eSMatthew G. Knepley 
14309566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qc));
14319566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(dim, &points));
14329566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(Nc, &weights));
1433c0ce001eSMatthew G. Knepley       weights[c] = 1.0;
14349566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureSetData(qc, dim, Nc, 1, points, weights));
14359566063dSJacob Faibussowitsch       PetscCall(PetscDualSpaceSimpleSetFunctional(fvm->dualSpace, c, qc));
14369566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureDestroy(&qc));
1437c0ce001eSMatthew G. Knepley     }
14389566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSetUp(fvm->dualSpace));
1439c0ce001eSMatthew G. Knepley   }
1440c0ce001eSMatthew G. Knepley   *sp = fvm->dualSpace;
1441c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1442c0ce001eSMatthew G. Knepley }
1443c0ce001eSMatthew G. Knepley 
1444c0ce001eSMatthew G. Knepley /*@
1445c0ce001eSMatthew G. Knepley   PetscFVSetDualSpace - Sets the PetscDualSpace used to define the inner product
1446c0ce001eSMatthew G. Knepley 
1447c0ce001eSMatthew G. Knepley   Not collective
1448c0ce001eSMatthew G. Knepley 
1449c0ce001eSMatthew G. Knepley   Input Parameters:
1450c0ce001eSMatthew G. Knepley + fvm - The PetscFV object
1451c0ce001eSMatthew G. Knepley - sp  - The PetscDualSpace object
1452c0ce001eSMatthew G. Knepley 
1453c0ce001eSMatthew G. Knepley   Level: intermediate
1454c0ce001eSMatthew G. Knepley 
1455c0ce001eSMatthew G. Knepley   Note: A simple dual space is provided automatically, and the user typically will not need to override it.
1456c0ce001eSMatthew G. Knepley 
1457db781477SPatrick Sanan .seealso: `PetscFVCreate()`
1458c0ce001eSMatthew G. Knepley @*/
14599371c9d4SSatish Balay PetscErrorCode PetscFVSetDualSpace(PetscFV fvm, PetscDualSpace sp) {
1460c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1461c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1462c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 2);
14639566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceDestroy(&fvm->dualSpace));
1464c0ce001eSMatthew G. Knepley   fvm->dualSpace = sp;
14659566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)fvm->dualSpace));
1466c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1467c0ce001eSMatthew G. Knepley }
1468c0ce001eSMatthew G. Knepley 
146988f5f89eSMatthew G. Knepley /*@C
1470ef0bb6c7SMatthew G. Knepley   PetscFVGetCellTabulation - Returns the tabulation of the basis functions at the quadrature points
147188f5f89eSMatthew G. Knepley 
147288f5f89eSMatthew G. Knepley   Not collective
147388f5f89eSMatthew G. Knepley 
147488f5f89eSMatthew G. Knepley   Input Parameter:
147588f5f89eSMatthew G. Knepley . fvm - The PetscFV object
147688f5f89eSMatthew G. Knepley 
1477ef0bb6c7SMatthew G. Knepley   Output Parameter:
1478a5b23f4aSJose E. Roman . T - The basis function values and derivatives at quadrature points
147988f5f89eSMatthew G. Knepley 
148088f5f89eSMatthew G. Knepley   Note:
1481ef0bb6c7SMatthew G. Knepley $ T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c
1482ef0bb6c7SMatthew 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
1483ef0bb6c7SMatthew 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
148488f5f89eSMatthew G. Knepley 
148588f5f89eSMatthew G. Knepley   Level: intermediate
148688f5f89eSMatthew G. Knepley 
1487db781477SPatrick Sanan .seealso: `PetscFEGetCellTabulation()`, `PetscFVCreateTabulation()`, `PetscFVGetQuadrature()`, `PetscQuadratureGetData()`
148888f5f89eSMatthew G. Knepley @*/
14899371c9d4SSatish Balay PetscErrorCode PetscFVGetCellTabulation(PetscFV fvm, PetscTabulation *T) {
1490c0ce001eSMatthew G. Knepley   PetscInt         npoints;
1491c0ce001eSMatthew G. Knepley   const PetscReal *points;
1492c0ce001eSMatthew G. Knepley 
1493c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1494c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1495ef0bb6c7SMatthew G. Knepley   PetscValidPointer(T, 2);
14969566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureGetData(fvm->quadrature, NULL, NULL, &npoints, &points, NULL));
14979566063dSJacob Faibussowitsch   if (!fvm->T) PetscCall(PetscFVCreateTabulation(fvm, 1, npoints, points, 1, &fvm->T));
1498ef0bb6c7SMatthew G. Knepley   *T = fvm->T;
1499c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1500c0ce001eSMatthew G. Knepley }
1501c0ce001eSMatthew G. Knepley 
150288f5f89eSMatthew G. Knepley /*@C
1503ef0bb6c7SMatthew G. Knepley   PetscFVCreateTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided.
150488f5f89eSMatthew G. Knepley 
150588f5f89eSMatthew G. Knepley   Not collective
150688f5f89eSMatthew G. Knepley 
150788f5f89eSMatthew G. Knepley   Input Parameters:
150888f5f89eSMatthew G. Knepley + fvm     - The PetscFV object
1509ef0bb6c7SMatthew G. Knepley . nrepl   - The number of replicas
1510ef0bb6c7SMatthew G. Knepley . npoints - The number of tabulation points in a replica
1511ef0bb6c7SMatthew G. Knepley . points  - The tabulation point coordinates
1512ef0bb6c7SMatthew G. Knepley - K       - The order of derivative to tabulate
151388f5f89eSMatthew G. Knepley 
1514ef0bb6c7SMatthew G. Knepley   Output Parameter:
1515a5b23f4aSJose E. Roman . T - The basis function values and derivative at tabulation points
151688f5f89eSMatthew G. Knepley 
151788f5f89eSMatthew G. Knepley   Note:
1518ef0bb6c7SMatthew G. Knepley $ T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c
1519ef0bb6c7SMatthew 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
1520ef0bb6c7SMatthew 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
152188f5f89eSMatthew G. Knepley 
152288f5f89eSMatthew G. Knepley   Level: intermediate
152388f5f89eSMatthew G. Knepley 
1524db781477SPatrick Sanan .seealso: `PetscFECreateTabulation()`, `PetscTabulationDestroy()`, `PetscFEGetCellTabulation()`
152588f5f89eSMatthew G. Knepley @*/
15269371c9d4SSatish Balay PetscErrorCode PetscFVCreateTabulation(PetscFV fvm, PetscInt nrepl, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation *T) {
1527c0ce001eSMatthew G. Knepley   PetscInt pdim = 1; /* Dimension of approximation space P */
1528ef0bb6c7SMatthew G. Knepley   PetscInt cdim;     /* Spatial dimension */
1529ef0bb6c7SMatthew G. Knepley   PetscInt Nc;       /* Field components */
1530ef0bb6c7SMatthew G. Knepley   PetscInt k, p, d, c, e;
1531c0ce001eSMatthew G. Knepley 
1532c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1533ef0bb6c7SMatthew G. Knepley   if (!npoints || K < 0) {
1534ef0bb6c7SMatthew G. Knepley     *T = NULL;
1535c0ce001eSMatthew G. Knepley     PetscFunctionReturn(0);
1536c0ce001eSMatthew G. Knepley   }
1537c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1538dadcf809SJacob Faibussowitsch   PetscValidRealPointer(points, 4);
153940a2aa30SMatthew G. Knepley   PetscValidPointer(T, 6);
15409566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &cdim));
15419566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fvm, &Nc));
15429566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(1, T));
1543ef0bb6c7SMatthew G. Knepley   (*T)->K    = !cdim ? 0 : K;
1544ef0bb6c7SMatthew G. Knepley   (*T)->Nr   = nrepl;
1545ef0bb6c7SMatthew G. Knepley   (*T)->Np   = npoints;
1546ef0bb6c7SMatthew G. Knepley   (*T)->Nb   = pdim;
1547ef0bb6c7SMatthew G. Knepley   (*T)->Nc   = Nc;
1548ef0bb6c7SMatthew G. Knepley   (*T)->cdim = cdim;
15499566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1((*T)->K + 1, &(*T)->T));
155048a46eb9SPierre Jolivet   for (k = 0; k <= (*T)->K; ++k) PetscCall(PetscMalloc1(nrepl * npoints * pdim * Nc * PetscPowInt(cdim, k), &(*T)->T[k]));
15519371c9d4SSatish Balay   if (K >= 0) {
15529371c9d4SSatish Balay     for (p = 0; p < nrepl * npoints; ++p)
15539371c9d4SSatish Balay       for (d = 0; d < pdim; ++d)
15549371c9d4SSatish Balay         for (c = 0; c < Nc; ++c) (*T)->T[0][(p * pdim + d) * Nc + c] = 1.0;
1555ef0bb6c7SMatthew G. Knepley   }
15569371c9d4SSatish Balay   if (K >= 1) {
15579371c9d4SSatish Balay     for (p = 0; p < nrepl * npoints; ++p)
15589371c9d4SSatish Balay       for (d = 0; d < pdim; ++d)
15599371c9d4SSatish Balay         for (c = 0; c < Nc; ++c)
15609371c9d4SSatish Balay           for (e = 0; e < cdim; ++e) (*T)->T[1][((p * pdim + d) * Nc + c) * cdim + e] = 0.0;
15619371c9d4SSatish Balay   }
15629371c9d4SSatish Balay   if (K >= 2) {
15639371c9d4SSatish Balay     for (p = 0; p < nrepl * npoints; ++p)
15649371c9d4SSatish Balay       for (d = 0; d < pdim; ++d)
15659371c9d4SSatish Balay         for (c = 0; c < Nc; ++c)
15669371c9d4SSatish Balay           for (e = 0; e < cdim * cdim; ++e) (*T)->T[2][((p * pdim + d) * Nc + c) * cdim * cdim + e] = 0.0;
15679371c9d4SSatish Balay   }
1568c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1569c0ce001eSMatthew G. Knepley }
1570c0ce001eSMatthew G. Knepley 
1571c0ce001eSMatthew G. Knepley /*@C
1572c0ce001eSMatthew G. Knepley   PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell
1573c0ce001eSMatthew G. Knepley 
1574c0ce001eSMatthew G. Knepley   Input Parameters:
1575c0ce001eSMatthew G. Knepley + fvm      - The PetscFV object
1576c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained
1577c0ce001eSMatthew G. Knepley - dx       - The vector from the cell centroid to the neighboring cell centroid for each face
1578c0ce001eSMatthew G. Knepley 
157988f5f89eSMatthew G. Knepley   Level: advanced
1580c0ce001eSMatthew G. Knepley 
1581db781477SPatrick Sanan .seealso: `PetscFVCreate()`
1582c0ce001eSMatthew G. Knepley @*/
15839371c9d4SSatish Balay PetscErrorCode PetscFVComputeGradient(PetscFV fvm, PetscInt numFaces, PetscScalar dx[], PetscScalar grad[]) {
1584c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1585c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1586dbbe0bcdSBarry Smith   PetscTryTypeMethod(fvm, computegradient, numFaces, dx, grad);
1587c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1588c0ce001eSMatthew G. Knepley }
1589c0ce001eSMatthew G. Knepley 
159088f5f89eSMatthew G. Knepley /*@C
1591c0ce001eSMatthew G. Knepley   PetscFVIntegrateRHSFunction - Produce the cell residual vector for a chunk of elements by quadrature integration
1592c0ce001eSMatthew G. Knepley 
1593c0ce001eSMatthew G. Knepley   Not collective
1594c0ce001eSMatthew G. Knepley 
1595c0ce001eSMatthew G. Knepley   Input Parameters:
1596c0ce001eSMatthew G. Knepley + fvm          - The PetscFV object for the field being integrated
1597c0ce001eSMatthew G. Knepley . prob         - The PetscDS specifing the discretizations and continuum functions
1598c0ce001eSMatthew G. Knepley . field        - The field being integrated
1599c0ce001eSMatthew G. Knepley . Nf           - The number of faces in the chunk
1600c0ce001eSMatthew G. Knepley . fgeom        - The face geometry for each face in the chunk
1601c0ce001eSMatthew G. Knepley . neighborVol  - The volume for each pair of cells in the chunk
1602c0ce001eSMatthew G. Knepley . uL           - The state from the cell on the left
1603c0ce001eSMatthew G. Knepley - uR           - The state from the cell on the right
1604c0ce001eSMatthew G. Knepley 
1605d8d19677SJose E. Roman   Output Parameters:
1606c0ce001eSMatthew G. Knepley + fluxL        - the left fluxes for each face
1607c0ce001eSMatthew G. Knepley - fluxR        - the right fluxes for each face
160888f5f89eSMatthew G. Knepley 
160988f5f89eSMatthew G. Knepley   Level: developer
161088f5f89eSMatthew G. Knepley 
1611db781477SPatrick Sanan .seealso: `PetscFVCreate()`
161288f5f89eSMatthew G. Knepley @*/
16139371c9d4SSatish Balay PetscErrorCode PetscFVIntegrateRHSFunction(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) {
1614c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1615c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1616dbbe0bcdSBarry Smith   PetscTryTypeMethod(fvm, integraterhsfunction, prob, field, Nf, fgeom, neighborVol, uL, uR, fluxL, fluxR);
1617c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1618c0ce001eSMatthew G. Knepley }
1619c0ce001eSMatthew G. Knepley 
1620c0ce001eSMatthew G. Knepley /*@
1621c0ce001eSMatthew G. Knepley   PetscFVRefine - Create a "refined" PetscFV object that refines the reference cell into smaller copies. This is typically used
1622c0ce001eSMatthew 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
1623c0ce001eSMatthew G. Knepley   sparsity). It is also used to create an interpolation between regularly refined meshes.
1624c0ce001eSMatthew G. Knepley 
1625c0ce001eSMatthew G. Knepley   Input Parameter:
1626c0ce001eSMatthew G. Knepley . fv - The initial PetscFV
1627c0ce001eSMatthew G. Knepley 
1628c0ce001eSMatthew G. Knepley   Output Parameter:
1629c0ce001eSMatthew G. Knepley . fvRef - The refined PetscFV
1630c0ce001eSMatthew G. Knepley 
163188f5f89eSMatthew G. Knepley   Level: advanced
1632c0ce001eSMatthew G. Knepley 
1633db781477SPatrick Sanan .seealso: `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()`
1634c0ce001eSMatthew G. Knepley @*/
16359371c9d4SSatish Balay PetscErrorCode PetscFVRefine(PetscFV fv, PetscFV *fvRef) {
1636c0ce001eSMatthew G. Knepley   PetscDualSpace  Q, Qref;
1637c0ce001eSMatthew G. Knepley   DM              K, Kref;
1638c0ce001eSMatthew G. Knepley   PetscQuadrature q, qref;
1639412e9a14SMatthew G. Knepley   DMPolytopeType  ct;
1640012bc364SMatthew G. Knepley   DMPlexTransform tr;
1641c0ce001eSMatthew G. Knepley   PetscReal      *v0;
1642c0ce001eSMatthew G. Knepley   PetscReal      *jac, *invjac;
1643c0ce001eSMatthew G. Knepley   PetscInt        numComp, numSubelements, s;
1644c0ce001eSMatthew G. Knepley 
1645c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
16469566063dSJacob Faibussowitsch   PetscCall(PetscFVGetDualSpace(fv, &Q));
16479566063dSJacob Faibussowitsch   PetscCall(PetscFVGetQuadrature(fv, &q));
16489566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceGetDM(Q, &K));
1649c0ce001eSMatthew G. Knepley   /* Create dual space */
16509566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceDuplicate(Q, &Qref));
16519566063dSJacob Faibussowitsch   PetscCall(DMRefine(K, PetscObjectComm((PetscObject)fv), &Kref));
16529566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceSetDM(Qref, Kref));
16539566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&Kref));
16549566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceSetUp(Qref));
1655c0ce001eSMatthew G. Knepley   /* Create volume */
16569566063dSJacob Faibussowitsch   PetscCall(PetscFVCreate(PetscObjectComm((PetscObject)fv), fvRef));
16579566063dSJacob Faibussowitsch   PetscCall(PetscFVSetDualSpace(*fvRef, Qref));
16589566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fv, &numComp));
16599566063dSJacob Faibussowitsch   PetscCall(PetscFVSetNumComponents(*fvRef, numComp));
16609566063dSJacob Faibussowitsch   PetscCall(PetscFVSetUp(*fvRef));
1661c0ce001eSMatthew G. Knepley   /* Create quadrature */
16629566063dSJacob Faibussowitsch   PetscCall(DMPlexGetCellType(K, 0, &ct));
16639566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformCreate(PETSC_COMM_SELF, &tr));
16649566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR));
16659566063dSJacob Faibussowitsch   PetscCall(DMPlexRefineRegularGetAffineTransforms(tr, ct, &numSubelements, &v0, &jac, &invjac));
16669566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref));
16679566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceSimpleSetDimension(Qref, numSubelements));
1668c0ce001eSMatthew G. Knepley   for (s = 0; s < numSubelements; ++s) {
1669c0ce001eSMatthew G. Knepley     PetscQuadrature  qs;
1670c0ce001eSMatthew G. Knepley     const PetscReal *points, *weights;
1671c0ce001eSMatthew G. Knepley     PetscReal       *p, *w;
1672c0ce001eSMatthew G. Knepley     PetscInt         dim, Nc, npoints, np;
1673c0ce001eSMatthew G. Knepley 
16749566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qs));
16759566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureGetData(q, &dim, &Nc, &npoints, &points, &weights));
1676c0ce001eSMatthew G. Knepley     np = npoints / numSubelements;
16779566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(np * dim, &p));
16789566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(np * Nc, &w));
16799566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(p, &points[s * np * dim], np * dim));
16809566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(w, &weights[s * np * Nc], np * Nc));
16819566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureSetData(qs, dim, Nc, np, p, w));
16829566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSimpleSetFunctional(Qref, s, qs));
16839566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureDestroy(&qs));
1684c0ce001eSMatthew G. Knepley   }
16859566063dSJacob Faibussowitsch   PetscCall(PetscFVSetQuadrature(*fvRef, qref));
16869566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformDestroy(&tr));
16879566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureDestroy(&qref));
16889566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceDestroy(&Qref));
1689c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1690c0ce001eSMatthew G. Knepley }
1691c0ce001eSMatthew G. Knepley 
16929371c9d4SSatish Balay static PetscErrorCode PetscFVDestroy_Upwind(PetscFV fvm) {
1693c0ce001eSMatthew G. Knepley   PetscFV_Upwind *b = (PetscFV_Upwind *)fvm->data;
1694c0ce001eSMatthew G. Knepley 
1695c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
16969566063dSJacob Faibussowitsch   PetscCall(PetscFree(b));
1697c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1698c0ce001eSMatthew G. Knepley }
1699c0ce001eSMatthew G. Knepley 
17009371c9d4SSatish Balay static PetscErrorCode PetscFVView_Upwind_Ascii(PetscFV fv, PetscViewer viewer) {
1701c0ce001eSMatthew G. Knepley   PetscInt          Nc, c;
1702c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
1703c0ce001eSMatthew G. Knepley 
1704c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
17059566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fv, &Nc));
17069566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
17079566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Upwind Finite Volume:\n"));
170863a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  num components: %" PetscInt_FMT "\n", Nc));
1709c0ce001eSMatthew G. Knepley   for (c = 0; c < Nc; c++) {
171048a46eb9SPierre Jolivet     if (fv->componentNames[c]) PetscCall(PetscViewerASCIIPrintf(viewer, "    component %" PetscInt_FMT ": %s\n", c, fv->componentNames[c]));
1711c0ce001eSMatthew G. Knepley   }
1712c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1713c0ce001eSMatthew G. Knepley }
1714c0ce001eSMatthew G. Knepley 
17159371c9d4SSatish Balay static PetscErrorCode PetscFVView_Upwind(PetscFV fv, PetscViewer viewer) {
1716c0ce001eSMatthew G. Knepley   PetscBool iascii;
1717c0ce001eSMatthew G. Knepley 
1718c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1719c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1);
1720c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
17219566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
17229566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscFVView_Upwind_Ascii(fv, viewer));
1723c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1724c0ce001eSMatthew G. Knepley }
1725c0ce001eSMatthew G. Knepley 
17269371c9d4SSatish Balay static PetscErrorCode PetscFVSetUp_Upwind(PetscFV fvm) {
1727c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1728c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1729c0ce001eSMatthew G. Knepley }
1730c0ce001eSMatthew G. Knepley 
1731c0ce001eSMatthew G. Knepley /*
1732c0ce001eSMatthew G. Knepley   neighborVol[f*2+0] contains the left  geom
1733c0ce001eSMatthew G. Knepley   neighborVol[f*2+1] contains the right geom
1734c0ce001eSMatthew G. Knepley */
17359371c9d4SSatish Balay static PetscErrorCode PetscFVIntegrateRHSFunction_Upwind(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) {
1736c0ce001eSMatthew G. Knepley   void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *);
1737c0ce001eSMatthew G. Knepley   void              *rctx;
1738c0ce001eSMatthew G. Knepley   PetscScalar       *flux = fvm->fluxWork;
1739c0ce001eSMatthew G. Knepley   const PetscScalar *constants;
1740c0ce001eSMatthew G. Knepley   PetscInt           dim, numConstants, pdim, totDim, Nc, off, f, d;
1741c0ce001eSMatthew G. Knepley 
1742c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
17439566063dSJacob Faibussowitsch   PetscCall(PetscDSGetTotalComponents(prob, &Nc));
17449566063dSJacob Faibussowitsch   PetscCall(PetscDSGetTotalDimension(prob, &totDim));
17459566063dSJacob Faibussowitsch   PetscCall(PetscDSGetFieldOffset(prob, field, &off));
17469566063dSJacob Faibussowitsch   PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann));
17479566063dSJacob Faibussowitsch   PetscCall(PetscDSGetContext(prob, field, &rctx));
17489566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &numConstants, &constants));
17499566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
17509566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fvm, &pdim));
1751c0ce001eSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
1752c0ce001eSMatthew G. Knepley     (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f * Nc], &uR[f * Nc], numConstants, constants, flux, rctx);
1753c0ce001eSMatthew G. Knepley     for (d = 0; d < pdim; ++d) {
1754c0ce001eSMatthew G. Knepley       fluxL[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 0];
1755c0ce001eSMatthew G. Knepley       fluxR[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 1];
1756c0ce001eSMatthew G. Knepley     }
1757c0ce001eSMatthew G. Knepley   }
1758c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1759c0ce001eSMatthew G. Knepley }
1760c0ce001eSMatthew G. Knepley 
17619371c9d4SSatish Balay static PetscErrorCode PetscFVInitialize_Upwind(PetscFV fvm) {
1762c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1763c0ce001eSMatthew G. Knepley   fvm->ops->setfromoptions       = NULL;
1764c0ce001eSMatthew G. Knepley   fvm->ops->setup                = PetscFVSetUp_Upwind;
1765c0ce001eSMatthew G. Knepley   fvm->ops->view                 = PetscFVView_Upwind;
1766c0ce001eSMatthew G. Knepley   fvm->ops->destroy              = PetscFVDestroy_Upwind;
1767c0ce001eSMatthew G. Knepley   fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_Upwind;
1768c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1769c0ce001eSMatthew G. Knepley }
1770c0ce001eSMatthew G. Knepley 
1771c0ce001eSMatthew G. Knepley /*MC
1772c0ce001eSMatthew G. Knepley   PETSCFVUPWIND = "upwind" - A PetscFV object
1773c0ce001eSMatthew G. Knepley 
1774c0ce001eSMatthew G. Knepley   Level: intermediate
1775c0ce001eSMatthew G. Knepley 
1776db781477SPatrick Sanan .seealso: `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()`
1777c0ce001eSMatthew G. Knepley M*/
1778c0ce001eSMatthew G. Knepley 
17799371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscFVCreate_Upwind(PetscFV fvm) {
1780c0ce001eSMatthew G. Knepley   PetscFV_Upwind *b;
1781c0ce001eSMatthew G. Knepley 
1782c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1783c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1784*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
1785c0ce001eSMatthew G. Knepley   fvm->data = b;
1786c0ce001eSMatthew G. Knepley 
17879566063dSJacob Faibussowitsch   PetscCall(PetscFVInitialize_Upwind(fvm));
1788c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1789c0ce001eSMatthew G. Knepley }
1790c0ce001eSMatthew G. Knepley 
1791c0ce001eSMatthew G. Knepley #include <petscblaslapack.h>
1792c0ce001eSMatthew G. Knepley 
17939371c9d4SSatish Balay static PetscErrorCode PetscFVDestroy_LeastSquares(PetscFV fvm) {
1794c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data;
1795c0ce001eSMatthew G. Knepley 
1796c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
17979566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)fvm, "PetscFVLeastSquaresSetMaxFaces_C", NULL));
17989566063dSJacob Faibussowitsch   PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work));
17999566063dSJacob Faibussowitsch   PetscCall(PetscFree(ls));
1800c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1801c0ce001eSMatthew G. Knepley }
1802c0ce001eSMatthew G. Knepley 
18039371c9d4SSatish Balay static PetscErrorCode PetscFVView_LeastSquares_Ascii(PetscFV fv, PetscViewer viewer) {
1804c0ce001eSMatthew G. Knepley   PetscInt          Nc, c;
1805c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
1806c0ce001eSMatthew G. Knepley 
1807c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
18089566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fv, &Nc));
18099566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
18109566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Finite Volume with Least Squares Reconstruction:\n"));
181163a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  num components: %" PetscInt_FMT "\n", Nc));
1812c0ce001eSMatthew G. Knepley   for (c = 0; c < Nc; c++) {
181348a46eb9SPierre Jolivet     if (fv->componentNames[c]) PetscCall(PetscViewerASCIIPrintf(viewer, "    component %" PetscInt_FMT ": %s\n", c, fv->componentNames[c]));
1814c0ce001eSMatthew G. Knepley   }
1815c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1816c0ce001eSMatthew G. Knepley }
1817c0ce001eSMatthew G. Knepley 
18189371c9d4SSatish Balay static PetscErrorCode PetscFVView_LeastSquares(PetscFV fv, PetscViewer viewer) {
1819c0ce001eSMatthew G. Knepley   PetscBool iascii;
1820c0ce001eSMatthew G. Knepley 
1821c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1822c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1);
1823c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
18249566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
18259566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscFVView_LeastSquares_Ascii(fv, viewer));
1826c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1827c0ce001eSMatthew G. Knepley }
1828c0ce001eSMatthew G. Knepley 
18299371c9d4SSatish Balay static PetscErrorCode PetscFVSetUp_LeastSquares(PetscFV fvm) {
1830c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1831c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1832c0ce001eSMatthew G. Knepley }
1833c0ce001eSMatthew G. Knepley 
1834c0ce001eSMatthew G. Knepley /* Overwrites A. Can only handle full-rank problems with m>=n */
18359371c9d4SSatish Balay static PetscErrorCode PetscFVLeastSquaresPseudoInverse_Static(PetscInt m, PetscInt mstride, PetscInt n, PetscScalar *A, PetscScalar *Ainv, PetscScalar *tau, PetscInt worksize, PetscScalar *work) {
1836c0ce001eSMatthew G. Knepley   PetscBool    debug = PETSC_FALSE;
1837c0ce001eSMatthew G. Knepley   PetscBLASInt M, N, K, lda, ldb, ldwork, info;
1838c0ce001eSMatthew G. Knepley   PetscScalar *R, *Q, *Aback, Alpha;
1839c0ce001eSMatthew G. Knepley 
1840c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1841c0ce001eSMatthew G. Knepley   if (debug) {
18429566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m * n, &Aback));
18439566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(Aback, A, m * n));
1844c0ce001eSMatthew G. Knepley   }
1845c0ce001eSMatthew G. Knepley 
18469566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m, &M));
18479566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n, &N));
18489566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(mstride, &lda));
18499566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(worksize, &ldwork));
18509566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
1851792fecdfSBarry Smith   PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&M, &N, A, &lda, tau, work, &ldwork, &info));
18529566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
185328b400f6SJacob Faibussowitsch   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xGEQRF error");
1854c0ce001eSMatthew G. Knepley   R = A; /* Upper triangular part of A now contains R, the rest contains the elementary reflectors */
1855c0ce001eSMatthew G. Knepley 
1856c0ce001eSMatthew G. Knepley   /* Extract an explicit representation of Q */
1857c0ce001eSMatthew G. Knepley   Q = Ainv;
18589566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(Q, A, mstride * n));
1859c0ce001eSMatthew G. Knepley   K = N; /* full rank */
1860792fecdfSBarry Smith   PetscCallBLAS("LAPACKorgqr", LAPACKorgqr_(&M, &N, &K, Q, &lda, tau, work, &ldwork, &info));
186128b400f6SJacob Faibussowitsch   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xORGQR/xUNGQR error");
1862c0ce001eSMatthew G. Knepley 
1863c0ce001eSMatthew G. Knepley   /* Compute A^{-T} = (R^{-1} Q^T)^T = Q R^{-T} */
1864c0ce001eSMatthew G. Knepley   Alpha = 1.0;
1865c0ce001eSMatthew G. Knepley   ldb   = lda;
1866c0ce001eSMatthew G. Knepley   BLAStrsm_("Right", "Upper", "ConjugateTranspose", "NotUnitTriangular", &M, &N, &Alpha, R, &lda, Q, &ldb);
1867c0ce001eSMatthew G. Knepley   /* Ainv is Q, overwritten with inverse */
1868c0ce001eSMatthew G. Knepley 
1869c0ce001eSMatthew G. Knepley   if (debug) { /* Check that pseudo-inverse worked */
1870c0ce001eSMatthew G. Knepley     PetscScalar  Beta = 0.0;
1871c0ce001eSMatthew G. Knepley     PetscBLASInt ldc;
1872c0ce001eSMatthew G. Knepley     K   = N;
1873c0ce001eSMatthew G. Knepley     ldc = N;
1874c0ce001eSMatthew G. Knepley     BLASgemm_("ConjugateTranspose", "Normal", &N, &K, &M, &Alpha, Ainv, &lda, Aback, &ldb, &Beta, work, &ldc);
18759566063dSJacob Faibussowitsch     PetscCall(PetscScalarView(n * n, work, PETSC_VIEWER_STDOUT_SELF));
18769566063dSJacob Faibussowitsch     PetscCall(PetscFree(Aback));
1877c0ce001eSMatthew G. Knepley   }
1878c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1879c0ce001eSMatthew G. Knepley }
1880c0ce001eSMatthew G. Knepley 
1881c0ce001eSMatthew G. Knepley /* Overwrites A. Can handle degenerate problems and m<n. */
18829371c9d4SSatish Balay static PetscErrorCode PetscFVLeastSquaresPseudoInverseSVD_Static(PetscInt m, PetscInt mstride, PetscInt n, PetscScalar *A, PetscScalar *Ainv, PetscScalar *tau, PetscInt worksize, PetscScalar *work) {
18836bb27163SBarry Smith   PetscScalar *Brhs;
1884c0ce001eSMatthew G. Knepley   PetscScalar *tmpwork;
1885c0ce001eSMatthew G. Knepley   PetscReal    rcond;
1886c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX)
1887c0ce001eSMatthew G. Knepley   PetscInt   rworkSize;
1888c0ce001eSMatthew G. Knepley   PetscReal *rwork;
1889c0ce001eSMatthew G. Knepley #endif
1890c0ce001eSMatthew G. Knepley   PetscInt     i, j, maxmn;
1891c0ce001eSMatthew G. Knepley   PetscBLASInt M, N, lda, ldb, ldwork;
1892c0ce001eSMatthew G. Knepley   PetscBLASInt nrhs, irank, info;
1893c0ce001eSMatthew G. Knepley 
1894c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1895c0ce001eSMatthew G. Knepley   /* initialize to identity */
1896736d4f42SpierreXVI   tmpwork = work;
1897736d4f42SpierreXVI   Brhs    = Ainv;
1898c0ce001eSMatthew G. Knepley   maxmn   = PetscMax(m, n);
1899c0ce001eSMatthew G. Knepley   for (j = 0; j < maxmn; j++) {
1900c0ce001eSMatthew G. Knepley     for (i = 0; i < maxmn; i++) Brhs[i + j * maxmn] = 1.0 * (i == j);
1901c0ce001eSMatthew G. Knepley   }
1902c0ce001eSMatthew G. Knepley 
19039566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m, &M));
19049566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n, &N));
19059566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(mstride, &lda));
19069566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(maxmn, &ldb));
19079566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(worksize, &ldwork));
1908c0ce001eSMatthew G. Knepley   rcond = -1;
1909c0ce001eSMatthew G. Knepley   nrhs  = M;
1910c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX)
1911c0ce001eSMatthew G. Knepley   rworkSize = 5 * PetscMin(M, N);
19129566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(rworkSize, &rwork));
19136bb27163SBarry Smith   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
1914792fecdfSBarry Smith   PetscCallBLAS("LAPACKgelss", LAPACKgelss_(&M, &N, &nrhs, A, &lda, Brhs, &ldb, (PetscReal *)tau, &rcond, &irank, tmpwork, &ldwork, rwork, &info));
19159566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
19169566063dSJacob Faibussowitsch   PetscCall(PetscFree(rwork));
1917c0ce001eSMatthew G. Knepley #else
1918c0ce001eSMatthew G. Knepley   nrhs = M;
19196bb27163SBarry Smith   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
1920792fecdfSBarry Smith   PetscCallBLAS("LAPACKgelss", LAPACKgelss_(&M, &N, &nrhs, A, &lda, Brhs, &ldb, (PetscReal *)tau, &rcond, &irank, tmpwork, &ldwork, &info));
19219566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
1922c0ce001eSMatthew G. Knepley #endif
192328b400f6SJacob Faibussowitsch   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xGELSS error");
1924c0ce001eSMatthew G. Knepley   /* The following check should be turned into a diagnostic as soon as someone wants to do this intentionally */
192508401ef6SPierre 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");
1926c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1927c0ce001eSMatthew G. Knepley }
1928c0ce001eSMatthew G. Knepley 
1929c0ce001eSMatthew G. Knepley #if 0
1930c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresDebugCell_Static(PetscFV fvm, PetscInt cell, DM dm, DM dmFace, PetscScalar *fgeom, DM dmCell, PetscScalar *cgeom)
1931c0ce001eSMatthew G. Knepley {
1932c0ce001eSMatthew G. Knepley   PetscReal       grad[2] = {0, 0};
1933c0ce001eSMatthew G. Knepley   const PetscInt *faces;
1934c0ce001eSMatthew G. Knepley   PetscInt        numFaces, f;
1935c0ce001eSMatthew G. Knepley 
1936c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
19379566063dSJacob Faibussowitsch   PetscCall(DMPlexGetConeSize(dm, cell, &numFaces));
19389566063dSJacob Faibussowitsch   PetscCall(DMPlexGetCone(dm, cell, &faces));
1939c0ce001eSMatthew G. Knepley   for (f = 0; f < numFaces; ++f) {
1940c0ce001eSMatthew G. Knepley     const PetscInt *fcells;
1941c0ce001eSMatthew G. Knepley     const CellGeom *cg1;
1942c0ce001eSMatthew G. Knepley     const FaceGeom *fg;
1943c0ce001eSMatthew G. Knepley 
19449566063dSJacob Faibussowitsch     PetscCall(DMPlexGetSupport(dm, faces[f], &fcells));
19459566063dSJacob Faibussowitsch     PetscCall(DMPlexPointLocalRead(dmFace, faces[f], fgeom, &fg));
1946c0ce001eSMatthew G. Knepley     for (i = 0; i < 2; ++i) {
1947c0ce001eSMatthew G. Knepley       PetscScalar du;
1948c0ce001eSMatthew G. Knepley 
1949c0ce001eSMatthew G. Knepley       if (fcells[i] == c) continue;
19509566063dSJacob Faibussowitsch       PetscCall(DMPlexPointLocalRead(dmCell, fcells[i], cgeom, &cg1));
1951c0ce001eSMatthew G. Knepley       du   = cg1->centroid[0] + 3*cg1->centroid[1] - (cg->centroid[0] + 3*cg->centroid[1]);
1952c0ce001eSMatthew G. Knepley       grad[0] += fg->grad[!i][0] * du;
1953c0ce001eSMatthew G. Knepley       grad[1] += fg->grad[!i][1] * du;
1954c0ce001eSMatthew G. Knepley     }
1955c0ce001eSMatthew G. Knepley   }
19569566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_SELF, "cell[%d] grad (%g, %g)\n", cell, grad[0], grad[1]));
1957c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1958c0ce001eSMatthew G. Knepley }
1959c0ce001eSMatthew G. Knepley #endif
1960c0ce001eSMatthew G. Knepley 
1961c0ce001eSMatthew G. Knepley /*
1962c0ce001eSMatthew G. Knepley   PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell
1963c0ce001eSMatthew G. Knepley 
1964c0ce001eSMatthew G. Knepley   Input Parameters:
1965c0ce001eSMatthew G. Knepley + fvm      - The PetscFV object
1966c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained
1967c0ce001eSMatthew G. Knepley . dx       - The vector from the cell centroid to the neighboring cell centroid for each face
1968c0ce001eSMatthew G. Knepley 
1969c0ce001eSMatthew G. Knepley   Level: developer
1970c0ce001eSMatthew G. Knepley 
1971db781477SPatrick Sanan .seealso: `PetscFVCreate()`
1972c0ce001eSMatthew G. Knepley */
19739371c9d4SSatish Balay static PetscErrorCode PetscFVComputeGradient_LeastSquares(PetscFV fvm, PetscInt numFaces, const PetscScalar dx[], PetscScalar grad[]) {
1974c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls       = (PetscFV_LeastSquares *)fvm->data;
1975c0ce001eSMatthew G. Knepley   const PetscBool       useSVD   = PETSC_TRUE;
1976c0ce001eSMatthew G. Knepley   const PetscInt        maxFaces = ls->maxFaces;
1977c0ce001eSMatthew G. Knepley   PetscInt              dim, f, d;
1978c0ce001eSMatthew G. Knepley 
1979c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1980c0ce001eSMatthew G. Knepley   if (numFaces > maxFaces) {
198108401ef6SPierre Jolivet     PetscCheck(maxFaces >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Reconstruction has not been initialized, call PetscFVLeastSquaresSetMaxFaces()");
198263a3b9bcSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of input faces %" PetscInt_FMT " > %" PetscInt_FMT " maxfaces", numFaces, maxFaces);
1983c0ce001eSMatthew G. Knepley   }
19849566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
1985c0ce001eSMatthew G. Knepley   for (f = 0; f < numFaces; ++f) {
1986c0ce001eSMatthew G. Knepley     for (d = 0; d < dim; ++d) ls->B[d * maxFaces + f] = dx[f * dim + d];
1987c0ce001eSMatthew G. Knepley   }
1988c0ce001eSMatthew G. Knepley   /* Overwrites B with garbage, returns Binv in row-major format */
1989736d4f42SpierreXVI   if (useSVD) {
1990736d4f42SpierreXVI     PetscInt maxmn = PetscMax(numFaces, dim);
19919566063dSJacob Faibussowitsch     PetscCall(PetscFVLeastSquaresPseudoInverseSVD_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work));
1992736d4f42SpierreXVI     /* Binv shaped in column-major, coldim=maxmn.*/
1993736d4f42SpierreXVI     for (f = 0; f < numFaces; ++f) {
1994736d4f42SpierreXVI       for (d = 0; d < dim; ++d) grad[f * dim + d] = ls->Binv[d + maxmn * f];
1995736d4f42SpierreXVI     }
1996736d4f42SpierreXVI   } else {
19979566063dSJacob Faibussowitsch     PetscCall(PetscFVLeastSquaresPseudoInverse_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work));
1998736d4f42SpierreXVI     /* Binv shaped in row-major, rowdim=maxFaces.*/
1999c0ce001eSMatthew G. Knepley     for (f = 0; f < numFaces; ++f) {
2000c0ce001eSMatthew G. Knepley       for (d = 0; d < dim; ++d) grad[f * dim + d] = ls->Binv[d * maxFaces + f];
2001c0ce001eSMatthew G. Knepley     }
2002736d4f42SpierreXVI   }
2003c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2004c0ce001eSMatthew G. Knepley }
2005c0ce001eSMatthew G. Knepley 
2006c0ce001eSMatthew G. Knepley /*
2007c0ce001eSMatthew G. Knepley   neighborVol[f*2+0] contains the left  geom
2008c0ce001eSMatthew G. Knepley   neighborVol[f*2+1] contains the right geom
2009c0ce001eSMatthew G. Knepley */
20109371c9d4SSatish Balay static PetscErrorCode PetscFVIntegrateRHSFunction_LeastSquares(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) {
2011c0ce001eSMatthew G. Knepley   void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *);
2012c0ce001eSMatthew G. Knepley   void              *rctx;
2013c0ce001eSMatthew G. Knepley   PetscScalar       *flux = fvm->fluxWork;
2014c0ce001eSMatthew G. Knepley   const PetscScalar *constants;
2015c0ce001eSMatthew G. Knepley   PetscInt           dim, numConstants, pdim, Nc, totDim, off, f, d;
2016c0ce001eSMatthew G. Knepley 
2017c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
20189566063dSJacob Faibussowitsch   PetscCall(PetscDSGetTotalComponents(prob, &Nc));
20199566063dSJacob Faibussowitsch   PetscCall(PetscDSGetTotalDimension(prob, &totDim));
20209566063dSJacob Faibussowitsch   PetscCall(PetscDSGetFieldOffset(prob, field, &off));
20219566063dSJacob Faibussowitsch   PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann));
20229566063dSJacob Faibussowitsch   PetscCall(PetscDSGetContext(prob, field, &rctx));
20239566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &numConstants, &constants));
20249566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
20259566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fvm, &pdim));
2026c0ce001eSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
2027c0ce001eSMatthew G. Knepley     (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f * Nc], &uR[f * Nc], numConstants, constants, flux, rctx);
2028c0ce001eSMatthew G. Knepley     for (d = 0; d < pdim; ++d) {
2029c0ce001eSMatthew G. Knepley       fluxL[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 0];
2030c0ce001eSMatthew G. Knepley       fluxR[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 1];
2031c0ce001eSMatthew G. Knepley     }
2032c0ce001eSMatthew G. Knepley   }
2033c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2034c0ce001eSMatthew G. Knepley }
2035c0ce001eSMatthew G. Knepley 
20369371c9d4SSatish Balay static PetscErrorCode PetscFVLeastSquaresSetMaxFaces_LS(PetscFV fvm, PetscInt maxFaces) {
2037c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data;
2038736d4f42SpierreXVI   PetscInt              dim, m, n, nrhs, minmn, maxmn;
2039c0ce001eSMatthew G. Knepley 
2040c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2041c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
20429566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
20439566063dSJacob Faibussowitsch   PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work));
2044c0ce001eSMatthew G. Knepley   ls->maxFaces = maxFaces;
2045c0ce001eSMatthew G. Knepley   m            = ls->maxFaces;
2046c0ce001eSMatthew G. Knepley   n            = dim;
2047c0ce001eSMatthew G. Knepley   nrhs         = ls->maxFaces;
2048736d4f42SpierreXVI   minmn        = PetscMin(m, n);
2049736d4f42SpierreXVI   maxmn        = PetscMax(m, n);
2050736d4f42SpierreXVI   ls->workSize = 3 * minmn + PetscMax(2 * minmn, PetscMax(maxmn, nrhs)); /* required by LAPACK */
20519566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(m * n, &ls->B, maxmn * maxmn, &ls->Binv, minmn, &ls->tau, ls->workSize, &ls->work));
2052c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2053c0ce001eSMatthew G. Knepley }
2054c0ce001eSMatthew G. Knepley 
20559371c9d4SSatish Balay PetscErrorCode PetscFVInitialize_LeastSquares(PetscFV fvm) {
2056c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2057c0ce001eSMatthew G. Knepley   fvm->ops->setfromoptions       = NULL;
2058c0ce001eSMatthew G. Knepley   fvm->ops->setup                = PetscFVSetUp_LeastSquares;
2059c0ce001eSMatthew G. Knepley   fvm->ops->view                 = PetscFVView_LeastSquares;
2060c0ce001eSMatthew G. Knepley   fvm->ops->destroy              = PetscFVDestroy_LeastSquares;
2061c0ce001eSMatthew G. Knepley   fvm->ops->computegradient      = PetscFVComputeGradient_LeastSquares;
2062c0ce001eSMatthew G. Knepley   fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_LeastSquares;
2063c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2064c0ce001eSMatthew G. Knepley }
2065c0ce001eSMatthew G. Knepley 
2066c0ce001eSMatthew G. Knepley /*MC
2067c0ce001eSMatthew G. Knepley   PETSCFVLEASTSQUARES = "leastsquares" - A PetscFV object
2068c0ce001eSMatthew G. Knepley 
2069c0ce001eSMatthew G. Knepley   Level: intermediate
2070c0ce001eSMatthew G. Knepley 
2071db781477SPatrick Sanan .seealso: `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()`
2072c0ce001eSMatthew G. Knepley M*/
2073c0ce001eSMatthew G. Knepley 
20749371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscFVCreate_LeastSquares(PetscFV fvm) {
2075c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls;
2076c0ce001eSMatthew G. Knepley 
2077c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2078c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
2079*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&ls));
2080c0ce001eSMatthew G. Knepley   fvm->data = ls;
2081c0ce001eSMatthew G. Knepley 
2082c0ce001eSMatthew G. Knepley   ls->maxFaces = -1;
2083c0ce001eSMatthew G. Knepley   ls->workSize = -1;
2084c0ce001eSMatthew G. Knepley   ls->B        = NULL;
2085c0ce001eSMatthew G. Knepley   ls->Binv     = NULL;
2086c0ce001eSMatthew G. Knepley   ls->tau      = NULL;
2087c0ce001eSMatthew G. Knepley   ls->work     = NULL;
2088c0ce001eSMatthew G. Knepley 
20899566063dSJacob Faibussowitsch   PetscCall(PetscFVSetComputeGradients(fvm, PETSC_TRUE));
20909566063dSJacob Faibussowitsch   PetscCall(PetscFVInitialize_LeastSquares(fvm));
20919566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)fvm, "PetscFVLeastSquaresSetMaxFaces_C", PetscFVLeastSquaresSetMaxFaces_LS));
2092c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2093c0ce001eSMatthew G. Knepley }
2094c0ce001eSMatthew G. Knepley 
2095c0ce001eSMatthew G. Knepley /*@
2096c0ce001eSMatthew G. Knepley   PetscFVLeastSquaresSetMaxFaces - Set the maximum number of cell faces for gradient reconstruction
2097c0ce001eSMatthew G. Knepley 
2098c0ce001eSMatthew G. Knepley   Not collective
2099c0ce001eSMatthew G. Knepley 
2100c0ce001eSMatthew G. Knepley   Input parameters:
2101c0ce001eSMatthew G. Knepley + fvm      - The PetscFV object
2102c0ce001eSMatthew G. Knepley - maxFaces - The maximum number of cell faces
2103c0ce001eSMatthew G. Knepley 
2104c0ce001eSMatthew G. Knepley   Level: intermediate
2105c0ce001eSMatthew G. Knepley 
2106db781477SPatrick Sanan .seealso: `PetscFVCreate()`, `PETSCFVLEASTSQUARES`
2107c0ce001eSMatthew G. Knepley @*/
21089371c9d4SSatish Balay PetscErrorCode PetscFVLeastSquaresSetMaxFaces(PetscFV fvm, PetscInt maxFaces) {
2109c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2110c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
2111cac4c232SBarry Smith   PetscTryMethod(fvm, "PetscFVLeastSquaresSetMaxFaces_C", (PetscFV, PetscInt), (fvm, maxFaces));
2112c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2113c0ce001eSMatthew G. Knepley }
2114