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 20*dce8aebaSBarry Smith 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 Sample usage: 29c0ce001eSMatthew G. Knepley .vb 30c0ce001eSMatthew G. Knepley PetscLimiterRegister("my_lim", MyPetscLimiterCreate); 31c0ce001eSMatthew G. Knepley .ve 32c0ce001eSMatthew G. Knepley 33*dce8aebaSBarry Smith Then, your `PetscLimiter` type can be chosen with the procedural interface via 34c0ce001eSMatthew G. Knepley .vb 35c0ce001eSMatthew G. Knepley PetscLimiterCreate(MPI_Comm, PetscLimiter *); 36c0ce001eSMatthew G. Knepley PetscLimiterSetType(PetscLimiter, "my_lim"); 37c0ce001eSMatthew G. Knepley .ve 38c0ce001eSMatthew G. Knepley or at runtime via the option 39c0ce001eSMatthew G. Knepley .vb 40c0ce001eSMatthew G. Knepley -petsclimiter_type my_lim 41c0ce001eSMatthew G. Knepley .ve 42c0ce001eSMatthew G. Knepley 43c0ce001eSMatthew G. Knepley Level: advanced 44c0ce001eSMatthew G. Knepley 45*dce8aebaSBarry Smith Note: 46*dce8aebaSBarry Smith `PetscLimiterRegister()` may be called multiple times to add several user-defined PetscLimiters 47c0ce001eSMatthew G. Knepley 48*dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterRegisterAll()`, `PetscLimiterRegisterDestroy()` 49c0ce001eSMatthew G. Knepley @*/ 50d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterRegister(const char sname[], PetscErrorCode (*function)(PetscLimiter)) 51d71ae5a4SJacob Faibussowitsch { 52c0ce001eSMatthew G. Knepley PetscFunctionBegin; 539566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&PetscLimiterList, sname, function)); 54c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 55c0ce001eSMatthew G. Knepley } 56c0ce001eSMatthew G. Knepley 57c0ce001eSMatthew G. Knepley /*@C 58*dce8aebaSBarry Smith PetscLimiterSetType - Builds a `PetscLimiter` for a given `PetscLimiterType` 59c0ce001eSMatthew G. Knepley 60c0ce001eSMatthew G. Knepley Collective on lim 61c0ce001eSMatthew G. Knepley 62c0ce001eSMatthew G. Knepley Input Parameters: 63*dce8aebaSBarry Smith + lim - The `PetscLimiter` object 64c0ce001eSMatthew G. Knepley - name - The kind of limiter 65c0ce001eSMatthew G. Knepley 66c0ce001eSMatthew G. Knepley Options Database Key: 67c0ce001eSMatthew G. Knepley . -petsclimiter_type <type> - Sets the PetscLimiter type; use -help for a list of available types 68c0ce001eSMatthew G. Knepley 69c0ce001eSMatthew G. Knepley Level: intermediate 70c0ce001eSMatthew G. Knepley 71*dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterGetType()`, `PetscLimiterCreate()` 72c0ce001eSMatthew G. Knepley @*/ 73d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterSetType(PetscLimiter lim, PetscLimiterType name) 74d71ae5a4SJacob Faibussowitsch { 75c0ce001eSMatthew G. Knepley PetscErrorCode (*r)(PetscLimiter); 76c0ce001eSMatthew G. Knepley PetscBool match; 77c0ce001eSMatthew G. Knepley 78c0ce001eSMatthew G. Knepley PetscFunctionBegin; 79c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 809566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)lim, name, &match)); 81c0ce001eSMatthew G. Knepley if (match) PetscFunctionReturn(0); 82c0ce001eSMatthew G. Knepley 839566063dSJacob Faibussowitsch PetscCall(PetscLimiterRegisterAll()); 849566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(PetscLimiterList, name, &r)); 8528b400f6SJacob Faibussowitsch PetscCheck(r, PetscObjectComm((PetscObject)lim), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscLimiter type: %s", name); 86c0ce001eSMatthew G. Knepley 87c0ce001eSMatthew G. Knepley if (lim->ops->destroy) { 88dbbe0bcdSBarry Smith PetscUseTypeMethod(lim, destroy); 89c0ce001eSMatthew G. Knepley lim->ops->destroy = NULL; 90c0ce001eSMatthew G. Knepley } 919566063dSJacob Faibussowitsch PetscCall((*r)(lim)); 929566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)lim, name)); 93c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 94c0ce001eSMatthew G. Knepley } 95c0ce001eSMatthew G. Knepley 96c0ce001eSMatthew G. Knepley /*@C 97*dce8aebaSBarry Smith PetscLimiterGetType - Gets the `PetscLimiterType` name (as a string) from the `PetscLimiter`. 98c0ce001eSMatthew G. Knepley 99c0ce001eSMatthew G. Knepley Not Collective 100c0ce001eSMatthew G. Knepley 101c0ce001eSMatthew G. Knepley Input Parameter: 102*dce8aebaSBarry Smith . lim - The `PetscLimiter` 103c0ce001eSMatthew G. Knepley 104c0ce001eSMatthew G. Knepley Output Parameter: 105*dce8aebaSBarry Smith . name - The `PetscLimiterType` 106c0ce001eSMatthew G. Knepley 107c0ce001eSMatthew G. Knepley Level: intermediate 108c0ce001eSMatthew G. Knepley 109*dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterSetType()`, `PetscLimiterCreate()` 110c0ce001eSMatthew G. Knepley @*/ 111d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterGetType(PetscLimiter lim, PetscLimiterType *name) 112d71ae5a4SJacob Faibussowitsch { 113c0ce001eSMatthew G. Knepley PetscFunctionBegin; 114c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 115c0ce001eSMatthew G. Knepley PetscValidPointer(name, 2); 1169566063dSJacob Faibussowitsch PetscCall(PetscLimiterRegisterAll()); 117c0ce001eSMatthew G. Knepley *name = ((PetscObject)lim)->type_name; 118c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 119c0ce001eSMatthew G. Knepley } 120c0ce001eSMatthew G. Knepley 121c0ce001eSMatthew G. Knepley /*@C 122*dce8aebaSBarry Smith PetscLimiterViewFromOptions - View a `PetscLimiter` based on values in the options database 123fe2efc57SMark 124*dce8aebaSBarry Smith Collective on A 125fe2efc57SMark 126fe2efc57SMark Input Parameters: 127*dce8aebaSBarry Smith + A - the `PetscLimiter` object to view 128*dce8aebaSBarry Smith . obj - Optional object that provides the options prefix to use 129*dce8aebaSBarry Smith - name - command line option name 130fe2efc57SMark 131fe2efc57SMark Level: intermediate 132*dce8aebaSBarry Smith 133*dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterView()`, `PetscObjectViewFromOptions()`, `PetscLimiterCreate()` 134fe2efc57SMark @*/ 135d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterViewFromOptions(PetscLimiter A, PetscObject obj, const char name[]) 136d71ae5a4SJacob Faibussowitsch { 137fe2efc57SMark PetscFunctionBegin; 138fe2efc57SMark PetscValidHeaderSpecific(A, PETSCLIMITER_CLASSID, 1); 1399566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 140fe2efc57SMark PetscFunctionReturn(0); 141fe2efc57SMark } 142fe2efc57SMark 143fe2efc57SMark /*@C 144*dce8aebaSBarry Smith PetscLimiterView - Views a `PetscLimiter` 145c0ce001eSMatthew G. Knepley 146c0ce001eSMatthew G. Knepley Collective on lim 147c0ce001eSMatthew G. Knepley 148d8d19677SJose E. Roman Input Parameters: 149*dce8aebaSBarry Smith + lim - the `PetscLimiter` object to view 150c0ce001eSMatthew G. Knepley - v - the viewer 151c0ce001eSMatthew G. Knepley 15288f5f89eSMatthew G. Knepley Level: beginner 153c0ce001eSMatthew G. Knepley 154*dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscViewer`, `PetscLimiterDestroy()`, `PetscLimiterViewFromOptions()` 155c0ce001eSMatthew G. Knepley @*/ 156d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterView(PetscLimiter lim, PetscViewer v) 157d71ae5a4SJacob 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 /*@ 166*dce8aebaSBarry Smith 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: 171*dce8aebaSBarry Smith . lim - the `PetscLimiter` object to set options for 172c0ce001eSMatthew G. Knepley 17388f5f89eSMatthew G. Knepley Level: intermediate 174c0ce001eSMatthew G. Knepley 175*dce8aebaSBarry Smith .seealso: `PetscLimiter`, ``PetscLimiterView()` 176c0ce001eSMatthew G. Knepley @*/ 177d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterSetFromOptions(PetscLimiter lim) 178d71ae5a4SJacob 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 205*dce8aebaSBarry Smith PetscLimiterSetUp - Construct data structures for the `PetscLimiter` 206c0ce001eSMatthew G. Knepley 207c0ce001eSMatthew G. Knepley Collective on lim 208c0ce001eSMatthew G. Knepley 209c0ce001eSMatthew G. Knepley Input Parameter: 210*dce8aebaSBarry Smith . lim - the `PetscLimiter` object to setup 211c0ce001eSMatthew G. Knepley 21288f5f89eSMatthew G. Knepley Level: intermediate 213c0ce001eSMatthew G. Knepley 214*dce8aebaSBarry Smith .seealso: `PetscLimiter`, ``PetscLimiterView()`, `PetscLimiterDestroy()` 215c0ce001eSMatthew G. Knepley @*/ 216d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterSetUp(PetscLimiter lim) 217d71ae5a4SJacob 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 /*@ 225*dce8aebaSBarry Smith PetscLimiterDestroy - Destroys a `PetscLimiter` object 226c0ce001eSMatthew G. Knepley 227c0ce001eSMatthew G. Knepley Collective on lim 228c0ce001eSMatthew G. Knepley 229c0ce001eSMatthew G. Knepley Input Parameter: 230*dce8aebaSBarry Smith . lim - the `PetscLimiter` object to destroy 231c0ce001eSMatthew G. Knepley 23288f5f89eSMatthew G. Knepley Level: beginner 233c0ce001eSMatthew G. Knepley 234*dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterView()` 235c0ce001eSMatthew G. Knepley @*/ 236d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterDestroy(PetscLimiter *lim) 237d71ae5a4SJacob 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 /*@ 254*dce8aebaSBarry Smith 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: 259*dce8aebaSBarry Smith . comm - The communicator for the `PetscLimiter` object 260c0ce001eSMatthew G. Knepley 261c0ce001eSMatthew G. Knepley Output Parameter: 262*dce8aebaSBarry Smith . lim - The `PetscLimiter` object 263c0ce001eSMatthew G. Knepley 264c0ce001eSMatthew G. Knepley Level: beginner 265c0ce001eSMatthew G. Knepley 266*dce8aebaSBarry Smith .seealso: `PetscLimiter`, PetscLimiterType`, `PetscLimiterSetType()`, `PETSCLIMITERSIN` 267c0ce001eSMatthew G. Knepley @*/ 268d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterCreate(MPI_Comm comm, PetscLimiter *lim) 269d71ae5a4SJacob 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: 288*dce8aebaSBarry Smith + 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 Level: beginner 29588f5f89eSMatthew G. Knepley 296*dce8aebaSBarry Smith Note: 297*dce8aebaSBarry Smith Limiters given in symmetric form following Berger, Aftosmis, and Murman 2005 298*dce8aebaSBarry Smith .vb 299*dce8aebaSBarry Smith The classical flux-limited formulation is psi(r) where 300*dce8aebaSBarry Smith 301*dce8aebaSBarry Smith r = (u[0] - u[-1]) / (u[1] - u[0]) 302*dce8aebaSBarry Smith 303*dce8aebaSBarry Smith The second order TVD region is bounded by 304*dce8aebaSBarry Smith 305*dce8aebaSBarry Smith psi_minmod(r) = min(r,1) and psi_superbee(r) = min(2, 2r, max(1,r)) 306*dce8aebaSBarry Smith 307*dce8aebaSBarry Smith where all limiters are implicitly clipped to be non-negative. A more convenient slope-limited form is psi(r) = 308*dce8aebaSBarry Smith phi(r)(r+1)/2 in which the reconstructed interface values are 309*dce8aebaSBarry Smith 310*dce8aebaSBarry Smith u(v) = u[0] + phi(r) (grad u)[0] v 311*dce8aebaSBarry Smith 312*dce8aebaSBarry Smith where v is the vector from centroid to quadrature point. In these variables, the usual limiters become 313*dce8aebaSBarry Smith 314*dce8aebaSBarry Smith 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)) 315*dce8aebaSBarry Smith 316*dce8aebaSBarry Smith For a nicer symmetric formulation, rewrite in terms of 317*dce8aebaSBarry Smith 318*dce8aebaSBarry Smith f = (u[0] - u[-1]) / (u[1] - u[-1]) 319*dce8aebaSBarry Smith 320*dce8aebaSBarry Smith where r(f) = f/(1-f). Not that r(1-f) = (1-f)/f = 1/r(f) so the symmetry condition 321*dce8aebaSBarry Smith 322*dce8aebaSBarry Smith phi(r) = phi(1/r) 323*dce8aebaSBarry Smith 324*dce8aebaSBarry Smith becomes 325*dce8aebaSBarry Smith 326*dce8aebaSBarry Smith w(f) = w(1-f). 327*dce8aebaSBarry Smith 328*dce8aebaSBarry Smith The limiters below implement this final form w(f). The reference methods are 329*dce8aebaSBarry Smith 330*dce8aebaSBarry Smith w_minmod(f) = 2 min(f,(1-f)) w_superbee(r) = 4 min((1-f), f) 331*dce8aebaSBarry Smith .ve 332*dce8aebaSBarry Smith 333*dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterSetType()`, `PetscLimiterCreate()` 33488f5f89eSMatthew G. Knepley @*/ 335d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterLimit(PetscLimiter lim, PetscReal flim, PetscReal *phi) 336d71ae5a4SJacob Faibussowitsch { 337c0ce001eSMatthew G. Knepley PetscFunctionBegin; 338c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 339dadcf809SJacob Faibussowitsch PetscValidRealPointer(phi, 3); 340dbbe0bcdSBarry Smith PetscUseTypeMethod(lim, limit, flim, phi); 341c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 342c0ce001eSMatthew G. Knepley } 343c0ce001eSMatthew G. Knepley 344d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_Sin(PetscLimiter lim) 345d71ae5a4SJacob Faibussowitsch { 346c0ce001eSMatthew G. Knepley PetscLimiter_Sin *l = (PetscLimiter_Sin *)lim->data; 347c0ce001eSMatthew G. Knepley 348c0ce001eSMatthew G. Knepley PetscFunctionBegin; 3499566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 350c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 351c0ce001eSMatthew G. Knepley } 352c0ce001eSMatthew G. Knepley 353d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Sin_Ascii(PetscLimiter lim, PetscViewer viewer) 354d71ae5a4SJacob Faibussowitsch { 355c0ce001eSMatthew G. Knepley PetscViewerFormat format; 356c0ce001eSMatthew G. Knepley 357c0ce001eSMatthew G. Knepley PetscFunctionBegin; 3589566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 3599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Sin Slope Limiter:\n")); 360c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 361c0ce001eSMatthew G. Knepley } 362c0ce001eSMatthew G. Knepley 363d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Sin(PetscLimiter lim, PetscViewer viewer) 364d71ae5a4SJacob Faibussowitsch { 365c0ce001eSMatthew G. Knepley PetscBool iascii; 366c0ce001eSMatthew G. Knepley 367c0ce001eSMatthew G. Knepley PetscFunctionBegin; 368c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 369c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 3709566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 3719566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_Sin_Ascii(lim, viewer)); 372c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 373c0ce001eSMatthew G. Knepley } 374c0ce001eSMatthew G. Knepley 375d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_Sin(PetscLimiter lim, PetscReal f, PetscReal *phi) 376d71ae5a4SJacob Faibussowitsch { 377c0ce001eSMatthew G. Knepley PetscFunctionBegin; 378c0ce001eSMatthew G. Knepley *phi = PetscSinReal(PETSC_PI * PetscMax(0, PetscMin(f, 1))); 379c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 380c0ce001eSMatthew G. Knepley } 381c0ce001eSMatthew G. Knepley 382d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_Sin(PetscLimiter lim) 383d71ae5a4SJacob Faibussowitsch { 384c0ce001eSMatthew G. Knepley PetscFunctionBegin; 385c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Sin; 386c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Sin; 387c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Sin; 388c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 389c0ce001eSMatthew G. Knepley } 390c0ce001eSMatthew G. Knepley 391c0ce001eSMatthew G. Knepley /*MC 392*dce8aebaSBarry Smith PETSCLIMITERSIN = "sin" - A `PetscLimiter` implementation 393c0ce001eSMatthew G. Knepley 394c0ce001eSMatthew G. Knepley Level: intermediate 395c0ce001eSMatthew G. Knepley 396*dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 397c0ce001eSMatthew G. Knepley M*/ 398c0ce001eSMatthew G. Knepley 399d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Sin(PetscLimiter lim) 400d71ae5a4SJacob Faibussowitsch { 401c0ce001eSMatthew G. Knepley PetscLimiter_Sin *l; 402c0ce001eSMatthew G. Knepley 403c0ce001eSMatthew G. Knepley PetscFunctionBegin; 404c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 4054dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 406c0ce001eSMatthew G. Knepley lim->data = l; 407c0ce001eSMatthew G. Knepley 4089566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_Sin(lim)); 409c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 410c0ce001eSMatthew G. Knepley } 411c0ce001eSMatthew G. Knepley 412d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_Zero(PetscLimiter lim) 413d71ae5a4SJacob Faibussowitsch { 414c0ce001eSMatthew G. Knepley PetscLimiter_Zero *l = (PetscLimiter_Zero *)lim->data; 415c0ce001eSMatthew G. Knepley 416c0ce001eSMatthew G. Knepley PetscFunctionBegin; 4179566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 418c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 419c0ce001eSMatthew G. Knepley } 420c0ce001eSMatthew G. Knepley 421d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Zero_Ascii(PetscLimiter lim, PetscViewer viewer) 422d71ae5a4SJacob Faibussowitsch { 423c0ce001eSMatthew G. Knepley PetscViewerFormat format; 424c0ce001eSMatthew G. Knepley 425c0ce001eSMatthew G. Knepley PetscFunctionBegin; 4269566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 4279566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Zero Slope Limiter:\n")); 428c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 429c0ce001eSMatthew G. Knepley } 430c0ce001eSMatthew G. Knepley 431d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Zero(PetscLimiter lim, PetscViewer viewer) 432d71ae5a4SJacob Faibussowitsch { 433c0ce001eSMatthew G. Knepley PetscBool iascii; 434c0ce001eSMatthew G. Knepley 435c0ce001eSMatthew G. Knepley PetscFunctionBegin; 436c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 437c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 4389566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 4399566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_Zero_Ascii(lim, viewer)); 440c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 441c0ce001eSMatthew G. Knepley } 442c0ce001eSMatthew G. Knepley 443d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_Zero(PetscLimiter lim, PetscReal f, PetscReal *phi) 444d71ae5a4SJacob Faibussowitsch { 445c0ce001eSMatthew G. Knepley PetscFunctionBegin; 446c0ce001eSMatthew G. Knepley *phi = 0.0; 447c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 448c0ce001eSMatthew G. Knepley } 449c0ce001eSMatthew G. Knepley 450d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_Zero(PetscLimiter lim) 451d71ae5a4SJacob Faibussowitsch { 452c0ce001eSMatthew G. Knepley PetscFunctionBegin; 453c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Zero; 454c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Zero; 455c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Zero; 456c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 457c0ce001eSMatthew G. Knepley } 458c0ce001eSMatthew G. Knepley 459c0ce001eSMatthew G. Knepley /*MC 460*dce8aebaSBarry Smith PETSCLIMITERZERO = "zero" - A simple `PetscLimiter` implementation 461c0ce001eSMatthew G. Knepley 462c0ce001eSMatthew G. Knepley Level: intermediate 463c0ce001eSMatthew G. Knepley 464*dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 465c0ce001eSMatthew G. Knepley M*/ 466c0ce001eSMatthew G. Knepley 467d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Zero(PetscLimiter lim) 468d71ae5a4SJacob Faibussowitsch { 469c0ce001eSMatthew G. Knepley PetscLimiter_Zero *l; 470c0ce001eSMatthew G. Knepley 471c0ce001eSMatthew G. Knepley PetscFunctionBegin; 472c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 4734dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 474c0ce001eSMatthew G. Knepley lim->data = l; 475c0ce001eSMatthew G. Knepley 4769566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_Zero(lim)); 477c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 478c0ce001eSMatthew G. Knepley } 479c0ce001eSMatthew G. Knepley 480d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_None(PetscLimiter lim) 481d71ae5a4SJacob Faibussowitsch { 482c0ce001eSMatthew G. Knepley PetscLimiter_None *l = (PetscLimiter_None *)lim->data; 483c0ce001eSMatthew G. Knepley 484c0ce001eSMatthew G. Knepley PetscFunctionBegin; 4859566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 486c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 487c0ce001eSMatthew G. Knepley } 488c0ce001eSMatthew G. Knepley 489d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_None_Ascii(PetscLimiter lim, PetscViewer viewer) 490d71ae5a4SJacob Faibussowitsch { 491c0ce001eSMatthew G. Knepley PetscViewerFormat format; 492c0ce001eSMatthew G. Knepley 493c0ce001eSMatthew G. Knepley PetscFunctionBegin; 4949566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 4959566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "None Slope Limiter:\n")); 496c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 497c0ce001eSMatthew G. Knepley } 498c0ce001eSMatthew G. Knepley 499d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_None(PetscLimiter lim, PetscViewer viewer) 500d71ae5a4SJacob Faibussowitsch { 501c0ce001eSMatthew G. Knepley PetscBool iascii; 502c0ce001eSMatthew G. Knepley 503c0ce001eSMatthew G. Knepley PetscFunctionBegin; 504c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 505c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 5069566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 5079566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_None_Ascii(lim, viewer)); 508c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 509c0ce001eSMatthew G. Knepley } 510c0ce001eSMatthew G. Knepley 511d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_None(PetscLimiter lim, PetscReal f, PetscReal *phi) 512d71ae5a4SJacob Faibussowitsch { 513c0ce001eSMatthew G. Knepley PetscFunctionBegin; 514c0ce001eSMatthew G. Knepley *phi = 1.0; 515c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 516c0ce001eSMatthew G. Knepley } 517c0ce001eSMatthew G. Knepley 518d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_None(PetscLimiter lim) 519d71ae5a4SJacob Faibussowitsch { 520c0ce001eSMatthew G. Knepley PetscFunctionBegin; 521c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_None; 522c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_None; 523c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_None; 524c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 525c0ce001eSMatthew G. Knepley } 526c0ce001eSMatthew G. Knepley 527c0ce001eSMatthew G. Knepley /*MC 528*dce8aebaSBarry Smith PETSCLIMITERNONE = "none" - A trivial `PetscLimiter` implementation 529c0ce001eSMatthew G. Knepley 530c0ce001eSMatthew G. Knepley Level: intermediate 531c0ce001eSMatthew G. Knepley 532*dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 533c0ce001eSMatthew G. Knepley M*/ 534c0ce001eSMatthew G. Knepley 535d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_None(PetscLimiter lim) 536d71ae5a4SJacob Faibussowitsch { 537c0ce001eSMatthew G. Knepley PetscLimiter_None *l; 538c0ce001eSMatthew G. Knepley 539c0ce001eSMatthew G. Knepley PetscFunctionBegin; 540c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 5414dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 542c0ce001eSMatthew G. Knepley lim->data = l; 543c0ce001eSMatthew G. Knepley 5449566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_None(lim)); 545c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 546c0ce001eSMatthew G. Knepley } 547c0ce001eSMatthew G. Knepley 548d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_Minmod(PetscLimiter lim) 549d71ae5a4SJacob Faibussowitsch { 550c0ce001eSMatthew G. Knepley PetscLimiter_Minmod *l = (PetscLimiter_Minmod *)lim->data; 551c0ce001eSMatthew G. Knepley 552c0ce001eSMatthew G. Knepley PetscFunctionBegin; 5539566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 554c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 555c0ce001eSMatthew G. Knepley } 556c0ce001eSMatthew G. Knepley 557d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Minmod_Ascii(PetscLimiter lim, PetscViewer viewer) 558d71ae5a4SJacob Faibussowitsch { 559c0ce001eSMatthew G. Knepley PetscViewerFormat format; 560c0ce001eSMatthew G. Knepley 561c0ce001eSMatthew G. Knepley PetscFunctionBegin; 5629566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 5639566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Minmod Slope Limiter:\n")); 564c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 565c0ce001eSMatthew G. Knepley } 566c0ce001eSMatthew G. Knepley 567d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Minmod(PetscLimiter lim, PetscViewer viewer) 568d71ae5a4SJacob Faibussowitsch { 569c0ce001eSMatthew G. Knepley PetscBool iascii; 570c0ce001eSMatthew G. Knepley 571c0ce001eSMatthew G. Knepley PetscFunctionBegin; 572c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 573c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 5749566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 5759566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_Minmod_Ascii(lim, viewer)); 576c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 577c0ce001eSMatthew G. Knepley } 578c0ce001eSMatthew G. Knepley 579d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_Minmod(PetscLimiter lim, PetscReal f, PetscReal *phi) 580d71ae5a4SJacob Faibussowitsch { 581c0ce001eSMatthew G. Knepley PetscFunctionBegin; 582c0ce001eSMatthew G. Knepley *phi = 2 * PetscMax(0, PetscMin(f, 1 - f)); 583c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 584c0ce001eSMatthew G. Knepley } 585c0ce001eSMatthew G. Knepley 586d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_Minmod(PetscLimiter lim) 587d71ae5a4SJacob Faibussowitsch { 588c0ce001eSMatthew G. Knepley PetscFunctionBegin; 589c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Minmod; 590c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Minmod; 591c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Minmod; 592c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 593c0ce001eSMatthew G. Knepley } 594c0ce001eSMatthew G. Knepley 595c0ce001eSMatthew G. Knepley /*MC 596*dce8aebaSBarry Smith PETSCLIMITERMINMOD = "minmod" - A `PetscLimiter` implementation 597c0ce001eSMatthew G. Knepley 598c0ce001eSMatthew G. Knepley Level: intermediate 599c0ce001eSMatthew G. Knepley 600*dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 601c0ce001eSMatthew G. Knepley M*/ 602c0ce001eSMatthew G. Knepley 603d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Minmod(PetscLimiter lim) 604d71ae5a4SJacob Faibussowitsch { 605c0ce001eSMatthew G. Knepley PetscLimiter_Minmod *l; 606c0ce001eSMatthew G. Knepley 607c0ce001eSMatthew G. Knepley PetscFunctionBegin; 608c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 6094dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 610c0ce001eSMatthew G. Knepley lim->data = l; 611c0ce001eSMatthew G. Knepley 6129566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_Minmod(lim)); 613c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 614c0ce001eSMatthew G. Knepley } 615c0ce001eSMatthew G. Knepley 616d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_VanLeer(PetscLimiter lim) 617d71ae5a4SJacob Faibussowitsch { 618c0ce001eSMatthew G. Knepley PetscLimiter_VanLeer *l = (PetscLimiter_VanLeer *)lim->data; 619c0ce001eSMatthew G. Knepley 620c0ce001eSMatthew G. Knepley PetscFunctionBegin; 6219566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 622c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 623c0ce001eSMatthew G. Knepley } 624c0ce001eSMatthew G. Knepley 625d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_VanLeer_Ascii(PetscLimiter lim, PetscViewer viewer) 626d71ae5a4SJacob Faibussowitsch { 627c0ce001eSMatthew G. Knepley PetscViewerFormat format; 628c0ce001eSMatthew G. Knepley 629c0ce001eSMatthew G. Knepley PetscFunctionBegin; 6309566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 6319566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Van Leer Slope Limiter:\n")); 632c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 633c0ce001eSMatthew G. Knepley } 634c0ce001eSMatthew G. Knepley 635d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_VanLeer(PetscLimiter lim, PetscViewer viewer) 636d71ae5a4SJacob Faibussowitsch { 637c0ce001eSMatthew G. Knepley PetscBool iascii; 638c0ce001eSMatthew G. Knepley 639c0ce001eSMatthew G. Knepley PetscFunctionBegin; 640c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 641c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 6429566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 6439566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_VanLeer_Ascii(lim, viewer)); 644c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 645c0ce001eSMatthew G. Knepley } 646c0ce001eSMatthew G. Knepley 647d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_VanLeer(PetscLimiter lim, PetscReal f, PetscReal *phi) 648d71ae5a4SJacob Faibussowitsch { 649c0ce001eSMatthew G. Knepley PetscFunctionBegin; 650c0ce001eSMatthew G. Knepley *phi = PetscMax(0, 4 * f * (1 - f)); 651c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 652c0ce001eSMatthew G. Knepley } 653c0ce001eSMatthew G. Knepley 654d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_VanLeer(PetscLimiter lim) 655d71ae5a4SJacob Faibussowitsch { 656c0ce001eSMatthew G. Knepley PetscFunctionBegin; 657c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_VanLeer; 658c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_VanLeer; 659c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_VanLeer; 660c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 661c0ce001eSMatthew G. Knepley } 662c0ce001eSMatthew G. Knepley 663c0ce001eSMatthew G. Knepley /*MC 664*dce8aebaSBarry Smith PETSCLIMITERVANLEER = "vanleer" - A `PetscLimiter` implementation 665c0ce001eSMatthew G. Knepley 666c0ce001eSMatthew G. Knepley Level: intermediate 667c0ce001eSMatthew G. Knepley 668*dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 669c0ce001eSMatthew G. Knepley M*/ 670c0ce001eSMatthew G. Knepley 671d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanLeer(PetscLimiter lim) 672d71ae5a4SJacob Faibussowitsch { 673c0ce001eSMatthew G. Knepley PetscLimiter_VanLeer *l; 674c0ce001eSMatthew G. Knepley 675c0ce001eSMatthew G. Knepley PetscFunctionBegin; 676c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 6774dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 678c0ce001eSMatthew G. Knepley lim->data = l; 679c0ce001eSMatthew G. Knepley 6809566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_VanLeer(lim)); 681c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 682c0ce001eSMatthew G. Knepley } 683c0ce001eSMatthew G. Knepley 684d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_VanAlbada(PetscLimiter lim) 685d71ae5a4SJacob Faibussowitsch { 686c0ce001eSMatthew G. Knepley PetscLimiter_VanAlbada *l = (PetscLimiter_VanAlbada *)lim->data; 687c0ce001eSMatthew G. Knepley 688c0ce001eSMatthew G. Knepley PetscFunctionBegin; 6899566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 690c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 691c0ce001eSMatthew G. Knepley } 692c0ce001eSMatthew G. Knepley 693d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_VanAlbada_Ascii(PetscLimiter lim, PetscViewer viewer) 694d71ae5a4SJacob Faibussowitsch { 695c0ce001eSMatthew G. Knepley PetscViewerFormat format; 696c0ce001eSMatthew G. Knepley 697c0ce001eSMatthew G. Knepley PetscFunctionBegin; 6989566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 6999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Van Albada Slope Limiter:\n")); 700c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 701c0ce001eSMatthew G. Knepley } 702c0ce001eSMatthew G. Knepley 703d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_VanAlbada(PetscLimiter lim, PetscViewer viewer) 704d71ae5a4SJacob Faibussowitsch { 705c0ce001eSMatthew G. Knepley PetscBool iascii; 706c0ce001eSMatthew G. Knepley 707c0ce001eSMatthew G. Knepley PetscFunctionBegin; 708c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 709c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 7109566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 7119566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_VanAlbada_Ascii(lim, viewer)); 712c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 713c0ce001eSMatthew G. Knepley } 714c0ce001eSMatthew G. Knepley 715d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_VanAlbada(PetscLimiter lim, PetscReal f, PetscReal *phi) 716d71ae5a4SJacob Faibussowitsch { 717c0ce001eSMatthew G. Knepley PetscFunctionBegin; 718c0ce001eSMatthew G. Knepley *phi = PetscMax(0, 2 * f * (1 - f) / (PetscSqr(f) + PetscSqr(1 - f))); 719c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 720c0ce001eSMatthew G. Knepley } 721c0ce001eSMatthew G. Knepley 722d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_VanAlbada(PetscLimiter lim) 723d71ae5a4SJacob Faibussowitsch { 724c0ce001eSMatthew G. Knepley PetscFunctionBegin; 725c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_VanAlbada; 726c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_VanAlbada; 727c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_VanAlbada; 728c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 729c0ce001eSMatthew G. Knepley } 730c0ce001eSMatthew G. Knepley 731c0ce001eSMatthew G. Knepley /*MC 732*dce8aebaSBarry Smith PETSCLIMITERVANALBADA = "vanalbada" - A PetscLimiter implementation 733c0ce001eSMatthew G. Knepley 734c0ce001eSMatthew G. Knepley Level: intermediate 735c0ce001eSMatthew G. Knepley 736*dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 737c0ce001eSMatthew G. Knepley M*/ 738c0ce001eSMatthew G. Knepley 739d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanAlbada(PetscLimiter lim) 740d71ae5a4SJacob Faibussowitsch { 741c0ce001eSMatthew G. Knepley PetscLimiter_VanAlbada *l; 742c0ce001eSMatthew G. Knepley 743c0ce001eSMatthew G. Knepley PetscFunctionBegin; 744c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 7454dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 746c0ce001eSMatthew G. Knepley lim->data = l; 747c0ce001eSMatthew G. Knepley 7489566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_VanAlbada(lim)); 749c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 750c0ce001eSMatthew G. Knepley } 751c0ce001eSMatthew G. Knepley 752d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_Superbee(PetscLimiter lim) 753d71ae5a4SJacob Faibussowitsch { 754c0ce001eSMatthew G. Knepley PetscLimiter_Superbee *l = (PetscLimiter_Superbee *)lim->data; 755c0ce001eSMatthew G. Knepley 756c0ce001eSMatthew G. Knepley PetscFunctionBegin; 7579566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 758c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 759c0ce001eSMatthew G. Knepley } 760c0ce001eSMatthew G. Knepley 761d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Superbee_Ascii(PetscLimiter lim, PetscViewer viewer) 762d71ae5a4SJacob Faibussowitsch { 763c0ce001eSMatthew G. Knepley PetscViewerFormat format; 764c0ce001eSMatthew G. Knepley 765c0ce001eSMatthew G. Knepley PetscFunctionBegin; 7669566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 7679566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Superbee Slope Limiter:\n")); 768c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 769c0ce001eSMatthew G. Knepley } 770c0ce001eSMatthew G. Knepley 771d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Superbee(PetscLimiter lim, PetscViewer viewer) 772d71ae5a4SJacob Faibussowitsch { 773c0ce001eSMatthew G. Knepley PetscBool iascii; 774c0ce001eSMatthew G. Knepley 775c0ce001eSMatthew G. Knepley PetscFunctionBegin; 776c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 777c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 7789566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 7799566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_Superbee_Ascii(lim, viewer)); 780c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 781c0ce001eSMatthew G. Knepley } 782c0ce001eSMatthew G. Knepley 783d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_Superbee(PetscLimiter lim, PetscReal f, PetscReal *phi) 784d71ae5a4SJacob Faibussowitsch { 785c0ce001eSMatthew G. Knepley PetscFunctionBegin; 786c0ce001eSMatthew G. Knepley *phi = 4 * PetscMax(0, PetscMin(f, 1 - f)); 787c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 788c0ce001eSMatthew G. Knepley } 789c0ce001eSMatthew G. Knepley 790d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_Superbee(PetscLimiter lim) 791d71ae5a4SJacob Faibussowitsch { 792c0ce001eSMatthew G. Knepley PetscFunctionBegin; 793c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Superbee; 794c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Superbee; 795c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Superbee; 796c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 797c0ce001eSMatthew G. Knepley } 798c0ce001eSMatthew G. Knepley 799c0ce001eSMatthew G. Knepley /*MC 800*dce8aebaSBarry Smith PETSCLIMITERSUPERBEE = "superbee" - A `PetscLimiter` implementation 801c0ce001eSMatthew G. Knepley 802c0ce001eSMatthew G. Knepley Level: intermediate 803c0ce001eSMatthew G. Knepley 804*dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 805c0ce001eSMatthew G. Knepley M*/ 806c0ce001eSMatthew G. Knepley 807d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Superbee(PetscLimiter lim) 808d71ae5a4SJacob Faibussowitsch { 809c0ce001eSMatthew G. Knepley PetscLimiter_Superbee *l; 810c0ce001eSMatthew G. Knepley 811c0ce001eSMatthew G. Knepley PetscFunctionBegin; 812c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 8134dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 814c0ce001eSMatthew G. Knepley lim->data = l; 815c0ce001eSMatthew G. Knepley 8169566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_Superbee(lim)); 817c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 818c0ce001eSMatthew G. Knepley } 819c0ce001eSMatthew G. Knepley 820d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_MC(PetscLimiter lim) 821d71ae5a4SJacob Faibussowitsch { 822c0ce001eSMatthew G. Knepley PetscLimiter_MC *l = (PetscLimiter_MC *)lim->data; 823c0ce001eSMatthew G. Knepley 824c0ce001eSMatthew G. Knepley PetscFunctionBegin; 8259566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 826c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 827c0ce001eSMatthew G. Knepley } 828c0ce001eSMatthew G. Knepley 829d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_MC_Ascii(PetscLimiter lim, PetscViewer viewer) 830d71ae5a4SJacob Faibussowitsch { 831c0ce001eSMatthew G. Knepley PetscViewerFormat format; 832c0ce001eSMatthew G. Knepley 833c0ce001eSMatthew G. Knepley PetscFunctionBegin; 8349566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 8359566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "MC Slope Limiter:\n")); 836c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 837c0ce001eSMatthew G. Knepley } 838c0ce001eSMatthew G. Knepley 839d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_MC(PetscLimiter lim, PetscViewer viewer) 840d71ae5a4SJacob Faibussowitsch { 841c0ce001eSMatthew G. Knepley PetscBool iascii; 842c0ce001eSMatthew G. Knepley 843c0ce001eSMatthew G. Knepley PetscFunctionBegin; 844c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 845c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 8469566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 8479566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_MC_Ascii(lim, viewer)); 848c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 849c0ce001eSMatthew G. Knepley } 850c0ce001eSMatthew G. Knepley 851c0ce001eSMatthew G. Knepley /* aka Barth-Jespersen */ 852d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_MC(PetscLimiter lim, PetscReal f, PetscReal *phi) 853d71ae5a4SJacob Faibussowitsch { 854c0ce001eSMatthew G. Knepley PetscFunctionBegin; 855c0ce001eSMatthew G. Knepley *phi = PetscMin(1, 4 * PetscMax(0, PetscMin(f, 1 - f))); 856c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 857c0ce001eSMatthew G. Knepley } 858c0ce001eSMatthew G. Knepley 859d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_MC(PetscLimiter lim) 860d71ae5a4SJacob Faibussowitsch { 861c0ce001eSMatthew G. Knepley PetscFunctionBegin; 862c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_MC; 863c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_MC; 864c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_MC; 865c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 866c0ce001eSMatthew G. Knepley } 867c0ce001eSMatthew G. Knepley 868c0ce001eSMatthew G. Knepley /*MC 869*dce8aebaSBarry Smith PETSCLIMITERMC = "mc" - A `PetscLimiter` implementation 870c0ce001eSMatthew G. Knepley 871c0ce001eSMatthew G. Knepley Level: intermediate 872c0ce001eSMatthew G. Knepley 873*dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 874c0ce001eSMatthew G. Knepley M*/ 875c0ce001eSMatthew G. Knepley 876d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_MC(PetscLimiter lim) 877d71ae5a4SJacob Faibussowitsch { 878c0ce001eSMatthew G. Knepley PetscLimiter_MC *l; 879c0ce001eSMatthew G. Knepley 880c0ce001eSMatthew G. Knepley PetscFunctionBegin; 881c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 8824dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 883c0ce001eSMatthew G. Knepley lim->data = l; 884c0ce001eSMatthew G. Knepley 8859566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_MC(lim)); 886c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 887c0ce001eSMatthew G. Knepley } 888c0ce001eSMatthew G. Knepley 889c0ce001eSMatthew G. Knepley PetscClassId PETSCFV_CLASSID = 0; 890c0ce001eSMatthew G. Knepley 891c0ce001eSMatthew G. Knepley PetscFunctionList PetscFVList = NULL; 892c0ce001eSMatthew G. Knepley PetscBool PetscFVRegisterAllCalled = PETSC_FALSE; 893c0ce001eSMatthew G. Knepley 894c0ce001eSMatthew G. Knepley /*@C 895*dce8aebaSBarry Smith PetscFVRegister - Adds a new `PetscFV` implementation 896c0ce001eSMatthew G. Knepley 897c0ce001eSMatthew G. Knepley Not Collective 898c0ce001eSMatthew G. Knepley 899c0ce001eSMatthew G. Knepley Input Parameters: 900c0ce001eSMatthew G. Knepley + name - The name of a new user-defined creation routine 901c0ce001eSMatthew G. Knepley - create_func - The creation routine itself 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 920*dce8aebaSBarry Smith Note: 921*dce8aebaSBarry Smith `PetscFVRegister()` may be called multiple times to add several user-defined PetscFVs 922c0ce001eSMatthew G. Knepley 923*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVRegisterAll()`, `PetscFVRegisterDestroy()` 924c0ce001eSMatthew G. Knepley @*/ 925d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVRegister(const char sname[], PetscErrorCode (*function)(PetscFV)) 926d71ae5a4SJacob Faibussowitsch { 927c0ce001eSMatthew G. Knepley PetscFunctionBegin; 9289566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&PetscFVList, sname, function)); 929c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 930c0ce001eSMatthew G. Knepley } 931c0ce001eSMatthew G. Knepley 932c0ce001eSMatthew G. Knepley /*@C 933*dce8aebaSBarry Smith PetscFVSetType - Builds a particular `PetscFV` 934c0ce001eSMatthew G. Knepley 935c0ce001eSMatthew G. Knepley Collective on fvm 936c0ce001eSMatthew G. Knepley 937c0ce001eSMatthew G. Knepley Input Parameters: 938*dce8aebaSBarry Smith + fvm - The `PetscFV` object 939*dce8aebaSBarry Smith - name - The type of FVM space 940c0ce001eSMatthew G. Knepley 941c0ce001eSMatthew G. Knepley Options Database Key: 942*dce8aebaSBarry Smith . -petscfv_type <type> - Sets the `PetscFVType`; use -help for a list of available types 943c0ce001eSMatthew G. Knepley 944c0ce001eSMatthew G. Knepley Level: intermediate 945c0ce001eSMatthew G. Knepley 946*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVGetType()`, `PetscFVCreate()` 947c0ce001eSMatthew G. Knepley @*/ 948d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetType(PetscFV fvm, PetscFVType name) 949d71ae5a4SJacob Faibussowitsch { 950c0ce001eSMatthew G. Knepley PetscErrorCode (*r)(PetscFV); 951c0ce001eSMatthew G. Knepley PetscBool match; 952c0ce001eSMatthew G. Knepley 953c0ce001eSMatthew G. Knepley PetscFunctionBegin; 954c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 9559566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)fvm, name, &match)); 956c0ce001eSMatthew G. Knepley if (match) PetscFunctionReturn(0); 957c0ce001eSMatthew G. Knepley 9589566063dSJacob Faibussowitsch PetscCall(PetscFVRegisterAll()); 9599566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(PetscFVList, name, &r)); 96028b400f6SJacob Faibussowitsch PetscCheck(r, PetscObjectComm((PetscObject)fvm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscFV type: %s", name); 961c0ce001eSMatthew G. Knepley 962dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, destroy); 963c0ce001eSMatthew G. Knepley fvm->ops->destroy = NULL; 964dbbe0bcdSBarry Smith 9659566063dSJacob Faibussowitsch PetscCall((*r)(fvm)); 9669566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)fvm, name)); 967c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 968c0ce001eSMatthew G. Knepley } 969c0ce001eSMatthew G. Knepley 970c0ce001eSMatthew G. Knepley /*@C 971*dce8aebaSBarry Smith PetscFVGetType - Gets the `PetscFVType` (as a string) from a `PetscFV`. 972c0ce001eSMatthew G. Knepley 973c0ce001eSMatthew G. Knepley Not Collective 974c0ce001eSMatthew G. Knepley 975c0ce001eSMatthew G. Knepley Input Parameter: 976*dce8aebaSBarry Smith . fvm - The `PetscFV` 977c0ce001eSMatthew G. Knepley 978c0ce001eSMatthew G. Knepley Output Parameter: 979*dce8aebaSBarry Smith . name - The `PetscFVType` name 980c0ce001eSMatthew G. Knepley 981c0ce001eSMatthew G. Knepley Level: intermediate 982c0ce001eSMatthew G. Knepley 983*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVSetType()`, `PetscFVCreate()` 984c0ce001eSMatthew G. Knepley @*/ 985d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetType(PetscFV fvm, PetscFVType *name) 986d71ae5a4SJacob Faibussowitsch { 987c0ce001eSMatthew G. Knepley PetscFunctionBegin; 988c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 989c0ce001eSMatthew G. Knepley PetscValidPointer(name, 2); 9909566063dSJacob Faibussowitsch PetscCall(PetscFVRegisterAll()); 991c0ce001eSMatthew G. Knepley *name = ((PetscObject)fvm)->type_name; 992c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 993c0ce001eSMatthew G. Knepley } 994c0ce001eSMatthew G. Knepley 995c0ce001eSMatthew G. Knepley /*@C 996*dce8aebaSBarry Smith PetscFVViewFromOptions - View a `PetscFV` based on values in the options database 997fe2efc57SMark 998*dce8aebaSBarry Smith Collective on A 999fe2efc57SMark 1000fe2efc57SMark Input Parameters: 1001*dce8aebaSBarry Smith + A - the `PetscFV` object 1002*dce8aebaSBarry Smith . obj - Optional object that provides the options prefix 1003*dce8aebaSBarry Smith - name - command line option name 1004fe2efc57SMark 1005fe2efc57SMark Level: intermediate 1006*dce8aebaSBarry Smith 1007*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVView()`, `PetscObjectViewFromOptions()`, `PetscFVCreate()` 1008fe2efc57SMark @*/ 1009d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVViewFromOptions(PetscFV A, PetscObject obj, const char name[]) 1010d71ae5a4SJacob Faibussowitsch { 1011fe2efc57SMark PetscFunctionBegin; 1012fe2efc57SMark PetscValidHeaderSpecific(A, PETSCFV_CLASSID, 1); 10139566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 1014fe2efc57SMark PetscFunctionReturn(0); 1015fe2efc57SMark } 1016fe2efc57SMark 1017fe2efc57SMark /*@C 1018*dce8aebaSBarry Smith PetscFVView - Views a `PetscFV` 1019c0ce001eSMatthew G. Knepley 1020c0ce001eSMatthew G. Knepley Collective on fvm 1021c0ce001eSMatthew G. Knepley 1022d8d19677SJose E. Roman Input Parameters: 1023*dce8aebaSBarry Smith + fvm - the `PetscFV` object to view 1024c0ce001eSMatthew G. Knepley - v - the viewer 1025c0ce001eSMatthew G. Knepley 102688f5f89eSMatthew G. Knepley Level: beginner 1027c0ce001eSMatthew G. Knepley 1028*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscViewer`, `PetscFVDestroy()` 1029c0ce001eSMatthew G. Knepley @*/ 1030d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVView(PetscFV fvm, PetscViewer v) 1031d71ae5a4SJacob Faibussowitsch { 1032c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1033c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 10349566063dSJacob Faibussowitsch if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)fvm), &v)); 1035dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, view, v); 1036c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1037c0ce001eSMatthew G. Knepley } 1038c0ce001eSMatthew G. Knepley 1039c0ce001eSMatthew G. Knepley /*@ 1040*dce8aebaSBarry Smith PetscFVSetFromOptions - sets parameters in a `PetscFV` from the options database 1041c0ce001eSMatthew G. Knepley 1042c0ce001eSMatthew G. Knepley Collective on fvm 1043c0ce001eSMatthew G. Knepley 1044c0ce001eSMatthew G. Knepley Input Parameter: 1045*dce8aebaSBarry Smith . fvm - the `PetscFV` object to set options for 1046c0ce001eSMatthew G. Knepley 1047c0ce001eSMatthew G. Knepley Options Database Key: 1048c0ce001eSMatthew G. Knepley . -petscfv_compute_gradients <bool> - Determines whether cell gradients are calculated 1049c0ce001eSMatthew G. Knepley 105088f5f89eSMatthew G. Knepley Level: intermediate 1051c0ce001eSMatthew G. Knepley 1052*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVView()` 1053c0ce001eSMatthew G. Knepley @*/ 1054d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetFromOptions(PetscFV fvm) 1055d71ae5a4SJacob Faibussowitsch { 1056c0ce001eSMatthew G. Knepley const char *defaultType; 1057c0ce001eSMatthew G. Knepley char name[256]; 1058c0ce001eSMatthew G. Knepley PetscBool flg; 1059c0ce001eSMatthew G. Knepley 1060c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1061c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1062c0ce001eSMatthew G. Knepley if (!((PetscObject)fvm)->type_name) defaultType = PETSCFVUPWIND; 1063c0ce001eSMatthew G. Knepley else defaultType = ((PetscObject)fvm)->type_name; 10649566063dSJacob Faibussowitsch PetscCall(PetscFVRegisterAll()); 1065c0ce001eSMatthew G. Knepley 1066d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)fvm); 10679566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-petscfv_type", "Finite volume discretization", "PetscFVSetType", PetscFVList, defaultType, name, 256, &flg)); 1068c0ce001eSMatthew G. Knepley if (flg) { 10699566063dSJacob Faibussowitsch PetscCall(PetscFVSetType(fvm, name)); 1070c0ce001eSMatthew G. Knepley } else if (!((PetscObject)fvm)->type_name) { 10719566063dSJacob Faibussowitsch PetscCall(PetscFVSetType(fvm, defaultType)); 1072c0ce001eSMatthew G. Knepley } 10739566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-petscfv_compute_gradients", "Compute cell gradients", "PetscFVSetComputeGradients", fvm->computeGradients, &fvm->computeGradients, NULL)); 1074dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, setfromoptions); 1075c0ce001eSMatthew G. Knepley /* process any options handlers added with PetscObjectAddOptionsHandler() */ 1076dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)fvm, PetscOptionsObject)); 10779566063dSJacob Faibussowitsch PetscCall(PetscLimiterSetFromOptions(fvm->limiter)); 1078d0609cedSBarry Smith PetscOptionsEnd(); 10799566063dSJacob Faibussowitsch PetscCall(PetscFVViewFromOptions(fvm, NULL, "-petscfv_view")); 1080c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1081c0ce001eSMatthew G. Knepley } 1082c0ce001eSMatthew G. Knepley 1083c0ce001eSMatthew G. Knepley /*@ 1084*dce8aebaSBarry Smith PetscFVSetUp - Setup the data structures for the `PetscFV` based on the `PetscFVType` provided by `PetscFVSetType()` 1085c0ce001eSMatthew G. Knepley 1086c0ce001eSMatthew G. Knepley Collective on fvm 1087c0ce001eSMatthew G. Knepley 1088c0ce001eSMatthew G. Knepley Input Parameter: 1089*dce8aebaSBarry Smith . fvm - the `PetscFV` object to setup 1090c0ce001eSMatthew G. Knepley 109188f5f89eSMatthew G. Knepley Level: intermediate 1092c0ce001eSMatthew G. Knepley 1093*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVView()`, `PetscFVDestroy()` 1094c0ce001eSMatthew G. Knepley @*/ 1095d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetUp(PetscFV fvm) 1096d71ae5a4SJacob Faibussowitsch { 1097c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1098c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 10999566063dSJacob Faibussowitsch PetscCall(PetscLimiterSetUp(fvm->limiter)); 1100dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, setup); 1101c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1102c0ce001eSMatthew G. Knepley } 1103c0ce001eSMatthew G. Knepley 1104c0ce001eSMatthew G. Knepley /*@ 1105*dce8aebaSBarry Smith PetscFVDestroy - Destroys a `PetscFV` object 1106c0ce001eSMatthew G. Knepley 1107c0ce001eSMatthew G. Knepley Collective on fvm 1108c0ce001eSMatthew G. Knepley 1109c0ce001eSMatthew G. Knepley Input Parameter: 1110*dce8aebaSBarry Smith . fvm - the `PetscFV` object to destroy 1111c0ce001eSMatthew G. Knepley 111288f5f89eSMatthew G. Knepley Level: beginner 1113c0ce001eSMatthew G. Knepley 1114*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVCreate()`, `PetscFVView()` 1115c0ce001eSMatthew G. Knepley @*/ 1116d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVDestroy(PetscFV *fvm) 1117d71ae5a4SJacob Faibussowitsch { 1118c0ce001eSMatthew G. Knepley PetscInt i; 1119c0ce001eSMatthew G. Knepley 1120c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1121c0ce001eSMatthew G. Knepley if (!*fvm) PetscFunctionReturn(0); 1122c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific((*fvm), PETSCFV_CLASSID, 1); 1123c0ce001eSMatthew G. Knepley 11249371c9d4SSatish Balay if (--((PetscObject)(*fvm))->refct > 0) { 11259371c9d4SSatish Balay *fvm = NULL; 11269371c9d4SSatish Balay PetscFunctionReturn(0); 11279371c9d4SSatish Balay } 1128c0ce001eSMatthew G. Knepley ((PetscObject)(*fvm))->refct = 0; 1129c0ce001eSMatthew G. Knepley 113048a46eb9SPierre Jolivet for (i = 0; i < (*fvm)->numComponents; i++) PetscCall(PetscFree((*fvm)->componentNames[i])); 11319566063dSJacob Faibussowitsch PetscCall(PetscFree((*fvm)->componentNames)); 11329566063dSJacob Faibussowitsch PetscCall(PetscLimiterDestroy(&(*fvm)->limiter)); 11339566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&(*fvm)->dualSpace)); 11349566063dSJacob Faibussowitsch PetscCall(PetscFree((*fvm)->fluxWork)); 11359566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&(*fvm)->quadrature)); 11369566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&(*fvm)->T)); 1137c0ce001eSMatthew G. Knepley 1138dbbe0bcdSBarry Smith PetscTryTypeMethod((*fvm), destroy); 11399566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(fvm)); 1140c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1141c0ce001eSMatthew G. Knepley } 1142c0ce001eSMatthew G. Knepley 1143c0ce001eSMatthew G. Knepley /*@ 1144*dce8aebaSBarry Smith PetscFVCreate - Creates an empty `PetscFV` object. The type can then be set with `PetscFVSetType()`. 1145c0ce001eSMatthew G. Knepley 1146c0ce001eSMatthew G. Knepley Collective 1147c0ce001eSMatthew G. Knepley 1148c0ce001eSMatthew G. Knepley Input Parameter: 1149*dce8aebaSBarry Smith . comm - The communicator for the `PetscFV` object 1150c0ce001eSMatthew G. Knepley 1151c0ce001eSMatthew G. Knepley Output Parameter: 1152*dce8aebaSBarry Smith . fvm - The `PetscFV` object 1153c0ce001eSMatthew G. Knepley 1154c0ce001eSMatthew G. Knepley Level: beginner 1155c0ce001eSMatthew G. Knepley 1156*dce8aebaSBarry Smith .seealso: `PetscFVSet`, `PetscFVSetType()`, `PETSCFVUPWIND`, `PetscFVDestroy()` 1157c0ce001eSMatthew G. Knepley @*/ 1158d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVCreate(MPI_Comm comm, PetscFV *fvm) 1159d71ae5a4SJacob Faibussowitsch { 1160c0ce001eSMatthew G. Knepley PetscFV f; 1161c0ce001eSMatthew G. Knepley 1162c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1163c0ce001eSMatthew G. Knepley PetscValidPointer(fvm, 2); 1164c0ce001eSMatthew G. Knepley *fvm = NULL; 11659566063dSJacob Faibussowitsch PetscCall(PetscFVInitializePackage()); 1166c0ce001eSMatthew G. Knepley 11679566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(f, PETSCFV_CLASSID, "PetscFV", "Finite Volume", "PetscFV", comm, PetscFVDestroy, PetscFVView)); 11689566063dSJacob Faibussowitsch PetscCall(PetscMemzero(f->ops, sizeof(struct _PetscFVOps))); 1169c0ce001eSMatthew G. Knepley 11709566063dSJacob Faibussowitsch PetscCall(PetscLimiterCreate(comm, &f->limiter)); 1171c0ce001eSMatthew G. Knepley f->numComponents = 1; 1172c0ce001eSMatthew G. Knepley f->dim = 0; 1173c0ce001eSMatthew G. Knepley f->computeGradients = PETSC_FALSE; 1174c0ce001eSMatthew G. Knepley f->fluxWork = NULL; 11759566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(f->numComponents, &f->componentNames)); 1176c0ce001eSMatthew G. Knepley 1177c0ce001eSMatthew G. Knepley *fvm = f; 1178c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1179c0ce001eSMatthew G. Knepley } 1180c0ce001eSMatthew G. Knepley 1181c0ce001eSMatthew G. Knepley /*@ 1182*dce8aebaSBarry Smith PetscFVSetLimiter - Set the `PetscLimiter` to the `PetscFV` 1183c0ce001eSMatthew G. Knepley 1184c0ce001eSMatthew G. Knepley Logically collective on fvm 1185c0ce001eSMatthew G. Knepley 1186c0ce001eSMatthew G. Knepley Input Parameters: 1187*dce8aebaSBarry Smith + fvm - the `PetscFV` object 1188*dce8aebaSBarry Smith - lim - The `PetscLimiter` 1189c0ce001eSMatthew G. Knepley 119088f5f89eSMatthew G. Knepley Level: intermediate 1191c0ce001eSMatthew G. Knepley 1192*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscLimiter`, `PetscFVGetLimiter()` 1193c0ce001eSMatthew G. Knepley @*/ 1194d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetLimiter(PetscFV fvm, PetscLimiter lim) 1195d71ae5a4SJacob Faibussowitsch { 1196c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1197c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1198c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 2); 11999566063dSJacob Faibussowitsch PetscCall(PetscLimiterDestroy(&fvm->limiter)); 12009566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)lim)); 1201c0ce001eSMatthew G. Knepley fvm->limiter = lim; 1202c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1203c0ce001eSMatthew G. Knepley } 1204c0ce001eSMatthew G. Knepley 1205c0ce001eSMatthew G. Knepley /*@ 1206*dce8aebaSBarry Smith PetscFVGetLimiter - Get the `PetscLimiter` object from the `PetscFV` 1207c0ce001eSMatthew G. Knepley 1208c0ce001eSMatthew G. Knepley Not collective 1209c0ce001eSMatthew G. Knepley 1210c0ce001eSMatthew G. Knepley Input Parameter: 1211*dce8aebaSBarry Smith . fvm - the `PetscFV` object 1212c0ce001eSMatthew G. Knepley 1213c0ce001eSMatthew G. Knepley Output Parameter: 1214*dce8aebaSBarry Smith . lim - The `PetscLimiter` 1215c0ce001eSMatthew G. Knepley 121688f5f89eSMatthew G. Knepley Level: intermediate 1217c0ce001eSMatthew G. Knepley 1218*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscLimiter`, `PetscFVSetLimiter()` 1219c0ce001eSMatthew G. Knepley @*/ 1220d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetLimiter(PetscFV fvm, PetscLimiter *lim) 1221d71ae5a4SJacob Faibussowitsch { 1222c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1223c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1224c0ce001eSMatthew G. Knepley PetscValidPointer(lim, 2); 1225c0ce001eSMatthew G. Knepley *lim = fvm->limiter; 1226c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1227c0ce001eSMatthew G. Knepley } 1228c0ce001eSMatthew G. Knepley 1229c0ce001eSMatthew G. Knepley /*@ 1230*dce8aebaSBarry Smith PetscFVSetNumComponents - Set the number of field components in a `PetscFV` 1231c0ce001eSMatthew G. Knepley 1232c0ce001eSMatthew G. Knepley Logically collective on fvm 1233c0ce001eSMatthew G. Knepley 1234c0ce001eSMatthew G. Knepley Input Parameters: 1235*dce8aebaSBarry Smith + fvm - the `PetscFV` object 1236c0ce001eSMatthew G. Knepley - comp - The number of components 1237c0ce001eSMatthew G. Knepley 123888f5f89eSMatthew G. Knepley Level: intermediate 1239c0ce001eSMatthew G. Knepley 1240*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVGetNumComponents()` 1241c0ce001eSMatthew G. Knepley @*/ 1242d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetNumComponents(PetscFV fvm, PetscInt comp) 1243d71ae5a4SJacob Faibussowitsch { 1244c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1245c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1246c0ce001eSMatthew G. Knepley if (fvm->numComponents != comp) { 1247c0ce001eSMatthew G. Knepley PetscInt i; 1248c0ce001eSMatthew G. Knepley 124948a46eb9SPierre Jolivet for (i = 0; i < fvm->numComponents; i++) PetscCall(PetscFree(fvm->componentNames[i])); 12509566063dSJacob Faibussowitsch PetscCall(PetscFree(fvm->componentNames)); 12519566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(comp, &fvm->componentNames)); 1252c0ce001eSMatthew G. Knepley } 1253c0ce001eSMatthew G. Knepley fvm->numComponents = comp; 12549566063dSJacob Faibussowitsch PetscCall(PetscFree(fvm->fluxWork)); 12559566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(comp, &fvm->fluxWork)); 1256c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1257c0ce001eSMatthew G. Knepley } 1258c0ce001eSMatthew G. Knepley 1259c0ce001eSMatthew G. Knepley /*@ 1260*dce8aebaSBarry Smith PetscFVGetNumComponents - Get the number of field components in a `PetscFV` 1261c0ce001eSMatthew G. Knepley 1262c0ce001eSMatthew G. Knepley Not collective 1263c0ce001eSMatthew G. Knepley 1264c0ce001eSMatthew G. Knepley Input Parameter: 1265*dce8aebaSBarry Smith . fvm - the `PetscFV` object 1266c0ce001eSMatthew G. Knepley 1267c0ce001eSMatthew G. Knepley Output Parameter: 1268c0ce001eSMatthew G. Knepley , comp - The number of components 1269c0ce001eSMatthew G. Knepley 127088f5f89eSMatthew G. Knepley Level: intermediate 1271c0ce001eSMatthew G. Knepley 1272*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVSetNumComponents()`, `PetscFVSetComponentName()` 1273c0ce001eSMatthew G. Knepley @*/ 1274d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetNumComponents(PetscFV fvm, PetscInt *comp) 1275d71ae5a4SJacob Faibussowitsch { 1276c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1277c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1278dadcf809SJacob Faibussowitsch PetscValidIntPointer(comp, 2); 1279c0ce001eSMatthew G. Knepley *comp = fvm->numComponents; 1280c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1281c0ce001eSMatthew G. Knepley } 1282c0ce001eSMatthew G. Knepley 1283c0ce001eSMatthew G. Knepley /*@C 1284*dce8aebaSBarry Smith PetscFVSetComponentName - Set the name of a component (used in output and viewing) in a `PetscFV` 1285c0ce001eSMatthew G. Knepley 1286c0ce001eSMatthew G. Knepley Logically collective on fvm 1287*dce8aebaSBarry Smith 1288c0ce001eSMatthew G. Knepley Input Parameters: 1289*dce8aebaSBarry Smith + fvm - the `PetscFV` object 1290c0ce001eSMatthew G. Knepley . comp - the component number 1291c0ce001eSMatthew G. Knepley - name - the component name 1292c0ce001eSMatthew G. Knepley 129388f5f89eSMatthew G. Knepley Level: intermediate 1294c0ce001eSMatthew G. Knepley 1295*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVGetComponentName()` 1296c0ce001eSMatthew G. Knepley @*/ 1297d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetComponentName(PetscFV fvm, PetscInt comp, const char *name) 1298d71ae5a4SJacob Faibussowitsch { 1299c0ce001eSMatthew G. Knepley PetscFunctionBegin; 13009566063dSJacob Faibussowitsch PetscCall(PetscFree(fvm->componentNames[comp])); 13019566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &fvm->componentNames[comp])); 1302c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1303c0ce001eSMatthew G. Knepley } 1304c0ce001eSMatthew G. Knepley 1305c0ce001eSMatthew G. Knepley /*@C 1306*dce8aebaSBarry Smith PetscFVGetComponentName - Get the name of a component (used in output and viewing) in a `PetscFV` 1307c0ce001eSMatthew G. Knepley 1308c0ce001eSMatthew G. Knepley Logically collective on fvm 1309c0ce001eSMatthew G. Knepley Input Parameters: 1310*dce8aebaSBarry Smith + fvm - the `PetscFV` object 1311c0ce001eSMatthew G. Knepley - comp - the component number 1312c0ce001eSMatthew G. Knepley 1313c0ce001eSMatthew G. Knepley Output Parameter: 1314c0ce001eSMatthew G. Knepley . name - the component name 1315c0ce001eSMatthew G. Knepley 131688f5f89eSMatthew G. Knepley Level: intermediate 1317c0ce001eSMatthew G. Knepley 1318*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVSetComponentName()` 1319c0ce001eSMatthew G. Knepley @*/ 1320d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetComponentName(PetscFV fvm, PetscInt comp, const char **name) 1321d71ae5a4SJacob Faibussowitsch { 1322c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1323c0ce001eSMatthew G. Knepley *name = fvm->componentNames[comp]; 1324c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1325c0ce001eSMatthew G. Knepley } 1326c0ce001eSMatthew G. Knepley 1327c0ce001eSMatthew G. Knepley /*@ 1328*dce8aebaSBarry Smith PetscFVSetSpatialDimension - Set the spatial dimension of a `PetscFV` 1329c0ce001eSMatthew G. Knepley 1330c0ce001eSMatthew G. Knepley Logically collective on fvm 1331c0ce001eSMatthew G. Knepley 1332c0ce001eSMatthew G. Knepley Input Parameters: 1333*dce8aebaSBarry Smith + fvm - the `PetscFV` object 1334c0ce001eSMatthew G. Knepley - dim - The spatial dimension 1335c0ce001eSMatthew G. Knepley 133688f5f89eSMatthew G. Knepley Level: intermediate 1337c0ce001eSMatthew G. Knepley 1338*dce8aebaSBarry Smith .seealso: `PetscFV`, ``PetscFVGetSpatialDimension()` 1339c0ce001eSMatthew G. Knepley @*/ 1340d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetSpatialDimension(PetscFV fvm, PetscInt dim) 1341d71ae5a4SJacob Faibussowitsch { 1342c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1343c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1344c0ce001eSMatthew G. Knepley fvm->dim = dim; 1345c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1346c0ce001eSMatthew G. Knepley } 1347c0ce001eSMatthew G. Knepley 1348c0ce001eSMatthew G. Knepley /*@ 1349*dce8aebaSBarry Smith PetscFVGetSpatialDimension - Get the spatial dimension of a `PetscFV` 1350c0ce001eSMatthew G. Knepley 1351c0ce001eSMatthew G. Knepley Logically collective on fvm 1352c0ce001eSMatthew G. Knepley 1353c0ce001eSMatthew G. Knepley Input Parameter: 1354*dce8aebaSBarry Smith . fvm - the `PetscFV` object 1355c0ce001eSMatthew G. Knepley 1356c0ce001eSMatthew G. Knepley Output Parameter: 1357c0ce001eSMatthew G. Knepley . dim - The spatial dimension 1358c0ce001eSMatthew G. Knepley 135988f5f89eSMatthew G. Knepley Level: intermediate 1360c0ce001eSMatthew G. Knepley 1361*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVSetSpatialDimension()` 1362c0ce001eSMatthew G. Knepley @*/ 1363d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetSpatialDimension(PetscFV fvm, PetscInt *dim) 1364d71ae5a4SJacob Faibussowitsch { 1365c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1366c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1367dadcf809SJacob Faibussowitsch PetscValidIntPointer(dim, 2); 1368c0ce001eSMatthew G. Knepley *dim = fvm->dim; 1369c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1370c0ce001eSMatthew G. Knepley } 1371c0ce001eSMatthew G. Knepley 1372c0ce001eSMatthew G. Knepley /*@ 1373*dce8aebaSBarry Smith PetscFVSetComputeGradients - Toggle computation of cell gradients on a `PetscFV` 1374c0ce001eSMatthew G. Knepley 1375c0ce001eSMatthew G. Knepley Logically collective on fvm 1376c0ce001eSMatthew G. Knepley 1377c0ce001eSMatthew G. Knepley Input Parameters: 1378*dce8aebaSBarry Smith + fvm - the `PetscFV` object 1379c0ce001eSMatthew G. Knepley - computeGradients - Flag to compute cell gradients 1380c0ce001eSMatthew G. Knepley 138188f5f89eSMatthew G. Knepley Level: intermediate 1382c0ce001eSMatthew G. Knepley 1383*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVGetComputeGradients()` 1384c0ce001eSMatthew G. Knepley @*/ 1385d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetComputeGradients(PetscFV fvm, PetscBool computeGradients) 1386d71ae5a4SJacob Faibussowitsch { 1387c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1388c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1389c0ce001eSMatthew G. Knepley fvm->computeGradients = computeGradients; 1390c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1391c0ce001eSMatthew G. Knepley } 1392c0ce001eSMatthew G. Knepley 1393c0ce001eSMatthew G. Knepley /*@ 1394*dce8aebaSBarry Smith PetscFVGetComputeGradients - Return flag for computation of cell gradients on a `PetscFV` 1395c0ce001eSMatthew G. Knepley 1396c0ce001eSMatthew G. Knepley Not collective 1397c0ce001eSMatthew G. Knepley 1398c0ce001eSMatthew G. Knepley Input Parameter: 1399*dce8aebaSBarry Smith . fvm - the `PetscFV` object 1400c0ce001eSMatthew G. Knepley 1401c0ce001eSMatthew G. Knepley Output Parameter: 1402c0ce001eSMatthew G. Knepley . computeGradients - Flag to compute cell gradients 1403c0ce001eSMatthew G. Knepley 140488f5f89eSMatthew G. Knepley Level: intermediate 1405c0ce001eSMatthew G. Knepley 1406*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVSetComputeGradients()` 1407c0ce001eSMatthew G. Knepley @*/ 1408d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetComputeGradients(PetscFV fvm, PetscBool *computeGradients) 1409d71ae5a4SJacob Faibussowitsch { 1410c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1411c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1412dadcf809SJacob Faibussowitsch PetscValidBoolPointer(computeGradients, 2); 1413c0ce001eSMatthew G. Knepley *computeGradients = fvm->computeGradients; 1414c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1415c0ce001eSMatthew G. Knepley } 1416c0ce001eSMatthew G. Knepley 1417c0ce001eSMatthew G. Knepley /*@ 1418*dce8aebaSBarry Smith PetscFVSetQuadrature - Set the `PetscQuadrature` object for a `PetscFV` 1419c0ce001eSMatthew G. Knepley 1420c0ce001eSMatthew G. Knepley Logically collective on fvm 1421c0ce001eSMatthew G. Knepley 1422c0ce001eSMatthew G. Knepley Input Parameters: 1423*dce8aebaSBarry Smith + fvm - the `PetscFV` object 1424*dce8aebaSBarry Smith - q - The `PetscQuadrature` 1425c0ce001eSMatthew G. Knepley 142688f5f89eSMatthew G. Knepley Level: intermediate 1427c0ce001eSMatthew G. Knepley 1428*dce8aebaSBarry Smith .seealso: `PetscQuadrature`, `PetscFV`, `PetscFVGetQuadrature()` 1429c0ce001eSMatthew G. Knepley @*/ 1430d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetQuadrature(PetscFV fvm, PetscQuadrature q) 1431d71ae5a4SJacob Faibussowitsch { 1432c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1433c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 14349566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&fvm->quadrature)); 14359566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)q)); 1436c0ce001eSMatthew G. Knepley fvm->quadrature = q; 1437c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1438c0ce001eSMatthew G. Knepley } 1439c0ce001eSMatthew G. Knepley 1440c0ce001eSMatthew G. Knepley /*@ 1441*dce8aebaSBarry Smith PetscFVGetQuadrature - Get the `PetscQuadrature` from a `PetscFV` 1442c0ce001eSMatthew G. Knepley 1443c0ce001eSMatthew G. Knepley Not collective 1444c0ce001eSMatthew G. Knepley 1445c0ce001eSMatthew G. Knepley Input Parameter: 1446*dce8aebaSBarry Smith . fvm - the `PetscFV` object 1447c0ce001eSMatthew G. Knepley 1448c0ce001eSMatthew G. Knepley Output Parameter: 1449*dce8aebaSBarry Smith . lim - The `PetscQuadrature` 1450c0ce001eSMatthew G. Knepley 145188f5f89eSMatthew G. Knepley Level: intermediate 1452c0ce001eSMatthew G. Knepley 1453*dce8aebaSBarry Smith .seealso: `PetscQuadrature`, `PetscFV`, `PetscFVSetQuadrature()` 1454c0ce001eSMatthew G. Knepley @*/ 1455d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetQuadrature(PetscFV fvm, PetscQuadrature *q) 1456d71ae5a4SJacob Faibussowitsch { 1457c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1458c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1459c0ce001eSMatthew G. Knepley PetscValidPointer(q, 2); 1460c0ce001eSMatthew G. Knepley if (!fvm->quadrature) { 1461c0ce001eSMatthew G. Knepley /* Create default 1-point quadrature */ 1462c0ce001eSMatthew G. Knepley PetscReal *points, *weights; 1463c0ce001eSMatthew G. Knepley 14649566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &fvm->quadrature)); 14659566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(fvm->dim, &points)); 14669566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, &weights)); 1467c0ce001eSMatthew G. Knepley weights[0] = 1.0; 14689566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(fvm->quadrature, fvm->dim, 1, 1, points, weights)); 1469c0ce001eSMatthew G. Knepley } 1470c0ce001eSMatthew G. Knepley *q = fvm->quadrature; 1471c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1472c0ce001eSMatthew G. Knepley } 1473c0ce001eSMatthew G. Knepley 1474c0ce001eSMatthew G. Knepley /*@ 1475*dce8aebaSBarry Smith PetscFVGetDualSpace - Returns the `PetscDualSpace` used to define the inner product on a `PetscFV` 1476c0ce001eSMatthew G. Knepley 1477c0ce001eSMatthew G. Knepley Not collective 1478c0ce001eSMatthew G. Knepley 1479c0ce001eSMatthew G. Knepley Input Parameter: 1480*dce8aebaSBarry Smith . fvm - The `PetscFV` object 1481c0ce001eSMatthew G. Knepley 1482c0ce001eSMatthew G. Knepley Output Parameter: 1483c0ce001eSMatthew G. Knepley . sp - The PetscDualSpace object 1484c0ce001eSMatthew G. Knepley 148588f5f89eSMatthew G. Knepley Level: intermediate 1486c0ce001eSMatthew G. Knepley 1487*dce8aebaSBarry Smith Developer Note: 1488*dce8aebaSBarry Smith There is overlap between the methods of `PetscFE` and `PetscFV`, they should probably share a common parent class 1489*dce8aebaSBarry Smith 1490*dce8aebaSBarry Smith .seealso: `PetscDualSpace`, `PetscFV`, `PetscFVCreate()` 1491c0ce001eSMatthew G. Knepley @*/ 1492d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetDualSpace(PetscFV fvm, PetscDualSpace *sp) 1493d71ae5a4SJacob Faibussowitsch { 1494c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1495c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1496c0ce001eSMatthew G. Knepley PetscValidPointer(sp, 2); 1497c0ce001eSMatthew G. Knepley if (!fvm->dualSpace) { 1498c0ce001eSMatthew G. Knepley DM K; 1499c0ce001eSMatthew G. Knepley PetscInt dim, Nc, c; 1500c0ce001eSMatthew G. Knepley 15019566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 15029566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &Nc)); 15039566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceCreate(PetscObjectComm((PetscObject)fvm), &fvm->dualSpace)); 15049566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetType(fvm->dualSpace, PETSCDUALSPACESIMPLE)); 15059566063dSJacob Faibussowitsch PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, DMPolytopeTypeSimpleShape(dim, PETSC_FALSE), &K)); 15069566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetNumComponents(fvm->dualSpace, Nc)); 15079566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(fvm->dualSpace, K)); 15089566063dSJacob Faibussowitsch PetscCall(DMDestroy(&K)); 15099566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetDimension(fvm->dualSpace, Nc)); 1510c0ce001eSMatthew G. Knepley /* Should we be using PetscFVGetQuadrature() here? */ 1511c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; ++c) { 1512c0ce001eSMatthew G. Knepley PetscQuadrature qc; 1513c0ce001eSMatthew G. Knepley PetscReal *points, *weights; 1514c0ce001eSMatthew G. Knepley 15159566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qc)); 15169566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(dim, &points)); 15179566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nc, &weights)); 1518c0ce001eSMatthew G. Knepley weights[c] = 1.0; 15199566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(qc, dim, Nc, 1, points, weights)); 15209566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetFunctional(fvm->dualSpace, c, qc)); 15219566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qc)); 1522c0ce001eSMatthew G. Knepley } 15239566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(fvm->dualSpace)); 1524c0ce001eSMatthew G. Knepley } 1525c0ce001eSMatthew G. Knepley *sp = fvm->dualSpace; 1526c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1527c0ce001eSMatthew G. Knepley } 1528c0ce001eSMatthew G. Knepley 1529c0ce001eSMatthew G. Knepley /*@ 1530*dce8aebaSBarry Smith PetscFVSetDualSpace - Sets the `PetscDualSpace` used to define the inner product 1531c0ce001eSMatthew G. Knepley 1532c0ce001eSMatthew G. Knepley Not collective 1533c0ce001eSMatthew G. Knepley 1534c0ce001eSMatthew G. Knepley Input Parameters: 1535*dce8aebaSBarry Smith + fvm - The `PetscFV` object 1536*dce8aebaSBarry Smith - sp - The `PetscDualSpace` object 1537c0ce001eSMatthew G. Knepley 1538c0ce001eSMatthew G. Knepley Level: intermediate 1539c0ce001eSMatthew G. Knepley 1540*dce8aebaSBarry Smith Note: 1541*dce8aebaSBarry Smith A simple dual space is provided automatically, and the user typically will not need to override it. 1542c0ce001eSMatthew G. Knepley 1543*dce8aebaSBarry Smith .seealso: `PetscDualSpace`, `PetscFV`, `PetscFVCreate()` 1544c0ce001eSMatthew G. Knepley @*/ 1545d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetDualSpace(PetscFV fvm, PetscDualSpace sp) 1546d71ae5a4SJacob Faibussowitsch { 1547c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1548c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1549c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 2); 15509566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&fvm->dualSpace)); 1551c0ce001eSMatthew G. Knepley fvm->dualSpace = sp; 15529566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fvm->dualSpace)); 1553c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1554c0ce001eSMatthew G. Knepley } 1555c0ce001eSMatthew G. Knepley 155688f5f89eSMatthew G. Knepley /*@C 1557ef0bb6c7SMatthew G. Knepley PetscFVGetCellTabulation - Returns the tabulation of the basis functions at the quadrature points 155888f5f89eSMatthew G. Knepley 155988f5f89eSMatthew G. Knepley Not collective 156088f5f89eSMatthew G. Knepley 156188f5f89eSMatthew G. Knepley Input Parameter: 1562*dce8aebaSBarry Smith . fvm - The `PetscFV` object 156388f5f89eSMatthew G. Knepley 1564ef0bb6c7SMatthew G. Knepley Output Parameter: 1565a5b23f4aSJose E. Roman . T - The basis function values and derivatives at quadrature points 156688f5f89eSMatthew G. Knepley 156788f5f89eSMatthew G. Knepley Level: intermediate 156888f5f89eSMatthew G. Knepley 1569*dce8aebaSBarry Smith Note: 1570*dce8aebaSBarry Smith .vb 1571*dce8aebaSBarry Smith T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 1572*dce8aebaSBarry Smith 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 1573*dce8aebaSBarry Smith 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 1574*dce8aebaSBarry Smith .ve 1575*dce8aebaSBarry Smith 1576*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscTabulation`, `PetscFEGetCellTabulation()`, `PetscFVCreateTabulation()`, `PetscFVGetQuadrature()`, `PetscQuadratureGetData()` 157788f5f89eSMatthew G. Knepley @*/ 1578d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetCellTabulation(PetscFV fvm, PetscTabulation *T) 1579d71ae5a4SJacob Faibussowitsch { 1580c0ce001eSMatthew G. Knepley PetscInt npoints; 1581c0ce001eSMatthew G. Knepley const PetscReal *points; 1582c0ce001eSMatthew G. Knepley 1583c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1584c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1585ef0bb6c7SMatthew G. Knepley PetscValidPointer(T, 2); 15869566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(fvm->quadrature, NULL, NULL, &npoints, &points, NULL)); 15879566063dSJacob Faibussowitsch if (!fvm->T) PetscCall(PetscFVCreateTabulation(fvm, 1, npoints, points, 1, &fvm->T)); 1588ef0bb6c7SMatthew G. Knepley *T = fvm->T; 1589c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1590c0ce001eSMatthew G. Knepley } 1591c0ce001eSMatthew G. Knepley 159288f5f89eSMatthew G. Knepley /*@C 1593ef0bb6c7SMatthew G. Knepley PetscFVCreateTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided. 159488f5f89eSMatthew G. Knepley 159588f5f89eSMatthew G. Knepley Not collective 159688f5f89eSMatthew G. Knepley 159788f5f89eSMatthew G. Knepley Input Parameters: 1598*dce8aebaSBarry Smith + fvm - The `PetscFV` object 1599ef0bb6c7SMatthew G. Knepley . nrepl - The number of replicas 1600ef0bb6c7SMatthew G. Knepley . npoints - The number of tabulation points in a replica 1601ef0bb6c7SMatthew G. Knepley . points - The tabulation point coordinates 1602ef0bb6c7SMatthew G. Knepley - K - The order of derivative to tabulate 160388f5f89eSMatthew G. Knepley 1604ef0bb6c7SMatthew G. Knepley Output Parameter: 1605a5b23f4aSJose E. Roman . T - The basis function values and derivative at tabulation points 160688f5f89eSMatthew G. Knepley 160788f5f89eSMatthew G. Knepley Level: intermediate 160888f5f89eSMatthew G. Knepley 1609*dce8aebaSBarry Smith Note: 1610*dce8aebaSBarry Smith .vb 1611*dce8aebaSBarry Smith T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 1612*dce8aebaSBarry Smith 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 1613*dce8aebaSBarry Smith 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 1614*dce8aebaSBarry Smith .ve 1615*dce8aebaSBarry Smith 1616*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscTabulation`, `PetscFECreateTabulation()`, `PetscTabulationDestroy()`, `PetscFEGetCellTabulation()` 161788f5f89eSMatthew G. Knepley @*/ 1618d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVCreateTabulation(PetscFV fvm, PetscInt nrepl, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation *T) 1619d71ae5a4SJacob Faibussowitsch { 1620c0ce001eSMatthew G. Knepley PetscInt pdim = 1; /* Dimension of approximation space P */ 1621ef0bb6c7SMatthew G. Knepley PetscInt cdim; /* Spatial dimension */ 1622ef0bb6c7SMatthew G. Knepley PetscInt Nc; /* Field components */ 1623ef0bb6c7SMatthew G. Knepley PetscInt k, p, d, c, e; 1624c0ce001eSMatthew G. Knepley 1625c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1626ef0bb6c7SMatthew G. Knepley if (!npoints || K < 0) { 1627ef0bb6c7SMatthew G. Knepley *T = NULL; 1628c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1629c0ce001eSMatthew G. Knepley } 1630c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1631dadcf809SJacob Faibussowitsch PetscValidRealPointer(points, 4); 163240a2aa30SMatthew G. Knepley PetscValidPointer(T, 6); 16339566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &cdim)); 16349566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &Nc)); 16359566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, T)); 1636ef0bb6c7SMatthew G. Knepley (*T)->K = !cdim ? 0 : K; 1637ef0bb6c7SMatthew G. Knepley (*T)->Nr = nrepl; 1638ef0bb6c7SMatthew G. Knepley (*T)->Np = npoints; 1639ef0bb6c7SMatthew G. Knepley (*T)->Nb = pdim; 1640ef0bb6c7SMatthew G. Knepley (*T)->Nc = Nc; 1641ef0bb6c7SMatthew G. Knepley (*T)->cdim = cdim; 16429566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*T)->K + 1, &(*T)->T)); 164348a46eb9SPierre Jolivet for (k = 0; k <= (*T)->K; ++k) PetscCall(PetscMalloc1(nrepl * npoints * pdim * Nc * PetscPowInt(cdim, k), &(*T)->T[k])); 16449371c9d4SSatish Balay if (K >= 0) { 16459371c9d4SSatish Balay for (p = 0; p < nrepl * npoints; ++p) 16469371c9d4SSatish Balay for (d = 0; d < pdim; ++d) 16479371c9d4SSatish Balay for (c = 0; c < Nc; ++c) (*T)->T[0][(p * pdim + d) * Nc + c] = 1.0; 1648ef0bb6c7SMatthew G. Knepley } 16499371c9d4SSatish Balay if (K >= 1) { 16509371c9d4SSatish Balay for (p = 0; p < nrepl * npoints; ++p) 16519371c9d4SSatish Balay for (d = 0; d < pdim; ++d) 16529371c9d4SSatish Balay for (c = 0; c < Nc; ++c) 16539371c9d4SSatish Balay for (e = 0; e < cdim; ++e) (*T)->T[1][((p * pdim + d) * Nc + c) * cdim + e] = 0.0; 16549371c9d4SSatish Balay } 16559371c9d4SSatish Balay if (K >= 2) { 16569371c9d4SSatish Balay for (p = 0; p < nrepl * npoints; ++p) 16579371c9d4SSatish Balay for (d = 0; d < pdim; ++d) 16589371c9d4SSatish Balay for (c = 0; c < Nc; ++c) 16599371c9d4SSatish Balay for (e = 0; e < cdim * cdim; ++e) (*T)->T[2][((p * pdim + d) * Nc + c) * cdim * cdim + e] = 0.0; 16609371c9d4SSatish Balay } 1661c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1662c0ce001eSMatthew G. Knepley } 1663c0ce001eSMatthew G. Knepley 1664c0ce001eSMatthew G. Knepley /*@C 1665c0ce001eSMatthew G. Knepley PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell 1666c0ce001eSMatthew G. Knepley 1667c0ce001eSMatthew G. Knepley Input Parameters: 1668*dce8aebaSBarry Smith + fvm - The `PetscFV` object 1669c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained 1670c0ce001eSMatthew G. Knepley - dx - The vector from the cell centroid to the neighboring cell centroid for each face 1671c0ce001eSMatthew G. Knepley 167288f5f89eSMatthew G. Knepley Level: advanced 1673c0ce001eSMatthew G. Knepley 1674*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVCreate()` 1675c0ce001eSMatthew G. Knepley @*/ 1676d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVComputeGradient(PetscFV fvm, PetscInt numFaces, PetscScalar dx[], PetscScalar grad[]) 1677d71ae5a4SJacob Faibussowitsch { 1678c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1679c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1680dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, computegradient, numFaces, dx, grad); 1681c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1682c0ce001eSMatthew G. Knepley } 1683c0ce001eSMatthew G. Knepley 168488f5f89eSMatthew G. Knepley /*@C 1685c0ce001eSMatthew G. Knepley PetscFVIntegrateRHSFunction - Produce the cell residual vector for a chunk of elements by quadrature integration 1686c0ce001eSMatthew G. Knepley 1687c0ce001eSMatthew G. Knepley Not collective 1688c0ce001eSMatthew G. Knepley 1689c0ce001eSMatthew G. Knepley Input Parameters: 1690*dce8aebaSBarry Smith + fvm - The `PetscFV` object for the field being integrated 1691*dce8aebaSBarry Smith . prob - The `PetscDS` specifing the discretizations and continuum functions 1692c0ce001eSMatthew G. Knepley . field - The field being integrated 1693c0ce001eSMatthew G. Knepley . Nf - The number of faces in the chunk 1694c0ce001eSMatthew G. Knepley . fgeom - The face geometry for each face in the chunk 1695c0ce001eSMatthew G. Knepley . neighborVol - The volume for each pair of cells in the chunk 1696c0ce001eSMatthew G. Knepley . uL - The state from the cell on the left 1697c0ce001eSMatthew G. Knepley - uR - The state from the cell on the right 1698c0ce001eSMatthew G. Knepley 1699d8d19677SJose E. Roman Output Parameters: 1700c0ce001eSMatthew G. Knepley + fluxL - the left fluxes for each face 1701c0ce001eSMatthew G. Knepley - fluxR - the right fluxes for each face 170288f5f89eSMatthew G. Knepley 170388f5f89eSMatthew G. Knepley Level: developer 170488f5f89eSMatthew G. Knepley 1705*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscDS`, `PetscFVFaceGeom`, `PetscFVCreate()` 170688f5f89eSMatthew G. Knepley @*/ 1707d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVIntegrateRHSFunction(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) 1708d71ae5a4SJacob Faibussowitsch { 1709c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1710c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1711dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, integraterhsfunction, prob, field, Nf, fgeom, neighborVol, uL, uR, fluxL, fluxR); 1712c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1713c0ce001eSMatthew G. Knepley } 1714c0ce001eSMatthew G. Knepley 1715c0ce001eSMatthew G. Knepley /*@ 1716*dce8aebaSBarry Smith PetscFVRefine - Create a "refined" `PetscFV` object that refines the reference cell into smaller copies. This is typically used 1717c0ce001eSMatthew 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 1718c0ce001eSMatthew G. Knepley sparsity). It is also used to create an interpolation between regularly refined meshes. 1719c0ce001eSMatthew G. Knepley 1720c0ce001eSMatthew G. Knepley Input Parameter: 1721*dce8aebaSBarry Smith . fv - The initial `PetscFV` 1722c0ce001eSMatthew G. Knepley 1723c0ce001eSMatthew G. Knepley Output Parameter: 1724*dce8aebaSBarry Smith . fvRef - The refined `PetscFV` 1725c0ce001eSMatthew G. Knepley 172688f5f89eSMatthew G. Knepley Level: advanced 1727c0ce001eSMatthew G. Knepley 1728*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 1729c0ce001eSMatthew G. Knepley @*/ 1730d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVRefine(PetscFV fv, PetscFV *fvRef) 1731d71ae5a4SJacob Faibussowitsch { 1732c0ce001eSMatthew G. Knepley PetscDualSpace Q, Qref; 1733c0ce001eSMatthew G. Knepley DM K, Kref; 1734c0ce001eSMatthew G. Knepley PetscQuadrature q, qref; 1735412e9a14SMatthew G. Knepley DMPolytopeType ct; 1736012bc364SMatthew G. Knepley DMPlexTransform tr; 1737c0ce001eSMatthew G. Knepley PetscReal *v0; 1738c0ce001eSMatthew G. Knepley PetscReal *jac, *invjac; 1739c0ce001eSMatthew G. Knepley PetscInt numComp, numSubelements, s; 1740c0ce001eSMatthew G. Knepley 1741c0ce001eSMatthew G. Knepley PetscFunctionBegin; 17429566063dSJacob Faibussowitsch PetscCall(PetscFVGetDualSpace(fv, &Q)); 17439566063dSJacob Faibussowitsch PetscCall(PetscFVGetQuadrature(fv, &q)); 17449566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &K)); 1745c0ce001eSMatthew G. Knepley /* Create dual space */ 17469566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDuplicate(Q, &Qref)); 17479566063dSJacob Faibussowitsch PetscCall(DMRefine(K, PetscObjectComm((PetscObject)fv), &Kref)); 17489566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(Qref, Kref)); 17499566063dSJacob Faibussowitsch PetscCall(DMDestroy(&Kref)); 17509566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(Qref)); 1751c0ce001eSMatthew G. Knepley /* Create volume */ 17529566063dSJacob Faibussowitsch PetscCall(PetscFVCreate(PetscObjectComm((PetscObject)fv), fvRef)); 17539566063dSJacob Faibussowitsch PetscCall(PetscFVSetDualSpace(*fvRef, Qref)); 17549566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &numComp)); 17559566063dSJacob Faibussowitsch PetscCall(PetscFVSetNumComponents(*fvRef, numComp)); 17569566063dSJacob Faibussowitsch PetscCall(PetscFVSetUp(*fvRef)); 1757c0ce001eSMatthew G. Knepley /* Create quadrature */ 17589566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(K, 0, &ct)); 17599566063dSJacob Faibussowitsch PetscCall(DMPlexTransformCreate(PETSC_COMM_SELF, &tr)); 17609566063dSJacob Faibussowitsch PetscCall(DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR)); 17619566063dSJacob Faibussowitsch PetscCall(DMPlexRefineRegularGetAffineTransforms(tr, ct, &numSubelements, &v0, &jac, &invjac)); 17629566063dSJacob Faibussowitsch PetscCall(PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref)); 17639566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetDimension(Qref, numSubelements)); 1764c0ce001eSMatthew G. Knepley for (s = 0; s < numSubelements; ++s) { 1765c0ce001eSMatthew G. Knepley PetscQuadrature qs; 1766c0ce001eSMatthew G. Knepley const PetscReal *points, *weights; 1767c0ce001eSMatthew G. Knepley PetscReal *p, *w; 1768c0ce001eSMatthew G. Knepley PetscInt dim, Nc, npoints, np; 1769c0ce001eSMatthew G. Knepley 17709566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qs)); 17719566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(q, &dim, &Nc, &npoints, &points, &weights)); 1772c0ce001eSMatthew G. Knepley np = npoints / numSubelements; 17739566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(np * dim, &p)); 17749566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(np * Nc, &w)); 17759566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(p, &points[s * np * dim], np * dim)); 17769566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(w, &weights[s * np * Nc], np * Nc)); 17779566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(qs, dim, Nc, np, p, w)); 17789566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetFunctional(Qref, s, qs)); 17799566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qs)); 1780c0ce001eSMatthew G. Knepley } 17819566063dSJacob Faibussowitsch PetscCall(PetscFVSetQuadrature(*fvRef, qref)); 17829566063dSJacob Faibussowitsch PetscCall(DMPlexTransformDestroy(&tr)); 17839566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qref)); 17849566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&Qref)); 1785c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1786c0ce001eSMatthew G. Knepley } 1787c0ce001eSMatthew G. Knepley 1788d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVDestroy_Upwind(PetscFV fvm) 1789d71ae5a4SJacob Faibussowitsch { 1790c0ce001eSMatthew G. Knepley PetscFV_Upwind *b = (PetscFV_Upwind *)fvm->data; 1791c0ce001eSMatthew G. Knepley 1792c0ce001eSMatthew G. Knepley PetscFunctionBegin; 17939566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 1794c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1795c0ce001eSMatthew G. Knepley } 1796c0ce001eSMatthew G. Knepley 1797d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_Upwind_Ascii(PetscFV fv, PetscViewer viewer) 1798d71ae5a4SJacob Faibussowitsch { 1799c0ce001eSMatthew G. Knepley PetscInt Nc, c; 1800c0ce001eSMatthew G. Knepley PetscViewerFormat format; 1801c0ce001eSMatthew G. Knepley 1802c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18039566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &Nc)); 18049566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 18059566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Upwind Finite Volume:\n")); 180663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " num components: %" PetscInt_FMT "\n", Nc)); 1807c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; c++) { 180848a46eb9SPierre Jolivet if (fv->componentNames[c]) PetscCall(PetscViewerASCIIPrintf(viewer, " component %" PetscInt_FMT ": %s\n", c, fv->componentNames[c])); 1809c0ce001eSMatthew G. Knepley } 1810c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1811c0ce001eSMatthew G. Knepley } 1812c0ce001eSMatthew G. Knepley 1813d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_Upwind(PetscFV fv, PetscViewer viewer) 1814d71ae5a4SJacob Faibussowitsch { 1815c0ce001eSMatthew G. Knepley PetscBool iascii; 1816c0ce001eSMatthew G. Knepley 1817c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1818c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1); 1819c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 18209566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 18219566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscFVView_Upwind_Ascii(fv, viewer)); 1822c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1823c0ce001eSMatthew G. Knepley } 1824c0ce001eSMatthew G. Knepley 1825d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVSetUp_Upwind(PetscFV fvm) 1826d71ae5a4SJacob Faibussowitsch { 1827c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1828c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1829c0ce001eSMatthew G. Knepley } 1830c0ce001eSMatthew G. Knepley 1831c0ce001eSMatthew G. Knepley /* 1832c0ce001eSMatthew G. Knepley neighborVol[f*2+0] contains the left geom 1833c0ce001eSMatthew G. Knepley neighborVol[f*2+1] contains the right geom 1834c0ce001eSMatthew G. Knepley */ 1835d71ae5a4SJacob 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[]) 1836d71ae5a4SJacob Faibussowitsch { 1837c0ce001eSMatthew G. Knepley void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *); 1838c0ce001eSMatthew G. Knepley void *rctx; 1839c0ce001eSMatthew G. Knepley PetscScalar *flux = fvm->fluxWork; 1840c0ce001eSMatthew G. Knepley const PetscScalar *constants; 1841c0ce001eSMatthew G. Knepley PetscInt dim, numConstants, pdim, totDim, Nc, off, f, d; 1842c0ce001eSMatthew G. Knepley 1843c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18449566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalComponents(prob, &Nc)); 18459566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalDimension(prob, &totDim)); 18469566063dSJacob Faibussowitsch PetscCall(PetscDSGetFieldOffset(prob, field, &off)); 18479566063dSJacob Faibussowitsch PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann)); 18489566063dSJacob Faibussowitsch PetscCall(PetscDSGetContext(prob, field, &rctx)); 18499566063dSJacob Faibussowitsch PetscCall(PetscDSGetConstants(prob, &numConstants, &constants)); 18509566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 18519566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &pdim)); 1852c0ce001eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 1853c0ce001eSMatthew G. Knepley (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f * Nc], &uR[f * Nc], numConstants, constants, flux, rctx); 1854c0ce001eSMatthew G. Knepley for (d = 0; d < pdim; ++d) { 1855c0ce001eSMatthew G. Knepley fluxL[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 0]; 1856c0ce001eSMatthew G. Knepley fluxR[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 1]; 1857c0ce001eSMatthew G. Knepley } 1858c0ce001eSMatthew G. Knepley } 1859c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1860c0ce001eSMatthew G. Knepley } 1861c0ce001eSMatthew G. Knepley 1862d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVInitialize_Upwind(PetscFV fvm) 1863d71ae5a4SJacob Faibussowitsch { 1864c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1865c0ce001eSMatthew G. Knepley fvm->ops->setfromoptions = NULL; 1866c0ce001eSMatthew G. Knepley fvm->ops->setup = PetscFVSetUp_Upwind; 1867c0ce001eSMatthew G. Knepley fvm->ops->view = PetscFVView_Upwind; 1868c0ce001eSMatthew G. Knepley fvm->ops->destroy = PetscFVDestroy_Upwind; 1869c0ce001eSMatthew G. Knepley fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_Upwind; 1870c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1871c0ce001eSMatthew G. Knepley } 1872c0ce001eSMatthew G. Knepley 1873c0ce001eSMatthew G. Knepley /*MC 1874*dce8aebaSBarry Smith PETSCFVUPWIND = "upwind" - A `PetscFV` implementation 1875c0ce001eSMatthew G. Knepley 1876c0ce001eSMatthew G. Knepley Level: intermediate 1877c0ce001eSMatthew G. Knepley 1878*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 1879c0ce001eSMatthew G. Knepley M*/ 1880c0ce001eSMatthew G. Knepley 1881d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscFVCreate_Upwind(PetscFV fvm) 1882d71ae5a4SJacob Faibussowitsch { 1883c0ce001eSMatthew G. Knepley PetscFV_Upwind *b; 1884c0ce001eSMatthew G. Knepley 1885c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1886c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 18874dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 1888c0ce001eSMatthew G. Knepley fvm->data = b; 1889c0ce001eSMatthew G. Knepley 18909566063dSJacob Faibussowitsch PetscCall(PetscFVInitialize_Upwind(fvm)); 1891c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1892c0ce001eSMatthew G. Knepley } 1893c0ce001eSMatthew G. Knepley 1894c0ce001eSMatthew G. Knepley #include <petscblaslapack.h> 1895c0ce001eSMatthew G. Knepley 1896d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVDestroy_LeastSquares(PetscFV fvm) 1897d71ae5a4SJacob Faibussowitsch { 1898c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data; 1899c0ce001eSMatthew G. Knepley 1900c0ce001eSMatthew G. Knepley PetscFunctionBegin; 19019566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fvm, "PetscFVLeastSquaresSetMaxFaces_C", NULL)); 19029566063dSJacob Faibussowitsch PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work)); 19039566063dSJacob Faibussowitsch PetscCall(PetscFree(ls)); 1904c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1905c0ce001eSMatthew G. Knepley } 1906c0ce001eSMatthew G. Knepley 1907d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_LeastSquares_Ascii(PetscFV fv, PetscViewer viewer) 1908d71ae5a4SJacob Faibussowitsch { 1909c0ce001eSMatthew G. Knepley PetscInt Nc, c; 1910c0ce001eSMatthew G. Knepley PetscViewerFormat format; 1911c0ce001eSMatthew G. Knepley 1912c0ce001eSMatthew G. Knepley PetscFunctionBegin; 19139566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &Nc)); 19149566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 19159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Finite Volume with Least Squares Reconstruction:\n")); 191663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " num components: %" PetscInt_FMT "\n", Nc)); 1917c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; c++) { 191848a46eb9SPierre Jolivet if (fv->componentNames[c]) PetscCall(PetscViewerASCIIPrintf(viewer, " component %" PetscInt_FMT ": %s\n", c, fv->componentNames[c])); 1919c0ce001eSMatthew G. Knepley } 1920c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1921c0ce001eSMatthew G. Knepley } 1922c0ce001eSMatthew G. Knepley 1923d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_LeastSquares(PetscFV fv, PetscViewer viewer) 1924d71ae5a4SJacob Faibussowitsch { 1925c0ce001eSMatthew G. Knepley PetscBool iascii; 1926c0ce001eSMatthew G. Knepley 1927c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1928c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1); 1929c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 19309566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 19319566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscFVView_LeastSquares_Ascii(fv, viewer)); 1932c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1933c0ce001eSMatthew G. Knepley } 1934c0ce001eSMatthew G. Knepley 1935d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVSetUp_LeastSquares(PetscFV fvm) 1936d71ae5a4SJacob Faibussowitsch { 1937c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1938c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1939c0ce001eSMatthew G. Knepley } 1940c0ce001eSMatthew G. Knepley 1941c0ce001eSMatthew G. Knepley /* Overwrites A. Can only handle full-rank problems with m>=n */ 1942d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresPseudoInverse_Static(PetscInt m, PetscInt mstride, PetscInt n, PetscScalar *A, PetscScalar *Ainv, PetscScalar *tau, PetscInt worksize, PetscScalar *work) 1943d71ae5a4SJacob Faibussowitsch { 1944c0ce001eSMatthew G. Knepley PetscBool debug = PETSC_FALSE; 1945c0ce001eSMatthew G. Knepley PetscBLASInt M, N, K, lda, ldb, ldwork, info; 1946c0ce001eSMatthew G. Knepley PetscScalar *R, *Q, *Aback, Alpha; 1947c0ce001eSMatthew G. Knepley 1948c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1949c0ce001eSMatthew G. Knepley if (debug) { 19509566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * n, &Aback)); 19519566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(Aback, A, m * n)); 1952c0ce001eSMatthew G. Knepley } 1953c0ce001eSMatthew G. Knepley 19549566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &M)); 19559566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &N)); 19569566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(mstride, &lda)); 19579566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(worksize, &ldwork)); 19589566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 1959792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&M, &N, A, &lda, tau, work, &ldwork, &info)); 19609566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 196128b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xGEQRF error"); 1962c0ce001eSMatthew G. Knepley R = A; /* Upper triangular part of A now contains R, the rest contains the elementary reflectors */ 1963c0ce001eSMatthew G. Knepley 1964c0ce001eSMatthew G. Knepley /* Extract an explicit representation of Q */ 1965c0ce001eSMatthew G. Knepley Q = Ainv; 19669566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(Q, A, mstride * n)); 1967c0ce001eSMatthew G. Knepley K = N; /* full rank */ 1968792fecdfSBarry Smith PetscCallBLAS("LAPACKorgqr", LAPACKorgqr_(&M, &N, &K, Q, &lda, tau, work, &ldwork, &info)); 196928b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xORGQR/xUNGQR error"); 1970c0ce001eSMatthew G. Knepley 1971c0ce001eSMatthew G. Knepley /* Compute A^{-T} = (R^{-1} Q^T)^T = Q R^{-T} */ 1972c0ce001eSMatthew G. Knepley Alpha = 1.0; 1973c0ce001eSMatthew G. Knepley ldb = lda; 1974c0ce001eSMatthew G. Knepley BLAStrsm_("Right", "Upper", "ConjugateTranspose", "NotUnitTriangular", &M, &N, &Alpha, R, &lda, Q, &ldb); 1975c0ce001eSMatthew G. Knepley /* Ainv is Q, overwritten with inverse */ 1976c0ce001eSMatthew G. Knepley 1977c0ce001eSMatthew G. Knepley if (debug) { /* Check that pseudo-inverse worked */ 1978c0ce001eSMatthew G. Knepley PetscScalar Beta = 0.0; 1979c0ce001eSMatthew G. Knepley PetscBLASInt ldc; 1980c0ce001eSMatthew G. Knepley K = N; 1981c0ce001eSMatthew G. Knepley ldc = N; 1982c0ce001eSMatthew G. Knepley BLASgemm_("ConjugateTranspose", "Normal", &N, &K, &M, &Alpha, Ainv, &lda, Aback, &ldb, &Beta, work, &ldc); 19839566063dSJacob Faibussowitsch PetscCall(PetscScalarView(n * n, work, PETSC_VIEWER_STDOUT_SELF)); 19849566063dSJacob Faibussowitsch PetscCall(PetscFree(Aback)); 1985c0ce001eSMatthew G. Knepley } 1986c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1987c0ce001eSMatthew G. Knepley } 1988c0ce001eSMatthew G. Knepley 1989c0ce001eSMatthew G. Knepley /* Overwrites A. Can handle degenerate problems and m<n. */ 1990d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresPseudoInverseSVD_Static(PetscInt m, PetscInt mstride, PetscInt n, PetscScalar *A, PetscScalar *Ainv, PetscScalar *tau, PetscInt worksize, PetscScalar *work) 1991d71ae5a4SJacob Faibussowitsch { 19926bb27163SBarry Smith PetscScalar *Brhs; 1993c0ce001eSMatthew G. Knepley PetscScalar *tmpwork; 1994c0ce001eSMatthew G. Knepley PetscReal rcond; 1995c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX) 1996c0ce001eSMatthew G. Knepley PetscInt rworkSize; 1997c0ce001eSMatthew G. Knepley PetscReal *rwork; 1998c0ce001eSMatthew G. Knepley #endif 1999c0ce001eSMatthew G. Knepley PetscInt i, j, maxmn; 2000c0ce001eSMatthew G. Knepley PetscBLASInt M, N, lda, ldb, ldwork; 2001c0ce001eSMatthew G. Knepley PetscBLASInt nrhs, irank, info; 2002c0ce001eSMatthew G. Knepley 2003c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2004c0ce001eSMatthew G. Knepley /* initialize to identity */ 2005736d4f42SpierreXVI tmpwork = work; 2006736d4f42SpierreXVI Brhs = Ainv; 2007c0ce001eSMatthew G. Knepley maxmn = PetscMax(m, n); 2008c0ce001eSMatthew G. Knepley for (j = 0; j < maxmn; j++) { 2009c0ce001eSMatthew G. Knepley for (i = 0; i < maxmn; i++) Brhs[i + j * maxmn] = 1.0 * (i == j); 2010c0ce001eSMatthew G. Knepley } 2011c0ce001eSMatthew G. Knepley 20129566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &M)); 20139566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &N)); 20149566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(mstride, &lda)); 20159566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(maxmn, &ldb)); 20169566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(worksize, &ldwork)); 2017c0ce001eSMatthew G. Knepley rcond = -1; 2018c0ce001eSMatthew G. Knepley nrhs = M; 2019c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX) 2020c0ce001eSMatthew G. Knepley rworkSize = 5 * PetscMin(M, N); 20219566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(rworkSize, &rwork)); 20226bb27163SBarry Smith PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 2023792fecdfSBarry Smith PetscCallBLAS("LAPACKgelss", LAPACKgelss_(&M, &N, &nrhs, A, &lda, Brhs, &ldb, (PetscReal *)tau, &rcond, &irank, tmpwork, &ldwork, rwork, &info)); 20249566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 20259566063dSJacob Faibussowitsch PetscCall(PetscFree(rwork)); 2026c0ce001eSMatthew G. Knepley #else 2027c0ce001eSMatthew G. Knepley nrhs = M; 20286bb27163SBarry Smith PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 2029792fecdfSBarry Smith PetscCallBLAS("LAPACKgelss", LAPACKgelss_(&M, &N, &nrhs, A, &lda, Brhs, &ldb, (PetscReal *)tau, &rcond, &irank, tmpwork, &ldwork, &info)); 20309566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 2031c0ce001eSMatthew G. Knepley #endif 203228b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xGELSS error"); 2033c0ce001eSMatthew G. Knepley /* The following check should be turned into a diagnostic as soon as someone wants to do this intentionally */ 203408401ef6SPierre 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"); 2035c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2036c0ce001eSMatthew G. Knepley } 2037c0ce001eSMatthew G. Knepley 2038c0ce001eSMatthew G. Knepley #if 0 2039c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresDebugCell_Static(PetscFV fvm, PetscInt cell, DM dm, DM dmFace, PetscScalar *fgeom, DM dmCell, PetscScalar *cgeom) 2040c0ce001eSMatthew G. Knepley { 2041c0ce001eSMatthew G. Knepley PetscReal grad[2] = {0, 0}; 2042c0ce001eSMatthew G. Knepley const PetscInt *faces; 2043c0ce001eSMatthew G. Knepley PetscInt numFaces, f; 2044c0ce001eSMatthew G. Knepley 2045c0ce001eSMatthew G. Knepley PetscFunctionBegin; 20469566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, cell, &numFaces)); 20479566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, cell, &faces)); 2048c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2049c0ce001eSMatthew G. Knepley const PetscInt *fcells; 2050c0ce001eSMatthew G. Knepley const CellGeom *cg1; 2051c0ce001eSMatthew G. Knepley const FaceGeom *fg; 2052c0ce001eSMatthew G. Knepley 20539566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupport(dm, faces[f], &fcells)); 20549566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmFace, faces[f], fgeom, &fg)); 2055c0ce001eSMatthew G. Knepley for (i = 0; i < 2; ++i) { 2056c0ce001eSMatthew G. Knepley PetscScalar du; 2057c0ce001eSMatthew G. Knepley 2058c0ce001eSMatthew G. Knepley if (fcells[i] == c) continue; 20599566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmCell, fcells[i], cgeom, &cg1)); 2060c0ce001eSMatthew G. Knepley du = cg1->centroid[0] + 3*cg1->centroid[1] - (cg->centroid[0] + 3*cg->centroid[1]); 2061c0ce001eSMatthew G. Knepley grad[0] += fg->grad[!i][0] * du; 2062c0ce001eSMatthew G. Knepley grad[1] += fg->grad[!i][1] * du; 2063c0ce001eSMatthew G. Knepley } 2064c0ce001eSMatthew G. Knepley } 20659566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "cell[%d] grad (%g, %g)\n", cell, grad[0], grad[1])); 2066c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2067c0ce001eSMatthew G. Knepley } 2068c0ce001eSMatthew G. Knepley #endif 2069c0ce001eSMatthew G. Knepley 2070c0ce001eSMatthew G. Knepley /* 2071c0ce001eSMatthew G. Knepley PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell 2072c0ce001eSMatthew G. Knepley 2073c0ce001eSMatthew G. Knepley Input Parameters: 2074*dce8aebaSBarry Smith + fvm - The `PetscFV` object 2075c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained 2076c0ce001eSMatthew G. Knepley . dx - The vector from the cell centroid to the neighboring cell centroid for each face 2077c0ce001eSMatthew G. Knepley 2078c0ce001eSMatthew G. Knepley Level: developer 2079c0ce001eSMatthew G. Knepley 2080*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVCreate()` 2081c0ce001eSMatthew G. Knepley */ 2082d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVComputeGradient_LeastSquares(PetscFV fvm, PetscInt numFaces, const PetscScalar dx[], PetscScalar grad[]) 2083d71ae5a4SJacob Faibussowitsch { 2084c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data; 2085c0ce001eSMatthew G. Knepley const PetscBool useSVD = PETSC_TRUE; 2086c0ce001eSMatthew G. Knepley const PetscInt maxFaces = ls->maxFaces; 2087c0ce001eSMatthew G. Knepley PetscInt dim, f, d; 2088c0ce001eSMatthew G. Knepley 2089c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2090c0ce001eSMatthew G. Knepley if (numFaces > maxFaces) { 209108401ef6SPierre Jolivet PetscCheck(maxFaces >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Reconstruction has not been initialized, call PetscFVLeastSquaresSetMaxFaces()"); 209263a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of input faces %" PetscInt_FMT " > %" PetscInt_FMT " maxfaces", numFaces, maxFaces); 2093c0ce001eSMatthew G. Knepley } 20949566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 2095c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2096c0ce001eSMatthew G. Knepley for (d = 0; d < dim; ++d) ls->B[d * maxFaces + f] = dx[f * dim + d]; 2097c0ce001eSMatthew G. Knepley } 2098c0ce001eSMatthew G. Knepley /* Overwrites B with garbage, returns Binv in row-major format */ 2099736d4f42SpierreXVI if (useSVD) { 2100736d4f42SpierreXVI PetscInt maxmn = PetscMax(numFaces, dim); 21019566063dSJacob Faibussowitsch PetscCall(PetscFVLeastSquaresPseudoInverseSVD_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work)); 2102736d4f42SpierreXVI /* Binv shaped in column-major, coldim=maxmn.*/ 2103736d4f42SpierreXVI for (f = 0; f < numFaces; ++f) { 2104736d4f42SpierreXVI for (d = 0; d < dim; ++d) grad[f * dim + d] = ls->Binv[d + maxmn * f]; 2105736d4f42SpierreXVI } 2106736d4f42SpierreXVI } else { 21079566063dSJacob Faibussowitsch PetscCall(PetscFVLeastSquaresPseudoInverse_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work)); 2108736d4f42SpierreXVI /* Binv shaped in row-major, rowdim=maxFaces.*/ 2109c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2110c0ce001eSMatthew G. Knepley for (d = 0; d < dim; ++d) grad[f * dim + d] = ls->Binv[d * maxFaces + f]; 2111c0ce001eSMatthew G. Knepley } 2112736d4f42SpierreXVI } 2113c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2114c0ce001eSMatthew G. Knepley } 2115c0ce001eSMatthew G. Knepley 2116c0ce001eSMatthew G. Knepley /* 2117c0ce001eSMatthew G. Knepley neighborVol[f*2+0] contains the left geom 2118c0ce001eSMatthew G. Knepley neighborVol[f*2+1] contains the right geom 2119c0ce001eSMatthew G. Knepley */ 2120d71ae5a4SJacob 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[]) 2121d71ae5a4SJacob Faibussowitsch { 2122c0ce001eSMatthew G. Knepley void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *); 2123c0ce001eSMatthew G. Knepley void *rctx; 2124c0ce001eSMatthew G. Knepley PetscScalar *flux = fvm->fluxWork; 2125c0ce001eSMatthew G. Knepley const PetscScalar *constants; 2126c0ce001eSMatthew G. Knepley PetscInt dim, numConstants, pdim, Nc, totDim, off, f, d; 2127c0ce001eSMatthew G. Knepley 2128c0ce001eSMatthew G. Knepley PetscFunctionBegin; 21299566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalComponents(prob, &Nc)); 21309566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalDimension(prob, &totDim)); 21319566063dSJacob Faibussowitsch PetscCall(PetscDSGetFieldOffset(prob, field, &off)); 21329566063dSJacob Faibussowitsch PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann)); 21339566063dSJacob Faibussowitsch PetscCall(PetscDSGetContext(prob, field, &rctx)); 21349566063dSJacob Faibussowitsch PetscCall(PetscDSGetConstants(prob, &numConstants, &constants)); 21359566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 21369566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &pdim)); 2137c0ce001eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2138c0ce001eSMatthew G. Knepley (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f * Nc], &uR[f * Nc], numConstants, constants, flux, rctx); 2139c0ce001eSMatthew G. Knepley for (d = 0; d < pdim; ++d) { 2140c0ce001eSMatthew G. Knepley fluxL[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 0]; 2141c0ce001eSMatthew G. Knepley fluxR[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 1]; 2142c0ce001eSMatthew G. Knepley } 2143c0ce001eSMatthew G. Knepley } 2144c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2145c0ce001eSMatthew G. Knepley } 2146c0ce001eSMatthew G. Knepley 2147d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresSetMaxFaces_LS(PetscFV fvm, PetscInt maxFaces) 2148d71ae5a4SJacob Faibussowitsch { 2149c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data; 2150736d4f42SpierreXVI PetscInt dim, m, n, nrhs, minmn, maxmn; 2151c0ce001eSMatthew G. Knepley 2152c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2153c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 21549566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 21559566063dSJacob Faibussowitsch PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work)); 2156c0ce001eSMatthew G. Knepley ls->maxFaces = maxFaces; 2157c0ce001eSMatthew G. Knepley m = ls->maxFaces; 2158c0ce001eSMatthew G. Knepley n = dim; 2159c0ce001eSMatthew G. Knepley nrhs = ls->maxFaces; 2160736d4f42SpierreXVI minmn = PetscMin(m, n); 2161736d4f42SpierreXVI maxmn = PetscMax(m, n); 2162736d4f42SpierreXVI ls->workSize = 3 * minmn + PetscMax(2 * minmn, PetscMax(maxmn, nrhs)); /* required by LAPACK */ 21639566063dSJacob Faibussowitsch PetscCall(PetscMalloc4(m * n, &ls->B, maxmn * maxmn, &ls->Binv, minmn, &ls->tau, ls->workSize, &ls->work)); 2164c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2165c0ce001eSMatthew G. Knepley } 2166c0ce001eSMatthew G. Knepley 2167d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVInitialize_LeastSquares(PetscFV fvm) 2168d71ae5a4SJacob Faibussowitsch { 2169c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2170c0ce001eSMatthew G. Knepley fvm->ops->setfromoptions = NULL; 2171c0ce001eSMatthew G. Knepley fvm->ops->setup = PetscFVSetUp_LeastSquares; 2172c0ce001eSMatthew G. Knepley fvm->ops->view = PetscFVView_LeastSquares; 2173c0ce001eSMatthew G. Knepley fvm->ops->destroy = PetscFVDestroy_LeastSquares; 2174c0ce001eSMatthew G. Knepley fvm->ops->computegradient = PetscFVComputeGradient_LeastSquares; 2175c0ce001eSMatthew G. Knepley fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_LeastSquares; 2176c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2177c0ce001eSMatthew G. Knepley } 2178c0ce001eSMatthew G. Knepley 2179c0ce001eSMatthew G. Knepley /*MC 2180*dce8aebaSBarry Smith PETSCFVLEASTSQUARES = "leastsquares" - A `PetscFV` implementation 2181c0ce001eSMatthew G. Knepley 2182c0ce001eSMatthew G. Knepley Level: intermediate 2183c0ce001eSMatthew G. Knepley 2184*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 2185c0ce001eSMatthew G. Knepley M*/ 2186c0ce001eSMatthew G. Knepley 2187d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscFVCreate_LeastSquares(PetscFV fvm) 2188d71ae5a4SJacob Faibussowitsch { 2189c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls; 2190c0ce001eSMatthew G. Knepley 2191c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2192c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 21934dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&ls)); 2194c0ce001eSMatthew G. Knepley fvm->data = ls; 2195c0ce001eSMatthew G. Knepley 2196c0ce001eSMatthew G. Knepley ls->maxFaces = -1; 2197c0ce001eSMatthew G. Knepley ls->workSize = -1; 2198c0ce001eSMatthew G. Knepley ls->B = NULL; 2199c0ce001eSMatthew G. Knepley ls->Binv = NULL; 2200c0ce001eSMatthew G. Knepley ls->tau = NULL; 2201c0ce001eSMatthew G. Knepley ls->work = NULL; 2202c0ce001eSMatthew G. Knepley 22039566063dSJacob Faibussowitsch PetscCall(PetscFVSetComputeGradients(fvm, PETSC_TRUE)); 22049566063dSJacob Faibussowitsch PetscCall(PetscFVInitialize_LeastSquares(fvm)); 22059566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fvm, "PetscFVLeastSquaresSetMaxFaces_C", PetscFVLeastSquaresSetMaxFaces_LS)); 2206c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2207c0ce001eSMatthew G. Knepley } 2208c0ce001eSMatthew G. Knepley 2209c0ce001eSMatthew G. Knepley /*@ 2210c0ce001eSMatthew G. Knepley PetscFVLeastSquaresSetMaxFaces - Set the maximum number of cell faces for gradient reconstruction 2211c0ce001eSMatthew G. Knepley 2212c0ce001eSMatthew G. Knepley Not collective 2213c0ce001eSMatthew G. Knepley 2214c0ce001eSMatthew G. Knepley Input parameters: 2215*dce8aebaSBarry Smith + fvm - The `PetscFV` object 2216c0ce001eSMatthew G. Knepley - maxFaces - The maximum number of cell faces 2217c0ce001eSMatthew G. Knepley 2218c0ce001eSMatthew G. Knepley Level: intermediate 2219c0ce001eSMatthew G. Knepley 2220*dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVCreate()`, `PETSCFVLEASTSQUARES`, `PetscFVComputeGradient()` 2221c0ce001eSMatthew G. Knepley @*/ 2222d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVLeastSquaresSetMaxFaces(PetscFV fvm, PetscInt maxFaces) 2223d71ae5a4SJacob Faibussowitsch { 2224c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2225c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 2226cac4c232SBarry Smith PetscTryMethod(fvm, "PetscFVLeastSquaresSetMaxFaces_C", (PetscFV, PetscInt), (fvm, maxFaces)); 2227c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2228c0ce001eSMatthew G. Knepley } 2229