1c0ce001eSMatthew G. Knepley #include <petsc/private/petscfvimpl.h> /*I "petscfv.h" I*/ 2412e9a14SMatthew G. Knepley #include <petscdmplex.h> 3012bc364SMatthew G. Knepley #include <petscdmplextransform.h> 4c0ce001eSMatthew G. Knepley #include <petscds.h> 5c0ce001eSMatthew G. Knepley 6c0ce001eSMatthew G. Knepley PetscClassId PETSCLIMITER_CLASSID = 0; 7c0ce001eSMatthew G. Knepley 8c0ce001eSMatthew G. Knepley PetscFunctionList PetscLimiterList = NULL; 9c0ce001eSMatthew G. Knepley PetscBool PetscLimiterRegisterAllCalled = PETSC_FALSE; 10c0ce001eSMatthew G. Knepley 11c0ce001eSMatthew G. Knepley PetscBool Limitercite = PETSC_FALSE; 12c0ce001eSMatthew G. Knepley const char LimiterCitation[] = "@article{BergerAftosmisMurman2005,\n" 13c0ce001eSMatthew G. Knepley " title = {Analysis of slope limiters on irregular grids},\n" 14c0ce001eSMatthew G. Knepley " journal = {AIAA paper},\n" 15c0ce001eSMatthew G. Knepley " author = {Marsha Berger and Michael J. Aftosmis and Scott M. Murman},\n" 16c0ce001eSMatthew G. Knepley " volume = {490},\n" 17c0ce001eSMatthew G. Knepley " year = {2005}\n}\n"; 18c0ce001eSMatthew G. Knepley 19c0ce001eSMatthew G. Knepley /*@C 20c0ce001eSMatthew G. Knepley PetscLimiterRegister - Adds a new PetscLimiter implementation 21c0ce001eSMatthew G. Knepley 22c0ce001eSMatthew G. Knepley Not Collective 23c0ce001eSMatthew G. Knepley 24c0ce001eSMatthew G. Knepley Input Parameters: 25c0ce001eSMatthew G. Knepley + name - The name of a new user-defined creation routine 26c0ce001eSMatthew G. Knepley - create_func - The creation routine itself 27c0ce001eSMatthew G. Knepley 28c0ce001eSMatthew G. Knepley Notes: 29c0ce001eSMatthew G. Knepley PetscLimiterRegister() may be called multiple times to add several user-defined PetscLimiters 30c0ce001eSMatthew G. Knepley 31c0ce001eSMatthew G. Knepley Sample usage: 32c0ce001eSMatthew G. Knepley .vb 33c0ce001eSMatthew G. Knepley PetscLimiterRegister("my_lim", MyPetscLimiterCreate); 34c0ce001eSMatthew G. Knepley .ve 35c0ce001eSMatthew G. Knepley 36c0ce001eSMatthew G. Knepley Then, your PetscLimiter type can be chosen with the procedural interface via 37c0ce001eSMatthew G. Knepley .vb 38c0ce001eSMatthew G. Knepley PetscLimiterCreate(MPI_Comm, PetscLimiter *); 39c0ce001eSMatthew G. Knepley PetscLimiterSetType(PetscLimiter, "my_lim"); 40c0ce001eSMatthew G. Knepley .ve 41c0ce001eSMatthew G. Knepley or at runtime via the option 42c0ce001eSMatthew G. Knepley .vb 43c0ce001eSMatthew G. Knepley -petsclimiter_type my_lim 44c0ce001eSMatthew G. Knepley .ve 45c0ce001eSMatthew G. Knepley 46c0ce001eSMatthew G. Knepley Level: advanced 47c0ce001eSMatthew G. Knepley 48db781477SPatrick Sanan .seealso: `PetscLimiterRegisterAll()`, `PetscLimiterRegisterDestroy()` 49c0ce001eSMatthew G. Knepley 50c0ce001eSMatthew G. Knepley @*/ 51*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterRegister(const char sname[], PetscErrorCode (*function)(PetscLimiter)) 52*d71ae5a4SJacob Faibussowitsch { 53c0ce001eSMatthew G. Knepley PetscFunctionBegin; 549566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&PetscLimiterList, sname, function)); 55c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 56c0ce001eSMatthew G. Knepley } 57c0ce001eSMatthew G. Knepley 58c0ce001eSMatthew G. Knepley /*@C 59c0ce001eSMatthew G. Knepley PetscLimiterSetType - Builds a particular PetscLimiter 60c0ce001eSMatthew G. Knepley 61c0ce001eSMatthew G. Knepley Collective on lim 62c0ce001eSMatthew G. Knepley 63c0ce001eSMatthew G. Knepley Input Parameters: 64c0ce001eSMatthew G. Knepley + lim - The PetscLimiter object 65c0ce001eSMatthew G. Knepley - name - The kind of limiter 66c0ce001eSMatthew G. Knepley 67c0ce001eSMatthew G. Knepley Options Database Key: 68c0ce001eSMatthew G. Knepley . -petsclimiter_type <type> - Sets the PetscLimiter type; use -help for a list of available types 69c0ce001eSMatthew G. Knepley 70c0ce001eSMatthew G. Knepley Level: intermediate 71c0ce001eSMatthew G. Knepley 72db781477SPatrick Sanan .seealso: `PetscLimiterGetType()`, `PetscLimiterCreate()` 73c0ce001eSMatthew G. Knepley @*/ 74*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterSetType(PetscLimiter lim, PetscLimiterType name) 75*d71ae5a4SJacob Faibussowitsch { 76c0ce001eSMatthew G. Knepley PetscErrorCode (*r)(PetscLimiter); 77c0ce001eSMatthew G. Knepley PetscBool match; 78c0ce001eSMatthew G. Knepley 79c0ce001eSMatthew G. Knepley PetscFunctionBegin; 80c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 819566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)lim, name, &match)); 82c0ce001eSMatthew G. Knepley if (match) PetscFunctionReturn(0); 83c0ce001eSMatthew G. Knepley 849566063dSJacob Faibussowitsch PetscCall(PetscLimiterRegisterAll()); 859566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(PetscLimiterList, name, &r)); 8628b400f6SJacob Faibussowitsch PetscCheck(r, PetscObjectComm((PetscObject)lim), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscLimiter type: %s", name); 87c0ce001eSMatthew G. Knepley 88c0ce001eSMatthew G. Knepley if (lim->ops->destroy) { 89dbbe0bcdSBarry Smith PetscUseTypeMethod(lim, destroy); 90c0ce001eSMatthew G. Knepley lim->ops->destroy = NULL; 91c0ce001eSMatthew G. Knepley } 929566063dSJacob Faibussowitsch PetscCall((*r)(lim)); 939566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)lim, name)); 94c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 95c0ce001eSMatthew G. Knepley } 96c0ce001eSMatthew G. Knepley 97c0ce001eSMatthew G. Knepley /*@C 98c0ce001eSMatthew G. Knepley PetscLimiterGetType - Gets the PetscLimiter type name (as a string) from the object. 99c0ce001eSMatthew G. Knepley 100c0ce001eSMatthew G. Knepley Not Collective 101c0ce001eSMatthew G. Knepley 102c0ce001eSMatthew G. Knepley Input Parameter: 103c0ce001eSMatthew G. Knepley . lim - The PetscLimiter 104c0ce001eSMatthew G. Knepley 105c0ce001eSMatthew G. Knepley Output Parameter: 106c0ce001eSMatthew G. Knepley . name - The PetscLimiter type name 107c0ce001eSMatthew G. Knepley 108c0ce001eSMatthew G. Knepley Level: intermediate 109c0ce001eSMatthew G. Knepley 110db781477SPatrick Sanan .seealso: `PetscLimiterSetType()`, `PetscLimiterCreate()` 111c0ce001eSMatthew G. Knepley @*/ 112*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterGetType(PetscLimiter lim, PetscLimiterType *name) 113*d71ae5a4SJacob Faibussowitsch { 114c0ce001eSMatthew G. Knepley PetscFunctionBegin; 115c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 116c0ce001eSMatthew G. Knepley PetscValidPointer(name, 2); 1179566063dSJacob Faibussowitsch PetscCall(PetscLimiterRegisterAll()); 118c0ce001eSMatthew G. Knepley *name = ((PetscObject)lim)->type_name; 119c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 120c0ce001eSMatthew G. Knepley } 121c0ce001eSMatthew G. Knepley 122c0ce001eSMatthew G. Knepley /*@C 123fe2efc57SMark PetscLimiterViewFromOptions - View from Options 124fe2efc57SMark 125fe2efc57SMark Collective on PetscLimiter 126fe2efc57SMark 127fe2efc57SMark Input Parameters: 128fe2efc57SMark + A - the PetscLimiter object to view 129736c3998SJose E. Roman . obj - Optional object 130736c3998SJose E. Roman - name - command line option 131fe2efc57SMark 132fe2efc57SMark Level: intermediate 133db781477SPatrick Sanan .seealso: `PetscLimiter`, `PetscLimiterView`, `PetscObjectViewFromOptions()`, `PetscLimiterCreate()` 134fe2efc57SMark @*/ 135*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterViewFromOptions(PetscLimiter A, PetscObject obj, const char name[]) 136*d71ae5a4SJacob Faibussowitsch { 137fe2efc57SMark PetscFunctionBegin; 138fe2efc57SMark PetscValidHeaderSpecific(A, PETSCLIMITER_CLASSID, 1); 1399566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 140fe2efc57SMark PetscFunctionReturn(0); 141fe2efc57SMark } 142fe2efc57SMark 143fe2efc57SMark /*@C 144c0ce001eSMatthew G. Knepley PetscLimiterView - Views a PetscLimiter 145c0ce001eSMatthew G. Knepley 146c0ce001eSMatthew G. Knepley Collective on lim 147c0ce001eSMatthew G. Knepley 148d8d19677SJose E. Roman Input Parameters: 149c0ce001eSMatthew G. Knepley + lim - the PetscLimiter object to view 150c0ce001eSMatthew G. Knepley - v - the viewer 151c0ce001eSMatthew G. Knepley 15288f5f89eSMatthew G. Knepley Level: beginner 153c0ce001eSMatthew G. Knepley 154db781477SPatrick Sanan .seealso: `PetscLimiterDestroy()` 155c0ce001eSMatthew G. Knepley @*/ 156*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterView(PetscLimiter lim, PetscViewer v) 157*d71ae5a4SJacob Faibussowitsch { 158c0ce001eSMatthew G. Knepley PetscFunctionBegin; 159c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 1609566063dSJacob Faibussowitsch if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lim), &v)); 161dbbe0bcdSBarry Smith PetscTryTypeMethod(lim, view, v); 162c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 163c0ce001eSMatthew G. Knepley } 164c0ce001eSMatthew G. Knepley 165c0ce001eSMatthew G. Knepley /*@ 166c0ce001eSMatthew G. Knepley PetscLimiterSetFromOptions - sets parameters in a PetscLimiter from the options database 167c0ce001eSMatthew G. Knepley 168c0ce001eSMatthew G. Knepley Collective on lim 169c0ce001eSMatthew G. Knepley 170c0ce001eSMatthew G. Knepley Input Parameter: 171c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to set options for 172c0ce001eSMatthew G. Knepley 17388f5f89eSMatthew G. Knepley Level: intermediate 174c0ce001eSMatthew G. Knepley 175db781477SPatrick Sanan .seealso: `PetscLimiterView()` 176c0ce001eSMatthew G. Knepley @*/ 177*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterSetFromOptions(PetscLimiter lim) 178*d71ae5a4SJacob Faibussowitsch { 179c0ce001eSMatthew G. Knepley const char *defaultType; 180c0ce001eSMatthew G. Knepley char name[256]; 181c0ce001eSMatthew G. Knepley PetscBool flg; 182c0ce001eSMatthew G. Knepley 183c0ce001eSMatthew G. Knepley PetscFunctionBegin; 184c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 185c0ce001eSMatthew G. Knepley if (!((PetscObject)lim)->type_name) defaultType = PETSCLIMITERSIN; 186c0ce001eSMatthew G. Knepley else defaultType = ((PetscObject)lim)->type_name; 1879566063dSJacob Faibussowitsch PetscCall(PetscLimiterRegisterAll()); 188c0ce001eSMatthew G. Knepley 189d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)lim); 1909566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-petsclimiter_type", "Finite volume slope limiter", "PetscLimiterSetType", PetscLimiterList, defaultType, name, 256, &flg)); 191c0ce001eSMatthew G. Knepley if (flg) { 1929566063dSJacob Faibussowitsch PetscCall(PetscLimiterSetType(lim, name)); 193c0ce001eSMatthew G. Knepley } else if (!((PetscObject)lim)->type_name) { 1949566063dSJacob Faibussowitsch PetscCall(PetscLimiterSetType(lim, defaultType)); 195c0ce001eSMatthew G. Knepley } 196dbbe0bcdSBarry Smith PetscTryTypeMethod(lim, setfromoptions); 197c0ce001eSMatthew G. Knepley /* process any options handlers added with PetscObjectAddOptionsHandler() */ 198dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)lim, PetscOptionsObject)); 199d0609cedSBarry Smith PetscOptionsEnd(); 2009566063dSJacob Faibussowitsch PetscCall(PetscLimiterViewFromOptions(lim, NULL, "-petsclimiter_view")); 201c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 202c0ce001eSMatthew G. Knepley } 203c0ce001eSMatthew G. Knepley 204c0ce001eSMatthew G. Knepley /*@C 205c0ce001eSMatthew G. Knepley PetscLimiterSetUp - Construct data structures for the PetscLimiter 206c0ce001eSMatthew G. Knepley 207c0ce001eSMatthew G. Knepley Collective on lim 208c0ce001eSMatthew G. Knepley 209c0ce001eSMatthew G. Knepley Input Parameter: 210c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to setup 211c0ce001eSMatthew G. Knepley 21288f5f89eSMatthew G. Knepley Level: intermediate 213c0ce001eSMatthew G. Knepley 214db781477SPatrick Sanan .seealso: `PetscLimiterView()`, `PetscLimiterDestroy()` 215c0ce001eSMatthew G. Knepley @*/ 216*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterSetUp(PetscLimiter lim) 217*d71ae5a4SJacob Faibussowitsch { 218c0ce001eSMatthew G. Knepley PetscFunctionBegin; 219c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 220dbbe0bcdSBarry Smith PetscTryTypeMethod(lim, setup); 221c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 222c0ce001eSMatthew G. Knepley } 223c0ce001eSMatthew G. Knepley 224c0ce001eSMatthew G. Knepley /*@ 225c0ce001eSMatthew G. Knepley PetscLimiterDestroy - Destroys a PetscLimiter object 226c0ce001eSMatthew G. Knepley 227c0ce001eSMatthew G. Knepley Collective on lim 228c0ce001eSMatthew G. Knepley 229c0ce001eSMatthew G. Knepley Input Parameter: 230c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to destroy 231c0ce001eSMatthew G. Knepley 23288f5f89eSMatthew G. Knepley Level: beginner 233c0ce001eSMatthew G. Knepley 234db781477SPatrick Sanan .seealso: `PetscLimiterView()` 235c0ce001eSMatthew G. Knepley @*/ 236*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterDestroy(PetscLimiter *lim) 237*d71ae5a4SJacob Faibussowitsch { 238c0ce001eSMatthew G. Knepley PetscFunctionBegin; 239c0ce001eSMatthew G. Knepley if (!*lim) PetscFunctionReturn(0); 240c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific((*lim), PETSCLIMITER_CLASSID, 1); 241c0ce001eSMatthew G. Knepley 2429371c9d4SSatish Balay if (--((PetscObject)(*lim))->refct > 0) { 2439371c9d4SSatish Balay *lim = NULL; 2449371c9d4SSatish Balay PetscFunctionReturn(0); 2459371c9d4SSatish Balay } 246c0ce001eSMatthew G. Knepley ((PetscObject)(*lim))->refct = 0; 247c0ce001eSMatthew G. Knepley 248dbbe0bcdSBarry Smith PetscTryTypeMethod((*lim), destroy); 2499566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(lim)); 250c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 251c0ce001eSMatthew G. Knepley } 252c0ce001eSMatthew G. Knepley 253c0ce001eSMatthew G. Knepley /*@ 254c0ce001eSMatthew G. Knepley PetscLimiterCreate - Creates an empty PetscLimiter object. The type can then be set with PetscLimiterSetType(). 255c0ce001eSMatthew G. Knepley 256c0ce001eSMatthew G. Knepley Collective 257c0ce001eSMatthew G. Knepley 258c0ce001eSMatthew G. Knepley Input Parameter: 259c0ce001eSMatthew G. Knepley . comm - The communicator for the PetscLimiter object 260c0ce001eSMatthew G. Knepley 261c0ce001eSMatthew G. Knepley Output Parameter: 262c0ce001eSMatthew G. Knepley . lim - The PetscLimiter object 263c0ce001eSMatthew G. Knepley 264c0ce001eSMatthew G. Knepley Level: beginner 265c0ce001eSMatthew G. Knepley 266db781477SPatrick Sanan .seealso: `PetscLimiterSetType()`, `PETSCLIMITERSIN` 267c0ce001eSMatthew G. Knepley @*/ 268*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterCreate(MPI_Comm comm, PetscLimiter *lim) 269*d71ae5a4SJacob Faibussowitsch { 270c0ce001eSMatthew G. Knepley PetscLimiter l; 271c0ce001eSMatthew G. Knepley 272c0ce001eSMatthew G. Knepley PetscFunctionBegin; 273c0ce001eSMatthew G. Knepley PetscValidPointer(lim, 2); 2749566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(LimiterCitation, &Limitercite)); 275c0ce001eSMatthew G. Knepley *lim = NULL; 2769566063dSJacob Faibussowitsch PetscCall(PetscFVInitializePackage()); 277c0ce001eSMatthew G. Knepley 2789566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(l, PETSCLIMITER_CLASSID, "PetscLimiter", "Finite Volume Slope Limiter", "PetscLimiter", comm, PetscLimiterDestroy, PetscLimiterView)); 279c0ce001eSMatthew G. Knepley 280c0ce001eSMatthew G. Knepley *lim = l; 281c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 282c0ce001eSMatthew G. Knepley } 283c0ce001eSMatthew G. Knepley 28488f5f89eSMatthew G. Knepley /*@ 28588f5f89eSMatthew G. Knepley PetscLimiterLimit - Limit the flux 28688f5f89eSMatthew G. Knepley 28788f5f89eSMatthew G. Knepley Input Parameters: 28888f5f89eSMatthew G. Knepley + lim - The PetscLimiter 28988f5f89eSMatthew G. Knepley - flim - The input field 29088f5f89eSMatthew G. Knepley 29188f5f89eSMatthew G. Knepley Output Parameter: 29288f5f89eSMatthew G. Knepley . phi - The limited field 29388f5f89eSMatthew G. Knepley 29488f5f89eSMatthew G. Knepley Note: Limiters given in symmetric form following Berger, Aftosmis, and Murman 2005 29588f5f89eSMatthew G. Knepley $ The classical flux-limited formulation is psi(r) where 29688f5f89eSMatthew G. Knepley $ 29788f5f89eSMatthew G. Knepley $ r = (u[0] - u[-1]) / (u[1] - u[0]) 29888f5f89eSMatthew G. Knepley $ 29988f5f89eSMatthew G. Knepley $ The second order TVD region is bounded by 30088f5f89eSMatthew G. Knepley $ 30188f5f89eSMatthew G. Knepley $ psi_minmod(r) = min(r,1) and psi_superbee(r) = min(2, 2r, max(1,r)) 30288f5f89eSMatthew G. Knepley $ 30388f5f89eSMatthew G. Knepley $ where all limiters are implicitly clipped to be non-negative. A more convenient slope-limited form is psi(r) = 30488f5f89eSMatthew G. Knepley $ phi(r)(r+1)/2 in which the reconstructed interface values are 30588f5f89eSMatthew G. Knepley $ 30688f5f89eSMatthew G. Knepley $ u(v) = u[0] + phi(r) (grad u)[0] v 30788f5f89eSMatthew G. Knepley $ 30888f5f89eSMatthew G. Knepley $ where v is the vector from centroid to quadrature point. In these variables, the usual limiters become 30988f5f89eSMatthew G. Knepley $ 31088f5f89eSMatthew G. Knepley $ phi_minmod(r) = 2 min(1/(1+r),r/(1+r)) phi_superbee(r) = 2 min(2/(1+r), 2r/(1+r), max(1,r)/(1+r)) 31188f5f89eSMatthew G. Knepley $ 31288f5f89eSMatthew G. Knepley $ For a nicer symmetric formulation, rewrite in terms of 31388f5f89eSMatthew G. Knepley $ 31488f5f89eSMatthew G. Knepley $ f = (u[0] - u[-1]) / (u[1] - u[-1]) 31588f5f89eSMatthew G. Knepley $ 31688f5f89eSMatthew G. Knepley $ where r(f) = f/(1-f). Not that r(1-f) = (1-f)/f = 1/r(f) so the symmetry condition 31788f5f89eSMatthew G. Knepley $ 31888f5f89eSMatthew G. Knepley $ phi(r) = phi(1/r) 31988f5f89eSMatthew G. Knepley $ 32088f5f89eSMatthew G. Knepley $ becomes 32188f5f89eSMatthew G. Knepley $ 32288f5f89eSMatthew G. Knepley $ w(f) = w(1-f). 32388f5f89eSMatthew G. Knepley $ 32488f5f89eSMatthew G. Knepley $ The limiters below implement this final form w(f). The reference methods are 32588f5f89eSMatthew G. Knepley $ 32688f5f89eSMatthew G. Knepley $ w_minmod(f) = 2 min(f,(1-f)) w_superbee(r) = 4 min((1-f), f) 32788f5f89eSMatthew G. Knepley 32888f5f89eSMatthew G. Knepley Level: beginner 32988f5f89eSMatthew G. Knepley 330db781477SPatrick Sanan .seealso: `PetscLimiterSetType()`, `PetscLimiterCreate()` 33188f5f89eSMatthew G. Knepley @*/ 332*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterLimit(PetscLimiter lim, PetscReal flim, PetscReal *phi) 333*d71ae5a4SJacob Faibussowitsch { 334c0ce001eSMatthew G. Knepley PetscFunctionBegin; 335c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 336dadcf809SJacob Faibussowitsch PetscValidRealPointer(phi, 3); 337dbbe0bcdSBarry Smith PetscUseTypeMethod(lim, limit, flim, phi); 338c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 339c0ce001eSMatthew G. Knepley } 340c0ce001eSMatthew G. Knepley 341*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_Sin(PetscLimiter lim) 342*d71ae5a4SJacob Faibussowitsch { 343c0ce001eSMatthew G. Knepley PetscLimiter_Sin *l = (PetscLimiter_Sin *)lim->data; 344c0ce001eSMatthew G. Knepley 345c0ce001eSMatthew G. Knepley PetscFunctionBegin; 3469566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 347c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 348c0ce001eSMatthew G. Knepley } 349c0ce001eSMatthew G. Knepley 350*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Sin_Ascii(PetscLimiter lim, PetscViewer viewer) 351*d71ae5a4SJacob Faibussowitsch { 352c0ce001eSMatthew G. Knepley PetscViewerFormat format; 353c0ce001eSMatthew G. Knepley 354c0ce001eSMatthew G. Knepley PetscFunctionBegin; 3559566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 3569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Sin Slope Limiter:\n")); 357c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 358c0ce001eSMatthew G. Knepley } 359c0ce001eSMatthew G. Knepley 360*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Sin(PetscLimiter lim, PetscViewer viewer) 361*d71ae5a4SJacob Faibussowitsch { 362c0ce001eSMatthew G. Knepley PetscBool iascii; 363c0ce001eSMatthew G. Knepley 364c0ce001eSMatthew G. Knepley PetscFunctionBegin; 365c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 366c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 3679566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 3689566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_Sin_Ascii(lim, viewer)); 369c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 370c0ce001eSMatthew G. Knepley } 371c0ce001eSMatthew G. Knepley 372*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_Sin(PetscLimiter lim, PetscReal f, PetscReal *phi) 373*d71ae5a4SJacob Faibussowitsch { 374c0ce001eSMatthew G. Knepley PetscFunctionBegin; 375c0ce001eSMatthew G. Knepley *phi = PetscSinReal(PETSC_PI * PetscMax(0, PetscMin(f, 1))); 376c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 377c0ce001eSMatthew G. Knepley } 378c0ce001eSMatthew G. Knepley 379*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_Sin(PetscLimiter lim) 380*d71ae5a4SJacob Faibussowitsch { 381c0ce001eSMatthew G. Knepley PetscFunctionBegin; 382c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Sin; 383c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Sin; 384c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Sin; 385c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 386c0ce001eSMatthew G. Knepley } 387c0ce001eSMatthew G. Knepley 388c0ce001eSMatthew G. Knepley /*MC 389c0ce001eSMatthew G. Knepley PETSCLIMITERSIN = "sin" - A PetscLimiter object 390c0ce001eSMatthew G. Knepley 391c0ce001eSMatthew G. Knepley Level: intermediate 392c0ce001eSMatthew G. Knepley 393db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 394c0ce001eSMatthew G. Knepley M*/ 395c0ce001eSMatthew G. Knepley 396*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Sin(PetscLimiter lim) 397*d71ae5a4SJacob Faibussowitsch { 398c0ce001eSMatthew G. Knepley PetscLimiter_Sin *l; 399c0ce001eSMatthew G. Knepley 400c0ce001eSMatthew G. Knepley PetscFunctionBegin; 401c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 4024dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 403c0ce001eSMatthew G. Knepley lim->data = l; 404c0ce001eSMatthew G. Knepley 4059566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_Sin(lim)); 406c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 407c0ce001eSMatthew G. Knepley } 408c0ce001eSMatthew G. Knepley 409*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_Zero(PetscLimiter lim) 410*d71ae5a4SJacob Faibussowitsch { 411c0ce001eSMatthew G. Knepley PetscLimiter_Zero *l = (PetscLimiter_Zero *)lim->data; 412c0ce001eSMatthew G. Knepley 413c0ce001eSMatthew G. Knepley PetscFunctionBegin; 4149566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 415c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 416c0ce001eSMatthew G. Knepley } 417c0ce001eSMatthew G. Knepley 418*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Zero_Ascii(PetscLimiter lim, PetscViewer viewer) 419*d71ae5a4SJacob Faibussowitsch { 420c0ce001eSMatthew G. Knepley PetscViewerFormat format; 421c0ce001eSMatthew G. Knepley 422c0ce001eSMatthew G. Knepley PetscFunctionBegin; 4239566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 4249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Zero Slope Limiter:\n")); 425c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 426c0ce001eSMatthew G. Knepley } 427c0ce001eSMatthew G. Knepley 428*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Zero(PetscLimiter lim, PetscViewer viewer) 429*d71ae5a4SJacob Faibussowitsch { 430c0ce001eSMatthew G. Knepley PetscBool iascii; 431c0ce001eSMatthew G. Knepley 432c0ce001eSMatthew G. Knepley PetscFunctionBegin; 433c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 434c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 4359566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 4369566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_Zero_Ascii(lim, viewer)); 437c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 438c0ce001eSMatthew G. Knepley } 439c0ce001eSMatthew G. Knepley 440*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_Zero(PetscLimiter lim, PetscReal f, PetscReal *phi) 441*d71ae5a4SJacob Faibussowitsch { 442c0ce001eSMatthew G. Knepley PetscFunctionBegin; 443c0ce001eSMatthew G. Knepley *phi = 0.0; 444c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 445c0ce001eSMatthew G. Knepley } 446c0ce001eSMatthew G. Knepley 447*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_Zero(PetscLimiter lim) 448*d71ae5a4SJacob Faibussowitsch { 449c0ce001eSMatthew G. Knepley PetscFunctionBegin; 450c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Zero; 451c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Zero; 452c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Zero; 453c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 454c0ce001eSMatthew G. Knepley } 455c0ce001eSMatthew G. Knepley 456c0ce001eSMatthew G. Knepley /*MC 457c0ce001eSMatthew G. Knepley PETSCLIMITERZERO = "zero" - A PetscLimiter object 458c0ce001eSMatthew G. Knepley 459c0ce001eSMatthew G. Knepley Level: intermediate 460c0ce001eSMatthew G. Knepley 461db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 462c0ce001eSMatthew G. Knepley M*/ 463c0ce001eSMatthew G. Knepley 464*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Zero(PetscLimiter lim) 465*d71ae5a4SJacob Faibussowitsch { 466c0ce001eSMatthew G. Knepley PetscLimiter_Zero *l; 467c0ce001eSMatthew G. Knepley 468c0ce001eSMatthew G. Knepley PetscFunctionBegin; 469c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 4704dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 471c0ce001eSMatthew G. Knepley lim->data = l; 472c0ce001eSMatthew G. Knepley 4739566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_Zero(lim)); 474c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 475c0ce001eSMatthew G. Knepley } 476c0ce001eSMatthew G. Knepley 477*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_None(PetscLimiter lim) 478*d71ae5a4SJacob Faibussowitsch { 479c0ce001eSMatthew G. Knepley PetscLimiter_None *l = (PetscLimiter_None *)lim->data; 480c0ce001eSMatthew G. Knepley 481c0ce001eSMatthew G. Knepley PetscFunctionBegin; 4829566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 483c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 484c0ce001eSMatthew G. Knepley } 485c0ce001eSMatthew G. Knepley 486*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_None_Ascii(PetscLimiter lim, PetscViewer viewer) 487*d71ae5a4SJacob Faibussowitsch { 488c0ce001eSMatthew G. Knepley PetscViewerFormat format; 489c0ce001eSMatthew G. Knepley 490c0ce001eSMatthew G. Knepley PetscFunctionBegin; 4919566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 4929566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "None Slope Limiter:\n")); 493c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 494c0ce001eSMatthew G. Knepley } 495c0ce001eSMatthew G. Knepley 496*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_None(PetscLimiter lim, PetscViewer viewer) 497*d71ae5a4SJacob Faibussowitsch { 498c0ce001eSMatthew G. Knepley PetscBool iascii; 499c0ce001eSMatthew G. Knepley 500c0ce001eSMatthew G. Knepley PetscFunctionBegin; 501c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 502c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 5039566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 5049566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_None_Ascii(lim, viewer)); 505c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 506c0ce001eSMatthew G. Knepley } 507c0ce001eSMatthew G. Knepley 508*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_None(PetscLimiter lim, PetscReal f, PetscReal *phi) 509*d71ae5a4SJacob Faibussowitsch { 510c0ce001eSMatthew G. Knepley PetscFunctionBegin; 511c0ce001eSMatthew G. Knepley *phi = 1.0; 512c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 513c0ce001eSMatthew G. Knepley } 514c0ce001eSMatthew G. Knepley 515*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_None(PetscLimiter lim) 516*d71ae5a4SJacob Faibussowitsch { 517c0ce001eSMatthew G. Knepley PetscFunctionBegin; 518c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_None; 519c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_None; 520c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_None; 521c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 522c0ce001eSMatthew G. Knepley } 523c0ce001eSMatthew G. Knepley 524c0ce001eSMatthew G. Knepley /*MC 525c0ce001eSMatthew G. Knepley PETSCLIMITERNONE = "none" - A PetscLimiter object 526c0ce001eSMatthew G. Knepley 527c0ce001eSMatthew G. Knepley Level: intermediate 528c0ce001eSMatthew G. Knepley 529db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 530c0ce001eSMatthew G. Knepley M*/ 531c0ce001eSMatthew G. Knepley 532*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_None(PetscLimiter lim) 533*d71ae5a4SJacob Faibussowitsch { 534c0ce001eSMatthew G. Knepley PetscLimiter_None *l; 535c0ce001eSMatthew G. Knepley 536c0ce001eSMatthew G. Knepley PetscFunctionBegin; 537c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 5384dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 539c0ce001eSMatthew G. Knepley lim->data = l; 540c0ce001eSMatthew G. Knepley 5419566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_None(lim)); 542c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 543c0ce001eSMatthew G. Knepley } 544c0ce001eSMatthew G. Knepley 545*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_Minmod(PetscLimiter lim) 546*d71ae5a4SJacob Faibussowitsch { 547c0ce001eSMatthew G. Knepley PetscLimiter_Minmod *l = (PetscLimiter_Minmod *)lim->data; 548c0ce001eSMatthew G. Knepley 549c0ce001eSMatthew G. Knepley PetscFunctionBegin; 5509566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 551c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 552c0ce001eSMatthew G. Knepley } 553c0ce001eSMatthew G. Knepley 554*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Minmod_Ascii(PetscLimiter lim, PetscViewer viewer) 555*d71ae5a4SJacob Faibussowitsch { 556c0ce001eSMatthew G. Knepley PetscViewerFormat format; 557c0ce001eSMatthew G. Knepley 558c0ce001eSMatthew G. Knepley PetscFunctionBegin; 5599566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 5609566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Minmod Slope Limiter:\n")); 561c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 562c0ce001eSMatthew G. Knepley } 563c0ce001eSMatthew G. Knepley 564*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Minmod(PetscLimiter lim, PetscViewer viewer) 565*d71ae5a4SJacob Faibussowitsch { 566c0ce001eSMatthew G. Knepley PetscBool iascii; 567c0ce001eSMatthew G. Knepley 568c0ce001eSMatthew G. Knepley PetscFunctionBegin; 569c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 570c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 5719566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 5729566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_Minmod_Ascii(lim, viewer)); 573c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 574c0ce001eSMatthew G. Knepley } 575c0ce001eSMatthew G. Knepley 576*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_Minmod(PetscLimiter lim, PetscReal f, PetscReal *phi) 577*d71ae5a4SJacob Faibussowitsch { 578c0ce001eSMatthew G. Knepley PetscFunctionBegin; 579c0ce001eSMatthew G. Knepley *phi = 2 * PetscMax(0, PetscMin(f, 1 - f)); 580c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 581c0ce001eSMatthew G. Knepley } 582c0ce001eSMatthew G. Knepley 583*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_Minmod(PetscLimiter lim) 584*d71ae5a4SJacob Faibussowitsch { 585c0ce001eSMatthew G. Knepley PetscFunctionBegin; 586c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Minmod; 587c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Minmod; 588c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Minmod; 589c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 590c0ce001eSMatthew G. Knepley } 591c0ce001eSMatthew G. Knepley 592c0ce001eSMatthew G. Knepley /*MC 593c0ce001eSMatthew G. Knepley PETSCLIMITERMINMOD = "minmod" - A PetscLimiter object 594c0ce001eSMatthew G. Knepley 595c0ce001eSMatthew G. Knepley Level: intermediate 596c0ce001eSMatthew G. Knepley 597db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 598c0ce001eSMatthew G. Knepley M*/ 599c0ce001eSMatthew G. Knepley 600*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Minmod(PetscLimiter lim) 601*d71ae5a4SJacob Faibussowitsch { 602c0ce001eSMatthew G. Knepley PetscLimiter_Minmod *l; 603c0ce001eSMatthew G. Knepley 604c0ce001eSMatthew G. Knepley PetscFunctionBegin; 605c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 6064dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 607c0ce001eSMatthew G. Knepley lim->data = l; 608c0ce001eSMatthew G. Knepley 6099566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_Minmod(lim)); 610c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 611c0ce001eSMatthew G. Knepley } 612c0ce001eSMatthew G. Knepley 613*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_VanLeer(PetscLimiter lim) 614*d71ae5a4SJacob Faibussowitsch { 615c0ce001eSMatthew G. Knepley PetscLimiter_VanLeer *l = (PetscLimiter_VanLeer *)lim->data; 616c0ce001eSMatthew G. Knepley 617c0ce001eSMatthew G. Knepley PetscFunctionBegin; 6189566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 619c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 620c0ce001eSMatthew G. Knepley } 621c0ce001eSMatthew G. Knepley 622*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_VanLeer_Ascii(PetscLimiter lim, PetscViewer viewer) 623*d71ae5a4SJacob Faibussowitsch { 624c0ce001eSMatthew G. Knepley PetscViewerFormat format; 625c0ce001eSMatthew G. Knepley 626c0ce001eSMatthew G. Knepley PetscFunctionBegin; 6279566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 6289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Van Leer Slope Limiter:\n")); 629c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 630c0ce001eSMatthew G. Knepley } 631c0ce001eSMatthew G. Knepley 632*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_VanLeer(PetscLimiter lim, PetscViewer viewer) 633*d71ae5a4SJacob Faibussowitsch { 634c0ce001eSMatthew G. Knepley PetscBool iascii; 635c0ce001eSMatthew G. Knepley 636c0ce001eSMatthew G. Knepley PetscFunctionBegin; 637c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 638c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 6399566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 6409566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_VanLeer_Ascii(lim, viewer)); 641c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 642c0ce001eSMatthew G. Knepley } 643c0ce001eSMatthew G. Knepley 644*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_VanLeer(PetscLimiter lim, PetscReal f, PetscReal *phi) 645*d71ae5a4SJacob Faibussowitsch { 646c0ce001eSMatthew G. Knepley PetscFunctionBegin; 647c0ce001eSMatthew G. Knepley *phi = PetscMax(0, 4 * f * (1 - f)); 648c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 649c0ce001eSMatthew G. Knepley } 650c0ce001eSMatthew G. Knepley 651*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_VanLeer(PetscLimiter lim) 652*d71ae5a4SJacob Faibussowitsch { 653c0ce001eSMatthew G. Knepley PetscFunctionBegin; 654c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_VanLeer; 655c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_VanLeer; 656c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_VanLeer; 657c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 658c0ce001eSMatthew G. Knepley } 659c0ce001eSMatthew G. Knepley 660c0ce001eSMatthew G. Knepley /*MC 661c0ce001eSMatthew G. Knepley PETSCLIMITERVANLEER = "vanleer" - A PetscLimiter object 662c0ce001eSMatthew G. Knepley 663c0ce001eSMatthew G. Knepley Level: intermediate 664c0ce001eSMatthew G. Knepley 665db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 666c0ce001eSMatthew G. Knepley M*/ 667c0ce001eSMatthew G. Knepley 668*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanLeer(PetscLimiter lim) 669*d71ae5a4SJacob Faibussowitsch { 670c0ce001eSMatthew G. Knepley PetscLimiter_VanLeer *l; 671c0ce001eSMatthew G. Knepley 672c0ce001eSMatthew G. Knepley PetscFunctionBegin; 673c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 6744dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 675c0ce001eSMatthew G. Knepley lim->data = l; 676c0ce001eSMatthew G. Knepley 6779566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_VanLeer(lim)); 678c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 679c0ce001eSMatthew G. Knepley } 680c0ce001eSMatthew G. Knepley 681*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_VanAlbada(PetscLimiter lim) 682*d71ae5a4SJacob Faibussowitsch { 683c0ce001eSMatthew G. Knepley PetscLimiter_VanAlbada *l = (PetscLimiter_VanAlbada *)lim->data; 684c0ce001eSMatthew G. Knepley 685c0ce001eSMatthew G. Knepley PetscFunctionBegin; 6869566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 687c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 688c0ce001eSMatthew G. Knepley } 689c0ce001eSMatthew G. Knepley 690*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_VanAlbada_Ascii(PetscLimiter lim, PetscViewer viewer) 691*d71ae5a4SJacob Faibussowitsch { 692c0ce001eSMatthew G. Knepley PetscViewerFormat format; 693c0ce001eSMatthew G. Knepley 694c0ce001eSMatthew G. Knepley PetscFunctionBegin; 6959566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 6969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Van Albada Slope Limiter:\n")); 697c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 698c0ce001eSMatthew G. Knepley } 699c0ce001eSMatthew G. Knepley 700*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_VanAlbada(PetscLimiter lim, PetscViewer viewer) 701*d71ae5a4SJacob Faibussowitsch { 702c0ce001eSMatthew G. Knepley PetscBool iascii; 703c0ce001eSMatthew G. Knepley 704c0ce001eSMatthew G. Knepley PetscFunctionBegin; 705c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 706c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 7079566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 7089566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_VanAlbada_Ascii(lim, viewer)); 709c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 710c0ce001eSMatthew G. Knepley } 711c0ce001eSMatthew G. Knepley 712*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_VanAlbada(PetscLimiter lim, PetscReal f, PetscReal *phi) 713*d71ae5a4SJacob Faibussowitsch { 714c0ce001eSMatthew G. Knepley PetscFunctionBegin; 715c0ce001eSMatthew G. Knepley *phi = PetscMax(0, 2 * f * (1 - f) / (PetscSqr(f) + PetscSqr(1 - f))); 716c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 717c0ce001eSMatthew G. Knepley } 718c0ce001eSMatthew G. Knepley 719*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_VanAlbada(PetscLimiter lim) 720*d71ae5a4SJacob Faibussowitsch { 721c0ce001eSMatthew G. Knepley PetscFunctionBegin; 722c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_VanAlbada; 723c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_VanAlbada; 724c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_VanAlbada; 725c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 726c0ce001eSMatthew G. Knepley } 727c0ce001eSMatthew G. Knepley 728c0ce001eSMatthew G. Knepley /*MC 729c0ce001eSMatthew G. Knepley PETSCLIMITERVANALBADA = "vanalbada" - A PetscLimiter object 730c0ce001eSMatthew G. Knepley 731c0ce001eSMatthew G. Knepley Level: intermediate 732c0ce001eSMatthew G. Knepley 733db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 734c0ce001eSMatthew G. Knepley M*/ 735c0ce001eSMatthew G. Knepley 736*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanAlbada(PetscLimiter lim) 737*d71ae5a4SJacob Faibussowitsch { 738c0ce001eSMatthew G. Knepley PetscLimiter_VanAlbada *l; 739c0ce001eSMatthew G. Knepley 740c0ce001eSMatthew G. Knepley PetscFunctionBegin; 741c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 7424dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 743c0ce001eSMatthew G. Knepley lim->data = l; 744c0ce001eSMatthew G. Knepley 7459566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_VanAlbada(lim)); 746c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 747c0ce001eSMatthew G. Knepley } 748c0ce001eSMatthew G. Knepley 749*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_Superbee(PetscLimiter lim) 750*d71ae5a4SJacob Faibussowitsch { 751c0ce001eSMatthew G. Knepley PetscLimiter_Superbee *l = (PetscLimiter_Superbee *)lim->data; 752c0ce001eSMatthew G. Knepley 753c0ce001eSMatthew G. Knepley PetscFunctionBegin; 7549566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 755c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 756c0ce001eSMatthew G. Knepley } 757c0ce001eSMatthew G. Knepley 758*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Superbee_Ascii(PetscLimiter lim, PetscViewer viewer) 759*d71ae5a4SJacob Faibussowitsch { 760c0ce001eSMatthew G. Knepley PetscViewerFormat format; 761c0ce001eSMatthew G. Knepley 762c0ce001eSMatthew G. Knepley PetscFunctionBegin; 7639566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 7649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Superbee Slope Limiter:\n")); 765c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 766c0ce001eSMatthew G. Knepley } 767c0ce001eSMatthew G. Knepley 768*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Superbee(PetscLimiter lim, PetscViewer viewer) 769*d71ae5a4SJacob Faibussowitsch { 770c0ce001eSMatthew G. Knepley PetscBool iascii; 771c0ce001eSMatthew G. Knepley 772c0ce001eSMatthew G. Knepley PetscFunctionBegin; 773c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 774c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 7759566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 7769566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_Superbee_Ascii(lim, viewer)); 777c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 778c0ce001eSMatthew G. Knepley } 779c0ce001eSMatthew G. Knepley 780*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_Superbee(PetscLimiter lim, PetscReal f, PetscReal *phi) 781*d71ae5a4SJacob Faibussowitsch { 782c0ce001eSMatthew G. Knepley PetscFunctionBegin; 783c0ce001eSMatthew G. Knepley *phi = 4 * PetscMax(0, PetscMin(f, 1 - f)); 784c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 785c0ce001eSMatthew G. Knepley } 786c0ce001eSMatthew G. Knepley 787*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_Superbee(PetscLimiter lim) 788*d71ae5a4SJacob Faibussowitsch { 789c0ce001eSMatthew G. Knepley PetscFunctionBegin; 790c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Superbee; 791c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Superbee; 792c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Superbee; 793c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 794c0ce001eSMatthew G. Knepley } 795c0ce001eSMatthew G. Knepley 796c0ce001eSMatthew G. Knepley /*MC 797c0ce001eSMatthew G. Knepley PETSCLIMITERSUPERBEE = "superbee" - A PetscLimiter object 798c0ce001eSMatthew G. Knepley 799c0ce001eSMatthew G. Knepley Level: intermediate 800c0ce001eSMatthew G. Knepley 801db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 802c0ce001eSMatthew G. Knepley M*/ 803c0ce001eSMatthew G. Knepley 804*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Superbee(PetscLimiter lim) 805*d71ae5a4SJacob Faibussowitsch { 806c0ce001eSMatthew G. Knepley PetscLimiter_Superbee *l; 807c0ce001eSMatthew G. Knepley 808c0ce001eSMatthew G. Knepley PetscFunctionBegin; 809c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 8104dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 811c0ce001eSMatthew G. Knepley lim->data = l; 812c0ce001eSMatthew G. Knepley 8139566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_Superbee(lim)); 814c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 815c0ce001eSMatthew G. Knepley } 816c0ce001eSMatthew G. Knepley 817*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_MC(PetscLimiter lim) 818*d71ae5a4SJacob Faibussowitsch { 819c0ce001eSMatthew G. Knepley PetscLimiter_MC *l = (PetscLimiter_MC *)lim->data; 820c0ce001eSMatthew G. Knepley 821c0ce001eSMatthew G. Knepley PetscFunctionBegin; 8229566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 823c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 824c0ce001eSMatthew G. Knepley } 825c0ce001eSMatthew G. Knepley 826*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_MC_Ascii(PetscLimiter lim, PetscViewer viewer) 827*d71ae5a4SJacob Faibussowitsch { 828c0ce001eSMatthew G. Knepley PetscViewerFormat format; 829c0ce001eSMatthew G. Knepley 830c0ce001eSMatthew G. Knepley PetscFunctionBegin; 8319566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 8329566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "MC Slope Limiter:\n")); 833c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 834c0ce001eSMatthew G. Knepley } 835c0ce001eSMatthew G. Knepley 836*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_MC(PetscLimiter lim, PetscViewer viewer) 837*d71ae5a4SJacob Faibussowitsch { 838c0ce001eSMatthew G. Knepley PetscBool iascii; 839c0ce001eSMatthew G. Knepley 840c0ce001eSMatthew G. Knepley PetscFunctionBegin; 841c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 842c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 8439566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 8449566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_MC_Ascii(lim, viewer)); 845c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 846c0ce001eSMatthew G. Knepley } 847c0ce001eSMatthew G. Knepley 848c0ce001eSMatthew G. Knepley /* aka Barth-Jespersen */ 849*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_MC(PetscLimiter lim, PetscReal f, PetscReal *phi) 850*d71ae5a4SJacob Faibussowitsch { 851c0ce001eSMatthew G. Knepley PetscFunctionBegin; 852c0ce001eSMatthew G. Knepley *phi = PetscMin(1, 4 * PetscMax(0, PetscMin(f, 1 - f))); 853c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 854c0ce001eSMatthew G. Knepley } 855c0ce001eSMatthew G. Knepley 856*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_MC(PetscLimiter lim) 857*d71ae5a4SJacob Faibussowitsch { 858c0ce001eSMatthew G. Knepley PetscFunctionBegin; 859c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_MC; 860c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_MC; 861c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_MC; 862c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 863c0ce001eSMatthew G. Knepley } 864c0ce001eSMatthew G. Knepley 865c0ce001eSMatthew G. Knepley /*MC 866c0ce001eSMatthew G. Knepley PETSCLIMITERMC = "mc" - A PetscLimiter object 867c0ce001eSMatthew G. Knepley 868c0ce001eSMatthew G. Knepley Level: intermediate 869c0ce001eSMatthew G. Knepley 870db781477SPatrick Sanan .seealso: `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 871c0ce001eSMatthew G. Knepley M*/ 872c0ce001eSMatthew G. Knepley 873*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_MC(PetscLimiter lim) 874*d71ae5a4SJacob Faibussowitsch { 875c0ce001eSMatthew G. Knepley PetscLimiter_MC *l; 876c0ce001eSMatthew G. Knepley 877c0ce001eSMatthew G. Knepley PetscFunctionBegin; 878c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 8794dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 880c0ce001eSMatthew G. Knepley lim->data = l; 881c0ce001eSMatthew G. Knepley 8829566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_MC(lim)); 883c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 884c0ce001eSMatthew G. Knepley } 885c0ce001eSMatthew G. Knepley 886c0ce001eSMatthew G. Knepley PetscClassId PETSCFV_CLASSID = 0; 887c0ce001eSMatthew G. Knepley 888c0ce001eSMatthew G. Knepley PetscFunctionList PetscFVList = NULL; 889c0ce001eSMatthew G. Knepley PetscBool PetscFVRegisterAllCalled = PETSC_FALSE; 890c0ce001eSMatthew G. Knepley 891c0ce001eSMatthew G. Knepley /*@C 892c0ce001eSMatthew G. Knepley PetscFVRegister - Adds a new PetscFV implementation 893c0ce001eSMatthew G. Knepley 894c0ce001eSMatthew G. Knepley Not Collective 895c0ce001eSMatthew G. Knepley 896c0ce001eSMatthew G. Knepley Input Parameters: 897c0ce001eSMatthew G. Knepley + name - The name of a new user-defined creation routine 898c0ce001eSMatthew G. Knepley - create_func - The creation routine itself 899c0ce001eSMatthew G. Knepley 900c0ce001eSMatthew G. Knepley Notes: 901c0ce001eSMatthew G. Knepley PetscFVRegister() may be called multiple times to add several user-defined PetscFVs 902c0ce001eSMatthew G. Knepley 903c0ce001eSMatthew G. Knepley Sample usage: 904c0ce001eSMatthew G. Knepley .vb 905c0ce001eSMatthew G. Knepley PetscFVRegister("my_fv", MyPetscFVCreate); 906c0ce001eSMatthew G. Knepley .ve 907c0ce001eSMatthew G. Knepley 908c0ce001eSMatthew G. Knepley Then, your PetscFV type can be chosen with the procedural interface via 909c0ce001eSMatthew G. Knepley .vb 910c0ce001eSMatthew G. Knepley PetscFVCreate(MPI_Comm, PetscFV *); 911c0ce001eSMatthew G. Knepley PetscFVSetType(PetscFV, "my_fv"); 912c0ce001eSMatthew G. Knepley .ve 913c0ce001eSMatthew G. Knepley or at runtime via the option 914c0ce001eSMatthew G. Knepley .vb 915c0ce001eSMatthew G. Knepley -petscfv_type my_fv 916c0ce001eSMatthew G. Knepley .ve 917c0ce001eSMatthew G. Knepley 918c0ce001eSMatthew G. Knepley Level: advanced 919c0ce001eSMatthew G. Knepley 920db781477SPatrick Sanan .seealso: `PetscFVRegisterAll()`, `PetscFVRegisterDestroy()` 921c0ce001eSMatthew G. Knepley 922c0ce001eSMatthew G. Knepley @*/ 923*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVRegister(const char sname[], PetscErrorCode (*function)(PetscFV)) 924*d71ae5a4SJacob Faibussowitsch { 925c0ce001eSMatthew G. Knepley PetscFunctionBegin; 9269566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&PetscFVList, sname, function)); 927c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 928c0ce001eSMatthew G. Knepley } 929c0ce001eSMatthew G. Knepley 930c0ce001eSMatthew G. Knepley /*@C 931c0ce001eSMatthew G. Knepley PetscFVSetType - Builds a particular PetscFV 932c0ce001eSMatthew G. Knepley 933c0ce001eSMatthew G. Knepley Collective on fvm 934c0ce001eSMatthew G. Knepley 935c0ce001eSMatthew G. Knepley Input Parameters: 936c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 937c0ce001eSMatthew G. Knepley - name - The kind of FVM space 938c0ce001eSMatthew G. Knepley 939c0ce001eSMatthew G. Knepley Options Database Key: 940c0ce001eSMatthew G. Knepley . -petscfv_type <type> - Sets the PetscFV type; use -help for a list of available types 941c0ce001eSMatthew G. Knepley 942c0ce001eSMatthew G. Knepley Level: intermediate 943c0ce001eSMatthew G. Knepley 944db781477SPatrick Sanan .seealso: `PetscFVGetType()`, `PetscFVCreate()` 945c0ce001eSMatthew G. Knepley @*/ 946*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetType(PetscFV fvm, PetscFVType name) 947*d71ae5a4SJacob Faibussowitsch { 948c0ce001eSMatthew G. Knepley PetscErrorCode (*r)(PetscFV); 949c0ce001eSMatthew G. Knepley PetscBool match; 950c0ce001eSMatthew G. Knepley 951c0ce001eSMatthew G. Knepley PetscFunctionBegin; 952c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 9539566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)fvm, name, &match)); 954c0ce001eSMatthew G. Knepley if (match) PetscFunctionReturn(0); 955c0ce001eSMatthew G. Knepley 9569566063dSJacob Faibussowitsch PetscCall(PetscFVRegisterAll()); 9579566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(PetscFVList, name, &r)); 95828b400f6SJacob Faibussowitsch PetscCheck(r, PetscObjectComm((PetscObject)fvm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscFV type: %s", name); 959c0ce001eSMatthew G. Knepley 960dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, destroy); 961c0ce001eSMatthew G. Knepley fvm->ops->destroy = NULL; 962dbbe0bcdSBarry Smith 9639566063dSJacob Faibussowitsch PetscCall((*r)(fvm)); 9649566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)fvm, name)); 965c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 966c0ce001eSMatthew G. Knepley } 967c0ce001eSMatthew G. Knepley 968c0ce001eSMatthew G. Knepley /*@C 969c0ce001eSMatthew G. Knepley PetscFVGetType - Gets the PetscFV type name (as a string) from the object. 970c0ce001eSMatthew G. Knepley 971c0ce001eSMatthew G. Knepley Not Collective 972c0ce001eSMatthew G. Knepley 973c0ce001eSMatthew G. Knepley Input Parameter: 974c0ce001eSMatthew G. Knepley . fvm - The PetscFV 975c0ce001eSMatthew G. Knepley 976c0ce001eSMatthew G. Knepley Output Parameter: 977c0ce001eSMatthew G. Knepley . name - The PetscFV type name 978c0ce001eSMatthew G. Knepley 979c0ce001eSMatthew G. Knepley Level: intermediate 980c0ce001eSMatthew G. Knepley 981db781477SPatrick Sanan .seealso: `PetscFVSetType()`, `PetscFVCreate()` 982c0ce001eSMatthew G. Knepley @*/ 983*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetType(PetscFV fvm, PetscFVType *name) 984*d71ae5a4SJacob Faibussowitsch { 985c0ce001eSMatthew G. Knepley PetscFunctionBegin; 986c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 987c0ce001eSMatthew G. Knepley PetscValidPointer(name, 2); 9889566063dSJacob Faibussowitsch PetscCall(PetscFVRegisterAll()); 989c0ce001eSMatthew G. Knepley *name = ((PetscObject)fvm)->type_name; 990c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 991c0ce001eSMatthew G. Knepley } 992c0ce001eSMatthew G. Knepley 993c0ce001eSMatthew G. Knepley /*@C 994fe2efc57SMark PetscFVViewFromOptions - View from Options 995fe2efc57SMark 996fe2efc57SMark Collective on PetscFV 997fe2efc57SMark 998fe2efc57SMark Input Parameters: 999fe2efc57SMark + A - the PetscFV object 1000736c3998SJose E. Roman . obj - Optional object 1001736c3998SJose E. Roman - name - command line option 1002fe2efc57SMark 1003fe2efc57SMark Level: intermediate 1004db781477SPatrick Sanan .seealso: `PetscFV`, `PetscFVView`, `PetscObjectViewFromOptions()`, `PetscFVCreate()` 1005fe2efc57SMark @*/ 1006*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVViewFromOptions(PetscFV A, PetscObject obj, const char name[]) 1007*d71ae5a4SJacob Faibussowitsch { 1008fe2efc57SMark PetscFunctionBegin; 1009fe2efc57SMark PetscValidHeaderSpecific(A, PETSCFV_CLASSID, 1); 10109566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 1011fe2efc57SMark PetscFunctionReturn(0); 1012fe2efc57SMark } 1013fe2efc57SMark 1014fe2efc57SMark /*@C 1015c0ce001eSMatthew G. Knepley PetscFVView - Views a PetscFV 1016c0ce001eSMatthew G. Knepley 1017c0ce001eSMatthew G. Knepley Collective on fvm 1018c0ce001eSMatthew G. Knepley 1019d8d19677SJose E. Roman Input Parameters: 1020c0ce001eSMatthew G. Knepley + fvm - the PetscFV object to view 1021c0ce001eSMatthew G. Knepley - v - the viewer 1022c0ce001eSMatthew G. Knepley 102388f5f89eSMatthew G. Knepley Level: beginner 1024c0ce001eSMatthew G. Knepley 1025db781477SPatrick Sanan .seealso: `PetscFVDestroy()` 1026c0ce001eSMatthew G. Knepley @*/ 1027*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVView(PetscFV fvm, PetscViewer v) 1028*d71ae5a4SJacob Faibussowitsch { 1029c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1030c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 10319566063dSJacob Faibussowitsch if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)fvm), &v)); 1032dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, view, v); 1033c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1034c0ce001eSMatthew G. Knepley } 1035c0ce001eSMatthew G. Knepley 1036c0ce001eSMatthew G. Knepley /*@ 1037c0ce001eSMatthew G. Knepley PetscFVSetFromOptions - sets parameters in a PetscFV from the options database 1038c0ce001eSMatthew G. Knepley 1039c0ce001eSMatthew G. Knepley Collective on fvm 1040c0ce001eSMatthew G. Knepley 1041c0ce001eSMatthew G. Knepley Input Parameter: 1042c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to set options for 1043c0ce001eSMatthew G. Knepley 1044c0ce001eSMatthew G. Knepley Options Database Key: 1045c0ce001eSMatthew G. Knepley . -petscfv_compute_gradients <bool> - Determines whether cell gradients are calculated 1046c0ce001eSMatthew G. Knepley 104788f5f89eSMatthew G. Knepley Level: intermediate 1048c0ce001eSMatthew G. Knepley 1049db781477SPatrick Sanan .seealso: `PetscFVView()` 1050c0ce001eSMatthew G. Knepley @*/ 1051*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetFromOptions(PetscFV fvm) 1052*d71ae5a4SJacob Faibussowitsch { 1053c0ce001eSMatthew G. Knepley const char *defaultType; 1054c0ce001eSMatthew G. Knepley char name[256]; 1055c0ce001eSMatthew G. Knepley PetscBool flg; 1056c0ce001eSMatthew G. Knepley 1057c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1058c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1059c0ce001eSMatthew G. Knepley if (!((PetscObject)fvm)->type_name) defaultType = PETSCFVUPWIND; 1060c0ce001eSMatthew G. Knepley else defaultType = ((PetscObject)fvm)->type_name; 10619566063dSJacob Faibussowitsch PetscCall(PetscFVRegisterAll()); 1062c0ce001eSMatthew G. Knepley 1063d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)fvm); 10649566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-petscfv_type", "Finite volume discretization", "PetscFVSetType", PetscFVList, defaultType, name, 256, &flg)); 1065c0ce001eSMatthew G. Knepley if (flg) { 10669566063dSJacob Faibussowitsch PetscCall(PetscFVSetType(fvm, name)); 1067c0ce001eSMatthew G. Knepley } else if (!((PetscObject)fvm)->type_name) { 10689566063dSJacob Faibussowitsch PetscCall(PetscFVSetType(fvm, defaultType)); 1069c0ce001eSMatthew G. Knepley } 10709566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-petscfv_compute_gradients", "Compute cell gradients", "PetscFVSetComputeGradients", fvm->computeGradients, &fvm->computeGradients, NULL)); 1071dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, setfromoptions); 1072c0ce001eSMatthew G. Knepley /* process any options handlers added with PetscObjectAddOptionsHandler() */ 1073dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)fvm, PetscOptionsObject)); 10749566063dSJacob Faibussowitsch PetscCall(PetscLimiterSetFromOptions(fvm->limiter)); 1075d0609cedSBarry Smith PetscOptionsEnd(); 10769566063dSJacob Faibussowitsch PetscCall(PetscFVViewFromOptions(fvm, NULL, "-petscfv_view")); 1077c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1078c0ce001eSMatthew G. Knepley } 1079c0ce001eSMatthew G. Knepley 1080c0ce001eSMatthew G. Knepley /*@ 1081c0ce001eSMatthew G. Knepley PetscFVSetUp - Construct data structures for the PetscFV 1082c0ce001eSMatthew G. Knepley 1083c0ce001eSMatthew G. Knepley Collective on fvm 1084c0ce001eSMatthew G. Knepley 1085c0ce001eSMatthew G. Knepley Input Parameter: 1086c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to setup 1087c0ce001eSMatthew G. Knepley 108888f5f89eSMatthew G. Knepley Level: intermediate 1089c0ce001eSMatthew G. Knepley 1090db781477SPatrick Sanan .seealso: `PetscFVView()`, `PetscFVDestroy()` 1091c0ce001eSMatthew G. Knepley @*/ 1092*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetUp(PetscFV fvm) 1093*d71ae5a4SJacob Faibussowitsch { 1094c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1095c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 10969566063dSJacob Faibussowitsch PetscCall(PetscLimiterSetUp(fvm->limiter)); 1097dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, setup); 1098c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1099c0ce001eSMatthew G. Knepley } 1100c0ce001eSMatthew G. Knepley 1101c0ce001eSMatthew G. Knepley /*@ 1102c0ce001eSMatthew G. Knepley PetscFVDestroy - Destroys a PetscFV object 1103c0ce001eSMatthew G. Knepley 1104c0ce001eSMatthew G. Knepley Collective on fvm 1105c0ce001eSMatthew G. Knepley 1106c0ce001eSMatthew G. Knepley Input Parameter: 1107c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to destroy 1108c0ce001eSMatthew G. Knepley 110988f5f89eSMatthew G. Knepley Level: beginner 1110c0ce001eSMatthew G. Knepley 1111db781477SPatrick Sanan .seealso: `PetscFVView()` 1112c0ce001eSMatthew G. Knepley @*/ 1113*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVDestroy(PetscFV *fvm) 1114*d71ae5a4SJacob Faibussowitsch { 1115c0ce001eSMatthew G. Knepley PetscInt i; 1116c0ce001eSMatthew G. Knepley 1117c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1118c0ce001eSMatthew G. Knepley if (!*fvm) PetscFunctionReturn(0); 1119c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific((*fvm), PETSCFV_CLASSID, 1); 1120c0ce001eSMatthew G. Knepley 11219371c9d4SSatish Balay if (--((PetscObject)(*fvm))->refct > 0) { 11229371c9d4SSatish Balay *fvm = NULL; 11239371c9d4SSatish Balay PetscFunctionReturn(0); 11249371c9d4SSatish Balay } 1125c0ce001eSMatthew G. Knepley ((PetscObject)(*fvm))->refct = 0; 1126c0ce001eSMatthew G. Knepley 112748a46eb9SPierre Jolivet for (i = 0; i < (*fvm)->numComponents; i++) PetscCall(PetscFree((*fvm)->componentNames[i])); 11289566063dSJacob Faibussowitsch PetscCall(PetscFree((*fvm)->componentNames)); 11299566063dSJacob Faibussowitsch PetscCall(PetscLimiterDestroy(&(*fvm)->limiter)); 11309566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&(*fvm)->dualSpace)); 11319566063dSJacob Faibussowitsch PetscCall(PetscFree((*fvm)->fluxWork)); 11329566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&(*fvm)->quadrature)); 11339566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&(*fvm)->T)); 1134c0ce001eSMatthew G. Knepley 1135dbbe0bcdSBarry Smith PetscTryTypeMethod((*fvm), destroy); 11369566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(fvm)); 1137c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1138c0ce001eSMatthew G. Knepley } 1139c0ce001eSMatthew G. Knepley 1140c0ce001eSMatthew G. Knepley /*@ 1141c0ce001eSMatthew G. Knepley PetscFVCreate - Creates an empty PetscFV object. The type can then be set with PetscFVSetType(). 1142c0ce001eSMatthew G. Knepley 1143c0ce001eSMatthew G. Knepley Collective 1144c0ce001eSMatthew G. Knepley 1145c0ce001eSMatthew G. Knepley Input Parameter: 1146c0ce001eSMatthew G. Knepley . comm - The communicator for the PetscFV object 1147c0ce001eSMatthew G. Knepley 1148c0ce001eSMatthew G. Knepley Output Parameter: 1149c0ce001eSMatthew G. Knepley . fvm - The PetscFV object 1150c0ce001eSMatthew G. Knepley 1151c0ce001eSMatthew G. Knepley Level: beginner 1152c0ce001eSMatthew G. Knepley 1153db781477SPatrick Sanan .seealso: `PetscFVSetType()`, `PETSCFVUPWIND` 1154c0ce001eSMatthew G. Knepley @*/ 1155*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVCreate(MPI_Comm comm, PetscFV *fvm) 1156*d71ae5a4SJacob Faibussowitsch { 1157c0ce001eSMatthew G. Knepley PetscFV f; 1158c0ce001eSMatthew G. Knepley 1159c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1160c0ce001eSMatthew G. Knepley PetscValidPointer(fvm, 2); 1161c0ce001eSMatthew G. Knepley *fvm = NULL; 11629566063dSJacob Faibussowitsch PetscCall(PetscFVInitializePackage()); 1163c0ce001eSMatthew G. Knepley 11649566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(f, PETSCFV_CLASSID, "PetscFV", "Finite Volume", "PetscFV", comm, PetscFVDestroy, PetscFVView)); 11659566063dSJacob Faibussowitsch PetscCall(PetscMemzero(f->ops, sizeof(struct _PetscFVOps))); 1166c0ce001eSMatthew G. Knepley 11679566063dSJacob Faibussowitsch PetscCall(PetscLimiterCreate(comm, &f->limiter)); 1168c0ce001eSMatthew G. Knepley f->numComponents = 1; 1169c0ce001eSMatthew G. Knepley f->dim = 0; 1170c0ce001eSMatthew G. Knepley f->computeGradients = PETSC_FALSE; 1171c0ce001eSMatthew G. Knepley f->fluxWork = NULL; 11729566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(f->numComponents, &f->componentNames)); 1173c0ce001eSMatthew G. Knepley 1174c0ce001eSMatthew G. Knepley *fvm = f; 1175c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1176c0ce001eSMatthew G. Knepley } 1177c0ce001eSMatthew G. Knepley 1178c0ce001eSMatthew G. Knepley /*@ 1179c0ce001eSMatthew G. Knepley PetscFVSetLimiter - Set the limiter object 1180c0ce001eSMatthew G. Knepley 1181c0ce001eSMatthew G. Knepley Logically collective on fvm 1182c0ce001eSMatthew G. Knepley 1183c0ce001eSMatthew G. Knepley Input Parameters: 1184c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1185c0ce001eSMatthew G. Knepley - lim - The PetscLimiter 1186c0ce001eSMatthew G. Knepley 118788f5f89eSMatthew G. Knepley Level: intermediate 1188c0ce001eSMatthew G. Knepley 1189db781477SPatrick Sanan .seealso: `PetscFVGetLimiter()` 1190c0ce001eSMatthew G. Knepley @*/ 1191*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetLimiter(PetscFV fvm, PetscLimiter lim) 1192*d71ae5a4SJacob Faibussowitsch { 1193c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1194c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1195c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 2); 11969566063dSJacob Faibussowitsch PetscCall(PetscLimiterDestroy(&fvm->limiter)); 11979566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)lim)); 1198c0ce001eSMatthew G. Knepley fvm->limiter = lim; 1199c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1200c0ce001eSMatthew G. Knepley } 1201c0ce001eSMatthew G. Knepley 1202c0ce001eSMatthew G. Knepley /*@ 1203c0ce001eSMatthew G. Knepley PetscFVGetLimiter - Get the limiter object 1204c0ce001eSMatthew G. Knepley 1205c0ce001eSMatthew G. Knepley Not collective 1206c0ce001eSMatthew G. Knepley 1207c0ce001eSMatthew G. Knepley Input Parameter: 1208c0ce001eSMatthew G. Knepley . fvm - the PetscFV object 1209c0ce001eSMatthew G. Knepley 1210c0ce001eSMatthew G. Knepley Output Parameter: 1211c0ce001eSMatthew G. Knepley . lim - The PetscLimiter 1212c0ce001eSMatthew G. Knepley 121388f5f89eSMatthew G. Knepley Level: intermediate 1214c0ce001eSMatthew G. Knepley 1215db781477SPatrick Sanan .seealso: `PetscFVSetLimiter()` 1216c0ce001eSMatthew G. Knepley @*/ 1217*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetLimiter(PetscFV fvm, PetscLimiter *lim) 1218*d71ae5a4SJacob Faibussowitsch { 1219c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1220c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1221c0ce001eSMatthew G. Knepley PetscValidPointer(lim, 2); 1222c0ce001eSMatthew G. Knepley *lim = fvm->limiter; 1223c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1224c0ce001eSMatthew G. Knepley } 1225c0ce001eSMatthew G. Knepley 1226c0ce001eSMatthew G. Knepley /*@ 1227c0ce001eSMatthew G. Knepley PetscFVSetNumComponents - Set the number of field components 1228c0ce001eSMatthew G. Knepley 1229c0ce001eSMatthew G. Knepley Logically collective on fvm 1230c0ce001eSMatthew G. Knepley 1231c0ce001eSMatthew G. Knepley Input Parameters: 1232c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1233c0ce001eSMatthew G. Knepley - comp - The number of components 1234c0ce001eSMatthew G. Knepley 123588f5f89eSMatthew G. Knepley Level: intermediate 1236c0ce001eSMatthew G. Knepley 1237db781477SPatrick Sanan .seealso: `PetscFVGetNumComponents()` 1238c0ce001eSMatthew G. Knepley @*/ 1239*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetNumComponents(PetscFV fvm, PetscInt comp) 1240*d71ae5a4SJacob Faibussowitsch { 1241c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1242c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1243c0ce001eSMatthew G. Knepley if (fvm->numComponents != comp) { 1244c0ce001eSMatthew G. Knepley PetscInt i; 1245c0ce001eSMatthew G. Knepley 124648a46eb9SPierre Jolivet for (i = 0; i < fvm->numComponents; i++) PetscCall(PetscFree(fvm->componentNames[i])); 12479566063dSJacob Faibussowitsch PetscCall(PetscFree(fvm->componentNames)); 12489566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(comp, &fvm->componentNames)); 1249c0ce001eSMatthew G. Knepley } 1250c0ce001eSMatthew G. Knepley fvm->numComponents = comp; 12519566063dSJacob Faibussowitsch PetscCall(PetscFree(fvm->fluxWork)); 12529566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(comp, &fvm->fluxWork)); 1253c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1254c0ce001eSMatthew G. Knepley } 1255c0ce001eSMatthew G. Knepley 1256c0ce001eSMatthew G. Knepley /*@ 1257c0ce001eSMatthew G. Knepley PetscFVGetNumComponents - Get the number of field components 1258c0ce001eSMatthew G. Knepley 1259c0ce001eSMatthew G. Knepley Not collective 1260c0ce001eSMatthew G. Knepley 1261c0ce001eSMatthew G. Knepley Input Parameter: 1262c0ce001eSMatthew G. Knepley . fvm - the PetscFV object 1263c0ce001eSMatthew G. Knepley 1264c0ce001eSMatthew G. Knepley Output Parameter: 1265c0ce001eSMatthew G. Knepley , comp - The number of components 1266c0ce001eSMatthew G. Knepley 126788f5f89eSMatthew G. Knepley Level: intermediate 1268c0ce001eSMatthew G. Knepley 1269db781477SPatrick Sanan .seealso: `PetscFVSetNumComponents()` 1270c0ce001eSMatthew G. Knepley @*/ 1271*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetNumComponents(PetscFV fvm, PetscInt *comp) 1272*d71ae5a4SJacob Faibussowitsch { 1273c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1274c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1275dadcf809SJacob Faibussowitsch PetscValidIntPointer(comp, 2); 1276c0ce001eSMatthew G. Knepley *comp = fvm->numComponents; 1277c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1278c0ce001eSMatthew G. Knepley } 1279c0ce001eSMatthew G. Knepley 1280c0ce001eSMatthew G. Knepley /*@C 1281c0ce001eSMatthew G. Knepley PetscFVSetComponentName - Set the name of a component (used in output and viewing) 1282c0ce001eSMatthew G. Knepley 1283c0ce001eSMatthew G. Knepley Logically collective on fvm 1284c0ce001eSMatthew G. Knepley Input Parameters: 1285c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1286c0ce001eSMatthew G. Knepley . comp - the component number 1287c0ce001eSMatthew G. Knepley - name - the component name 1288c0ce001eSMatthew G. Knepley 128988f5f89eSMatthew G. Knepley Level: intermediate 1290c0ce001eSMatthew G. Knepley 1291db781477SPatrick Sanan .seealso: `PetscFVGetComponentName()` 1292c0ce001eSMatthew G. Knepley @*/ 1293*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetComponentName(PetscFV fvm, PetscInt comp, const char *name) 1294*d71ae5a4SJacob Faibussowitsch { 1295c0ce001eSMatthew G. Knepley PetscFunctionBegin; 12969566063dSJacob Faibussowitsch PetscCall(PetscFree(fvm->componentNames[comp])); 12979566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &fvm->componentNames[comp])); 1298c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1299c0ce001eSMatthew G. Knepley } 1300c0ce001eSMatthew G. Knepley 1301c0ce001eSMatthew G. Knepley /*@C 1302c0ce001eSMatthew G. Knepley PetscFVGetComponentName - Get the name of a component (used in output and viewing) 1303c0ce001eSMatthew G. Knepley 1304c0ce001eSMatthew G. Knepley Logically collective on fvm 1305c0ce001eSMatthew G. Knepley Input Parameters: 1306c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1307c0ce001eSMatthew G. Knepley - comp - the component number 1308c0ce001eSMatthew G. Knepley 1309c0ce001eSMatthew G. Knepley Output Parameter: 1310c0ce001eSMatthew G. Knepley . name - the component name 1311c0ce001eSMatthew G. Knepley 131288f5f89eSMatthew G. Knepley Level: intermediate 1313c0ce001eSMatthew G. Knepley 1314db781477SPatrick Sanan .seealso: `PetscFVSetComponentName()` 1315c0ce001eSMatthew G. Knepley @*/ 1316*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetComponentName(PetscFV fvm, PetscInt comp, const char **name) 1317*d71ae5a4SJacob Faibussowitsch { 1318c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1319c0ce001eSMatthew G. Knepley *name = fvm->componentNames[comp]; 1320c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1321c0ce001eSMatthew G. Knepley } 1322c0ce001eSMatthew G. Knepley 1323c0ce001eSMatthew G. Knepley /*@ 1324c0ce001eSMatthew G. Knepley PetscFVSetSpatialDimension - Set the spatial dimension 1325c0ce001eSMatthew G. Knepley 1326c0ce001eSMatthew G. Knepley Logically collective on fvm 1327c0ce001eSMatthew G. Knepley 1328c0ce001eSMatthew G. Knepley Input Parameters: 1329c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1330c0ce001eSMatthew G. Knepley - dim - The spatial dimension 1331c0ce001eSMatthew G. Knepley 133288f5f89eSMatthew G. Knepley Level: intermediate 1333c0ce001eSMatthew G. Knepley 1334db781477SPatrick Sanan .seealso: `PetscFVGetSpatialDimension()` 1335c0ce001eSMatthew G. Knepley @*/ 1336*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetSpatialDimension(PetscFV fvm, PetscInt dim) 1337*d71ae5a4SJacob Faibussowitsch { 1338c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1339c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1340c0ce001eSMatthew G. Knepley fvm->dim = dim; 1341c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1342c0ce001eSMatthew G. Knepley } 1343c0ce001eSMatthew G. Knepley 1344c0ce001eSMatthew G. Knepley /*@ 1345c0ce001eSMatthew G. Knepley PetscFVGetSpatialDimension - Get the spatial dimension 1346c0ce001eSMatthew G. Knepley 1347c0ce001eSMatthew G. Knepley Logically collective on fvm 1348c0ce001eSMatthew G. Knepley 1349c0ce001eSMatthew G. Knepley Input Parameter: 1350c0ce001eSMatthew G. Knepley . fvm - the PetscFV object 1351c0ce001eSMatthew G. Knepley 1352c0ce001eSMatthew G. Knepley Output Parameter: 1353c0ce001eSMatthew G. Knepley . dim - The spatial dimension 1354c0ce001eSMatthew G. Knepley 135588f5f89eSMatthew G. Knepley Level: intermediate 1356c0ce001eSMatthew G. Knepley 1357db781477SPatrick Sanan .seealso: `PetscFVSetSpatialDimension()` 1358c0ce001eSMatthew G. Knepley @*/ 1359*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetSpatialDimension(PetscFV fvm, PetscInt *dim) 1360*d71ae5a4SJacob Faibussowitsch { 1361c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1362c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1363dadcf809SJacob Faibussowitsch PetscValidIntPointer(dim, 2); 1364c0ce001eSMatthew G. Knepley *dim = fvm->dim; 1365c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1366c0ce001eSMatthew G. Knepley } 1367c0ce001eSMatthew G. Knepley 1368c0ce001eSMatthew G. Knepley /*@ 1369c0ce001eSMatthew G. Knepley PetscFVSetComputeGradients - Toggle computation of cell gradients 1370c0ce001eSMatthew G. Knepley 1371c0ce001eSMatthew G. Knepley Logically collective on fvm 1372c0ce001eSMatthew G. Knepley 1373c0ce001eSMatthew G. Knepley Input Parameters: 1374c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1375c0ce001eSMatthew G. Knepley - computeGradients - Flag to compute cell gradients 1376c0ce001eSMatthew G. Knepley 137788f5f89eSMatthew G. Knepley Level: intermediate 1378c0ce001eSMatthew G. Knepley 1379db781477SPatrick Sanan .seealso: `PetscFVGetComputeGradients()` 1380c0ce001eSMatthew G. Knepley @*/ 1381*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetComputeGradients(PetscFV fvm, PetscBool computeGradients) 1382*d71ae5a4SJacob Faibussowitsch { 1383c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1384c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1385c0ce001eSMatthew G. Knepley fvm->computeGradients = computeGradients; 1386c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1387c0ce001eSMatthew G. Knepley } 1388c0ce001eSMatthew G. Knepley 1389c0ce001eSMatthew G. Knepley /*@ 1390c0ce001eSMatthew G. Knepley PetscFVGetComputeGradients - Return flag for computation of cell gradients 1391c0ce001eSMatthew G. Knepley 1392c0ce001eSMatthew G. Knepley Not collective 1393c0ce001eSMatthew G. Knepley 1394c0ce001eSMatthew G. Knepley Input Parameter: 1395c0ce001eSMatthew G. Knepley . fvm - the PetscFV object 1396c0ce001eSMatthew G. Knepley 1397c0ce001eSMatthew G. Knepley Output Parameter: 1398c0ce001eSMatthew G. Knepley . computeGradients - Flag to compute cell gradients 1399c0ce001eSMatthew G. Knepley 140088f5f89eSMatthew G. Knepley Level: intermediate 1401c0ce001eSMatthew G. Knepley 1402db781477SPatrick Sanan .seealso: `PetscFVSetComputeGradients()` 1403c0ce001eSMatthew G. Knepley @*/ 1404*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetComputeGradients(PetscFV fvm, PetscBool *computeGradients) 1405*d71ae5a4SJacob Faibussowitsch { 1406c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1407c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1408dadcf809SJacob Faibussowitsch PetscValidBoolPointer(computeGradients, 2); 1409c0ce001eSMatthew G. Knepley *computeGradients = fvm->computeGradients; 1410c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1411c0ce001eSMatthew G. Knepley } 1412c0ce001eSMatthew G. Knepley 1413c0ce001eSMatthew G. Knepley /*@ 1414c0ce001eSMatthew G. Knepley PetscFVSetQuadrature - Set the quadrature object 1415c0ce001eSMatthew G. Knepley 1416c0ce001eSMatthew G. Knepley Logically collective on fvm 1417c0ce001eSMatthew G. Knepley 1418c0ce001eSMatthew G. Knepley Input Parameters: 1419c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1420c0ce001eSMatthew G. Knepley - q - The PetscQuadrature 1421c0ce001eSMatthew G. Knepley 142288f5f89eSMatthew G. Knepley Level: intermediate 1423c0ce001eSMatthew G. Knepley 1424db781477SPatrick Sanan .seealso: `PetscFVGetQuadrature()` 1425c0ce001eSMatthew G. Knepley @*/ 1426*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetQuadrature(PetscFV fvm, PetscQuadrature q) 1427*d71ae5a4SJacob Faibussowitsch { 1428c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1429c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 14309566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&fvm->quadrature)); 14319566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)q)); 1432c0ce001eSMatthew G. Knepley fvm->quadrature = q; 1433c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1434c0ce001eSMatthew G. Knepley } 1435c0ce001eSMatthew G. Knepley 1436c0ce001eSMatthew G. Knepley /*@ 1437c0ce001eSMatthew G. Knepley PetscFVGetQuadrature - Get the quadrature object 1438c0ce001eSMatthew G. Knepley 1439c0ce001eSMatthew G. Knepley Not collective 1440c0ce001eSMatthew G. Knepley 1441c0ce001eSMatthew G. Knepley Input Parameter: 1442c0ce001eSMatthew G. Knepley . fvm - the PetscFV object 1443c0ce001eSMatthew G. Knepley 1444c0ce001eSMatthew G. Knepley Output Parameter: 1445c0ce001eSMatthew G. Knepley . lim - The PetscQuadrature 1446c0ce001eSMatthew G. Knepley 144788f5f89eSMatthew G. Knepley Level: intermediate 1448c0ce001eSMatthew G. Knepley 1449db781477SPatrick Sanan .seealso: `PetscFVSetQuadrature()` 1450c0ce001eSMatthew G. Knepley @*/ 1451*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetQuadrature(PetscFV fvm, PetscQuadrature *q) 1452*d71ae5a4SJacob Faibussowitsch { 1453c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1454c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1455c0ce001eSMatthew G. Knepley PetscValidPointer(q, 2); 1456c0ce001eSMatthew G. Knepley if (!fvm->quadrature) { 1457c0ce001eSMatthew G. Knepley /* Create default 1-point quadrature */ 1458c0ce001eSMatthew G. Knepley PetscReal *points, *weights; 1459c0ce001eSMatthew G. Knepley 14609566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &fvm->quadrature)); 14619566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(fvm->dim, &points)); 14629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, &weights)); 1463c0ce001eSMatthew G. Knepley weights[0] = 1.0; 14649566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(fvm->quadrature, fvm->dim, 1, 1, points, weights)); 1465c0ce001eSMatthew G. Knepley } 1466c0ce001eSMatthew G. Knepley *q = fvm->quadrature; 1467c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1468c0ce001eSMatthew G. Knepley } 1469c0ce001eSMatthew G. Knepley 1470c0ce001eSMatthew G. Knepley /*@ 1471c0ce001eSMatthew G. Knepley PetscFVGetDualSpace - Returns the PetscDualSpace used to define the inner product 1472c0ce001eSMatthew G. Knepley 1473c0ce001eSMatthew G. Knepley Not collective 1474c0ce001eSMatthew G. Knepley 1475c0ce001eSMatthew G. Knepley Input Parameter: 1476c0ce001eSMatthew G. Knepley . fvm - The PetscFV object 1477c0ce001eSMatthew G. Knepley 1478c0ce001eSMatthew G. Knepley Output Parameter: 1479c0ce001eSMatthew G. Knepley . sp - The PetscDualSpace object 1480c0ce001eSMatthew G. Knepley 1481c0ce001eSMatthew G. Knepley Note: A simple dual space is provided automatically, and the user typically will not need to override it. 1482c0ce001eSMatthew G. Knepley 148388f5f89eSMatthew G. Knepley Level: intermediate 1484c0ce001eSMatthew G. Knepley 1485db781477SPatrick Sanan .seealso: `PetscFVCreate()` 1486c0ce001eSMatthew G. Knepley @*/ 1487*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetDualSpace(PetscFV fvm, PetscDualSpace *sp) 1488*d71ae5a4SJacob Faibussowitsch { 1489c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1490c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1491c0ce001eSMatthew G. Knepley PetscValidPointer(sp, 2); 1492c0ce001eSMatthew G. Knepley if (!fvm->dualSpace) { 1493c0ce001eSMatthew G. Knepley DM K; 1494c0ce001eSMatthew G. Knepley PetscInt dim, Nc, c; 1495c0ce001eSMatthew G. Knepley 14969566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 14979566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &Nc)); 14989566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceCreate(PetscObjectComm((PetscObject)fvm), &fvm->dualSpace)); 14999566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetType(fvm->dualSpace, PETSCDUALSPACESIMPLE)); 15009566063dSJacob Faibussowitsch PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, DMPolytopeTypeSimpleShape(dim, PETSC_FALSE), &K)); 15019566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetNumComponents(fvm->dualSpace, Nc)); 15029566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(fvm->dualSpace, K)); 15039566063dSJacob Faibussowitsch PetscCall(DMDestroy(&K)); 15049566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetDimension(fvm->dualSpace, Nc)); 1505c0ce001eSMatthew G. Knepley /* Should we be using PetscFVGetQuadrature() here? */ 1506c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; ++c) { 1507c0ce001eSMatthew G. Knepley PetscQuadrature qc; 1508c0ce001eSMatthew G. Knepley PetscReal *points, *weights; 1509c0ce001eSMatthew G. Knepley 15109566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qc)); 15119566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(dim, &points)); 15129566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nc, &weights)); 1513c0ce001eSMatthew G. Knepley weights[c] = 1.0; 15149566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(qc, dim, Nc, 1, points, weights)); 15159566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetFunctional(fvm->dualSpace, c, qc)); 15169566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qc)); 1517c0ce001eSMatthew G. Knepley } 15189566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(fvm->dualSpace)); 1519c0ce001eSMatthew G. Knepley } 1520c0ce001eSMatthew G. Knepley *sp = fvm->dualSpace; 1521c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1522c0ce001eSMatthew G. Knepley } 1523c0ce001eSMatthew G. Knepley 1524c0ce001eSMatthew G. Knepley /*@ 1525c0ce001eSMatthew G. Knepley PetscFVSetDualSpace - Sets the PetscDualSpace used to define the inner product 1526c0ce001eSMatthew G. Knepley 1527c0ce001eSMatthew G. Knepley Not collective 1528c0ce001eSMatthew G. Knepley 1529c0ce001eSMatthew G. Knepley Input Parameters: 1530c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 1531c0ce001eSMatthew G. Knepley - sp - The PetscDualSpace object 1532c0ce001eSMatthew G. Knepley 1533c0ce001eSMatthew G. Knepley Level: intermediate 1534c0ce001eSMatthew G. Knepley 1535c0ce001eSMatthew G. Knepley Note: A simple dual space is provided automatically, and the user typically will not need to override it. 1536c0ce001eSMatthew G. Knepley 1537db781477SPatrick Sanan .seealso: `PetscFVCreate()` 1538c0ce001eSMatthew G. Knepley @*/ 1539*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetDualSpace(PetscFV fvm, PetscDualSpace sp) 1540*d71ae5a4SJacob Faibussowitsch { 1541c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1542c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1543c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 2); 15449566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&fvm->dualSpace)); 1545c0ce001eSMatthew G. Knepley fvm->dualSpace = sp; 15469566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fvm->dualSpace)); 1547c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1548c0ce001eSMatthew G. Knepley } 1549c0ce001eSMatthew G. Knepley 155088f5f89eSMatthew G. Knepley /*@C 1551ef0bb6c7SMatthew G. Knepley PetscFVGetCellTabulation - Returns the tabulation of the basis functions at the quadrature points 155288f5f89eSMatthew G. Knepley 155388f5f89eSMatthew G. Knepley Not collective 155488f5f89eSMatthew G. Knepley 155588f5f89eSMatthew G. Knepley Input Parameter: 155688f5f89eSMatthew G. Knepley . fvm - The PetscFV object 155788f5f89eSMatthew G. Knepley 1558ef0bb6c7SMatthew G. Knepley Output Parameter: 1559a5b23f4aSJose E. Roman . T - The basis function values and derivatives at quadrature points 156088f5f89eSMatthew G. Knepley 156188f5f89eSMatthew G. Knepley Note: 1562ef0bb6c7SMatthew G. Knepley $ T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 1563ef0bb6c7SMatthew G. Knepley $ T->T[1] = D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d 1564ef0bb6c7SMatthew G. Knepley $ T->T[2] = H[(((p*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point p for basis function i, component c, in directions d and e 156588f5f89eSMatthew G. Knepley 156688f5f89eSMatthew G. Knepley Level: intermediate 156788f5f89eSMatthew G. Knepley 1568db781477SPatrick Sanan .seealso: `PetscFEGetCellTabulation()`, `PetscFVCreateTabulation()`, `PetscFVGetQuadrature()`, `PetscQuadratureGetData()` 156988f5f89eSMatthew G. Knepley @*/ 1570*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetCellTabulation(PetscFV fvm, PetscTabulation *T) 1571*d71ae5a4SJacob Faibussowitsch { 1572c0ce001eSMatthew G. Knepley PetscInt npoints; 1573c0ce001eSMatthew G. Knepley const PetscReal *points; 1574c0ce001eSMatthew G. Knepley 1575c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1576c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1577ef0bb6c7SMatthew G. Knepley PetscValidPointer(T, 2); 15789566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(fvm->quadrature, NULL, NULL, &npoints, &points, NULL)); 15799566063dSJacob Faibussowitsch if (!fvm->T) PetscCall(PetscFVCreateTabulation(fvm, 1, npoints, points, 1, &fvm->T)); 1580ef0bb6c7SMatthew G. Knepley *T = fvm->T; 1581c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1582c0ce001eSMatthew G. Knepley } 1583c0ce001eSMatthew G. Knepley 158488f5f89eSMatthew G. Knepley /*@C 1585ef0bb6c7SMatthew G. Knepley PetscFVCreateTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided. 158688f5f89eSMatthew G. Knepley 158788f5f89eSMatthew G. Knepley Not collective 158888f5f89eSMatthew G. Knepley 158988f5f89eSMatthew G. Knepley Input Parameters: 159088f5f89eSMatthew G. Knepley + fvm - The PetscFV object 1591ef0bb6c7SMatthew G. Knepley . nrepl - The number of replicas 1592ef0bb6c7SMatthew G. Knepley . npoints - The number of tabulation points in a replica 1593ef0bb6c7SMatthew G. Knepley . points - The tabulation point coordinates 1594ef0bb6c7SMatthew G. Knepley - K - The order of derivative to tabulate 159588f5f89eSMatthew G. Knepley 1596ef0bb6c7SMatthew G. Knepley Output Parameter: 1597a5b23f4aSJose E. Roman . T - The basis function values and derivative at tabulation points 159888f5f89eSMatthew G. Knepley 159988f5f89eSMatthew G. Knepley Note: 1600ef0bb6c7SMatthew G. Knepley $ T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 1601ef0bb6c7SMatthew G. Knepley $ T->T[1] = D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d 1602ef0bb6c7SMatthew G. Knepley $ T->T[2] = H[(((p*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point p for basis function i, component c, in directions d and e 160388f5f89eSMatthew G. Knepley 160488f5f89eSMatthew G. Knepley Level: intermediate 160588f5f89eSMatthew G. Knepley 1606db781477SPatrick Sanan .seealso: `PetscFECreateTabulation()`, `PetscTabulationDestroy()`, `PetscFEGetCellTabulation()` 160788f5f89eSMatthew G. Knepley @*/ 1608*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVCreateTabulation(PetscFV fvm, PetscInt nrepl, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation *T) 1609*d71ae5a4SJacob Faibussowitsch { 1610c0ce001eSMatthew G. Knepley PetscInt pdim = 1; /* Dimension of approximation space P */ 1611ef0bb6c7SMatthew G. Knepley PetscInt cdim; /* Spatial dimension */ 1612ef0bb6c7SMatthew G. Knepley PetscInt Nc; /* Field components */ 1613ef0bb6c7SMatthew G. Knepley PetscInt k, p, d, c, e; 1614c0ce001eSMatthew G. Knepley 1615c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1616ef0bb6c7SMatthew G. Knepley if (!npoints || K < 0) { 1617ef0bb6c7SMatthew G. Knepley *T = NULL; 1618c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1619c0ce001eSMatthew G. Knepley } 1620c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1621dadcf809SJacob Faibussowitsch PetscValidRealPointer(points, 4); 162240a2aa30SMatthew G. Knepley PetscValidPointer(T, 6); 16239566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &cdim)); 16249566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &Nc)); 16259566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, T)); 1626ef0bb6c7SMatthew G. Knepley (*T)->K = !cdim ? 0 : K; 1627ef0bb6c7SMatthew G. Knepley (*T)->Nr = nrepl; 1628ef0bb6c7SMatthew G. Knepley (*T)->Np = npoints; 1629ef0bb6c7SMatthew G. Knepley (*T)->Nb = pdim; 1630ef0bb6c7SMatthew G. Knepley (*T)->Nc = Nc; 1631ef0bb6c7SMatthew G. Knepley (*T)->cdim = cdim; 16329566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*T)->K + 1, &(*T)->T)); 163348a46eb9SPierre Jolivet for (k = 0; k <= (*T)->K; ++k) PetscCall(PetscMalloc1(nrepl * npoints * pdim * Nc * PetscPowInt(cdim, k), &(*T)->T[k])); 16349371c9d4SSatish Balay if (K >= 0) { 16359371c9d4SSatish Balay for (p = 0; p < nrepl * npoints; ++p) 16369371c9d4SSatish Balay for (d = 0; d < pdim; ++d) 16379371c9d4SSatish Balay for (c = 0; c < Nc; ++c) (*T)->T[0][(p * pdim + d) * Nc + c] = 1.0; 1638ef0bb6c7SMatthew G. Knepley } 16399371c9d4SSatish Balay if (K >= 1) { 16409371c9d4SSatish Balay for (p = 0; p < nrepl * npoints; ++p) 16419371c9d4SSatish Balay for (d = 0; d < pdim; ++d) 16429371c9d4SSatish Balay for (c = 0; c < Nc; ++c) 16439371c9d4SSatish Balay for (e = 0; e < cdim; ++e) (*T)->T[1][((p * pdim + d) * Nc + c) * cdim + e] = 0.0; 16449371c9d4SSatish Balay } 16459371c9d4SSatish Balay if (K >= 2) { 16469371c9d4SSatish Balay for (p = 0; p < nrepl * npoints; ++p) 16479371c9d4SSatish Balay for (d = 0; d < pdim; ++d) 16489371c9d4SSatish Balay for (c = 0; c < Nc; ++c) 16499371c9d4SSatish Balay for (e = 0; e < cdim * cdim; ++e) (*T)->T[2][((p * pdim + d) * Nc + c) * cdim * cdim + e] = 0.0; 16509371c9d4SSatish Balay } 1651c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1652c0ce001eSMatthew G. Knepley } 1653c0ce001eSMatthew G. Knepley 1654c0ce001eSMatthew G. Knepley /*@C 1655c0ce001eSMatthew G. Knepley PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell 1656c0ce001eSMatthew G. Knepley 1657c0ce001eSMatthew G. Knepley Input Parameters: 1658c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 1659c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained 1660c0ce001eSMatthew G. Knepley - dx - The vector from the cell centroid to the neighboring cell centroid for each face 1661c0ce001eSMatthew G. Knepley 166288f5f89eSMatthew G. Knepley Level: advanced 1663c0ce001eSMatthew G. Knepley 1664db781477SPatrick Sanan .seealso: `PetscFVCreate()` 1665c0ce001eSMatthew G. Knepley @*/ 1666*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVComputeGradient(PetscFV fvm, PetscInt numFaces, PetscScalar dx[], PetscScalar grad[]) 1667*d71ae5a4SJacob Faibussowitsch { 1668c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1669c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1670dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, computegradient, numFaces, dx, grad); 1671c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1672c0ce001eSMatthew G. Knepley } 1673c0ce001eSMatthew G. Knepley 167488f5f89eSMatthew G. Knepley /*@C 1675c0ce001eSMatthew G. Knepley PetscFVIntegrateRHSFunction - Produce the cell residual vector for a chunk of elements by quadrature integration 1676c0ce001eSMatthew G. Knepley 1677c0ce001eSMatthew G. Knepley Not collective 1678c0ce001eSMatthew G. Knepley 1679c0ce001eSMatthew G. Knepley Input Parameters: 1680c0ce001eSMatthew G. Knepley + fvm - The PetscFV object for the field being integrated 1681c0ce001eSMatthew G. Knepley . prob - The PetscDS specifing the discretizations and continuum functions 1682c0ce001eSMatthew G. Knepley . field - The field being integrated 1683c0ce001eSMatthew G. Knepley . Nf - The number of faces in the chunk 1684c0ce001eSMatthew G. Knepley . fgeom - The face geometry for each face in the chunk 1685c0ce001eSMatthew G. Knepley . neighborVol - The volume for each pair of cells in the chunk 1686c0ce001eSMatthew G. Knepley . uL - The state from the cell on the left 1687c0ce001eSMatthew G. Knepley - uR - The state from the cell on the right 1688c0ce001eSMatthew G. Knepley 1689d8d19677SJose E. Roman Output Parameters: 1690c0ce001eSMatthew G. Knepley + fluxL - the left fluxes for each face 1691c0ce001eSMatthew G. Knepley - fluxR - the right fluxes for each face 169288f5f89eSMatthew G. Knepley 169388f5f89eSMatthew G. Knepley Level: developer 169488f5f89eSMatthew G. Knepley 1695db781477SPatrick Sanan .seealso: `PetscFVCreate()` 169688f5f89eSMatthew G. Knepley @*/ 1697*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVIntegrateRHSFunction(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) 1698*d71ae5a4SJacob Faibussowitsch { 1699c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1700c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1701dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, integraterhsfunction, prob, field, Nf, fgeom, neighborVol, uL, uR, fluxL, fluxR); 1702c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1703c0ce001eSMatthew G. Knepley } 1704c0ce001eSMatthew G. Knepley 1705c0ce001eSMatthew G. Knepley /*@ 1706c0ce001eSMatthew G. Knepley PetscFVRefine - Create a "refined" PetscFV object that refines the reference cell into smaller copies. This is typically used 1707c0ce001eSMatthew G. Knepley to precondition a higher order method with a lower order method on a refined mesh having the same number of dofs (but more 1708c0ce001eSMatthew G. Knepley sparsity). It is also used to create an interpolation between regularly refined meshes. 1709c0ce001eSMatthew G. Knepley 1710c0ce001eSMatthew G. Knepley Input Parameter: 1711c0ce001eSMatthew G. Knepley . fv - The initial PetscFV 1712c0ce001eSMatthew G. Knepley 1713c0ce001eSMatthew G. Knepley Output Parameter: 1714c0ce001eSMatthew G. Knepley . fvRef - The refined PetscFV 1715c0ce001eSMatthew G. Knepley 171688f5f89eSMatthew G. Knepley Level: advanced 1717c0ce001eSMatthew G. Knepley 1718db781477SPatrick Sanan .seealso: `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 1719c0ce001eSMatthew G. Knepley @*/ 1720*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVRefine(PetscFV fv, PetscFV *fvRef) 1721*d71ae5a4SJacob Faibussowitsch { 1722c0ce001eSMatthew G. Knepley PetscDualSpace Q, Qref; 1723c0ce001eSMatthew G. Knepley DM K, Kref; 1724c0ce001eSMatthew G. Knepley PetscQuadrature q, qref; 1725412e9a14SMatthew G. Knepley DMPolytopeType ct; 1726012bc364SMatthew G. Knepley DMPlexTransform tr; 1727c0ce001eSMatthew G. Knepley PetscReal *v0; 1728c0ce001eSMatthew G. Knepley PetscReal *jac, *invjac; 1729c0ce001eSMatthew G. Knepley PetscInt numComp, numSubelements, s; 1730c0ce001eSMatthew G. Knepley 1731c0ce001eSMatthew G. Knepley PetscFunctionBegin; 17329566063dSJacob Faibussowitsch PetscCall(PetscFVGetDualSpace(fv, &Q)); 17339566063dSJacob Faibussowitsch PetscCall(PetscFVGetQuadrature(fv, &q)); 17349566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &K)); 1735c0ce001eSMatthew G. Knepley /* Create dual space */ 17369566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDuplicate(Q, &Qref)); 17379566063dSJacob Faibussowitsch PetscCall(DMRefine(K, PetscObjectComm((PetscObject)fv), &Kref)); 17389566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(Qref, Kref)); 17399566063dSJacob Faibussowitsch PetscCall(DMDestroy(&Kref)); 17409566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(Qref)); 1741c0ce001eSMatthew G. Knepley /* Create volume */ 17429566063dSJacob Faibussowitsch PetscCall(PetscFVCreate(PetscObjectComm((PetscObject)fv), fvRef)); 17439566063dSJacob Faibussowitsch PetscCall(PetscFVSetDualSpace(*fvRef, Qref)); 17449566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &numComp)); 17459566063dSJacob Faibussowitsch PetscCall(PetscFVSetNumComponents(*fvRef, numComp)); 17469566063dSJacob Faibussowitsch PetscCall(PetscFVSetUp(*fvRef)); 1747c0ce001eSMatthew G. Knepley /* Create quadrature */ 17489566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(K, 0, &ct)); 17499566063dSJacob Faibussowitsch PetscCall(DMPlexTransformCreate(PETSC_COMM_SELF, &tr)); 17509566063dSJacob Faibussowitsch PetscCall(DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR)); 17519566063dSJacob Faibussowitsch PetscCall(DMPlexRefineRegularGetAffineTransforms(tr, ct, &numSubelements, &v0, &jac, &invjac)); 17529566063dSJacob Faibussowitsch PetscCall(PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref)); 17539566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetDimension(Qref, numSubelements)); 1754c0ce001eSMatthew G. Knepley for (s = 0; s < numSubelements; ++s) { 1755c0ce001eSMatthew G. Knepley PetscQuadrature qs; 1756c0ce001eSMatthew G. Knepley const PetscReal *points, *weights; 1757c0ce001eSMatthew G. Knepley PetscReal *p, *w; 1758c0ce001eSMatthew G. Knepley PetscInt dim, Nc, npoints, np; 1759c0ce001eSMatthew G. Knepley 17609566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qs)); 17619566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(q, &dim, &Nc, &npoints, &points, &weights)); 1762c0ce001eSMatthew G. Knepley np = npoints / numSubelements; 17639566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(np * dim, &p)); 17649566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(np * Nc, &w)); 17659566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(p, &points[s * np * dim], np * dim)); 17669566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(w, &weights[s * np * Nc], np * Nc)); 17679566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(qs, dim, Nc, np, p, w)); 17689566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetFunctional(Qref, s, qs)); 17699566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qs)); 1770c0ce001eSMatthew G. Knepley } 17719566063dSJacob Faibussowitsch PetscCall(PetscFVSetQuadrature(*fvRef, qref)); 17729566063dSJacob Faibussowitsch PetscCall(DMPlexTransformDestroy(&tr)); 17739566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qref)); 17749566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&Qref)); 1775c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1776c0ce001eSMatthew G. Knepley } 1777c0ce001eSMatthew G. Knepley 1778*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVDestroy_Upwind(PetscFV fvm) 1779*d71ae5a4SJacob Faibussowitsch { 1780c0ce001eSMatthew G. Knepley PetscFV_Upwind *b = (PetscFV_Upwind *)fvm->data; 1781c0ce001eSMatthew G. Knepley 1782c0ce001eSMatthew G. Knepley PetscFunctionBegin; 17839566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 1784c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1785c0ce001eSMatthew G. Knepley } 1786c0ce001eSMatthew G. Knepley 1787*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_Upwind_Ascii(PetscFV fv, PetscViewer viewer) 1788*d71ae5a4SJacob Faibussowitsch { 1789c0ce001eSMatthew G. Knepley PetscInt Nc, c; 1790c0ce001eSMatthew G. Knepley PetscViewerFormat format; 1791c0ce001eSMatthew G. Knepley 1792c0ce001eSMatthew G. Knepley PetscFunctionBegin; 17939566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &Nc)); 17949566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 17959566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Upwind Finite Volume:\n")); 179663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " num components: %" PetscInt_FMT "\n", Nc)); 1797c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; c++) { 179848a46eb9SPierre Jolivet if (fv->componentNames[c]) PetscCall(PetscViewerASCIIPrintf(viewer, " component %" PetscInt_FMT ": %s\n", c, fv->componentNames[c])); 1799c0ce001eSMatthew G. Knepley } 1800c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1801c0ce001eSMatthew G. Knepley } 1802c0ce001eSMatthew G. Knepley 1803*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_Upwind(PetscFV fv, PetscViewer viewer) 1804*d71ae5a4SJacob Faibussowitsch { 1805c0ce001eSMatthew G. Knepley PetscBool iascii; 1806c0ce001eSMatthew G. Knepley 1807c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1808c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1); 1809c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 18109566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 18119566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscFVView_Upwind_Ascii(fv, viewer)); 1812c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1813c0ce001eSMatthew G. Knepley } 1814c0ce001eSMatthew G. Knepley 1815*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVSetUp_Upwind(PetscFV fvm) 1816*d71ae5a4SJacob Faibussowitsch { 1817c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1818c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1819c0ce001eSMatthew G. Knepley } 1820c0ce001eSMatthew G. Knepley 1821c0ce001eSMatthew G. Knepley /* 1822c0ce001eSMatthew G. Knepley neighborVol[f*2+0] contains the left geom 1823c0ce001eSMatthew G. Knepley neighborVol[f*2+1] contains the right geom 1824c0ce001eSMatthew G. Knepley */ 1825*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVIntegrateRHSFunction_Upwind(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) 1826*d71ae5a4SJacob Faibussowitsch { 1827c0ce001eSMatthew G. Knepley void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *); 1828c0ce001eSMatthew G. Knepley void *rctx; 1829c0ce001eSMatthew G. Knepley PetscScalar *flux = fvm->fluxWork; 1830c0ce001eSMatthew G. Knepley const PetscScalar *constants; 1831c0ce001eSMatthew G. Knepley PetscInt dim, numConstants, pdim, totDim, Nc, off, f, d; 1832c0ce001eSMatthew G. Knepley 1833c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18349566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalComponents(prob, &Nc)); 18359566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalDimension(prob, &totDim)); 18369566063dSJacob Faibussowitsch PetscCall(PetscDSGetFieldOffset(prob, field, &off)); 18379566063dSJacob Faibussowitsch PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann)); 18389566063dSJacob Faibussowitsch PetscCall(PetscDSGetContext(prob, field, &rctx)); 18399566063dSJacob Faibussowitsch PetscCall(PetscDSGetConstants(prob, &numConstants, &constants)); 18409566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 18419566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &pdim)); 1842c0ce001eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 1843c0ce001eSMatthew G. Knepley (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f * Nc], &uR[f * Nc], numConstants, constants, flux, rctx); 1844c0ce001eSMatthew G. Knepley for (d = 0; d < pdim; ++d) { 1845c0ce001eSMatthew G. Knepley fluxL[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 0]; 1846c0ce001eSMatthew G. Knepley fluxR[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 1]; 1847c0ce001eSMatthew G. Knepley } 1848c0ce001eSMatthew G. Knepley } 1849c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1850c0ce001eSMatthew G. Knepley } 1851c0ce001eSMatthew G. Knepley 1852*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVInitialize_Upwind(PetscFV fvm) 1853*d71ae5a4SJacob Faibussowitsch { 1854c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1855c0ce001eSMatthew G. Knepley fvm->ops->setfromoptions = NULL; 1856c0ce001eSMatthew G. Knepley fvm->ops->setup = PetscFVSetUp_Upwind; 1857c0ce001eSMatthew G. Knepley fvm->ops->view = PetscFVView_Upwind; 1858c0ce001eSMatthew G. Knepley fvm->ops->destroy = PetscFVDestroy_Upwind; 1859c0ce001eSMatthew G. Knepley fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_Upwind; 1860c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1861c0ce001eSMatthew G. Knepley } 1862c0ce001eSMatthew G. Knepley 1863c0ce001eSMatthew G. Knepley /*MC 1864c0ce001eSMatthew G. Knepley PETSCFVUPWIND = "upwind" - A PetscFV object 1865c0ce001eSMatthew G. Knepley 1866c0ce001eSMatthew G. Knepley Level: intermediate 1867c0ce001eSMatthew G. Knepley 1868db781477SPatrick Sanan .seealso: `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 1869c0ce001eSMatthew G. Knepley M*/ 1870c0ce001eSMatthew G. Knepley 1871*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscFVCreate_Upwind(PetscFV fvm) 1872*d71ae5a4SJacob Faibussowitsch { 1873c0ce001eSMatthew G. Knepley PetscFV_Upwind *b; 1874c0ce001eSMatthew G. Knepley 1875c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1876c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 18774dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 1878c0ce001eSMatthew G. Knepley fvm->data = b; 1879c0ce001eSMatthew G. Knepley 18809566063dSJacob Faibussowitsch PetscCall(PetscFVInitialize_Upwind(fvm)); 1881c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1882c0ce001eSMatthew G. Knepley } 1883c0ce001eSMatthew G. Knepley 1884c0ce001eSMatthew G. Knepley #include <petscblaslapack.h> 1885c0ce001eSMatthew G. Knepley 1886*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVDestroy_LeastSquares(PetscFV fvm) 1887*d71ae5a4SJacob Faibussowitsch { 1888c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data; 1889c0ce001eSMatthew G. Knepley 1890c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18919566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fvm, "PetscFVLeastSquaresSetMaxFaces_C", NULL)); 18929566063dSJacob Faibussowitsch PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work)); 18939566063dSJacob Faibussowitsch PetscCall(PetscFree(ls)); 1894c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1895c0ce001eSMatthew G. Knepley } 1896c0ce001eSMatthew G. Knepley 1897*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_LeastSquares_Ascii(PetscFV fv, PetscViewer viewer) 1898*d71ae5a4SJacob Faibussowitsch { 1899c0ce001eSMatthew G. Knepley PetscInt Nc, c; 1900c0ce001eSMatthew G. Knepley PetscViewerFormat format; 1901c0ce001eSMatthew G. Knepley 1902c0ce001eSMatthew G. Knepley PetscFunctionBegin; 19039566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &Nc)); 19049566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 19059566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Finite Volume with Least Squares Reconstruction:\n")); 190663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " num components: %" PetscInt_FMT "\n", Nc)); 1907c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; c++) { 190848a46eb9SPierre Jolivet if (fv->componentNames[c]) PetscCall(PetscViewerASCIIPrintf(viewer, " component %" PetscInt_FMT ": %s\n", c, fv->componentNames[c])); 1909c0ce001eSMatthew G. Knepley } 1910c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1911c0ce001eSMatthew G. Knepley } 1912c0ce001eSMatthew G. Knepley 1913*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_LeastSquares(PetscFV fv, PetscViewer viewer) 1914*d71ae5a4SJacob Faibussowitsch { 1915c0ce001eSMatthew G. Knepley PetscBool iascii; 1916c0ce001eSMatthew G. Knepley 1917c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1918c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1); 1919c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 19209566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 19219566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscFVView_LeastSquares_Ascii(fv, viewer)); 1922c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1923c0ce001eSMatthew G. Knepley } 1924c0ce001eSMatthew G. Knepley 1925*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVSetUp_LeastSquares(PetscFV fvm) 1926*d71ae5a4SJacob Faibussowitsch { 1927c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1928c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1929c0ce001eSMatthew G. Knepley } 1930c0ce001eSMatthew G. Knepley 1931c0ce001eSMatthew G. Knepley /* Overwrites A. Can only handle full-rank problems with m>=n */ 1932*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresPseudoInverse_Static(PetscInt m, PetscInt mstride, PetscInt n, PetscScalar *A, PetscScalar *Ainv, PetscScalar *tau, PetscInt worksize, PetscScalar *work) 1933*d71ae5a4SJacob Faibussowitsch { 1934c0ce001eSMatthew G. Knepley PetscBool debug = PETSC_FALSE; 1935c0ce001eSMatthew G. Knepley PetscBLASInt M, N, K, lda, ldb, ldwork, info; 1936c0ce001eSMatthew G. Knepley PetscScalar *R, *Q, *Aback, Alpha; 1937c0ce001eSMatthew G. Knepley 1938c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1939c0ce001eSMatthew G. Knepley if (debug) { 19409566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * n, &Aback)); 19419566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(Aback, A, m * n)); 1942c0ce001eSMatthew G. Knepley } 1943c0ce001eSMatthew G. Knepley 19449566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &M)); 19459566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &N)); 19469566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(mstride, &lda)); 19479566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(worksize, &ldwork)); 19489566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 1949792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&M, &N, A, &lda, tau, work, &ldwork, &info)); 19509566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 195128b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xGEQRF error"); 1952c0ce001eSMatthew G. Knepley R = A; /* Upper triangular part of A now contains R, the rest contains the elementary reflectors */ 1953c0ce001eSMatthew G. Knepley 1954c0ce001eSMatthew G. Knepley /* Extract an explicit representation of Q */ 1955c0ce001eSMatthew G. Knepley Q = Ainv; 19569566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(Q, A, mstride * n)); 1957c0ce001eSMatthew G. Knepley K = N; /* full rank */ 1958792fecdfSBarry Smith PetscCallBLAS("LAPACKorgqr", LAPACKorgqr_(&M, &N, &K, Q, &lda, tau, work, &ldwork, &info)); 195928b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xORGQR/xUNGQR error"); 1960c0ce001eSMatthew G. Knepley 1961c0ce001eSMatthew G. Knepley /* Compute A^{-T} = (R^{-1} Q^T)^T = Q R^{-T} */ 1962c0ce001eSMatthew G. Knepley Alpha = 1.0; 1963c0ce001eSMatthew G. Knepley ldb = lda; 1964c0ce001eSMatthew G. Knepley BLAStrsm_("Right", "Upper", "ConjugateTranspose", "NotUnitTriangular", &M, &N, &Alpha, R, &lda, Q, &ldb); 1965c0ce001eSMatthew G. Knepley /* Ainv is Q, overwritten with inverse */ 1966c0ce001eSMatthew G. Knepley 1967c0ce001eSMatthew G. Knepley if (debug) { /* Check that pseudo-inverse worked */ 1968c0ce001eSMatthew G. Knepley PetscScalar Beta = 0.0; 1969c0ce001eSMatthew G. Knepley PetscBLASInt ldc; 1970c0ce001eSMatthew G. Knepley K = N; 1971c0ce001eSMatthew G. Knepley ldc = N; 1972c0ce001eSMatthew G. Knepley BLASgemm_("ConjugateTranspose", "Normal", &N, &K, &M, &Alpha, Ainv, &lda, Aback, &ldb, &Beta, work, &ldc); 19739566063dSJacob Faibussowitsch PetscCall(PetscScalarView(n * n, work, PETSC_VIEWER_STDOUT_SELF)); 19749566063dSJacob Faibussowitsch PetscCall(PetscFree(Aback)); 1975c0ce001eSMatthew G. Knepley } 1976c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1977c0ce001eSMatthew G. Knepley } 1978c0ce001eSMatthew G. Knepley 1979c0ce001eSMatthew G. Knepley /* Overwrites A. Can handle degenerate problems and m<n. */ 1980*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresPseudoInverseSVD_Static(PetscInt m, PetscInt mstride, PetscInt n, PetscScalar *A, PetscScalar *Ainv, PetscScalar *tau, PetscInt worksize, PetscScalar *work) 1981*d71ae5a4SJacob Faibussowitsch { 19826bb27163SBarry Smith PetscScalar *Brhs; 1983c0ce001eSMatthew G. Knepley PetscScalar *tmpwork; 1984c0ce001eSMatthew G. Knepley PetscReal rcond; 1985c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX) 1986c0ce001eSMatthew G. Knepley PetscInt rworkSize; 1987c0ce001eSMatthew G. Knepley PetscReal *rwork; 1988c0ce001eSMatthew G. Knepley #endif 1989c0ce001eSMatthew G. Knepley PetscInt i, j, maxmn; 1990c0ce001eSMatthew G. Knepley PetscBLASInt M, N, lda, ldb, ldwork; 1991c0ce001eSMatthew G. Knepley PetscBLASInt nrhs, irank, info; 1992c0ce001eSMatthew G. Knepley 1993c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1994c0ce001eSMatthew G. Knepley /* initialize to identity */ 1995736d4f42SpierreXVI tmpwork = work; 1996736d4f42SpierreXVI Brhs = Ainv; 1997c0ce001eSMatthew G. Knepley maxmn = PetscMax(m, n); 1998c0ce001eSMatthew G. Knepley for (j = 0; j < maxmn; j++) { 1999c0ce001eSMatthew G. Knepley for (i = 0; i < maxmn; i++) Brhs[i + j * maxmn] = 1.0 * (i == j); 2000c0ce001eSMatthew G. Knepley } 2001c0ce001eSMatthew G. Knepley 20029566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &M)); 20039566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &N)); 20049566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(mstride, &lda)); 20059566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(maxmn, &ldb)); 20069566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(worksize, &ldwork)); 2007c0ce001eSMatthew G. Knepley rcond = -1; 2008c0ce001eSMatthew G. Knepley nrhs = M; 2009c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX) 2010c0ce001eSMatthew G. Knepley rworkSize = 5 * PetscMin(M, N); 20119566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(rworkSize, &rwork)); 20126bb27163SBarry Smith PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 2013792fecdfSBarry Smith PetscCallBLAS("LAPACKgelss", LAPACKgelss_(&M, &N, &nrhs, A, &lda, Brhs, &ldb, (PetscReal *)tau, &rcond, &irank, tmpwork, &ldwork, rwork, &info)); 20149566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 20159566063dSJacob Faibussowitsch PetscCall(PetscFree(rwork)); 2016c0ce001eSMatthew G. Knepley #else 2017c0ce001eSMatthew G. Knepley nrhs = M; 20186bb27163SBarry Smith PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 2019792fecdfSBarry Smith PetscCallBLAS("LAPACKgelss", LAPACKgelss_(&M, &N, &nrhs, A, &lda, Brhs, &ldb, (PetscReal *)tau, &rcond, &irank, tmpwork, &ldwork, &info)); 20209566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 2021c0ce001eSMatthew G. Knepley #endif 202228b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xGELSS error"); 2023c0ce001eSMatthew G. Knepley /* The following check should be turned into a diagnostic as soon as someone wants to do this intentionally */ 202408401ef6SPierre Jolivet PetscCheck(irank >= PetscMin(M, N), PETSC_COMM_SELF, PETSC_ERR_USER, "Rank deficient least squares fit, indicates an isolated cell with two colinear points"); 2025c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2026c0ce001eSMatthew G. Knepley } 2027c0ce001eSMatthew G. Knepley 2028c0ce001eSMatthew G. Knepley #if 0 2029c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresDebugCell_Static(PetscFV fvm, PetscInt cell, DM dm, DM dmFace, PetscScalar *fgeom, DM dmCell, PetscScalar *cgeom) 2030c0ce001eSMatthew G. Knepley { 2031c0ce001eSMatthew G. Knepley PetscReal grad[2] = {0, 0}; 2032c0ce001eSMatthew G. Knepley const PetscInt *faces; 2033c0ce001eSMatthew G. Knepley PetscInt numFaces, f; 2034c0ce001eSMatthew G. Knepley 2035c0ce001eSMatthew G. Knepley PetscFunctionBegin; 20369566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, cell, &numFaces)); 20379566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, cell, &faces)); 2038c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2039c0ce001eSMatthew G. Knepley const PetscInt *fcells; 2040c0ce001eSMatthew G. Knepley const CellGeom *cg1; 2041c0ce001eSMatthew G. Knepley const FaceGeom *fg; 2042c0ce001eSMatthew G. Knepley 20439566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupport(dm, faces[f], &fcells)); 20449566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmFace, faces[f], fgeom, &fg)); 2045c0ce001eSMatthew G. Knepley for (i = 0; i < 2; ++i) { 2046c0ce001eSMatthew G. Knepley PetscScalar du; 2047c0ce001eSMatthew G. Knepley 2048c0ce001eSMatthew G. Knepley if (fcells[i] == c) continue; 20499566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmCell, fcells[i], cgeom, &cg1)); 2050c0ce001eSMatthew G. Knepley du = cg1->centroid[0] + 3*cg1->centroid[1] - (cg->centroid[0] + 3*cg->centroid[1]); 2051c0ce001eSMatthew G. Knepley grad[0] += fg->grad[!i][0] * du; 2052c0ce001eSMatthew G. Knepley grad[1] += fg->grad[!i][1] * du; 2053c0ce001eSMatthew G. Knepley } 2054c0ce001eSMatthew G. Knepley } 20559566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "cell[%d] grad (%g, %g)\n", cell, grad[0], grad[1])); 2056c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2057c0ce001eSMatthew G. Knepley } 2058c0ce001eSMatthew G. Knepley #endif 2059c0ce001eSMatthew G. Knepley 2060c0ce001eSMatthew G. Knepley /* 2061c0ce001eSMatthew G. Knepley PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell 2062c0ce001eSMatthew G. Knepley 2063c0ce001eSMatthew G. Knepley Input Parameters: 2064c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 2065c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained 2066c0ce001eSMatthew G. Knepley . dx - The vector from the cell centroid to the neighboring cell centroid for each face 2067c0ce001eSMatthew G. Knepley 2068c0ce001eSMatthew G. Knepley Level: developer 2069c0ce001eSMatthew G. Knepley 2070db781477SPatrick Sanan .seealso: `PetscFVCreate()` 2071c0ce001eSMatthew G. Knepley */ 2072*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVComputeGradient_LeastSquares(PetscFV fvm, PetscInt numFaces, const PetscScalar dx[], PetscScalar grad[]) 2073*d71ae5a4SJacob Faibussowitsch { 2074c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data; 2075c0ce001eSMatthew G. Knepley const PetscBool useSVD = PETSC_TRUE; 2076c0ce001eSMatthew G. Knepley const PetscInt maxFaces = ls->maxFaces; 2077c0ce001eSMatthew G. Knepley PetscInt dim, f, d; 2078c0ce001eSMatthew G. Knepley 2079c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2080c0ce001eSMatthew G. Knepley if (numFaces > maxFaces) { 208108401ef6SPierre Jolivet PetscCheck(maxFaces >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Reconstruction has not been initialized, call PetscFVLeastSquaresSetMaxFaces()"); 208263a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of input faces %" PetscInt_FMT " > %" PetscInt_FMT " maxfaces", numFaces, maxFaces); 2083c0ce001eSMatthew G. Knepley } 20849566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 2085c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2086c0ce001eSMatthew G. Knepley for (d = 0; d < dim; ++d) ls->B[d * maxFaces + f] = dx[f * dim + d]; 2087c0ce001eSMatthew G. Knepley } 2088c0ce001eSMatthew G. Knepley /* Overwrites B with garbage, returns Binv in row-major format */ 2089736d4f42SpierreXVI if (useSVD) { 2090736d4f42SpierreXVI PetscInt maxmn = PetscMax(numFaces, dim); 20919566063dSJacob Faibussowitsch PetscCall(PetscFVLeastSquaresPseudoInverseSVD_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work)); 2092736d4f42SpierreXVI /* Binv shaped in column-major, coldim=maxmn.*/ 2093736d4f42SpierreXVI for (f = 0; f < numFaces; ++f) { 2094736d4f42SpierreXVI for (d = 0; d < dim; ++d) grad[f * dim + d] = ls->Binv[d + maxmn * f]; 2095736d4f42SpierreXVI } 2096736d4f42SpierreXVI } else { 20979566063dSJacob Faibussowitsch PetscCall(PetscFVLeastSquaresPseudoInverse_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work)); 2098736d4f42SpierreXVI /* Binv shaped in row-major, rowdim=maxFaces.*/ 2099c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2100c0ce001eSMatthew G. Knepley for (d = 0; d < dim; ++d) grad[f * dim + d] = ls->Binv[d * maxFaces + f]; 2101c0ce001eSMatthew G. Knepley } 2102736d4f42SpierreXVI } 2103c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2104c0ce001eSMatthew G. Knepley } 2105c0ce001eSMatthew G. Knepley 2106c0ce001eSMatthew G. Knepley /* 2107c0ce001eSMatthew G. Knepley neighborVol[f*2+0] contains the left geom 2108c0ce001eSMatthew G. Knepley neighborVol[f*2+1] contains the right geom 2109c0ce001eSMatthew G. Knepley */ 2110*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVIntegrateRHSFunction_LeastSquares(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) 2111*d71ae5a4SJacob Faibussowitsch { 2112c0ce001eSMatthew G. Knepley void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *); 2113c0ce001eSMatthew G. Knepley void *rctx; 2114c0ce001eSMatthew G. Knepley PetscScalar *flux = fvm->fluxWork; 2115c0ce001eSMatthew G. Knepley const PetscScalar *constants; 2116c0ce001eSMatthew G. Knepley PetscInt dim, numConstants, pdim, Nc, totDim, off, f, d; 2117c0ce001eSMatthew G. Knepley 2118c0ce001eSMatthew G. Knepley PetscFunctionBegin; 21199566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalComponents(prob, &Nc)); 21209566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalDimension(prob, &totDim)); 21219566063dSJacob Faibussowitsch PetscCall(PetscDSGetFieldOffset(prob, field, &off)); 21229566063dSJacob Faibussowitsch PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann)); 21239566063dSJacob Faibussowitsch PetscCall(PetscDSGetContext(prob, field, &rctx)); 21249566063dSJacob Faibussowitsch PetscCall(PetscDSGetConstants(prob, &numConstants, &constants)); 21259566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 21269566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &pdim)); 2127c0ce001eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2128c0ce001eSMatthew G. Knepley (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f * Nc], &uR[f * Nc], numConstants, constants, flux, rctx); 2129c0ce001eSMatthew G. Knepley for (d = 0; d < pdim; ++d) { 2130c0ce001eSMatthew G. Knepley fluxL[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 0]; 2131c0ce001eSMatthew G. Knepley fluxR[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 1]; 2132c0ce001eSMatthew G. Knepley } 2133c0ce001eSMatthew G. Knepley } 2134c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2135c0ce001eSMatthew G. Knepley } 2136c0ce001eSMatthew G. Knepley 2137*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresSetMaxFaces_LS(PetscFV fvm, PetscInt maxFaces) 2138*d71ae5a4SJacob Faibussowitsch { 2139c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data; 2140736d4f42SpierreXVI PetscInt dim, m, n, nrhs, minmn, maxmn; 2141c0ce001eSMatthew G. Knepley 2142c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2143c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 21449566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 21459566063dSJacob Faibussowitsch PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work)); 2146c0ce001eSMatthew G. Knepley ls->maxFaces = maxFaces; 2147c0ce001eSMatthew G. Knepley m = ls->maxFaces; 2148c0ce001eSMatthew G. Knepley n = dim; 2149c0ce001eSMatthew G. Knepley nrhs = ls->maxFaces; 2150736d4f42SpierreXVI minmn = PetscMin(m, n); 2151736d4f42SpierreXVI maxmn = PetscMax(m, n); 2152736d4f42SpierreXVI ls->workSize = 3 * minmn + PetscMax(2 * minmn, PetscMax(maxmn, nrhs)); /* required by LAPACK */ 21539566063dSJacob Faibussowitsch PetscCall(PetscMalloc4(m * n, &ls->B, maxmn * maxmn, &ls->Binv, minmn, &ls->tau, ls->workSize, &ls->work)); 2154c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2155c0ce001eSMatthew G. Knepley } 2156c0ce001eSMatthew G. Knepley 2157*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVInitialize_LeastSquares(PetscFV fvm) 2158*d71ae5a4SJacob Faibussowitsch { 2159c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2160c0ce001eSMatthew G. Knepley fvm->ops->setfromoptions = NULL; 2161c0ce001eSMatthew G. Knepley fvm->ops->setup = PetscFVSetUp_LeastSquares; 2162c0ce001eSMatthew G. Knepley fvm->ops->view = PetscFVView_LeastSquares; 2163c0ce001eSMatthew G. Knepley fvm->ops->destroy = PetscFVDestroy_LeastSquares; 2164c0ce001eSMatthew G. Knepley fvm->ops->computegradient = PetscFVComputeGradient_LeastSquares; 2165c0ce001eSMatthew G. Knepley fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_LeastSquares; 2166c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2167c0ce001eSMatthew G. Knepley } 2168c0ce001eSMatthew G. Knepley 2169c0ce001eSMatthew G. Knepley /*MC 2170c0ce001eSMatthew G. Knepley PETSCFVLEASTSQUARES = "leastsquares" - A PetscFV object 2171c0ce001eSMatthew G. Knepley 2172c0ce001eSMatthew G. Knepley Level: intermediate 2173c0ce001eSMatthew G. Knepley 2174db781477SPatrick Sanan .seealso: `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 2175c0ce001eSMatthew G. Knepley M*/ 2176c0ce001eSMatthew G. Knepley 2177*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscFVCreate_LeastSquares(PetscFV fvm) 2178*d71ae5a4SJacob Faibussowitsch { 2179c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls; 2180c0ce001eSMatthew G. Knepley 2181c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2182c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 21834dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&ls)); 2184c0ce001eSMatthew G. Knepley fvm->data = ls; 2185c0ce001eSMatthew G. Knepley 2186c0ce001eSMatthew G. Knepley ls->maxFaces = -1; 2187c0ce001eSMatthew G. Knepley ls->workSize = -1; 2188c0ce001eSMatthew G. Knepley ls->B = NULL; 2189c0ce001eSMatthew G. Knepley ls->Binv = NULL; 2190c0ce001eSMatthew G. Knepley ls->tau = NULL; 2191c0ce001eSMatthew G. Knepley ls->work = NULL; 2192c0ce001eSMatthew G. Knepley 21939566063dSJacob Faibussowitsch PetscCall(PetscFVSetComputeGradients(fvm, PETSC_TRUE)); 21949566063dSJacob Faibussowitsch PetscCall(PetscFVInitialize_LeastSquares(fvm)); 21959566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fvm, "PetscFVLeastSquaresSetMaxFaces_C", PetscFVLeastSquaresSetMaxFaces_LS)); 2196c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2197c0ce001eSMatthew G. Knepley } 2198c0ce001eSMatthew G. Knepley 2199c0ce001eSMatthew G. Knepley /*@ 2200c0ce001eSMatthew G. Knepley PetscFVLeastSquaresSetMaxFaces - Set the maximum number of cell faces for gradient reconstruction 2201c0ce001eSMatthew G. Knepley 2202c0ce001eSMatthew G. Knepley Not collective 2203c0ce001eSMatthew G. Knepley 2204c0ce001eSMatthew G. Knepley Input parameters: 2205c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 2206c0ce001eSMatthew G. Knepley - maxFaces - The maximum number of cell faces 2207c0ce001eSMatthew G. Knepley 2208c0ce001eSMatthew G. Knepley Level: intermediate 2209c0ce001eSMatthew G. Knepley 2210db781477SPatrick Sanan .seealso: `PetscFVCreate()`, `PETSCFVLEASTSQUARES` 2211c0ce001eSMatthew G. Knepley @*/ 2212*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVLeastSquaresSetMaxFaces(PetscFV fvm, PetscInt maxFaces) 2213*d71ae5a4SJacob Faibussowitsch { 2214c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2215c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 2216cac4c232SBarry Smith PetscTryMethod(fvm, "PetscFVLeastSquaresSetMaxFaces_C", (PetscFV, PetscInt), (fvm, maxFaces)); 2217c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2218c0ce001eSMatthew G. Knepley } 2219