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 1156dce8aebaSBarry Smith .seealso: `PetscFVSet`, `PetscFVSetType()`, `PETSCFVUPWIND`, `PetscFVDestroy()` 1157c0ce001eSMatthew G. Knepley @*/ 1158d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVCreate(MPI_Comm comm, PetscFV *fvm) 1159d71ae5a4SJacob Faibussowitsch { 1160c0ce001eSMatthew G. Knepley PetscFV f; 1161c0ce001eSMatthew G. Knepley 1162c0ce001eSMatthew G. Knepley PetscFunctionBegin; 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: 1268*a4e35b19SJacob 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 1673*a4e35b19SJacob Faibussowitsch Output Parameter: 1674*a4e35b19SJacob Faibussowitsch . grad - the gradient 1675*a4e35b19SJacob 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 /*@ 1720*a4e35b19SJacob Faibussowitsch PetscFVRefine - Create a "refined" `PetscFV` object that refines the reference cell into 1721*a4e35b19SJacob 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 1731*a4e35b19SJacob Faibussowitsch Notes: 1732*a4e35b19SJacob Faibussowitsch This is typically used to generate a preconditioner for a high order method from a lower order method on a 1733*a4e35b19SJacob Faibussowitsch refined mesh having the same number of dofs (but more sparsity). It is also used to create an 1734*a4e35b19SJacob Faibussowitsch interpolation between regularly refined meshes. 1735*a4e35b19SJacob 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 2175d71ae5a4SJacob Faibussowitsch 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