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 20dce8aebaSBarry Smith PetscLimiterRegister - Adds a new `PetscLimiter` implementation 21c0ce001eSMatthew G. Knepley 22c0ce001eSMatthew G. Knepley Not Collective 23c0ce001eSMatthew G. Knepley 24c0ce001eSMatthew G. Knepley Input Parameters: 252fe279fdSBarry Smith + sname - The name of a new user-defined creation routine 262fe279fdSBarry Smith - function - The creation routine 27c0ce001eSMatthew G. Knepley 2860225df5SJacob Faibussowitsch Example Usage: 29c0ce001eSMatthew G. Knepley .vb 30c0ce001eSMatthew G. Knepley PetscLimiterRegister("my_lim", MyPetscLimiterCreate); 31c0ce001eSMatthew G. Knepley .ve 32c0ce001eSMatthew G. Knepley 33dce8aebaSBarry 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 45dce8aebaSBarry Smith Note: 46dce8aebaSBarry Smith `PetscLimiterRegister()` may be called multiple times to add several user-defined PetscLimiters 47c0ce001eSMatthew G. Knepley 48dce8aebaSBarry 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)); 543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 55c0ce001eSMatthew G. Knepley } 56c0ce001eSMatthew G. Knepley 57c0ce001eSMatthew G. Knepley /*@C 58dce8aebaSBarry Smith PetscLimiterSetType - Builds a `PetscLimiter` for a given `PetscLimiterType` 59c0ce001eSMatthew G. Knepley 6020f4b53cSBarry Smith Collective 61c0ce001eSMatthew G. Knepley 62c0ce001eSMatthew G. Knepley Input Parameters: 63dce8aebaSBarry 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 71dce8aebaSBarry 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)); 813ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 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)); 933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 94c0ce001eSMatthew G. Knepley } 95c0ce001eSMatthew G. Knepley 96c0ce001eSMatthew G. Knepley /*@C 97dce8aebaSBarry 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: 102dce8aebaSBarry Smith . lim - The `PetscLimiter` 103c0ce001eSMatthew G. Knepley 104c0ce001eSMatthew G. Knepley Output Parameter: 105dce8aebaSBarry Smith . name - The `PetscLimiterType` 106c0ce001eSMatthew G. Knepley 107c0ce001eSMatthew G. Knepley Level: intermediate 108c0ce001eSMatthew G. Knepley 109dce8aebaSBarry 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); 1154f572ea9SToby Isaac PetscAssertPointer(name, 2); 1169566063dSJacob Faibussowitsch PetscCall(PetscLimiterRegisterAll()); 117c0ce001eSMatthew G. Knepley *name = ((PetscObject)lim)->type_name; 1183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 119c0ce001eSMatthew G. Knepley } 120c0ce001eSMatthew G. Knepley 121c0ce001eSMatthew G. Knepley /*@C 122dce8aebaSBarry Smith PetscLimiterViewFromOptions - View a `PetscLimiter` based on values in the options database 123fe2efc57SMark 12420f4b53cSBarry Smith Collective 125fe2efc57SMark 126fe2efc57SMark Input Parameters: 127dce8aebaSBarry Smith + A - the `PetscLimiter` object to view 128dce8aebaSBarry Smith . obj - Optional object that provides the options prefix to use 129dce8aebaSBarry Smith - name - command line option name 130fe2efc57SMark 131fe2efc57SMark Level: intermediate 132dce8aebaSBarry Smith 133dce8aebaSBarry 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)); 1403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 141fe2efc57SMark } 142fe2efc57SMark 143fe2efc57SMark /*@C 144dce8aebaSBarry Smith PetscLimiterView - Views a `PetscLimiter` 145c0ce001eSMatthew G. Knepley 14620f4b53cSBarry Smith Collective 147c0ce001eSMatthew G. Knepley 148d8d19677SJose E. Roman Input Parameters: 149dce8aebaSBarry Smith + lim - the `PetscLimiter` object to view 150c0ce001eSMatthew G. Knepley - v - the viewer 151c0ce001eSMatthew G. Knepley 15288f5f89eSMatthew G. Knepley Level: beginner 153c0ce001eSMatthew G. Knepley 154dce8aebaSBarry 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); 1623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 163c0ce001eSMatthew G. Knepley } 164c0ce001eSMatthew G. Knepley 165c0ce001eSMatthew G. Knepley /*@ 166dce8aebaSBarry Smith PetscLimiterSetFromOptions - sets parameters in a `PetscLimiter` from the options database 167c0ce001eSMatthew G. Knepley 16820f4b53cSBarry Smith Collective 169c0ce001eSMatthew G. Knepley 170c0ce001eSMatthew G. Knepley Input Parameter: 171dce8aebaSBarry Smith . lim - the `PetscLimiter` object to set options for 172c0ce001eSMatthew G. Knepley 17388f5f89eSMatthew G. Knepley Level: intermediate 174c0ce001eSMatthew G. Knepley 175dce8aebaSBarry 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")); 2013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 202c0ce001eSMatthew G. Knepley } 203c0ce001eSMatthew G. Knepley 204c0ce001eSMatthew G. Knepley /*@C 205dce8aebaSBarry Smith PetscLimiterSetUp - Construct data structures for the `PetscLimiter` 206c0ce001eSMatthew G. Knepley 20720f4b53cSBarry Smith Collective 208c0ce001eSMatthew G. Knepley 209c0ce001eSMatthew G. Knepley Input Parameter: 210dce8aebaSBarry Smith . lim - the `PetscLimiter` object to setup 211c0ce001eSMatthew G. Knepley 21288f5f89eSMatthew G. Knepley Level: intermediate 213c0ce001eSMatthew G. Knepley 214dce8aebaSBarry 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); 2213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 222c0ce001eSMatthew G. Knepley } 223c0ce001eSMatthew G. Knepley 224c0ce001eSMatthew G. Knepley /*@ 225dce8aebaSBarry Smith PetscLimiterDestroy - Destroys a `PetscLimiter` object 226c0ce001eSMatthew G. Knepley 22720f4b53cSBarry Smith Collective 228c0ce001eSMatthew G. Knepley 229c0ce001eSMatthew G. Knepley Input Parameter: 230dce8aebaSBarry Smith . lim - the `PetscLimiter` object to destroy 231c0ce001eSMatthew G. Knepley 23288f5f89eSMatthew G. Knepley Level: beginner 233c0ce001eSMatthew G. Knepley 234dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterView()` 235c0ce001eSMatthew G. Knepley @*/ 236d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterDestroy(PetscLimiter *lim) 237d71ae5a4SJacob Faibussowitsch { 238c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2393ba16761SJacob Faibussowitsch if (!*lim) PetscFunctionReturn(PETSC_SUCCESS); 240c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific((*lim), PETSCLIMITER_CLASSID, 1); 241c0ce001eSMatthew G. Knepley 2429371c9d4SSatish Balay if (--((PetscObject)(*lim))->refct > 0) { 2439371c9d4SSatish Balay *lim = NULL; 2443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2459371c9d4SSatish Balay } 246c0ce001eSMatthew G. Knepley ((PetscObject)(*lim))->refct = 0; 247c0ce001eSMatthew G. Knepley 248dbbe0bcdSBarry Smith PetscTryTypeMethod((*lim), destroy); 2499566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(lim)); 2503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 251c0ce001eSMatthew G. Knepley } 252c0ce001eSMatthew G. Knepley 253c0ce001eSMatthew G. Knepley /*@ 254dce8aebaSBarry 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: 259dce8aebaSBarry Smith . comm - The communicator for the `PetscLimiter` object 260c0ce001eSMatthew G. Knepley 261c0ce001eSMatthew G. Knepley Output Parameter: 262dce8aebaSBarry Smith . lim - The `PetscLimiter` object 263c0ce001eSMatthew G. Knepley 264c0ce001eSMatthew G. Knepley Level: beginner 265c0ce001eSMatthew G. Knepley 26660225df5SJacob Faibussowitsch .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; 2734f572ea9SToby Isaac PetscAssertPointer(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; 2813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 282c0ce001eSMatthew G. Knepley } 283c0ce001eSMatthew G. Knepley 28488f5f89eSMatthew G. Knepley /*@ 28588f5f89eSMatthew G. Knepley PetscLimiterLimit - Limit the flux 28688f5f89eSMatthew G. Knepley 28788f5f89eSMatthew G. Knepley Input Parameters: 288dce8aebaSBarry 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 296dce8aebaSBarry Smith Note: 297dce8aebaSBarry Smith Limiters given in symmetric form following Berger, Aftosmis, and Murman 2005 298dce8aebaSBarry Smith .vb 299dce8aebaSBarry Smith The classical flux-limited formulation is psi(r) where 300dce8aebaSBarry Smith 301dce8aebaSBarry Smith r = (u[0] - u[-1]) / (u[1] - u[0]) 302dce8aebaSBarry Smith 303dce8aebaSBarry Smith The second order TVD region is bounded by 304dce8aebaSBarry Smith 305dce8aebaSBarry Smith psi_minmod(r) = min(r,1) and psi_superbee(r) = min(2, 2r, max(1,r)) 306dce8aebaSBarry Smith 307dce8aebaSBarry Smith where all limiters are implicitly clipped to be non-negative. A more convenient slope-limited form is psi(r) = 308dce8aebaSBarry Smith phi(r)(r+1)/2 in which the reconstructed interface values are 309dce8aebaSBarry Smith 310dce8aebaSBarry Smith u(v) = u[0] + phi(r) (grad u)[0] v 311dce8aebaSBarry Smith 312dce8aebaSBarry Smith where v is the vector from centroid to quadrature point. In these variables, the usual limiters become 313dce8aebaSBarry Smith 314dce8aebaSBarry 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)) 315dce8aebaSBarry Smith 316dce8aebaSBarry Smith For a nicer symmetric formulation, rewrite in terms of 317dce8aebaSBarry Smith 318dce8aebaSBarry Smith f = (u[0] - u[-1]) / (u[1] - u[-1]) 319dce8aebaSBarry Smith 320dce8aebaSBarry Smith where r(f) = f/(1-f). Not that r(1-f) = (1-f)/f = 1/r(f) so the symmetry condition 321dce8aebaSBarry Smith 322dce8aebaSBarry Smith phi(r) = phi(1/r) 323dce8aebaSBarry Smith 324dce8aebaSBarry Smith becomes 325dce8aebaSBarry Smith 326dce8aebaSBarry Smith w(f) = w(1-f). 327dce8aebaSBarry Smith 328dce8aebaSBarry Smith The limiters below implement this final form w(f). The reference methods are 329dce8aebaSBarry Smith 330dce8aebaSBarry Smith w_minmod(f) = 2 min(f,(1-f)) w_superbee(r) = 4 min((1-f), f) 331dce8aebaSBarry Smith .ve 332dce8aebaSBarry Smith 333dce8aebaSBarry 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); 3394f572ea9SToby Isaac PetscAssertPointer(phi, 3); 340dbbe0bcdSBarry Smith PetscUseTypeMethod(lim, limit, flim, phi); 3413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 3503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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")); 3603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 3723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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))); 3793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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; 3883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 389c0ce001eSMatthew G. Knepley } 390c0ce001eSMatthew G. Knepley 391c0ce001eSMatthew G. Knepley /*MC 392dce8aebaSBarry Smith PETSCLIMITERSIN = "sin" - A `PetscLimiter` implementation 393c0ce001eSMatthew G. Knepley 394c0ce001eSMatthew G. Knepley Level: intermediate 395c0ce001eSMatthew G. Knepley 396dce8aebaSBarry 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)); 4093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 4183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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")); 4283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 4403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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; 4473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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; 4563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 457c0ce001eSMatthew G. Knepley } 458c0ce001eSMatthew G. Knepley 459c0ce001eSMatthew G. Knepley /*MC 460dce8aebaSBarry Smith PETSCLIMITERZERO = "zero" - A simple `PetscLimiter` implementation 461c0ce001eSMatthew G. Knepley 462c0ce001eSMatthew G. Knepley Level: intermediate 463c0ce001eSMatthew G. Knepley 464dce8aebaSBarry 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)); 4773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 4863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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")); 4963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 5083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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; 5153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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; 5243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 525c0ce001eSMatthew G. Knepley } 526c0ce001eSMatthew G. Knepley 527c0ce001eSMatthew G. Knepley /*MC 528dce8aebaSBarry Smith PETSCLIMITERNONE = "none" - A trivial `PetscLimiter` implementation 529c0ce001eSMatthew G. Knepley 530c0ce001eSMatthew G. Knepley Level: intermediate 531c0ce001eSMatthew G. Knepley 532dce8aebaSBarry 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)); 5453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 5543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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")); 5643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 5763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 5833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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; 5923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 593c0ce001eSMatthew G. Knepley } 594c0ce001eSMatthew G. Knepley 595c0ce001eSMatthew G. Knepley /*MC 596dce8aebaSBarry Smith PETSCLIMITERMINMOD = "minmod" - A `PetscLimiter` implementation 597c0ce001eSMatthew G. Knepley 598c0ce001eSMatthew G. Knepley Level: intermediate 599c0ce001eSMatthew G. Knepley 600dce8aebaSBarry 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)); 6133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 6223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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")); 6323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 6443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 6513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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; 6603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 661c0ce001eSMatthew G. Knepley } 662c0ce001eSMatthew G. Knepley 663c0ce001eSMatthew G. Knepley /*MC 664dce8aebaSBarry Smith PETSCLIMITERVANLEER = "vanleer" - A `PetscLimiter` implementation 665c0ce001eSMatthew G. Knepley 666c0ce001eSMatthew G. Knepley Level: intermediate 667c0ce001eSMatthew G. Knepley 668dce8aebaSBarry 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)); 6813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 6903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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")); 7003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 7123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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))); 7193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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; 7283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 729c0ce001eSMatthew G. Knepley } 730c0ce001eSMatthew G. Knepley 731c0ce001eSMatthew G. Knepley /*MC 732dce8aebaSBarry Smith PETSCLIMITERVANALBADA = "vanalbada" - A PetscLimiter implementation 733c0ce001eSMatthew G. Knepley 734c0ce001eSMatthew G. Knepley Level: intermediate 735c0ce001eSMatthew G. Knepley 736dce8aebaSBarry 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)); 7493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 7583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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")); 7683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 7803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 7873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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; 7963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 797c0ce001eSMatthew G. Knepley } 798c0ce001eSMatthew G. Knepley 799c0ce001eSMatthew G. Knepley /*MC 800dce8aebaSBarry Smith PETSCLIMITERSUPERBEE = "superbee" - A `PetscLimiter` implementation 801c0ce001eSMatthew G. Knepley 802c0ce001eSMatthew G. Knepley Level: intermediate 803c0ce001eSMatthew G. Knepley 804dce8aebaSBarry 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)); 8173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 8263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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")); 8363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 8483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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))); 8563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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; 8653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 866c0ce001eSMatthew G. Knepley } 867c0ce001eSMatthew G. Knepley 868c0ce001eSMatthew G. Knepley /*MC 869dce8aebaSBarry Smith PETSCLIMITERMC = "mc" - A `PetscLimiter` implementation 870c0ce001eSMatthew G. Knepley 871c0ce001eSMatthew G. Knepley Level: intermediate 872c0ce001eSMatthew G. Knepley 873dce8aebaSBarry 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)); 8863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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 895dce8aebaSBarry Smith PetscFVRegister - Adds a new `PetscFV` implementation 896c0ce001eSMatthew G. Knepley 897c0ce001eSMatthew G. Knepley Not Collective 898c0ce001eSMatthew G. Knepley 899c0ce001eSMatthew G. Knepley Input Parameters: 9002fe279fdSBarry Smith + sname - The name of a new user-defined creation routine 9012fe279fdSBarry Smith - function - The creation routine itself 902c0ce001eSMatthew G. Knepley 90360225df5SJacob Faibussowitsch Example 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 920dce8aebaSBarry Smith Note: 921dce8aebaSBarry Smith `PetscFVRegister()` may be called multiple times to add several user-defined PetscFVs 922c0ce001eSMatthew G. Knepley 923dce8aebaSBarry 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)); 9293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 930c0ce001eSMatthew G. Knepley } 931c0ce001eSMatthew G. Knepley 932c0ce001eSMatthew G. Knepley /*@C 933dce8aebaSBarry Smith PetscFVSetType - Builds a particular `PetscFV` 934c0ce001eSMatthew G. Knepley 93520f4b53cSBarry Smith Collective 936c0ce001eSMatthew G. Knepley 937c0ce001eSMatthew G. Knepley Input Parameters: 938dce8aebaSBarry Smith + fvm - The `PetscFV` object 939dce8aebaSBarry Smith - name - The type of FVM space 940c0ce001eSMatthew G. Knepley 941c0ce001eSMatthew G. Knepley Options Database Key: 942dce8aebaSBarry 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 946dce8aebaSBarry 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)); 9563ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 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)); 9673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 968c0ce001eSMatthew G. Knepley } 969c0ce001eSMatthew G. Knepley 970c0ce001eSMatthew G. Knepley /*@C 971dce8aebaSBarry 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: 976dce8aebaSBarry Smith . fvm - The `PetscFV` 977c0ce001eSMatthew G. Knepley 978c0ce001eSMatthew G. Knepley Output Parameter: 979dce8aebaSBarry Smith . name - The `PetscFVType` name 980c0ce001eSMatthew G. Knepley 981c0ce001eSMatthew G. Knepley Level: intermediate 982c0ce001eSMatthew G. Knepley 983dce8aebaSBarry 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); 9894f572ea9SToby Isaac PetscAssertPointer(name, 2); 9909566063dSJacob Faibussowitsch PetscCall(PetscFVRegisterAll()); 991c0ce001eSMatthew G. Knepley *name = ((PetscObject)fvm)->type_name; 9923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 993c0ce001eSMatthew G. Knepley } 994c0ce001eSMatthew G. Knepley 995c0ce001eSMatthew G. Knepley /*@C 996dce8aebaSBarry Smith PetscFVViewFromOptions - View a `PetscFV` based on values in the options database 997fe2efc57SMark 99820f4b53cSBarry Smith Collective 999fe2efc57SMark 1000fe2efc57SMark Input Parameters: 1001dce8aebaSBarry Smith + A - the `PetscFV` object 1002dce8aebaSBarry Smith . obj - Optional object that provides the options prefix 1003dce8aebaSBarry Smith - name - command line option name 1004fe2efc57SMark 1005fe2efc57SMark Level: intermediate 1006dce8aebaSBarry Smith 1007dce8aebaSBarry 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)); 10143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1015fe2efc57SMark } 1016fe2efc57SMark 1017fe2efc57SMark /*@C 1018dce8aebaSBarry Smith PetscFVView - Views a `PetscFV` 1019c0ce001eSMatthew G. Knepley 102020f4b53cSBarry Smith Collective 1021c0ce001eSMatthew G. Knepley 1022d8d19677SJose E. Roman Input Parameters: 1023dce8aebaSBarry Smith + fvm - the `PetscFV` object to view 1024c0ce001eSMatthew G. Knepley - v - the viewer 1025c0ce001eSMatthew G. Knepley 102688f5f89eSMatthew G. Knepley Level: beginner 1027c0ce001eSMatthew G. Knepley 1028dce8aebaSBarry 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); 10363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1037c0ce001eSMatthew G. Knepley } 1038c0ce001eSMatthew G. Knepley 1039c0ce001eSMatthew G. Knepley /*@ 1040dce8aebaSBarry Smith PetscFVSetFromOptions - sets parameters in a `PetscFV` from the options database 1041c0ce001eSMatthew G. Knepley 104220f4b53cSBarry Smith Collective 1043c0ce001eSMatthew G. Knepley 1044c0ce001eSMatthew G. Knepley Input Parameter: 1045dce8aebaSBarry 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 1052dce8aebaSBarry 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")); 10803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1081c0ce001eSMatthew G. Knepley } 1082c0ce001eSMatthew G. Knepley 1083c0ce001eSMatthew G. Knepley /*@ 1084dce8aebaSBarry Smith PetscFVSetUp - Setup the data structures for the `PetscFV` based on the `PetscFVType` provided by `PetscFVSetType()` 1085c0ce001eSMatthew G. Knepley 108620f4b53cSBarry Smith Collective 1087c0ce001eSMatthew G. Knepley 1088c0ce001eSMatthew G. Knepley Input Parameter: 1089dce8aebaSBarry Smith . fvm - the `PetscFV` object to setup 1090c0ce001eSMatthew G. Knepley 109188f5f89eSMatthew G. Knepley Level: intermediate 1092c0ce001eSMatthew G. Knepley 1093dce8aebaSBarry 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); 11013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1102c0ce001eSMatthew G. Knepley } 1103c0ce001eSMatthew G. Knepley 1104c0ce001eSMatthew G. Knepley /*@ 1105dce8aebaSBarry Smith PetscFVDestroy - Destroys a `PetscFV` object 1106c0ce001eSMatthew G. Knepley 110720f4b53cSBarry Smith Collective 1108c0ce001eSMatthew G. Knepley 1109c0ce001eSMatthew G. Knepley Input Parameter: 1110dce8aebaSBarry Smith . fvm - the `PetscFV` object to destroy 1111c0ce001eSMatthew G. Knepley 111288f5f89eSMatthew G. Knepley Level: beginner 1113c0ce001eSMatthew G. Knepley 1114dce8aebaSBarry 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; 11213ba16761SJacob Faibussowitsch if (!*fvm) PetscFunctionReturn(PETSC_SUCCESS); 1122c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific((*fvm), PETSCFV_CLASSID, 1); 1123c0ce001eSMatthew G. Knepley 11249371c9d4SSatish Balay if (--((PetscObject)(*fvm))->refct > 0) { 11259371c9d4SSatish Balay *fvm = NULL; 11263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 11403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1141c0ce001eSMatthew G. Knepley } 1142c0ce001eSMatthew G. Knepley 1143c0ce001eSMatthew G. Knepley /*@ 1144dce8aebaSBarry 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: 1149dce8aebaSBarry Smith . comm - The communicator for the `PetscFV` object 1150c0ce001eSMatthew G. Knepley 1151c0ce001eSMatthew G. Knepley Output Parameter: 1152dce8aebaSBarry Smith . fvm - The `PetscFV` object 1153c0ce001eSMatthew G. Knepley 1154c0ce001eSMatthew G. Knepley Level: beginner 1155c0ce001eSMatthew G. Knepley 1156*1d27aa22SBarry Smith .seealso: `PetscFVSetUp()`, `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; 11634f572ea9SToby Isaac PetscAssertPointer(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; 11783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1179c0ce001eSMatthew G. Knepley } 1180c0ce001eSMatthew G. Knepley 1181c0ce001eSMatthew G. Knepley /*@ 1182dce8aebaSBarry Smith PetscFVSetLimiter - Set the `PetscLimiter` to the `PetscFV` 1183c0ce001eSMatthew G. Knepley 118420f4b53cSBarry Smith Logically Collective 1185c0ce001eSMatthew G. Knepley 1186c0ce001eSMatthew G. Knepley Input Parameters: 1187dce8aebaSBarry Smith + fvm - the `PetscFV` object 1188dce8aebaSBarry Smith - lim - The `PetscLimiter` 1189c0ce001eSMatthew G. Knepley 119088f5f89eSMatthew G. Knepley Level: intermediate 1191c0ce001eSMatthew G. Knepley 1192dce8aebaSBarry 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; 12023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1203c0ce001eSMatthew G. Knepley } 1204c0ce001eSMatthew G. Knepley 1205c0ce001eSMatthew G. Knepley /*@ 1206dce8aebaSBarry Smith PetscFVGetLimiter - Get the `PetscLimiter` object from the `PetscFV` 1207c0ce001eSMatthew G. Knepley 120820f4b53cSBarry Smith Not Collective 1209c0ce001eSMatthew G. Knepley 1210c0ce001eSMatthew G. Knepley Input Parameter: 1211dce8aebaSBarry Smith . fvm - the `PetscFV` object 1212c0ce001eSMatthew G. Knepley 1213c0ce001eSMatthew G. Knepley Output Parameter: 1214dce8aebaSBarry Smith . lim - The `PetscLimiter` 1215c0ce001eSMatthew G. Knepley 121688f5f89eSMatthew G. Knepley Level: intermediate 1217c0ce001eSMatthew G. Knepley 1218dce8aebaSBarry 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); 12244f572ea9SToby Isaac PetscAssertPointer(lim, 2); 1225c0ce001eSMatthew G. Knepley *lim = fvm->limiter; 12263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1227c0ce001eSMatthew G. Knepley } 1228c0ce001eSMatthew G. Knepley 1229c0ce001eSMatthew G. Knepley /*@ 1230dce8aebaSBarry Smith PetscFVSetNumComponents - Set the number of field components in a `PetscFV` 1231c0ce001eSMatthew G. Knepley 123220f4b53cSBarry Smith Logically Collective 1233c0ce001eSMatthew G. Knepley 1234c0ce001eSMatthew G. Knepley Input Parameters: 1235dce8aebaSBarry Smith + fvm - the `PetscFV` object 1236c0ce001eSMatthew G. Knepley - comp - The number of components 1237c0ce001eSMatthew G. Knepley 123888f5f89eSMatthew G. Knepley Level: intermediate 1239c0ce001eSMatthew G. Knepley 1240dce8aebaSBarry 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)); 12563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1257c0ce001eSMatthew G. Knepley } 1258c0ce001eSMatthew G. Knepley 1259c0ce001eSMatthew G. Knepley /*@ 1260dce8aebaSBarry Smith PetscFVGetNumComponents - Get the number of field components in a `PetscFV` 1261c0ce001eSMatthew G. Knepley 126220f4b53cSBarry Smith Not Collective 1263c0ce001eSMatthew G. Knepley 1264c0ce001eSMatthew G. Knepley Input Parameter: 1265dce8aebaSBarry Smith . fvm - the `PetscFV` object 1266c0ce001eSMatthew G. Knepley 1267c0ce001eSMatthew G. Knepley Output Parameter: 1268a4e35b19SJacob Faibussowitsch . comp - The number of components 1269c0ce001eSMatthew G. Knepley 127088f5f89eSMatthew G. Knepley Level: intermediate 1271c0ce001eSMatthew G. Knepley 1272dce8aebaSBarry 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); 12784f572ea9SToby Isaac PetscAssertPointer(comp, 2); 1279c0ce001eSMatthew G. Knepley *comp = fvm->numComponents; 12803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1281c0ce001eSMatthew G. Knepley } 1282c0ce001eSMatthew G. Knepley 1283c0ce001eSMatthew G. Knepley /*@C 1284dce8aebaSBarry Smith PetscFVSetComponentName - Set the name of a component (used in output and viewing) in a `PetscFV` 1285c0ce001eSMatthew G. Knepley 128620f4b53cSBarry Smith Logically Collective 1287dce8aebaSBarry Smith 1288c0ce001eSMatthew G. Knepley Input Parameters: 1289dce8aebaSBarry 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 1295dce8aebaSBarry 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])); 13023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1303c0ce001eSMatthew G. Knepley } 1304c0ce001eSMatthew G. Knepley 1305c0ce001eSMatthew G. Knepley /*@C 1306dce8aebaSBarry Smith PetscFVGetComponentName - Get the name of a component (used in output and viewing) in a `PetscFV` 1307c0ce001eSMatthew G. Knepley 130820f4b53cSBarry Smith Logically Collective 130960225df5SJacob Faibussowitsch 1310c0ce001eSMatthew G. Knepley Input Parameters: 1311dce8aebaSBarry Smith + fvm - the `PetscFV` object 1312c0ce001eSMatthew G. Knepley - comp - the component number 1313c0ce001eSMatthew G. Knepley 1314c0ce001eSMatthew G. Knepley Output Parameter: 1315c0ce001eSMatthew G. Knepley . name - the component name 1316c0ce001eSMatthew G. Knepley 131788f5f89eSMatthew G. Knepley Level: intermediate 1318c0ce001eSMatthew G. Knepley 1319dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVSetComponentName()` 1320c0ce001eSMatthew G. Knepley @*/ 1321d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetComponentName(PetscFV fvm, PetscInt comp, const char **name) 1322d71ae5a4SJacob Faibussowitsch { 1323c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1324c0ce001eSMatthew G. Knepley *name = fvm->componentNames[comp]; 13253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1326c0ce001eSMatthew G. Knepley } 1327c0ce001eSMatthew G. Knepley 1328c0ce001eSMatthew G. Knepley /*@ 1329dce8aebaSBarry Smith PetscFVSetSpatialDimension - Set the spatial dimension of a `PetscFV` 1330c0ce001eSMatthew G. Knepley 133120f4b53cSBarry Smith Logically Collective 1332c0ce001eSMatthew G. Knepley 1333c0ce001eSMatthew G. Knepley Input Parameters: 1334dce8aebaSBarry Smith + fvm - the `PetscFV` object 1335c0ce001eSMatthew G. Knepley - dim - The spatial dimension 1336c0ce001eSMatthew G. Knepley 133788f5f89eSMatthew G. Knepley Level: intermediate 1338c0ce001eSMatthew G. Knepley 1339dce8aebaSBarry Smith .seealso: `PetscFV`, ``PetscFVGetSpatialDimension()` 1340c0ce001eSMatthew G. Knepley @*/ 1341d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetSpatialDimension(PetscFV fvm, PetscInt dim) 1342d71ae5a4SJacob Faibussowitsch { 1343c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1344c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1345c0ce001eSMatthew G. Knepley fvm->dim = dim; 13463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1347c0ce001eSMatthew G. Knepley } 1348c0ce001eSMatthew G. Knepley 1349c0ce001eSMatthew G. Knepley /*@ 1350dce8aebaSBarry Smith PetscFVGetSpatialDimension - Get the spatial dimension of a `PetscFV` 1351c0ce001eSMatthew G. Knepley 135220f4b53cSBarry Smith Not Collective 1353c0ce001eSMatthew G. Knepley 1354c0ce001eSMatthew G. Knepley Input Parameter: 1355dce8aebaSBarry Smith . fvm - the `PetscFV` object 1356c0ce001eSMatthew G. Knepley 1357c0ce001eSMatthew G. Knepley Output Parameter: 1358c0ce001eSMatthew G. Knepley . dim - The spatial dimension 1359c0ce001eSMatthew G. Knepley 136088f5f89eSMatthew G. Knepley Level: intermediate 1361c0ce001eSMatthew G. Knepley 1362dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVSetSpatialDimension()` 1363c0ce001eSMatthew G. Knepley @*/ 1364d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetSpatialDimension(PetscFV fvm, PetscInt *dim) 1365d71ae5a4SJacob Faibussowitsch { 1366c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1367c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 13684f572ea9SToby Isaac PetscAssertPointer(dim, 2); 1369c0ce001eSMatthew G. Knepley *dim = fvm->dim; 13703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1371c0ce001eSMatthew G. Knepley } 1372c0ce001eSMatthew G. Knepley 1373c0ce001eSMatthew G. Knepley /*@ 1374dce8aebaSBarry Smith PetscFVSetComputeGradients - Toggle computation of cell gradients on a `PetscFV` 1375c0ce001eSMatthew G. Knepley 137620f4b53cSBarry Smith Logically Collective 1377c0ce001eSMatthew G. Knepley 1378c0ce001eSMatthew G. Knepley Input Parameters: 1379dce8aebaSBarry Smith + fvm - the `PetscFV` object 1380c0ce001eSMatthew G. Knepley - computeGradients - Flag to compute cell gradients 1381c0ce001eSMatthew G. Knepley 138288f5f89eSMatthew G. Knepley Level: intermediate 1383c0ce001eSMatthew G. Knepley 1384dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVGetComputeGradients()` 1385c0ce001eSMatthew G. Knepley @*/ 1386d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetComputeGradients(PetscFV fvm, PetscBool computeGradients) 1387d71ae5a4SJacob Faibussowitsch { 1388c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1389c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1390c0ce001eSMatthew G. Knepley fvm->computeGradients = computeGradients; 13913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1392c0ce001eSMatthew G. Knepley } 1393c0ce001eSMatthew G. Knepley 1394c0ce001eSMatthew G. Knepley /*@ 1395dce8aebaSBarry Smith PetscFVGetComputeGradients - Return flag for computation of cell gradients on a `PetscFV` 1396c0ce001eSMatthew G. Knepley 139720f4b53cSBarry Smith Not Collective 1398c0ce001eSMatthew G. Knepley 1399c0ce001eSMatthew G. Knepley Input Parameter: 1400dce8aebaSBarry Smith . fvm - the `PetscFV` object 1401c0ce001eSMatthew G. Knepley 1402c0ce001eSMatthew G. Knepley Output Parameter: 1403c0ce001eSMatthew G. Knepley . computeGradients - Flag to compute cell gradients 1404c0ce001eSMatthew G. Knepley 140588f5f89eSMatthew G. Knepley Level: intermediate 1406c0ce001eSMatthew G. Knepley 1407dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVSetComputeGradients()` 1408c0ce001eSMatthew G. Knepley @*/ 1409d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetComputeGradients(PetscFV fvm, PetscBool *computeGradients) 1410d71ae5a4SJacob Faibussowitsch { 1411c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1412c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 14134f572ea9SToby Isaac PetscAssertPointer(computeGradients, 2); 1414c0ce001eSMatthew G. Knepley *computeGradients = fvm->computeGradients; 14153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1416c0ce001eSMatthew G. Knepley } 1417c0ce001eSMatthew G. Knepley 1418c0ce001eSMatthew G. Knepley /*@ 1419dce8aebaSBarry Smith PetscFVSetQuadrature - Set the `PetscQuadrature` object for a `PetscFV` 1420c0ce001eSMatthew G. Knepley 142120f4b53cSBarry Smith Logically Collective 1422c0ce001eSMatthew G. Knepley 1423c0ce001eSMatthew G. Knepley Input Parameters: 1424dce8aebaSBarry Smith + fvm - the `PetscFV` object 1425dce8aebaSBarry Smith - q - The `PetscQuadrature` 1426c0ce001eSMatthew G. Knepley 142788f5f89eSMatthew G. Knepley Level: intermediate 1428c0ce001eSMatthew G. Knepley 1429dce8aebaSBarry Smith .seealso: `PetscQuadrature`, `PetscFV`, `PetscFVGetQuadrature()` 1430c0ce001eSMatthew G. Knepley @*/ 1431d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetQuadrature(PetscFV fvm, PetscQuadrature q) 1432d71ae5a4SJacob Faibussowitsch { 1433c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1434c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 14359566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&fvm->quadrature)); 14369566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)q)); 1437c0ce001eSMatthew G. Knepley fvm->quadrature = q; 14383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1439c0ce001eSMatthew G. Knepley } 1440c0ce001eSMatthew G. Knepley 1441c0ce001eSMatthew G. Knepley /*@ 1442dce8aebaSBarry Smith PetscFVGetQuadrature - Get the `PetscQuadrature` from a `PetscFV` 1443c0ce001eSMatthew G. Knepley 144420f4b53cSBarry Smith Not Collective 1445c0ce001eSMatthew G. Knepley 1446c0ce001eSMatthew G. Knepley Input Parameter: 1447dce8aebaSBarry Smith . fvm - the `PetscFV` object 1448c0ce001eSMatthew G. Knepley 1449c0ce001eSMatthew G. Knepley Output Parameter: 145060225df5SJacob Faibussowitsch . q - The `PetscQuadrature` 1451c0ce001eSMatthew G. Knepley 145288f5f89eSMatthew G. Knepley Level: intermediate 1453c0ce001eSMatthew G. Knepley 1454dce8aebaSBarry Smith .seealso: `PetscQuadrature`, `PetscFV`, `PetscFVSetQuadrature()` 1455c0ce001eSMatthew G. Knepley @*/ 1456d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetQuadrature(PetscFV fvm, PetscQuadrature *q) 1457d71ae5a4SJacob Faibussowitsch { 1458c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1459c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 14604f572ea9SToby Isaac PetscAssertPointer(q, 2); 1461c0ce001eSMatthew G. Knepley if (!fvm->quadrature) { 1462c0ce001eSMatthew G. Knepley /* Create default 1-point quadrature */ 1463c0ce001eSMatthew G. Knepley PetscReal *points, *weights; 1464c0ce001eSMatthew G. Knepley 14659566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &fvm->quadrature)); 14669566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(fvm->dim, &points)); 14679566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, &weights)); 1468c0ce001eSMatthew G. Knepley weights[0] = 1.0; 14699566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(fvm->quadrature, fvm->dim, 1, 1, points, weights)); 1470c0ce001eSMatthew G. Knepley } 1471c0ce001eSMatthew G. Knepley *q = fvm->quadrature; 14723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1473c0ce001eSMatthew G. Knepley } 1474c0ce001eSMatthew G. Knepley 1475c0ce001eSMatthew G. Knepley /*@ 1476dce8aebaSBarry Smith PetscFVGetDualSpace - Returns the `PetscDualSpace` used to define the inner product on a `PetscFV` 1477c0ce001eSMatthew G. Knepley 147820f4b53cSBarry Smith Not Collective 1479c0ce001eSMatthew G. Knepley 1480c0ce001eSMatthew G. Knepley Input Parameter: 1481dce8aebaSBarry Smith . fvm - The `PetscFV` object 1482c0ce001eSMatthew G. Knepley 1483c0ce001eSMatthew G. Knepley Output Parameter: 148420f4b53cSBarry Smith . sp - The `PetscDualSpace` object 1485c0ce001eSMatthew G. Knepley 148688f5f89eSMatthew G. Knepley Level: intermediate 1487c0ce001eSMatthew G. Knepley 148860225df5SJacob Faibussowitsch Developer Notes: 1489dce8aebaSBarry Smith There is overlap between the methods of `PetscFE` and `PetscFV`, they should probably share a common parent class 1490dce8aebaSBarry Smith 1491dce8aebaSBarry Smith .seealso: `PetscDualSpace`, `PetscFV`, `PetscFVCreate()` 1492c0ce001eSMatthew G. Knepley @*/ 1493d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetDualSpace(PetscFV fvm, PetscDualSpace *sp) 1494d71ae5a4SJacob Faibussowitsch { 1495c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1496c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 14974f572ea9SToby Isaac PetscAssertPointer(sp, 2); 1498c0ce001eSMatthew G. Knepley if (!fvm->dualSpace) { 1499c0ce001eSMatthew G. Knepley DM K; 1500c0ce001eSMatthew G. Knepley PetscInt dim, Nc, c; 1501c0ce001eSMatthew G. Knepley 15029566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 15039566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &Nc)); 15049566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceCreate(PetscObjectComm((PetscObject)fvm), &fvm->dualSpace)); 15059566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetType(fvm->dualSpace, PETSCDUALSPACESIMPLE)); 15069566063dSJacob Faibussowitsch PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, DMPolytopeTypeSimpleShape(dim, PETSC_FALSE), &K)); 15079566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetNumComponents(fvm->dualSpace, Nc)); 15089566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(fvm->dualSpace, K)); 15099566063dSJacob Faibussowitsch PetscCall(DMDestroy(&K)); 15109566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetDimension(fvm->dualSpace, Nc)); 1511c0ce001eSMatthew G. Knepley /* Should we be using PetscFVGetQuadrature() here? */ 1512c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; ++c) { 1513c0ce001eSMatthew G. Knepley PetscQuadrature qc; 1514c0ce001eSMatthew G. Knepley PetscReal *points, *weights; 1515c0ce001eSMatthew G. Knepley 15169566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qc)); 15179566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(dim, &points)); 15189566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nc, &weights)); 1519c0ce001eSMatthew G. Knepley weights[c] = 1.0; 15209566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(qc, dim, Nc, 1, points, weights)); 15219566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetFunctional(fvm->dualSpace, c, qc)); 15229566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qc)); 1523c0ce001eSMatthew G. Knepley } 15249566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(fvm->dualSpace)); 1525c0ce001eSMatthew G. Knepley } 1526c0ce001eSMatthew G. Knepley *sp = fvm->dualSpace; 15273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1528c0ce001eSMatthew G. Knepley } 1529c0ce001eSMatthew G. Knepley 1530c0ce001eSMatthew G. Knepley /*@ 1531dce8aebaSBarry Smith PetscFVSetDualSpace - Sets the `PetscDualSpace` used to define the inner product 1532c0ce001eSMatthew G. Knepley 153320f4b53cSBarry Smith Not Collective 1534c0ce001eSMatthew G. Knepley 1535c0ce001eSMatthew G. Knepley Input Parameters: 1536dce8aebaSBarry Smith + fvm - The `PetscFV` object 1537dce8aebaSBarry Smith - sp - The `PetscDualSpace` object 1538c0ce001eSMatthew G. Knepley 1539c0ce001eSMatthew G. Knepley Level: intermediate 1540c0ce001eSMatthew G. Knepley 1541dce8aebaSBarry Smith Note: 1542dce8aebaSBarry Smith A simple dual space is provided automatically, and the user typically will not need to override it. 1543c0ce001eSMatthew G. Knepley 1544dce8aebaSBarry Smith .seealso: `PetscDualSpace`, `PetscFV`, `PetscFVCreate()` 1545c0ce001eSMatthew G. Knepley @*/ 1546d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetDualSpace(PetscFV fvm, PetscDualSpace sp) 1547d71ae5a4SJacob Faibussowitsch { 1548c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1549c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1550c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 2); 15519566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&fvm->dualSpace)); 1552c0ce001eSMatthew G. Knepley fvm->dualSpace = sp; 15539566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fvm->dualSpace)); 15543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1555c0ce001eSMatthew G. Knepley } 1556c0ce001eSMatthew G. Knepley 155788f5f89eSMatthew G. Knepley /*@C 1558ef0bb6c7SMatthew G. Knepley PetscFVGetCellTabulation - Returns the tabulation of the basis functions at the quadrature points 155988f5f89eSMatthew G. Knepley 156020f4b53cSBarry Smith Not Collective 156188f5f89eSMatthew G. Knepley 156288f5f89eSMatthew G. Knepley Input Parameter: 1563dce8aebaSBarry Smith . fvm - The `PetscFV` object 156488f5f89eSMatthew G. Knepley 1565ef0bb6c7SMatthew G. Knepley Output Parameter: 1566a5b23f4aSJose E. Roman . T - The basis function values and derivatives at quadrature points 156788f5f89eSMatthew G. Knepley 156888f5f89eSMatthew G. Knepley Level: intermediate 156988f5f89eSMatthew G. Knepley 1570dce8aebaSBarry Smith Note: 1571dce8aebaSBarry Smith .vb 1572dce8aebaSBarry Smith T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 1573dce8aebaSBarry 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 1574dce8aebaSBarry 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 1575dce8aebaSBarry Smith .ve 1576dce8aebaSBarry Smith 1577dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscTabulation`, `PetscFEGetCellTabulation()`, `PetscFVCreateTabulation()`, `PetscFVGetQuadrature()`, `PetscQuadratureGetData()` 157888f5f89eSMatthew G. Knepley @*/ 1579d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetCellTabulation(PetscFV fvm, PetscTabulation *T) 1580d71ae5a4SJacob Faibussowitsch { 1581c0ce001eSMatthew G. Knepley PetscInt npoints; 1582c0ce001eSMatthew G. Knepley const PetscReal *points; 1583c0ce001eSMatthew G. Knepley 1584c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1585c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 15864f572ea9SToby Isaac PetscAssertPointer(T, 2); 15879566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(fvm->quadrature, NULL, NULL, &npoints, &points, NULL)); 15889566063dSJacob Faibussowitsch if (!fvm->T) PetscCall(PetscFVCreateTabulation(fvm, 1, npoints, points, 1, &fvm->T)); 1589ef0bb6c7SMatthew G. Knepley *T = fvm->T; 15903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1591c0ce001eSMatthew G. Knepley } 1592c0ce001eSMatthew G. Knepley 159388f5f89eSMatthew G. Knepley /*@C 1594ef0bb6c7SMatthew G. Knepley PetscFVCreateTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided. 159588f5f89eSMatthew G. Knepley 159620f4b53cSBarry Smith Not Collective 159788f5f89eSMatthew G. Knepley 159888f5f89eSMatthew G. Knepley Input Parameters: 1599dce8aebaSBarry Smith + fvm - The `PetscFV` object 1600ef0bb6c7SMatthew G. Knepley . nrepl - The number of replicas 1601ef0bb6c7SMatthew G. Knepley . npoints - The number of tabulation points in a replica 1602ef0bb6c7SMatthew G. Knepley . points - The tabulation point coordinates 1603ef0bb6c7SMatthew G. Knepley - K - The order of derivative to tabulate 160488f5f89eSMatthew G. Knepley 1605ef0bb6c7SMatthew G. Knepley Output Parameter: 1606a5b23f4aSJose E. Roman . T - The basis function values and derivative at tabulation points 160788f5f89eSMatthew G. Knepley 160888f5f89eSMatthew G. Knepley Level: intermediate 160988f5f89eSMatthew G. Knepley 1610dce8aebaSBarry Smith Note: 1611dce8aebaSBarry Smith .vb 1612dce8aebaSBarry Smith T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 1613dce8aebaSBarry 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 1614dce8aebaSBarry 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 1615dce8aebaSBarry Smith .ve 1616dce8aebaSBarry Smith 1617dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscTabulation`, `PetscFECreateTabulation()`, `PetscTabulationDestroy()`, `PetscFEGetCellTabulation()` 161888f5f89eSMatthew G. Knepley @*/ 1619d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVCreateTabulation(PetscFV fvm, PetscInt nrepl, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation *T) 1620d71ae5a4SJacob Faibussowitsch { 1621c0ce001eSMatthew G. Knepley PetscInt pdim = 1; /* Dimension of approximation space P */ 1622ef0bb6c7SMatthew G. Knepley PetscInt cdim; /* Spatial dimension */ 1623ef0bb6c7SMatthew G. Knepley PetscInt Nc; /* Field components */ 1624ef0bb6c7SMatthew G. Knepley PetscInt k, p, d, c, e; 1625c0ce001eSMatthew G. Knepley 1626c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1627ef0bb6c7SMatthew G. Knepley if (!npoints || K < 0) { 1628ef0bb6c7SMatthew G. Knepley *T = NULL; 16293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1630c0ce001eSMatthew G. Knepley } 1631c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 16324f572ea9SToby Isaac PetscAssertPointer(points, 4); 16334f572ea9SToby Isaac PetscAssertPointer(T, 6); 16349566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &cdim)); 16359566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &Nc)); 16369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, T)); 1637ef0bb6c7SMatthew G. Knepley (*T)->K = !cdim ? 0 : K; 1638ef0bb6c7SMatthew G. Knepley (*T)->Nr = nrepl; 1639ef0bb6c7SMatthew G. Knepley (*T)->Np = npoints; 1640ef0bb6c7SMatthew G. Knepley (*T)->Nb = pdim; 1641ef0bb6c7SMatthew G. Knepley (*T)->Nc = Nc; 1642ef0bb6c7SMatthew G. Knepley (*T)->cdim = cdim; 16439566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*T)->K + 1, &(*T)->T)); 164448a46eb9SPierre Jolivet for (k = 0; k <= (*T)->K; ++k) PetscCall(PetscMalloc1(nrepl * npoints * pdim * Nc * PetscPowInt(cdim, k), &(*T)->T[k])); 16459371c9d4SSatish Balay if (K >= 0) { 16469371c9d4SSatish Balay for (p = 0; p < nrepl * npoints; ++p) 16479371c9d4SSatish Balay for (d = 0; d < pdim; ++d) 16489371c9d4SSatish Balay for (c = 0; c < Nc; ++c) (*T)->T[0][(p * pdim + d) * Nc + c] = 1.0; 1649ef0bb6c7SMatthew G. Knepley } 16509371c9d4SSatish Balay if (K >= 1) { 16519371c9d4SSatish Balay for (p = 0; p < nrepl * npoints; ++p) 16529371c9d4SSatish Balay for (d = 0; d < pdim; ++d) 16539371c9d4SSatish Balay for (c = 0; c < Nc; ++c) 16549371c9d4SSatish Balay for (e = 0; e < cdim; ++e) (*T)->T[1][((p * pdim + d) * Nc + c) * cdim + e] = 0.0; 16559371c9d4SSatish Balay } 16569371c9d4SSatish Balay if (K >= 2) { 16579371c9d4SSatish Balay for (p = 0; p < nrepl * npoints; ++p) 16589371c9d4SSatish Balay for (d = 0; d < pdim; ++d) 16599371c9d4SSatish Balay for (c = 0; c < Nc; ++c) 16609371c9d4SSatish Balay for (e = 0; e < cdim * cdim; ++e) (*T)->T[2][((p * pdim + d) * Nc + c) * cdim * cdim + e] = 0.0; 16619371c9d4SSatish Balay } 16623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1663c0ce001eSMatthew G. Knepley } 1664c0ce001eSMatthew G. Knepley 1665c0ce001eSMatthew G. Knepley /*@C 1666c0ce001eSMatthew G. Knepley PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell 1667c0ce001eSMatthew G. Knepley 1668c0ce001eSMatthew G. Knepley Input Parameters: 1669dce8aebaSBarry Smith + fvm - The `PetscFV` object 1670c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained 1671c0ce001eSMatthew G. Knepley - dx - The vector from the cell centroid to the neighboring cell centroid for each face 1672c0ce001eSMatthew G. Knepley 1673a4e35b19SJacob Faibussowitsch Output Parameter: 1674a4e35b19SJacob Faibussowitsch . grad - the gradient 1675a4e35b19SJacob Faibussowitsch 167688f5f89eSMatthew G. Knepley Level: advanced 1677c0ce001eSMatthew G. Knepley 1678dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVCreate()` 1679c0ce001eSMatthew G. Knepley @*/ 1680d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVComputeGradient(PetscFV fvm, PetscInt numFaces, PetscScalar dx[], PetscScalar grad[]) 1681d71ae5a4SJacob Faibussowitsch { 1682c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1683c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1684dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, computegradient, numFaces, dx, grad); 16853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1686c0ce001eSMatthew G. Knepley } 1687c0ce001eSMatthew G. Knepley 168888f5f89eSMatthew G. Knepley /*@C 1689c0ce001eSMatthew G. Knepley PetscFVIntegrateRHSFunction - Produce the cell residual vector for a chunk of elements by quadrature integration 1690c0ce001eSMatthew G. Knepley 169120f4b53cSBarry Smith Not Collective 1692c0ce001eSMatthew G. Knepley 1693c0ce001eSMatthew G. Knepley Input Parameters: 1694dce8aebaSBarry Smith + fvm - The `PetscFV` object for the field being integrated 1695da81f932SPierre Jolivet . prob - The `PetscDS` specifying the discretizations and continuum functions 1696c0ce001eSMatthew G. Knepley . field - The field being integrated 1697c0ce001eSMatthew G. Knepley . Nf - The number of faces in the chunk 1698c0ce001eSMatthew G. Knepley . fgeom - The face geometry for each face in the chunk 1699c0ce001eSMatthew G. Knepley . neighborVol - The volume for each pair of cells in the chunk 1700c0ce001eSMatthew G. Knepley . uL - The state from the cell on the left 1701c0ce001eSMatthew G. Knepley - uR - The state from the cell on the right 1702c0ce001eSMatthew G. Knepley 1703d8d19677SJose E. Roman Output Parameters: 1704c0ce001eSMatthew G. Knepley + fluxL - the left fluxes for each face 1705c0ce001eSMatthew G. Knepley - fluxR - the right fluxes for each face 170688f5f89eSMatthew G. Knepley 170788f5f89eSMatthew G. Knepley Level: developer 170888f5f89eSMatthew G. Knepley 1709dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscDS`, `PetscFVFaceGeom`, `PetscFVCreate()` 171088f5f89eSMatthew G. Knepley @*/ 1711d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVIntegrateRHSFunction(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) 1712d71ae5a4SJacob Faibussowitsch { 1713c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1714c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1715dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, integraterhsfunction, prob, field, Nf, fgeom, neighborVol, uL, uR, fluxL, fluxR); 17163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1717c0ce001eSMatthew G. Knepley } 1718c0ce001eSMatthew G. Knepley 1719c0ce001eSMatthew G. Knepley /*@ 1720a4e35b19SJacob Faibussowitsch PetscFVRefine - Create a "refined" `PetscFV` object that refines the reference cell into 1721a4e35b19SJacob Faibussowitsch smaller copies. 1722c0ce001eSMatthew G. Knepley 1723c0ce001eSMatthew G. Knepley Input Parameter: 1724dce8aebaSBarry Smith . fv - The initial `PetscFV` 1725c0ce001eSMatthew G. Knepley 1726c0ce001eSMatthew G. Knepley Output Parameter: 1727dce8aebaSBarry Smith . fvRef - The refined `PetscFV` 1728c0ce001eSMatthew G. Knepley 172988f5f89eSMatthew G. Knepley Level: advanced 1730c0ce001eSMatthew G. Knepley 1731a4e35b19SJacob Faibussowitsch Notes: 1732a4e35b19SJacob Faibussowitsch This is typically used to generate a preconditioner for a high order method from a lower order method on a 1733a4e35b19SJacob Faibussowitsch refined mesh having the same number of dofs (but more sparsity). It is also used to create an 1734a4e35b19SJacob Faibussowitsch interpolation between regularly refined meshes. 1735a4e35b19SJacob Faibussowitsch 1736dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 1737c0ce001eSMatthew G. Knepley @*/ 1738d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVRefine(PetscFV fv, PetscFV *fvRef) 1739d71ae5a4SJacob Faibussowitsch { 1740c0ce001eSMatthew G. Knepley PetscDualSpace Q, Qref; 1741c0ce001eSMatthew G. Knepley DM K, Kref; 1742c0ce001eSMatthew G. Knepley PetscQuadrature q, qref; 1743412e9a14SMatthew G. Knepley DMPolytopeType ct; 1744012bc364SMatthew G. Knepley DMPlexTransform tr; 1745c0ce001eSMatthew G. Knepley PetscReal *v0; 1746c0ce001eSMatthew G. Knepley PetscReal *jac, *invjac; 1747c0ce001eSMatthew G. Knepley PetscInt numComp, numSubelements, s; 1748c0ce001eSMatthew G. Knepley 1749c0ce001eSMatthew G. Knepley PetscFunctionBegin; 17509566063dSJacob Faibussowitsch PetscCall(PetscFVGetDualSpace(fv, &Q)); 17519566063dSJacob Faibussowitsch PetscCall(PetscFVGetQuadrature(fv, &q)); 17529566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &K)); 1753c0ce001eSMatthew G. Knepley /* Create dual space */ 17549566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDuplicate(Q, &Qref)); 17559566063dSJacob Faibussowitsch PetscCall(DMRefine(K, PetscObjectComm((PetscObject)fv), &Kref)); 17569566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(Qref, Kref)); 17579566063dSJacob Faibussowitsch PetscCall(DMDestroy(&Kref)); 17589566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(Qref)); 1759c0ce001eSMatthew G. Knepley /* Create volume */ 17609566063dSJacob Faibussowitsch PetscCall(PetscFVCreate(PetscObjectComm((PetscObject)fv), fvRef)); 17619566063dSJacob Faibussowitsch PetscCall(PetscFVSetDualSpace(*fvRef, Qref)); 17629566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &numComp)); 17639566063dSJacob Faibussowitsch PetscCall(PetscFVSetNumComponents(*fvRef, numComp)); 17649566063dSJacob Faibussowitsch PetscCall(PetscFVSetUp(*fvRef)); 1765c0ce001eSMatthew G. Knepley /* Create quadrature */ 17669566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(K, 0, &ct)); 17679566063dSJacob Faibussowitsch PetscCall(DMPlexTransformCreate(PETSC_COMM_SELF, &tr)); 17689566063dSJacob Faibussowitsch PetscCall(DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR)); 17699566063dSJacob Faibussowitsch PetscCall(DMPlexRefineRegularGetAffineTransforms(tr, ct, &numSubelements, &v0, &jac, &invjac)); 17709566063dSJacob Faibussowitsch PetscCall(PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref)); 17719566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetDimension(Qref, numSubelements)); 1772c0ce001eSMatthew G. Knepley for (s = 0; s < numSubelements; ++s) { 1773c0ce001eSMatthew G. Knepley PetscQuadrature qs; 1774c0ce001eSMatthew G. Knepley const PetscReal *points, *weights; 1775c0ce001eSMatthew G. Knepley PetscReal *p, *w; 1776c0ce001eSMatthew G. Knepley PetscInt dim, Nc, npoints, np; 1777c0ce001eSMatthew G. Knepley 17789566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qs)); 17799566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(q, &dim, &Nc, &npoints, &points, &weights)); 1780c0ce001eSMatthew G. Knepley np = npoints / numSubelements; 17819566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(np * dim, &p)); 17829566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(np * Nc, &w)); 17839566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(p, &points[s * np * dim], np * dim)); 17849566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(w, &weights[s * np * Nc], np * Nc)); 17859566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(qs, dim, Nc, np, p, w)); 17869566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetFunctional(Qref, s, qs)); 17879566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qs)); 1788c0ce001eSMatthew G. Knepley } 17899566063dSJacob Faibussowitsch PetscCall(PetscFVSetQuadrature(*fvRef, qref)); 17909566063dSJacob Faibussowitsch PetscCall(DMPlexTransformDestroy(&tr)); 17919566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qref)); 17929566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&Qref)); 17933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1794c0ce001eSMatthew G. Knepley } 1795c0ce001eSMatthew G. Knepley 1796d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVDestroy_Upwind(PetscFV fvm) 1797d71ae5a4SJacob Faibussowitsch { 1798c0ce001eSMatthew G. Knepley PetscFV_Upwind *b = (PetscFV_Upwind *)fvm->data; 1799c0ce001eSMatthew G. Knepley 1800c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18019566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 18023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1803c0ce001eSMatthew G. Knepley } 1804c0ce001eSMatthew G. Knepley 1805d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_Upwind_Ascii(PetscFV fv, PetscViewer viewer) 1806d71ae5a4SJacob Faibussowitsch { 1807c0ce001eSMatthew G. Knepley PetscInt Nc, c; 1808c0ce001eSMatthew G. Knepley PetscViewerFormat format; 1809c0ce001eSMatthew G. Knepley 1810c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18119566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &Nc)); 18129566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 18139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Upwind Finite Volume:\n")); 181463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " num components: %" PetscInt_FMT "\n", Nc)); 1815c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; c++) { 181648a46eb9SPierre Jolivet if (fv->componentNames[c]) PetscCall(PetscViewerASCIIPrintf(viewer, " component %" PetscInt_FMT ": %s\n", c, fv->componentNames[c])); 1817c0ce001eSMatthew G. Knepley } 18183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1819c0ce001eSMatthew G. Knepley } 1820c0ce001eSMatthew G. Knepley 1821d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_Upwind(PetscFV fv, PetscViewer viewer) 1822d71ae5a4SJacob Faibussowitsch { 1823c0ce001eSMatthew G. Knepley PetscBool iascii; 1824c0ce001eSMatthew G. Knepley 1825c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1826c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1); 1827c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 18289566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 18299566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscFVView_Upwind_Ascii(fv, viewer)); 18303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1831c0ce001eSMatthew G. Knepley } 1832c0ce001eSMatthew G. Knepley 1833d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVSetUp_Upwind(PetscFV fvm) 1834d71ae5a4SJacob Faibussowitsch { 1835c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1837c0ce001eSMatthew G. Knepley } 1838c0ce001eSMatthew G. Knepley 1839c0ce001eSMatthew G. Knepley /* 1840c0ce001eSMatthew G. Knepley neighborVol[f*2+0] contains the left geom 1841c0ce001eSMatthew G. Knepley neighborVol[f*2+1] contains the right geom 1842c0ce001eSMatthew G. Knepley */ 1843d71ae5a4SJacob 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[]) 1844d71ae5a4SJacob Faibussowitsch { 1845c0ce001eSMatthew G. Knepley void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *); 1846c0ce001eSMatthew G. Knepley void *rctx; 1847c0ce001eSMatthew G. Knepley PetscScalar *flux = fvm->fluxWork; 1848c0ce001eSMatthew G. Knepley const PetscScalar *constants; 1849c0ce001eSMatthew G. Knepley PetscInt dim, numConstants, pdim, totDim, Nc, off, f, d; 1850c0ce001eSMatthew G. Knepley 1851c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18529566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalComponents(prob, &Nc)); 18539566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalDimension(prob, &totDim)); 18549566063dSJacob Faibussowitsch PetscCall(PetscDSGetFieldOffset(prob, field, &off)); 18559566063dSJacob Faibussowitsch PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann)); 18569566063dSJacob Faibussowitsch PetscCall(PetscDSGetContext(prob, field, &rctx)); 18579566063dSJacob Faibussowitsch PetscCall(PetscDSGetConstants(prob, &numConstants, &constants)); 18589566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 18599566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &pdim)); 1860c0ce001eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 1861c0ce001eSMatthew G. Knepley (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f * Nc], &uR[f * Nc], numConstants, constants, flux, rctx); 1862c0ce001eSMatthew G. Knepley for (d = 0; d < pdim; ++d) { 1863c0ce001eSMatthew G. Knepley fluxL[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 0]; 1864c0ce001eSMatthew G. Knepley fluxR[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 1]; 1865c0ce001eSMatthew G. Knepley } 1866c0ce001eSMatthew G. Knepley } 18673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1868c0ce001eSMatthew G. Knepley } 1869c0ce001eSMatthew G. Knepley 1870d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVInitialize_Upwind(PetscFV fvm) 1871d71ae5a4SJacob Faibussowitsch { 1872c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1873c0ce001eSMatthew G. Knepley fvm->ops->setfromoptions = NULL; 1874c0ce001eSMatthew G. Knepley fvm->ops->setup = PetscFVSetUp_Upwind; 1875c0ce001eSMatthew G. Knepley fvm->ops->view = PetscFVView_Upwind; 1876c0ce001eSMatthew G. Knepley fvm->ops->destroy = PetscFVDestroy_Upwind; 1877c0ce001eSMatthew G. Knepley fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_Upwind; 18783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1879c0ce001eSMatthew G. Knepley } 1880c0ce001eSMatthew G. Knepley 1881c0ce001eSMatthew G. Knepley /*MC 1882dce8aebaSBarry Smith PETSCFVUPWIND = "upwind" - A `PetscFV` implementation 1883c0ce001eSMatthew G. Knepley 1884c0ce001eSMatthew G. Knepley Level: intermediate 1885c0ce001eSMatthew G. Knepley 1886dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 1887c0ce001eSMatthew G. Knepley M*/ 1888c0ce001eSMatthew G. Knepley 1889d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscFVCreate_Upwind(PetscFV fvm) 1890d71ae5a4SJacob Faibussowitsch { 1891c0ce001eSMatthew G. Knepley PetscFV_Upwind *b; 1892c0ce001eSMatthew G. Knepley 1893c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1894c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 18954dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 1896c0ce001eSMatthew G. Knepley fvm->data = b; 1897c0ce001eSMatthew G. Knepley 18989566063dSJacob Faibussowitsch PetscCall(PetscFVInitialize_Upwind(fvm)); 18993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1900c0ce001eSMatthew G. Knepley } 1901c0ce001eSMatthew G. Knepley 1902c0ce001eSMatthew G. Knepley #include <petscblaslapack.h> 1903c0ce001eSMatthew G. Knepley 1904d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVDestroy_LeastSquares(PetscFV fvm) 1905d71ae5a4SJacob Faibussowitsch { 1906c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data; 1907c0ce001eSMatthew G. Knepley 1908c0ce001eSMatthew G. Knepley PetscFunctionBegin; 19099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fvm, "PetscFVLeastSquaresSetMaxFaces_C", NULL)); 19109566063dSJacob Faibussowitsch PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work)); 19119566063dSJacob Faibussowitsch PetscCall(PetscFree(ls)); 19123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1913c0ce001eSMatthew G. Knepley } 1914c0ce001eSMatthew G. Knepley 1915d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_LeastSquares_Ascii(PetscFV fv, PetscViewer viewer) 1916d71ae5a4SJacob Faibussowitsch { 1917c0ce001eSMatthew G. Knepley PetscInt Nc, c; 1918c0ce001eSMatthew G. Knepley PetscViewerFormat format; 1919c0ce001eSMatthew G. Knepley 1920c0ce001eSMatthew G. Knepley PetscFunctionBegin; 19219566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &Nc)); 19229566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 19239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Finite Volume with Least Squares Reconstruction:\n")); 192463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " num components: %" PetscInt_FMT "\n", Nc)); 1925c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; c++) { 192648a46eb9SPierre Jolivet if (fv->componentNames[c]) PetscCall(PetscViewerASCIIPrintf(viewer, " component %" PetscInt_FMT ": %s\n", c, fv->componentNames[c])); 1927c0ce001eSMatthew G. Knepley } 19283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1929c0ce001eSMatthew G. Knepley } 1930c0ce001eSMatthew G. Knepley 1931d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_LeastSquares(PetscFV fv, PetscViewer viewer) 1932d71ae5a4SJacob Faibussowitsch { 1933c0ce001eSMatthew G. Knepley PetscBool iascii; 1934c0ce001eSMatthew G. Knepley 1935c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1936c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1); 1937c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 19389566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 19399566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscFVView_LeastSquares_Ascii(fv, viewer)); 19403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1941c0ce001eSMatthew G. Knepley } 1942c0ce001eSMatthew G. Knepley 1943d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVSetUp_LeastSquares(PetscFV fvm) 1944d71ae5a4SJacob Faibussowitsch { 1945c0ce001eSMatthew G. Knepley PetscFunctionBegin; 19463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1947c0ce001eSMatthew G. Knepley } 1948c0ce001eSMatthew G. Knepley 1949c0ce001eSMatthew G. Knepley /* Overwrites A. Can only handle full-rank problems with m>=n */ 1950d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresPseudoInverse_Static(PetscInt m, PetscInt mstride, PetscInt n, PetscScalar *A, PetscScalar *Ainv, PetscScalar *tau, PetscInt worksize, PetscScalar *work) 1951d71ae5a4SJacob Faibussowitsch { 1952c0ce001eSMatthew G. Knepley PetscBool debug = PETSC_FALSE; 1953c0ce001eSMatthew G. Knepley PetscBLASInt M, N, K, lda, ldb, ldwork, info; 1954c0ce001eSMatthew G. Knepley PetscScalar *R, *Q, *Aback, Alpha; 1955c0ce001eSMatthew G. Knepley 1956c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1957c0ce001eSMatthew G. Knepley if (debug) { 19589566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * n, &Aback)); 19599566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(Aback, A, m * n)); 1960c0ce001eSMatthew G. Knepley } 1961c0ce001eSMatthew G. Knepley 19629566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &M)); 19639566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &N)); 19649566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(mstride, &lda)); 19659566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(worksize, &ldwork)); 19669566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 1967792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&M, &N, A, &lda, tau, work, &ldwork, &info)); 19689566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 196928b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xGEQRF error"); 1970c0ce001eSMatthew G. Knepley R = A; /* Upper triangular part of A now contains R, the rest contains the elementary reflectors */ 1971c0ce001eSMatthew G. Knepley 1972c0ce001eSMatthew G. Knepley /* Extract an explicit representation of Q */ 1973c0ce001eSMatthew G. Knepley Q = Ainv; 19749566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(Q, A, mstride * n)); 1975c0ce001eSMatthew G. Knepley K = N; /* full rank */ 1976792fecdfSBarry Smith PetscCallBLAS("LAPACKorgqr", LAPACKorgqr_(&M, &N, &K, Q, &lda, tau, work, &ldwork, &info)); 197728b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xORGQR/xUNGQR error"); 1978c0ce001eSMatthew G. Knepley 1979c0ce001eSMatthew G. Knepley /* Compute A^{-T} = (R^{-1} Q^T)^T = Q R^{-T} */ 1980c0ce001eSMatthew G. Knepley Alpha = 1.0; 1981c0ce001eSMatthew G. Knepley ldb = lda; 1982c0ce001eSMatthew G. Knepley BLAStrsm_("Right", "Upper", "ConjugateTranspose", "NotUnitTriangular", &M, &N, &Alpha, R, &lda, Q, &ldb); 1983c0ce001eSMatthew G. Knepley /* Ainv is Q, overwritten with inverse */ 1984c0ce001eSMatthew G. Knepley 1985c0ce001eSMatthew G. Knepley if (debug) { /* Check that pseudo-inverse worked */ 1986c0ce001eSMatthew G. Knepley PetscScalar Beta = 0.0; 1987c0ce001eSMatthew G. Knepley PetscBLASInt ldc; 1988c0ce001eSMatthew G. Knepley K = N; 1989c0ce001eSMatthew G. Knepley ldc = N; 1990c0ce001eSMatthew G. Knepley BLASgemm_("ConjugateTranspose", "Normal", &N, &K, &M, &Alpha, Ainv, &lda, Aback, &ldb, &Beta, work, &ldc); 19919566063dSJacob Faibussowitsch PetscCall(PetscScalarView(n * n, work, PETSC_VIEWER_STDOUT_SELF)); 19929566063dSJacob Faibussowitsch PetscCall(PetscFree(Aback)); 1993c0ce001eSMatthew G. Knepley } 19943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1995c0ce001eSMatthew G. Knepley } 1996c0ce001eSMatthew G. Knepley 1997c0ce001eSMatthew G. Knepley /* Overwrites A. Can handle degenerate problems and m<n. */ 1998d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresPseudoInverseSVD_Static(PetscInt m, PetscInt mstride, PetscInt n, PetscScalar *A, PetscScalar *Ainv, PetscScalar *tau, PetscInt worksize, PetscScalar *work) 1999d71ae5a4SJacob Faibussowitsch { 20006bb27163SBarry Smith PetscScalar *Brhs; 2001c0ce001eSMatthew G. Knepley PetscScalar *tmpwork; 2002c0ce001eSMatthew G. Knepley PetscReal rcond; 2003c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX) 2004c0ce001eSMatthew G. Knepley PetscInt rworkSize; 2005c0ce001eSMatthew G. Knepley PetscReal *rwork; 2006c0ce001eSMatthew G. Knepley #endif 2007c0ce001eSMatthew G. Knepley PetscInt i, j, maxmn; 2008c0ce001eSMatthew G. Knepley PetscBLASInt M, N, lda, ldb, ldwork; 2009c0ce001eSMatthew G. Knepley PetscBLASInt nrhs, irank, info; 2010c0ce001eSMatthew G. Knepley 2011c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2012c0ce001eSMatthew G. Knepley /* initialize to identity */ 2013736d4f42SpierreXVI tmpwork = work; 2014736d4f42SpierreXVI Brhs = Ainv; 2015c0ce001eSMatthew G. Knepley maxmn = PetscMax(m, n); 2016c0ce001eSMatthew G. Knepley for (j = 0; j < maxmn; j++) { 2017c0ce001eSMatthew G. Knepley for (i = 0; i < maxmn; i++) Brhs[i + j * maxmn] = 1.0 * (i == j); 2018c0ce001eSMatthew G. Knepley } 2019c0ce001eSMatthew G. Knepley 20209566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &M)); 20219566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &N)); 20229566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(mstride, &lda)); 20239566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(maxmn, &ldb)); 20249566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(worksize, &ldwork)); 2025c0ce001eSMatthew G. Knepley rcond = -1; 2026c0ce001eSMatthew G. Knepley nrhs = M; 2027c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX) 2028c0ce001eSMatthew G. Knepley rworkSize = 5 * PetscMin(M, N); 20299566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(rworkSize, &rwork)); 20306bb27163SBarry Smith PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 2031792fecdfSBarry Smith PetscCallBLAS("LAPACKgelss", LAPACKgelss_(&M, &N, &nrhs, A, &lda, Brhs, &ldb, (PetscReal *)tau, &rcond, &irank, tmpwork, &ldwork, rwork, &info)); 20329566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 20339566063dSJacob Faibussowitsch PetscCall(PetscFree(rwork)); 2034c0ce001eSMatthew G. Knepley #else 2035c0ce001eSMatthew G. Knepley nrhs = M; 20366bb27163SBarry Smith PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 2037792fecdfSBarry Smith PetscCallBLAS("LAPACKgelss", LAPACKgelss_(&M, &N, &nrhs, A, &lda, Brhs, &ldb, (PetscReal *)tau, &rcond, &irank, tmpwork, &ldwork, &info)); 20389566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 2039c0ce001eSMatthew G. Knepley #endif 204028b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xGELSS error"); 2041c0ce001eSMatthew G. Knepley /* The following check should be turned into a diagnostic as soon as someone wants to do this intentionally */ 204208401ef6SPierre 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"); 20433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2044c0ce001eSMatthew G. Knepley } 2045c0ce001eSMatthew G. Knepley 2046c0ce001eSMatthew G. Knepley #if 0 2047c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresDebugCell_Static(PetscFV fvm, PetscInt cell, DM dm, DM dmFace, PetscScalar *fgeom, DM dmCell, PetscScalar *cgeom) 2048c0ce001eSMatthew G. Knepley { 2049c0ce001eSMatthew G. Knepley PetscReal grad[2] = {0, 0}; 2050c0ce001eSMatthew G. Knepley const PetscInt *faces; 2051c0ce001eSMatthew G. Knepley PetscInt numFaces, f; 2052c0ce001eSMatthew G. Knepley 2053c0ce001eSMatthew G. Knepley PetscFunctionBegin; 20549566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, cell, &numFaces)); 20559566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, cell, &faces)); 2056c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2057c0ce001eSMatthew G. Knepley const PetscInt *fcells; 2058c0ce001eSMatthew G. Knepley const CellGeom *cg1; 2059c0ce001eSMatthew G. Knepley const FaceGeom *fg; 2060c0ce001eSMatthew G. Knepley 20619566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupport(dm, faces[f], &fcells)); 20629566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmFace, faces[f], fgeom, &fg)); 2063c0ce001eSMatthew G. Knepley for (i = 0; i < 2; ++i) { 2064c0ce001eSMatthew G. Knepley PetscScalar du; 2065c0ce001eSMatthew G. Knepley 2066c0ce001eSMatthew G. Knepley if (fcells[i] == c) continue; 20679566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmCell, fcells[i], cgeom, &cg1)); 2068c0ce001eSMatthew G. Knepley du = cg1->centroid[0] + 3*cg1->centroid[1] - (cg->centroid[0] + 3*cg->centroid[1]); 2069c0ce001eSMatthew G. Knepley grad[0] += fg->grad[!i][0] * du; 2070c0ce001eSMatthew G. Knepley grad[1] += fg->grad[!i][1] * du; 2071c0ce001eSMatthew G. Knepley } 2072c0ce001eSMatthew G. Knepley } 20739566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "cell[%d] grad (%g, %g)\n", cell, grad[0], grad[1])); 20743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2075c0ce001eSMatthew G. Knepley } 2076c0ce001eSMatthew G. Knepley #endif 2077c0ce001eSMatthew G. Knepley 2078c0ce001eSMatthew G. Knepley /* 2079c0ce001eSMatthew G. Knepley PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell 2080c0ce001eSMatthew G. Knepley 2081c0ce001eSMatthew G. Knepley Input Parameters: 2082dce8aebaSBarry Smith + fvm - The `PetscFV` object 2083c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained 2084c0ce001eSMatthew G. Knepley . dx - The vector from the cell centroid to the neighboring cell centroid for each face 2085c0ce001eSMatthew G. Knepley 2086c0ce001eSMatthew G. Knepley Level: developer 2087c0ce001eSMatthew G. Knepley 2088dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVCreate()` 2089c0ce001eSMatthew G. Knepley */ 2090d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVComputeGradient_LeastSquares(PetscFV fvm, PetscInt numFaces, const PetscScalar dx[], PetscScalar grad[]) 2091d71ae5a4SJacob Faibussowitsch { 2092c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data; 2093c0ce001eSMatthew G. Knepley const PetscBool useSVD = PETSC_TRUE; 2094c0ce001eSMatthew G. Knepley const PetscInt maxFaces = ls->maxFaces; 2095c0ce001eSMatthew G. Knepley PetscInt dim, f, d; 2096c0ce001eSMatthew G. Knepley 2097c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2098c0ce001eSMatthew G. Knepley if (numFaces > maxFaces) { 209908401ef6SPierre Jolivet PetscCheck(maxFaces >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Reconstruction has not been initialized, call PetscFVLeastSquaresSetMaxFaces()"); 210063a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of input faces %" PetscInt_FMT " > %" PetscInt_FMT " maxfaces", numFaces, maxFaces); 2101c0ce001eSMatthew G. Knepley } 21029566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 2103c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2104c0ce001eSMatthew G. Knepley for (d = 0; d < dim; ++d) ls->B[d * maxFaces + f] = dx[f * dim + d]; 2105c0ce001eSMatthew G. Knepley } 2106c0ce001eSMatthew G. Knepley /* Overwrites B with garbage, returns Binv in row-major format */ 2107736d4f42SpierreXVI if (useSVD) { 2108736d4f42SpierreXVI PetscInt maxmn = PetscMax(numFaces, dim); 21099566063dSJacob Faibussowitsch PetscCall(PetscFVLeastSquaresPseudoInverseSVD_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work)); 2110736d4f42SpierreXVI /* Binv shaped in column-major, coldim=maxmn.*/ 2111736d4f42SpierreXVI for (f = 0; f < numFaces; ++f) { 2112736d4f42SpierreXVI for (d = 0; d < dim; ++d) grad[f * dim + d] = ls->Binv[d + maxmn * f]; 2113736d4f42SpierreXVI } 2114736d4f42SpierreXVI } else { 21159566063dSJacob Faibussowitsch PetscCall(PetscFVLeastSquaresPseudoInverse_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work)); 2116736d4f42SpierreXVI /* Binv shaped in row-major, rowdim=maxFaces.*/ 2117c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2118c0ce001eSMatthew G. Knepley for (d = 0; d < dim; ++d) grad[f * dim + d] = ls->Binv[d * maxFaces + f]; 2119c0ce001eSMatthew G. Knepley } 2120736d4f42SpierreXVI } 21213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2122c0ce001eSMatthew G. Knepley } 2123c0ce001eSMatthew G. Knepley 2124c0ce001eSMatthew G. Knepley /* 2125c0ce001eSMatthew G. Knepley neighborVol[f*2+0] contains the left geom 2126c0ce001eSMatthew G. Knepley neighborVol[f*2+1] contains the right geom 2127c0ce001eSMatthew G. Knepley */ 2128d71ae5a4SJacob 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[]) 2129d71ae5a4SJacob Faibussowitsch { 2130c0ce001eSMatthew G. Knepley void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *); 2131c0ce001eSMatthew G. Knepley void *rctx; 2132c0ce001eSMatthew G. Knepley PetscScalar *flux = fvm->fluxWork; 2133c0ce001eSMatthew G. Knepley const PetscScalar *constants; 2134c0ce001eSMatthew G. Knepley PetscInt dim, numConstants, pdim, Nc, totDim, off, f, d; 2135c0ce001eSMatthew G. Knepley 2136c0ce001eSMatthew G. Knepley PetscFunctionBegin; 21379566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalComponents(prob, &Nc)); 21389566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalDimension(prob, &totDim)); 21399566063dSJacob Faibussowitsch PetscCall(PetscDSGetFieldOffset(prob, field, &off)); 21409566063dSJacob Faibussowitsch PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann)); 21419566063dSJacob Faibussowitsch PetscCall(PetscDSGetContext(prob, field, &rctx)); 21429566063dSJacob Faibussowitsch PetscCall(PetscDSGetConstants(prob, &numConstants, &constants)); 21439566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 21449566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &pdim)); 2145c0ce001eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2146c0ce001eSMatthew G. Knepley (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f * Nc], &uR[f * Nc], numConstants, constants, flux, rctx); 2147c0ce001eSMatthew G. Knepley for (d = 0; d < pdim; ++d) { 2148c0ce001eSMatthew G. Knepley fluxL[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 0]; 2149c0ce001eSMatthew G. Knepley fluxR[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 1]; 2150c0ce001eSMatthew G. Knepley } 2151c0ce001eSMatthew G. Knepley } 21523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2153c0ce001eSMatthew G. Knepley } 2154c0ce001eSMatthew G. Knepley 2155d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresSetMaxFaces_LS(PetscFV fvm, PetscInt maxFaces) 2156d71ae5a4SJacob Faibussowitsch { 2157c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data; 2158736d4f42SpierreXVI PetscInt dim, m, n, nrhs, minmn, maxmn; 2159c0ce001eSMatthew G. Knepley 2160c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2161c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 21629566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 21639566063dSJacob Faibussowitsch PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work)); 2164c0ce001eSMatthew G. Knepley ls->maxFaces = maxFaces; 2165c0ce001eSMatthew G. Knepley m = ls->maxFaces; 2166c0ce001eSMatthew G. Knepley n = dim; 2167c0ce001eSMatthew G. Knepley nrhs = ls->maxFaces; 2168736d4f42SpierreXVI minmn = PetscMin(m, n); 2169736d4f42SpierreXVI maxmn = PetscMax(m, n); 2170736d4f42SpierreXVI ls->workSize = 3 * minmn + PetscMax(2 * minmn, PetscMax(maxmn, nrhs)); /* required by LAPACK */ 21719566063dSJacob Faibussowitsch PetscCall(PetscMalloc4(m * n, &ls->B, maxmn * maxmn, &ls->Binv, minmn, &ls->tau, ls->workSize, &ls->work)); 21723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2173c0ce001eSMatthew G. Knepley } 2174c0ce001eSMatthew G. Knepley 217566976f2fSJacob Faibussowitsch static PetscErrorCode PetscFVInitialize_LeastSquares(PetscFV fvm) 2176d71ae5a4SJacob Faibussowitsch { 2177c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2178c0ce001eSMatthew G. Knepley fvm->ops->setfromoptions = NULL; 2179c0ce001eSMatthew G. Knepley fvm->ops->setup = PetscFVSetUp_LeastSquares; 2180c0ce001eSMatthew G. Knepley fvm->ops->view = PetscFVView_LeastSquares; 2181c0ce001eSMatthew G. Knepley fvm->ops->destroy = PetscFVDestroy_LeastSquares; 2182c0ce001eSMatthew G. Knepley fvm->ops->computegradient = PetscFVComputeGradient_LeastSquares; 2183c0ce001eSMatthew G. Knepley fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_LeastSquares; 21843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2185c0ce001eSMatthew G. Knepley } 2186c0ce001eSMatthew G. Knepley 2187c0ce001eSMatthew G. Knepley /*MC 2188dce8aebaSBarry Smith PETSCFVLEASTSQUARES = "leastsquares" - A `PetscFV` implementation 2189c0ce001eSMatthew G. Knepley 2190c0ce001eSMatthew G. Knepley Level: intermediate 2191c0ce001eSMatthew G. Knepley 2192dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 2193c0ce001eSMatthew G. Knepley M*/ 2194c0ce001eSMatthew G. Knepley 2195d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscFVCreate_LeastSquares(PetscFV fvm) 2196d71ae5a4SJacob Faibussowitsch { 2197c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls; 2198c0ce001eSMatthew G. Knepley 2199c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2200c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 22014dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&ls)); 2202c0ce001eSMatthew G. Knepley fvm->data = ls; 2203c0ce001eSMatthew G. Knepley 2204c0ce001eSMatthew G. Knepley ls->maxFaces = -1; 2205c0ce001eSMatthew G. Knepley ls->workSize = -1; 2206c0ce001eSMatthew G. Knepley ls->B = NULL; 2207c0ce001eSMatthew G. Knepley ls->Binv = NULL; 2208c0ce001eSMatthew G. Knepley ls->tau = NULL; 2209c0ce001eSMatthew G. Knepley ls->work = NULL; 2210c0ce001eSMatthew G. Knepley 22119566063dSJacob Faibussowitsch PetscCall(PetscFVSetComputeGradients(fvm, PETSC_TRUE)); 22129566063dSJacob Faibussowitsch PetscCall(PetscFVInitialize_LeastSquares(fvm)); 22139566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fvm, "PetscFVLeastSquaresSetMaxFaces_C", PetscFVLeastSquaresSetMaxFaces_LS)); 22143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2215c0ce001eSMatthew G. Knepley } 2216c0ce001eSMatthew G. Knepley 2217c0ce001eSMatthew G. Knepley /*@ 2218c0ce001eSMatthew G. Knepley PetscFVLeastSquaresSetMaxFaces - Set the maximum number of cell faces for gradient reconstruction 2219c0ce001eSMatthew G. Knepley 222020f4b53cSBarry Smith Not Collective 2221c0ce001eSMatthew G. Knepley 222260225df5SJacob Faibussowitsch Input Parameters: 2223dce8aebaSBarry Smith + fvm - The `PetscFV` object 2224c0ce001eSMatthew G. Knepley - maxFaces - The maximum number of cell faces 2225c0ce001eSMatthew G. Knepley 2226c0ce001eSMatthew G. Knepley Level: intermediate 2227c0ce001eSMatthew G. Knepley 2228dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVCreate()`, `PETSCFVLEASTSQUARES`, `PetscFVComputeGradient()` 2229c0ce001eSMatthew G. Knepley @*/ 2230d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVLeastSquaresSetMaxFaces(PetscFV fvm, PetscInt maxFaces) 2231d71ae5a4SJacob Faibussowitsch { 2232c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2233c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 2234cac4c232SBarry Smith PetscTryMethod(fvm, "PetscFVLeastSquaresSetMaxFaces_C", (PetscFV, PetscInt), (fvm, maxFaces)); 22353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2236c0ce001eSMatthew G. Knepley } 2237