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 879927e4dfSBarry Smith PetscTryTypeMethod(lim, destroy); 88c0ce001eSMatthew G. Knepley lim->ops->destroy = NULL; 899927e4dfSBarry Smith 909566063dSJacob Faibussowitsch PetscCall((*r)(lim)); 919566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)lim, name)); 923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 93c0ce001eSMatthew G. Knepley } 94c0ce001eSMatthew G. Knepley 95c0ce001eSMatthew G. Knepley /*@C 96dce8aebaSBarry Smith PetscLimiterGetType - Gets the `PetscLimiterType` name (as a string) from the `PetscLimiter`. 97c0ce001eSMatthew G. Knepley 98c0ce001eSMatthew G. Knepley Not Collective 99c0ce001eSMatthew G. Knepley 100c0ce001eSMatthew G. Knepley Input Parameter: 101dce8aebaSBarry Smith . lim - The `PetscLimiter` 102c0ce001eSMatthew G. Knepley 103c0ce001eSMatthew G. Knepley Output Parameter: 104dce8aebaSBarry Smith . name - The `PetscLimiterType` 105c0ce001eSMatthew G. Knepley 106c0ce001eSMatthew G. Knepley Level: intermediate 107c0ce001eSMatthew G. Knepley 108dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterSetType()`, `PetscLimiterCreate()` 109c0ce001eSMatthew G. Knepley @*/ 110d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterGetType(PetscLimiter lim, PetscLimiterType *name) 111d71ae5a4SJacob Faibussowitsch { 112c0ce001eSMatthew G. Knepley PetscFunctionBegin; 113c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 1144f572ea9SToby Isaac PetscAssertPointer(name, 2); 1159566063dSJacob Faibussowitsch PetscCall(PetscLimiterRegisterAll()); 116c0ce001eSMatthew G. Knepley *name = ((PetscObject)lim)->type_name; 1173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 118c0ce001eSMatthew G. Knepley } 119c0ce001eSMatthew G. Knepley 120c0ce001eSMatthew G. Knepley /*@C 121dce8aebaSBarry Smith PetscLimiterViewFromOptions - View a `PetscLimiter` based on values in the options database 122fe2efc57SMark 12320f4b53cSBarry Smith Collective 124fe2efc57SMark 125fe2efc57SMark Input Parameters: 126dce8aebaSBarry Smith + A - the `PetscLimiter` object to view 127dce8aebaSBarry Smith . obj - Optional object that provides the options prefix to use 128dce8aebaSBarry Smith - name - command line option name 129fe2efc57SMark 130fe2efc57SMark Level: intermediate 131dce8aebaSBarry Smith 132dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterView()`, `PetscObjectViewFromOptions()`, `PetscLimiterCreate()` 133fe2efc57SMark @*/ 134d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterViewFromOptions(PetscLimiter A, PetscObject obj, const char name[]) 135d71ae5a4SJacob Faibussowitsch { 136fe2efc57SMark PetscFunctionBegin; 137fe2efc57SMark PetscValidHeaderSpecific(A, PETSCLIMITER_CLASSID, 1); 1389566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 1393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 140fe2efc57SMark } 141fe2efc57SMark 142fe2efc57SMark /*@C 143dce8aebaSBarry Smith PetscLimiterView - Views a `PetscLimiter` 144c0ce001eSMatthew G. Knepley 14520f4b53cSBarry Smith Collective 146c0ce001eSMatthew G. Knepley 147d8d19677SJose E. Roman Input Parameters: 148dce8aebaSBarry Smith + lim - the `PetscLimiter` object to view 149c0ce001eSMatthew G. Knepley - v - the viewer 150c0ce001eSMatthew G. Knepley 15188f5f89eSMatthew G. Knepley Level: beginner 152c0ce001eSMatthew G. Knepley 153dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscViewer`, `PetscLimiterDestroy()`, `PetscLimiterViewFromOptions()` 154c0ce001eSMatthew G. Knepley @*/ 155d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterView(PetscLimiter lim, PetscViewer v) 156d71ae5a4SJacob Faibussowitsch { 157c0ce001eSMatthew G. Knepley PetscFunctionBegin; 158c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 1599566063dSJacob Faibussowitsch if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lim), &v)); 160dbbe0bcdSBarry Smith PetscTryTypeMethod(lim, view, v); 1613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 162c0ce001eSMatthew G. Knepley } 163c0ce001eSMatthew G. Knepley 164c0ce001eSMatthew G. Knepley /*@ 165dce8aebaSBarry Smith PetscLimiterSetFromOptions - sets parameters in a `PetscLimiter` from the options database 166c0ce001eSMatthew G. Knepley 16720f4b53cSBarry Smith Collective 168c0ce001eSMatthew G. Knepley 169c0ce001eSMatthew G. Knepley Input Parameter: 170dce8aebaSBarry Smith . lim - the `PetscLimiter` object to set options for 171c0ce001eSMatthew G. Knepley 17288f5f89eSMatthew G. Knepley Level: intermediate 173c0ce001eSMatthew G. Knepley 174dce8aebaSBarry Smith .seealso: `PetscLimiter`, ``PetscLimiterView()` 175c0ce001eSMatthew G. Knepley @*/ 176d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterSetFromOptions(PetscLimiter lim) 177d71ae5a4SJacob Faibussowitsch { 178c0ce001eSMatthew G. Knepley const char *defaultType; 179c0ce001eSMatthew G. Knepley char name[256]; 180c0ce001eSMatthew G. Knepley PetscBool flg; 181c0ce001eSMatthew G. Knepley 182c0ce001eSMatthew G. Knepley PetscFunctionBegin; 183c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 184c0ce001eSMatthew G. Knepley if (!((PetscObject)lim)->type_name) defaultType = PETSCLIMITERSIN; 185c0ce001eSMatthew G. Knepley else defaultType = ((PetscObject)lim)->type_name; 1869566063dSJacob Faibussowitsch PetscCall(PetscLimiterRegisterAll()); 187c0ce001eSMatthew G. Knepley 188d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)lim); 1899566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-petsclimiter_type", "Finite volume slope limiter", "PetscLimiterSetType", PetscLimiterList, defaultType, name, 256, &flg)); 190c0ce001eSMatthew G. Knepley if (flg) { 1919566063dSJacob Faibussowitsch PetscCall(PetscLimiterSetType(lim, name)); 192c0ce001eSMatthew G. Knepley } else if (!((PetscObject)lim)->type_name) { 1939566063dSJacob Faibussowitsch PetscCall(PetscLimiterSetType(lim, defaultType)); 194c0ce001eSMatthew G. Knepley } 195dbbe0bcdSBarry Smith PetscTryTypeMethod(lim, setfromoptions); 196c0ce001eSMatthew G. Knepley /* process any options handlers added with PetscObjectAddOptionsHandler() */ 197dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)lim, PetscOptionsObject)); 198d0609cedSBarry Smith PetscOptionsEnd(); 1999566063dSJacob Faibussowitsch PetscCall(PetscLimiterViewFromOptions(lim, NULL, "-petsclimiter_view")); 2003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 201c0ce001eSMatthew G. Knepley } 202c0ce001eSMatthew G. Knepley 203c0ce001eSMatthew G. Knepley /*@C 204dce8aebaSBarry Smith PetscLimiterSetUp - Construct data structures for the `PetscLimiter` 205c0ce001eSMatthew G. Knepley 20620f4b53cSBarry Smith Collective 207c0ce001eSMatthew G. Knepley 208c0ce001eSMatthew G. Knepley Input Parameter: 209dce8aebaSBarry Smith . lim - the `PetscLimiter` object to setup 210c0ce001eSMatthew G. Knepley 21188f5f89eSMatthew G. Knepley Level: intermediate 212c0ce001eSMatthew G. Knepley 213dce8aebaSBarry Smith .seealso: `PetscLimiter`, ``PetscLimiterView()`, `PetscLimiterDestroy()` 214c0ce001eSMatthew G. Knepley @*/ 215d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterSetUp(PetscLimiter lim) 216d71ae5a4SJacob Faibussowitsch { 217c0ce001eSMatthew G. Knepley PetscFunctionBegin; 218c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 219dbbe0bcdSBarry Smith PetscTryTypeMethod(lim, setup); 2203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 221c0ce001eSMatthew G. Knepley } 222c0ce001eSMatthew G. Knepley 223c0ce001eSMatthew G. Knepley /*@ 224dce8aebaSBarry Smith PetscLimiterDestroy - Destroys a `PetscLimiter` object 225c0ce001eSMatthew G. Knepley 22620f4b53cSBarry Smith Collective 227c0ce001eSMatthew G. Knepley 228c0ce001eSMatthew G. Knepley Input Parameter: 229dce8aebaSBarry Smith . lim - the `PetscLimiter` object to destroy 230c0ce001eSMatthew G. Knepley 23188f5f89eSMatthew G. Knepley Level: beginner 232c0ce001eSMatthew G. Knepley 233dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterView()` 234c0ce001eSMatthew G. Knepley @*/ 235d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterDestroy(PetscLimiter *lim) 236d71ae5a4SJacob Faibussowitsch { 237c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2383ba16761SJacob Faibussowitsch if (!*lim) PetscFunctionReturn(PETSC_SUCCESS); 239c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific((*lim), PETSCLIMITER_CLASSID, 1); 240c0ce001eSMatthew G. Knepley 2419371c9d4SSatish Balay if (--((PetscObject)(*lim))->refct > 0) { 2429371c9d4SSatish Balay *lim = NULL; 2433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2449371c9d4SSatish Balay } 245c0ce001eSMatthew G. Knepley ((PetscObject)(*lim))->refct = 0; 246c0ce001eSMatthew G. Knepley 247dbbe0bcdSBarry Smith PetscTryTypeMethod((*lim), destroy); 2489566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(lim)); 2493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 250c0ce001eSMatthew G. Knepley } 251c0ce001eSMatthew G. Knepley 252c0ce001eSMatthew G. Knepley /*@ 253dce8aebaSBarry Smith PetscLimiterCreate - Creates an empty `PetscLimiter` object. The type can then be set with `PetscLimiterSetType()`. 254c0ce001eSMatthew G. Knepley 255c0ce001eSMatthew G. Knepley Collective 256c0ce001eSMatthew G. Knepley 257c0ce001eSMatthew G. Knepley Input Parameter: 258dce8aebaSBarry Smith . comm - The communicator for the `PetscLimiter` object 259c0ce001eSMatthew G. Knepley 260c0ce001eSMatthew G. Knepley Output Parameter: 261dce8aebaSBarry Smith . lim - The `PetscLimiter` object 262c0ce001eSMatthew G. Knepley 263c0ce001eSMatthew G. Knepley Level: beginner 264c0ce001eSMatthew G. Knepley 26560225df5SJacob Faibussowitsch .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterSetType()`, `PETSCLIMITERSIN` 266c0ce001eSMatthew G. Knepley @*/ 267d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterCreate(MPI_Comm comm, PetscLimiter *lim) 268d71ae5a4SJacob Faibussowitsch { 269c0ce001eSMatthew G. Knepley PetscLimiter l; 270c0ce001eSMatthew G. Knepley 271c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2724f572ea9SToby Isaac PetscAssertPointer(lim, 2); 2739566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(LimiterCitation, &Limitercite)); 274c0ce001eSMatthew G. Knepley *lim = NULL; 2759566063dSJacob Faibussowitsch PetscCall(PetscFVInitializePackage()); 276c0ce001eSMatthew G. Knepley 2779566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(l, PETSCLIMITER_CLASSID, "PetscLimiter", "Finite Volume Slope Limiter", "PetscLimiter", comm, PetscLimiterDestroy, PetscLimiterView)); 278c0ce001eSMatthew G. Knepley 279c0ce001eSMatthew G. Knepley *lim = l; 2803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 281c0ce001eSMatthew G. Knepley } 282c0ce001eSMatthew G. Knepley 28388f5f89eSMatthew G. Knepley /*@ 28488f5f89eSMatthew G. Knepley PetscLimiterLimit - Limit the flux 28588f5f89eSMatthew G. Knepley 28688f5f89eSMatthew G. Knepley Input Parameters: 287dce8aebaSBarry Smith + lim - The `PetscLimiter` 28888f5f89eSMatthew G. Knepley - flim - The input field 28988f5f89eSMatthew G. Knepley 29088f5f89eSMatthew G. Knepley Output Parameter: 29188f5f89eSMatthew G. Knepley . phi - The limited field 29288f5f89eSMatthew G. Knepley 29388f5f89eSMatthew G. Knepley Level: beginner 29488f5f89eSMatthew G. Knepley 295dce8aebaSBarry Smith Note: 296dce8aebaSBarry Smith Limiters given in symmetric form following Berger, Aftosmis, and Murman 2005 297dce8aebaSBarry Smith .vb 298dce8aebaSBarry Smith The classical flux-limited formulation is psi(r) where 299dce8aebaSBarry Smith 300dce8aebaSBarry Smith r = (u[0] - u[-1]) / (u[1] - u[0]) 301dce8aebaSBarry Smith 302dce8aebaSBarry Smith The second order TVD region is bounded by 303dce8aebaSBarry Smith 304dce8aebaSBarry Smith psi_minmod(r) = min(r,1) and psi_superbee(r) = min(2, 2r, max(1,r)) 305dce8aebaSBarry Smith 306dce8aebaSBarry Smith where all limiters are implicitly clipped to be non-negative. A more convenient slope-limited form is psi(r) = 307dce8aebaSBarry Smith phi(r)(r+1)/2 in which the reconstructed interface values are 308dce8aebaSBarry Smith 309dce8aebaSBarry Smith u(v) = u[0] + phi(r) (grad u)[0] v 310dce8aebaSBarry Smith 311dce8aebaSBarry Smith where v is the vector from centroid to quadrature point. In these variables, the usual limiters become 312dce8aebaSBarry Smith 313dce8aebaSBarry 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)) 314dce8aebaSBarry Smith 315dce8aebaSBarry Smith For a nicer symmetric formulation, rewrite in terms of 316dce8aebaSBarry Smith 317dce8aebaSBarry Smith f = (u[0] - u[-1]) / (u[1] - u[-1]) 318dce8aebaSBarry Smith 319dce8aebaSBarry Smith where r(f) = f/(1-f). Not that r(1-f) = (1-f)/f = 1/r(f) so the symmetry condition 320dce8aebaSBarry Smith 321dce8aebaSBarry Smith phi(r) = phi(1/r) 322dce8aebaSBarry Smith 323dce8aebaSBarry Smith becomes 324dce8aebaSBarry Smith 325dce8aebaSBarry Smith w(f) = w(1-f). 326dce8aebaSBarry Smith 327dce8aebaSBarry Smith The limiters below implement this final form w(f). The reference methods are 328dce8aebaSBarry Smith 329dce8aebaSBarry Smith w_minmod(f) = 2 min(f,(1-f)) w_superbee(r) = 4 min((1-f), f) 330dce8aebaSBarry Smith .ve 331dce8aebaSBarry Smith 332dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterSetType()`, `PetscLimiterCreate()` 33388f5f89eSMatthew G. Knepley @*/ 334d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLimiterLimit(PetscLimiter lim, PetscReal flim, PetscReal *phi) 335d71ae5a4SJacob Faibussowitsch { 336c0ce001eSMatthew G. Knepley PetscFunctionBegin; 337c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 3384f572ea9SToby Isaac PetscAssertPointer(phi, 3); 339dbbe0bcdSBarry Smith PetscUseTypeMethod(lim, limit, flim, phi); 3403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 341c0ce001eSMatthew G. Knepley } 342c0ce001eSMatthew G. Knepley 343d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_Sin(PetscLimiter lim) 344d71ae5a4SJacob Faibussowitsch { 345c0ce001eSMatthew G. Knepley PetscLimiter_Sin *l = (PetscLimiter_Sin *)lim->data; 346c0ce001eSMatthew G. Knepley 347c0ce001eSMatthew G. Knepley PetscFunctionBegin; 3489566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 3493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 350c0ce001eSMatthew G. Knepley } 351c0ce001eSMatthew G. Knepley 352d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Sin_Ascii(PetscLimiter lim, PetscViewer viewer) 353d71ae5a4SJacob Faibussowitsch { 354c0ce001eSMatthew G. Knepley PetscViewerFormat format; 355c0ce001eSMatthew G. Knepley 356c0ce001eSMatthew G. Knepley PetscFunctionBegin; 3579566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 3589566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Sin Slope Limiter:\n")); 3593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 360c0ce001eSMatthew G. Knepley } 361c0ce001eSMatthew G. Knepley 362d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Sin(PetscLimiter lim, PetscViewer viewer) 363d71ae5a4SJacob Faibussowitsch { 364c0ce001eSMatthew G. Knepley PetscBool iascii; 365c0ce001eSMatthew G. Knepley 366c0ce001eSMatthew G. Knepley PetscFunctionBegin; 367c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 368c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 3699566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 3709566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_Sin_Ascii(lim, viewer)); 3713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 372c0ce001eSMatthew G. Knepley } 373c0ce001eSMatthew G. Knepley 374d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_Sin(PetscLimiter lim, PetscReal f, PetscReal *phi) 375d71ae5a4SJacob Faibussowitsch { 376c0ce001eSMatthew G. Knepley PetscFunctionBegin; 377c0ce001eSMatthew G. Knepley *phi = PetscSinReal(PETSC_PI * PetscMax(0, PetscMin(f, 1))); 3783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 379c0ce001eSMatthew G. Knepley } 380c0ce001eSMatthew G. Knepley 381d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_Sin(PetscLimiter lim) 382d71ae5a4SJacob Faibussowitsch { 383c0ce001eSMatthew G. Knepley PetscFunctionBegin; 384c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Sin; 385c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Sin; 386c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Sin; 3873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 388c0ce001eSMatthew G. Knepley } 389c0ce001eSMatthew G. Knepley 390c0ce001eSMatthew G. Knepley /*MC 391dce8aebaSBarry Smith PETSCLIMITERSIN = "sin" - A `PetscLimiter` implementation 392c0ce001eSMatthew G. Knepley 393c0ce001eSMatthew G. Knepley Level: intermediate 394c0ce001eSMatthew G. Knepley 395dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 396c0ce001eSMatthew G. Knepley M*/ 397c0ce001eSMatthew G. Knepley 398d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Sin(PetscLimiter lim) 399d71ae5a4SJacob Faibussowitsch { 400c0ce001eSMatthew G. Knepley PetscLimiter_Sin *l; 401c0ce001eSMatthew G. Knepley 402c0ce001eSMatthew G. Knepley PetscFunctionBegin; 403c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 4044dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 405c0ce001eSMatthew G. Knepley lim->data = l; 406c0ce001eSMatthew G. Knepley 4079566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_Sin(lim)); 4083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 409c0ce001eSMatthew G. Knepley } 410c0ce001eSMatthew G. Knepley 411d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_Zero(PetscLimiter lim) 412d71ae5a4SJacob Faibussowitsch { 413c0ce001eSMatthew G. Knepley PetscLimiter_Zero *l = (PetscLimiter_Zero *)lim->data; 414c0ce001eSMatthew G. Knepley 415c0ce001eSMatthew G. Knepley PetscFunctionBegin; 4169566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 4173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 418c0ce001eSMatthew G. Knepley } 419c0ce001eSMatthew G. Knepley 420d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Zero_Ascii(PetscLimiter lim, PetscViewer viewer) 421d71ae5a4SJacob Faibussowitsch { 422c0ce001eSMatthew G. Knepley PetscViewerFormat format; 423c0ce001eSMatthew G. Knepley 424c0ce001eSMatthew G. Knepley PetscFunctionBegin; 4259566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 4269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Zero Slope Limiter:\n")); 4273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 428c0ce001eSMatthew G. Knepley } 429c0ce001eSMatthew G. Knepley 430d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Zero(PetscLimiter lim, PetscViewer viewer) 431d71ae5a4SJacob Faibussowitsch { 432c0ce001eSMatthew G. Knepley PetscBool iascii; 433c0ce001eSMatthew G. Knepley 434c0ce001eSMatthew G. Knepley PetscFunctionBegin; 435c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 436c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 4379566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 4389566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_Zero_Ascii(lim, viewer)); 4393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 440c0ce001eSMatthew G. Knepley } 441c0ce001eSMatthew G. Knepley 442d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_Zero(PetscLimiter lim, PetscReal f, PetscReal *phi) 443d71ae5a4SJacob Faibussowitsch { 444c0ce001eSMatthew G. Knepley PetscFunctionBegin; 445c0ce001eSMatthew G. Knepley *phi = 0.0; 4463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 447c0ce001eSMatthew G. Knepley } 448c0ce001eSMatthew G. Knepley 449d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_Zero(PetscLimiter lim) 450d71ae5a4SJacob Faibussowitsch { 451c0ce001eSMatthew G. Knepley PetscFunctionBegin; 452c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Zero; 453c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Zero; 454c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Zero; 4553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 456c0ce001eSMatthew G. Knepley } 457c0ce001eSMatthew G. Knepley 458c0ce001eSMatthew G. Knepley /*MC 459dce8aebaSBarry Smith PETSCLIMITERZERO = "zero" - A simple `PetscLimiter` implementation 460c0ce001eSMatthew G. Knepley 461c0ce001eSMatthew G. Knepley Level: intermediate 462c0ce001eSMatthew G. Knepley 463dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 464c0ce001eSMatthew G. Knepley M*/ 465c0ce001eSMatthew G. Knepley 466d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Zero(PetscLimiter lim) 467d71ae5a4SJacob Faibussowitsch { 468c0ce001eSMatthew G. Knepley PetscLimiter_Zero *l; 469c0ce001eSMatthew G. Knepley 470c0ce001eSMatthew G. Knepley PetscFunctionBegin; 471c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 4724dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 473c0ce001eSMatthew G. Knepley lim->data = l; 474c0ce001eSMatthew G. Knepley 4759566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_Zero(lim)); 4763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 477c0ce001eSMatthew G. Knepley } 478c0ce001eSMatthew G. Knepley 479d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_None(PetscLimiter lim) 480d71ae5a4SJacob Faibussowitsch { 481c0ce001eSMatthew G. Knepley PetscLimiter_None *l = (PetscLimiter_None *)lim->data; 482c0ce001eSMatthew G. Knepley 483c0ce001eSMatthew G. Knepley PetscFunctionBegin; 4849566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 4853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 486c0ce001eSMatthew G. Knepley } 487c0ce001eSMatthew G. Knepley 488d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_None_Ascii(PetscLimiter lim, PetscViewer viewer) 489d71ae5a4SJacob Faibussowitsch { 490c0ce001eSMatthew G. Knepley PetscViewerFormat format; 491c0ce001eSMatthew G. Knepley 492c0ce001eSMatthew G. Knepley PetscFunctionBegin; 4939566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 4949566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "None Slope Limiter:\n")); 4953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 496c0ce001eSMatthew G. Knepley } 497c0ce001eSMatthew G. Knepley 498d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_None(PetscLimiter lim, PetscViewer viewer) 499d71ae5a4SJacob Faibussowitsch { 500c0ce001eSMatthew G. Knepley PetscBool iascii; 501c0ce001eSMatthew G. Knepley 502c0ce001eSMatthew G. Knepley PetscFunctionBegin; 503c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 504c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 5059566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 5069566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_None_Ascii(lim, viewer)); 5073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 508c0ce001eSMatthew G. Knepley } 509c0ce001eSMatthew G. Knepley 510d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_None(PetscLimiter lim, PetscReal f, PetscReal *phi) 511d71ae5a4SJacob Faibussowitsch { 512c0ce001eSMatthew G. Knepley PetscFunctionBegin; 513c0ce001eSMatthew G. Knepley *phi = 1.0; 5143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 515c0ce001eSMatthew G. Knepley } 516c0ce001eSMatthew G. Knepley 517d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_None(PetscLimiter lim) 518d71ae5a4SJacob Faibussowitsch { 519c0ce001eSMatthew G. Knepley PetscFunctionBegin; 520c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_None; 521c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_None; 522c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_None; 5233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 524c0ce001eSMatthew G. Knepley } 525c0ce001eSMatthew G. Knepley 526c0ce001eSMatthew G. Knepley /*MC 527dce8aebaSBarry Smith PETSCLIMITERNONE = "none" - A trivial `PetscLimiter` implementation 528c0ce001eSMatthew G. Knepley 529c0ce001eSMatthew G. Knepley Level: intermediate 530c0ce001eSMatthew G. Knepley 531dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 532c0ce001eSMatthew G. Knepley M*/ 533c0ce001eSMatthew G. Knepley 534d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_None(PetscLimiter lim) 535d71ae5a4SJacob Faibussowitsch { 536c0ce001eSMatthew G. Knepley PetscLimiter_None *l; 537c0ce001eSMatthew G. Knepley 538c0ce001eSMatthew G. Knepley PetscFunctionBegin; 539c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 5404dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 541c0ce001eSMatthew G. Knepley lim->data = l; 542c0ce001eSMatthew G. Knepley 5439566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_None(lim)); 5443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 545c0ce001eSMatthew G. Knepley } 546c0ce001eSMatthew G. Knepley 547d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_Minmod(PetscLimiter lim) 548d71ae5a4SJacob Faibussowitsch { 549c0ce001eSMatthew G. Knepley PetscLimiter_Minmod *l = (PetscLimiter_Minmod *)lim->data; 550c0ce001eSMatthew G. Knepley 551c0ce001eSMatthew G. Knepley PetscFunctionBegin; 5529566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 5533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 554c0ce001eSMatthew G. Knepley } 555c0ce001eSMatthew G. Knepley 556d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Minmod_Ascii(PetscLimiter lim, PetscViewer viewer) 557d71ae5a4SJacob Faibussowitsch { 558c0ce001eSMatthew G. Knepley PetscViewerFormat format; 559c0ce001eSMatthew G. Knepley 560c0ce001eSMatthew G. Knepley PetscFunctionBegin; 5619566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 5629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Minmod Slope Limiter:\n")); 5633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 564c0ce001eSMatthew G. Knepley } 565c0ce001eSMatthew G. Knepley 566d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Minmod(PetscLimiter lim, PetscViewer viewer) 567d71ae5a4SJacob Faibussowitsch { 568c0ce001eSMatthew G. Knepley PetscBool iascii; 569c0ce001eSMatthew G. Knepley 570c0ce001eSMatthew G. Knepley PetscFunctionBegin; 571c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 572c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 5739566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 5749566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_Minmod_Ascii(lim, viewer)); 5753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 576c0ce001eSMatthew G. Knepley } 577c0ce001eSMatthew G. Knepley 578d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_Minmod(PetscLimiter lim, PetscReal f, PetscReal *phi) 579d71ae5a4SJacob Faibussowitsch { 580c0ce001eSMatthew G. Knepley PetscFunctionBegin; 581c0ce001eSMatthew G. Knepley *phi = 2 * PetscMax(0, PetscMin(f, 1 - f)); 5823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 583c0ce001eSMatthew G. Knepley } 584c0ce001eSMatthew G. Knepley 585d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_Minmod(PetscLimiter lim) 586d71ae5a4SJacob Faibussowitsch { 587c0ce001eSMatthew G. Knepley PetscFunctionBegin; 588c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Minmod; 589c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Minmod; 590c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Minmod; 5913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 592c0ce001eSMatthew G. Knepley } 593c0ce001eSMatthew G. Knepley 594c0ce001eSMatthew G. Knepley /*MC 595dce8aebaSBarry Smith PETSCLIMITERMINMOD = "minmod" - A `PetscLimiter` implementation 596c0ce001eSMatthew G. Knepley 597c0ce001eSMatthew G. Knepley Level: intermediate 598c0ce001eSMatthew G. Knepley 599dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 600c0ce001eSMatthew G. Knepley M*/ 601c0ce001eSMatthew G. Knepley 602d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Minmod(PetscLimiter lim) 603d71ae5a4SJacob Faibussowitsch { 604c0ce001eSMatthew G. Knepley PetscLimiter_Minmod *l; 605c0ce001eSMatthew G. Knepley 606c0ce001eSMatthew G. Knepley PetscFunctionBegin; 607c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 6084dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 609c0ce001eSMatthew G. Knepley lim->data = l; 610c0ce001eSMatthew G. Knepley 6119566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_Minmod(lim)); 6123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 613c0ce001eSMatthew G. Knepley } 614c0ce001eSMatthew G. Knepley 615d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_VanLeer(PetscLimiter lim) 616d71ae5a4SJacob Faibussowitsch { 617c0ce001eSMatthew G. Knepley PetscLimiter_VanLeer *l = (PetscLimiter_VanLeer *)lim->data; 618c0ce001eSMatthew G. Knepley 619c0ce001eSMatthew G. Knepley PetscFunctionBegin; 6209566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 6213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 622c0ce001eSMatthew G. Knepley } 623c0ce001eSMatthew G. Knepley 624d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_VanLeer_Ascii(PetscLimiter lim, PetscViewer viewer) 625d71ae5a4SJacob Faibussowitsch { 626c0ce001eSMatthew G. Knepley PetscViewerFormat format; 627c0ce001eSMatthew G. Knepley 628c0ce001eSMatthew G. Knepley PetscFunctionBegin; 6299566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 6309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Van Leer Slope Limiter:\n")); 6313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 632c0ce001eSMatthew G. Knepley } 633c0ce001eSMatthew G. Knepley 634d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_VanLeer(PetscLimiter lim, PetscViewer viewer) 635d71ae5a4SJacob Faibussowitsch { 636c0ce001eSMatthew G. Knepley PetscBool iascii; 637c0ce001eSMatthew G. Knepley 638c0ce001eSMatthew G. Knepley PetscFunctionBegin; 639c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 640c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 6419566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 6429566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_VanLeer_Ascii(lim, viewer)); 6433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 644c0ce001eSMatthew G. Knepley } 645c0ce001eSMatthew G. Knepley 646d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_VanLeer(PetscLimiter lim, PetscReal f, PetscReal *phi) 647d71ae5a4SJacob Faibussowitsch { 648c0ce001eSMatthew G. Knepley PetscFunctionBegin; 649c0ce001eSMatthew G. Knepley *phi = PetscMax(0, 4 * f * (1 - f)); 6503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 651c0ce001eSMatthew G. Knepley } 652c0ce001eSMatthew G. Knepley 653d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_VanLeer(PetscLimiter lim) 654d71ae5a4SJacob Faibussowitsch { 655c0ce001eSMatthew G. Knepley PetscFunctionBegin; 656c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_VanLeer; 657c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_VanLeer; 658c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_VanLeer; 6593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 660c0ce001eSMatthew G. Knepley } 661c0ce001eSMatthew G. Knepley 662c0ce001eSMatthew G. Knepley /*MC 663dce8aebaSBarry Smith PETSCLIMITERVANLEER = "vanleer" - A `PetscLimiter` implementation 664c0ce001eSMatthew G. Knepley 665c0ce001eSMatthew G. Knepley Level: intermediate 666c0ce001eSMatthew G. Knepley 667dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 668c0ce001eSMatthew G. Knepley M*/ 669c0ce001eSMatthew G. Knepley 670d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanLeer(PetscLimiter lim) 671d71ae5a4SJacob Faibussowitsch { 672c0ce001eSMatthew G. Knepley PetscLimiter_VanLeer *l; 673c0ce001eSMatthew G. Knepley 674c0ce001eSMatthew G. Knepley PetscFunctionBegin; 675c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 6764dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 677c0ce001eSMatthew G. Knepley lim->data = l; 678c0ce001eSMatthew G. Knepley 6799566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_VanLeer(lim)); 6803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 681c0ce001eSMatthew G. Knepley } 682c0ce001eSMatthew G. Knepley 683d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_VanAlbada(PetscLimiter lim) 684d71ae5a4SJacob Faibussowitsch { 685c0ce001eSMatthew G. Knepley PetscLimiter_VanAlbada *l = (PetscLimiter_VanAlbada *)lim->data; 686c0ce001eSMatthew G. Knepley 687c0ce001eSMatthew G. Knepley PetscFunctionBegin; 6889566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 6893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 690c0ce001eSMatthew G. Knepley } 691c0ce001eSMatthew G. Knepley 692d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_VanAlbada_Ascii(PetscLimiter lim, PetscViewer viewer) 693d71ae5a4SJacob Faibussowitsch { 694c0ce001eSMatthew G. Knepley PetscViewerFormat format; 695c0ce001eSMatthew G. Knepley 696c0ce001eSMatthew G. Knepley PetscFunctionBegin; 6979566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 6989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Van Albada Slope Limiter:\n")); 6993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 700c0ce001eSMatthew G. Knepley } 701c0ce001eSMatthew G. Knepley 702d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_VanAlbada(PetscLimiter lim, PetscViewer viewer) 703d71ae5a4SJacob Faibussowitsch { 704c0ce001eSMatthew G. Knepley PetscBool iascii; 705c0ce001eSMatthew G. Knepley 706c0ce001eSMatthew G. Knepley PetscFunctionBegin; 707c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 708c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 7099566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 7109566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_VanAlbada_Ascii(lim, viewer)); 7113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 712c0ce001eSMatthew G. Knepley } 713c0ce001eSMatthew G. Knepley 714d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_VanAlbada(PetscLimiter lim, PetscReal f, PetscReal *phi) 715d71ae5a4SJacob Faibussowitsch { 716c0ce001eSMatthew G. Knepley PetscFunctionBegin; 717c0ce001eSMatthew G. Knepley *phi = PetscMax(0, 2 * f * (1 - f) / (PetscSqr(f) + PetscSqr(1 - f))); 7183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 719c0ce001eSMatthew G. Knepley } 720c0ce001eSMatthew G. Knepley 721d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_VanAlbada(PetscLimiter lim) 722d71ae5a4SJacob Faibussowitsch { 723c0ce001eSMatthew G. Knepley PetscFunctionBegin; 724c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_VanAlbada; 725c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_VanAlbada; 726c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_VanAlbada; 7273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 728c0ce001eSMatthew G. Knepley } 729c0ce001eSMatthew G. Knepley 730c0ce001eSMatthew G. Knepley /*MC 731dce8aebaSBarry Smith PETSCLIMITERVANALBADA = "vanalbada" - A PetscLimiter implementation 732c0ce001eSMatthew G. Knepley 733c0ce001eSMatthew G. Knepley Level: intermediate 734c0ce001eSMatthew G. Knepley 735dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 736c0ce001eSMatthew G. Knepley M*/ 737c0ce001eSMatthew G. Knepley 738d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanAlbada(PetscLimiter lim) 739d71ae5a4SJacob Faibussowitsch { 740c0ce001eSMatthew G. Knepley PetscLimiter_VanAlbada *l; 741c0ce001eSMatthew G. Knepley 742c0ce001eSMatthew G. Knepley PetscFunctionBegin; 743c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 7444dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 745c0ce001eSMatthew G. Knepley lim->data = l; 746c0ce001eSMatthew G. Knepley 7479566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_VanAlbada(lim)); 7483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 749c0ce001eSMatthew G. Knepley } 750c0ce001eSMatthew G. Knepley 751d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_Superbee(PetscLimiter lim) 752d71ae5a4SJacob Faibussowitsch { 753c0ce001eSMatthew G. Knepley PetscLimiter_Superbee *l = (PetscLimiter_Superbee *)lim->data; 754c0ce001eSMatthew G. Knepley 755c0ce001eSMatthew G. Knepley PetscFunctionBegin; 7569566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 7573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 758c0ce001eSMatthew G. Knepley } 759c0ce001eSMatthew G. Knepley 760d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Superbee_Ascii(PetscLimiter lim, PetscViewer viewer) 761d71ae5a4SJacob Faibussowitsch { 762c0ce001eSMatthew G. Knepley PetscViewerFormat format; 763c0ce001eSMatthew G. Knepley 764c0ce001eSMatthew G. Knepley PetscFunctionBegin; 7659566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 7669566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Superbee Slope Limiter:\n")); 7673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 768c0ce001eSMatthew G. Knepley } 769c0ce001eSMatthew G. Knepley 770d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_Superbee(PetscLimiter lim, PetscViewer viewer) 771d71ae5a4SJacob Faibussowitsch { 772c0ce001eSMatthew G. Knepley PetscBool iascii; 773c0ce001eSMatthew G. Knepley 774c0ce001eSMatthew G. Knepley PetscFunctionBegin; 775c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 776c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 7779566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 7789566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_Superbee_Ascii(lim, viewer)); 7793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 780c0ce001eSMatthew G. Knepley } 781c0ce001eSMatthew G. Knepley 782d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_Superbee(PetscLimiter lim, PetscReal f, PetscReal *phi) 783d71ae5a4SJacob Faibussowitsch { 784c0ce001eSMatthew G. Knepley PetscFunctionBegin; 785c0ce001eSMatthew G. Knepley *phi = 4 * PetscMax(0, PetscMin(f, 1 - f)); 7863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 787c0ce001eSMatthew G. Knepley } 788c0ce001eSMatthew G. Knepley 789d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_Superbee(PetscLimiter lim) 790d71ae5a4SJacob Faibussowitsch { 791c0ce001eSMatthew G. Knepley PetscFunctionBegin; 792c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Superbee; 793c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Superbee; 794c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Superbee; 7953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 796c0ce001eSMatthew G. Knepley } 797c0ce001eSMatthew G. Knepley 798c0ce001eSMatthew G. Knepley /*MC 799dce8aebaSBarry Smith PETSCLIMITERSUPERBEE = "superbee" - A `PetscLimiter` implementation 800c0ce001eSMatthew G. Knepley 801c0ce001eSMatthew G. Knepley Level: intermediate 802c0ce001eSMatthew G. Knepley 803dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 804c0ce001eSMatthew G. Knepley M*/ 805c0ce001eSMatthew G. Knepley 806d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Superbee(PetscLimiter lim) 807d71ae5a4SJacob Faibussowitsch { 808c0ce001eSMatthew G. Knepley PetscLimiter_Superbee *l; 809c0ce001eSMatthew G. Knepley 810c0ce001eSMatthew G. Knepley PetscFunctionBegin; 811c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 8124dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 813c0ce001eSMatthew G. Knepley lim->data = l; 814c0ce001eSMatthew G. Knepley 8159566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_Superbee(lim)); 8163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 817c0ce001eSMatthew G. Knepley } 818c0ce001eSMatthew G. Knepley 819d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterDestroy_MC(PetscLimiter lim) 820d71ae5a4SJacob Faibussowitsch { 821c0ce001eSMatthew G. Knepley PetscLimiter_MC *l = (PetscLimiter_MC *)lim->data; 822c0ce001eSMatthew G. Knepley 823c0ce001eSMatthew G. Knepley PetscFunctionBegin; 8249566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 8253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 826c0ce001eSMatthew G. Knepley } 827c0ce001eSMatthew G. Knepley 828d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_MC_Ascii(PetscLimiter lim, PetscViewer viewer) 829d71ae5a4SJacob Faibussowitsch { 830c0ce001eSMatthew G. Knepley PetscViewerFormat format; 831c0ce001eSMatthew G. Knepley 832c0ce001eSMatthew G. Knepley PetscFunctionBegin; 8339566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 8349566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "MC Slope Limiter:\n")); 8353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 836c0ce001eSMatthew G. Knepley } 837c0ce001eSMatthew G. Knepley 838d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterView_MC(PetscLimiter lim, PetscViewer viewer) 839d71ae5a4SJacob Faibussowitsch { 840c0ce001eSMatthew G. Knepley PetscBool iascii; 841c0ce001eSMatthew G. Knepley 842c0ce001eSMatthew G. Knepley PetscFunctionBegin; 843c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 844c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 8459566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 8469566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_MC_Ascii(lim, viewer)); 8473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 848c0ce001eSMatthew G. Knepley } 849c0ce001eSMatthew G. Knepley 850c0ce001eSMatthew G. Knepley /* aka Barth-Jespersen */ 851d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterLimit_MC(PetscLimiter lim, PetscReal f, PetscReal *phi) 852d71ae5a4SJacob Faibussowitsch { 853c0ce001eSMatthew G. Knepley PetscFunctionBegin; 854c0ce001eSMatthew G. Knepley *phi = PetscMin(1, 4 * PetscMax(0, PetscMin(f, 1 - f))); 8553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 856c0ce001eSMatthew G. Knepley } 857c0ce001eSMatthew G. Knepley 858d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLimiterInitialize_MC(PetscLimiter lim) 859d71ae5a4SJacob Faibussowitsch { 860c0ce001eSMatthew G. Knepley PetscFunctionBegin; 861c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_MC; 862c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_MC; 863c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_MC; 8643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 865c0ce001eSMatthew G. Knepley } 866c0ce001eSMatthew G. Knepley 867c0ce001eSMatthew G. Knepley /*MC 868dce8aebaSBarry Smith PETSCLIMITERMC = "mc" - A `PetscLimiter` implementation 869c0ce001eSMatthew G. Knepley 870c0ce001eSMatthew G. Knepley Level: intermediate 871c0ce001eSMatthew G. Knepley 872dce8aebaSBarry Smith .seealso: `PetscLimiter`, `PetscLimiterType`, `PetscLimiterCreate()`, `PetscLimiterSetType()` 873c0ce001eSMatthew G. Knepley M*/ 874c0ce001eSMatthew G. Knepley 875d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscLimiterCreate_MC(PetscLimiter lim) 876d71ae5a4SJacob Faibussowitsch { 877c0ce001eSMatthew G. Knepley PetscLimiter_MC *l; 878c0ce001eSMatthew G. Knepley 879c0ce001eSMatthew G. Knepley PetscFunctionBegin; 880c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 8814dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&l)); 882c0ce001eSMatthew G. Knepley lim->data = l; 883c0ce001eSMatthew G. Knepley 8849566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_MC(lim)); 8853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 886c0ce001eSMatthew G. Knepley } 887c0ce001eSMatthew G. Knepley 888c0ce001eSMatthew G. Knepley PetscClassId PETSCFV_CLASSID = 0; 889c0ce001eSMatthew G. Knepley 890c0ce001eSMatthew G. Knepley PetscFunctionList PetscFVList = NULL; 891c0ce001eSMatthew G. Knepley PetscBool PetscFVRegisterAllCalled = PETSC_FALSE; 892c0ce001eSMatthew G. Knepley 893c0ce001eSMatthew G. Knepley /*@C 894dce8aebaSBarry Smith PetscFVRegister - Adds a new `PetscFV` implementation 895c0ce001eSMatthew G. Knepley 896c0ce001eSMatthew G. Knepley Not Collective 897c0ce001eSMatthew G. Knepley 898c0ce001eSMatthew G. Knepley Input Parameters: 8992fe279fdSBarry Smith + sname - The name of a new user-defined creation routine 9002fe279fdSBarry Smith - function - The creation routine itself 901c0ce001eSMatthew G. Knepley 90260225df5SJacob Faibussowitsch Example Usage: 903c0ce001eSMatthew G. Knepley .vb 904c0ce001eSMatthew G. Knepley PetscFVRegister("my_fv", MyPetscFVCreate); 905c0ce001eSMatthew G. Knepley .ve 906c0ce001eSMatthew G. Knepley 907c0ce001eSMatthew G. Knepley Then, your PetscFV type can be chosen with the procedural interface via 908c0ce001eSMatthew G. Knepley .vb 909c0ce001eSMatthew G. Knepley PetscFVCreate(MPI_Comm, PetscFV *); 910c0ce001eSMatthew G. Knepley PetscFVSetType(PetscFV, "my_fv"); 911c0ce001eSMatthew G. Knepley .ve 912c0ce001eSMatthew G. Knepley or at runtime via the option 913c0ce001eSMatthew G. Knepley .vb 914c0ce001eSMatthew G. Knepley -petscfv_type my_fv 915c0ce001eSMatthew G. Knepley .ve 916c0ce001eSMatthew G. Knepley 917c0ce001eSMatthew G. Knepley Level: advanced 918c0ce001eSMatthew G. Knepley 919dce8aebaSBarry Smith Note: 920dce8aebaSBarry Smith `PetscFVRegister()` may be called multiple times to add several user-defined PetscFVs 921c0ce001eSMatthew G. Knepley 922dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVRegisterAll()`, `PetscFVRegisterDestroy()` 923c0ce001eSMatthew G. Knepley @*/ 924d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVRegister(const char sname[], PetscErrorCode (*function)(PetscFV)) 925d71ae5a4SJacob Faibussowitsch { 926c0ce001eSMatthew G. Knepley PetscFunctionBegin; 9279566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&PetscFVList, sname, function)); 9283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 929c0ce001eSMatthew G. Knepley } 930c0ce001eSMatthew G. Knepley 931c0ce001eSMatthew G. Knepley /*@C 932dce8aebaSBarry Smith PetscFVSetType - Builds a particular `PetscFV` 933c0ce001eSMatthew G. Knepley 93420f4b53cSBarry Smith Collective 935c0ce001eSMatthew G. Knepley 936c0ce001eSMatthew G. Knepley Input Parameters: 937dce8aebaSBarry Smith + fvm - The `PetscFV` object 938dce8aebaSBarry Smith - name - The type of FVM space 939c0ce001eSMatthew G. Knepley 940c0ce001eSMatthew G. Knepley Options Database Key: 941dce8aebaSBarry Smith . -petscfv_type <type> - Sets the `PetscFVType`; use -help for a list of available types 942c0ce001eSMatthew G. Knepley 943c0ce001eSMatthew G. Knepley Level: intermediate 944c0ce001eSMatthew G. Knepley 945dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVGetType()`, `PetscFVCreate()` 946c0ce001eSMatthew G. Knepley @*/ 947d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetType(PetscFV fvm, PetscFVType name) 948d71ae5a4SJacob Faibussowitsch { 949c0ce001eSMatthew G. Knepley PetscErrorCode (*r)(PetscFV); 950c0ce001eSMatthew G. Knepley PetscBool match; 951c0ce001eSMatthew G. Knepley 952c0ce001eSMatthew G. Knepley PetscFunctionBegin; 953c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 9549566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)fvm, name, &match)); 9553ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 956c0ce001eSMatthew G. Knepley 9579566063dSJacob Faibussowitsch PetscCall(PetscFVRegisterAll()); 9589566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(PetscFVList, name, &r)); 95928b400f6SJacob Faibussowitsch PetscCheck(r, PetscObjectComm((PetscObject)fvm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscFV type: %s", name); 960c0ce001eSMatthew G. Knepley 961dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, destroy); 962c0ce001eSMatthew G. Knepley fvm->ops->destroy = NULL; 963dbbe0bcdSBarry Smith 9649566063dSJacob Faibussowitsch PetscCall((*r)(fvm)); 9659566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)fvm, name)); 9663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 967c0ce001eSMatthew G. Knepley } 968c0ce001eSMatthew G. Knepley 969c0ce001eSMatthew G. Knepley /*@C 970dce8aebaSBarry Smith PetscFVGetType - Gets the `PetscFVType` (as a string) from a `PetscFV`. 971c0ce001eSMatthew G. Knepley 972c0ce001eSMatthew G. Knepley Not Collective 973c0ce001eSMatthew G. Knepley 974c0ce001eSMatthew G. Knepley Input Parameter: 975dce8aebaSBarry Smith . fvm - The `PetscFV` 976c0ce001eSMatthew G. Knepley 977c0ce001eSMatthew G. Knepley Output Parameter: 978dce8aebaSBarry Smith . name - The `PetscFVType` name 979c0ce001eSMatthew G. Knepley 980c0ce001eSMatthew G. Knepley Level: intermediate 981c0ce001eSMatthew G. Knepley 982dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVSetType()`, `PetscFVCreate()` 983c0ce001eSMatthew G. Knepley @*/ 984d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetType(PetscFV fvm, PetscFVType *name) 985d71ae5a4SJacob Faibussowitsch { 986c0ce001eSMatthew G. Knepley PetscFunctionBegin; 987c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 9884f572ea9SToby Isaac PetscAssertPointer(name, 2); 9899566063dSJacob Faibussowitsch PetscCall(PetscFVRegisterAll()); 990c0ce001eSMatthew G. Knepley *name = ((PetscObject)fvm)->type_name; 9913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 992c0ce001eSMatthew G. Knepley } 993c0ce001eSMatthew G. Knepley 994c0ce001eSMatthew G. Knepley /*@C 995dce8aebaSBarry Smith PetscFVViewFromOptions - View a `PetscFV` based on values in the options database 996fe2efc57SMark 99720f4b53cSBarry Smith Collective 998fe2efc57SMark 999fe2efc57SMark Input Parameters: 1000dce8aebaSBarry Smith + A - the `PetscFV` object 1001dce8aebaSBarry Smith . obj - Optional object that provides the options prefix 1002dce8aebaSBarry Smith - name - command line option name 1003fe2efc57SMark 1004fe2efc57SMark Level: intermediate 1005dce8aebaSBarry Smith 1006dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVView()`, `PetscObjectViewFromOptions()`, `PetscFVCreate()` 1007fe2efc57SMark @*/ 1008d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVViewFromOptions(PetscFV A, PetscObject obj, const char name[]) 1009d71ae5a4SJacob Faibussowitsch { 1010fe2efc57SMark PetscFunctionBegin; 1011fe2efc57SMark PetscValidHeaderSpecific(A, PETSCFV_CLASSID, 1); 10129566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 10133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1014fe2efc57SMark } 1015fe2efc57SMark 1016fe2efc57SMark /*@C 1017dce8aebaSBarry Smith PetscFVView - Views a `PetscFV` 1018c0ce001eSMatthew G. Knepley 101920f4b53cSBarry Smith Collective 1020c0ce001eSMatthew G. Knepley 1021d8d19677SJose E. Roman Input Parameters: 1022dce8aebaSBarry Smith + fvm - the `PetscFV` object to view 1023c0ce001eSMatthew G. Knepley - v - the viewer 1024c0ce001eSMatthew G. Knepley 102588f5f89eSMatthew G. Knepley Level: beginner 1026c0ce001eSMatthew G. Knepley 1027dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscViewer`, `PetscFVDestroy()` 1028c0ce001eSMatthew G. Knepley @*/ 1029d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVView(PetscFV fvm, PetscViewer v) 1030d71ae5a4SJacob Faibussowitsch { 1031c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1032c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 10339566063dSJacob Faibussowitsch if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)fvm), &v)); 1034dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, view, v); 10353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1036c0ce001eSMatthew G. Knepley } 1037c0ce001eSMatthew G. Knepley 1038c0ce001eSMatthew G. Knepley /*@ 1039dce8aebaSBarry Smith PetscFVSetFromOptions - sets parameters in a `PetscFV` from the options database 1040c0ce001eSMatthew G. Knepley 104120f4b53cSBarry Smith Collective 1042c0ce001eSMatthew G. Knepley 1043c0ce001eSMatthew G. Knepley Input Parameter: 1044dce8aebaSBarry Smith . fvm - the `PetscFV` object to set options for 1045c0ce001eSMatthew G. Knepley 1046c0ce001eSMatthew G. Knepley Options Database Key: 1047c0ce001eSMatthew G. Knepley . -petscfv_compute_gradients <bool> - Determines whether cell gradients are calculated 1048c0ce001eSMatthew G. Knepley 104988f5f89eSMatthew G. Knepley Level: intermediate 1050c0ce001eSMatthew G. Knepley 1051dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVView()` 1052c0ce001eSMatthew G. Knepley @*/ 1053d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetFromOptions(PetscFV fvm) 1054d71ae5a4SJacob Faibussowitsch { 1055c0ce001eSMatthew G. Knepley const char *defaultType; 1056c0ce001eSMatthew G. Knepley char name[256]; 1057c0ce001eSMatthew G. Knepley PetscBool flg; 1058c0ce001eSMatthew G. Knepley 1059c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1060c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1061c0ce001eSMatthew G. Knepley if (!((PetscObject)fvm)->type_name) defaultType = PETSCFVUPWIND; 1062c0ce001eSMatthew G. Knepley else defaultType = ((PetscObject)fvm)->type_name; 10639566063dSJacob Faibussowitsch PetscCall(PetscFVRegisterAll()); 1064c0ce001eSMatthew G. Knepley 1065d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)fvm); 10669566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-petscfv_type", "Finite volume discretization", "PetscFVSetType", PetscFVList, defaultType, name, 256, &flg)); 1067c0ce001eSMatthew G. Knepley if (flg) { 10689566063dSJacob Faibussowitsch PetscCall(PetscFVSetType(fvm, name)); 1069c0ce001eSMatthew G. Knepley } else if (!((PetscObject)fvm)->type_name) { 10709566063dSJacob Faibussowitsch PetscCall(PetscFVSetType(fvm, defaultType)); 1071c0ce001eSMatthew G. Knepley } 10729566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-petscfv_compute_gradients", "Compute cell gradients", "PetscFVSetComputeGradients", fvm->computeGradients, &fvm->computeGradients, NULL)); 1073dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, setfromoptions); 1074c0ce001eSMatthew G. Knepley /* process any options handlers added with PetscObjectAddOptionsHandler() */ 1075dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)fvm, PetscOptionsObject)); 10769566063dSJacob Faibussowitsch PetscCall(PetscLimiterSetFromOptions(fvm->limiter)); 1077d0609cedSBarry Smith PetscOptionsEnd(); 10789566063dSJacob Faibussowitsch PetscCall(PetscFVViewFromOptions(fvm, NULL, "-petscfv_view")); 10793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1080c0ce001eSMatthew G. Knepley } 1081c0ce001eSMatthew G. Knepley 1082c0ce001eSMatthew G. Knepley /*@ 1083dce8aebaSBarry Smith PetscFVSetUp - Setup the data structures for the `PetscFV` based on the `PetscFVType` provided by `PetscFVSetType()` 1084c0ce001eSMatthew G. Knepley 108520f4b53cSBarry Smith Collective 1086c0ce001eSMatthew G. Knepley 1087c0ce001eSMatthew G. Knepley Input Parameter: 1088dce8aebaSBarry Smith . fvm - the `PetscFV` object to setup 1089c0ce001eSMatthew G. Knepley 109088f5f89eSMatthew G. Knepley Level: intermediate 1091c0ce001eSMatthew G. Knepley 1092dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVView()`, `PetscFVDestroy()` 1093c0ce001eSMatthew G. Knepley @*/ 1094d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetUp(PetscFV fvm) 1095d71ae5a4SJacob Faibussowitsch { 1096c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1097c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 10989566063dSJacob Faibussowitsch PetscCall(PetscLimiterSetUp(fvm->limiter)); 1099dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, setup); 11003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1101c0ce001eSMatthew G. Knepley } 1102c0ce001eSMatthew G. Knepley 1103c0ce001eSMatthew G. Knepley /*@ 1104dce8aebaSBarry Smith PetscFVDestroy - Destroys a `PetscFV` object 1105c0ce001eSMatthew G. Knepley 110620f4b53cSBarry Smith Collective 1107c0ce001eSMatthew G. Knepley 1108c0ce001eSMatthew G. Knepley Input Parameter: 1109dce8aebaSBarry Smith . fvm - the `PetscFV` object to destroy 1110c0ce001eSMatthew G. Knepley 111188f5f89eSMatthew G. Knepley Level: beginner 1112c0ce001eSMatthew G. Knepley 1113dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVCreate()`, `PetscFVView()` 1114c0ce001eSMatthew G. Knepley @*/ 1115d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVDestroy(PetscFV *fvm) 1116d71ae5a4SJacob Faibussowitsch { 1117c0ce001eSMatthew G. Knepley PetscInt i; 1118c0ce001eSMatthew G. Knepley 1119c0ce001eSMatthew G. Knepley PetscFunctionBegin; 11203ba16761SJacob Faibussowitsch if (!*fvm) PetscFunctionReturn(PETSC_SUCCESS); 1121c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific((*fvm), PETSCFV_CLASSID, 1); 1122c0ce001eSMatthew G. Knepley 11239371c9d4SSatish Balay if (--((PetscObject)(*fvm))->refct > 0) { 11249371c9d4SSatish Balay *fvm = NULL; 11253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11269371c9d4SSatish Balay } 1127c0ce001eSMatthew G. Knepley ((PetscObject)(*fvm))->refct = 0; 1128c0ce001eSMatthew G. Knepley 112948a46eb9SPierre Jolivet for (i = 0; i < (*fvm)->numComponents; i++) PetscCall(PetscFree((*fvm)->componentNames[i])); 11309566063dSJacob Faibussowitsch PetscCall(PetscFree((*fvm)->componentNames)); 11319566063dSJacob Faibussowitsch PetscCall(PetscLimiterDestroy(&(*fvm)->limiter)); 11329566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&(*fvm)->dualSpace)); 11339566063dSJacob Faibussowitsch PetscCall(PetscFree((*fvm)->fluxWork)); 11349566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&(*fvm)->quadrature)); 11359566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&(*fvm)->T)); 1136c0ce001eSMatthew G. Knepley 1137dbbe0bcdSBarry Smith PetscTryTypeMethod((*fvm), destroy); 11389566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(fvm)); 11393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1140c0ce001eSMatthew G. Knepley } 1141c0ce001eSMatthew G. Knepley 1142c0ce001eSMatthew G. Knepley /*@ 1143dce8aebaSBarry Smith PetscFVCreate - Creates an empty `PetscFV` object. The type can then be set with `PetscFVSetType()`. 1144c0ce001eSMatthew G. Knepley 1145c0ce001eSMatthew G. Knepley Collective 1146c0ce001eSMatthew G. Knepley 1147c0ce001eSMatthew G. Knepley Input Parameter: 1148dce8aebaSBarry Smith . comm - The communicator for the `PetscFV` object 1149c0ce001eSMatthew G. Knepley 1150c0ce001eSMatthew G. Knepley Output Parameter: 1151dce8aebaSBarry Smith . fvm - The `PetscFV` object 1152c0ce001eSMatthew G. Knepley 1153c0ce001eSMatthew G. Knepley Level: beginner 1154c0ce001eSMatthew G. Knepley 11551d27aa22SBarry Smith .seealso: `PetscFVSetUp()`, `PetscFVSetType()`, `PETSCFVUPWIND`, `PetscFVDestroy()` 1156c0ce001eSMatthew G. Knepley @*/ 1157d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVCreate(MPI_Comm comm, PetscFV *fvm) 1158d71ae5a4SJacob Faibussowitsch { 1159c0ce001eSMatthew G. Knepley PetscFV f; 1160c0ce001eSMatthew G. Knepley 1161c0ce001eSMatthew G. Knepley PetscFunctionBegin; 11624f572ea9SToby Isaac PetscAssertPointer(fvm, 2); 1163c0ce001eSMatthew G. Knepley *fvm = NULL; 11649566063dSJacob Faibussowitsch PetscCall(PetscFVInitializePackage()); 1165c0ce001eSMatthew G. Knepley 11669566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(f, PETSCFV_CLASSID, "PetscFV", "Finite Volume", "PetscFV", comm, PetscFVDestroy, PetscFVView)); 11679566063dSJacob Faibussowitsch PetscCall(PetscMemzero(f->ops, sizeof(struct _PetscFVOps))); 1168c0ce001eSMatthew G. Knepley 11699566063dSJacob Faibussowitsch PetscCall(PetscLimiterCreate(comm, &f->limiter)); 1170c0ce001eSMatthew G. Knepley f->numComponents = 1; 1171c0ce001eSMatthew G. Knepley f->dim = 0; 1172c0ce001eSMatthew G. Knepley f->computeGradients = PETSC_FALSE; 1173c0ce001eSMatthew G. Knepley f->fluxWork = NULL; 11749566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(f->numComponents, &f->componentNames)); 1175c0ce001eSMatthew G. Knepley 1176c0ce001eSMatthew G. Knepley *fvm = f; 11773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1178c0ce001eSMatthew G. Knepley } 1179c0ce001eSMatthew G. Knepley 1180c0ce001eSMatthew G. Knepley /*@ 1181dce8aebaSBarry Smith PetscFVSetLimiter - Set the `PetscLimiter` to the `PetscFV` 1182c0ce001eSMatthew G. Knepley 118320f4b53cSBarry Smith Logically Collective 1184c0ce001eSMatthew G. Knepley 1185c0ce001eSMatthew G. Knepley Input Parameters: 1186dce8aebaSBarry Smith + fvm - the `PetscFV` object 1187dce8aebaSBarry Smith - lim - The `PetscLimiter` 1188c0ce001eSMatthew G. Knepley 118988f5f89eSMatthew G. Knepley Level: intermediate 1190c0ce001eSMatthew G. Knepley 1191dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscLimiter`, `PetscFVGetLimiter()` 1192c0ce001eSMatthew G. Knepley @*/ 1193d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetLimiter(PetscFV fvm, PetscLimiter lim) 1194d71ae5a4SJacob Faibussowitsch { 1195c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1196c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1197c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 2); 11989566063dSJacob Faibussowitsch PetscCall(PetscLimiterDestroy(&fvm->limiter)); 11999566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)lim)); 1200c0ce001eSMatthew G. Knepley fvm->limiter = lim; 12013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1202c0ce001eSMatthew G. Knepley } 1203c0ce001eSMatthew G. Knepley 1204c0ce001eSMatthew G. Knepley /*@ 1205dce8aebaSBarry Smith PetscFVGetLimiter - Get the `PetscLimiter` object from the `PetscFV` 1206c0ce001eSMatthew G. Knepley 120720f4b53cSBarry Smith Not Collective 1208c0ce001eSMatthew G. Knepley 1209c0ce001eSMatthew G. Knepley Input Parameter: 1210dce8aebaSBarry Smith . fvm - the `PetscFV` object 1211c0ce001eSMatthew G. Knepley 1212c0ce001eSMatthew G. Knepley Output Parameter: 1213dce8aebaSBarry Smith . lim - The `PetscLimiter` 1214c0ce001eSMatthew G. Knepley 121588f5f89eSMatthew G. Knepley Level: intermediate 1216c0ce001eSMatthew G. Knepley 1217dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscLimiter`, `PetscFVSetLimiter()` 1218c0ce001eSMatthew G. Knepley @*/ 1219d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetLimiter(PetscFV fvm, PetscLimiter *lim) 1220d71ae5a4SJacob Faibussowitsch { 1221c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1222c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 12234f572ea9SToby Isaac PetscAssertPointer(lim, 2); 1224c0ce001eSMatthew G. Knepley *lim = fvm->limiter; 12253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1226c0ce001eSMatthew G. Knepley } 1227c0ce001eSMatthew G. Knepley 1228c0ce001eSMatthew G. Knepley /*@ 1229dce8aebaSBarry Smith PetscFVSetNumComponents - Set the number of field components in a `PetscFV` 1230c0ce001eSMatthew G. Knepley 123120f4b53cSBarry Smith Logically Collective 1232c0ce001eSMatthew G. Knepley 1233c0ce001eSMatthew G. Knepley Input Parameters: 1234dce8aebaSBarry Smith + fvm - the `PetscFV` object 1235c0ce001eSMatthew G. Knepley - comp - The number of components 1236c0ce001eSMatthew G. Knepley 123788f5f89eSMatthew G. Knepley Level: intermediate 1238c0ce001eSMatthew G. Knepley 1239dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVGetNumComponents()` 1240c0ce001eSMatthew G. Knepley @*/ 1241d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetNumComponents(PetscFV fvm, PetscInt comp) 1242d71ae5a4SJacob Faibussowitsch { 1243c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1244c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1245c0ce001eSMatthew G. Knepley if (fvm->numComponents != comp) { 1246c0ce001eSMatthew G. Knepley PetscInt i; 1247c0ce001eSMatthew G. Knepley 124848a46eb9SPierre Jolivet for (i = 0; i < fvm->numComponents; i++) PetscCall(PetscFree(fvm->componentNames[i])); 12499566063dSJacob Faibussowitsch PetscCall(PetscFree(fvm->componentNames)); 12509566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(comp, &fvm->componentNames)); 1251c0ce001eSMatthew G. Knepley } 1252c0ce001eSMatthew G. Knepley fvm->numComponents = comp; 12539566063dSJacob Faibussowitsch PetscCall(PetscFree(fvm->fluxWork)); 12549566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(comp, &fvm->fluxWork)); 12553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1256c0ce001eSMatthew G. Knepley } 1257c0ce001eSMatthew G. Knepley 1258c0ce001eSMatthew G. Knepley /*@ 1259dce8aebaSBarry Smith PetscFVGetNumComponents - Get the number of field components in a `PetscFV` 1260c0ce001eSMatthew G. Knepley 126120f4b53cSBarry Smith Not Collective 1262c0ce001eSMatthew G. Knepley 1263c0ce001eSMatthew G. Knepley Input Parameter: 1264dce8aebaSBarry Smith . fvm - the `PetscFV` object 1265c0ce001eSMatthew G. Knepley 1266c0ce001eSMatthew G. Knepley Output Parameter: 1267a4e35b19SJacob Faibussowitsch . comp - The number of components 1268c0ce001eSMatthew G. Knepley 126988f5f89eSMatthew G. Knepley Level: intermediate 1270c0ce001eSMatthew G. Knepley 1271dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVSetNumComponents()`, `PetscFVSetComponentName()` 1272c0ce001eSMatthew G. Knepley @*/ 1273d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetNumComponents(PetscFV fvm, PetscInt *comp) 1274d71ae5a4SJacob Faibussowitsch { 1275c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1276c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 12774f572ea9SToby Isaac PetscAssertPointer(comp, 2); 1278c0ce001eSMatthew G. Knepley *comp = fvm->numComponents; 12793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1280c0ce001eSMatthew G. Knepley } 1281c0ce001eSMatthew G. Knepley 1282c0ce001eSMatthew G. Knepley /*@C 1283dce8aebaSBarry Smith PetscFVSetComponentName - Set the name of a component (used in output and viewing) in a `PetscFV` 1284c0ce001eSMatthew G. Knepley 128520f4b53cSBarry Smith Logically Collective 1286dce8aebaSBarry Smith 1287c0ce001eSMatthew G. Knepley Input Parameters: 1288dce8aebaSBarry Smith + fvm - the `PetscFV` object 1289c0ce001eSMatthew G. Knepley . comp - the component number 1290c0ce001eSMatthew G. Knepley - name - the component name 1291c0ce001eSMatthew G. Knepley 129288f5f89eSMatthew G. Knepley Level: intermediate 1293c0ce001eSMatthew G. Knepley 1294dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVGetComponentName()` 1295c0ce001eSMatthew G. Knepley @*/ 1296d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetComponentName(PetscFV fvm, PetscInt comp, const char *name) 1297d71ae5a4SJacob Faibussowitsch { 1298c0ce001eSMatthew G. Knepley PetscFunctionBegin; 12999566063dSJacob Faibussowitsch PetscCall(PetscFree(fvm->componentNames[comp])); 13009566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &fvm->componentNames[comp])); 13013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1302c0ce001eSMatthew G. Knepley } 1303c0ce001eSMatthew G. Knepley 1304c0ce001eSMatthew G. Knepley /*@C 1305dce8aebaSBarry Smith PetscFVGetComponentName - Get the name of a component (used in output and viewing) in a `PetscFV` 1306c0ce001eSMatthew G. Knepley 130720f4b53cSBarry Smith Logically Collective 130860225df5SJacob Faibussowitsch 1309c0ce001eSMatthew G. Knepley Input Parameters: 1310dce8aebaSBarry Smith + fvm - the `PetscFV` object 1311c0ce001eSMatthew G. Knepley - comp - the component number 1312c0ce001eSMatthew G. Knepley 1313c0ce001eSMatthew G. Knepley Output Parameter: 1314c0ce001eSMatthew G. Knepley . name - the component name 1315c0ce001eSMatthew G. Knepley 131688f5f89eSMatthew G. Knepley Level: intermediate 1317c0ce001eSMatthew G. Knepley 1318dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVSetComponentName()` 1319c0ce001eSMatthew G. Knepley @*/ 1320d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetComponentName(PetscFV fvm, PetscInt comp, const char **name) 1321d71ae5a4SJacob Faibussowitsch { 1322c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1323c0ce001eSMatthew G. Knepley *name = fvm->componentNames[comp]; 13243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1325c0ce001eSMatthew G. Knepley } 1326c0ce001eSMatthew G. Knepley 1327c0ce001eSMatthew G. Knepley /*@ 1328dce8aebaSBarry Smith PetscFVSetSpatialDimension - Set the spatial dimension of a `PetscFV` 1329c0ce001eSMatthew G. Knepley 133020f4b53cSBarry Smith Logically Collective 1331c0ce001eSMatthew G. Knepley 1332c0ce001eSMatthew G. Knepley Input Parameters: 1333dce8aebaSBarry Smith + fvm - the `PetscFV` object 1334c0ce001eSMatthew G. Knepley - dim - The spatial dimension 1335c0ce001eSMatthew G. Knepley 133688f5f89eSMatthew G. Knepley Level: intermediate 1337c0ce001eSMatthew G. Knepley 1338dce8aebaSBarry Smith .seealso: `PetscFV`, ``PetscFVGetSpatialDimension()` 1339c0ce001eSMatthew G. Knepley @*/ 1340d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetSpatialDimension(PetscFV fvm, PetscInt dim) 1341d71ae5a4SJacob Faibussowitsch { 1342c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1343c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1344c0ce001eSMatthew G. Knepley fvm->dim = dim; 13453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1346c0ce001eSMatthew G. Knepley } 1347c0ce001eSMatthew G. Knepley 1348c0ce001eSMatthew G. Knepley /*@ 1349dce8aebaSBarry Smith PetscFVGetSpatialDimension - Get the spatial dimension of a `PetscFV` 1350c0ce001eSMatthew G. Knepley 135120f4b53cSBarry Smith Not Collective 1352c0ce001eSMatthew G. Knepley 1353c0ce001eSMatthew G. Knepley Input Parameter: 1354dce8aebaSBarry Smith . fvm - the `PetscFV` object 1355c0ce001eSMatthew G. Knepley 1356c0ce001eSMatthew G. Knepley Output Parameter: 1357c0ce001eSMatthew G. Knepley . dim - The spatial dimension 1358c0ce001eSMatthew G. Knepley 135988f5f89eSMatthew G. Knepley Level: intermediate 1360c0ce001eSMatthew G. Knepley 1361dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVSetSpatialDimension()` 1362c0ce001eSMatthew G. Knepley @*/ 1363d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetSpatialDimension(PetscFV fvm, PetscInt *dim) 1364d71ae5a4SJacob Faibussowitsch { 1365c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1366c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 13674f572ea9SToby Isaac PetscAssertPointer(dim, 2); 1368c0ce001eSMatthew G. Knepley *dim = fvm->dim; 13693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1370c0ce001eSMatthew G. Knepley } 1371c0ce001eSMatthew G. Knepley 1372c0ce001eSMatthew G. Knepley /*@ 1373dce8aebaSBarry Smith PetscFVSetComputeGradients - Toggle computation of cell gradients on a `PetscFV` 1374c0ce001eSMatthew G. Knepley 137520f4b53cSBarry Smith Logically Collective 1376c0ce001eSMatthew G. Knepley 1377c0ce001eSMatthew G. Knepley Input Parameters: 1378dce8aebaSBarry Smith + fvm - the `PetscFV` object 1379c0ce001eSMatthew G. Knepley - computeGradients - Flag to compute cell gradients 1380c0ce001eSMatthew G. Knepley 138188f5f89eSMatthew G. Knepley Level: intermediate 1382c0ce001eSMatthew G. Knepley 1383dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVGetComputeGradients()` 1384c0ce001eSMatthew G. Knepley @*/ 1385d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetComputeGradients(PetscFV fvm, PetscBool computeGradients) 1386d71ae5a4SJacob Faibussowitsch { 1387c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1388c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1389c0ce001eSMatthew G. Knepley fvm->computeGradients = computeGradients; 13903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1391c0ce001eSMatthew G. Knepley } 1392c0ce001eSMatthew G. Knepley 1393c0ce001eSMatthew G. Knepley /*@ 1394dce8aebaSBarry Smith PetscFVGetComputeGradients - Return flag for computation of cell gradients on a `PetscFV` 1395c0ce001eSMatthew G. Knepley 139620f4b53cSBarry Smith Not Collective 1397c0ce001eSMatthew G. Knepley 1398c0ce001eSMatthew G. Knepley Input Parameter: 1399dce8aebaSBarry Smith . fvm - the `PetscFV` object 1400c0ce001eSMatthew G. Knepley 1401c0ce001eSMatthew G. Knepley Output Parameter: 1402c0ce001eSMatthew G. Knepley . computeGradients - Flag to compute cell gradients 1403c0ce001eSMatthew G. Knepley 140488f5f89eSMatthew G. Knepley Level: intermediate 1405c0ce001eSMatthew G. Knepley 1406dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVSetComputeGradients()` 1407c0ce001eSMatthew G. Knepley @*/ 1408d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetComputeGradients(PetscFV fvm, PetscBool *computeGradients) 1409d71ae5a4SJacob Faibussowitsch { 1410c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1411c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 14124f572ea9SToby Isaac PetscAssertPointer(computeGradients, 2); 1413c0ce001eSMatthew G. Knepley *computeGradients = fvm->computeGradients; 14143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1415c0ce001eSMatthew G. Knepley } 1416c0ce001eSMatthew G. Knepley 1417c0ce001eSMatthew G. Knepley /*@ 1418dce8aebaSBarry Smith PetscFVSetQuadrature - Set the `PetscQuadrature` object for a `PetscFV` 1419c0ce001eSMatthew G. Knepley 142020f4b53cSBarry Smith Logically Collective 1421c0ce001eSMatthew G. Knepley 1422c0ce001eSMatthew G. Knepley Input Parameters: 1423dce8aebaSBarry Smith + fvm - the `PetscFV` object 1424dce8aebaSBarry Smith - q - The `PetscQuadrature` 1425c0ce001eSMatthew G. Knepley 142688f5f89eSMatthew G. Knepley Level: intermediate 1427c0ce001eSMatthew G. Knepley 1428dce8aebaSBarry Smith .seealso: `PetscQuadrature`, `PetscFV`, `PetscFVGetQuadrature()` 1429c0ce001eSMatthew G. Knepley @*/ 1430d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetQuadrature(PetscFV fvm, PetscQuadrature q) 1431d71ae5a4SJacob Faibussowitsch { 1432c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1433c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 14349566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)q)); 1435*f6feae9bSMatthew G. Knepley PetscCall(PetscQuadratureDestroy(&fvm->quadrature)); 1436c0ce001eSMatthew G. Knepley fvm->quadrature = q; 14373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1438c0ce001eSMatthew G. Knepley } 1439c0ce001eSMatthew G. Knepley 1440c0ce001eSMatthew G. Knepley /*@ 1441dce8aebaSBarry Smith PetscFVGetQuadrature - Get the `PetscQuadrature` from a `PetscFV` 1442c0ce001eSMatthew G. Knepley 144320f4b53cSBarry Smith Not Collective 1444c0ce001eSMatthew G. Knepley 1445c0ce001eSMatthew G. Knepley Input Parameter: 1446dce8aebaSBarry Smith . fvm - the `PetscFV` object 1447c0ce001eSMatthew G. Knepley 1448c0ce001eSMatthew G. Knepley Output Parameter: 144960225df5SJacob Faibussowitsch . q - The `PetscQuadrature` 1450c0ce001eSMatthew G. Knepley 145188f5f89eSMatthew G. Knepley Level: intermediate 1452c0ce001eSMatthew G. Knepley 1453dce8aebaSBarry Smith .seealso: `PetscQuadrature`, `PetscFV`, `PetscFVSetQuadrature()` 1454c0ce001eSMatthew G. Knepley @*/ 1455d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetQuadrature(PetscFV fvm, PetscQuadrature *q) 1456d71ae5a4SJacob Faibussowitsch { 1457c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1458c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 14594f572ea9SToby Isaac PetscAssertPointer(q, 2); 1460c0ce001eSMatthew G. Knepley if (!fvm->quadrature) { 1461c0ce001eSMatthew G. Knepley /* Create default 1-point quadrature */ 1462c0ce001eSMatthew G. Knepley PetscReal *points, *weights; 1463c0ce001eSMatthew G. Knepley 14649566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &fvm->quadrature)); 14659566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(fvm->dim, &points)); 14669566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, &weights)); 1467c0ce001eSMatthew G. Knepley weights[0] = 1.0; 14689566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(fvm->quadrature, fvm->dim, 1, 1, points, weights)); 1469c0ce001eSMatthew G. Knepley } 1470c0ce001eSMatthew G. Knepley *q = fvm->quadrature; 14713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1472c0ce001eSMatthew G. Knepley } 1473c0ce001eSMatthew G. Knepley 1474c0ce001eSMatthew G. Knepley /*@ 1475dce8aebaSBarry Smith PetscFVGetDualSpace - Returns the `PetscDualSpace` used to define the inner product on a `PetscFV` 1476c0ce001eSMatthew G. Knepley 147720f4b53cSBarry Smith Not Collective 1478c0ce001eSMatthew G. Knepley 1479c0ce001eSMatthew G. Knepley Input Parameter: 1480dce8aebaSBarry Smith . fvm - The `PetscFV` object 1481c0ce001eSMatthew G. Knepley 1482c0ce001eSMatthew G. Knepley Output Parameter: 148320f4b53cSBarry Smith . sp - The `PetscDualSpace` object 1484c0ce001eSMatthew G. Knepley 148588f5f89eSMatthew G. Knepley Level: intermediate 1486c0ce001eSMatthew G. Knepley 148760225df5SJacob Faibussowitsch Developer Notes: 1488dce8aebaSBarry Smith There is overlap between the methods of `PetscFE` and `PetscFV`, they should probably share a common parent class 1489dce8aebaSBarry Smith 1490dce8aebaSBarry Smith .seealso: `PetscDualSpace`, `PetscFV`, `PetscFVCreate()` 1491c0ce001eSMatthew G. Knepley @*/ 1492d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetDualSpace(PetscFV fvm, PetscDualSpace *sp) 1493d71ae5a4SJacob Faibussowitsch { 1494c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1495c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 14964f572ea9SToby Isaac PetscAssertPointer(sp, 2); 1497c0ce001eSMatthew G. Knepley if (!fvm->dualSpace) { 1498c0ce001eSMatthew G. Knepley DM K; 1499c0ce001eSMatthew G. Knepley PetscInt dim, Nc, c; 1500c0ce001eSMatthew G. Knepley 15019566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 15029566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &Nc)); 15039566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceCreate(PetscObjectComm((PetscObject)fvm), &fvm->dualSpace)); 15049566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetType(fvm->dualSpace, PETSCDUALSPACESIMPLE)); 15059566063dSJacob Faibussowitsch PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, DMPolytopeTypeSimpleShape(dim, PETSC_FALSE), &K)); 15069566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetNumComponents(fvm->dualSpace, Nc)); 15079566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(fvm->dualSpace, K)); 15089566063dSJacob Faibussowitsch PetscCall(DMDestroy(&K)); 15099566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetDimension(fvm->dualSpace, Nc)); 1510c0ce001eSMatthew G. Knepley /* Should we be using PetscFVGetQuadrature() here? */ 1511c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; ++c) { 1512c0ce001eSMatthew G. Knepley PetscQuadrature qc; 1513c0ce001eSMatthew G. Knepley PetscReal *points, *weights; 1514c0ce001eSMatthew G. Knepley 15159566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qc)); 15169566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(dim, &points)); 15179566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nc, &weights)); 1518c0ce001eSMatthew G. Knepley weights[c] = 1.0; 15199566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(qc, dim, Nc, 1, points, weights)); 15209566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetFunctional(fvm->dualSpace, c, qc)); 15219566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qc)); 1522c0ce001eSMatthew G. Knepley } 15239566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(fvm->dualSpace)); 1524c0ce001eSMatthew G. Knepley } 1525c0ce001eSMatthew G. Knepley *sp = fvm->dualSpace; 15263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1527c0ce001eSMatthew G. Knepley } 1528c0ce001eSMatthew G. Knepley 1529c0ce001eSMatthew G. Knepley /*@ 1530dce8aebaSBarry Smith PetscFVSetDualSpace - Sets the `PetscDualSpace` used to define the inner product 1531c0ce001eSMatthew G. Knepley 153220f4b53cSBarry Smith Not Collective 1533c0ce001eSMatthew G. Knepley 1534c0ce001eSMatthew G. Knepley Input Parameters: 1535dce8aebaSBarry Smith + fvm - The `PetscFV` object 1536dce8aebaSBarry Smith - sp - The `PetscDualSpace` object 1537c0ce001eSMatthew G. Knepley 1538c0ce001eSMatthew G. Knepley Level: intermediate 1539c0ce001eSMatthew G. Knepley 1540dce8aebaSBarry Smith Note: 1541dce8aebaSBarry Smith A simple dual space is provided automatically, and the user typically will not need to override it. 1542c0ce001eSMatthew G. Knepley 1543dce8aebaSBarry Smith .seealso: `PetscDualSpace`, `PetscFV`, `PetscFVCreate()` 1544c0ce001eSMatthew G. Knepley @*/ 1545d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetDualSpace(PetscFV fvm, PetscDualSpace sp) 1546d71ae5a4SJacob Faibussowitsch { 1547c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1548c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1549c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 2); 15509566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&fvm->dualSpace)); 1551c0ce001eSMatthew G. Knepley fvm->dualSpace = sp; 15529566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fvm->dualSpace)); 15533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1554c0ce001eSMatthew G. Knepley } 1555c0ce001eSMatthew G. Knepley 155688f5f89eSMatthew G. Knepley /*@C 1557ef0bb6c7SMatthew G. Knepley PetscFVGetCellTabulation - Returns the tabulation of the basis functions at the quadrature points 155888f5f89eSMatthew G. Knepley 155920f4b53cSBarry Smith Not Collective 156088f5f89eSMatthew G. Knepley 156188f5f89eSMatthew G. Knepley Input Parameter: 1562dce8aebaSBarry Smith . fvm - The `PetscFV` object 156388f5f89eSMatthew G. Knepley 1564ef0bb6c7SMatthew G. Knepley Output Parameter: 1565a5b23f4aSJose E. Roman . T - The basis function values and derivatives at quadrature points 156688f5f89eSMatthew G. Knepley 156788f5f89eSMatthew G. Knepley Level: intermediate 156888f5f89eSMatthew G. Knepley 1569dce8aebaSBarry Smith Note: 1570dce8aebaSBarry Smith .vb 1571dce8aebaSBarry Smith T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 1572dce8aebaSBarry 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 1573dce8aebaSBarry 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 1574dce8aebaSBarry Smith .ve 1575dce8aebaSBarry Smith 1576dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscTabulation`, `PetscFEGetCellTabulation()`, `PetscFVCreateTabulation()`, `PetscFVGetQuadrature()`, `PetscQuadratureGetData()` 157788f5f89eSMatthew G. Knepley @*/ 1578d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetCellTabulation(PetscFV fvm, PetscTabulation *T) 1579d71ae5a4SJacob Faibussowitsch { 1580c0ce001eSMatthew G. Knepley PetscInt npoints; 1581c0ce001eSMatthew G. Knepley const PetscReal *points; 1582c0ce001eSMatthew G. Knepley 1583c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1584c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 15854f572ea9SToby Isaac PetscAssertPointer(T, 2); 15869566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(fvm->quadrature, NULL, NULL, &npoints, &points, NULL)); 15879566063dSJacob Faibussowitsch if (!fvm->T) PetscCall(PetscFVCreateTabulation(fvm, 1, npoints, points, 1, &fvm->T)); 1588ef0bb6c7SMatthew G. Knepley *T = fvm->T; 15893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1590c0ce001eSMatthew G. Knepley } 1591c0ce001eSMatthew G. Knepley 159288f5f89eSMatthew G. Knepley /*@C 1593ef0bb6c7SMatthew G. Knepley PetscFVCreateTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided. 159488f5f89eSMatthew G. Knepley 159520f4b53cSBarry Smith Not Collective 159688f5f89eSMatthew G. Knepley 159788f5f89eSMatthew G. Knepley Input Parameters: 1598dce8aebaSBarry Smith + fvm - The `PetscFV` object 1599ef0bb6c7SMatthew G. Knepley . nrepl - The number of replicas 1600ef0bb6c7SMatthew G. Knepley . npoints - The number of tabulation points in a replica 1601ef0bb6c7SMatthew G. Knepley . points - The tabulation point coordinates 1602ef0bb6c7SMatthew G. Knepley - K - The order of derivative to tabulate 160388f5f89eSMatthew G. Knepley 1604ef0bb6c7SMatthew G. Knepley Output Parameter: 1605a5b23f4aSJose E. Roman . T - The basis function values and derivative at tabulation points 160688f5f89eSMatthew G. Knepley 160788f5f89eSMatthew G. Knepley Level: intermediate 160888f5f89eSMatthew G. Knepley 1609dce8aebaSBarry Smith Note: 1610dce8aebaSBarry Smith .vb 1611dce8aebaSBarry Smith T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 1612dce8aebaSBarry 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 1613dce8aebaSBarry 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 1614dce8aebaSBarry Smith .ve 1615dce8aebaSBarry Smith 1616dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscTabulation`, `PetscFECreateTabulation()`, `PetscTabulationDestroy()`, `PetscFEGetCellTabulation()` 161788f5f89eSMatthew G. Knepley @*/ 1618d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVCreateTabulation(PetscFV fvm, PetscInt nrepl, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation *T) 1619d71ae5a4SJacob Faibussowitsch { 1620c0ce001eSMatthew G. Knepley PetscInt pdim = 1; /* Dimension of approximation space P */ 1621ef0bb6c7SMatthew G. Knepley PetscInt cdim; /* Spatial dimension */ 1622ef0bb6c7SMatthew G. Knepley PetscInt Nc; /* Field components */ 1623ef0bb6c7SMatthew G. Knepley PetscInt k, p, d, c, e; 1624c0ce001eSMatthew G. Knepley 1625c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1626ef0bb6c7SMatthew G. Knepley if (!npoints || K < 0) { 1627ef0bb6c7SMatthew G. Knepley *T = NULL; 16283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1629c0ce001eSMatthew G. Knepley } 1630c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 16314f572ea9SToby Isaac PetscAssertPointer(points, 4); 16324f572ea9SToby Isaac PetscAssertPointer(T, 6); 16339566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &cdim)); 16349566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &Nc)); 16359566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, T)); 1636ef0bb6c7SMatthew G. Knepley (*T)->K = !cdim ? 0 : K; 1637ef0bb6c7SMatthew G. Knepley (*T)->Nr = nrepl; 1638ef0bb6c7SMatthew G. Knepley (*T)->Np = npoints; 1639ef0bb6c7SMatthew G. Knepley (*T)->Nb = pdim; 1640ef0bb6c7SMatthew G. Knepley (*T)->Nc = Nc; 1641ef0bb6c7SMatthew G. Knepley (*T)->cdim = cdim; 16429566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*T)->K + 1, &(*T)->T)); 164348a46eb9SPierre Jolivet for (k = 0; k <= (*T)->K; ++k) PetscCall(PetscMalloc1(nrepl * npoints * pdim * Nc * PetscPowInt(cdim, k), &(*T)->T[k])); 16449371c9d4SSatish Balay if (K >= 0) { 16459371c9d4SSatish Balay for (p = 0; p < nrepl * npoints; ++p) 16469371c9d4SSatish Balay for (d = 0; d < pdim; ++d) 16479371c9d4SSatish Balay for (c = 0; c < Nc; ++c) (*T)->T[0][(p * pdim + d) * Nc + c] = 1.0; 1648ef0bb6c7SMatthew G. Knepley } 16499371c9d4SSatish Balay if (K >= 1) { 16509371c9d4SSatish Balay for (p = 0; p < nrepl * npoints; ++p) 16519371c9d4SSatish Balay for (d = 0; d < pdim; ++d) 16529371c9d4SSatish Balay for (c = 0; c < Nc; ++c) 16539371c9d4SSatish Balay for (e = 0; e < cdim; ++e) (*T)->T[1][((p * pdim + d) * Nc + c) * cdim + e] = 0.0; 16549371c9d4SSatish Balay } 16559371c9d4SSatish Balay if (K >= 2) { 16569371c9d4SSatish Balay for (p = 0; p < nrepl * npoints; ++p) 16579371c9d4SSatish Balay for (d = 0; d < pdim; ++d) 16589371c9d4SSatish Balay for (c = 0; c < Nc; ++c) 16599371c9d4SSatish Balay for (e = 0; e < cdim * cdim; ++e) (*T)->T[2][((p * pdim + d) * Nc + c) * cdim * cdim + e] = 0.0; 16609371c9d4SSatish Balay } 16613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1662c0ce001eSMatthew G. Knepley } 1663c0ce001eSMatthew G. Knepley 1664c0ce001eSMatthew G. Knepley /*@C 1665c0ce001eSMatthew G. Knepley PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell 1666c0ce001eSMatthew G. Knepley 1667c0ce001eSMatthew G. Knepley Input Parameters: 1668dce8aebaSBarry Smith + fvm - The `PetscFV` object 1669c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained 1670c0ce001eSMatthew G. Knepley - dx - The vector from the cell centroid to the neighboring cell centroid for each face 1671c0ce001eSMatthew G. Knepley 1672a4e35b19SJacob Faibussowitsch Output Parameter: 1673a4e35b19SJacob Faibussowitsch . grad - the gradient 1674a4e35b19SJacob Faibussowitsch 167588f5f89eSMatthew G. Knepley Level: advanced 1676c0ce001eSMatthew G. Knepley 1677dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVCreate()` 1678c0ce001eSMatthew G. Knepley @*/ 1679d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVComputeGradient(PetscFV fvm, PetscInt numFaces, PetscScalar dx[], PetscScalar grad[]) 1680d71ae5a4SJacob Faibussowitsch { 1681c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1682c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1683dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, computegradient, numFaces, dx, grad); 16843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1685c0ce001eSMatthew G. Knepley } 1686c0ce001eSMatthew G. Knepley 168788f5f89eSMatthew G. Knepley /*@C 1688c0ce001eSMatthew G. Knepley PetscFVIntegrateRHSFunction - Produce the cell residual vector for a chunk of elements by quadrature integration 1689c0ce001eSMatthew G. Knepley 169020f4b53cSBarry Smith Not Collective 1691c0ce001eSMatthew G. Knepley 1692c0ce001eSMatthew G. Knepley Input Parameters: 1693dce8aebaSBarry Smith + fvm - The `PetscFV` object for the field being integrated 1694da81f932SPierre Jolivet . prob - The `PetscDS` specifying the discretizations and continuum functions 1695c0ce001eSMatthew G. Knepley . field - The field being integrated 1696c0ce001eSMatthew G. Knepley . Nf - The number of faces in the chunk 1697c0ce001eSMatthew G. Knepley . fgeom - The face geometry for each face in the chunk 1698c0ce001eSMatthew G. Knepley . neighborVol - The volume for each pair of cells in the chunk 1699c0ce001eSMatthew G. Knepley . uL - The state from the cell on the left 1700c0ce001eSMatthew G. Knepley - uR - The state from the cell on the right 1701c0ce001eSMatthew G. Knepley 1702d8d19677SJose E. Roman Output Parameters: 1703c0ce001eSMatthew G. Knepley + fluxL - the left fluxes for each face 1704c0ce001eSMatthew G. Knepley - fluxR - the right fluxes for each face 170588f5f89eSMatthew G. Knepley 170688f5f89eSMatthew G. Knepley Level: developer 170788f5f89eSMatthew G. Knepley 1708dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscDS`, `PetscFVFaceGeom`, `PetscFVCreate()` 170988f5f89eSMatthew G. Knepley @*/ 1710d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVIntegrateRHSFunction(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) 1711d71ae5a4SJacob Faibussowitsch { 1712c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1713c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1714dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, integraterhsfunction, prob, field, Nf, fgeom, neighborVol, uL, uR, fluxL, fluxR); 17153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1716c0ce001eSMatthew G. Knepley } 1717c0ce001eSMatthew G. Knepley 1718c0ce001eSMatthew G. Knepley /*@ 1719*f6feae9bSMatthew G. Knepley PetscFVClone - Create a shallow copy of a `PetscFV` object that jsut references the internal objects. 1720*f6feae9bSMatthew G. Knepley 1721*f6feae9bSMatthew G. Knepley Input Parameter: 1722*f6feae9bSMatthew G. Knepley . fv - The initial `PetscFV` 1723*f6feae9bSMatthew G. Knepley 1724*f6feae9bSMatthew G. Knepley Output Parameter: 1725*f6feae9bSMatthew G. Knepley . fvNew - A clone of the `PetscFV` 1726*f6feae9bSMatthew G. Knepley 1727*f6feae9bSMatthew G. Knepley Level: advanced 1728*f6feae9bSMatthew G. Knepley 1729*f6feae9bSMatthew G. Knepley Notes: 1730*f6feae9bSMatthew G. Knepley This is typically used to change the number of components. 1731*f6feae9bSMatthew G. Knepley 1732*f6feae9bSMatthew G. Knepley .seealso: `PetscFV`, `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 1733*f6feae9bSMatthew G. Knepley @*/ 1734*f6feae9bSMatthew G. Knepley PetscErrorCode PetscFVClone(PetscFV fv, PetscFV *fvNew) 1735*f6feae9bSMatthew G. Knepley { 1736*f6feae9bSMatthew G. Knepley PetscDualSpace Q; 1737*f6feae9bSMatthew G. Knepley DM K; 1738*f6feae9bSMatthew G. Knepley PetscQuadrature q; 1739*f6feae9bSMatthew G. Knepley PetscInt Nc, cdim; 1740*f6feae9bSMatthew G. Knepley 1741*f6feae9bSMatthew G. Knepley PetscFunctionBegin; 1742*f6feae9bSMatthew G. Knepley PetscCall(PetscFVGetDualSpace(fv, &Q)); 1743*f6feae9bSMatthew G. Knepley PetscCall(PetscFVGetQuadrature(fv, &q)); 1744*f6feae9bSMatthew G. Knepley PetscCall(PetscDualSpaceGetDM(Q, &K)); 1745*f6feae9bSMatthew G. Knepley 1746*f6feae9bSMatthew G. Knepley PetscCall(PetscFVCreate(PetscObjectComm((PetscObject)fv), fvNew)); 1747*f6feae9bSMatthew G. Knepley PetscCall(PetscFVSetDualSpace(*fvNew, Q)); 1748*f6feae9bSMatthew G. Knepley PetscCall(PetscFVGetNumComponents(fv, &Nc)); 1749*f6feae9bSMatthew G. Knepley PetscCall(PetscFVSetNumComponents(*fvNew, Nc)); 1750*f6feae9bSMatthew G. Knepley PetscCall(PetscFVGetSpatialDimension(fv, &cdim)); 1751*f6feae9bSMatthew G. Knepley PetscCall(PetscFVSetSpatialDimension(*fvNew, cdim)); 1752*f6feae9bSMatthew G. Knepley PetscCall(PetscFVSetQuadrature(*fvNew, q)); 1753*f6feae9bSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 1754*f6feae9bSMatthew G. Knepley } 1755*f6feae9bSMatthew G. Knepley 1756*f6feae9bSMatthew G. Knepley /*@ 1757a4e35b19SJacob Faibussowitsch PetscFVRefine - Create a "refined" `PetscFV` object that refines the reference cell into 1758a4e35b19SJacob Faibussowitsch smaller copies. 1759c0ce001eSMatthew G. Knepley 1760c0ce001eSMatthew G. Knepley Input Parameter: 1761dce8aebaSBarry Smith . fv - The initial `PetscFV` 1762c0ce001eSMatthew G. Knepley 1763c0ce001eSMatthew G. Knepley Output Parameter: 1764dce8aebaSBarry Smith . fvRef - The refined `PetscFV` 1765c0ce001eSMatthew G. Knepley 176688f5f89eSMatthew G. Knepley Level: advanced 1767c0ce001eSMatthew G. Knepley 1768a4e35b19SJacob Faibussowitsch Notes: 1769a4e35b19SJacob Faibussowitsch This is typically used to generate a preconditioner for a high order method from a lower order method on a 1770a4e35b19SJacob Faibussowitsch refined mesh having the same number of dofs (but more sparsity). It is also used to create an 1771a4e35b19SJacob Faibussowitsch interpolation between regularly refined meshes. 1772a4e35b19SJacob Faibussowitsch 1773dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 1774c0ce001eSMatthew G. Knepley @*/ 1775d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVRefine(PetscFV fv, PetscFV *fvRef) 1776d71ae5a4SJacob Faibussowitsch { 1777c0ce001eSMatthew G. Knepley PetscDualSpace Q, Qref; 1778c0ce001eSMatthew G. Knepley DM K, Kref; 1779c0ce001eSMatthew G. Knepley PetscQuadrature q, qref; 1780412e9a14SMatthew G. Knepley DMPolytopeType ct; 1781012bc364SMatthew G. Knepley DMPlexTransform tr; 1782c0ce001eSMatthew G. Knepley PetscReal *v0; 1783c0ce001eSMatthew G. Knepley PetscReal *jac, *invjac; 1784c0ce001eSMatthew G. Knepley PetscInt numComp, numSubelements, s; 1785c0ce001eSMatthew G. Knepley 1786c0ce001eSMatthew G. Knepley PetscFunctionBegin; 17879566063dSJacob Faibussowitsch PetscCall(PetscFVGetDualSpace(fv, &Q)); 17889566063dSJacob Faibussowitsch PetscCall(PetscFVGetQuadrature(fv, &q)); 17899566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &K)); 1790c0ce001eSMatthew G. Knepley /* Create dual space */ 17919566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDuplicate(Q, &Qref)); 17929566063dSJacob Faibussowitsch PetscCall(DMRefine(K, PetscObjectComm((PetscObject)fv), &Kref)); 17939566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(Qref, Kref)); 17949566063dSJacob Faibussowitsch PetscCall(DMDestroy(&Kref)); 17959566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(Qref)); 1796c0ce001eSMatthew G. Knepley /* Create volume */ 17979566063dSJacob Faibussowitsch PetscCall(PetscFVCreate(PetscObjectComm((PetscObject)fv), fvRef)); 17989566063dSJacob Faibussowitsch PetscCall(PetscFVSetDualSpace(*fvRef, Qref)); 17999566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &numComp)); 18009566063dSJacob Faibussowitsch PetscCall(PetscFVSetNumComponents(*fvRef, numComp)); 18019566063dSJacob Faibussowitsch PetscCall(PetscFVSetUp(*fvRef)); 1802c0ce001eSMatthew G. Knepley /* Create quadrature */ 18039566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(K, 0, &ct)); 18049566063dSJacob Faibussowitsch PetscCall(DMPlexTransformCreate(PETSC_COMM_SELF, &tr)); 18059566063dSJacob Faibussowitsch PetscCall(DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR)); 18069566063dSJacob Faibussowitsch PetscCall(DMPlexRefineRegularGetAffineTransforms(tr, ct, &numSubelements, &v0, &jac, &invjac)); 18079566063dSJacob Faibussowitsch PetscCall(PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref)); 18089566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetDimension(Qref, numSubelements)); 1809c0ce001eSMatthew G. Knepley for (s = 0; s < numSubelements; ++s) { 1810c0ce001eSMatthew G. Knepley PetscQuadrature qs; 1811c0ce001eSMatthew G. Knepley const PetscReal *points, *weights; 1812c0ce001eSMatthew G. Knepley PetscReal *p, *w; 1813c0ce001eSMatthew G. Knepley PetscInt dim, Nc, npoints, np; 1814c0ce001eSMatthew G. Knepley 18159566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qs)); 18169566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(q, &dim, &Nc, &npoints, &points, &weights)); 1817c0ce001eSMatthew G. Knepley np = npoints / numSubelements; 18189566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(np * dim, &p)); 18199566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(np * Nc, &w)); 18209566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(p, &points[s * np * dim], np * dim)); 18219566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(w, &weights[s * np * Nc], np * Nc)); 18229566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(qs, dim, Nc, np, p, w)); 18239566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetFunctional(Qref, s, qs)); 18249566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qs)); 1825c0ce001eSMatthew G. Knepley } 18269566063dSJacob Faibussowitsch PetscCall(PetscFVSetQuadrature(*fvRef, qref)); 18279566063dSJacob Faibussowitsch PetscCall(DMPlexTransformDestroy(&tr)); 18289566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qref)); 18299566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&Qref)); 18303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1831c0ce001eSMatthew G. Knepley } 1832c0ce001eSMatthew G. Knepley 1833d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVDestroy_Upwind(PetscFV fvm) 1834d71ae5a4SJacob Faibussowitsch { 1835c0ce001eSMatthew G. Knepley PetscFV_Upwind *b = (PetscFV_Upwind *)fvm->data; 1836c0ce001eSMatthew G. Knepley 1837c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18389566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 18393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1840c0ce001eSMatthew G. Knepley } 1841c0ce001eSMatthew G. Knepley 1842d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_Upwind_Ascii(PetscFV fv, PetscViewer viewer) 1843d71ae5a4SJacob Faibussowitsch { 1844c0ce001eSMatthew G. Knepley PetscInt Nc, c; 1845c0ce001eSMatthew G. Knepley PetscViewerFormat format; 1846c0ce001eSMatthew G. Knepley 1847c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18489566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &Nc)); 18499566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 18509566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Upwind Finite Volume:\n")); 185163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " num components: %" PetscInt_FMT "\n", Nc)); 1852c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; c++) { 185348a46eb9SPierre Jolivet if (fv->componentNames[c]) PetscCall(PetscViewerASCIIPrintf(viewer, " component %" PetscInt_FMT ": %s\n", c, fv->componentNames[c])); 1854c0ce001eSMatthew G. Knepley } 18553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1856c0ce001eSMatthew G. Knepley } 1857c0ce001eSMatthew G. Knepley 1858d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_Upwind(PetscFV fv, PetscViewer viewer) 1859d71ae5a4SJacob Faibussowitsch { 1860c0ce001eSMatthew G. Knepley PetscBool iascii; 1861c0ce001eSMatthew G. Knepley 1862c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1863c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1); 1864c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 18659566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 18669566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscFVView_Upwind_Ascii(fv, viewer)); 18673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1868c0ce001eSMatthew G. Knepley } 1869c0ce001eSMatthew G. Knepley 1870d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVSetUp_Upwind(PetscFV fvm) 1871d71ae5a4SJacob Faibussowitsch { 1872c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1874c0ce001eSMatthew G. Knepley } 1875c0ce001eSMatthew G. Knepley 1876c0ce001eSMatthew G. Knepley /* 1877c0ce001eSMatthew G. Knepley neighborVol[f*2+0] contains the left geom 1878c0ce001eSMatthew G. Knepley neighborVol[f*2+1] contains the right geom 1879c0ce001eSMatthew G. Knepley */ 1880d71ae5a4SJacob 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[]) 1881d71ae5a4SJacob Faibussowitsch { 1882c0ce001eSMatthew G. Knepley void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *); 1883c0ce001eSMatthew G. Knepley void *rctx; 1884c0ce001eSMatthew G. Knepley PetscScalar *flux = fvm->fluxWork; 1885c0ce001eSMatthew G. Knepley const PetscScalar *constants; 1886c0ce001eSMatthew G. Knepley PetscInt dim, numConstants, pdim, totDim, Nc, off, f, d; 1887c0ce001eSMatthew G. Knepley 1888c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18899566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalComponents(prob, &Nc)); 18909566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalDimension(prob, &totDim)); 18919566063dSJacob Faibussowitsch PetscCall(PetscDSGetFieldOffset(prob, field, &off)); 18929566063dSJacob Faibussowitsch PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann)); 18939566063dSJacob Faibussowitsch PetscCall(PetscDSGetContext(prob, field, &rctx)); 18949566063dSJacob Faibussowitsch PetscCall(PetscDSGetConstants(prob, &numConstants, &constants)); 18959566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 18969566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &pdim)); 1897c0ce001eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 1898c0ce001eSMatthew G. Knepley (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f * Nc], &uR[f * Nc], numConstants, constants, flux, rctx); 1899c0ce001eSMatthew G. Knepley for (d = 0; d < pdim; ++d) { 1900c0ce001eSMatthew G. Knepley fluxL[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 0]; 1901c0ce001eSMatthew G. Knepley fluxR[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 1]; 1902c0ce001eSMatthew G. Knepley } 1903c0ce001eSMatthew G. Knepley } 19043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1905c0ce001eSMatthew G. Knepley } 1906c0ce001eSMatthew G. Knepley 1907d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVInitialize_Upwind(PetscFV fvm) 1908d71ae5a4SJacob Faibussowitsch { 1909c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1910c0ce001eSMatthew G. Knepley fvm->ops->setfromoptions = NULL; 1911c0ce001eSMatthew G. Knepley fvm->ops->setup = PetscFVSetUp_Upwind; 1912c0ce001eSMatthew G. Knepley fvm->ops->view = PetscFVView_Upwind; 1913c0ce001eSMatthew G. Knepley fvm->ops->destroy = PetscFVDestroy_Upwind; 1914c0ce001eSMatthew G. Knepley fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_Upwind; 19153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1916c0ce001eSMatthew G. Knepley } 1917c0ce001eSMatthew G. Knepley 1918c0ce001eSMatthew G. Knepley /*MC 1919dce8aebaSBarry Smith PETSCFVUPWIND = "upwind" - A `PetscFV` implementation 1920c0ce001eSMatthew G. Knepley 1921c0ce001eSMatthew G. Knepley Level: intermediate 1922c0ce001eSMatthew G. Knepley 1923dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 1924c0ce001eSMatthew G. Knepley M*/ 1925c0ce001eSMatthew G. Knepley 1926d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscFVCreate_Upwind(PetscFV fvm) 1927d71ae5a4SJacob Faibussowitsch { 1928c0ce001eSMatthew G. Knepley PetscFV_Upwind *b; 1929c0ce001eSMatthew G. Knepley 1930c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1931c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 19324dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 1933c0ce001eSMatthew G. Knepley fvm->data = b; 1934c0ce001eSMatthew G. Knepley 19359566063dSJacob Faibussowitsch PetscCall(PetscFVInitialize_Upwind(fvm)); 19363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1937c0ce001eSMatthew G. Knepley } 1938c0ce001eSMatthew G. Knepley 1939c0ce001eSMatthew G. Knepley #include <petscblaslapack.h> 1940c0ce001eSMatthew G. Knepley 1941d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVDestroy_LeastSquares(PetscFV fvm) 1942d71ae5a4SJacob Faibussowitsch { 1943c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data; 1944c0ce001eSMatthew G. Knepley 1945c0ce001eSMatthew G. Knepley PetscFunctionBegin; 19469566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fvm, "PetscFVLeastSquaresSetMaxFaces_C", NULL)); 19479566063dSJacob Faibussowitsch PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work)); 19489566063dSJacob Faibussowitsch PetscCall(PetscFree(ls)); 19493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1950c0ce001eSMatthew G. Knepley } 1951c0ce001eSMatthew G. Knepley 1952d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_LeastSquares_Ascii(PetscFV fv, PetscViewer viewer) 1953d71ae5a4SJacob Faibussowitsch { 1954c0ce001eSMatthew G. Knepley PetscInt Nc, c; 1955c0ce001eSMatthew G. Knepley PetscViewerFormat format; 1956c0ce001eSMatthew G. Knepley 1957c0ce001eSMatthew G. Knepley PetscFunctionBegin; 19589566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &Nc)); 19599566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 19609566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Finite Volume with Least Squares Reconstruction:\n")); 196163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " num components: %" PetscInt_FMT "\n", Nc)); 1962c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; c++) { 196348a46eb9SPierre Jolivet if (fv->componentNames[c]) PetscCall(PetscViewerASCIIPrintf(viewer, " component %" PetscInt_FMT ": %s\n", c, fv->componentNames[c])); 1964c0ce001eSMatthew G. Knepley } 19653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1966c0ce001eSMatthew G. Knepley } 1967c0ce001eSMatthew G. Knepley 1968d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_LeastSquares(PetscFV fv, PetscViewer viewer) 1969d71ae5a4SJacob Faibussowitsch { 1970c0ce001eSMatthew G. Knepley PetscBool iascii; 1971c0ce001eSMatthew G. Knepley 1972c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1973c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1); 1974c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 19759566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 19769566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscFVView_LeastSquares_Ascii(fv, viewer)); 19773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1978c0ce001eSMatthew G. Knepley } 1979c0ce001eSMatthew G. Knepley 1980d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVSetUp_LeastSquares(PetscFV fvm) 1981d71ae5a4SJacob Faibussowitsch { 1982c0ce001eSMatthew G. Knepley PetscFunctionBegin; 19833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1984c0ce001eSMatthew G. Knepley } 1985c0ce001eSMatthew G. Knepley 1986c0ce001eSMatthew G. Knepley /* Overwrites A. Can only handle full-rank problems with m>=n */ 1987d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresPseudoInverse_Static(PetscInt m, PetscInt mstride, PetscInt n, PetscScalar *A, PetscScalar *Ainv, PetscScalar *tau, PetscInt worksize, PetscScalar *work) 1988d71ae5a4SJacob Faibussowitsch { 1989c0ce001eSMatthew G. Knepley PetscBool debug = PETSC_FALSE; 1990c0ce001eSMatthew G. Knepley PetscBLASInt M, N, K, lda, ldb, ldwork, info; 1991c0ce001eSMatthew G. Knepley PetscScalar *R, *Q, *Aback, Alpha; 1992c0ce001eSMatthew G. Knepley 1993c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1994c0ce001eSMatthew G. Knepley if (debug) { 19959566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * n, &Aback)); 19969566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(Aback, A, m * n)); 1997c0ce001eSMatthew G. Knepley } 1998c0ce001eSMatthew G. Knepley 19999566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &M)); 20009566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &N)); 20019566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(mstride, &lda)); 20029566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(worksize, &ldwork)); 20039566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 2004792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&M, &N, A, &lda, tau, work, &ldwork, &info)); 20059566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 200628b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xGEQRF error"); 2007c0ce001eSMatthew G. Knepley R = A; /* Upper triangular part of A now contains R, the rest contains the elementary reflectors */ 2008c0ce001eSMatthew G. Knepley 2009c0ce001eSMatthew G. Knepley /* Extract an explicit representation of Q */ 2010c0ce001eSMatthew G. Knepley Q = Ainv; 20119566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(Q, A, mstride * n)); 2012c0ce001eSMatthew G. Knepley K = N; /* full rank */ 2013792fecdfSBarry Smith PetscCallBLAS("LAPACKorgqr", LAPACKorgqr_(&M, &N, &K, Q, &lda, tau, work, &ldwork, &info)); 201428b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xORGQR/xUNGQR error"); 2015c0ce001eSMatthew G. Knepley 2016c0ce001eSMatthew G. Knepley /* Compute A^{-T} = (R^{-1} Q^T)^T = Q R^{-T} */ 2017c0ce001eSMatthew G. Knepley Alpha = 1.0; 2018c0ce001eSMatthew G. Knepley ldb = lda; 2019c0ce001eSMatthew G. Knepley BLAStrsm_("Right", "Upper", "ConjugateTranspose", "NotUnitTriangular", &M, &N, &Alpha, R, &lda, Q, &ldb); 2020c0ce001eSMatthew G. Knepley /* Ainv is Q, overwritten with inverse */ 2021c0ce001eSMatthew G. Knepley 2022c0ce001eSMatthew G. Knepley if (debug) { /* Check that pseudo-inverse worked */ 2023c0ce001eSMatthew G. Knepley PetscScalar Beta = 0.0; 2024c0ce001eSMatthew G. Knepley PetscBLASInt ldc; 2025c0ce001eSMatthew G. Knepley K = N; 2026c0ce001eSMatthew G. Knepley ldc = N; 2027c0ce001eSMatthew G. Knepley BLASgemm_("ConjugateTranspose", "Normal", &N, &K, &M, &Alpha, Ainv, &lda, Aback, &ldb, &Beta, work, &ldc); 20289566063dSJacob Faibussowitsch PetscCall(PetscScalarView(n * n, work, PETSC_VIEWER_STDOUT_SELF)); 20299566063dSJacob Faibussowitsch PetscCall(PetscFree(Aback)); 2030c0ce001eSMatthew G. Knepley } 20313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2032c0ce001eSMatthew G. Knepley } 2033c0ce001eSMatthew G. Knepley 2034c0ce001eSMatthew G. Knepley /* Overwrites A. Can handle degenerate problems and m<n. */ 2035d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresPseudoInverseSVD_Static(PetscInt m, PetscInt mstride, PetscInt n, PetscScalar *A, PetscScalar *Ainv, PetscScalar *tau, PetscInt worksize, PetscScalar *work) 2036d71ae5a4SJacob Faibussowitsch { 20376bb27163SBarry Smith PetscScalar *Brhs; 2038c0ce001eSMatthew G. Knepley PetscScalar *tmpwork; 2039c0ce001eSMatthew G. Knepley PetscReal rcond; 2040c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX) 2041c0ce001eSMatthew G. Knepley PetscInt rworkSize; 2042c0ce001eSMatthew G. Knepley PetscReal *rwork; 2043c0ce001eSMatthew G. Knepley #endif 2044c0ce001eSMatthew G. Knepley PetscInt i, j, maxmn; 2045c0ce001eSMatthew G. Knepley PetscBLASInt M, N, lda, ldb, ldwork; 2046c0ce001eSMatthew G. Knepley PetscBLASInt nrhs, irank, info; 2047c0ce001eSMatthew G. Knepley 2048c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2049c0ce001eSMatthew G. Knepley /* initialize to identity */ 2050736d4f42SpierreXVI tmpwork = work; 2051736d4f42SpierreXVI Brhs = Ainv; 2052c0ce001eSMatthew G. Knepley maxmn = PetscMax(m, n); 2053c0ce001eSMatthew G. Knepley for (j = 0; j < maxmn; j++) { 2054c0ce001eSMatthew G. Knepley for (i = 0; i < maxmn; i++) Brhs[i + j * maxmn] = 1.0 * (i == j); 2055c0ce001eSMatthew G. Knepley } 2056c0ce001eSMatthew G. Knepley 20579566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &M)); 20589566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &N)); 20599566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(mstride, &lda)); 20609566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(maxmn, &ldb)); 20619566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(worksize, &ldwork)); 2062c0ce001eSMatthew G. Knepley rcond = -1; 2063c0ce001eSMatthew G. Knepley nrhs = M; 2064c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX) 2065c0ce001eSMatthew G. Knepley rworkSize = 5 * PetscMin(M, N); 20669566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(rworkSize, &rwork)); 20676bb27163SBarry Smith PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 2068792fecdfSBarry Smith PetscCallBLAS("LAPACKgelss", LAPACKgelss_(&M, &N, &nrhs, A, &lda, Brhs, &ldb, (PetscReal *)tau, &rcond, &irank, tmpwork, &ldwork, rwork, &info)); 20699566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 20709566063dSJacob Faibussowitsch PetscCall(PetscFree(rwork)); 2071c0ce001eSMatthew G. Knepley #else 2072c0ce001eSMatthew G. Knepley nrhs = M; 20736bb27163SBarry Smith PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 2074792fecdfSBarry Smith PetscCallBLAS("LAPACKgelss", LAPACKgelss_(&M, &N, &nrhs, A, &lda, Brhs, &ldb, (PetscReal *)tau, &rcond, &irank, tmpwork, &ldwork, &info)); 20759566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 2076c0ce001eSMatthew G. Knepley #endif 207728b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xGELSS error"); 2078c0ce001eSMatthew G. Knepley /* The following check should be turned into a diagnostic as soon as someone wants to do this intentionally */ 207908401ef6SPierre 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"); 20803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2081c0ce001eSMatthew G. Knepley } 2082c0ce001eSMatthew G. Knepley 2083c0ce001eSMatthew G. Knepley #if 0 2084c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresDebugCell_Static(PetscFV fvm, PetscInt cell, DM dm, DM dmFace, PetscScalar *fgeom, DM dmCell, PetscScalar *cgeom) 2085c0ce001eSMatthew G. Knepley { 2086c0ce001eSMatthew G. Knepley PetscReal grad[2] = {0, 0}; 2087c0ce001eSMatthew G. Knepley const PetscInt *faces; 2088c0ce001eSMatthew G. Knepley PetscInt numFaces, f; 2089c0ce001eSMatthew G. Knepley 2090c0ce001eSMatthew G. Knepley PetscFunctionBegin; 20919566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, cell, &numFaces)); 20929566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, cell, &faces)); 2093c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2094c0ce001eSMatthew G. Knepley const PetscInt *fcells; 2095c0ce001eSMatthew G. Knepley const CellGeom *cg1; 2096c0ce001eSMatthew G. Knepley const FaceGeom *fg; 2097c0ce001eSMatthew G. Knepley 20989566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupport(dm, faces[f], &fcells)); 20999566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmFace, faces[f], fgeom, &fg)); 2100c0ce001eSMatthew G. Knepley for (i = 0; i < 2; ++i) { 2101c0ce001eSMatthew G. Knepley PetscScalar du; 2102c0ce001eSMatthew G. Knepley 2103c0ce001eSMatthew G. Knepley if (fcells[i] == c) continue; 21049566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmCell, fcells[i], cgeom, &cg1)); 2105c0ce001eSMatthew G. Knepley du = cg1->centroid[0] + 3*cg1->centroid[1] - (cg->centroid[0] + 3*cg->centroid[1]); 2106c0ce001eSMatthew G. Knepley grad[0] += fg->grad[!i][0] * du; 2107c0ce001eSMatthew G. Knepley grad[1] += fg->grad[!i][1] * du; 2108c0ce001eSMatthew G. Knepley } 2109c0ce001eSMatthew G. Knepley } 21109566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "cell[%d] grad (%g, %g)\n", cell, grad[0], grad[1])); 21113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2112c0ce001eSMatthew G. Knepley } 2113c0ce001eSMatthew G. Knepley #endif 2114c0ce001eSMatthew G. Knepley 2115c0ce001eSMatthew G. Knepley /* 2116c0ce001eSMatthew G. Knepley PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell 2117c0ce001eSMatthew G. Knepley 2118c0ce001eSMatthew G. Knepley Input Parameters: 2119dce8aebaSBarry Smith + fvm - The `PetscFV` object 2120c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained 2121c0ce001eSMatthew G. Knepley . dx - The vector from the cell centroid to the neighboring cell centroid for each face 2122c0ce001eSMatthew G. Knepley 2123c0ce001eSMatthew G. Knepley Level: developer 2124c0ce001eSMatthew G. Knepley 2125dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVCreate()` 2126c0ce001eSMatthew G. Knepley */ 2127d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVComputeGradient_LeastSquares(PetscFV fvm, PetscInt numFaces, const PetscScalar dx[], PetscScalar grad[]) 2128d71ae5a4SJacob Faibussowitsch { 2129c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data; 2130c0ce001eSMatthew G. Knepley const PetscBool useSVD = PETSC_TRUE; 2131c0ce001eSMatthew G. Knepley const PetscInt maxFaces = ls->maxFaces; 2132c0ce001eSMatthew G. Knepley PetscInt dim, f, d; 2133c0ce001eSMatthew G. Knepley 2134c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2135c0ce001eSMatthew G. Knepley if (numFaces > maxFaces) { 213608401ef6SPierre Jolivet PetscCheck(maxFaces >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Reconstruction has not been initialized, call PetscFVLeastSquaresSetMaxFaces()"); 213763a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of input faces %" PetscInt_FMT " > %" PetscInt_FMT " maxfaces", numFaces, maxFaces); 2138c0ce001eSMatthew G. Knepley } 21399566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 2140c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2141c0ce001eSMatthew G. Knepley for (d = 0; d < dim; ++d) ls->B[d * maxFaces + f] = dx[f * dim + d]; 2142c0ce001eSMatthew G. Knepley } 2143c0ce001eSMatthew G. Knepley /* Overwrites B with garbage, returns Binv in row-major format */ 2144736d4f42SpierreXVI if (useSVD) { 2145736d4f42SpierreXVI PetscInt maxmn = PetscMax(numFaces, dim); 21469566063dSJacob Faibussowitsch PetscCall(PetscFVLeastSquaresPseudoInverseSVD_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work)); 2147736d4f42SpierreXVI /* Binv shaped in column-major, coldim=maxmn.*/ 2148736d4f42SpierreXVI for (f = 0; f < numFaces; ++f) { 2149736d4f42SpierreXVI for (d = 0; d < dim; ++d) grad[f * dim + d] = ls->Binv[d + maxmn * f]; 2150736d4f42SpierreXVI } 2151736d4f42SpierreXVI } else { 21529566063dSJacob Faibussowitsch PetscCall(PetscFVLeastSquaresPseudoInverse_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work)); 2153736d4f42SpierreXVI /* Binv shaped in row-major, rowdim=maxFaces.*/ 2154c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2155c0ce001eSMatthew G. Knepley for (d = 0; d < dim; ++d) grad[f * dim + d] = ls->Binv[d * maxFaces + f]; 2156c0ce001eSMatthew G. Knepley } 2157736d4f42SpierreXVI } 21583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2159c0ce001eSMatthew G. Knepley } 2160c0ce001eSMatthew G. Knepley 2161c0ce001eSMatthew G. Knepley /* 2162c0ce001eSMatthew G. Knepley neighborVol[f*2+0] contains the left geom 2163c0ce001eSMatthew G. Knepley neighborVol[f*2+1] contains the right geom 2164c0ce001eSMatthew G. Knepley */ 2165d71ae5a4SJacob 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[]) 2166d71ae5a4SJacob Faibussowitsch { 2167c0ce001eSMatthew G. Knepley void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *); 2168c0ce001eSMatthew G. Knepley void *rctx; 2169c0ce001eSMatthew G. Knepley PetscScalar *flux = fvm->fluxWork; 2170c0ce001eSMatthew G. Knepley const PetscScalar *constants; 2171c0ce001eSMatthew G. Knepley PetscInt dim, numConstants, pdim, Nc, totDim, off, f, d; 2172c0ce001eSMatthew G. Knepley 2173c0ce001eSMatthew G. Knepley PetscFunctionBegin; 21749566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalComponents(prob, &Nc)); 21759566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalDimension(prob, &totDim)); 21769566063dSJacob Faibussowitsch PetscCall(PetscDSGetFieldOffset(prob, field, &off)); 21779566063dSJacob Faibussowitsch PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann)); 21789566063dSJacob Faibussowitsch PetscCall(PetscDSGetContext(prob, field, &rctx)); 21799566063dSJacob Faibussowitsch PetscCall(PetscDSGetConstants(prob, &numConstants, &constants)); 21809566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 21819566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &pdim)); 2182c0ce001eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2183c0ce001eSMatthew G. Knepley (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f * Nc], &uR[f * Nc], numConstants, constants, flux, rctx); 2184c0ce001eSMatthew G. Knepley for (d = 0; d < pdim; ++d) { 2185c0ce001eSMatthew G. Knepley fluxL[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 0]; 2186c0ce001eSMatthew G. Knepley fluxR[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 1]; 2187c0ce001eSMatthew G. Knepley } 2188c0ce001eSMatthew G. Knepley } 21893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2190c0ce001eSMatthew G. Knepley } 2191c0ce001eSMatthew G. Knepley 2192d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresSetMaxFaces_LS(PetscFV fvm, PetscInt maxFaces) 2193d71ae5a4SJacob Faibussowitsch { 2194c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data; 2195736d4f42SpierreXVI PetscInt dim, m, n, nrhs, minmn, maxmn; 2196c0ce001eSMatthew G. Knepley 2197c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2198c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 21999566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 22009566063dSJacob Faibussowitsch PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work)); 2201c0ce001eSMatthew G. Knepley ls->maxFaces = maxFaces; 2202c0ce001eSMatthew G. Knepley m = ls->maxFaces; 2203c0ce001eSMatthew G. Knepley n = dim; 2204c0ce001eSMatthew G. Knepley nrhs = ls->maxFaces; 2205736d4f42SpierreXVI minmn = PetscMin(m, n); 2206736d4f42SpierreXVI maxmn = PetscMax(m, n); 2207736d4f42SpierreXVI ls->workSize = 3 * minmn + PetscMax(2 * minmn, PetscMax(maxmn, nrhs)); /* required by LAPACK */ 22089566063dSJacob Faibussowitsch PetscCall(PetscMalloc4(m * n, &ls->B, maxmn * maxmn, &ls->Binv, minmn, &ls->tau, ls->workSize, &ls->work)); 22093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2210c0ce001eSMatthew G. Knepley } 2211c0ce001eSMatthew G. Knepley 221266976f2fSJacob Faibussowitsch static PetscErrorCode PetscFVInitialize_LeastSquares(PetscFV fvm) 2213d71ae5a4SJacob Faibussowitsch { 2214c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2215c0ce001eSMatthew G. Knepley fvm->ops->setfromoptions = NULL; 2216c0ce001eSMatthew G. Knepley fvm->ops->setup = PetscFVSetUp_LeastSquares; 2217c0ce001eSMatthew G. Knepley fvm->ops->view = PetscFVView_LeastSquares; 2218c0ce001eSMatthew G. Knepley fvm->ops->destroy = PetscFVDestroy_LeastSquares; 2219c0ce001eSMatthew G. Knepley fvm->ops->computegradient = PetscFVComputeGradient_LeastSquares; 2220c0ce001eSMatthew G. Knepley fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_LeastSquares; 22213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2222c0ce001eSMatthew G. Knepley } 2223c0ce001eSMatthew G. Knepley 2224c0ce001eSMatthew G. Knepley /*MC 2225dce8aebaSBarry Smith PETSCFVLEASTSQUARES = "leastsquares" - A `PetscFV` implementation 2226c0ce001eSMatthew G. Knepley 2227c0ce001eSMatthew G. Knepley Level: intermediate 2228c0ce001eSMatthew G. Knepley 2229dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 2230c0ce001eSMatthew G. Knepley M*/ 2231c0ce001eSMatthew G. Knepley 2232d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscFVCreate_LeastSquares(PetscFV fvm) 2233d71ae5a4SJacob Faibussowitsch { 2234c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls; 2235c0ce001eSMatthew G. Knepley 2236c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2237c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 22384dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&ls)); 2239c0ce001eSMatthew G. Knepley fvm->data = ls; 2240c0ce001eSMatthew G. Knepley 2241c0ce001eSMatthew G. Knepley ls->maxFaces = -1; 2242c0ce001eSMatthew G. Knepley ls->workSize = -1; 2243c0ce001eSMatthew G. Knepley ls->B = NULL; 2244c0ce001eSMatthew G. Knepley ls->Binv = NULL; 2245c0ce001eSMatthew G. Knepley ls->tau = NULL; 2246c0ce001eSMatthew G. Knepley ls->work = NULL; 2247c0ce001eSMatthew G. Knepley 22489566063dSJacob Faibussowitsch PetscCall(PetscFVSetComputeGradients(fvm, PETSC_TRUE)); 22499566063dSJacob Faibussowitsch PetscCall(PetscFVInitialize_LeastSquares(fvm)); 22509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fvm, "PetscFVLeastSquaresSetMaxFaces_C", PetscFVLeastSquaresSetMaxFaces_LS)); 22513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2252c0ce001eSMatthew G. Knepley } 2253c0ce001eSMatthew G. Knepley 2254c0ce001eSMatthew G. Knepley /*@ 2255c0ce001eSMatthew G. Knepley PetscFVLeastSquaresSetMaxFaces - Set the maximum number of cell faces for gradient reconstruction 2256c0ce001eSMatthew G. Knepley 225720f4b53cSBarry Smith Not Collective 2258c0ce001eSMatthew G. Knepley 225960225df5SJacob Faibussowitsch Input Parameters: 2260dce8aebaSBarry Smith + fvm - The `PetscFV` object 2261c0ce001eSMatthew G. Knepley - maxFaces - The maximum number of cell faces 2262c0ce001eSMatthew G. Knepley 2263c0ce001eSMatthew G. Knepley Level: intermediate 2264c0ce001eSMatthew G. Knepley 2265dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVCreate()`, `PETSCFVLEASTSQUARES`, `PetscFVComputeGradient()` 2266c0ce001eSMatthew G. Knepley @*/ 2267d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVLeastSquaresSetMaxFaces(PetscFV fvm, PetscInt maxFaces) 2268d71ae5a4SJacob Faibussowitsch { 2269c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2270c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 2271cac4c232SBarry Smith PetscTryMethod(fvm, "PetscFVLeastSquaresSetMaxFaces_C", (PetscFV, PetscInt), (fvm, maxFaces)); 22723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2273c0ce001eSMatthew G. Knepley } 2274