xref: /petsc/src/dm/dt/fv/interface/fv.c (revision cac4c232dc4f93991e342196e27ef7b0655dac7b)
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 
48c0ce001eSMatthew G. Knepley .seealso: PetscLimiterRegisterAll(), PetscLimiterRegisterDestroy()
49c0ce001eSMatthew G. Knepley 
50c0ce001eSMatthew G. Knepley @*/
51c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterRegister(const char sname[], PetscErrorCode (*function)(PetscLimiter))
52c0ce001eSMatthew G. Knepley {
53c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
549566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscLimiterList, sname, function));
55c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
56c0ce001eSMatthew G. Knepley }
57c0ce001eSMatthew G. Knepley 
58c0ce001eSMatthew G. Knepley /*@C
59c0ce001eSMatthew G. Knepley   PetscLimiterSetType - Builds a particular PetscLimiter
60c0ce001eSMatthew G. Knepley 
61c0ce001eSMatthew G. Knepley   Collective on lim
62c0ce001eSMatthew G. Knepley 
63c0ce001eSMatthew G. Knepley   Input Parameters:
64c0ce001eSMatthew G. Knepley + lim  - The PetscLimiter object
65c0ce001eSMatthew G. Knepley - name - The kind of limiter
66c0ce001eSMatthew G. Knepley 
67c0ce001eSMatthew G. Knepley   Options Database Key:
68c0ce001eSMatthew G. Knepley . -petsclimiter_type <type> - Sets the PetscLimiter type; use -help for a list of available types
69c0ce001eSMatthew G. Knepley 
70c0ce001eSMatthew G. Knepley   Level: intermediate
71c0ce001eSMatthew G. Knepley 
72c0ce001eSMatthew G. Knepley .seealso: PetscLimiterGetType(), PetscLimiterCreate()
73c0ce001eSMatthew G. Knepley @*/
74c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterSetType(PetscLimiter lim, PetscLimiterType name)
75c0ce001eSMatthew G. Knepley {
76c0ce001eSMatthew G. Knepley   PetscErrorCode (*r)(PetscLimiter);
77c0ce001eSMatthew G. Knepley   PetscBool      match;
78c0ce001eSMatthew G. Knepley 
79c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
80c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
819566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) lim, name, &match));
82c0ce001eSMatthew G. Knepley   if (match) PetscFunctionReturn(0);
83c0ce001eSMatthew G. Knepley 
849566063dSJacob Faibussowitsch   PetscCall(PetscLimiterRegisterAll());
859566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscLimiterList, name, &r));
8628b400f6SJacob Faibussowitsch   PetscCheck(r,PetscObjectComm((PetscObject) lim), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscLimiter type: %s", name);
87c0ce001eSMatthew G. Knepley 
88c0ce001eSMatthew G. Knepley   if (lim->ops->destroy) {
899566063dSJacob Faibussowitsch     PetscCall((*lim->ops->destroy)(lim));
90c0ce001eSMatthew G. Knepley     lim->ops->destroy = NULL;
91c0ce001eSMatthew G. Knepley   }
929566063dSJacob Faibussowitsch   PetscCall((*r)(lim));
939566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject) lim, name));
94c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
95c0ce001eSMatthew G. Knepley }
96c0ce001eSMatthew G. Knepley 
97c0ce001eSMatthew G. Knepley /*@C
98c0ce001eSMatthew G. Knepley   PetscLimiterGetType - Gets the PetscLimiter type name (as a string) from the object.
99c0ce001eSMatthew G. Knepley 
100c0ce001eSMatthew G. Knepley   Not Collective
101c0ce001eSMatthew G. Knepley 
102c0ce001eSMatthew G. Knepley   Input Parameter:
103c0ce001eSMatthew G. Knepley . lim  - The PetscLimiter
104c0ce001eSMatthew G. Knepley 
105c0ce001eSMatthew G. Knepley   Output Parameter:
106c0ce001eSMatthew G. Knepley . name - The PetscLimiter type name
107c0ce001eSMatthew G. Knepley 
108c0ce001eSMatthew G. Knepley   Level: intermediate
109c0ce001eSMatthew G. Knepley 
110c0ce001eSMatthew G. Knepley .seealso: PetscLimiterSetType(), PetscLimiterCreate()
111c0ce001eSMatthew G. Knepley @*/
112c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterGetType(PetscLimiter lim, PetscLimiterType *name)
113c0ce001eSMatthew G. Knepley {
114c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
115c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
116c0ce001eSMatthew G. Knepley   PetscValidPointer(name, 2);
1179566063dSJacob Faibussowitsch   PetscCall(PetscLimiterRegisterAll());
118c0ce001eSMatthew G. Knepley   *name = ((PetscObject) lim)->type_name;
119c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
120c0ce001eSMatthew G. Knepley }
121c0ce001eSMatthew G. Knepley 
122c0ce001eSMatthew G. Knepley /*@C
123fe2efc57SMark    PetscLimiterViewFromOptions - View from Options
124fe2efc57SMark 
125fe2efc57SMark    Collective on PetscLimiter
126fe2efc57SMark 
127fe2efc57SMark    Input Parameters:
128fe2efc57SMark +  A - the PetscLimiter object to view
129736c3998SJose E. Roman .  obj - Optional object
130736c3998SJose E. Roman -  name - command line option
131fe2efc57SMark 
132fe2efc57SMark    Level: intermediate
133fe2efc57SMark .seealso:  PetscLimiter, PetscLimiterView, PetscObjectViewFromOptions(), PetscLimiterCreate()
134fe2efc57SMark @*/
135fe2efc57SMark PetscErrorCode  PetscLimiterViewFromOptions(PetscLimiter A,PetscObject obj,const char name[])
136fe2efc57SMark {
137fe2efc57SMark   PetscFunctionBegin;
138fe2efc57SMark   PetscValidHeaderSpecific(A,PETSCLIMITER_CLASSID,1);
1399566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name));
140fe2efc57SMark   PetscFunctionReturn(0);
141fe2efc57SMark }
142fe2efc57SMark 
143fe2efc57SMark /*@C
144c0ce001eSMatthew G. Knepley   PetscLimiterView - Views a PetscLimiter
145c0ce001eSMatthew G. Knepley 
146c0ce001eSMatthew G. Knepley   Collective on lim
147c0ce001eSMatthew G. Knepley 
148d8d19677SJose E. Roman   Input Parameters:
149c0ce001eSMatthew G. Knepley + lim - the PetscLimiter object to view
150c0ce001eSMatthew G. Knepley - v   - the viewer
151c0ce001eSMatthew G. Knepley 
15288f5f89eSMatthew G. Knepley   Level: beginner
153c0ce001eSMatthew G. Knepley 
154c0ce001eSMatthew G. Knepley .seealso: PetscLimiterDestroy()
155c0ce001eSMatthew G. Knepley @*/
156c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterView(PetscLimiter lim, PetscViewer v)
157c0ce001eSMatthew G. Knepley {
158c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
159c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
1609566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) lim), &v));
1619566063dSJacob Faibussowitsch   if (lim->ops->view) PetscCall((*lim->ops->view)(lim, v));
162c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
163c0ce001eSMatthew G. Knepley }
164c0ce001eSMatthew G. Knepley 
165c0ce001eSMatthew G. Knepley /*@
166c0ce001eSMatthew G. Knepley   PetscLimiterSetFromOptions - sets parameters in a PetscLimiter from the options database
167c0ce001eSMatthew G. Knepley 
168c0ce001eSMatthew G. Knepley   Collective on lim
169c0ce001eSMatthew G. Knepley 
170c0ce001eSMatthew G. Knepley   Input Parameter:
171c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to set options for
172c0ce001eSMatthew G. Knepley 
17388f5f89eSMatthew G. Knepley   Level: intermediate
174c0ce001eSMatthew G. Knepley 
175c0ce001eSMatthew G. Knepley .seealso: PetscLimiterView()
176c0ce001eSMatthew G. Knepley @*/
177c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterSetFromOptions(PetscLimiter lim)
178c0ce001eSMatthew G. Knepley {
179c0ce001eSMatthew G. Knepley   const char    *defaultType;
180c0ce001eSMatthew G. Knepley   char           name[256];
181c0ce001eSMatthew G. Knepley   PetscBool      flg;
182c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
183c0ce001eSMatthew G. Knepley 
184c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
185c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
186c0ce001eSMatthew G. Knepley   if (!((PetscObject) lim)->type_name) defaultType = PETSCLIMITERSIN;
187c0ce001eSMatthew G. Knepley   else                                 defaultType = ((PetscObject) lim)->type_name;
1889566063dSJacob Faibussowitsch   PetscCall(PetscLimiterRegisterAll());
189c0ce001eSMatthew G. Knepley 
1909566063dSJacob Faibussowitsch   ierr = PetscObjectOptionsBegin((PetscObject) lim);PetscCall(ierr);
1919566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petsclimiter_type", "Finite volume slope limiter", "PetscLimiterSetType", PetscLimiterList, defaultType, name, 256, &flg));
192c0ce001eSMatthew G. Knepley   if (flg) {
1939566063dSJacob Faibussowitsch     PetscCall(PetscLimiterSetType(lim, name));
194c0ce001eSMatthew G. Knepley   } else if (!((PetscObject) lim)->type_name) {
1959566063dSJacob Faibussowitsch     PetscCall(PetscLimiterSetType(lim, defaultType));
196c0ce001eSMatthew G. Knepley   }
1979566063dSJacob Faibussowitsch   if (lim->ops->setfromoptions) PetscCall((*lim->ops->setfromoptions)(lim));
198c0ce001eSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
1999566063dSJacob Faibussowitsch   PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) lim));
2009566063dSJacob Faibussowitsch   ierr = PetscOptionsEnd();PetscCall(ierr);
2019566063dSJacob Faibussowitsch   PetscCall(PetscLimiterViewFromOptions(lim, NULL, "-petsclimiter_view"));
202c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
203c0ce001eSMatthew G. Knepley }
204c0ce001eSMatthew G. Knepley 
205c0ce001eSMatthew G. Knepley /*@C
206c0ce001eSMatthew G. Knepley   PetscLimiterSetUp - Construct data structures for the PetscLimiter
207c0ce001eSMatthew G. Knepley 
208c0ce001eSMatthew G. Knepley   Collective on lim
209c0ce001eSMatthew G. Knepley 
210c0ce001eSMatthew G. Knepley   Input Parameter:
211c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to setup
212c0ce001eSMatthew G. Knepley 
21388f5f89eSMatthew G. Knepley   Level: intermediate
214c0ce001eSMatthew G. Knepley 
215c0ce001eSMatthew G. Knepley .seealso: PetscLimiterView(), PetscLimiterDestroy()
216c0ce001eSMatthew G. Knepley @*/
217c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterSetUp(PetscLimiter lim)
218c0ce001eSMatthew G. Knepley {
219c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
220c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
2219566063dSJacob Faibussowitsch   if (lim->ops->setup) PetscCall((*lim->ops->setup)(lim));
222c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
223c0ce001eSMatthew G. Knepley }
224c0ce001eSMatthew G. Knepley 
225c0ce001eSMatthew G. Knepley /*@
226c0ce001eSMatthew G. Knepley   PetscLimiterDestroy - Destroys a PetscLimiter object
227c0ce001eSMatthew G. Knepley 
228c0ce001eSMatthew G. Knepley   Collective on lim
229c0ce001eSMatthew G. Knepley 
230c0ce001eSMatthew G. Knepley   Input Parameter:
231c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to destroy
232c0ce001eSMatthew G. Knepley 
23388f5f89eSMatthew G. Knepley   Level: beginner
234c0ce001eSMatthew G. Knepley 
235c0ce001eSMatthew G. Knepley .seealso: PetscLimiterView()
236c0ce001eSMatthew G. Knepley @*/
237c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterDestroy(PetscLimiter *lim)
238c0ce001eSMatthew G. Knepley {
239c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
240c0ce001eSMatthew G. Knepley   if (!*lim) PetscFunctionReturn(0);
241c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific((*lim), PETSCLIMITER_CLASSID, 1);
242c0ce001eSMatthew G. Knepley 
243ea78f98cSLisandro Dalcin   if (--((PetscObject)(*lim))->refct > 0) {*lim = NULL; PetscFunctionReturn(0);}
244c0ce001eSMatthew G. Knepley   ((PetscObject) (*lim))->refct = 0;
245c0ce001eSMatthew G. Knepley 
2469566063dSJacob Faibussowitsch   if ((*lim)->ops->destroy) PetscCall((*(*lim)->ops->destroy)(*lim));
2479566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(lim));
248c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
249c0ce001eSMatthew G. Knepley }
250c0ce001eSMatthew G. Knepley 
251c0ce001eSMatthew G. Knepley /*@
252c0ce001eSMatthew G. Knepley   PetscLimiterCreate - Creates an empty PetscLimiter object. The type can then be set with PetscLimiterSetType().
253c0ce001eSMatthew G. Knepley 
254c0ce001eSMatthew G. Knepley   Collective
255c0ce001eSMatthew G. Knepley 
256c0ce001eSMatthew G. Knepley   Input Parameter:
257c0ce001eSMatthew G. Knepley . comm - The communicator for the PetscLimiter object
258c0ce001eSMatthew G. Knepley 
259c0ce001eSMatthew G. Knepley   Output Parameter:
260c0ce001eSMatthew G. Knepley . lim - The PetscLimiter object
261c0ce001eSMatthew G. Knepley 
262c0ce001eSMatthew G. Knepley   Level: beginner
263c0ce001eSMatthew G. Knepley 
264c0ce001eSMatthew G. Knepley .seealso: PetscLimiterSetType(), PETSCLIMITERSIN
265c0ce001eSMatthew G. Knepley @*/
266c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterCreate(MPI_Comm comm, PetscLimiter *lim)
267c0ce001eSMatthew G. Knepley {
268c0ce001eSMatthew G. Knepley   PetscLimiter   l;
269c0ce001eSMatthew G. Knepley 
270c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
271c0ce001eSMatthew G. Knepley   PetscValidPointer(lim, 2);
2729566063dSJacob Faibussowitsch   PetscCall(PetscCitationsRegister(LimiterCitation,&Limitercite));
273c0ce001eSMatthew G. Knepley   *lim = NULL;
2749566063dSJacob Faibussowitsch   PetscCall(PetscFVInitializePackage());
275c0ce001eSMatthew G. Knepley 
2769566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(l, PETSCLIMITER_CLASSID, "PetscLimiter", "Finite Volume Slope Limiter", "PetscLimiter", comm, PetscLimiterDestroy, PetscLimiterView));
277c0ce001eSMatthew G. Knepley 
278c0ce001eSMatthew G. Knepley   *lim = l;
279c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
280c0ce001eSMatthew G. Knepley }
281c0ce001eSMatthew G. Knepley 
28288f5f89eSMatthew G. Knepley /*@
28388f5f89eSMatthew G. Knepley   PetscLimiterLimit - Limit the flux
28488f5f89eSMatthew G. Knepley 
28588f5f89eSMatthew G. Knepley   Input Parameters:
28688f5f89eSMatthew G. Knepley + lim  - The PetscLimiter
28788f5f89eSMatthew G. Knepley - flim - The input field
28888f5f89eSMatthew G. Knepley 
28988f5f89eSMatthew G. Knepley   Output Parameter:
29088f5f89eSMatthew G. Knepley . phi  - The limited field
29188f5f89eSMatthew G. Knepley 
29288f5f89eSMatthew G. Knepley Note: Limiters given in symmetric form following Berger, Aftosmis, and Murman 2005
29388f5f89eSMatthew G. Knepley $ The classical flux-limited formulation is psi(r) where
29488f5f89eSMatthew G. Knepley $
29588f5f89eSMatthew G. Knepley $ r = (u[0] - u[-1]) / (u[1] - u[0])
29688f5f89eSMatthew G. Knepley $
29788f5f89eSMatthew G. Knepley $ The second order TVD region is bounded by
29888f5f89eSMatthew G. Knepley $
29988f5f89eSMatthew G. Knepley $ psi_minmod(r) = min(r,1)      and        psi_superbee(r) = min(2, 2r, max(1,r))
30088f5f89eSMatthew G. Knepley $
30188f5f89eSMatthew G. Knepley $ where all limiters are implicitly clipped to be non-negative. A more convenient slope-limited form is psi(r) =
30288f5f89eSMatthew G. Knepley $ phi(r)(r+1)/2 in which the reconstructed interface values are
30388f5f89eSMatthew G. Knepley $
30488f5f89eSMatthew G. Knepley $ u(v) = u[0] + phi(r) (grad u)[0] v
30588f5f89eSMatthew G. Knepley $
30688f5f89eSMatthew G. Knepley $ where v is the vector from centroid to quadrature point. In these variables, the usual limiters become
30788f5f89eSMatthew G. Knepley $
30888f5f89eSMatthew 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))
30988f5f89eSMatthew G. Knepley $
31088f5f89eSMatthew G. Knepley $ For a nicer symmetric formulation, rewrite in terms of
31188f5f89eSMatthew G. Knepley $
31288f5f89eSMatthew G. Knepley $ f = (u[0] - u[-1]) / (u[1] - u[-1])
31388f5f89eSMatthew G. Knepley $
31488f5f89eSMatthew G. Knepley $ where r(f) = f/(1-f). Not that r(1-f) = (1-f)/f = 1/r(f) so the symmetry condition
31588f5f89eSMatthew G. Knepley $
31688f5f89eSMatthew G. Knepley $ phi(r) = phi(1/r)
31788f5f89eSMatthew G. Knepley $
31888f5f89eSMatthew G. Knepley $ becomes
31988f5f89eSMatthew G. Knepley $
32088f5f89eSMatthew G. Knepley $ w(f) = w(1-f).
32188f5f89eSMatthew G. Knepley $
32288f5f89eSMatthew G. Knepley $ The limiters below implement this final form w(f). The reference methods are
32388f5f89eSMatthew G. Knepley $
32488f5f89eSMatthew G. Knepley $ w_minmod(f) = 2 min(f,(1-f))             w_superbee(r) = 4 min((1-f), f)
32588f5f89eSMatthew G. Knepley 
32688f5f89eSMatthew G. Knepley   Level: beginner
32788f5f89eSMatthew G. Knepley 
32888f5f89eSMatthew G. Knepley .seealso: PetscLimiterSetType(), PetscLimiterCreate()
32988f5f89eSMatthew G. Knepley @*/
330c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterLimit(PetscLimiter lim, PetscReal flim, PetscReal *phi)
331c0ce001eSMatthew G. Knepley {
332c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
333c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
334dadcf809SJacob Faibussowitsch   PetscValidRealPointer(phi, 3);
3359566063dSJacob Faibussowitsch   PetscCall((*lim->ops->limit)(lim, flim, phi));
336c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
337c0ce001eSMatthew G. Knepley }
338c0ce001eSMatthew G. Knepley 
33988f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Sin(PetscLimiter lim)
340c0ce001eSMatthew G. Knepley {
341c0ce001eSMatthew G. Knepley   PetscLimiter_Sin *l = (PetscLimiter_Sin *) lim->data;
342c0ce001eSMatthew G. Knepley 
343c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
3449566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
345c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
346c0ce001eSMatthew G. Knepley }
347c0ce001eSMatthew G. Knepley 
34888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Sin_Ascii(PetscLimiter lim, PetscViewer viewer)
349c0ce001eSMatthew G. Knepley {
350c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
351c0ce001eSMatthew G. Knepley 
352c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
3539566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
3549566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Sin Slope Limiter:\n"));
355c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
356c0ce001eSMatthew G. Knepley }
357c0ce001eSMatthew G. Knepley 
35888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Sin(PetscLimiter lim, PetscViewer viewer)
359c0ce001eSMatthew G. Knepley {
360c0ce001eSMatthew G. Knepley   PetscBool      iascii;
361c0ce001eSMatthew G. Knepley 
362c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
363c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
364c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
3659566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
3669566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_Sin_Ascii(lim, viewer));
367c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
368c0ce001eSMatthew G. Knepley }
369c0ce001eSMatthew G. Knepley 
37088f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Sin(PetscLimiter lim, PetscReal f, PetscReal *phi)
371c0ce001eSMatthew G. Knepley {
372c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
373c0ce001eSMatthew G. Knepley   *phi = PetscSinReal(PETSC_PI*PetscMax(0, PetscMin(f, 1)));
374c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
375c0ce001eSMatthew G. Knepley }
376c0ce001eSMatthew G. Knepley 
37788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Sin(PetscLimiter lim)
378c0ce001eSMatthew G. Knepley {
379c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
380c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Sin;
381c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Sin;
382c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Sin;
383c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
384c0ce001eSMatthew G. Knepley }
385c0ce001eSMatthew G. Knepley 
386c0ce001eSMatthew G. Knepley /*MC
387c0ce001eSMatthew G. Knepley   PETSCLIMITERSIN = "sin" - A PetscLimiter object
388c0ce001eSMatthew G. Knepley 
389c0ce001eSMatthew G. Knepley   Level: intermediate
390c0ce001eSMatthew G. Knepley 
391c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType()
392c0ce001eSMatthew G. Knepley M*/
393c0ce001eSMatthew G. Knepley 
394c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Sin(PetscLimiter lim)
395c0ce001eSMatthew G. Knepley {
396c0ce001eSMatthew G. Knepley   PetscLimiter_Sin *l;
397c0ce001eSMatthew G. Knepley 
398c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
399c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
4009566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(lim, &l));
401c0ce001eSMatthew G. Knepley   lim->data = l;
402c0ce001eSMatthew G. Knepley 
4039566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_Sin(lim));
404c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
405c0ce001eSMatthew G. Knepley }
406c0ce001eSMatthew G. Knepley 
40788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Zero(PetscLimiter lim)
408c0ce001eSMatthew G. Knepley {
409c0ce001eSMatthew G. Knepley   PetscLimiter_Zero *l = (PetscLimiter_Zero *) lim->data;
410c0ce001eSMatthew G. Knepley 
411c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
4129566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
413c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
414c0ce001eSMatthew G. Knepley }
415c0ce001eSMatthew G. Knepley 
41688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Zero_Ascii(PetscLimiter lim, PetscViewer viewer)
417c0ce001eSMatthew G. Knepley {
418c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
419c0ce001eSMatthew G. Knepley 
420c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
4219566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
4229566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Zero Slope Limiter:\n"));
423c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
424c0ce001eSMatthew G. Knepley }
425c0ce001eSMatthew G. Knepley 
42688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Zero(PetscLimiter lim, PetscViewer viewer)
427c0ce001eSMatthew G. Knepley {
428c0ce001eSMatthew G. Knepley   PetscBool      iascii;
429c0ce001eSMatthew G. Knepley 
430c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
431c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
432c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
4339566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
4349566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_Zero_Ascii(lim, viewer));
435c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
436c0ce001eSMatthew G. Knepley }
437c0ce001eSMatthew G. Knepley 
43888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Zero(PetscLimiter lim, PetscReal f, PetscReal *phi)
439c0ce001eSMatthew G. Knepley {
440c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
441c0ce001eSMatthew G. Knepley   *phi = 0.0;
442c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
443c0ce001eSMatthew G. Knepley }
444c0ce001eSMatthew G. Knepley 
44588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Zero(PetscLimiter lim)
446c0ce001eSMatthew G. Knepley {
447c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
448c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Zero;
449c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Zero;
450c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Zero;
451c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
452c0ce001eSMatthew G. Knepley }
453c0ce001eSMatthew G. Knepley 
454c0ce001eSMatthew G. Knepley /*MC
455c0ce001eSMatthew G. Knepley   PETSCLIMITERZERO = "zero" - A PetscLimiter object
456c0ce001eSMatthew G. Knepley 
457c0ce001eSMatthew G. Knepley   Level: intermediate
458c0ce001eSMatthew G. Knepley 
459c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType()
460c0ce001eSMatthew G. Knepley M*/
461c0ce001eSMatthew G. Knepley 
462c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Zero(PetscLimiter lim)
463c0ce001eSMatthew G. Knepley {
464c0ce001eSMatthew G. Knepley   PetscLimiter_Zero *l;
465c0ce001eSMatthew G. Knepley 
466c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
467c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
4689566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(lim, &l));
469c0ce001eSMatthew G. Knepley   lim->data = l;
470c0ce001eSMatthew G. Knepley 
4719566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_Zero(lim));
472c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
473c0ce001eSMatthew G. Knepley }
474c0ce001eSMatthew G. Knepley 
47588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_None(PetscLimiter lim)
476c0ce001eSMatthew G. Knepley {
477c0ce001eSMatthew G. Knepley   PetscLimiter_None *l = (PetscLimiter_None *) lim->data;
478c0ce001eSMatthew G. Knepley 
479c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
4809566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
481c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
482c0ce001eSMatthew G. Knepley }
483c0ce001eSMatthew G. Knepley 
48488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_None_Ascii(PetscLimiter lim, PetscViewer viewer)
485c0ce001eSMatthew G. Knepley {
486c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
487c0ce001eSMatthew G. Knepley 
488c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
4899566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
4909566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "None Slope Limiter:\n"));
491c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
492c0ce001eSMatthew G. Knepley }
493c0ce001eSMatthew G. Knepley 
49488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_None(PetscLimiter lim, PetscViewer viewer)
495c0ce001eSMatthew G. Knepley {
496c0ce001eSMatthew G. Knepley   PetscBool      iascii;
497c0ce001eSMatthew G. Knepley 
498c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
499c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
500c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
5019566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
5029566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_None_Ascii(lim, viewer));
503c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
504c0ce001eSMatthew G. Knepley }
505c0ce001eSMatthew G. Knepley 
50688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_None(PetscLimiter lim, PetscReal f, PetscReal *phi)
507c0ce001eSMatthew G. Knepley {
508c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
509c0ce001eSMatthew G. Knepley   *phi = 1.0;
510c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
511c0ce001eSMatthew G. Knepley }
512c0ce001eSMatthew G. Knepley 
51388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_None(PetscLimiter lim)
514c0ce001eSMatthew G. Knepley {
515c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
516c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_None;
517c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_None;
518c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_None;
519c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
520c0ce001eSMatthew G. Knepley }
521c0ce001eSMatthew G. Knepley 
522c0ce001eSMatthew G. Knepley /*MC
523c0ce001eSMatthew G. Knepley   PETSCLIMITERNONE = "none" - A PetscLimiter object
524c0ce001eSMatthew G. Knepley 
525c0ce001eSMatthew G. Knepley   Level: intermediate
526c0ce001eSMatthew G. Knepley 
527c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType()
528c0ce001eSMatthew G. Knepley M*/
529c0ce001eSMatthew G. Knepley 
530c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_None(PetscLimiter lim)
531c0ce001eSMatthew G. Knepley {
532c0ce001eSMatthew G. Knepley   PetscLimiter_None *l;
533c0ce001eSMatthew G. Knepley 
534c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
535c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
5369566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(lim, &l));
537c0ce001eSMatthew G. Knepley   lim->data = l;
538c0ce001eSMatthew G. Knepley 
5399566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_None(lim));
540c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
541c0ce001eSMatthew G. Knepley }
542c0ce001eSMatthew G. Knepley 
54388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Minmod(PetscLimiter lim)
544c0ce001eSMatthew G. Knepley {
545c0ce001eSMatthew G. Knepley   PetscLimiter_Minmod *l = (PetscLimiter_Minmod *) lim->data;
546c0ce001eSMatthew G. Knepley 
547c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
5489566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
549c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
550c0ce001eSMatthew G. Knepley }
551c0ce001eSMatthew G. Knepley 
55288f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Minmod_Ascii(PetscLimiter lim, PetscViewer viewer)
553c0ce001eSMatthew G. Knepley {
554c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
555c0ce001eSMatthew G. Knepley 
556c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
5579566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
5589566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Minmod Slope Limiter:\n"));
559c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
560c0ce001eSMatthew G. Knepley }
561c0ce001eSMatthew G. Knepley 
56288f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Minmod(PetscLimiter lim, PetscViewer viewer)
563c0ce001eSMatthew G. Knepley {
564c0ce001eSMatthew G. Knepley   PetscBool      iascii;
565c0ce001eSMatthew G. Knepley 
566c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
567c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
568c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
5699566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
5709566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_Minmod_Ascii(lim, viewer));
571c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
572c0ce001eSMatthew G. Knepley }
573c0ce001eSMatthew G. Knepley 
57488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Minmod(PetscLimiter lim, PetscReal f, PetscReal *phi)
575c0ce001eSMatthew G. Knepley {
576c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
577c0ce001eSMatthew G. Knepley   *phi = 2*PetscMax(0, PetscMin(f, 1-f));
578c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
579c0ce001eSMatthew G. Knepley }
580c0ce001eSMatthew G. Knepley 
58188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Minmod(PetscLimiter lim)
582c0ce001eSMatthew G. Knepley {
583c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
584c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Minmod;
585c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Minmod;
586c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Minmod;
587c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
588c0ce001eSMatthew G. Knepley }
589c0ce001eSMatthew G. Knepley 
590c0ce001eSMatthew G. Knepley /*MC
591c0ce001eSMatthew G. Knepley   PETSCLIMITERMINMOD = "minmod" - A PetscLimiter object
592c0ce001eSMatthew G. Knepley 
593c0ce001eSMatthew G. Knepley   Level: intermediate
594c0ce001eSMatthew G. Knepley 
595c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType()
596c0ce001eSMatthew G. Knepley M*/
597c0ce001eSMatthew G. Knepley 
598c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Minmod(PetscLimiter lim)
599c0ce001eSMatthew G. Knepley {
600c0ce001eSMatthew G. Knepley   PetscLimiter_Minmod *l;
601c0ce001eSMatthew G. Knepley 
602c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
603c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
6049566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(lim, &l));
605c0ce001eSMatthew G. Knepley   lim->data = l;
606c0ce001eSMatthew G. Knepley 
6079566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_Minmod(lim));
608c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
609c0ce001eSMatthew G. Knepley }
610c0ce001eSMatthew G. Knepley 
61188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_VanLeer(PetscLimiter lim)
612c0ce001eSMatthew G. Knepley {
613c0ce001eSMatthew G. Knepley   PetscLimiter_VanLeer *l = (PetscLimiter_VanLeer *) lim->data;
614c0ce001eSMatthew G. Knepley 
615c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
6169566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
617c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
618c0ce001eSMatthew G. Knepley }
619c0ce001eSMatthew G. Knepley 
62088f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanLeer_Ascii(PetscLimiter lim, PetscViewer viewer)
621c0ce001eSMatthew G. Knepley {
622c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
623c0ce001eSMatthew G. Knepley 
624c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
6259566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
6269566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Van Leer Slope Limiter:\n"));
627c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
628c0ce001eSMatthew G. Knepley }
629c0ce001eSMatthew G. Knepley 
63088f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanLeer(PetscLimiter lim, PetscViewer viewer)
631c0ce001eSMatthew G. Knepley {
632c0ce001eSMatthew G. Knepley   PetscBool      iascii;
633c0ce001eSMatthew G. Knepley 
634c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
635c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
636c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
6379566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
6389566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_VanLeer_Ascii(lim, viewer));
639c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
640c0ce001eSMatthew G. Knepley }
641c0ce001eSMatthew G. Knepley 
64288f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_VanLeer(PetscLimiter lim, PetscReal f, PetscReal *phi)
643c0ce001eSMatthew G. Knepley {
644c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
645c0ce001eSMatthew G. Knepley   *phi = PetscMax(0, 4*f*(1-f));
646c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
647c0ce001eSMatthew G. Knepley }
648c0ce001eSMatthew G. Knepley 
64988f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_VanLeer(PetscLimiter lim)
650c0ce001eSMatthew G. Knepley {
651c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
652c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_VanLeer;
653c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_VanLeer;
654c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_VanLeer;
655c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
656c0ce001eSMatthew G. Knepley }
657c0ce001eSMatthew G. Knepley 
658c0ce001eSMatthew G. Knepley /*MC
659c0ce001eSMatthew G. Knepley   PETSCLIMITERVANLEER = "vanleer" - A PetscLimiter object
660c0ce001eSMatthew G. Knepley 
661c0ce001eSMatthew G. Knepley   Level: intermediate
662c0ce001eSMatthew G. Knepley 
663c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType()
664c0ce001eSMatthew G. Knepley M*/
665c0ce001eSMatthew G. Knepley 
666c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanLeer(PetscLimiter lim)
667c0ce001eSMatthew G. Knepley {
668c0ce001eSMatthew G. Knepley   PetscLimiter_VanLeer *l;
669c0ce001eSMatthew G. Knepley 
670c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
671c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
6729566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(lim, &l));
673c0ce001eSMatthew G. Knepley   lim->data = l;
674c0ce001eSMatthew G. Knepley 
6759566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_VanLeer(lim));
676c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
677c0ce001eSMatthew G. Knepley }
678c0ce001eSMatthew G. Knepley 
67988f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_VanAlbada(PetscLimiter lim)
680c0ce001eSMatthew G. Knepley {
681c0ce001eSMatthew G. Knepley   PetscLimiter_VanAlbada *l = (PetscLimiter_VanAlbada *) lim->data;
682c0ce001eSMatthew G. Knepley 
683c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
6849566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
685c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
686c0ce001eSMatthew G. Knepley }
687c0ce001eSMatthew G. Knepley 
68888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanAlbada_Ascii(PetscLimiter lim, PetscViewer viewer)
689c0ce001eSMatthew G. Knepley {
690c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
691c0ce001eSMatthew G. Knepley 
692c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
6939566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
6949566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Van Albada Slope Limiter:\n"));
695c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
696c0ce001eSMatthew G. Knepley }
697c0ce001eSMatthew G. Knepley 
69888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanAlbada(PetscLimiter lim, PetscViewer viewer)
699c0ce001eSMatthew G. Knepley {
700c0ce001eSMatthew G. Knepley   PetscBool      iascii;
701c0ce001eSMatthew G. Knepley 
702c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
703c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
704c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
7059566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
7069566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_VanAlbada_Ascii(lim, viewer));
707c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
708c0ce001eSMatthew G. Knepley }
709c0ce001eSMatthew G. Knepley 
71088f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_VanAlbada(PetscLimiter lim, PetscReal f, PetscReal *phi)
711c0ce001eSMatthew G. Knepley {
712c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
713c0ce001eSMatthew G. Knepley   *phi = PetscMax(0, 2*f*(1-f) / (PetscSqr(f) + PetscSqr(1-f)));
714c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
715c0ce001eSMatthew G. Knepley }
716c0ce001eSMatthew G. Knepley 
71788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_VanAlbada(PetscLimiter lim)
718c0ce001eSMatthew G. Knepley {
719c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
720c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_VanAlbada;
721c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_VanAlbada;
722c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_VanAlbada;
723c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
724c0ce001eSMatthew G. Knepley }
725c0ce001eSMatthew G. Knepley 
726c0ce001eSMatthew G. Knepley /*MC
727c0ce001eSMatthew G. Knepley   PETSCLIMITERVANALBADA = "vanalbada" - A PetscLimiter object
728c0ce001eSMatthew G. Knepley 
729c0ce001eSMatthew G. Knepley   Level: intermediate
730c0ce001eSMatthew G. Knepley 
731c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType()
732c0ce001eSMatthew G. Knepley M*/
733c0ce001eSMatthew G. Knepley 
734c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanAlbada(PetscLimiter lim)
735c0ce001eSMatthew G. Knepley {
736c0ce001eSMatthew G. Knepley   PetscLimiter_VanAlbada *l;
737c0ce001eSMatthew G. Knepley 
738c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
739c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
7409566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(lim, &l));
741c0ce001eSMatthew G. Knepley   lim->data = l;
742c0ce001eSMatthew G. Knepley 
7439566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_VanAlbada(lim));
744c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
745c0ce001eSMatthew G. Knepley }
746c0ce001eSMatthew G. Knepley 
74788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Superbee(PetscLimiter lim)
748c0ce001eSMatthew G. Knepley {
749c0ce001eSMatthew G. Knepley   PetscLimiter_Superbee *l = (PetscLimiter_Superbee *) lim->data;
750c0ce001eSMatthew G. Knepley 
751c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
7529566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
753c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
754c0ce001eSMatthew G. Knepley }
755c0ce001eSMatthew G. Knepley 
75688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Superbee_Ascii(PetscLimiter lim, PetscViewer viewer)
757c0ce001eSMatthew G. Knepley {
758c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
759c0ce001eSMatthew G. Knepley 
760c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
7619566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
7629566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Superbee Slope Limiter:\n"));
763c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
764c0ce001eSMatthew G. Knepley }
765c0ce001eSMatthew G. Knepley 
76688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Superbee(PetscLimiter lim, PetscViewer viewer)
767c0ce001eSMatthew G. Knepley {
768c0ce001eSMatthew G. Knepley   PetscBool      iascii;
769c0ce001eSMatthew G. Knepley 
770c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
771c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
772c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
7739566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
7749566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_Superbee_Ascii(lim, viewer));
775c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
776c0ce001eSMatthew G. Knepley }
777c0ce001eSMatthew G. Knepley 
77888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Superbee(PetscLimiter lim, PetscReal f, PetscReal *phi)
779c0ce001eSMatthew G. Knepley {
780c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
781c0ce001eSMatthew G. Knepley   *phi = 4*PetscMax(0, PetscMin(f, 1-f));
782c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
783c0ce001eSMatthew G. Knepley }
784c0ce001eSMatthew G. Knepley 
78588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Superbee(PetscLimiter lim)
786c0ce001eSMatthew G. Knepley {
787c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
788c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_Superbee;
789c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_Superbee;
790c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_Superbee;
791c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
792c0ce001eSMatthew G. Knepley }
793c0ce001eSMatthew G. Knepley 
794c0ce001eSMatthew G. Knepley /*MC
795c0ce001eSMatthew G. Knepley   PETSCLIMITERSUPERBEE = "superbee" - A PetscLimiter object
796c0ce001eSMatthew G. Knepley 
797c0ce001eSMatthew G. Knepley   Level: intermediate
798c0ce001eSMatthew G. Knepley 
799c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType()
800c0ce001eSMatthew G. Knepley M*/
801c0ce001eSMatthew G. Knepley 
802c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Superbee(PetscLimiter lim)
803c0ce001eSMatthew G. Knepley {
804c0ce001eSMatthew G. Knepley   PetscLimiter_Superbee *l;
805c0ce001eSMatthew G. Knepley 
806c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
807c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
8089566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(lim, &l));
809c0ce001eSMatthew G. Knepley   lim->data = l;
810c0ce001eSMatthew G. Knepley 
8119566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_Superbee(lim));
812c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
813c0ce001eSMatthew G. Knepley }
814c0ce001eSMatthew G. Knepley 
81588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_MC(PetscLimiter lim)
816c0ce001eSMatthew G. Knepley {
817c0ce001eSMatthew G. Knepley   PetscLimiter_MC *l = (PetscLimiter_MC *) lim->data;
818c0ce001eSMatthew G. Knepley 
819c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
8209566063dSJacob Faibussowitsch   PetscCall(PetscFree(l));
821c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
822c0ce001eSMatthew G. Knepley }
823c0ce001eSMatthew G. Knepley 
82488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_MC_Ascii(PetscLimiter lim, PetscViewer viewer)
825c0ce001eSMatthew G. Knepley {
826c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
827c0ce001eSMatthew G. Knepley 
828c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
8299566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
8309566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "MC Slope Limiter:\n"));
831c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
832c0ce001eSMatthew G. Knepley }
833c0ce001eSMatthew G. Knepley 
83488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_MC(PetscLimiter lim, PetscViewer viewer)
835c0ce001eSMatthew G. Knepley {
836c0ce001eSMatthew G. Knepley   PetscBool      iascii;
837c0ce001eSMatthew G. Knepley 
838c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
839c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
840c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
8419566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
8429566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscLimiterView_MC_Ascii(lim, viewer));
843c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
844c0ce001eSMatthew G. Knepley }
845c0ce001eSMatthew G. Knepley 
846c0ce001eSMatthew G. Knepley /* aka Barth-Jespersen */
84788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_MC(PetscLimiter lim, PetscReal f, PetscReal *phi)
848c0ce001eSMatthew G. Knepley {
849c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
850c0ce001eSMatthew G. Knepley   *phi = PetscMin(1, 4*PetscMax(0, PetscMin(f, 1-f)));
851c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
852c0ce001eSMatthew G. Knepley }
853c0ce001eSMatthew G. Knepley 
85488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_MC(PetscLimiter lim)
855c0ce001eSMatthew G. Knepley {
856c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
857c0ce001eSMatthew G. Knepley   lim->ops->view    = PetscLimiterView_MC;
858c0ce001eSMatthew G. Knepley   lim->ops->destroy = PetscLimiterDestroy_MC;
859c0ce001eSMatthew G. Knepley   lim->ops->limit   = PetscLimiterLimit_MC;
860c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
861c0ce001eSMatthew G. Knepley }
862c0ce001eSMatthew G. Knepley 
863c0ce001eSMatthew G. Knepley /*MC
864c0ce001eSMatthew G. Knepley   PETSCLIMITERMC = "mc" - A PetscLimiter object
865c0ce001eSMatthew G. Knepley 
866c0ce001eSMatthew G. Knepley   Level: intermediate
867c0ce001eSMatthew G. Knepley 
868c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType()
869c0ce001eSMatthew G. Knepley M*/
870c0ce001eSMatthew G. Knepley 
871c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_MC(PetscLimiter lim)
872c0ce001eSMatthew G. Knepley {
873c0ce001eSMatthew G. Knepley   PetscLimiter_MC *l;
874c0ce001eSMatthew G. Knepley 
875c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
876c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1);
8779566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(lim, &l));
878c0ce001eSMatthew G. Knepley   lim->data = l;
879c0ce001eSMatthew G. Knepley 
8809566063dSJacob Faibussowitsch   PetscCall(PetscLimiterInitialize_MC(lim));
881c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
882c0ce001eSMatthew G. Knepley }
883c0ce001eSMatthew G. Knepley 
884c0ce001eSMatthew G. Knepley PetscClassId PETSCFV_CLASSID = 0;
885c0ce001eSMatthew G. Knepley 
886c0ce001eSMatthew G. Knepley PetscFunctionList PetscFVList              = NULL;
887c0ce001eSMatthew G. Knepley PetscBool         PetscFVRegisterAllCalled = PETSC_FALSE;
888c0ce001eSMatthew G. Knepley 
889c0ce001eSMatthew G. Knepley /*@C
890c0ce001eSMatthew G. Knepley   PetscFVRegister - Adds a new PetscFV implementation
891c0ce001eSMatthew G. Knepley 
892c0ce001eSMatthew G. Knepley   Not Collective
893c0ce001eSMatthew G. Knepley 
894c0ce001eSMatthew G. Knepley   Input Parameters:
895c0ce001eSMatthew G. Knepley + name        - The name of a new user-defined creation routine
896c0ce001eSMatthew G. Knepley - create_func - The creation routine itself
897c0ce001eSMatthew G. Knepley 
898c0ce001eSMatthew G. Knepley   Notes:
899c0ce001eSMatthew G. Knepley   PetscFVRegister() may be called multiple times to add several user-defined PetscFVs
900c0ce001eSMatthew G. Knepley 
901c0ce001eSMatthew G. Knepley   Sample usage:
902c0ce001eSMatthew G. Knepley .vb
903c0ce001eSMatthew G. Knepley     PetscFVRegister("my_fv", MyPetscFVCreate);
904c0ce001eSMatthew G. Knepley .ve
905c0ce001eSMatthew G. Knepley 
906c0ce001eSMatthew G. Knepley   Then, your PetscFV type can be chosen with the procedural interface via
907c0ce001eSMatthew G. Knepley .vb
908c0ce001eSMatthew G. Knepley     PetscFVCreate(MPI_Comm, PetscFV *);
909c0ce001eSMatthew G. Knepley     PetscFVSetType(PetscFV, "my_fv");
910c0ce001eSMatthew G. Knepley .ve
911c0ce001eSMatthew G. Knepley    or at runtime via the option
912c0ce001eSMatthew G. Knepley .vb
913c0ce001eSMatthew G. Knepley     -petscfv_type my_fv
914c0ce001eSMatthew G. Knepley .ve
915c0ce001eSMatthew G. Knepley 
916c0ce001eSMatthew G. Knepley   Level: advanced
917c0ce001eSMatthew G. Knepley 
918c0ce001eSMatthew G. Knepley .seealso: PetscFVRegisterAll(), PetscFVRegisterDestroy()
919c0ce001eSMatthew G. Knepley 
920c0ce001eSMatthew G. Knepley @*/
921c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVRegister(const char sname[], PetscErrorCode (*function)(PetscFV))
922c0ce001eSMatthew G. Knepley {
923c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
9249566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscFVList, sname, function));
925c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
926c0ce001eSMatthew G. Knepley }
927c0ce001eSMatthew G. Knepley 
928c0ce001eSMatthew G. Knepley /*@C
929c0ce001eSMatthew G. Knepley   PetscFVSetType - Builds a particular PetscFV
930c0ce001eSMatthew G. Knepley 
931c0ce001eSMatthew G. Knepley   Collective on fvm
932c0ce001eSMatthew G. Knepley 
933c0ce001eSMatthew G. Knepley   Input Parameters:
934c0ce001eSMatthew G. Knepley + fvm  - The PetscFV object
935c0ce001eSMatthew G. Knepley - name - The kind of FVM space
936c0ce001eSMatthew G. Knepley 
937c0ce001eSMatthew G. Knepley   Options Database Key:
938c0ce001eSMatthew G. Knepley . -petscfv_type <type> - Sets the PetscFV type; use -help for a list of available types
939c0ce001eSMatthew G. Knepley 
940c0ce001eSMatthew G. Knepley   Level: intermediate
941c0ce001eSMatthew G. Knepley 
942c0ce001eSMatthew G. Knepley .seealso: PetscFVGetType(), PetscFVCreate()
943c0ce001eSMatthew G. Knepley @*/
944c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetType(PetscFV fvm, PetscFVType name)
945c0ce001eSMatthew G. Knepley {
946c0ce001eSMatthew G. Knepley   PetscErrorCode (*r)(PetscFV);
947c0ce001eSMatthew G. Knepley   PetscBool      match;
948c0ce001eSMatthew G. Knepley 
949c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
950c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
9519566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) fvm, name, &match));
952c0ce001eSMatthew G. Knepley   if (match) PetscFunctionReturn(0);
953c0ce001eSMatthew G. Knepley 
9549566063dSJacob Faibussowitsch   PetscCall(PetscFVRegisterAll());
9559566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscFVList, name, &r));
95628b400f6SJacob Faibussowitsch   PetscCheck(r,PetscObjectComm((PetscObject) fvm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscFV type: %s", name);
957c0ce001eSMatthew G. Knepley 
958c0ce001eSMatthew G. Knepley   if (fvm->ops->destroy) {
9599566063dSJacob Faibussowitsch     PetscCall((*fvm->ops->destroy)(fvm));
960c0ce001eSMatthew G. Knepley     fvm->ops->destroy = NULL;
961c0ce001eSMatthew G. Knepley   }
9629566063dSJacob Faibussowitsch   PetscCall((*r)(fvm));
9639566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject) fvm, name));
964c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
965c0ce001eSMatthew G. Knepley }
966c0ce001eSMatthew G. Knepley 
967c0ce001eSMatthew G. Knepley /*@C
968c0ce001eSMatthew G. Knepley   PetscFVGetType - Gets the PetscFV type name (as a string) from the object.
969c0ce001eSMatthew G. Knepley 
970c0ce001eSMatthew G. Knepley   Not Collective
971c0ce001eSMatthew G. Knepley 
972c0ce001eSMatthew G. Knepley   Input Parameter:
973c0ce001eSMatthew G. Knepley . fvm  - The PetscFV
974c0ce001eSMatthew G. Knepley 
975c0ce001eSMatthew G. Knepley   Output Parameter:
976c0ce001eSMatthew G. Knepley . name - The PetscFV type name
977c0ce001eSMatthew G. Knepley 
978c0ce001eSMatthew G. Knepley   Level: intermediate
979c0ce001eSMatthew G. Knepley 
980c0ce001eSMatthew G. Knepley .seealso: PetscFVSetType(), PetscFVCreate()
981c0ce001eSMatthew G. Knepley @*/
982c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetType(PetscFV fvm, PetscFVType *name)
983c0ce001eSMatthew G. Knepley {
984c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
985c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
986c0ce001eSMatthew G. Knepley   PetscValidPointer(name, 2);
9879566063dSJacob Faibussowitsch   PetscCall(PetscFVRegisterAll());
988c0ce001eSMatthew G. Knepley   *name = ((PetscObject) fvm)->type_name;
989c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
990c0ce001eSMatthew G. Knepley }
991c0ce001eSMatthew G. Knepley 
992c0ce001eSMatthew G. Knepley /*@C
993fe2efc57SMark    PetscFVViewFromOptions - View from Options
994fe2efc57SMark 
995fe2efc57SMark    Collective on PetscFV
996fe2efc57SMark 
997fe2efc57SMark    Input Parameters:
998fe2efc57SMark +  A - the PetscFV object
999736c3998SJose E. Roman .  obj - Optional object
1000736c3998SJose E. Roman -  name - command line option
1001fe2efc57SMark 
1002fe2efc57SMark    Level: intermediate
1003fe2efc57SMark .seealso:  PetscFV, PetscFVView, PetscObjectViewFromOptions(), PetscFVCreate()
1004fe2efc57SMark @*/
1005fe2efc57SMark PetscErrorCode  PetscFVViewFromOptions(PetscFV A,PetscObject obj,const char name[])
1006fe2efc57SMark {
1007fe2efc57SMark   PetscFunctionBegin;
1008fe2efc57SMark   PetscValidHeaderSpecific(A,PETSCFV_CLASSID,1);
10099566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name));
1010fe2efc57SMark   PetscFunctionReturn(0);
1011fe2efc57SMark }
1012fe2efc57SMark 
1013fe2efc57SMark /*@C
1014c0ce001eSMatthew G. Knepley   PetscFVView - Views a PetscFV
1015c0ce001eSMatthew G. Knepley 
1016c0ce001eSMatthew G. Knepley   Collective on fvm
1017c0ce001eSMatthew G. Knepley 
1018d8d19677SJose E. Roman   Input Parameters:
1019c0ce001eSMatthew G. Knepley + fvm - the PetscFV object to view
1020c0ce001eSMatthew G. Knepley - v   - the viewer
1021c0ce001eSMatthew G. Knepley 
102288f5f89eSMatthew G. Knepley   Level: beginner
1023c0ce001eSMatthew G. Knepley 
1024c0ce001eSMatthew G. Knepley .seealso: PetscFVDestroy()
1025c0ce001eSMatthew G. Knepley @*/
1026c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVView(PetscFV fvm, PetscViewer v)
1027c0ce001eSMatthew G. Knepley {
1028c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1029c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
10309566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) fvm), &v));
10319566063dSJacob Faibussowitsch   if (fvm->ops->view) PetscCall((*fvm->ops->view)(fvm, v));
1032c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1033c0ce001eSMatthew G. Knepley }
1034c0ce001eSMatthew G. Knepley 
1035c0ce001eSMatthew G. Knepley /*@
1036c0ce001eSMatthew G. Knepley   PetscFVSetFromOptions - sets parameters in a PetscFV from the options database
1037c0ce001eSMatthew G. Knepley 
1038c0ce001eSMatthew G. Knepley   Collective on fvm
1039c0ce001eSMatthew G. Knepley 
1040c0ce001eSMatthew G. Knepley   Input Parameter:
1041c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to set options for
1042c0ce001eSMatthew G. Knepley 
1043c0ce001eSMatthew G. Knepley   Options Database Key:
1044c0ce001eSMatthew G. Knepley . -petscfv_compute_gradients <bool> - Determines whether cell gradients are calculated
1045c0ce001eSMatthew G. Knepley 
104688f5f89eSMatthew G. Knepley   Level: intermediate
1047c0ce001eSMatthew G. Knepley 
1048c0ce001eSMatthew G. Knepley .seealso: PetscFVView()
1049c0ce001eSMatthew G. Knepley @*/
1050c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetFromOptions(PetscFV fvm)
1051c0ce001eSMatthew G. Knepley {
1052c0ce001eSMatthew G. Knepley   const char    *defaultType;
1053c0ce001eSMatthew G. Knepley   char           name[256];
1054c0ce001eSMatthew G. Knepley   PetscBool      flg;
1055c0ce001eSMatthew G. Knepley   PetscErrorCode ierr;
1056c0ce001eSMatthew G. Knepley 
1057c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1058c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1059c0ce001eSMatthew G. Knepley   if (!((PetscObject) fvm)->type_name) defaultType = PETSCFVUPWIND;
1060c0ce001eSMatthew G. Knepley   else                                 defaultType = ((PetscObject) fvm)->type_name;
10619566063dSJacob Faibussowitsch   PetscCall(PetscFVRegisterAll());
1062c0ce001eSMatthew G. Knepley 
10639566063dSJacob Faibussowitsch   ierr = PetscObjectOptionsBegin((PetscObject) fvm);PetscCall(ierr);
10649566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petscfv_type", "Finite volume discretization", "PetscFVSetType", PetscFVList, defaultType, name, 256, &flg));
1065c0ce001eSMatthew G. Knepley   if (flg) {
10669566063dSJacob Faibussowitsch     PetscCall(PetscFVSetType(fvm, name));
1067c0ce001eSMatthew G. Knepley   } else if (!((PetscObject) fvm)->type_name) {
10689566063dSJacob Faibussowitsch     PetscCall(PetscFVSetType(fvm, defaultType));
1069c0ce001eSMatthew G. Knepley 
1070c0ce001eSMatthew G. Knepley   }
10719566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-petscfv_compute_gradients", "Compute cell gradients", "PetscFVSetComputeGradients", fvm->computeGradients, &fvm->computeGradients, NULL));
10729566063dSJacob Faibussowitsch   if (fvm->ops->setfromoptions) PetscCall((*fvm->ops->setfromoptions)(fvm));
1073c0ce001eSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
10749566063dSJacob Faibussowitsch   PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) fvm));
10759566063dSJacob Faibussowitsch   PetscCall(PetscLimiterSetFromOptions(fvm->limiter));
10769566063dSJacob Faibussowitsch   ierr = PetscOptionsEnd();PetscCall(ierr);
10779566063dSJacob Faibussowitsch   PetscCall(PetscFVViewFromOptions(fvm, NULL, "-petscfv_view"));
1078c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1079c0ce001eSMatthew G. Knepley }
1080c0ce001eSMatthew G. Knepley 
1081c0ce001eSMatthew G. Knepley /*@
1082c0ce001eSMatthew G. Knepley   PetscFVSetUp - Construct data structures for the PetscFV
1083c0ce001eSMatthew G. Knepley 
1084c0ce001eSMatthew G. Knepley   Collective on fvm
1085c0ce001eSMatthew G. Knepley 
1086c0ce001eSMatthew G. Knepley   Input Parameter:
1087c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to setup
1088c0ce001eSMatthew G. Knepley 
108988f5f89eSMatthew G. Knepley   Level: intermediate
1090c0ce001eSMatthew G. Knepley 
1091c0ce001eSMatthew G. Knepley .seealso: PetscFVView(), PetscFVDestroy()
1092c0ce001eSMatthew G. Knepley @*/
1093c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetUp(PetscFV fvm)
1094c0ce001eSMatthew G. Knepley {
1095c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1096c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
10979566063dSJacob Faibussowitsch   PetscCall(PetscLimiterSetUp(fvm->limiter));
10989566063dSJacob Faibussowitsch   if (fvm->ops->setup) PetscCall((*fvm->ops->setup)(fvm));
1099c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1100c0ce001eSMatthew G. Knepley }
1101c0ce001eSMatthew G. Knepley 
1102c0ce001eSMatthew G. Knepley /*@
1103c0ce001eSMatthew G. Knepley   PetscFVDestroy - Destroys a PetscFV object
1104c0ce001eSMatthew G. Knepley 
1105c0ce001eSMatthew G. Knepley   Collective on fvm
1106c0ce001eSMatthew G. Knepley 
1107c0ce001eSMatthew G. Knepley   Input Parameter:
1108c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to destroy
1109c0ce001eSMatthew G. Knepley 
111088f5f89eSMatthew G. Knepley   Level: beginner
1111c0ce001eSMatthew G. Knepley 
1112c0ce001eSMatthew G. Knepley .seealso: PetscFVView()
1113c0ce001eSMatthew G. Knepley @*/
1114c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVDestroy(PetscFV *fvm)
1115c0ce001eSMatthew G. Knepley {
1116c0ce001eSMatthew G. Knepley   PetscInt       i;
1117c0ce001eSMatthew G. Knepley 
1118c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1119c0ce001eSMatthew G. Knepley   if (!*fvm) PetscFunctionReturn(0);
1120c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific((*fvm), PETSCFV_CLASSID, 1);
1121c0ce001eSMatthew G. Knepley 
1122ea78f98cSLisandro Dalcin   if (--((PetscObject)(*fvm))->refct > 0) {*fvm = NULL; PetscFunctionReturn(0);}
1123c0ce001eSMatthew G. Knepley   ((PetscObject) (*fvm))->refct = 0;
1124c0ce001eSMatthew G. Knepley 
1125c0ce001eSMatthew G. Knepley   for (i = 0; i < (*fvm)->numComponents; i++) {
11269566063dSJacob Faibussowitsch     PetscCall(PetscFree((*fvm)->componentNames[i]));
1127c0ce001eSMatthew G. Knepley   }
11289566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fvm)->componentNames));
11299566063dSJacob Faibussowitsch   PetscCall(PetscLimiterDestroy(&(*fvm)->limiter));
11309566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceDestroy(&(*fvm)->dualSpace));
11319566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fvm)->fluxWork));
11329566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureDestroy(&(*fvm)->quadrature));
11339566063dSJacob Faibussowitsch   PetscCall(PetscTabulationDestroy(&(*fvm)->T));
1134c0ce001eSMatthew G. Knepley 
11359566063dSJacob Faibussowitsch   if ((*fvm)->ops->destroy) PetscCall((*(*fvm)->ops->destroy)(*fvm));
11369566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(fvm));
1137c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1138c0ce001eSMatthew G. Knepley }
1139c0ce001eSMatthew G. Knepley 
1140c0ce001eSMatthew G. Knepley /*@
1141c0ce001eSMatthew G. Knepley   PetscFVCreate - Creates an empty PetscFV object. The type can then be set with PetscFVSetType().
1142c0ce001eSMatthew G. Knepley 
1143c0ce001eSMatthew G. Knepley   Collective
1144c0ce001eSMatthew G. Knepley 
1145c0ce001eSMatthew G. Knepley   Input Parameter:
1146c0ce001eSMatthew G. Knepley . comm - The communicator for the PetscFV object
1147c0ce001eSMatthew G. Knepley 
1148c0ce001eSMatthew G. Knepley   Output Parameter:
1149c0ce001eSMatthew G. Knepley . fvm - The PetscFV object
1150c0ce001eSMatthew G. Knepley 
1151c0ce001eSMatthew G. Knepley   Level: beginner
1152c0ce001eSMatthew G. Knepley 
1153c0ce001eSMatthew G. Knepley .seealso: PetscFVSetType(), PETSCFVUPWIND
1154c0ce001eSMatthew G. Knepley @*/
1155c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVCreate(MPI_Comm comm, PetscFV *fvm)
1156c0ce001eSMatthew G. Knepley {
1157c0ce001eSMatthew G. Knepley   PetscFV        f;
1158c0ce001eSMatthew G. Knepley 
1159c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1160c0ce001eSMatthew G. Knepley   PetscValidPointer(fvm, 2);
1161c0ce001eSMatthew G. Knepley   *fvm = NULL;
11629566063dSJacob Faibussowitsch   PetscCall(PetscFVInitializePackage());
1163c0ce001eSMatthew G. Knepley 
11649566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(f, PETSCFV_CLASSID, "PetscFV", "Finite Volume", "PetscFV", comm, PetscFVDestroy, PetscFVView));
11659566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(f->ops, sizeof(struct _PetscFVOps)));
1166c0ce001eSMatthew G. Knepley 
11679566063dSJacob Faibussowitsch   PetscCall(PetscLimiterCreate(comm, &f->limiter));
1168c0ce001eSMatthew G. Knepley   f->numComponents    = 1;
1169c0ce001eSMatthew G. Knepley   f->dim              = 0;
1170c0ce001eSMatthew G. Knepley   f->computeGradients = PETSC_FALSE;
1171c0ce001eSMatthew G. Knepley   f->fluxWork         = NULL;
11729566063dSJacob Faibussowitsch   PetscCall(PetscCalloc1(f->numComponents,&f->componentNames));
1173c0ce001eSMatthew G. Knepley 
1174c0ce001eSMatthew G. Knepley   *fvm = f;
1175c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1176c0ce001eSMatthew G. Knepley }
1177c0ce001eSMatthew G. Knepley 
1178c0ce001eSMatthew G. Knepley /*@
1179c0ce001eSMatthew G. Knepley   PetscFVSetLimiter - Set the limiter object
1180c0ce001eSMatthew G. Knepley 
1181c0ce001eSMatthew G. Knepley   Logically collective on fvm
1182c0ce001eSMatthew G. Knepley 
1183c0ce001eSMatthew G. Knepley   Input Parameters:
1184c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1185c0ce001eSMatthew G. Knepley - lim - The PetscLimiter
1186c0ce001eSMatthew G. Knepley 
118788f5f89eSMatthew G. Knepley   Level: intermediate
1188c0ce001eSMatthew G. Knepley 
1189c0ce001eSMatthew G. Knepley .seealso: PetscFVGetLimiter()
1190c0ce001eSMatthew G. Knepley @*/
1191c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetLimiter(PetscFV fvm, PetscLimiter lim)
1192c0ce001eSMatthew G. Knepley {
1193c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1194c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1195c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 2);
11969566063dSJacob Faibussowitsch   PetscCall(PetscLimiterDestroy(&fvm->limiter));
11979566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject) lim));
1198c0ce001eSMatthew G. Knepley   fvm->limiter = lim;
1199c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1200c0ce001eSMatthew G. Knepley }
1201c0ce001eSMatthew G. Knepley 
1202c0ce001eSMatthew G. Knepley /*@
1203c0ce001eSMatthew G. Knepley   PetscFVGetLimiter - Get the limiter object
1204c0ce001eSMatthew G. Knepley 
1205c0ce001eSMatthew G. Knepley   Not collective
1206c0ce001eSMatthew G. Knepley 
1207c0ce001eSMatthew G. Knepley   Input Parameter:
1208c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1209c0ce001eSMatthew G. Knepley 
1210c0ce001eSMatthew G. Knepley   Output Parameter:
1211c0ce001eSMatthew G. Knepley . lim - The PetscLimiter
1212c0ce001eSMatthew G. Knepley 
121388f5f89eSMatthew G. Knepley   Level: intermediate
1214c0ce001eSMatthew G. Knepley 
1215c0ce001eSMatthew G. Knepley .seealso: PetscFVSetLimiter()
1216c0ce001eSMatthew G. Knepley @*/
1217c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetLimiter(PetscFV fvm, PetscLimiter *lim)
1218c0ce001eSMatthew G. Knepley {
1219c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1220c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1221c0ce001eSMatthew G. Knepley   PetscValidPointer(lim, 2);
1222c0ce001eSMatthew G. Knepley   *lim = fvm->limiter;
1223c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1224c0ce001eSMatthew G. Knepley }
1225c0ce001eSMatthew G. Knepley 
1226c0ce001eSMatthew G. Knepley /*@
1227c0ce001eSMatthew G. Knepley   PetscFVSetNumComponents - Set the number of field components
1228c0ce001eSMatthew G. Knepley 
1229c0ce001eSMatthew G. Knepley   Logically collective on fvm
1230c0ce001eSMatthew G. Knepley 
1231c0ce001eSMatthew G. Knepley   Input Parameters:
1232c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1233c0ce001eSMatthew G. Knepley - comp - The number of components
1234c0ce001eSMatthew G. Knepley 
123588f5f89eSMatthew G. Knepley   Level: intermediate
1236c0ce001eSMatthew G. Knepley 
1237c0ce001eSMatthew G. Knepley .seealso: PetscFVGetNumComponents()
1238c0ce001eSMatthew G. Knepley @*/
1239c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetNumComponents(PetscFV fvm, PetscInt comp)
1240c0ce001eSMatthew G. Knepley {
1241c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1242c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1243c0ce001eSMatthew G. Knepley   if (fvm->numComponents != comp) {
1244c0ce001eSMatthew G. Knepley     PetscInt i;
1245c0ce001eSMatthew G. Knepley 
1246c0ce001eSMatthew G. Knepley     for (i = 0; i < fvm->numComponents; i++) {
12479566063dSJacob Faibussowitsch       PetscCall(PetscFree(fvm->componentNames[i]));
1248c0ce001eSMatthew G. Knepley     }
12499566063dSJacob Faibussowitsch     PetscCall(PetscFree(fvm->componentNames));
12509566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(comp,&fvm->componentNames));
1251c0ce001eSMatthew G. Knepley   }
1252c0ce001eSMatthew G. Knepley   fvm->numComponents = comp;
12539566063dSJacob Faibussowitsch   PetscCall(PetscFree(fvm->fluxWork));
12549566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(comp, &fvm->fluxWork));
1255c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1256c0ce001eSMatthew G. Knepley }
1257c0ce001eSMatthew G. Knepley 
1258c0ce001eSMatthew G. Knepley /*@
1259c0ce001eSMatthew G. Knepley   PetscFVGetNumComponents - Get the number of field components
1260c0ce001eSMatthew G. Knepley 
1261c0ce001eSMatthew G. Knepley   Not collective
1262c0ce001eSMatthew G. Knepley 
1263c0ce001eSMatthew G. Knepley   Input Parameter:
1264c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1265c0ce001eSMatthew G. Knepley 
1266c0ce001eSMatthew G. Knepley   Output Parameter:
1267c0ce001eSMatthew G. Knepley , comp - The number of components
1268c0ce001eSMatthew G. Knepley 
126988f5f89eSMatthew G. Knepley   Level: intermediate
1270c0ce001eSMatthew G. Knepley 
1271c0ce001eSMatthew G. Knepley .seealso: PetscFVSetNumComponents()
1272c0ce001eSMatthew G. Knepley @*/
1273c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetNumComponents(PetscFV fvm, PetscInt *comp)
1274c0ce001eSMatthew G. Knepley {
1275c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1276c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1277dadcf809SJacob Faibussowitsch   PetscValidIntPointer(comp, 2);
1278c0ce001eSMatthew G. Knepley   *comp = fvm->numComponents;
1279c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1280c0ce001eSMatthew G. Knepley }
1281c0ce001eSMatthew G. Knepley 
1282c0ce001eSMatthew G. Knepley /*@C
1283c0ce001eSMatthew G. Knepley   PetscFVSetComponentName - Set the name of a component (used in output and viewing)
1284c0ce001eSMatthew G. Knepley 
1285c0ce001eSMatthew G. Knepley   Logically collective on fvm
1286c0ce001eSMatthew G. Knepley   Input Parameters:
1287c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1288c0ce001eSMatthew G. Knepley . comp - the component number
1289c0ce001eSMatthew G. Knepley - name - the component name
1290c0ce001eSMatthew G. Knepley 
129188f5f89eSMatthew G. Knepley   Level: intermediate
1292c0ce001eSMatthew G. Knepley 
1293c0ce001eSMatthew G. Knepley .seealso: PetscFVGetComponentName()
1294c0ce001eSMatthew G. Knepley @*/
1295c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetComponentName(PetscFV fvm, PetscInt comp, const char *name)
1296c0ce001eSMatthew G. Knepley {
1297c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
12989566063dSJacob Faibussowitsch   PetscCall(PetscFree(fvm->componentNames[comp]));
12999566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name,&fvm->componentNames[comp]));
1300c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1301c0ce001eSMatthew G. Knepley }
1302c0ce001eSMatthew G. Knepley 
1303c0ce001eSMatthew G. Knepley /*@C
1304c0ce001eSMatthew G. Knepley   PetscFVGetComponentName - Get the name of a component (used in output and viewing)
1305c0ce001eSMatthew G. Knepley 
1306c0ce001eSMatthew G. Knepley   Logically collective on fvm
1307c0ce001eSMatthew G. Knepley   Input Parameters:
1308c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1309c0ce001eSMatthew G. Knepley - comp - the component number
1310c0ce001eSMatthew G. Knepley 
1311c0ce001eSMatthew G. Knepley   Output Parameter:
1312c0ce001eSMatthew G. Knepley . name - the component name
1313c0ce001eSMatthew G. Knepley 
131488f5f89eSMatthew G. Knepley   Level: intermediate
1315c0ce001eSMatthew G. Knepley 
1316c0ce001eSMatthew G. Knepley .seealso: PetscFVSetComponentName()
1317c0ce001eSMatthew G. Knepley @*/
1318c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetComponentName(PetscFV fvm, PetscInt comp, const char **name)
1319c0ce001eSMatthew G. Knepley {
1320c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1321c0ce001eSMatthew G. Knepley   *name = fvm->componentNames[comp];
1322c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1323c0ce001eSMatthew G. Knepley }
1324c0ce001eSMatthew G. Knepley 
1325c0ce001eSMatthew G. Knepley /*@
1326c0ce001eSMatthew G. Knepley   PetscFVSetSpatialDimension - Set the spatial dimension
1327c0ce001eSMatthew G. Knepley 
1328c0ce001eSMatthew G. Knepley   Logically collective on fvm
1329c0ce001eSMatthew G. Knepley 
1330c0ce001eSMatthew G. Knepley   Input Parameters:
1331c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1332c0ce001eSMatthew G. Knepley - dim - The spatial dimension
1333c0ce001eSMatthew G. Knepley 
133488f5f89eSMatthew G. Knepley   Level: intermediate
1335c0ce001eSMatthew G. Knepley 
1336c0ce001eSMatthew G. Knepley .seealso: PetscFVGetSpatialDimension()
1337c0ce001eSMatthew G. Knepley @*/
1338c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetSpatialDimension(PetscFV fvm, PetscInt dim)
1339c0ce001eSMatthew G. Knepley {
1340c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1341c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1342c0ce001eSMatthew G. Knepley   fvm->dim = dim;
1343c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1344c0ce001eSMatthew G. Knepley }
1345c0ce001eSMatthew G. Knepley 
1346c0ce001eSMatthew G. Knepley /*@
1347c0ce001eSMatthew G. Knepley   PetscFVGetSpatialDimension - Get the spatial dimension
1348c0ce001eSMatthew G. Knepley 
1349c0ce001eSMatthew G. Knepley   Logically collective on fvm
1350c0ce001eSMatthew G. Knepley 
1351c0ce001eSMatthew G. Knepley   Input Parameter:
1352c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1353c0ce001eSMatthew G. Knepley 
1354c0ce001eSMatthew G. Knepley   Output Parameter:
1355c0ce001eSMatthew G. Knepley . dim - The spatial dimension
1356c0ce001eSMatthew G. Knepley 
135788f5f89eSMatthew G. Knepley   Level: intermediate
1358c0ce001eSMatthew G. Knepley 
1359c0ce001eSMatthew G. Knepley .seealso: PetscFVSetSpatialDimension()
1360c0ce001eSMatthew G. Knepley @*/
1361c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetSpatialDimension(PetscFV fvm, PetscInt *dim)
1362c0ce001eSMatthew G. Knepley {
1363c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1364c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1365dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
1366c0ce001eSMatthew G. Knepley   *dim = fvm->dim;
1367c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1368c0ce001eSMatthew G. Knepley }
1369c0ce001eSMatthew G. Knepley 
1370c0ce001eSMatthew G. Knepley /*@
1371c0ce001eSMatthew G. Knepley   PetscFVSetComputeGradients - Toggle computation of cell gradients
1372c0ce001eSMatthew G. Knepley 
1373c0ce001eSMatthew G. Knepley   Logically collective on fvm
1374c0ce001eSMatthew G. Knepley 
1375c0ce001eSMatthew G. Knepley   Input Parameters:
1376c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1377c0ce001eSMatthew G. Knepley - computeGradients - Flag to compute cell gradients
1378c0ce001eSMatthew G. Knepley 
137988f5f89eSMatthew G. Knepley   Level: intermediate
1380c0ce001eSMatthew G. Knepley 
1381c0ce001eSMatthew G. Knepley .seealso: PetscFVGetComputeGradients()
1382c0ce001eSMatthew G. Knepley @*/
1383c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetComputeGradients(PetscFV fvm, PetscBool computeGradients)
1384c0ce001eSMatthew G. Knepley {
1385c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1386c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1387c0ce001eSMatthew G. Knepley   fvm->computeGradients = computeGradients;
1388c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1389c0ce001eSMatthew G. Knepley }
1390c0ce001eSMatthew G. Knepley 
1391c0ce001eSMatthew G. Knepley /*@
1392c0ce001eSMatthew G. Knepley   PetscFVGetComputeGradients - Return flag for computation of cell gradients
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 . computeGradients - Flag to compute cell gradients
1401c0ce001eSMatthew G. Knepley 
140288f5f89eSMatthew G. Knepley   Level: intermediate
1403c0ce001eSMatthew G. Knepley 
1404c0ce001eSMatthew G. Knepley .seealso: PetscFVSetComputeGradients()
1405c0ce001eSMatthew G. Knepley @*/
1406c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetComputeGradients(PetscFV fvm, PetscBool *computeGradients)
1407c0ce001eSMatthew G. Knepley {
1408c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1409c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1410dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(computeGradients, 2);
1411c0ce001eSMatthew G. Knepley   *computeGradients = fvm->computeGradients;
1412c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1413c0ce001eSMatthew G. Knepley }
1414c0ce001eSMatthew G. Knepley 
1415c0ce001eSMatthew G. Knepley /*@
1416c0ce001eSMatthew G. Knepley   PetscFVSetQuadrature - Set the quadrature object
1417c0ce001eSMatthew G. Knepley 
1418c0ce001eSMatthew G. Knepley   Logically collective on fvm
1419c0ce001eSMatthew G. Knepley 
1420c0ce001eSMatthew G. Knepley   Input Parameters:
1421c0ce001eSMatthew G. Knepley + fvm - the PetscFV object
1422c0ce001eSMatthew G. Knepley - q - The PetscQuadrature
1423c0ce001eSMatthew G. Knepley 
142488f5f89eSMatthew G. Knepley   Level: intermediate
1425c0ce001eSMatthew G. Knepley 
1426c0ce001eSMatthew G. Knepley .seealso: PetscFVGetQuadrature()
1427c0ce001eSMatthew G. Knepley @*/
1428c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetQuadrature(PetscFV fvm, PetscQuadrature q)
1429c0ce001eSMatthew G. Knepley {
1430c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1431c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
14329566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureDestroy(&fvm->quadrature));
14339566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject) q));
1434c0ce001eSMatthew G. Knepley   fvm->quadrature = q;
1435c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1436c0ce001eSMatthew G. Knepley }
1437c0ce001eSMatthew G. Knepley 
1438c0ce001eSMatthew G. Knepley /*@
1439c0ce001eSMatthew G. Knepley   PetscFVGetQuadrature - Get the quadrature object
1440c0ce001eSMatthew G. Knepley 
1441c0ce001eSMatthew G. Knepley   Not collective
1442c0ce001eSMatthew G. Knepley 
1443c0ce001eSMatthew G. Knepley   Input Parameter:
1444c0ce001eSMatthew G. Knepley . fvm - the PetscFV object
1445c0ce001eSMatthew G. Knepley 
1446c0ce001eSMatthew G. Knepley   Output Parameter:
1447c0ce001eSMatthew G. Knepley . lim - The PetscQuadrature
1448c0ce001eSMatthew G. Knepley 
144988f5f89eSMatthew G. Knepley   Level: intermediate
1450c0ce001eSMatthew G. Knepley 
1451c0ce001eSMatthew G. Knepley .seealso: PetscFVSetQuadrature()
1452c0ce001eSMatthew G. Knepley @*/
1453c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetQuadrature(PetscFV fvm, PetscQuadrature *q)
1454c0ce001eSMatthew G. Knepley {
1455c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1456c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1457c0ce001eSMatthew G. Knepley   PetscValidPointer(q, 2);
1458c0ce001eSMatthew G. Knepley   if (!fvm->quadrature) {
1459c0ce001eSMatthew G. Knepley     /* Create default 1-point quadrature */
1460c0ce001eSMatthew G. Knepley     PetscReal     *points, *weights;
1461c0ce001eSMatthew G. Knepley 
14629566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &fvm->quadrature));
14639566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(fvm->dim, &points));
14649566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(1, &weights));
1465c0ce001eSMatthew G. Knepley     weights[0] = 1.0;
14669566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureSetData(fvm->quadrature, fvm->dim, 1, 1, points, weights));
1467c0ce001eSMatthew G. Knepley   }
1468c0ce001eSMatthew G. Knepley   *q = fvm->quadrature;
1469c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1470c0ce001eSMatthew G. Knepley }
1471c0ce001eSMatthew G. Knepley 
1472c0ce001eSMatthew G. Knepley /*@
1473c0ce001eSMatthew G. Knepley   PetscFVGetDualSpace - Returns the PetscDualSpace used to define the inner product
1474c0ce001eSMatthew G. Knepley 
1475c0ce001eSMatthew G. Knepley   Not collective
1476c0ce001eSMatthew G. Knepley 
1477c0ce001eSMatthew G. Knepley   Input Parameter:
1478c0ce001eSMatthew G. Knepley . fvm - The PetscFV object
1479c0ce001eSMatthew G. Knepley 
1480c0ce001eSMatthew G. Knepley   Output Parameter:
1481c0ce001eSMatthew G. Knepley . sp - The PetscDualSpace object
1482c0ce001eSMatthew G. Knepley 
1483c0ce001eSMatthew G. Knepley   Note: A simple dual space is provided automatically, and the user typically will not need to override it.
1484c0ce001eSMatthew G. Knepley 
148588f5f89eSMatthew G. Knepley   Level: intermediate
1486c0ce001eSMatthew G. Knepley 
1487c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate()
1488c0ce001eSMatthew G. Knepley @*/
1489c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetDualSpace(PetscFV fvm, PetscDualSpace *sp)
1490c0ce001eSMatthew G. Knepley {
1491c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1492c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1493c0ce001eSMatthew G. Knepley   PetscValidPointer(sp, 2);
1494c0ce001eSMatthew G. Knepley   if (!fvm->dualSpace) {
1495c0ce001eSMatthew G. Knepley     DM              K;
1496c0ce001eSMatthew G. Knepley     PetscInt        dim, Nc, c;
1497c0ce001eSMatthew G. Knepley 
14989566063dSJacob Faibussowitsch     PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
14999566063dSJacob Faibussowitsch     PetscCall(PetscFVGetNumComponents(fvm, &Nc));
15009566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceCreate(PetscObjectComm((PetscObject) fvm), &fvm->dualSpace));
15019566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSetType(fvm->dualSpace, PETSCDUALSPACESIMPLE));
15029566063dSJacob Faibussowitsch     PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, DMPolytopeTypeSimpleShape(dim, PETSC_FALSE), &K));
15039566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSetNumComponents(fvm->dualSpace, Nc));
15049566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSetDM(fvm->dualSpace, K));
15059566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&K));
15069566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSimpleSetDimension(fvm->dualSpace, Nc));
1507c0ce001eSMatthew G. Knepley     /* Should we be using PetscFVGetQuadrature() here? */
1508c0ce001eSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
1509c0ce001eSMatthew G. Knepley       PetscQuadrature qc;
1510c0ce001eSMatthew G. Knepley       PetscReal      *points, *weights;
1511c0ce001eSMatthew G. Knepley 
15129566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qc));
15139566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(dim, &points));
15149566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(Nc, &weights));
1515c0ce001eSMatthew G. Knepley       weights[c] = 1.0;
15169566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureSetData(qc, dim, Nc, 1, points, weights));
15179566063dSJacob Faibussowitsch       PetscCall(PetscDualSpaceSimpleSetFunctional(fvm->dualSpace, c, qc));
15189566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureDestroy(&qc));
1519c0ce001eSMatthew G. Knepley     }
15209566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSetUp(fvm->dualSpace));
1521c0ce001eSMatthew G. Knepley   }
1522c0ce001eSMatthew G. Knepley   *sp = fvm->dualSpace;
1523c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1524c0ce001eSMatthew G. Knepley }
1525c0ce001eSMatthew G. Knepley 
1526c0ce001eSMatthew G. Knepley /*@
1527c0ce001eSMatthew G. Knepley   PetscFVSetDualSpace - Sets the PetscDualSpace used to define the inner product
1528c0ce001eSMatthew G. Knepley 
1529c0ce001eSMatthew G. Knepley   Not collective
1530c0ce001eSMatthew G. Knepley 
1531c0ce001eSMatthew G. Knepley   Input Parameters:
1532c0ce001eSMatthew G. Knepley + fvm - The PetscFV object
1533c0ce001eSMatthew G. Knepley - sp  - The PetscDualSpace object
1534c0ce001eSMatthew G. Knepley 
1535c0ce001eSMatthew G. Knepley   Level: intermediate
1536c0ce001eSMatthew G. Knepley 
1537c0ce001eSMatthew G. Knepley   Note: A simple dual space is provided automatically, and the user typically will not need to override it.
1538c0ce001eSMatthew G. Knepley 
1539c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate()
1540c0ce001eSMatthew G. Knepley @*/
1541c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetDualSpace(PetscFV fvm, PetscDualSpace sp)
1542c0ce001eSMatthew G. Knepley {
1543c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1544c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1545c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 2);
15469566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceDestroy(&fvm->dualSpace));
1547c0ce001eSMatthew G. Knepley   fvm->dualSpace = sp;
15489566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject) fvm->dualSpace));
1549c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1550c0ce001eSMatthew G. Knepley }
1551c0ce001eSMatthew G. Knepley 
155288f5f89eSMatthew G. Knepley /*@C
1553ef0bb6c7SMatthew G. Knepley   PetscFVGetCellTabulation - Returns the tabulation of the basis functions at the quadrature points
155488f5f89eSMatthew G. Knepley 
155588f5f89eSMatthew G. Knepley   Not collective
155688f5f89eSMatthew G. Knepley 
155788f5f89eSMatthew G. Knepley   Input Parameter:
155888f5f89eSMatthew G. Knepley . fvm - The PetscFV object
155988f5f89eSMatthew G. Knepley 
1560ef0bb6c7SMatthew G. Knepley   Output Parameter:
1561a5b23f4aSJose E. Roman . T - The basis function values and derivatives at quadrature points
156288f5f89eSMatthew G. Knepley 
156388f5f89eSMatthew G. Knepley   Note:
1564ef0bb6c7SMatthew G. Knepley $ T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c
1565ef0bb6c7SMatthew 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
1566ef0bb6c7SMatthew 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
156788f5f89eSMatthew G. Knepley 
156888f5f89eSMatthew G. Knepley   Level: intermediate
156988f5f89eSMatthew G. Knepley 
1570ef0bb6c7SMatthew G. Knepley .seealso: PetscFEGetCellTabulation(), PetscFVCreateTabulation(), PetscFVGetQuadrature(), PetscQuadratureGetData()
157188f5f89eSMatthew G. Knepley @*/
1572ef0bb6c7SMatthew G. Knepley PetscErrorCode PetscFVGetCellTabulation(PetscFV fvm, PetscTabulation *T)
1573c0ce001eSMatthew G. Knepley {
1574c0ce001eSMatthew G. Knepley   PetscInt         npoints;
1575c0ce001eSMatthew G. Knepley   const PetscReal *points;
1576c0ce001eSMatthew G. Knepley 
1577c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1578c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1579ef0bb6c7SMatthew G. Knepley   PetscValidPointer(T, 2);
15809566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureGetData(fvm->quadrature, NULL, NULL, &npoints, &points, NULL));
15819566063dSJacob Faibussowitsch   if (!fvm->T) PetscCall(PetscFVCreateTabulation(fvm, 1, npoints, points, 1, &fvm->T));
1582ef0bb6c7SMatthew G. Knepley   *T = fvm->T;
1583c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1584c0ce001eSMatthew G. Knepley }
1585c0ce001eSMatthew G. Knepley 
158688f5f89eSMatthew G. Knepley /*@C
1587ef0bb6c7SMatthew G. Knepley   PetscFVCreateTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided.
158888f5f89eSMatthew G. Knepley 
158988f5f89eSMatthew G. Knepley   Not collective
159088f5f89eSMatthew G. Knepley 
159188f5f89eSMatthew G. Knepley   Input Parameters:
159288f5f89eSMatthew G. Knepley + fvm     - The PetscFV object
1593ef0bb6c7SMatthew G. Knepley . nrepl   - The number of replicas
1594ef0bb6c7SMatthew G. Knepley . npoints - The number of tabulation points in a replica
1595ef0bb6c7SMatthew G. Knepley . points  - The tabulation point coordinates
1596ef0bb6c7SMatthew G. Knepley - K       - The order of derivative to tabulate
159788f5f89eSMatthew G. Knepley 
1598ef0bb6c7SMatthew G. Knepley   Output Parameter:
1599a5b23f4aSJose E. Roman . T - The basis function values and derivative at tabulation points
160088f5f89eSMatthew G. Knepley 
160188f5f89eSMatthew G. Knepley   Note:
1602ef0bb6c7SMatthew G. Knepley $ T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c
1603ef0bb6c7SMatthew 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
1604ef0bb6c7SMatthew 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
160588f5f89eSMatthew G. Knepley 
160688f5f89eSMatthew G. Knepley   Level: intermediate
160788f5f89eSMatthew G. Knepley 
1608ef0bb6c7SMatthew G. Knepley .seealso: PetscFECreateTabulation(), PetscTabulationDestroy(), PetscFEGetCellTabulation()
160988f5f89eSMatthew G. Knepley @*/
1610ef0bb6c7SMatthew G. Knepley PetscErrorCode PetscFVCreateTabulation(PetscFV fvm, PetscInt nrepl, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation *T)
1611c0ce001eSMatthew G. Knepley {
1612c0ce001eSMatthew G. Knepley   PetscInt         pdim = 1; /* Dimension of approximation space P */
1613ef0bb6c7SMatthew G. Knepley   PetscInt         cdim;     /* Spatial dimension */
1614ef0bb6c7SMatthew G. Knepley   PetscInt         Nc;       /* Field components */
1615ef0bb6c7SMatthew G. Knepley   PetscInt         k, p, d, c, e;
1616c0ce001eSMatthew G. Knepley 
1617c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1618ef0bb6c7SMatthew G. Knepley   if (!npoints || K < 0) {
1619ef0bb6c7SMatthew G. Knepley     *T = NULL;
1620c0ce001eSMatthew G. Knepley     PetscFunctionReturn(0);
1621c0ce001eSMatthew G. Knepley   }
1622c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
1623dadcf809SJacob Faibussowitsch   PetscValidRealPointer(points, 4);
162440a2aa30SMatthew G. Knepley   PetscValidPointer(T, 6);
16259566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &cdim));
16269566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fvm, &Nc));
16279566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(1, T));
1628ef0bb6c7SMatthew G. Knepley   (*T)->K    = !cdim ? 0 : K;
1629ef0bb6c7SMatthew G. Knepley   (*T)->Nr   = nrepl;
1630ef0bb6c7SMatthew G. Knepley   (*T)->Np   = npoints;
1631ef0bb6c7SMatthew G. Knepley   (*T)->Nb   = pdim;
1632ef0bb6c7SMatthew G. Knepley   (*T)->Nc   = Nc;
1633ef0bb6c7SMatthew G. Knepley   (*T)->cdim = cdim;
16349566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1((*T)->K+1, &(*T)->T));
1635ef0bb6c7SMatthew G. Knepley   for (k = 0; k <= (*T)->K; ++k) {
16369566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nrepl*npoints*pdim*Nc*PetscPowInt(cdim, k), &(*T)->T[k]));
1637ef0bb6c7SMatthew G. Knepley   }
1638ef0bb6c7SMatthew G. Knepley   if (K >= 0) {for (p = 0; p < nrepl*npoints; ++p) for (d = 0; d < pdim; ++d) for (c = 0; c < Nc; ++c) (*T)->T[0][(p*pdim + d)*Nc + c] = 1.0;}
1639ef0bb6c7SMatthew G. Knepley   if (K >= 1) {for (p = 0; p < nrepl*npoints; ++p) for (d = 0; d < pdim; ++d) for (c = 0; c < Nc; ++c) for (e = 0; e < cdim; ++e) (*T)->T[1][((p*pdim + d)*Nc + c)*cdim + e] = 0.0;}
1640ef0bb6c7SMatthew G. Knepley   if (K >= 2) {for (p = 0; p < nrepl*npoints; ++p) for (d = 0; d < pdim; ++d) for (c = 0; c < Nc; ++c) for (e = 0; e < cdim*cdim; ++e) (*T)->T[2][((p*pdim + d)*Nc + c)*cdim*cdim + e] = 0.0;}
1641c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1642c0ce001eSMatthew G. Knepley }
1643c0ce001eSMatthew G. Knepley 
1644c0ce001eSMatthew G. Knepley /*@C
1645c0ce001eSMatthew G. Knepley   PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell
1646c0ce001eSMatthew G. Knepley 
1647c0ce001eSMatthew G. Knepley   Input Parameters:
1648c0ce001eSMatthew G. Knepley + fvm      - The PetscFV object
1649c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained
1650c0ce001eSMatthew G. Knepley - dx       - The vector from the cell centroid to the neighboring cell centroid for each face
1651c0ce001eSMatthew G. Knepley 
165288f5f89eSMatthew G. Knepley   Level: advanced
1653c0ce001eSMatthew G. Knepley 
1654c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate()
1655c0ce001eSMatthew G. Knepley @*/
1656c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVComputeGradient(PetscFV fvm, PetscInt numFaces, PetscScalar dx[], PetscScalar grad[])
1657c0ce001eSMatthew G. Knepley {
1658c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1659c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
16609566063dSJacob Faibussowitsch   if (fvm->ops->computegradient) PetscCall((*fvm->ops->computegradient)(fvm, numFaces, dx, grad));
1661c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1662c0ce001eSMatthew G. Knepley }
1663c0ce001eSMatthew G. Knepley 
166488f5f89eSMatthew G. Knepley /*@C
1665c0ce001eSMatthew G. Knepley   PetscFVIntegrateRHSFunction - Produce the cell residual vector for a chunk of elements by quadrature integration
1666c0ce001eSMatthew G. Knepley 
1667c0ce001eSMatthew G. Knepley   Not collective
1668c0ce001eSMatthew G. Knepley 
1669c0ce001eSMatthew G. Knepley   Input Parameters:
1670c0ce001eSMatthew G. Knepley + fvm          - The PetscFV object for the field being integrated
1671c0ce001eSMatthew G. Knepley . prob         - The PetscDS specifing the discretizations and continuum functions
1672c0ce001eSMatthew G. Knepley . field        - The field being integrated
1673c0ce001eSMatthew G. Knepley . Nf           - The number of faces in the chunk
1674c0ce001eSMatthew G. Knepley . fgeom        - The face geometry for each face in the chunk
1675c0ce001eSMatthew G. Knepley . neighborVol  - The volume for each pair of cells in the chunk
1676c0ce001eSMatthew G. Knepley . uL           - The state from the cell on the left
1677c0ce001eSMatthew G. Knepley - uR           - The state from the cell on the right
1678c0ce001eSMatthew G. Knepley 
1679d8d19677SJose E. Roman   Output Parameters:
1680c0ce001eSMatthew G. Knepley + fluxL        - the left fluxes for each face
1681c0ce001eSMatthew G. Knepley - fluxR        - the right fluxes for each face
168288f5f89eSMatthew G. Knepley 
168388f5f89eSMatthew G. Knepley   Level: developer
168488f5f89eSMatthew G. Knepley 
168588f5f89eSMatthew G. Knepley .seealso: PetscFVCreate()
168688f5f89eSMatthew G. Knepley @*/
1687c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVIntegrateRHSFunction(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol,
1688c0ce001eSMatthew G. Knepley                                            PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[])
1689c0ce001eSMatthew G. Knepley {
1690c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1691c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
16929566063dSJacob Faibussowitsch   if (fvm->ops->integraterhsfunction) PetscCall((*fvm->ops->integraterhsfunction)(fvm, prob, field, Nf, fgeom, neighborVol, uL, uR, fluxL, fluxR));
1693c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1694c0ce001eSMatthew G. Knepley }
1695c0ce001eSMatthew G. Knepley 
1696c0ce001eSMatthew G. Knepley /*@
1697c0ce001eSMatthew G. Knepley   PetscFVRefine - Create a "refined" PetscFV object that refines the reference cell into smaller copies. This is typically used
1698c0ce001eSMatthew 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
1699c0ce001eSMatthew G. Knepley   sparsity). It is also used to create an interpolation between regularly refined meshes.
1700c0ce001eSMatthew G. Knepley 
1701c0ce001eSMatthew G. Knepley   Input Parameter:
1702c0ce001eSMatthew G. Knepley . fv - The initial PetscFV
1703c0ce001eSMatthew G. Knepley 
1704c0ce001eSMatthew G. Knepley   Output Parameter:
1705c0ce001eSMatthew G. Knepley . fvRef - The refined PetscFV
1706c0ce001eSMatthew G. Knepley 
170788f5f89eSMatthew G. Knepley   Level: advanced
1708c0ce001eSMatthew G. Knepley 
1709c0ce001eSMatthew G. Knepley .seealso: PetscFVType, PetscFVCreate(), PetscFVSetType()
1710c0ce001eSMatthew G. Knepley @*/
1711c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVRefine(PetscFV fv, PetscFV *fvRef)
1712c0ce001eSMatthew G. Knepley {
1713c0ce001eSMatthew G. Knepley   PetscDualSpace    Q, Qref;
1714c0ce001eSMatthew G. Knepley   DM                K, Kref;
1715c0ce001eSMatthew G. Knepley   PetscQuadrature   q, qref;
1716412e9a14SMatthew G. Knepley   DMPolytopeType    ct;
1717012bc364SMatthew G. Knepley   DMPlexTransform   tr;
1718c0ce001eSMatthew G. Knepley   PetscReal        *v0;
1719c0ce001eSMatthew G. Knepley   PetscReal        *jac, *invjac;
1720c0ce001eSMatthew G. Knepley   PetscInt          numComp, numSubelements, s;
1721c0ce001eSMatthew G. Knepley 
1722c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
17239566063dSJacob Faibussowitsch   PetscCall(PetscFVGetDualSpace(fv, &Q));
17249566063dSJacob Faibussowitsch   PetscCall(PetscFVGetQuadrature(fv, &q));
17259566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceGetDM(Q, &K));
1726c0ce001eSMatthew G. Knepley   /* Create dual space */
17279566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceDuplicate(Q, &Qref));
17289566063dSJacob Faibussowitsch   PetscCall(DMRefine(K, PetscObjectComm((PetscObject) fv), &Kref));
17299566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceSetDM(Qref, Kref));
17309566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&Kref));
17319566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceSetUp(Qref));
1732c0ce001eSMatthew G. Knepley   /* Create volume */
17339566063dSJacob Faibussowitsch   PetscCall(PetscFVCreate(PetscObjectComm((PetscObject) fv), fvRef));
17349566063dSJacob Faibussowitsch   PetscCall(PetscFVSetDualSpace(*fvRef, Qref));
17359566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fv,    &numComp));
17369566063dSJacob Faibussowitsch   PetscCall(PetscFVSetNumComponents(*fvRef, numComp));
17379566063dSJacob Faibussowitsch   PetscCall(PetscFVSetUp(*fvRef));
1738c0ce001eSMatthew G. Knepley   /* Create quadrature */
17399566063dSJacob Faibussowitsch   PetscCall(DMPlexGetCellType(K, 0, &ct));
17409566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformCreate(PETSC_COMM_SELF, &tr));
17419566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR));
17429566063dSJacob Faibussowitsch   PetscCall(DMPlexRefineRegularGetAffineTransforms(tr, ct, &numSubelements, &v0, &jac, &invjac));
17439566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref));
17449566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceSimpleSetDimension(Qref, numSubelements));
1745c0ce001eSMatthew G. Knepley   for (s = 0; s < numSubelements; ++s) {
1746c0ce001eSMatthew G. Knepley     PetscQuadrature  qs;
1747c0ce001eSMatthew G. Knepley     const PetscReal *points, *weights;
1748c0ce001eSMatthew G. Knepley     PetscReal       *p, *w;
1749c0ce001eSMatthew G. Knepley     PetscInt         dim, Nc, npoints, np;
1750c0ce001eSMatthew G. Knepley 
17519566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qs));
17529566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureGetData(q, &dim, &Nc, &npoints, &points, &weights));
1753c0ce001eSMatthew G. Knepley     np   = npoints/numSubelements;
17549566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(np*dim,&p));
17559566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(np*Nc,&w));
17569566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(p, &points[s*np*dim], np*dim));
17579566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(w, &weights[s*np*Nc], np*Nc));
17589566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureSetData(qs, dim, Nc, np, p, w));
17599566063dSJacob Faibussowitsch     PetscCall(PetscDualSpaceSimpleSetFunctional(Qref, s, qs));
17609566063dSJacob Faibussowitsch     PetscCall(PetscQuadratureDestroy(&qs));
1761c0ce001eSMatthew G. Knepley   }
17629566063dSJacob Faibussowitsch   PetscCall(PetscFVSetQuadrature(*fvRef, qref));
17639566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformDestroy(&tr));
17649566063dSJacob Faibussowitsch   PetscCall(PetscQuadratureDestroy(&qref));
17659566063dSJacob Faibussowitsch   PetscCall(PetscDualSpaceDestroy(&Qref));
1766c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1767c0ce001eSMatthew G. Knepley }
1768c0ce001eSMatthew G. Knepley 
176988f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVDestroy_Upwind(PetscFV fvm)
1770c0ce001eSMatthew G. Knepley {
1771c0ce001eSMatthew G. Knepley   PetscFV_Upwind *b = (PetscFV_Upwind *) fvm->data;
1772c0ce001eSMatthew G. Knepley 
1773c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
17749566063dSJacob Faibussowitsch   PetscCall(PetscFree(b));
1775c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1776c0ce001eSMatthew G. Knepley }
1777c0ce001eSMatthew G. Knepley 
177888f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_Upwind_Ascii(PetscFV fv, PetscViewer viewer)
1779c0ce001eSMatthew G. Knepley {
1780c0ce001eSMatthew G. Knepley   PetscInt          Nc, c;
1781c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
1782c0ce001eSMatthew G. Knepley 
1783c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
17849566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fv, &Nc));
17859566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
17869566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Upwind Finite Volume:\n"));
17879566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  num components: %d\n", Nc));
1788c0ce001eSMatthew G. Knepley   for (c = 0; c < Nc; c++) {
1789c0ce001eSMatthew G. Knepley     if (fv->componentNames[c]) {
17909566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "    component %d: %s\n", c, fv->componentNames[c]));
1791c0ce001eSMatthew G. Knepley     }
1792c0ce001eSMatthew G. Knepley   }
1793c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1794c0ce001eSMatthew G. Knepley }
1795c0ce001eSMatthew G. Knepley 
179688f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_Upwind(PetscFV fv, PetscViewer viewer)
1797c0ce001eSMatthew G. Knepley {
1798c0ce001eSMatthew G. Knepley   PetscBool      iascii;
1799c0ce001eSMatthew G. Knepley 
1800c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1801c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1);
1802c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
18039566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
18049566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscFVView_Upwind_Ascii(fv, viewer));
1805c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1806c0ce001eSMatthew G. Knepley }
1807c0ce001eSMatthew G. Knepley 
180888f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVSetUp_Upwind(PetscFV fvm)
1809c0ce001eSMatthew G. Knepley {
1810c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1811c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1812c0ce001eSMatthew G. Knepley }
1813c0ce001eSMatthew G. Knepley 
1814c0ce001eSMatthew G. Knepley /*
1815c0ce001eSMatthew G. Knepley   neighborVol[f*2+0] contains the left  geom
1816c0ce001eSMatthew G. Knepley   neighborVol[f*2+1] contains the right geom
1817c0ce001eSMatthew G. Knepley */
181888f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVIntegrateRHSFunction_Upwind(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol,
1819c0ce001eSMatthew G. Knepley                                                          PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[])
1820c0ce001eSMatthew G. Knepley {
1821c0ce001eSMatthew G. Knepley   void             (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *);
1822c0ce001eSMatthew G. Knepley   void              *rctx;
1823c0ce001eSMatthew G. Knepley   PetscScalar       *flux = fvm->fluxWork;
1824c0ce001eSMatthew G. Knepley   const PetscScalar *constants;
1825c0ce001eSMatthew G. Knepley   PetscInt           dim, numConstants, pdim, totDim, Nc, off, f, d;
1826c0ce001eSMatthew G. Knepley 
1827c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
18289566063dSJacob Faibussowitsch   PetscCall(PetscDSGetTotalComponents(prob, &Nc));
18299566063dSJacob Faibussowitsch   PetscCall(PetscDSGetTotalDimension(prob, &totDim));
18309566063dSJacob Faibussowitsch   PetscCall(PetscDSGetFieldOffset(prob, field, &off));
18319566063dSJacob Faibussowitsch   PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann));
18329566063dSJacob Faibussowitsch   PetscCall(PetscDSGetContext(prob, field, &rctx));
18339566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &numConstants, &constants));
18349566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
18359566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fvm, &pdim));
1836c0ce001eSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
1837c0ce001eSMatthew G. Knepley     (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f*Nc], &uR[f*Nc], numConstants, constants, flux, rctx);
1838c0ce001eSMatthew G. Knepley     for (d = 0; d < pdim; ++d) {
1839c0ce001eSMatthew G. Knepley       fluxL[f*totDim+off+d] = flux[d] / neighborVol[f*2+0];
1840c0ce001eSMatthew G. Knepley       fluxR[f*totDim+off+d] = flux[d] / neighborVol[f*2+1];
1841c0ce001eSMatthew G. Knepley     }
1842c0ce001eSMatthew G. Knepley   }
1843c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1844c0ce001eSMatthew G. Knepley }
1845c0ce001eSMatthew G. Knepley 
184688f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVInitialize_Upwind(PetscFV fvm)
1847c0ce001eSMatthew G. Knepley {
1848c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1849c0ce001eSMatthew G. Knepley   fvm->ops->setfromoptions          = NULL;
1850c0ce001eSMatthew G. Knepley   fvm->ops->setup                   = PetscFVSetUp_Upwind;
1851c0ce001eSMatthew G. Knepley   fvm->ops->view                    = PetscFVView_Upwind;
1852c0ce001eSMatthew G. Knepley   fvm->ops->destroy                 = PetscFVDestroy_Upwind;
1853c0ce001eSMatthew G. Knepley   fvm->ops->integraterhsfunction    = PetscFVIntegrateRHSFunction_Upwind;
1854c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1855c0ce001eSMatthew G. Knepley }
1856c0ce001eSMatthew G. Knepley 
1857c0ce001eSMatthew G. Knepley /*MC
1858c0ce001eSMatthew G. Knepley   PETSCFVUPWIND = "upwind" - A PetscFV object
1859c0ce001eSMatthew G. Knepley 
1860c0ce001eSMatthew G. Knepley   Level: intermediate
1861c0ce001eSMatthew G. Knepley 
1862c0ce001eSMatthew G. Knepley .seealso: PetscFVType, PetscFVCreate(), PetscFVSetType()
1863c0ce001eSMatthew G. Knepley M*/
1864c0ce001eSMatthew G. Knepley 
1865c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscFVCreate_Upwind(PetscFV fvm)
1866c0ce001eSMatthew G. Knepley {
1867c0ce001eSMatthew G. Knepley   PetscFV_Upwind *b;
1868c0ce001eSMatthew G. Knepley 
1869c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1870c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
18719566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(fvm,&b));
1872c0ce001eSMatthew G. Knepley   fvm->data = b;
1873c0ce001eSMatthew G. Knepley 
18749566063dSJacob Faibussowitsch   PetscCall(PetscFVInitialize_Upwind(fvm));
1875c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1876c0ce001eSMatthew G. Knepley }
1877c0ce001eSMatthew G. Knepley 
1878c0ce001eSMatthew G. Knepley #include <petscblaslapack.h>
1879c0ce001eSMatthew G. Knepley 
188088f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVDestroy_LeastSquares(PetscFV fvm)
1881c0ce001eSMatthew G. Knepley {
1882c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *) fvm->data;
1883c0ce001eSMatthew G. Knepley 
1884c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
18859566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject) fvm, "PetscFVLeastSquaresSetMaxFaces_C", NULL));
18869566063dSJacob Faibussowitsch   PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work));
18879566063dSJacob Faibussowitsch   PetscCall(PetscFree(ls));
1888c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1889c0ce001eSMatthew G. Knepley }
1890c0ce001eSMatthew G. Knepley 
189188f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_LeastSquares_Ascii(PetscFV fv, PetscViewer viewer)
1892c0ce001eSMatthew G. Knepley {
1893c0ce001eSMatthew G. Knepley   PetscInt          Nc, c;
1894c0ce001eSMatthew G. Knepley   PetscViewerFormat format;
1895c0ce001eSMatthew G. Knepley 
1896c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
18979566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fv, &Nc));
18989566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
18999566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Finite Volume with Least Squares Reconstruction:\n"));
19009566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  num components: %d\n", Nc));
1901c0ce001eSMatthew G. Knepley   for (c = 0; c < Nc; c++) {
1902c0ce001eSMatthew G. Knepley     if (fv->componentNames[c]) {
19039566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "    component %d: %s\n", c, fv->componentNames[c]));
1904c0ce001eSMatthew G. Knepley     }
1905c0ce001eSMatthew G. Knepley   }
1906c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1907c0ce001eSMatthew G. Knepley }
1908c0ce001eSMatthew G. Knepley 
190988f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_LeastSquares(PetscFV fv, PetscViewer viewer)
1910c0ce001eSMatthew G. Knepley {
1911c0ce001eSMatthew G. Knepley   PetscBool      iascii;
1912c0ce001eSMatthew G. Knepley 
1913c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1914c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1);
1915c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
19169566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii));
19179566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscFVView_LeastSquares_Ascii(fv, viewer));
1918c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1919c0ce001eSMatthew G. Knepley }
1920c0ce001eSMatthew G. Knepley 
192188f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVSetUp_LeastSquares(PetscFV fvm)
1922c0ce001eSMatthew G. Knepley {
1923c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1924c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1925c0ce001eSMatthew G. Knepley }
1926c0ce001eSMatthew G. Knepley 
1927c0ce001eSMatthew G. Knepley /* Overwrites A. Can only handle full-rank problems with m>=n */
1928c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresPseudoInverse_Static(PetscInt m,PetscInt mstride,PetscInt n,PetscScalar *A,PetscScalar *Ainv,PetscScalar *tau,PetscInt worksize,PetscScalar *work)
1929c0ce001eSMatthew G. Knepley {
1930c0ce001eSMatthew G. Knepley   PetscBool      debug = PETSC_FALSE;
1931c0ce001eSMatthew G. Knepley   PetscBLASInt   M,N,K,lda,ldb,ldwork,info;
1932c0ce001eSMatthew G. Knepley   PetscScalar    *R,*Q,*Aback,Alpha;
1933c0ce001eSMatthew G. Knepley 
1934c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1935c0ce001eSMatthew G. Knepley   if (debug) {
19369566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m*n,&Aback));
19379566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(Aback,A,m*n));
1938c0ce001eSMatthew G. Knepley   }
1939c0ce001eSMatthew G. Knepley 
19409566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m,&M));
19419566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n,&N));
19429566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(mstride,&lda));
19439566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(worksize,&ldwork));
19449566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
194573cf7048SBarry Smith   PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&M,&N,A,&lda,tau,work,&ldwork,&info));
19469566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
194728b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"xGEQRF error");
1948c0ce001eSMatthew G. Knepley   R = A; /* Upper triangular part of A now contains R, the rest contains the elementary reflectors */
1949c0ce001eSMatthew G. Knepley 
1950c0ce001eSMatthew G. Knepley   /* Extract an explicit representation of Q */
1951c0ce001eSMatthew G. Knepley   Q    = Ainv;
19529566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(Q,A,mstride*n));
1953c0ce001eSMatthew G. Knepley   K    = N;                     /* full rank */
1954c0ce001eSMatthew G. Knepley   PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&M,&N,&K,Q,&lda,tau,work,&ldwork,&info));
195528b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"xORGQR/xUNGQR error");
1956c0ce001eSMatthew G. Knepley 
1957c0ce001eSMatthew G. Knepley   /* Compute A^{-T} = (R^{-1} Q^T)^T = Q R^{-T} */
1958c0ce001eSMatthew G. Knepley   Alpha = 1.0;
1959c0ce001eSMatthew G. Knepley   ldb   = lda;
1960c0ce001eSMatthew G. Knepley   BLAStrsm_("Right","Upper","ConjugateTranspose","NotUnitTriangular",&M,&N,&Alpha,R,&lda,Q,&ldb);
1961c0ce001eSMatthew G. Knepley   /* Ainv is Q, overwritten with inverse */
1962c0ce001eSMatthew G. Knepley 
1963c0ce001eSMatthew G. Knepley   if (debug) {                      /* Check that pseudo-inverse worked */
1964c0ce001eSMatthew G. Knepley     PetscScalar  Beta = 0.0;
1965c0ce001eSMatthew G. Knepley     PetscBLASInt ldc;
1966c0ce001eSMatthew G. Knepley     K   = N;
1967c0ce001eSMatthew G. Knepley     ldc = N;
1968c0ce001eSMatthew G. Knepley     BLASgemm_("ConjugateTranspose","Normal",&N,&K,&M,&Alpha,Ainv,&lda,Aback,&ldb,&Beta,work,&ldc);
19699566063dSJacob Faibussowitsch     PetscCall(PetscScalarView(n*n,work,PETSC_VIEWER_STDOUT_SELF));
19709566063dSJacob Faibussowitsch     PetscCall(PetscFree(Aback));
1971c0ce001eSMatthew G. Knepley   }
1972c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
1973c0ce001eSMatthew G. Knepley }
1974c0ce001eSMatthew G. Knepley 
1975c0ce001eSMatthew G. Knepley /* Overwrites A. Can handle degenerate problems and m<n. */
1976c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresPseudoInverseSVD_Static(PetscInt m,PetscInt mstride,PetscInt n,PetscScalar *A,PetscScalar *Ainv,PetscScalar *tau,PetscInt worksize,PetscScalar *work)
1977c0ce001eSMatthew G. Knepley {
1978c0ce001eSMatthew G. Knepley   PetscBool      debug = PETSC_FALSE;
1979c0ce001eSMatthew G. Knepley   PetscScalar   *Brhs, *Aback;
1980c0ce001eSMatthew G. Knepley   PetscScalar   *tmpwork;
1981c0ce001eSMatthew G. Knepley   PetscReal      rcond;
1982c0ce001eSMatthew G. Knepley #if defined (PETSC_USE_COMPLEX)
1983c0ce001eSMatthew G. Knepley   PetscInt       rworkSize;
1984c0ce001eSMatthew G. Knepley   PetscReal     *rwork;
1985c0ce001eSMatthew G. Knepley #endif
1986c0ce001eSMatthew G. Knepley   PetscInt       i, j, maxmn;
1987c0ce001eSMatthew G. Knepley   PetscBLASInt   M, N, lda, ldb, ldwork;
1988c0ce001eSMatthew G. Knepley   PetscBLASInt   nrhs, irank, info;
1989c0ce001eSMatthew G. Knepley 
1990c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
1991c0ce001eSMatthew G. Knepley   if (debug) {
19929566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m*n,&Aback));
19939566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(Aback,A,m*n));
1994c0ce001eSMatthew G. Knepley   }
1995c0ce001eSMatthew G. Knepley 
1996c0ce001eSMatthew G. Knepley   /* initialize to identity */
1997736d4f42SpierreXVI   tmpwork = work;
1998736d4f42SpierreXVI   Brhs = Ainv;
1999c0ce001eSMatthew G. Knepley   maxmn = PetscMax(m,n);
2000c0ce001eSMatthew G. Knepley   for (j=0; j<maxmn; j++) {
2001c0ce001eSMatthew G. Knepley     for (i=0; i<maxmn; i++) Brhs[i + j*maxmn] = 1.0*(i == j);
2002c0ce001eSMatthew G. Knepley   }
2003c0ce001eSMatthew G. Knepley 
20049566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m,&M));
20059566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n,&N));
20069566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(mstride,&lda));
20079566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(maxmn,&ldb));
20089566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(worksize,&ldwork));
2009c0ce001eSMatthew G. Knepley   rcond = -1;
20109566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
2011c0ce001eSMatthew G. Knepley   nrhs  = M;
2012c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX)
2013c0ce001eSMatthew G. Knepley   rworkSize = 5 * PetscMin(M,N);
20149566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(rworkSize,&rwork));
201573cf7048SBarry Smith   PetscStackCallBLAS("LAPACKgelss",LAPACKgelss_(&M,&N,&nrhs,A,&lda,Brhs,&ldb, (PetscReal *) tau,&rcond,&irank,tmpwork,&ldwork,rwork,&info));
20169566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
20179566063dSJacob Faibussowitsch   PetscCall(PetscFree(rwork));
2018c0ce001eSMatthew G. Knepley #else
2019c0ce001eSMatthew G. Knepley   nrhs  = M;
202073cf7048SBarry Smith   PetscStackCallBLAS("LAPACKgelss",LAPACKgelss_(&M,&N,&nrhs,A,&lda,Brhs,&ldb, (PetscReal *) tau,&rcond,&irank,tmpwork,&ldwork,&info));
20219566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
2022c0ce001eSMatthew G. Knepley #endif
202328b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"xGELSS error");
2024c0ce001eSMatthew G. Knepley   /* The following check should be turned into a diagnostic as soon as someone wants to do this intentionally */
20252c71b3e2SJacob Faibussowitsch   PetscCheckFalse(irank < PetscMin(M,N),PETSC_COMM_SELF,PETSC_ERR_USER,"Rank deficient least squares fit, indicates an isolated cell with two colinear points");
2026c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2027c0ce001eSMatthew G. Knepley }
2028c0ce001eSMatthew G. Knepley 
2029c0ce001eSMatthew G. Knepley #if 0
2030c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresDebugCell_Static(PetscFV fvm, PetscInt cell, DM dm, DM dmFace, PetscScalar *fgeom, DM dmCell, PetscScalar *cgeom)
2031c0ce001eSMatthew G. Knepley {
2032c0ce001eSMatthew G. Knepley   PetscReal       grad[2] = {0, 0};
2033c0ce001eSMatthew G. Knepley   const PetscInt *faces;
2034c0ce001eSMatthew G. Knepley   PetscInt        numFaces, f;
2035c0ce001eSMatthew G. Knepley 
2036c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
20379566063dSJacob Faibussowitsch   PetscCall(DMPlexGetConeSize(dm, cell, &numFaces));
20389566063dSJacob Faibussowitsch   PetscCall(DMPlexGetCone(dm, cell, &faces));
2039c0ce001eSMatthew G. Knepley   for (f = 0; f < numFaces; ++f) {
2040c0ce001eSMatthew G. Knepley     const PetscInt *fcells;
2041c0ce001eSMatthew G. Knepley     const CellGeom *cg1;
2042c0ce001eSMatthew G. Knepley     const FaceGeom *fg;
2043c0ce001eSMatthew G. Knepley 
20449566063dSJacob Faibussowitsch     PetscCall(DMPlexGetSupport(dm, faces[f], &fcells));
20459566063dSJacob Faibussowitsch     PetscCall(DMPlexPointLocalRead(dmFace, faces[f], fgeom, &fg));
2046c0ce001eSMatthew G. Knepley     for (i = 0; i < 2; ++i) {
2047c0ce001eSMatthew G. Knepley       PetscScalar du;
2048c0ce001eSMatthew G. Knepley 
2049c0ce001eSMatthew G. Knepley       if (fcells[i] == c) continue;
20509566063dSJacob Faibussowitsch       PetscCall(DMPlexPointLocalRead(dmCell, fcells[i], cgeom, &cg1));
2051c0ce001eSMatthew G. Knepley       du   = cg1->centroid[0] + 3*cg1->centroid[1] - (cg->centroid[0] + 3*cg->centroid[1]);
2052c0ce001eSMatthew G. Knepley       grad[0] += fg->grad[!i][0] * du;
2053c0ce001eSMatthew G. Knepley       grad[1] += fg->grad[!i][1] * du;
2054c0ce001eSMatthew G. Knepley     }
2055c0ce001eSMatthew G. Knepley   }
20569566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_SELF, "cell[%d] grad (%g, %g)\n", cell, grad[0], grad[1]));
2057c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2058c0ce001eSMatthew G. Knepley }
2059c0ce001eSMatthew G. Knepley #endif
2060c0ce001eSMatthew G. Knepley 
2061c0ce001eSMatthew G. Knepley /*
2062c0ce001eSMatthew G. Knepley   PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell
2063c0ce001eSMatthew G. Knepley 
2064c0ce001eSMatthew G. Knepley   Input Parameters:
2065c0ce001eSMatthew G. Knepley + fvm      - The PetscFV object
2066c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained
2067c0ce001eSMatthew G. Knepley . dx       - The vector from the cell centroid to the neighboring cell centroid for each face
2068c0ce001eSMatthew G. Knepley 
2069c0ce001eSMatthew G. Knepley   Level: developer
2070c0ce001eSMatthew G. Knepley 
2071c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate()
2072c0ce001eSMatthew G. Knepley */
207388f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVComputeGradient_LeastSquares(PetscFV fvm, PetscInt numFaces, const PetscScalar dx[], PetscScalar grad[])
2074c0ce001eSMatthew G. Knepley {
2075c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls       = (PetscFV_LeastSquares *) fvm->data;
2076c0ce001eSMatthew G. Knepley   const PetscBool       useSVD   = PETSC_TRUE;
2077c0ce001eSMatthew G. Knepley   const PetscInt        maxFaces = ls->maxFaces;
2078c0ce001eSMatthew G. Knepley   PetscInt              dim, f, d;
2079c0ce001eSMatthew G. Knepley 
2080c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2081c0ce001eSMatthew G. Knepley   if (numFaces > maxFaces) {
20822c71b3e2SJacob Faibussowitsch     PetscCheckFalse(maxFaces < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Reconstruction has not been initialized, call PetscFVLeastSquaresSetMaxFaces()");
208398921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of input faces %D > %D maxfaces", numFaces, maxFaces);
2084c0ce001eSMatthew G. Knepley   }
20859566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
2086c0ce001eSMatthew G. Knepley   for (f = 0; f < numFaces; ++f) {
2087c0ce001eSMatthew G. Knepley     for (d = 0; d < dim; ++d) ls->B[d*maxFaces+f] = dx[f*dim+d];
2088c0ce001eSMatthew G. Knepley   }
2089c0ce001eSMatthew G. Knepley   /* Overwrites B with garbage, returns Binv in row-major format */
2090736d4f42SpierreXVI   if (useSVD) {
2091736d4f42SpierreXVI     PetscInt maxmn = PetscMax(numFaces, dim);
20929566063dSJacob Faibussowitsch     PetscCall(PetscFVLeastSquaresPseudoInverseSVD_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work));
2093736d4f42SpierreXVI     /* Binv shaped in column-major, coldim=maxmn.*/
2094736d4f42SpierreXVI     for (f = 0; f < numFaces; ++f) {
2095736d4f42SpierreXVI       for (d = 0; d < dim; ++d) grad[f*dim+d] = ls->Binv[d + maxmn*f];
2096736d4f42SpierreXVI     }
2097736d4f42SpierreXVI   } else {
20989566063dSJacob Faibussowitsch     PetscCall(PetscFVLeastSquaresPseudoInverse_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work));
2099736d4f42SpierreXVI     /* Binv shaped in row-major, rowdim=maxFaces.*/
2100c0ce001eSMatthew G. Knepley     for (f = 0; f < numFaces; ++f) {
2101c0ce001eSMatthew G. Knepley       for (d = 0; d < dim; ++d) grad[f*dim+d] = ls->Binv[d*maxFaces + f];
2102c0ce001eSMatthew G. Knepley     }
2103736d4f42SpierreXVI   }
2104c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2105c0ce001eSMatthew G. Knepley }
2106c0ce001eSMatthew G. Knepley 
2107c0ce001eSMatthew G. Knepley /*
2108c0ce001eSMatthew G. Knepley   neighborVol[f*2+0] contains the left  geom
2109c0ce001eSMatthew G. Knepley   neighborVol[f*2+1] contains the right geom
2110c0ce001eSMatthew G. Knepley */
211188f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVIntegrateRHSFunction_LeastSquares(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol,
2112c0ce001eSMatthew G. Knepley                                                                PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[])
2113c0ce001eSMatthew G. Knepley {
2114c0ce001eSMatthew G. Knepley   void             (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *);
2115c0ce001eSMatthew G. Knepley   void              *rctx;
2116c0ce001eSMatthew G. Knepley   PetscScalar       *flux = fvm->fluxWork;
2117c0ce001eSMatthew G. Knepley   const PetscScalar *constants;
2118c0ce001eSMatthew G. Knepley   PetscInt           dim, numConstants, pdim, Nc, totDim, off, f, d;
2119c0ce001eSMatthew G. Knepley 
2120c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
21219566063dSJacob Faibussowitsch   PetscCall(PetscDSGetTotalComponents(prob, &Nc));
21229566063dSJacob Faibussowitsch   PetscCall(PetscDSGetTotalDimension(prob, &totDim));
21239566063dSJacob Faibussowitsch   PetscCall(PetscDSGetFieldOffset(prob, field, &off));
21249566063dSJacob Faibussowitsch   PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann));
21259566063dSJacob Faibussowitsch   PetscCall(PetscDSGetContext(prob, field, &rctx));
21269566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &numConstants, &constants));
21279566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
21289566063dSJacob Faibussowitsch   PetscCall(PetscFVGetNumComponents(fvm, &pdim));
2129c0ce001eSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
2130c0ce001eSMatthew G. Knepley     (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f*Nc], &uR[f*Nc], numConstants, constants, flux, rctx);
2131c0ce001eSMatthew G. Knepley     for (d = 0; d < pdim; ++d) {
2132c0ce001eSMatthew G. Knepley       fluxL[f*totDim+off+d] = flux[d] / neighborVol[f*2+0];
2133c0ce001eSMatthew G. Knepley       fluxR[f*totDim+off+d] = flux[d] / neighborVol[f*2+1];
2134c0ce001eSMatthew G. Knepley     }
2135c0ce001eSMatthew G. Knepley   }
2136c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2137c0ce001eSMatthew G. Knepley }
2138c0ce001eSMatthew G. Knepley 
2139c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresSetMaxFaces_LS(PetscFV fvm, PetscInt maxFaces)
2140c0ce001eSMatthew G. Knepley {
2141c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *) fvm->data;
2142736d4f42SpierreXVI   PetscInt              dim,m,n,nrhs,minmn,maxmn;
2143c0ce001eSMatthew G. Knepley 
2144c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2145c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
21469566063dSJacob Faibussowitsch   PetscCall(PetscFVGetSpatialDimension(fvm, &dim));
21479566063dSJacob Faibussowitsch   PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work));
2148c0ce001eSMatthew G. Knepley   ls->maxFaces = maxFaces;
2149c0ce001eSMatthew G. Knepley   m       = ls->maxFaces;
2150c0ce001eSMatthew G. Knepley   n       = dim;
2151c0ce001eSMatthew G. Knepley   nrhs    = ls->maxFaces;
2152736d4f42SpierreXVI   minmn   = PetscMin(m,n);
2153736d4f42SpierreXVI   maxmn   = PetscMax(m,n);
2154736d4f42SpierreXVI   ls->workSize = 3*minmn + PetscMax(2*minmn, PetscMax(maxmn, nrhs)); /* required by LAPACK */
21559566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(m*n,&ls->B,maxmn*maxmn,&ls->Binv,minmn,&ls->tau,ls->workSize,&ls->work));
2156c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2157c0ce001eSMatthew G. Knepley }
2158c0ce001eSMatthew G. Knepley 
2159c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVInitialize_LeastSquares(PetscFV fvm)
2160c0ce001eSMatthew G. Knepley {
2161c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2162c0ce001eSMatthew G. Knepley   fvm->ops->setfromoptions          = NULL;
2163c0ce001eSMatthew G. Knepley   fvm->ops->setup                   = PetscFVSetUp_LeastSquares;
2164c0ce001eSMatthew G. Knepley   fvm->ops->view                    = PetscFVView_LeastSquares;
2165c0ce001eSMatthew G. Knepley   fvm->ops->destroy                 = PetscFVDestroy_LeastSquares;
2166c0ce001eSMatthew G. Knepley   fvm->ops->computegradient         = PetscFVComputeGradient_LeastSquares;
2167c0ce001eSMatthew G. Knepley   fvm->ops->integraterhsfunction    = PetscFVIntegrateRHSFunction_LeastSquares;
2168c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2169c0ce001eSMatthew G. Knepley }
2170c0ce001eSMatthew G. Knepley 
2171c0ce001eSMatthew G. Knepley /*MC
2172c0ce001eSMatthew G. Knepley   PETSCFVLEASTSQUARES = "leastsquares" - A PetscFV object
2173c0ce001eSMatthew G. Knepley 
2174c0ce001eSMatthew G. Knepley   Level: intermediate
2175c0ce001eSMatthew G. Knepley 
2176c0ce001eSMatthew G. Knepley .seealso: PetscFVType, PetscFVCreate(), PetscFVSetType()
2177c0ce001eSMatthew G. Knepley M*/
2178c0ce001eSMatthew G. Knepley 
2179c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscFVCreate_LeastSquares(PetscFV fvm)
2180c0ce001eSMatthew G. Knepley {
2181c0ce001eSMatthew G. Knepley   PetscFV_LeastSquares *ls;
2182c0ce001eSMatthew G. Knepley 
2183c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2184c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
21859566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(fvm, &ls));
2186c0ce001eSMatthew G. Knepley   fvm->data = ls;
2187c0ce001eSMatthew G. Knepley 
2188c0ce001eSMatthew G. Knepley   ls->maxFaces = -1;
2189c0ce001eSMatthew G. Knepley   ls->workSize = -1;
2190c0ce001eSMatthew G. Knepley   ls->B        = NULL;
2191c0ce001eSMatthew G. Knepley   ls->Binv     = NULL;
2192c0ce001eSMatthew G. Knepley   ls->tau      = NULL;
2193c0ce001eSMatthew G. Knepley   ls->work     = NULL;
2194c0ce001eSMatthew G. Knepley 
21959566063dSJacob Faibussowitsch   PetscCall(PetscFVSetComputeGradients(fvm, PETSC_TRUE));
21969566063dSJacob Faibussowitsch   PetscCall(PetscFVInitialize_LeastSquares(fvm));
21979566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject) fvm, "PetscFVLeastSquaresSetMaxFaces_C", PetscFVLeastSquaresSetMaxFaces_LS));
2198c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2199c0ce001eSMatthew G. Knepley }
2200c0ce001eSMatthew G. Knepley 
2201c0ce001eSMatthew G. Knepley /*@
2202c0ce001eSMatthew G. Knepley   PetscFVLeastSquaresSetMaxFaces - Set the maximum number of cell faces for gradient reconstruction
2203c0ce001eSMatthew G. Knepley 
2204c0ce001eSMatthew G. Knepley   Not collective
2205c0ce001eSMatthew G. Knepley 
2206c0ce001eSMatthew G. Knepley   Input parameters:
2207c0ce001eSMatthew G. Knepley + fvm      - The PetscFV object
2208c0ce001eSMatthew G. Knepley - maxFaces - The maximum number of cell faces
2209c0ce001eSMatthew G. Knepley 
2210c0ce001eSMatthew G. Knepley   Level: intermediate
2211c0ce001eSMatthew G. Knepley 
2212c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate(), PETSCFVLEASTSQUARES
2213c0ce001eSMatthew G. Knepley @*/
2214c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVLeastSquaresSetMaxFaces(PetscFV fvm, PetscInt maxFaces)
2215c0ce001eSMatthew G. Knepley {
2216c0ce001eSMatthew G. Knepley   PetscFunctionBegin;
2217c0ce001eSMatthew G. Knepley   PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1);
2218*cac4c232SBarry Smith   PetscTryMethod(fvm, "PetscFVLeastSquaresSetMaxFaces_C", (PetscFV,PetscInt), (fvm,maxFaces));
2219c0ce001eSMatthew G. Knepley   PetscFunctionReturn(0);
2220c0ce001eSMatthew G. Knepley }
2221