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 22cc4c1da9SBarry Smith Not Collective, No Fortran Support 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 57cc4c1da9SBarry Smith /*@ 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 95cc4c1da9SBarry Smith /*@ 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 120*ffeef943SBarry Smith /*@ 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 142*ffeef943SBarry Smith /*@ 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 203cc4c1da9SBarry Smith /*@ 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); 239f4f49eeaSPierre Jolivet PetscValidHeaderSpecific(*lim, PETSCLIMITER_CLASSID, 1); 240c0ce001eSMatthew G. Knepley 241f4f49eeaSPierre Jolivet if (--((PetscObject)*lim)->refct > 0) { 2429371c9d4SSatish Balay *lim = NULL; 2433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2449371c9d4SSatish Balay } 245f4f49eeaSPierre Jolivet ((PetscObject)*lim)->refct = 0; 246c0ce001eSMatthew G. Knepley 247f4f49eeaSPierre Jolivet 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 896cc4c1da9SBarry Smith Not Collective, No Fortran Support 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 931cc4c1da9SBarry Smith /*@ 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 969cc4c1da9SBarry Smith /*@ 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 994*ffeef943SBarry Smith /*@ 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 1016*ffeef943SBarry Smith /*@ 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); 1121f4f49eeaSPierre Jolivet PetscValidHeaderSpecific(*fvm, PETSCFV_CLASSID, 1); 1122c0ce001eSMatthew G. Knepley 1123f4f49eeaSPierre Jolivet if (--((PetscObject)*fvm)->refct > 0) { 11249371c9d4SSatish Balay *fvm = NULL; 11253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11269371c9d4SSatish Balay } 1127f4f49eeaSPierre Jolivet ((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 1137f4f49eeaSPierre Jolivet 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 1304cc4c1da9SBarry Smith /*@ 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 @*/ 1320cc4c1da9SBarry Smith 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)); 1435f6feae9bSMatthew 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 /*@ 14752f86f8c5SMatthew G. Knepley PetscFVCreateDualSpace - Creates a `PetscDualSpace` appropriate for the `PetscFV` 14762f86f8c5SMatthew G. Knepley 14772f86f8c5SMatthew G. Knepley Not Collective 14782f86f8c5SMatthew G. Knepley 14799cde84edSJose E. Roman Input Parameters: 14802f86f8c5SMatthew G. Knepley + fvm - The `PetscFV` object 14812f86f8c5SMatthew G. Knepley - ct - The `DMPolytopeType` for the cell 14822f86f8c5SMatthew G. Knepley 14832f86f8c5SMatthew G. Knepley Level: intermediate 14842f86f8c5SMatthew G. Knepley 14852f86f8c5SMatthew G. Knepley .seealso: `PetscFVGetDualSpace()`, `PetscFVSetDualSpace()`, `PetscDualSpace`, `PetscFV`, `PetscFVCreate()` 14862f86f8c5SMatthew G. Knepley @*/ 14872f86f8c5SMatthew G. Knepley PetscErrorCode PetscFVCreateDualSpace(PetscFV fvm, DMPolytopeType ct) 14882f86f8c5SMatthew G. Knepley { 14892f86f8c5SMatthew G. Knepley DM K; 14902f86f8c5SMatthew G. Knepley PetscInt dim, Nc; 14912f86f8c5SMatthew G. Knepley 14922f86f8c5SMatthew G. Knepley PetscFunctionBegin; 14932f86f8c5SMatthew G. Knepley PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 14942f86f8c5SMatthew G. Knepley PetscCall(PetscFVGetNumComponents(fvm, &Nc)); 14952f86f8c5SMatthew G. Knepley PetscCall(PetscDualSpaceCreate(PetscObjectComm((PetscObject)fvm), &fvm->dualSpace)); 14962f86f8c5SMatthew G. Knepley PetscCall(PetscDualSpaceSetType(fvm->dualSpace, PETSCDUALSPACESIMPLE)); 14972f86f8c5SMatthew G. Knepley PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, ct, &K)); 14982f86f8c5SMatthew G. Knepley PetscCall(PetscDualSpaceSetNumComponents(fvm->dualSpace, Nc)); 14992f86f8c5SMatthew G. Knepley PetscCall(PetscDualSpaceSetDM(fvm->dualSpace, K)); 15002f86f8c5SMatthew G. Knepley PetscCall(DMDestroy(&K)); 15012f86f8c5SMatthew G. Knepley PetscCall(PetscDualSpaceSimpleSetDimension(fvm->dualSpace, Nc)); 15022f86f8c5SMatthew G. Knepley // Should we be using PetscFVGetQuadrature() here? 15032f86f8c5SMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) { 15042f86f8c5SMatthew G. Knepley PetscQuadrature qc; 15052f86f8c5SMatthew G. Knepley PetscReal *points, *weights; 15062f86f8c5SMatthew G. Knepley 15072f86f8c5SMatthew G. Knepley PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qc)); 15082f86f8c5SMatthew G. Knepley PetscCall(PetscCalloc1(dim, &points)); 15092f86f8c5SMatthew G. Knepley PetscCall(PetscCalloc1(Nc, &weights)); 15102f86f8c5SMatthew G. Knepley weights[c] = 1.0; 15112f86f8c5SMatthew G. Knepley PetscCall(PetscQuadratureSetData(qc, dim, Nc, 1, points, weights)); 15122f86f8c5SMatthew G. Knepley PetscCall(PetscDualSpaceSimpleSetFunctional(fvm->dualSpace, c, qc)); 15132f86f8c5SMatthew G. Knepley PetscCall(PetscQuadratureDestroy(&qc)); 15142f86f8c5SMatthew G. Knepley } 15152f86f8c5SMatthew G. Knepley PetscCall(PetscDualSpaceSetUp(fvm->dualSpace)); 15162f86f8c5SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 15172f86f8c5SMatthew G. Knepley } 15182f86f8c5SMatthew G. Knepley 15192f86f8c5SMatthew G. Knepley /*@ 1520dce8aebaSBarry Smith PetscFVGetDualSpace - Returns the `PetscDualSpace` used to define the inner product on a `PetscFV` 1521c0ce001eSMatthew G. Knepley 152220f4b53cSBarry Smith Not Collective 1523c0ce001eSMatthew G. Knepley 1524c0ce001eSMatthew G. Knepley Input Parameter: 1525dce8aebaSBarry Smith . fvm - The `PetscFV` object 1526c0ce001eSMatthew G. Knepley 1527c0ce001eSMatthew G. Knepley Output Parameter: 152820f4b53cSBarry Smith . sp - The `PetscDualSpace` object 1529c0ce001eSMatthew G. Knepley 153088f5f89eSMatthew G. Knepley Level: intermediate 1531c0ce001eSMatthew G. Knepley 153260225df5SJacob Faibussowitsch Developer Notes: 1533dce8aebaSBarry Smith There is overlap between the methods of `PetscFE` and `PetscFV`, they should probably share a common parent class 1534dce8aebaSBarry Smith 15352f86f8c5SMatthew G. Knepley .seealso: `PetscFVSetDualSpace()`, `PetscFVCreateDualSpace()`, `PetscDualSpace`, `PetscFV`, `PetscFVCreate()` 1536c0ce001eSMatthew G. Knepley @*/ 1537d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetDualSpace(PetscFV fvm, PetscDualSpace *sp) 1538d71ae5a4SJacob Faibussowitsch { 1539c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1540c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 15414f572ea9SToby Isaac PetscAssertPointer(sp, 2); 1542c0ce001eSMatthew G. Knepley if (!fvm->dualSpace) { 15432f86f8c5SMatthew G. Knepley PetscInt dim; 1544c0ce001eSMatthew G. Knepley 15459566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 15462f86f8c5SMatthew G. Knepley PetscCall(PetscFVCreateDualSpace(fvm, DMPolytopeTypeSimpleShape(dim, PETSC_FALSE))); 1547c0ce001eSMatthew G. Knepley } 1548c0ce001eSMatthew G. Knepley *sp = fvm->dualSpace; 15493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1550c0ce001eSMatthew G. Knepley } 1551c0ce001eSMatthew G. Knepley 1552c0ce001eSMatthew G. Knepley /*@ 1553dce8aebaSBarry Smith PetscFVSetDualSpace - Sets the `PetscDualSpace` used to define the inner product 1554c0ce001eSMatthew G. Knepley 155520f4b53cSBarry Smith Not Collective 1556c0ce001eSMatthew G. Knepley 1557c0ce001eSMatthew G. Knepley Input Parameters: 1558dce8aebaSBarry Smith + fvm - The `PetscFV` object 1559dce8aebaSBarry Smith - sp - The `PetscDualSpace` object 1560c0ce001eSMatthew G. Knepley 1561c0ce001eSMatthew G. Knepley Level: intermediate 1562c0ce001eSMatthew G. Knepley 1563dce8aebaSBarry Smith Note: 1564dce8aebaSBarry Smith A simple dual space is provided automatically, and the user typically will not need to override it. 1565c0ce001eSMatthew G. Knepley 15662f86f8c5SMatthew G. Knepley .seealso: `PetscFVGetDualSpace()`, `PetscFVCreateDualSpace()`, `PetscDualSpace`, `PetscFV`, `PetscFVCreate()` 1567c0ce001eSMatthew G. Knepley @*/ 1568d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVSetDualSpace(PetscFV fvm, PetscDualSpace sp) 1569d71ae5a4SJacob Faibussowitsch { 1570c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1571c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1572c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 2); 15739566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&fvm->dualSpace)); 1574c0ce001eSMatthew G. Knepley fvm->dualSpace = sp; 15759566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fvm->dualSpace)); 15763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1577c0ce001eSMatthew G. Knepley } 1578c0ce001eSMatthew G. Knepley 157988f5f89eSMatthew G. Knepley /*@C 1580ef0bb6c7SMatthew G. Knepley PetscFVGetCellTabulation - Returns the tabulation of the basis functions at the quadrature points 158188f5f89eSMatthew G. Knepley 158220f4b53cSBarry Smith Not Collective 158388f5f89eSMatthew G. Knepley 158488f5f89eSMatthew G. Knepley Input Parameter: 1585dce8aebaSBarry Smith . fvm - The `PetscFV` object 158688f5f89eSMatthew G. Knepley 1587ef0bb6c7SMatthew G. Knepley Output Parameter: 1588a5b23f4aSJose E. Roman . T - The basis function values and derivatives at quadrature points 158988f5f89eSMatthew G. Knepley 159088f5f89eSMatthew G. Knepley Level: intermediate 159188f5f89eSMatthew G. Knepley 1592dce8aebaSBarry Smith Note: 1593dce8aebaSBarry Smith .vb 1594dce8aebaSBarry Smith T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 1595dce8aebaSBarry 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 1596dce8aebaSBarry 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 1597dce8aebaSBarry Smith .ve 1598dce8aebaSBarry Smith 1599dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscTabulation`, `PetscFEGetCellTabulation()`, `PetscFVCreateTabulation()`, `PetscFVGetQuadrature()`, `PetscQuadratureGetData()` 160088f5f89eSMatthew G. Knepley @*/ 1601d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVGetCellTabulation(PetscFV fvm, PetscTabulation *T) 1602d71ae5a4SJacob Faibussowitsch { 1603c0ce001eSMatthew G. Knepley PetscInt npoints; 1604c0ce001eSMatthew G. Knepley const PetscReal *points; 1605c0ce001eSMatthew G. Knepley 1606c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1607c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 16084f572ea9SToby Isaac PetscAssertPointer(T, 2); 16099566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(fvm->quadrature, NULL, NULL, &npoints, &points, NULL)); 16109566063dSJacob Faibussowitsch if (!fvm->T) PetscCall(PetscFVCreateTabulation(fvm, 1, npoints, points, 1, &fvm->T)); 1611ef0bb6c7SMatthew G. Knepley *T = fvm->T; 16123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1613c0ce001eSMatthew G. Knepley } 1614c0ce001eSMatthew G. Knepley 161588f5f89eSMatthew G. Knepley /*@C 1616ef0bb6c7SMatthew G. Knepley PetscFVCreateTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided. 161788f5f89eSMatthew G. Knepley 161820f4b53cSBarry Smith Not Collective 161988f5f89eSMatthew G. Knepley 162088f5f89eSMatthew G. Knepley Input Parameters: 1621dce8aebaSBarry Smith + fvm - The `PetscFV` object 1622ef0bb6c7SMatthew G. Knepley . nrepl - The number of replicas 1623ef0bb6c7SMatthew G. Knepley . npoints - The number of tabulation points in a replica 1624ef0bb6c7SMatthew G. Knepley . points - The tabulation point coordinates 1625ef0bb6c7SMatthew G. Knepley - K - The order of derivative to tabulate 162688f5f89eSMatthew G. Knepley 1627ef0bb6c7SMatthew G. Knepley Output Parameter: 1628a5b23f4aSJose E. Roman . T - The basis function values and derivative at tabulation points 162988f5f89eSMatthew G. Knepley 163088f5f89eSMatthew G. Knepley Level: intermediate 163188f5f89eSMatthew G. Knepley 1632dce8aebaSBarry Smith Note: 1633dce8aebaSBarry Smith .vb 1634dce8aebaSBarry Smith T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 1635dce8aebaSBarry 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 1636dce8aebaSBarry 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 1637dce8aebaSBarry Smith .ve 1638dce8aebaSBarry Smith 1639dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscTabulation`, `PetscFECreateTabulation()`, `PetscTabulationDestroy()`, `PetscFEGetCellTabulation()` 164088f5f89eSMatthew G. Knepley @*/ 1641d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVCreateTabulation(PetscFV fvm, PetscInt nrepl, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation *T) 1642d71ae5a4SJacob Faibussowitsch { 16432f86f8c5SMatthew G. Knepley PetscInt pdim; // Dimension of approximation space P 16442f86f8c5SMatthew G. Knepley PetscInt cdim; // Spatial dimension 16452f86f8c5SMatthew G. Knepley PetscInt Nc; // Field components 1646ef0bb6c7SMatthew G. Knepley PetscInt k, p, d, c, e; 1647c0ce001eSMatthew G. Knepley 1648c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1649ef0bb6c7SMatthew G. Knepley if (!npoints || K < 0) { 1650ef0bb6c7SMatthew G. Knepley *T = NULL; 16513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1652c0ce001eSMatthew G. Knepley } 1653c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 16544f572ea9SToby Isaac PetscAssertPointer(points, 4); 16554f572ea9SToby Isaac PetscAssertPointer(T, 6); 16569566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &cdim)); 16579566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &Nc)); 16582f86f8c5SMatthew G. Knepley pdim = Nc; 16599566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, T)); 1660ef0bb6c7SMatthew G. Knepley (*T)->K = !cdim ? 0 : K; 1661ef0bb6c7SMatthew G. Knepley (*T)->Nr = nrepl; 1662ef0bb6c7SMatthew G. Knepley (*T)->Np = npoints; 1663ef0bb6c7SMatthew G. Knepley (*T)->Nb = pdim; 1664ef0bb6c7SMatthew G. Knepley (*T)->Nc = Nc; 1665ef0bb6c7SMatthew G. Knepley (*T)->cdim = cdim; 16669566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*T)->K + 1, &(*T)->T)); 166748a46eb9SPierre Jolivet for (k = 0; k <= (*T)->K; ++k) PetscCall(PetscMalloc1(nrepl * npoints * pdim * Nc * PetscPowInt(cdim, k), &(*T)->T[k])); 16689371c9d4SSatish Balay if (K >= 0) { 16699371c9d4SSatish Balay for (p = 0; p < nrepl * npoints; ++p) 16709371c9d4SSatish Balay for (d = 0; d < pdim; ++d) 16712f86f8c5SMatthew G. Knepley for (c = 0; c < Nc; ++c) (*T)->T[0][(p * pdim + d) * Nc + c] = 1.; 1672ef0bb6c7SMatthew G. Knepley } 16739371c9d4SSatish Balay if (K >= 1) { 16749371c9d4SSatish Balay for (p = 0; p < nrepl * npoints; ++p) 16759371c9d4SSatish Balay for (d = 0; d < pdim; ++d) 16769371c9d4SSatish Balay for (c = 0; c < Nc; ++c) 16779371c9d4SSatish Balay for (e = 0; e < cdim; ++e) (*T)->T[1][((p * pdim + d) * Nc + c) * cdim + e] = 0.0; 16789371c9d4SSatish Balay } 16799371c9d4SSatish Balay if (K >= 2) { 16809371c9d4SSatish Balay for (p = 0; p < nrepl * npoints; ++p) 16819371c9d4SSatish Balay for (d = 0; d < pdim; ++d) 16829371c9d4SSatish Balay for (c = 0; c < Nc; ++c) 16839371c9d4SSatish Balay for (e = 0; e < cdim * cdim; ++e) (*T)->T[2][((p * pdim + d) * Nc + c) * cdim * cdim + e] = 0.0; 16849371c9d4SSatish Balay } 16853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1686c0ce001eSMatthew G. Knepley } 1687c0ce001eSMatthew G. Knepley 1688cc4c1da9SBarry Smith /*@ 1689c0ce001eSMatthew G. Knepley PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell 1690c0ce001eSMatthew G. Knepley 1691c0ce001eSMatthew G. Knepley Input Parameters: 1692dce8aebaSBarry Smith + fvm - The `PetscFV` object 1693c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained 1694c0ce001eSMatthew G. Knepley - dx - The vector from the cell centroid to the neighboring cell centroid for each face 1695c0ce001eSMatthew G. Knepley 1696a4e35b19SJacob Faibussowitsch Output Parameter: 1697a4e35b19SJacob Faibussowitsch . grad - the gradient 1698a4e35b19SJacob Faibussowitsch 169988f5f89eSMatthew G. Knepley Level: advanced 1700c0ce001eSMatthew G. Knepley 1701dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVCreate()` 1702c0ce001eSMatthew G. Knepley @*/ 1703d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVComputeGradient(PetscFV fvm, PetscInt numFaces, PetscScalar dx[], PetscScalar grad[]) 1704d71ae5a4SJacob Faibussowitsch { 1705c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1706c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1707dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, computegradient, numFaces, dx, grad); 17083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1709c0ce001eSMatthew G. Knepley } 1710c0ce001eSMatthew G. Knepley 171188f5f89eSMatthew G. Knepley /*@C 1712c0ce001eSMatthew G. Knepley PetscFVIntegrateRHSFunction - Produce the cell residual vector for a chunk of elements by quadrature integration 1713c0ce001eSMatthew G. Knepley 171420f4b53cSBarry Smith Not Collective 1715c0ce001eSMatthew G. Knepley 1716c0ce001eSMatthew G. Knepley Input Parameters: 1717dce8aebaSBarry Smith + fvm - The `PetscFV` object for the field being integrated 1718da81f932SPierre Jolivet . prob - The `PetscDS` specifying the discretizations and continuum functions 1719c0ce001eSMatthew G. Knepley . field - The field being integrated 1720c0ce001eSMatthew G. Knepley . Nf - The number of faces in the chunk 1721c0ce001eSMatthew G. Knepley . fgeom - The face geometry for each face in the chunk 1722c0ce001eSMatthew G. Knepley . neighborVol - The volume for each pair of cells in the chunk 1723c0ce001eSMatthew G. Knepley . uL - The state from the cell on the left 1724c0ce001eSMatthew G. Knepley - uR - The state from the cell on the right 1725c0ce001eSMatthew G. Knepley 1726d8d19677SJose E. Roman Output Parameters: 1727c0ce001eSMatthew G. Knepley + fluxL - the left fluxes for each face 1728c0ce001eSMatthew G. Knepley - fluxR - the right fluxes for each face 172988f5f89eSMatthew G. Knepley 173088f5f89eSMatthew G. Knepley Level: developer 173188f5f89eSMatthew G. Knepley 1732dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscDS`, `PetscFVFaceGeom`, `PetscFVCreate()` 173388f5f89eSMatthew G. Knepley @*/ 1734d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVIntegrateRHSFunction(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) 1735d71ae5a4SJacob Faibussowitsch { 1736c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1737c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1738dbbe0bcdSBarry Smith PetscTryTypeMethod(fvm, integraterhsfunction, prob, field, Nf, fgeom, neighborVol, uL, uR, fluxL, fluxR); 17393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1740c0ce001eSMatthew G. Knepley } 1741c0ce001eSMatthew G. Knepley 1742c0ce001eSMatthew G. Knepley /*@ 1743d8b4a066SPierre Jolivet PetscFVClone - Create a shallow copy of a `PetscFV` object that just references the internal objects. 1744f6feae9bSMatthew G. Knepley 1745f6feae9bSMatthew G. Knepley Input Parameter: 1746f6feae9bSMatthew G. Knepley . fv - The initial `PetscFV` 1747f6feae9bSMatthew G. Knepley 1748f6feae9bSMatthew G. Knepley Output Parameter: 1749f6feae9bSMatthew G. Knepley . fvNew - A clone of the `PetscFV` 1750f6feae9bSMatthew G. Knepley 1751f6feae9bSMatthew G. Knepley Level: advanced 1752f6feae9bSMatthew G. Knepley 1753f6feae9bSMatthew G. Knepley Notes: 1754f6feae9bSMatthew G. Knepley This is typically used to change the number of components. 1755f6feae9bSMatthew G. Knepley 1756f6feae9bSMatthew G. Knepley .seealso: `PetscFV`, `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 1757f6feae9bSMatthew G. Knepley @*/ 1758f6feae9bSMatthew G. Knepley PetscErrorCode PetscFVClone(PetscFV fv, PetscFV *fvNew) 1759f6feae9bSMatthew G. Knepley { 1760f6feae9bSMatthew G. Knepley PetscDualSpace Q; 1761f6feae9bSMatthew G. Knepley DM K; 1762f6feae9bSMatthew G. Knepley PetscQuadrature q; 1763f6feae9bSMatthew G. Knepley PetscInt Nc, cdim; 1764f6feae9bSMatthew G. Knepley 1765f6feae9bSMatthew G. Knepley PetscFunctionBegin; 1766f6feae9bSMatthew G. Knepley PetscCall(PetscFVGetDualSpace(fv, &Q)); 1767f6feae9bSMatthew G. Knepley PetscCall(PetscFVGetQuadrature(fv, &q)); 1768f6feae9bSMatthew G. Knepley PetscCall(PetscDualSpaceGetDM(Q, &K)); 1769f6feae9bSMatthew G. Knepley 1770f6feae9bSMatthew G. Knepley PetscCall(PetscFVCreate(PetscObjectComm((PetscObject)fv), fvNew)); 1771f6feae9bSMatthew G. Knepley PetscCall(PetscFVSetDualSpace(*fvNew, Q)); 1772f6feae9bSMatthew G. Knepley PetscCall(PetscFVGetNumComponents(fv, &Nc)); 1773f6feae9bSMatthew G. Knepley PetscCall(PetscFVSetNumComponents(*fvNew, Nc)); 1774f6feae9bSMatthew G. Knepley PetscCall(PetscFVGetSpatialDimension(fv, &cdim)); 1775f6feae9bSMatthew G. Knepley PetscCall(PetscFVSetSpatialDimension(*fvNew, cdim)); 1776f6feae9bSMatthew G. Knepley PetscCall(PetscFVSetQuadrature(*fvNew, q)); 1777f6feae9bSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 1778f6feae9bSMatthew G. Knepley } 1779f6feae9bSMatthew G. Knepley 1780f6feae9bSMatthew G. Knepley /*@ 1781a4e35b19SJacob Faibussowitsch PetscFVRefine - Create a "refined" `PetscFV` object that refines the reference cell into 1782a4e35b19SJacob Faibussowitsch smaller copies. 1783c0ce001eSMatthew G. Knepley 1784c0ce001eSMatthew G. Knepley Input Parameter: 1785dce8aebaSBarry Smith . fv - The initial `PetscFV` 1786c0ce001eSMatthew G. Knepley 1787c0ce001eSMatthew G. Knepley Output Parameter: 1788dce8aebaSBarry Smith . fvRef - The refined `PetscFV` 1789c0ce001eSMatthew G. Knepley 179088f5f89eSMatthew G. Knepley Level: advanced 1791c0ce001eSMatthew G. Knepley 1792a4e35b19SJacob Faibussowitsch Notes: 1793a4e35b19SJacob Faibussowitsch This is typically used to generate a preconditioner for a high order method from a lower order method on a 1794a4e35b19SJacob Faibussowitsch refined mesh having the same number of dofs (but more sparsity). It is also used to create an 1795a4e35b19SJacob Faibussowitsch interpolation between regularly refined meshes. 1796a4e35b19SJacob Faibussowitsch 1797dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 1798c0ce001eSMatthew G. Knepley @*/ 1799d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVRefine(PetscFV fv, PetscFV *fvRef) 1800d71ae5a4SJacob Faibussowitsch { 1801c0ce001eSMatthew G. Knepley PetscDualSpace Q, Qref; 1802c0ce001eSMatthew G. Knepley DM K, Kref; 1803c0ce001eSMatthew G. Knepley PetscQuadrature q, qref; 1804412e9a14SMatthew G. Knepley DMPolytopeType ct; 1805012bc364SMatthew G. Knepley DMPlexTransform tr; 1806c0ce001eSMatthew G. Knepley PetscReal *v0; 1807c0ce001eSMatthew G. Knepley PetscReal *jac, *invjac; 1808c0ce001eSMatthew G. Knepley PetscInt numComp, numSubelements, s; 1809c0ce001eSMatthew G. Knepley 1810c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18119566063dSJacob Faibussowitsch PetscCall(PetscFVGetDualSpace(fv, &Q)); 18129566063dSJacob Faibussowitsch PetscCall(PetscFVGetQuadrature(fv, &q)); 18139566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &K)); 1814c0ce001eSMatthew G. Knepley /* Create dual space */ 18159566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDuplicate(Q, &Qref)); 18169566063dSJacob Faibussowitsch PetscCall(DMRefine(K, PetscObjectComm((PetscObject)fv), &Kref)); 18179566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(Qref, Kref)); 18189566063dSJacob Faibussowitsch PetscCall(DMDestroy(&Kref)); 18199566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(Qref)); 1820c0ce001eSMatthew G. Knepley /* Create volume */ 18219566063dSJacob Faibussowitsch PetscCall(PetscFVCreate(PetscObjectComm((PetscObject)fv), fvRef)); 18229566063dSJacob Faibussowitsch PetscCall(PetscFVSetDualSpace(*fvRef, Qref)); 18239566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &numComp)); 18249566063dSJacob Faibussowitsch PetscCall(PetscFVSetNumComponents(*fvRef, numComp)); 18259566063dSJacob Faibussowitsch PetscCall(PetscFVSetUp(*fvRef)); 1826c0ce001eSMatthew G. Knepley /* Create quadrature */ 18279566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(K, 0, &ct)); 18289566063dSJacob Faibussowitsch PetscCall(DMPlexTransformCreate(PETSC_COMM_SELF, &tr)); 18299566063dSJacob Faibussowitsch PetscCall(DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR)); 18309566063dSJacob Faibussowitsch PetscCall(DMPlexRefineRegularGetAffineTransforms(tr, ct, &numSubelements, &v0, &jac, &invjac)); 18319566063dSJacob Faibussowitsch PetscCall(PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref)); 18329566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetDimension(Qref, numSubelements)); 1833c0ce001eSMatthew G. Knepley for (s = 0; s < numSubelements; ++s) { 1834c0ce001eSMatthew G. Knepley PetscQuadrature qs; 1835c0ce001eSMatthew G. Knepley const PetscReal *points, *weights; 1836c0ce001eSMatthew G. Knepley PetscReal *p, *w; 1837c0ce001eSMatthew G. Knepley PetscInt dim, Nc, npoints, np; 1838c0ce001eSMatthew G. Knepley 18399566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qs)); 18409566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(q, &dim, &Nc, &npoints, &points, &weights)); 1841c0ce001eSMatthew G. Knepley np = npoints / numSubelements; 18429566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(np * dim, &p)); 18439566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(np * Nc, &w)); 18449566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(p, &points[s * np * dim], np * dim)); 18459566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(w, &weights[s * np * Nc], np * Nc)); 18469566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(qs, dim, Nc, np, p, w)); 18479566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetFunctional(Qref, s, qs)); 18489566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qs)); 1849c0ce001eSMatthew G. Knepley } 18509566063dSJacob Faibussowitsch PetscCall(PetscFVSetQuadrature(*fvRef, qref)); 18519566063dSJacob Faibussowitsch PetscCall(DMPlexTransformDestroy(&tr)); 18529566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qref)); 18539566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&Qref)); 18543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1855c0ce001eSMatthew G. Knepley } 1856c0ce001eSMatthew G. Knepley 1857d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVDestroy_Upwind(PetscFV fvm) 1858d71ae5a4SJacob Faibussowitsch { 1859c0ce001eSMatthew G. Knepley PetscFV_Upwind *b = (PetscFV_Upwind *)fvm->data; 1860c0ce001eSMatthew G. Knepley 1861c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18629566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 18633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1864c0ce001eSMatthew G. Knepley } 1865c0ce001eSMatthew G. Knepley 1866d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_Upwind_Ascii(PetscFV fv, PetscViewer viewer) 1867d71ae5a4SJacob Faibussowitsch { 1868c0ce001eSMatthew G. Knepley PetscInt Nc, c; 1869c0ce001eSMatthew G. Knepley PetscViewerFormat format; 1870c0ce001eSMatthew G. Knepley 1871c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18729566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &Nc)); 18739566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 18749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Upwind Finite Volume:\n")); 187563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " num components: %" PetscInt_FMT "\n", Nc)); 1876c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; c++) { 187748a46eb9SPierre Jolivet if (fv->componentNames[c]) PetscCall(PetscViewerASCIIPrintf(viewer, " component %" PetscInt_FMT ": %s\n", c, fv->componentNames[c])); 1878c0ce001eSMatthew G. Knepley } 18793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1880c0ce001eSMatthew G. Knepley } 1881c0ce001eSMatthew G. Knepley 1882d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_Upwind(PetscFV fv, PetscViewer viewer) 1883d71ae5a4SJacob Faibussowitsch { 1884c0ce001eSMatthew G. Knepley PetscBool iascii; 1885c0ce001eSMatthew G. Knepley 1886c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1887c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1); 1888c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 18899566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 18909566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscFVView_Upwind_Ascii(fv, viewer)); 18913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1892c0ce001eSMatthew G. Knepley } 1893c0ce001eSMatthew G. Knepley 1894d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVSetUp_Upwind(PetscFV fvm) 1895d71ae5a4SJacob Faibussowitsch { 1896c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1898c0ce001eSMatthew G. Knepley } 1899c0ce001eSMatthew G. Knepley 19006f6f020cSMatthew G. Knepley static PetscErrorCode PetscFVComputeGradient_Upwind(PetscFV fv, PetscInt numFaces, const PetscScalar dx[], PetscScalar grad[]) 19016f6f020cSMatthew G. Knepley { 19026f6f020cSMatthew G. Knepley PetscInt dim; 19036f6f020cSMatthew G. Knepley 19046f6f020cSMatthew G. Knepley PetscFunctionBegin; 19056f6f020cSMatthew G. Knepley PetscCall(PetscFVGetSpatialDimension(fv, &dim)); 19066f6f020cSMatthew G. Knepley for (PetscInt f = 0; f < numFaces; ++f) { 19076f6f020cSMatthew G. Knepley for (PetscInt d = 0; d < dim; ++d) grad[f * dim + d] = 0.; 19086f6f020cSMatthew G. Knepley } 19096f6f020cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 19106f6f020cSMatthew G. Knepley } 19116f6f020cSMatthew G. Knepley 1912c0ce001eSMatthew G. Knepley /* 1913c0ce001eSMatthew G. Knepley neighborVol[f*2+0] contains the left geom 1914c0ce001eSMatthew G. Knepley neighborVol[f*2+1] contains the right geom 1915c0ce001eSMatthew G. Knepley */ 1916d71ae5a4SJacob 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[]) 1917d71ae5a4SJacob Faibussowitsch { 1918c0ce001eSMatthew G. Knepley void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *); 1919c0ce001eSMatthew G. Knepley void *rctx; 1920c0ce001eSMatthew G. Knepley PetscScalar *flux = fvm->fluxWork; 1921c0ce001eSMatthew G. Knepley const PetscScalar *constants; 1922c0ce001eSMatthew G. Knepley PetscInt dim, numConstants, pdim, totDim, Nc, off, f, d; 1923c0ce001eSMatthew G. Knepley 1924c0ce001eSMatthew G. Knepley PetscFunctionBegin; 19259566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalComponents(prob, &Nc)); 19269566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalDimension(prob, &totDim)); 19279566063dSJacob Faibussowitsch PetscCall(PetscDSGetFieldOffset(prob, field, &off)); 19289566063dSJacob Faibussowitsch PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann)); 19299566063dSJacob Faibussowitsch PetscCall(PetscDSGetContext(prob, field, &rctx)); 19309566063dSJacob Faibussowitsch PetscCall(PetscDSGetConstants(prob, &numConstants, &constants)); 19319566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 19329566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &pdim)); 1933c0ce001eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 1934c0ce001eSMatthew G. Knepley (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f * Nc], &uR[f * Nc], numConstants, constants, flux, rctx); 1935c0ce001eSMatthew G. Knepley for (d = 0; d < pdim; ++d) { 1936c0ce001eSMatthew G. Knepley fluxL[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 0]; 1937c0ce001eSMatthew G. Knepley fluxR[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 1]; 1938c0ce001eSMatthew G. Knepley } 1939c0ce001eSMatthew G. Knepley } 19403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1941c0ce001eSMatthew G. Knepley } 1942c0ce001eSMatthew G. Knepley 1943d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVInitialize_Upwind(PetscFV fvm) 1944d71ae5a4SJacob Faibussowitsch { 1945c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1946c0ce001eSMatthew G. Knepley fvm->ops->setfromoptions = NULL; 1947c0ce001eSMatthew G. Knepley fvm->ops->setup = PetscFVSetUp_Upwind; 1948c0ce001eSMatthew G. Knepley fvm->ops->view = PetscFVView_Upwind; 1949c0ce001eSMatthew G. Knepley fvm->ops->destroy = PetscFVDestroy_Upwind; 19506f6f020cSMatthew G. Knepley fvm->ops->computegradient = PetscFVComputeGradient_Upwind; 1951c0ce001eSMatthew G. Knepley fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_Upwind; 19523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1953c0ce001eSMatthew G. Knepley } 1954c0ce001eSMatthew G. Knepley 1955c0ce001eSMatthew G. Knepley /*MC 1956dce8aebaSBarry Smith PETSCFVUPWIND = "upwind" - A `PetscFV` implementation 1957c0ce001eSMatthew G. Knepley 1958c0ce001eSMatthew G. Knepley Level: intermediate 1959c0ce001eSMatthew G. Knepley 1960dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 1961c0ce001eSMatthew G. Knepley M*/ 1962c0ce001eSMatthew G. Knepley 1963d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscFVCreate_Upwind(PetscFV fvm) 1964d71ae5a4SJacob Faibussowitsch { 1965c0ce001eSMatthew G. Knepley PetscFV_Upwind *b; 1966c0ce001eSMatthew G. Knepley 1967c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1968c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 19694dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 1970c0ce001eSMatthew G. Knepley fvm->data = b; 1971c0ce001eSMatthew G. Knepley 19729566063dSJacob Faibussowitsch PetscCall(PetscFVInitialize_Upwind(fvm)); 19733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1974c0ce001eSMatthew G. Knepley } 1975c0ce001eSMatthew G. Knepley 1976c0ce001eSMatthew G. Knepley #include <petscblaslapack.h> 1977c0ce001eSMatthew G. Knepley 1978d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVDestroy_LeastSquares(PetscFV fvm) 1979d71ae5a4SJacob Faibussowitsch { 1980c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data; 1981c0ce001eSMatthew G. Knepley 1982c0ce001eSMatthew G. Knepley PetscFunctionBegin; 19839566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fvm, "PetscFVLeastSquaresSetMaxFaces_C", NULL)); 19849566063dSJacob Faibussowitsch PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work)); 19859566063dSJacob Faibussowitsch PetscCall(PetscFree(ls)); 19863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1987c0ce001eSMatthew G. Knepley } 1988c0ce001eSMatthew G. Knepley 1989d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_LeastSquares_Ascii(PetscFV fv, PetscViewer viewer) 1990d71ae5a4SJacob Faibussowitsch { 1991c0ce001eSMatthew G. Knepley PetscInt Nc, c; 1992c0ce001eSMatthew G. Knepley PetscViewerFormat format; 1993c0ce001eSMatthew G. Knepley 1994c0ce001eSMatthew G. Knepley PetscFunctionBegin; 19959566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &Nc)); 19969566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 19979566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Finite Volume with Least Squares Reconstruction:\n")); 199863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " num components: %" PetscInt_FMT "\n", Nc)); 1999c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; c++) { 200048a46eb9SPierre Jolivet if (fv->componentNames[c]) PetscCall(PetscViewerASCIIPrintf(viewer, " component %" PetscInt_FMT ": %s\n", c, fv->componentNames[c])); 2001c0ce001eSMatthew G. Knepley } 20023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2003c0ce001eSMatthew G. Knepley } 2004c0ce001eSMatthew G. Knepley 2005d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVView_LeastSquares(PetscFV fv, PetscViewer viewer) 2006d71ae5a4SJacob Faibussowitsch { 2007c0ce001eSMatthew G. Knepley PetscBool iascii; 2008c0ce001eSMatthew G. Knepley 2009c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2010c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1); 2011c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 20129566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 20139566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscFVView_LeastSquares_Ascii(fv, viewer)); 20143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2015c0ce001eSMatthew G. Knepley } 2016c0ce001eSMatthew G. Knepley 2017d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVSetUp_LeastSquares(PetscFV fvm) 2018d71ae5a4SJacob Faibussowitsch { 2019c0ce001eSMatthew G. Knepley PetscFunctionBegin; 20203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2021c0ce001eSMatthew G. Knepley } 2022c0ce001eSMatthew G. Knepley 2023c0ce001eSMatthew G. Knepley /* Overwrites A. Can only handle full-rank problems with m>=n */ 2024d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresPseudoInverse_Static(PetscInt m, PetscInt mstride, PetscInt n, PetscScalar *A, PetscScalar *Ainv, PetscScalar *tau, PetscInt worksize, PetscScalar *work) 2025d71ae5a4SJacob Faibussowitsch { 2026c0ce001eSMatthew G. Knepley PetscBool debug = PETSC_FALSE; 2027c0ce001eSMatthew G. Knepley PetscBLASInt M, N, K, lda, ldb, ldwork, info; 2028c0ce001eSMatthew G. Knepley PetscScalar *R, *Q, *Aback, Alpha; 2029c0ce001eSMatthew G. Knepley 2030c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2031c0ce001eSMatthew G. Knepley if (debug) { 20329566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * n, &Aback)); 20339566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(Aback, A, m * n)); 2034c0ce001eSMatthew G. Knepley } 2035c0ce001eSMatthew G. Knepley 20369566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &M)); 20379566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &N)); 20389566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(mstride, &lda)); 20399566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(worksize, &ldwork)); 20409566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 2041792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&M, &N, A, &lda, tau, work, &ldwork, &info)); 20429566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 204328b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xGEQRF error"); 2044c0ce001eSMatthew G. Knepley R = A; /* Upper triangular part of A now contains R, the rest contains the elementary reflectors */ 2045c0ce001eSMatthew G. Knepley 2046c0ce001eSMatthew G. Knepley /* Extract an explicit representation of Q */ 2047c0ce001eSMatthew G. Knepley Q = Ainv; 20489566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(Q, A, mstride * n)); 2049c0ce001eSMatthew G. Knepley K = N; /* full rank */ 2050792fecdfSBarry Smith PetscCallBLAS("LAPACKorgqr", LAPACKorgqr_(&M, &N, &K, Q, &lda, tau, work, &ldwork, &info)); 205128b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xORGQR/xUNGQR error"); 2052c0ce001eSMatthew G. Knepley 2053c0ce001eSMatthew G. Knepley /* Compute A^{-T} = (R^{-1} Q^T)^T = Q R^{-T} */ 2054c0ce001eSMatthew G. Knepley Alpha = 1.0; 2055c0ce001eSMatthew G. Knepley ldb = lda; 2056c0ce001eSMatthew G. Knepley BLAStrsm_("Right", "Upper", "ConjugateTranspose", "NotUnitTriangular", &M, &N, &Alpha, R, &lda, Q, &ldb); 2057c0ce001eSMatthew G. Knepley /* Ainv is Q, overwritten with inverse */ 2058c0ce001eSMatthew G. Knepley 2059c0ce001eSMatthew G. Knepley if (debug) { /* Check that pseudo-inverse worked */ 2060c0ce001eSMatthew G. Knepley PetscScalar Beta = 0.0; 2061c0ce001eSMatthew G. Knepley PetscBLASInt ldc; 2062c0ce001eSMatthew G. Knepley K = N; 2063c0ce001eSMatthew G. Knepley ldc = N; 2064c0ce001eSMatthew G. Knepley BLASgemm_("ConjugateTranspose", "Normal", &N, &K, &M, &Alpha, Ainv, &lda, Aback, &ldb, &Beta, work, &ldc); 20659566063dSJacob Faibussowitsch PetscCall(PetscScalarView(n * n, work, PETSC_VIEWER_STDOUT_SELF)); 20669566063dSJacob Faibussowitsch PetscCall(PetscFree(Aback)); 2067c0ce001eSMatthew G. Knepley } 20683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2069c0ce001eSMatthew G. Knepley } 2070c0ce001eSMatthew G. Knepley 2071c0ce001eSMatthew G. Knepley /* Overwrites A. Can handle degenerate problems and m<n. */ 2072d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresPseudoInverseSVD_Static(PetscInt m, PetscInt mstride, PetscInt n, PetscScalar *A, PetscScalar *Ainv, PetscScalar *tau, PetscInt worksize, PetscScalar *work) 2073d71ae5a4SJacob Faibussowitsch { 20746bb27163SBarry Smith PetscScalar *Brhs; 2075c0ce001eSMatthew G. Knepley PetscScalar *tmpwork; 2076c0ce001eSMatthew G. Knepley PetscReal rcond; 2077c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX) 2078c0ce001eSMatthew G. Knepley PetscInt rworkSize; 2079c0ce001eSMatthew G. Knepley PetscReal *rwork; 2080c0ce001eSMatthew G. Knepley #endif 2081c0ce001eSMatthew G. Knepley PetscInt i, j, maxmn; 2082c0ce001eSMatthew G. Knepley PetscBLASInt M, N, lda, ldb, ldwork; 2083c0ce001eSMatthew G. Knepley PetscBLASInt nrhs, irank, info; 2084c0ce001eSMatthew G. Knepley 2085c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2086c0ce001eSMatthew G. Knepley /* initialize to identity */ 2087736d4f42SpierreXVI tmpwork = work; 2088736d4f42SpierreXVI Brhs = Ainv; 2089c0ce001eSMatthew G. Knepley maxmn = PetscMax(m, n); 2090c0ce001eSMatthew G. Knepley for (j = 0; j < maxmn; j++) { 2091c0ce001eSMatthew G. Knepley for (i = 0; i < maxmn; i++) Brhs[i + j * maxmn] = 1.0 * (i == j); 2092c0ce001eSMatthew G. Knepley } 2093c0ce001eSMatthew G. Knepley 20949566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &M)); 20959566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &N)); 20969566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(mstride, &lda)); 20979566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(maxmn, &ldb)); 20989566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(worksize, &ldwork)); 2099c0ce001eSMatthew G. Knepley rcond = -1; 2100c0ce001eSMatthew G. Knepley nrhs = M; 2101c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX) 2102c0ce001eSMatthew G. Knepley rworkSize = 5 * PetscMin(M, N); 21039566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(rworkSize, &rwork)); 21046bb27163SBarry Smith PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 2105792fecdfSBarry Smith PetscCallBLAS("LAPACKgelss", LAPACKgelss_(&M, &N, &nrhs, A, &lda, Brhs, &ldb, (PetscReal *)tau, &rcond, &irank, tmpwork, &ldwork, rwork, &info)); 21069566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 21079566063dSJacob Faibussowitsch PetscCall(PetscFree(rwork)); 2108c0ce001eSMatthew G. Knepley #else 2109c0ce001eSMatthew G. Knepley nrhs = M; 21106bb27163SBarry Smith PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 2111792fecdfSBarry Smith PetscCallBLAS("LAPACKgelss", LAPACKgelss_(&M, &N, &nrhs, A, &lda, Brhs, &ldb, (PetscReal *)tau, &rcond, &irank, tmpwork, &ldwork, &info)); 21129566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 2113c0ce001eSMatthew G. Knepley #endif 211428b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "xGELSS error"); 2115c0ce001eSMatthew G. Knepley /* The following check should be turned into a diagnostic as soon as someone wants to do this intentionally */ 211608401ef6SPierre 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"); 21173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2118c0ce001eSMatthew G. Knepley } 2119c0ce001eSMatthew G. Knepley 2120c0ce001eSMatthew G. Knepley #if 0 2121c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresDebugCell_Static(PetscFV fvm, PetscInt cell, DM dm, DM dmFace, PetscScalar *fgeom, DM dmCell, PetscScalar *cgeom) 2122c0ce001eSMatthew G. Knepley { 2123c0ce001eSMatthew G. Knepley PetscReal grad[2] = {0, 0}; 2124c0ce001eSMatthew G. Knepley const PetscInt *faces; 2125c0ce001eSMatthew G. Knepley PetscInt numFaces, f; 2126c0ce001eSMatthew G. Knepley 2127c0ce001eSMatthew G. Knepley PetscFunctionBegin; 21289566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, cell, &numFaces)); 21299566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, cell, &faces)); 2130c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2131c0ce001eSMatthew G. Knepley const PetscInt *fcells; 2132c0ce001eSMatthew G. Knepley const CellGeom *cg1; 2133c0ce001eSMatthew G. Knepley const FaceGeom *fg; 2134c0ce001eSMatthew G. Knepley 21359566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupport(dm, faces[f], &fcells)); 21369566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmFace, faces[f], fgeom, &fg)); 2137c0ce001eSMatthew G. Knepley for (i = 0; i < 2; ++i) { 2138c0ce001eSMatthew G. Knepley PetscScalar du; 2139c0ce001eSMatthew G. Knepley 2140c0ce001eSMatthew G. Knepley if (fcells[i] == c) continue; 21419566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmCell, fcells[i], cgeom, &cg1)); 2142c0ce001eSMatthew G. Knepley du = cg1->centroid[0] + 3*cg1->centroid[1] - (cg->centroid[0] + 3*cg->centroid[1]); 2143c0ce001eSMatthew G. Knepley grad[0] += fg->grad[!i][0] * du; 2144c0ce001eSMatthew G. Knepley grad[1] += fg->grad[!i][1] * du; 2145c0ce001eSMatthew G. Knepley } 2146c0ce001eSMatthew G. Knepley } 21479566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "cell[%d] grad (%g, %g)\n", cell, grad[0], grad[1])); 21483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2149c0ce001eSMatthew G. Knepley } 2150c0ce001eSMatthew G. Knepley #endif 2151c0ce001eSMatthew G. Knepley 2152c0ce001eSMatthew G. Knepley /* 21536f6f020cSMatthew G. Knepley PetscFVComputeGradient_LeastSquares - Compute the gradient reconstruction matrix for a given cell 2154c0ce001eSMatthew G. Knepley 2155c0ce001eSMatthew G. Knepley Input Parameters: 2156dce8aebaSBarry Smith + fvm - The `PetscFV` object 2157c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained 2158c0ce001eSMatthew G. Knepley . dx - The vector from the cell centroid to the neighboring cell centroid for each face 2159c0ce001eSMatthew G. Knepley 2160c0ce001eSMatthew G. Knepley Level: developer 2161c0ce001eSMatthew G. Knepley 2162dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVCreate()` 2163c0ce001eSMatthew G. Knepley */ 2164d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVComputeGradient_LeastSquares(PetscFV fvm, PetscInt numFaces, const PetscScalar dx[], PetscScalar grad[]) 2165d71ae5a4SJacob Faibussowitsch { 2166c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data; 2167c0ce001eSMatthew G. Knepley const PetscBool useSVD = PETSC_TRUE; 2168c0ce001eSMatthew G. Knepley const PetscInt maxFaces = ls->maxFaces; 2169c0ce001eSMatthew G. Knepley PetscInt dim, f, d; 2170c0ce001eSMatthew G. Knepley 2171c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2172c0ce001eSMatthew G. Knepley if (numFaces > maxFaces) { 217308401ef6SPierre Jolivet PetscCheck(maxFaces >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Reconstruction has not been initialized, call PetscFVLeastSquaresSetMaxFaces()"); 217463a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of input faces %" PetscInt_FMT " > %" PetscInt_FMT " maxfaces", numFaces, maxFaces); 2175c0ce001eSMatthew G. Knepley } 21769566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 2177c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2178c0ce001eSMatthew G. Knepley for (d = 0; d < dim; ++d) ls->B[d * maxFaces + f] = dx[f * dim + d]; 2179c0ce001eSMatthew G. Knepley } 2180c0ce001eSMatthew G. Knepley /* Overwrites B with garbage, returns Binv in row-major format */ 2181736d4f42SpierreXVI if (useSVD) { 2182736d4f42SpierreXVI PetscInt maxmn = PetscMax(numFaces, dim); 21839566063dSJacob Faibussowitsch PetscCall(PetscFVLeastSquaresPseudoInverseSVD_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work)); 2184736d4f42SpierreXVI /* Binv shaped in column-major, coldim=maxmn.*/ 2185736d4f42SpierreXVI for (f = 0; f < numFaces; ++f) { 2186736d4f42SpierreXVI for (d = 0; d < dim; ++d) grad[f * dim + d] = ls->Binv[d + maxmn * f]; 2187736d4f42SpierreXVI } 2188736d4f42SpierreXVI } else { 21899566063dSJacob Faibussowitsch PetscCall(PetscFVLeastSquaresPseudoInverse_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work)); 2190736d4f42SpierreXVI /* Binv shaped in row-major, rowdim=maxFaces.*/ 2191c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2192c0ce001eSMatthew G. Knepley for (d = 0; d < dim; ++d) grad[f * dim + d] = ls->Binv[d * maxFaces + f]; 2193c0ce001eSMatthew G. Knepley } 2194736d4f42SpierreXVI } 21953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2196c0ce001eSMatthew G. Knepley } 2197c0ce001eSMatthew G. Knepley 2198c0ce001eSMatthew G. Knepley /* 2199c0ce001eSMatthew G. Knepley neighborVol[f*2+0] contains the left geom 2200c0ce001eSMatthew G. Knepley neighborVol[f*2+1] contains the right geom 2201c0ce001eSMatthew G. Knepley */ 2202d71ae5a4SJacob 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[]) 2203d71ae5a4SJacob Faibussowitsch { 2204c0ce001eSMatthew G. Knepley void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *); 2205c0ce001eSMatthew G. Knepley void *rctx; 2206c0ce001eSMatthew G. Knepley PetscScalar *flux = fvm->fluxWork; 2207c0ce001eSMatthew G. Knepley const PetscScalar *constants; 2208c0ce001eSMatthew G. Knepley PetscInt dim, numConstants, pdim, Nc, totDim, off, f, d; 2209c0ce001eSMatthew G. Knepley 2210c0ce001eSMatthew G. Knepley PetscFunctionBegin; 22119566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalComponents(prob, &Nc)); 22129566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalDimension(prob, &totDim)); 22139566063dSJacob Faibussowitsch PetscCall(PetscDSGetFieldOffset(prob, field, &off)); 22149566063dSJacob Faibussowitsch PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann)); 22159566063dSJacob Faibussowitsch PetscCall(PetscDSGetContext(prob, field, &rctx)); 22169566063dSJacob Faibussowitsch PetscCall(PetscDSGetConstants(prob, &numConstants, &constants)); 22179566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 22189566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &pdim)); 2219c0ce001eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2220c0ce001eSMatthew G. Knepley (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f * Nc], &uR[f * Nc], numConstants, constants, flux, rctx); 2221c0ce001eSMatthew G. Knepley for (d = 0; d < pdim; ++d) { 2222c0ce001eSMatthew G. Knepley fluxL[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 0]; 2223c0ce001eSMatthew G. Knepley fluxR[f * totDim + off + d] = flux[d] / neighborVol[f * 2 + 1]; 2224c0ce001eSMatthew G. Knepley } 2225c0ce001eSMatthew G. Knepley } 22263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2227c0ce001eSMatthew G. Knepley } 2228c0ce001eSMatthew G. Knepley 2229d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFVLeastSquaresSetMaxFaces_LS(PetscFV fvm, PetscInt maxFaces) 2230d71ae5a4SJacob Faibussowitsch { 2231c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *)fvm->data; 2232736d4f42SpierreXVI PetscInt dim, m, n, nrhs, minmn, maxmn; 2233c0ce001eSMatthew G. Knepley 2234c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2235c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 22369566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 22379566063dSJacob Faibussowitsch PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work)); 2238c0ce001eSMatthew G. Knepley ls->maxFaces = maxFaces; 2239c0ce001eSMatthew G. Knepley m = ls->maxFaces; 2240c0ce001eSMatthew G. Knepley n = dim; 2241c0ce001eSMatthew G. Knepley nrhs = ls->maxFaces; 2242736d4f42SpierreXVI minmn = PetscMin(m, n); 2243736d4f42SpierreXVI maxmn = PetscMax(m, n); 2244736d4f42SpierreXVI ls->workSize = 3 * minmn + PetscMax(2 * minmn, PetscMax(maxmn, nrhs)); /* required by LAPACK */ 22459566063dSJacob Faibussowitsch PetscCall(PetscMalloc4(m * n, &ls->B, maxmn * maxmn, &ls->Binv, minmn, &ls->tau, ls->workSize, &ls->work)); 22463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2247c0ce001eSMatthew G. Knepley } 2248c0ce001eSMatthew G. Knepley 224966976f2fSJacob Faibussowitsch static PetscErrorCode PetscFVInitialize_LeastSquares(PetscFV fvm) 2250d71ae5a4SJacob Faibussowitsch { 2251c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2252c0ce001eSMatthew G. Knepley fvm->ops->setfromoptions = NULL; 2253c0ce001eSMatthew G. Knepley fvm->ops->setup = PetscFVSetUp_LeastSquares; 2254c0ce001eSMatthew G. Knepley fvm->ops->view = PetscFVView_LeastSquares; 2255c0ce001eSMatthew G. Knepley fvm->ops->destroy = PetscFVDestroy_LeastSquares; 2256c0ce001eSMatthew G. Knepley fvm->ops->computegradient = PetscFVComputeGradient_LeastSquares; 2257c0ce001eSMatthew G. Knepley fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_LeastSquares; 22583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2259c0ce001eSMatthew G. Knepley } 2260c0ce001eSMatthew G. Knepley 2261c0ce001eSMatthew G. Knepley /*MC 2262dce8aebaSBarry Smith PETSCFVLEASTSQUARES = "leastsquares" - A `PetscFV` implementation 2263c0ce001eSMatthew G. Knepley 2264c0ce001eSMatthew G. Knepley Level: intermediate 2265c0ce001eSMatthew G. Knepley 2266dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVType`, `PetscFVCreate()`, `PetscFVSetType()` 2267c0ce001eSMatthew G. Knepley M*/ 2268c0ce001eSMatthew G. Knepley 2269d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscFVCreate_LeastSquares(PetscFV fvm) 2270d71ae5a4SJacob Faibussowitsch { 2271c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls; 2272c0ce001eSMatthew G. Knepley 2273c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2274c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 22754dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&ls)); 2276c0ce001eSMatthew G. Knepley fvm->data = ls; 2277c0ce001eSMatthew G. Knepley 2278c0ce001eSMatthew G. Knepley ls->maxFaces = -1; 2279c0ce001eSMatthew G. Knepley ls->workSize = -1; 2280c0ce001eSMatthew G. Knepley ls->B = NULL; 2281c0ce001eSMatthew G. Knepley ls->Binv = NULL; 2282c0ce001eSMatthew G. Knepley ls->tau = NULL; 2283c0ce001eSMatthew G. Knepley ls->work = NULL; 2284c0ce001eSMatthew G. Knepley 22859566063dSJacob Faibussowitsch PetscCall(PetscFVSetComputeGradients(fvm, PETSC_TRUE)); 22869566063dSJacob Faibussowitsch PetscCall(PetscFVInitialize_LeastSquares(fvm)); 22879566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fvm, "PetscFVLeastSquaresSetMaxFaces_C", PetscFVLeastSquaresSetMaxFaces_LS)); 22883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2289c0ce001eSMatthew G. Knepley } 2290c0ce001eSMatthew G. Knepley 2291c0ce001eSMatthew G. Knepley /*@ 2292c0ce001eSMatthew G. Knepley PetscFVLeastSquaresSetMaxFaces - Set the maximum number of cell faces for gradient reconstruction 2293c0ce001eSMatthew G. Knepley 229420f4b53cSBarry Smith Not Collective 2295c0ce001eSMatthew G. Knepley 229660225df5SJacob Faibussowitsch Input Parameters: 2297dce8aebaSBarry Smith + fvm - The `PetscFV` object 2298c0ce001eSMatthew G. Knepley - maxFaces - The maximum number of cell faces 2299c0ce001eSMatthew G. Knepley 2300c0ce001eSMatthew G. Knepley Level: intermediate 2301c0ce001eSMatthew G. Knepley 2302dce8aebaSBarry Smith .seealso: `PetscFV`, `PetscFVCreate()`, `PETSCFVLEASTSQUARES`, `PetscFVComputeGradient()` 2303c0ce001eSMatthew G. Knepley @*/ 2304d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFVLeastSquaresSetMaxFaces(PetscFV fvm, PetscInt maxFaces) 2305d71ae5a4SJacob Faibussowitsch { 2306c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2307c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 2308cac4c232SBarry Smith PetscTryMethod(fvm, "PetscFVLeastSquaresSetMaxFaces_C", (PetscFV, PetscInt), (fvm, maxFaces)); 23093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2310c0ce001eSMatthew G. Knepley } 2311