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 20c0ce001eSMatthew G. Knepley PetscLimiterRegister - Adds a new PetscLimiter implementation 21c0ce001eSMatthew G. Knepley 22c0ce001eSMatthew G. Knepley Not Collective 23c0ce001eSMatthew G. Knepley 24c0ce001eSMatthew G. Knepley Input Parameters: 25c0ce001eSMatthew G. Knepley + name - The name of a new user-defined creation routine 26c0ce001eSMatthew G. Knepley - create_func - The creation routine itself 27c0ce001eSMatthew G. Knepley 28c0ce001eSMatthew G. Knepley Notes: 29c0ce001eSMatthew G. Knepley PetscLimiterRegister() may be called multiple times to add several user-defined PetscLimiters 30c0ce001eSMatthew G. Knepley 31c0ce001eSMatthew G. Knepley Sample usage: 32c0ce001eSMatthew G. Knepley .vb 33c0ce001eSMatthew G. Knepley PetscLimiterRegister("my_lim", MyPetscLimiterCreate); 34c0ce001eSMatthew G. Knepley .ve 35c0ce001eSMatthew G. Knepley 36c0ce001eSMatthew G. Knepley Then, your PetscLimiter type can be chosen with the procedural interface via 37c0ce001eSMatthew G. Knepley .vb 38c0ce001eSMatthew G. Knepley PetscLimiterCreate(MPI_Comm, PetscLimiter *); 39c0ce001eSMatthew G. Knepley PetscLimiterSetType(PetscLimiter, "my_lim"); 40c0ce001eSMatthew G. Knepley .ve 41c0ce001eSMatthew G. Knepley or at runtime via the option 42c0ce001eSMatthew G. Knepley .vb 43c0ce001eSMatthew G. Knepley -petsclimiter_type my_lim 44c0ce001eSMatthew G. Knepley .ve 45c0ce001eSMatthew G. Knepley 46c0ce001eSMatthew G. Knepley Level: advanced 47c0ce001eSMatthew G. Knepley 48c0ce001eSMatthew G. Knepley .seealso: PetscLimiterRegisterAll(), PetscLimiterRegisterDestroy() 49c0ce001eSMatthew G. Knepley 50c0ce001eSMatthew G. Knepley @*/ 51c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterRegister(const char sname[], PetscErrorCode (*function)(PetscLimiter)) 52c0ce001eSMatthew G. Knepley { 53c0ce001eSMatthew G. Knepley PetscFunctionBegin; 549566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&PetscLimiterList, sname, function)); 55c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 56c0ce001eSMatthew G. Knepley } 57c0ce001eSMatthew G. Knepley 58c0ce001eSMatthew G. Knepley /*@C 59c0ce001eSMatthew G. Knepley PetscLimiterSetType - Builds a particular PetscLimiter 60c0ce001eSMatthew G. Knepley 61c0ce001eSMatthew G. Knepley Collective on lim 62c0ce001eSMatthew G. Knepley 63c0ce001eSMatthew G. Knepley Input Parameters: 64c0ce001eSMatthew G. Knepley + lim - The PetscLimiter object 65c0ce001eSMatthew G. Knepley - name - The kind of limiter 66c0ce001eSMatthew G. Knepley 67c0ce001eSMatthew G. Knepley Options Database Key: 68c0ce001eSMatthew G. Knepley . -petsclimiter_type <type> - Sets the PetscLimiter type; use -help for a list of available types 69c0ce001eSMatthew G. Knepley 70c0ce001eSMatthew G. Knepley Level: intermediate 71c0ce001eSMatthew G. Knepley 72c0ce001eSMatthew G. Knepley .seealso: PetscLimiterGetType(), PetscLimiterCreate() 73c0ce001eSMatthew G. Knepley @*/ 74c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterSetType(PetscLimiter lim, PetscLimiterType name) 75c0ce001eSMatthew G. Knepley { 76c0ce001eSMatthew G. Knepley PetscErrorCode (*r)(PetscLimiter); 77c0ce001eSMatthew G. Knepley PetscBool match; 78c0ce001eSMatthew G. Knepley 79c0ce001eSMatthew G. Knepley PetscFunctionBegin; 80c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 819566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) lim, name, &match)); 82c0ce001eSMatthew G. Knepley if (match) PetscFunctionReturn(0); 83c0ce001eSMatthew G. Knepley 849566063dSJacob Faibussowitsch PetscCall(PetscLimiterRegisterAll()); 859566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(PetscLimiterList, name, &r)); 8628b400f6SJacob Faibussowitsch PetscCheck(r,PetscObjectComm((PetscObject) lim), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscLimiter type: %s", name); 87c0ce001eSMatthew G. Knepley 88c0ce001eSMatthew G. Knepley if (lim->ops->destroy) { 899566063dSJacob Faibussowitsch PetscCall((*lim->ops->destroy)(lim)); 90c0ce001eSMatthew G. Knepley lim->ops->destroy = NULL; 91c0ce001eSMatthew G. Knepley } 929566063dSJacob Faibussowitsch PetscCall((*r)(lim)); 939566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject) lim, name)); 94c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 95c0ce001eSMatthew G. Knepley } 96c0ce001eSMatthew G. Knepley 97c0ce001eSMatthew G. Knepley /*@C 98c0ce001eSMatthew G. Knepley PetscLimiterGetType - Gets the PetscLimiter type name (as a string) from the object. 99c0ce001eSMatthew G. Knepley 100c0ce001eSMatthew G. Knepley Not Collective 101c0ce001eSMatthew G. Knepley 102c0ce001eSMatthew G. Knepley Input Parameter: 103c0ce001eSMatthew G. Knepley . lim - The PetscLimiter 104c0ce001eSMatthew G. Knepley 105c0ce001eSMatthew G. Knepley Output Parameter: 106c0ce001eSMatthew G. Knepley . name - The PetscLimiter type name 107c0ce001eSMatthew G. Knepley 108c0ce001eSMatthew G. Knepley Level: intermediate 109c0ce001eSMatthew G. Knepley 110c0ce001eSMatthew G. Knepley .seealso: PetscLimiterSetType(), PetscLimiterCreate() 111c0ce001eSMatthew G. Knepley @*/ 112c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterGetType(PetscLimiter lim, PetscLimiterType *name) 113c0ce001eSMatthew G. Knepley { 114c0ce001eSMatthew G. Knepley PetscFunctionBegin; 115c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 116c0ce001eSMatthew G. Knepley PetscValidPointer(name, 2); 1179566063dSJacob Faibussowitsch PetscCall(PetscLimiterRegisterAll()); 118c0ce001eSMatthew G. Knepley *name = ((PetscObject) lim)->type_name; 119c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 120c0ce001eSMatthew G. Knepley } 121c0ce001eSMatthew G. Knepley 122c0ce001eSMatthew G. Knepley /*@C 123fe2efc57SMark PetscLimiterViewFromOptions - View from Options 124fe2efc57SMark 125fe2efc57SMark Collective on PetscLimiter 126fe2efc57SMark 127fe2efc57SMark Input Parameters: 128fe2efc57SMark + A - the PetscLimiter object to view 129736c3998SJose E. Roman . obj - Optional object 130736c3998SJose E. Roman - name - command line option 131fe2efc57SMark 132fe2efc57SMark Level: intermediate 133fe2efc57SMark .seealso: PetscLimiter, PetscLimiterView, PetscObjectViewFromOptions(), PetscLimiterCreate() 134fe2efc57SMark @*/ 135fe2efc57SMark PetscErrorCode PetscLimiterViewFromOptions(PetscLimiter A,PetscObject obj,const char name[]) 136fe2efc57SMark { 137fe2efc57SMark PetscFunctionBegin; 138fe2efc57SMark PetscValidHeaderSpecific(A,PETSCLIMITER_CLASSID,1); 1399566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name)); 140fe2efc57SMark PetscFunctionReturn(0); 141fe2efc57SMark } 142fe2efc57SMark 143fe2efc57SMark /*@C 144c0ce001eSMatthew G. Knepley PetscLimiterView - Views a PetscLimiter 145c0ce001eSMatthew G. Knepley 146c0ce001eSMatthew G. Knepley Collective on lim 147c0ce001eSMatthew G. Knepley 148d8d19677SJose E. Roman Input Parameters: 149c0ce001eSMatthew G. Knepley + lim - the PetscLimiter object to view 150c0ce001eSMatthew G. Knepley - v - the viewer 151c0ce001eSMatthew G. Knepley 15288f5f89eSMatthew G. Knepley Level: beginner 153c0ce001eSMatthew G. Knepley 154c0ce001eSMatthew G. Knepley .seealso: PetscLimiterDestroy() 155c0ce001eSMatthew G. Knepley @*/ 156c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterView(PetscLimiter lim, PetscViewer v) 157c0ce001eSMatthew G. Knepley { 158c0ce001eSMatthew G. Knepley PetscFunctionBegin; 159c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 1609566063dSJacob Faibussowitsch if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) lim), &v)); 1619566063dSJacob Faibussowitsch if (lim->ops->view) PetscCall((*lim->ops->view)(lim, v)); 162c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 163c0ce001eSMatthew G. Knepley } 164c0ce001eSMatthew G. Knepley 165c0ce001eSMatthew G. Knepley /*@ 166c0ce001eSMatthew G. Knepley PetscLimiterSetFromOptions - sets parameters in a PetscLimiter from the options database 167c0ce001eSMatthew G. Knepley 168c0ce001eSMatthew G. Knepley Collective on lim 169c0ce001eSMatthew G. Knepley 170c0ce001eSMatthew G. Knepley Input Parameter: 171c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to set options for 172c0ce001eSMatthew G. Knepley 17388f5f89eSMatthew G. Knepley Level: intermediate 174c0ce001eSMatthew G. Knepley 175c0ce001eSMatthew G. Knepley .seealso: PetscLimiterView() 176c0ce001eSMatthew G. Knepley @*/ 177c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterSetFromOptions(PetscLimiter lim) 178c0ce001eSMatthew G. Knepley { 179c0ce001eSMatthew G. Knepley const char *defaultType; 180c0ce001eSMatthew G. Knepley char name[256]; 181c0ce001eSMatthew G. Knepley PetscBool flg; 182c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 183c0ce001eSMatthew G. Knepley 184c0ce001eSMatthew G. Knepley PetscFunctionBegin; 185c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 186c0ce001eSMatthew G. Knepley if (!((PetscObject) lim)->type_name) defaultType = PETSCLIMITERSIN; 187c0ce001eSMatthew G. Knepley else defaultType = ((PetscObject) lim)->type_name; 1889566063dSJacob Faibussowitsch PetscCall(PetscLimiterRegisterAll()); 189c0ce001eSMatthew G. Knepley 1909566063dSJacob Faibussowitsch ierr = PetscObjectOptionsBegin((PetscObject) lim);PetscCall(ierr); 1919566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-petsclimiter_type", "Finite volume slope limiter", "PetscLimiterSetType", PetscLimiterList, defaultType, name, 256, &flg)); 192c0ce001eSMatthew G. Knepley if (flg) { 1939566063dSJacob Faibussowitsch PetscCall(PetscLimiterSetType(lim, name)); 194c0ce001eSMatthew G. Knepley } else if (!((PetscObject) lim)->type_name) { 1959566063dSJacob Faibussowitsch PetscCall(PetscLimiterSetType(lim, defaultType)); 196c0ce001eSMatthew G. Knepley } 1979566063dSJacob Faibussowitsch if (lim->ops->setfromoptions) PetscCall((*lim->ops->setfromoptions)(lim)); 198c0ce001eSMatthew G. Knepley /* process any options handlers added with PetscObjectAddOptionsHandler() */ 1999566063dSJacob Faibussowitsch PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) lim)); 2009566063dSJacob Faibussowitsch ierr = PetscOptionsEnd();PetscCall(ierr); 2019566063dSJacob Faibussowitsch PetscCall(PetscLimiterViewFromOptions(lim, NULL, "-petsclimiter_view")); 202c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 203c0ce001eSMatthew G. Knepley } 204c0ce001eSMatthew G. Knepley 205c0ce001eSMatthew G. Knepley /*@C 206c0ce001eSMatthew G. Knepley PetscLimiterSetUp - Construct data structures for the PetscLimiter 207c0ce001eSMatthew G. Knepley 208c0ce001eSMatthew G. Knepley Collective on lim 209c0ce001eSMatthew G. Knepley 210c0ce001eSMatthew G. Knepley Input Parameter: 211c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to setup 212c0ce001eSMatthew G. Knepley 21388f5f89eSMatthew G. Knepley Level: intermediate 214c0ce001eSMatthew G. Knepley 215c0ce001eSMatthew G. Knepley .seealso: PetscLimiterView(), PetscLimiterDestroy() 216c0ce001eSMatthew G. Knepley @*/ 217c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterSetUp(PetscLimiter lim) 218c0ce001eSMatthew G. Knepley { 219c0ce001eSMatthew G. Knepley PetscFunctionBegin; 220c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 2219566063dSJacob Faibussowitsch if (lim->ops->setup) PetscCall((*lim->ops->setup)(lim)); 222c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 223c0ce001eSMatthew G. Knepley } 224c0ce001eSMatthew G. Knepley 225c0ce001eSMatthew G. Knepley /*@ 226c0ce001eSMatthew G. Knepley PetscLimiterDestroy - Destroys a PetscLimiter object 227c0ce001eSMatthew G. Knepley 228c0ce001eSMatthew G. Knepley Collective on lim 229c0ce001eSMatthew G. Knepley 230c0ce001eSMatthew G. Knepley Input Parameter: 231c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to destroy 232c0ce001eSMatthew G. Knepley 23388f5f89eSMatthew G. Knepley Level: beginner 234c0ce001eSMatthew G. Knepley 235c0ce001eSMatthew G. Knepley .seealso: PetscLimiterView() 236c0ce001eSMatthew G. Knepley @*/ 237c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterDestroy(PetscLimiter *lim) 238c0ce001eSMatthew G. Knepley { 239c0ce001eSMatthew G. Knepley PetscFunctionBegin; 240c0ce001eSMatthew G. Knepley if (!*lim) PetscFunctionReturn(0); 241c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific((*lim), PETSCLIMITER_CLASSID, 1); 242c0ce001eSMatthew G. Knepley 243ea78f98cSLisandro Dalcin if (--((PetscObject)(*lim))->refct > 0) {*lim = NULL; PetscFunctionReturn(0);} 244c0ce001eSMatthew G. Knepley ((PetscObject) (*lim))->refct = 0; 245c0ce001eSMatthew G. Knepley 2469566063dSJacob Faibussowitsch if ((*lim)->ops->destroy) PetscCall((*(*lim)->ops->destroy)(*lim)); 2479566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(lim)); 248c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 249c0ce001eSMatthew G. Knepley } 250c0ce001eSMatthew G. Knepley 251c0ce001eSMatthew G. Knepley /*@ 252c0ce001eSMatthew G. Knepley PetscLimiterCreate - Creates an empty PetscLimiter object. The type can then be set with PetscLimiterSetType(). 253c0ce001eSMatthew G. Knepley 254c0ce001eSMatthew G. Knepley Collective 255c0ce001eSMatthew G. Knepley 256c0ce001eSMatthew G. Knepley Input Parameter: 257c0ce001eSMatthew G. Knepley . comm - The communicator for the PetscLimiter object 258c0ce001eSMatthew G. Knepley 259c0ce001eSMatthew G. Knepley Output Parameter: 260c0ce001eSMatthew G. Knepley . lim - The PetscLimiter object 261c0ce001eSMatthew G. Knepley 262c0ce001eSMatthew G. Knepley Level: beginner 263c0ce001eSMatthew G. Knepley 264c0ce001eSMatthew G. Knepley .seealso: PetscLimiterSetType(), PETSCLIMITERSIN 265c0ce001eSMatthew G. Knepley @*/ 266c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterCreate(MPI_Comm comm, PetscLimiter *lim) 267c0ce001eSMatthew G. Knepley { 268c0ce001eSMatthew G. Knepley PetscLimiter l; 269c0ce001eSMatthew G. Knepley 270c0ce001eSMatthew G. Knepley PetscFunctionBegin; 271c0ce001eSMatthew G. Knepley PetscValidPointer(lim, 2); 2729566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(LimiterCitation,&Limitercite)); 273c0ce001eSMatthew G. Knepley *lim = NULL; 2749566063dSJacob Faibussowitsch PetscCall(PetscFVInitializePackage()); 275c0ce001eSMatthew G. Knepley 2769566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(l, PETSCLIMITER_CLASSID, "PetscLimiter", "Finite Volume Slope Limiter", "PetscLimiter", comm, PetscLimiterDestroy, PetscLimiterView)); 277c0ce001eSMatthew G. Knepley 278c0ce001eSMatthew G. Knepley *lim = l; 279c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 280c0ce001eSMatthew G. Knepley } 281c0ce001eSMatthew G. Knepley 28288f5f89eSMatthew G. Knepley /*@ 28388f5f89eSMatthew G. Knepley PetscLimiterLimit - Limit the flux 28488f5f89eSMatthew G. Knepley 28588f5f89eSMatthew G. Knepley Input Parameters: 28688f5f89eSMatthew G. Knepley + lim - The PetscLimiter 28788f5f89eSMatthew G. Knepley - flim - The input field 28888f5f89eSMatthew G. Knepley 28988f5f89eSMatthew G. Knepley Output Parameter: 29088f5f89eSMatthew G. Knepley . phi - The limited field 29188f5f89eSMatthew G. Knepley 29288f5f89eSMatthew G. Knepley Note: Limiters given in symmetric form following Berger, Aftosmis, and Murman 2005 29388f5f89eSMatthew G. Knepley $ The classical flux-limited formulation is psi(r) where 29488f5f89eSMatthew G. Knepley $ 29588f5f89eSMatthew G. Knepley $ r = (u[0] - u[-1]) / (u[1] - u[0]) 29688f5f89eSMatthew G. Knepley $ 29788f5f89eSMatthew G. Knepley $ The second order TVD region is bounded by 29888f5f89eSMatthew G. Knepley $ 29988f5f89eSMatthew G. Knepley $ psi_minmod(r) = min(r,1) and psi_superbee(r) = min(2, 2r, max(1,r)) 30088f5f89eSMatthew G. Knepley $ 30188f5f89eSMatthew G. Knepley $ where all limiters are implicitly clipped to be non-negative. A more convenient slope-limited form is psi(r) = 30288f5f89eSMatthew G. Knepley $ phi(r)(r+1)/2 in which the reconstructed interface values are 30388f5f89eSMatthew G. Knepley $ 30488f5f89eSMatthew G. Knepley $ u(v) = u[0] + phi(r) (grad u)[0] v 30588f5f89eSMatthew G. Knepley $ 30688f5f89eSMatthew G. Knepley $ where v is the vector from centroid to quadrature point. In these variables, the usual limiters become 30788f5f89eSMatthew G. Knepley $ 30888f5f89eSMatthew G. Knepley $ 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)) 30988f5f89eSMatthew G. Knepley $ 31088f5f89eSMatthew G. Knepley $ For a nicer symmetric formulation, rewrite in terms of 31188f5f89eSMatthew G. Knepley $ 31288f5f89eSMatthew G. Knepley $ f = (u[0] - u[-1]) / (u[1] - u[-1]) 31388f5f89eSMatthew G. Knepley $ 31488f5f89eSMatthew G. Knepley $ where r(f) = f/(1-f). Not that r(1-f) = (1-f)/f = 1/r(f) so the symmetry condition 31588f5f89eSMatthew G. Knepley $ 31688f5f89eSMatthew G. Knepley $ phi(r) = phi(1/r) 31788f5f89eSMatthew G. Knepley $ 31888f5f89eSMatthew G. Knepley $ becomes 31988f5f89eSMatthew G. Knepley $ 32088f5f89eSMatthew G. Knepley $ w(f) = w(1-f). 32188f5f89eSMatthew G. Knepley $ 32288f5f89eSMatthew G. Knepley $ The limiters below implement this final form w(f). The reference methods are 32388f5f89eSMatthew G. Knepley $ 32488f5f89eSMatthew G. Knepley $ w_minmod(f) = 2 min(f,(1-f)) w_superbee(r) = 4 min((1-f), f) 32588f5f89eSMatthew G. Knepley 32688f5f89eSMatthew G. Knepley Level: beginner 32788f5f89eSMatthew G. Knepley 32888f5f89eSMatthew G. Knepley .seealso: PetscLimiterSetType(), PetscLimiterCreate() 32988f5f89eSMatthew G. Knepley @*/ 330c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterLimit(PetscLimiter lim, PetscReal flim, PetscReal *phi) 331c0ce001eSMatthew G. Knepley { 332c0ce001eSMatthew G. Knepley PetscFunctionBegin; 333c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 334dadcf809SJacob Faibussowitsch PetscValidRealPointer(phi, 3); 3359566063dSJacob Faibussowitsch PetscCall((*lim->ops->limit)(lim, flim, phi)); 336c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 337c0ce001eSMatthew G. Knepley } 338c0ce001eSMatthew G. Knepley 33988f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Sin(PetscLimiter lim) 340c0ce001eSMatthew G. Knepley { 341c0ce001eSMatthew G. Knepley PetscLimiter_Sin *l = (PetscLimiter_Sin *) lim->data; 342c0ce001eSMatthew G. Knepley 343c0ce001eSMatthew G. Knepley PetscFunctionBegin; 3449566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 345c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 346c0ce001eSMatthew G. Knepley } 347c0ce001eSMatthew G. Knepley 34888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Sin_Ascii(PetscLimiter lim, PetscViewer viewer) 349c0ce001eSMatthew G. Knepley { 350c0ce001eSMatthew G. Knepley PetscViewerFormat format; 351c0ce001eSMatthew G. Knepley 352c0ce001eSMatthew G. Knepley PetscFunctionBegin; 3539566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 3549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Sin Slope Limiter:\n")); 355c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 356c0ce001eSMatthew G. Knepley } 357c0ce001eSMatthew G. Knepley 35888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Sin(PetscLimiter lim, PetscViewer viewer) 359c0ce001eSMatthew G. Knepley { 360c0ce001eSMatthew G. Knepley PetscBool iascii; 361c0ce001eSMatthew G. Knepley 362c0ce001eSMatthew G. Knepley PetscFunctionBegin; 363c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 364c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 3659566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 3669566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_Sin_Ascii(lim, viewer)); 367c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 368c0ce001eSMatthew G. Knepley } 369c0ce001eSMatthew G. Knepley 37088f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Sin(PetscLimiter lim, PetscReal f, PetscReal *phi) 371c0ce001eSMatthew G. Knepley { 372c0ce001eSMatthew G. Knepley PetscFunctionBegin; 373c0ce001eSMatthew G. Knepley *phi = PetscSinReal(PETSC_PI*PetscMax(0, PetscMin(f, 1))); 374c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 375c0ce001eSMatthew G. Knepley } 376c0ce001eSMatthew G. Knepley 37788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Sin(PetscLimiter lim) 378c0ce001eSMatthew G. Knepley { 379c0ce001eSMatthew G. Knepley PetscFunctionBegin; 380c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Sin; 381c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Sin; 382c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Sin; 383c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 384c0ce001eSMatthew G. Knepley } 385c0ce001eSMatthew G. Knepley 386c0ce001eSMatthew G. Knepley /*MC 387c0ce001eSMatthew G. Knepley PETSCLIMITERSIN = "sin" - A PetscLimiter object 388c0ce001eSMatthew G. Knepley 389c0ce001eSMatthew G. Knepley Level: intermediate 390c0ce001eSMatthew G. Knepley 391c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType() 392c0ce001eSMatthew G. Knepley M*/ 393c0ce001eSMatthew G. Knepley 394c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Sin(PetscLimiter lim) 395c0ce001eSMatthew G. Knepley { 396c0ce001eSMatthew G. Knepley PetscLimiter_Sin *l; 397c0ce001eSMatthew G. Knepley 398c0ce001eSMatthew G. Knepley PetscFunctionBegin; 399c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 4009566063dSJacob Faibussowitsch PetscCall(PetscNewLog(lim, &l)); 401c0ce001eSMatthew G. Knepley lim->data = l; 402c0ce001eSMatthew G. Knepley 4039566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_Sin(lim)); 404c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 405c0ce001eSMatthew G. Knepley } 406c0ce001eSMatthew G. Knepley 40788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Zero(PetscLimiter lim) 408c0ce001eSMatthew G. Knepley { 409c0ce001eSMatthew G. Knepley PetscLimiter_Zero *l = (PetscLimiter_Zero *) lim->data; 410c0ce001eSMatthew G. Knepley 411c0ce001eSMatthew G. Knepley PetscFunctionBegin; 4129566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 413c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 414c0ce001eSMatthew G. Knepley } 415c0ce001eSMatthew G. Knepley 41688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Zero_Ascii(PetscLimiter lim, PetscViewer viewer) 417c0ce001eSMatthew G. Knepley { 418c0ce001eSMatthew G. Knepley PetscViewerFormat format; 419c0ce001eSMatthew G. Knepley 420c0ce001eSMatthew G. Knepley PetscFunctionBegin; 4219566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 4229566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Zero Slope Limiter:\n")); 423c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 424c0ce001eSMatthew G. Knepley } 425c0ce001eSMatthew G. Knepley 42688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Zero(PetscLimiter lim, PetscViewer viewer) 427c0ce001eSMatthew G. Knepley { 428c0ce001eSMatthew G. Knepley PetscBool iascii; 429c0ce001eSMatthew G. Knepley 430c0ce001eSMatthew G. Knepley PetscFunctionBegin; 431c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 432c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 4339566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 4349566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_Zero_Ascii(lim, viewer)); 435c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 436c0ce001eSMatthew G. Knepley } 437c0ce001eSMatthew G. Knepley 43888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Zero(PetscLimiter lim, PetscReal f, PetscReal *phi) 439c0ce001eSMatthew G. Knepley { 440c0ce001eSMatthew G. Knepley PetscFunctionBegin; 441c0ce001eSMatthew G. Knepley *phi = 0.0; 442c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 443c0ce001eSMatthew G. Knepley } 444c0ce001eSMatthew G. Knepley 44588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Zero(PetscLimiter lim) 446c0ce001eSMatthew G. Knepley { 447c0ce001eSMatthew G. Knepley PetscFunctionBegin; 448c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Zero; 449c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Zero; 450c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Zero; 451c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 452c0ce001eSMatthew G. Knepley } 453c0ce001eSMatthew G. Knepley 454c0ce001eSMatthew G. Knepley /*MC 455c0ce001eSMatthew G. Knepley PETSCLIMITERZERO = "zero" - A PetscLimiter object 456c0ce001eSMatthew G. Knepley 457c0ce001eSMatthew G. Knepley Level: intermediate 458c0ce001eSMatthew G. Knepley 459c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType() 460c0ce001eSMatthew G. Knepley M*/ 461c0ce001eSMatthew G. Knepley 462c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Zero(PetscLimiter lim) 463c0ce001eSMatthew G. Knepley { 464c0ce001eSMatthew G. Knepley PetscLimiter_Zero *l; 465c0ce001eSMatthew G. Knepley 466c0ce001eSMatthew G. Knepley PetscFunctionBegin; 467c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 4689566063dSJacob Faibussowitsch PetscCall(PetscNewLog(lim, &l)); 469c0ce001eSMatthew G. Knepley lim->data = l; 470c0ce001eSMatthew G. Knepley 4719566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_Zero(lim)); 472c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 473c0ce001eSMatthew G. Knepley } 474c0ce001eSMatthew G. Knepley 47588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_None(PetscLimiter lim) 476c0ce001eSMatthew G. Knepley { 477c0ce001eSMatthew G. Knepley PetscLimiter_None *l = (PetscLimiter_None *) lim->data; 478c0ce001eSMatthew G. Knepley 479c0ce001eSMatthew G. Knepley PetscFunctionBegin; 4809566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 481c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 482c0ce001eSMatthew G. Knepley } 483c0ce001eSMatthew G. Knepley 48488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_None_Ascii(PetscLimiter lim, PetscViewer viewer) 485c0ce001eSMatthew G. Knepley { 486c0ce001eSMatthew G. Knepley PetscViewerFormat format; 487c0ce001eSMatthew G. Knepley 488c0ce001eSMatthew G. Knepley PetscFunctionBegin; 4899566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 4909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "None Slope Limiter:\n")); 491c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 492c0ce001eSMatthew G. Knepley } 493c0ce001eSMatthew G. Knepley 49488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_None(PetscLimiter lim, PetscViewer viewer) 495c0ce001eSMatthew G. Knepley { 496c0ce001eSMatthew G. Knepley PetscBool iascii; 497c0ce001eSMatthew G. Knepley 498c0ce001eSMatthew G. Knepley PetscFunctionBegin; 499c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 500c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 5019566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 5029566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_None_Ascii(lim, viewer)); 503c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 504c0ce001eSMatthew G. Knepley } 505c0ce001eSMatthew G. Knepley 50688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_None(PetscLimiter lim, PetscReal f, PetscReal *phi) 507c0ce001eSMatthew G. Knepley { 508c0ce001eSMatthew G. Knepley PetscFunctionBegin; 509c0ce001eSMatthew G. Knepley *phi = 1.0; 510c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 511c0ce001eSMatthew G. Knepley } 512c0ce001eSMatthew G. Knepley 51388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_None(PetscLimiter lim) 514c0ce001eSMatthew G. Knepley { 515c0ce001eSMatthew G. Knepley PetscFunctionBegin; 516c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_None; 517c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_None; 518c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_None; 519c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 520c0ce001eSMatthew G. Knepley } 521c0ce001eSMatthew G. Knepley 522c0ce001eSMatthew G. Knepley /*MC 523c0ce001eSMatthew G. Knepley PETSCLIMITERNONE = "none" - A PetscLimiter object 524c0ce001eSMatthew G. Knepley 525c0ce001eSMatthew G. Knepley Level: intermediate 526c0ce001eSMatthew G. Knepley 527c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType() 528c0ce001eSMatthew G. Knepley M*/ 529c0ce001eSMatthew G. Knepley 530c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_None(PetscLimiter lim) 531c0ce001eSMatthew G. Knepley { 532c0ce001eSMatthew G. Knepley PetscLimiter_None *l; 533c0ce001eSMatthew G. Knepley 534c0ce001eSMatthew G. Knepley PetscFunctionBegin; 535c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 5369566063dSJacob Faibussowitsch PetscCall(PetscNewLog(lim, &l)); 537c0ce001eSMatthew G. Knepley lim->data = l; 538c0ce001eSMatthew G. Knepley 5399566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_None(lim)); 540c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 541c0ce001eSMatthew G. Knepley } 542c0ce001eSMatthew G. Knepley 54388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Minmod(PetscLimiter lim) 544c0ce001eSMatthew G. Knepley { 545c0ce001eSMatthew G. Knepley PetscLimiter_Minmod *l = (PetscLimiter_Minmod *) lim->data; 546c0ce001eSMatthew G. Knepley 547c0ce001eSMatthew G. Knepley PetscFunctionBegin; 5489566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 549c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 550c0ce001eSMatthew G. Knepley } 551c0ce001eSMatthew G. Knepley 55288f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Minmod_Ascii(PetscLimiter lim, PetscViewer viewer) 553c0ce001eSMatthew G. Knepley { 554c0ce001eSMatthew G. Knepley PetscViewerFormat format; 555c0ce001eSMatthew G. Knepley 556c0ce001eSMatthew G. Knepley PetscFunctionBegin; 5579566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 5589566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Minmod Slope Limiter:\n")); 559c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 560c0ce001eSMatthew G. Knepley } 561c0ce001eSMatthew G. Knepley 56288f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Minmod(PetscLimiter lim, PetscViewer viewer) 563c0ce001eSMatthew G. Knepley { 564c0ce001eSMatthew G. Knepley PetscBool iascii; 565c0ce001eSMatthew G. Knepley 566c0ce001eSMatthew G. Knepley PetscFunctionBegin; 567c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 568c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 5699566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 5709566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_Minmod_Ascii(lim, viewer)); 571c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 572c0ce001eSMatthew G. Knepley } 573c0ce001eSMatthew G. Knepley 57488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Minmod(PetscLimiter lim, PetscReal f, PetscReal *phi) 575c0ce001eSMatthew G. Knepley { 576c0ce001eSMatthew G. Knepley PetscFunctionBegin; 577c0ce001eSMatthew G. Knepley *phi = 2*PetscMax(0, PetscMin(f, 1-f)); 578c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 579c0ce001eSMatthew G. Knepley } 580c0ce001eSMatthew G. Knepley 58188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Minmod(PetscLimiter lim) 582c0ce001eSMatthew G. Knepley { 583c0ce001eSMatthew G. Knepley PetscFunctionBegin; 584c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Minmod; 585c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Minmod; 586c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Minmod; 587c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 588c0ce001eSMatthew G. Knepley } 589c0ce001eSMatthew G. Knepley 590c0ce001eSMatthew G. Knepley /*MC 591c0ce001eSMatthew G. Knepley PETSCLIMITERMINMOD = "minmod" - A PetscLimiter object 592c0ce001eSMatthew G. Knepley 593c0ce001eSMatthew G. Knepley Level: intermediate 594c0ce001eSMatthew G. Knepley 595c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType() 596c0ce001eSMatthew G. Knepley M*/ 597c0ce001eSMatthew G. Knepley 598c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Minmod(PetscLimiter lim) 599c0ce001eSMatthew G. Knepley { 600c0ce001eSMatthew G. Knepley PetscLimiter_Minmod *l; 601c0ce001eSMatthew G. Knepley 602c0ce001eSMatthew G. Knepley PetscFunctionBegin; 603c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 6049566063dSJacob Faibussowitsch PetscCall(PetscNewLog(lim, &l)); 605c0ce001eSMatthew G. Knepley lim->data = l; 606c0ce001eSMatthew G. Knepley 6079566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_Minmod(lim)); 608c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 609c0ce001eSMatthew G. Knepley } 610c0ce001eSMatthew G. Knepley 61188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_VanLeer(PetscLimiter lim) 612c0ce001eSMatthew G. Knepley { 613c0ce001eSMatthew G. Knepley PetscLimiter_VanLeer *l = (PetscLimiter_VanLeer *) lim->data; 614c0ce001eSMatthew G. Knepley 615c0ce001eSMatthew G. Knepley PetscFunctionBegin; 6169566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 617c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 618c0ce001eSMatthew G. Knepley } 619c0ce001eSMatthew G. Knepley 62088f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanLeer_Ascii(PetscLimiter lim, PetscViewer viewer) 621c0ce001eSMatthew G. Knepley { 622c0ce001eSMatthew G. Knepley PetscViewerFormat format; 623c0ce001eSMatthew G. Knepley 624c0ce001eSMatthew G. Knepley PetscFunctionBegin; 6259566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 6269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Van Leer Slope Limiter:\n")); 627c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 628c0ce001eSMatthew G. Knepley } 629c0ce001eSMatthew G. Knepley 63088f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanLeer(PetscLimiter lim, PetscViewer viewer) 631c0ce001eSMatthew G. Knepley { 632c0ce001eSMatthew G. Knepley PetscBool iascii; 633c0ce001eSMatthew G. Knepley 634c0ce001eSMatthew G. Knepley PetscFunctionBegin; 635c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 636c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 6379566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 6389566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_VanLeer_Ascii(lim, viewer)); 639c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 640c0ce001eSMatthew G. Knepley } 641c0ce001eSMatthew G. Knepley 64288f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_VanLeer(PetscLimiter lim, PetscReal f, PetscReal *phi) 643c0ce001eSMatthew G. Knepley { 644c0ce001eSMatthew G. Knepley PetscFunctionBegin; 645c0ce001eSMatthew G. Knepley *phi = PetscMax(0, 4*f*(1-f)); 646c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 647c0ce001eSMatthew G. Knepley } 648c0ce001eSMatthew G. Knepley 64988f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_VanLeer(PetscLimiter lim) 650c0ce001eSMatthew G. Knepley { 651c0ce001eSMatthew G. Knepley PetscFunctionBegin; 652c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_VanLeer; 653c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_VanLeer; 654c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_VanLeer; 655c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 656c0ce001eSMatthew G. Knepley } 657c0ce001eSMatthew G. Knepley 658c0ce001eSMatthew G. Knepley /*MC 659c0ce001eSMatthew G. Knepley PETSCLIMITERVANLEER = "vanleer" - A PetscLimiter object 660c0ce001eSMatthew G. Knepley 661c0ce001eSMatthew G. Knepley Level: intermediate 662c0ce001eSMatthew G. Knepley 663c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType() 664c0ce001eSMatthew G. Knepley M*/ 665c0ce001eSMatthew G. Knepley 666c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanLeer(PetscLimiter lim) 667c0ce001eSMatthew G. Knepley { 668c0ce001eSMatthew G. Knepley PetscLimiter_VanLeer *l; 669c0ce001eSMatthew G. Knepley 670c0ce001eSMatthew G. Knepley PetscFunctionBegin; 671c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 6729566063dSJacob Faibussowitsch PetscCall(PetscNewLog(lim, &l)); 673c0ce001eSMatthew G. Knepley lim->data = l; 674c0ce001eSMatthew G. Knepley 6759566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_VanLeer(lim)); 676c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 677c0ce001eSMatthew G. Knepley } 678c0ce001eSMatthew G. Knepley 67988f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_VanAlbada(PetscLimiter lim) 680c0ce001eSMatthew G. Knepley { 681c0ce001eSMatthew G. Knepley PetscLimiter_VanAlbada *l = (PetscLimiter_VanAlbada *) lim->data; 682c0ce001eSMatthew G. Knepley 683c0ce001eSMatthew G. Knepley PetscFunctionBegin; 6849566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 685c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 686c0ce001eSMatthew G. Knepley } 687c0ce001eSMatthew G. Knepley 68888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanAlbada_Ascii(PetscLimiter lim, PetscViewer viewer) 689c0ce001eSMatthew G. Knepley { 690c0ce001eSMatthew G. Knepley PetscViewerFormat format; 691c0ce001eSMatthew G. Knepley 692c0ce001eSMatthew G. Knepley PetscFunctionBegin; 6939566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 6949566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Van Albada Slope Limiter:\n")); 695c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 696c0ce001eSMatthew G. Knepley } 697c0ce001eSMatthew G. Knepley 69888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanAlbada(PetscLimiter lim, PetscViewer viewer) 699c0ce001eSMatthew G. Knepley { 700c0ce001eSMatthew G. Knepley PetscBool iascii; 701c0ce001eSMatthew G. Knepley 702c0ce001eSMatthew G. Knepley PetscFunctionBegin; 703c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 704c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 7059566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 7069566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_VanAlbada_Ascii(lim, viewer)); 707c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 708c0ce001eSMatthew G. Knepley } 709c0ce001eSMatthew G. Knepley 71088f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_VanAlbada(PetscLimiter lim, PetscReal f, PetscReal *phi) 711c0ce001eSMatthew G. Knepley { 712c0ce001eSMatthew G. Knepley PetscFunctionBegin; 713c0ce001eSMatthew G. Knepley *phi = PetscMax(0, 2*f*(1-f) / (PetscSqr(f) + PetscSqr(1-f))); 714c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 715c0ce001eSMatthew G. Knepley } 716c0ce001eSMatthew G. Knepley 71788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_VanAlbada(PetscLimiter lim) 718c0ce001eSMatthew G. Knepley { 719c0ce001eSMatthew G. Knepley PetscFunctionBegin; 720c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_VanAlbada; 721c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_VanAlbada; 722c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_VanAlbada; 723c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 724c0ce001eSMatthew G. Knepley } 725c0ce001eSMatthew G. Knepley 726c0ce001eSMatthew G. Knepley /*MC 727c0ce001eSMatthew G. Knepley PETSCLIMITERVANALBADA = "vanalbada" - A PetscLimiter object 728c0ce001eSMatthew G. Knepley 729c0ce001eSMatthew G. Knepley Level: intermediate 730c0ce001eSMatthew G. Knepley 731c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType() 732c0ce001eSMatthew G. Knepley M*/ 733c0ce001eSMatthew G. Knepley 734c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanAlbada(PetscLimiter lim) 735c0ce001eSMatthew G. Knepley { 736c0ce001eSMatthew G. Knepley PetscLimiter_VanAlbada *l; 737c0ce001eSMatthew G. Knepley 738c0ce001eSMatthew G. Knepley PetscFunctionBegin; 739c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 7409566063dSJacob Faibussowitsch PetscCall(PetscNewLog(lim, &l)); 741c0ce001eSMatthew G. Knepley lim->data = l; 742c0ce001eSMatthew G. Knepley 7439566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_VanAlbada(lim)); 744c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 745c0ce001eSMatthew G. Knepley } 746c0ce001eSMatthew G. Knepley 74788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Superbee(PetscLimiter lim) 748c0ce001eSMatthew G. Knepley { 749c0ce001eSMatthew G. Knepley PetscLimiter_Superbee *l = (PetscLimiter_Superbee *) lim->data; 750c0ce001eSMatthew G. Knepley 751c0ce001eSMatthew G. Knepley PetscFunctionBegin; 7529566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 753c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 754c0ce001eSMatthew G. Knepley } 755c0ce001eSMatthew G. Knepley 75688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Superbee_Ascii(PetscLimiter lim, PetscViewer viewer) 757c0ce001eSMatthew G. Knepley { 758c0ce001eSMatthew G. Knepley PetscViewerFormat format; 759c0ce001eSMatthew G. Knepley 760c0ce001eSMatthew G. Knepley PetscFunctionBegin; 7619566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 7629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Superbee Slope Limiter:\n")); 763c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 764c0ce001eSMatthew G. Knepley } 765c0ce001eSMatthew G. Knepley 76688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Superbee(PetscLimiter lim, PetscViewer viewer) 767c0ce001eSMatthew G. Knepley { 768c0ce001eSMatthew G. Knepley PetscBool iascii; 769c0ce001eSMatthew G. Knepley 770c0ce001eSMatthew G. Knepley PetscFunctionBegin; 771c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 772c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 7739566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 7749566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_Superbee_Ascii(lim, viewer)); 775c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 776c0ce001eSMatthew G. Knepley } 777c0ce001eSMatthew G. Knepley 77888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Superbee(PetscLimiter lim, PetscReal f, PetscReal *phi) 779c0ce001eSMatthew G. Knepley { 780c0ce001eSMatthew G. Knepley PetscFunctionBegin; 781c0ce001eSMatthew G. Knepley *phi = 4*PetscMax(0, PetscMin(f, 1-f)); 782c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 783c0ce001eSMatthew G. Knepley } 784c0ce001eSMatthew G. Knepley 78588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Superbee(PetscLimiter lim) 786c0ce001eSMatthew G. Knepley { 787c0ce001eSMatthew G. Knepley PetscFunctionBegin; 788c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Superbee; 789c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Superbee; 790c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Superbee; 791c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 792c0ce001eSMatthew G. Knepley } 793c0ce001eSMatthew G. Knepley 794c0ce001eSMatthew G. Knepley /*MC 795c0ce001eSMatthew G. Knepley PETSCLIMITERSUPERBEE = "superbee" - A PetscLimiter object 796c0ce001eSMatthew G. Knepley 797c0ce001eSMatthew G. Knepley Level: intermediate 798c0ce001eSMatthew G. Knepley 799c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType() 800c0ce001eSMatthew G. Knepley M*/ 801c0ce001eSMatthew G. Knepley 802c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Superbee(PetscLimiter lim) 803c0ce001eSMatthew G. Knepley { 804c0ce001eSMatthew G. Knepley PetscLimiter_Superbee *l; 805c0ce001eSMatthew G. Knepley 806c0ce001eSMatthew G. Knepley PetscFunctionBegin; 807c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 8089566063dSJacob Faibussowitsch PetscCall(PetscNewLog(lim, &l)); 809c0ce001eSMatthew G. Knepley lim->data = l; 810c0ce001eSMatthew G. Knepley 8119566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_Superbee(lim)); 812c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 813c0ce001eSMatthew G. Knepley } 814c0ce001eSMatthew G. Knepley 81588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_MC(PetscLimiter lim) 816c0ce001eSMatthew G. Knepley { 817c0ce001eSMatthew G. Knepley PetscLimiter_MC *l = (PetscLimiter_MC *) lim->data; 818c0ce001eSMatthew G. Knepley 819c0ce001eSMatthew G. Knepley PetscFunctionBegin; 8209566063dSJacob Faibussowitsch PetscCall(PetscFree(l)); 821c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 822c0ce001eSMatthew G. Knepley } 823c0ce001eSMatthew G. Knepley 82488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_MC_Ascii(PetscLimiter lim, PetscViewer viewer) 825c0ce001eSMatthew G. Knepley { 826c0ce001eSMatthew G. Knepley PetscViewerFormat format; 827c0ce001eSMatthew G. Knepley 828c0ce001eSMatthew G. Knepley PetscFunctionBegin; 8299566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 8309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "MC Slope Limiter:\n")); 831c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 832c0ce001eSMatthew G. Knepley } 833c0ce001eSMatthew G. Knepley 83488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_MC(PetscLimiter lim, PetscViewer viewer) 835c0ce001eSMatthew G. Knepley { 836c0ce001eSMatthew G. Knepley PetscBool iascii; 837c0ce001eSMatthew G. Knepley 838c0ce001eSMatthew G. Knepley PetscFunctionBegin; 839c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 840c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 8419566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 8429566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscLimiterView_MC_Ascii(lim, viewer)); 843c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 844c0ce001eSMatthew G. Knepley } 845c0ce001eSMatthew G. Knepley 846c0ce001eSMatthew G. Knepley /* aka Barth-Jespersen */ 84788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_MC(PetscLimiter lim, PetscReal f, PetscReal *phi) 848c0ce001eSMatthew G. Knepley { 849c0ce001eSMatthew G. Knepley PetscFunctionBegin; 850c0ce001eSMatthew G. Knepley *phi = PetscMin(1, 4*PetscMax(0, PetscMin(f, 1-f))); 851c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 852c0ce001eSMatthew G. Knepley } 853c0ce001eSMatthew G. Knepley 85488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_MC(PetscLimiter lim) 855c0ce001eSMatthew G. Knepley { 856c0ce001eSMatthew G. Knepley PetscFunctionBegin; 857c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_MC; 858c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_MC; 859c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_MC; 860c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 861c0ce001eSMatthew G. Knepley } 862c0ce001eSMatthew G. Knepley 863c0ce001eSMatthew G. Knepley /*MC 864c0ce001eSMatthew G. Knepley PETSCLIMITERMC = "mc" - A PetscLimiter object 865c0ce001eSMatthew G. Knepley 866c0ce001eSMatthew G. Knepley Level: intermediate 867c0ce001eSMatthew G. Knepley 868c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType() 869c0ce001eSMatthew G. Knepley M*/ 870c0ce001eSMatthew G. Knepley 871c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_MC(PetscLimiter lim) 872c0ce001eSMatthew G. Knepley { 873c0ce001eSMatthew G. Knepley PetscLimiter_MC *l; 874c0ce001eSMatthew G. Knepley 875c0ce001eSMatthew G. Knepley PetscFunctionBegin; 876c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 8779566063dSJacob Faibussowitsch PetscCall(PetscNewLog(lim, &l)); 878c0ce001eSMatthew G. Knepley lim->data = l; 879c0ce001eSMatthew G. Knepley 8809566063dSJacob Faibussowitsch PetscCall(PetscLimiterInitialize_MC(lim)); 881c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 882c0ce001eSMatthew G. Knepley } 883c0ce001eSMatthew G. Knepley 884c0ce001eSMatthew G. Knepley PetscClassId PETSCFV_CLASSID = 0; 885c0ce001eSMatthew G. Knepley 886c0ce001eSMatthew G. Knepley PetscFunctionList PetscFVList = NULL; 887c0ce001eSMatthew G. Knepley PetscBool PetscFVRegisterAllCalled = PETSC_FALSE; 888c0ce001eSMatthew G. Knepley 889c0ce001eSMatthew G. Knepley /*@C 890c0ce001eSMatthew G. Knepley PetscFVRegister - Adds a new PetscFV implementation 891c0ce001eSMatthew G. Knepley 892c0ce001eSMatthew G. Knepley Not Collective 893c0ce001eSMatthew G. Knepley 894c0ce001eSMatthew G. Knepley Input Parameters: 895c0ce001eSMatthew G. Knepley + name - The name of a new user-defined creation routine 896c0ce001eSMatthew G. Knepley - create_func - The creation routine itself 897c0ce001eSMatthew G. Knepley 898c0ce001eSMatthew G. Knepley Notes: 899c0ce001eSMatthew G. Knepley PetscFVRegister() may be called multiple times to add several user-defined PetscFVs 900c0ce001eSMatthew G. Knepley 901c0ce001eSMatthew G. Knepley Sample usage: 902c0ce001eSMatthew G. Knepley .vb 903c0ce001eSMatthew G. Knepley PetscFVRegister("my_fv", MyPetscFVCreate); 904c0ce001eSMatthew G. Knepley .ve 905c0ce001eSMatthew G. Knepley 906c0ce001eSMatthew G. Knepley Then, your PetscFV type can be chosen with the procedural interface via 907c0ce001eSMatthew G. Knepley .vb 908c0ce001eSMatthew G. Knepley PetscFVCreate(MPI_Comm, PetscFV *); 909c0ce001eSMatthew G. Knepley PetscFVSetType(PetscFV, "my_fv"); 910c0ce001eSMatthew G. Knepley .ve 911c0ce001eSMatthew G. Knepley or at runtime via the option 912c0ce001eSMatthew G. Knepley .vb 913c0ce001eSMatthew G. Knepley -petscfv_type my_fv 914c0ce001eSMatthew G. Knepley .ve 915c0ce001eSMatthew G. Knepley 916c0ce001eSMatthew G. Knepley Level: advanced 917c0ce001eSMatthew G. Knepley 918c0ce001eSMatthew G. Knepley .seealso: PetscFVRegisterAll(), PetscFVRegisterDestroy() 919c0ce001eSMatthew G. Knepley 920c0ce001eSMatthew G. Knepley @*/ 921c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVRegister(const char sname[], PetscErrorCode (*function)(PetscFV)) 922c0ce001eSMatthew G. Knepley { 923c0ce001eSMatthew G. Knepley PetscFunctionBegin; 9249566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&PetscFVList, sname, function)); 925c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 926c0ce001eSMatthew G. Knepley } 927c0ce001eSMatthew G. Knepley 928c0ce001eSMatthew G. Knepley /*@C 929c0ce001eSMatthew G. Knepley PetscFVSetType - Builds a particular PetscFV 930c0ce001eSMatthew G. Knepley 931c0ce001eSMatthew G. Knepley Collective on fvm 932c0ce001eSMatthew G. Knepley 933c0ce001eSMatthew G. Knepley Input Parameters: 934c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 935c0ce001eSMatthew G. Knepley - name - The kind of FVM space 936c0ce001eSMatthew G. Knepley 937c0ce001eSMatthew G. Knepley Options Database Key: 938c0ce001eSMatthew G. Knepley . -petscfv_type <type> - Sets the PetscFV type; use -help for a list of available types 939c0ce001eSMatthew G. Knepley 940c0ce001eSMatthew G. Knepley Level: intermediate 941c0ce001eSMatthew G. Knepley 942c0ce001eSMatthew G. Knepley .seealso: PetscFVGetType(), PetscFVCreate() 943c0ce001eSMatthew G. Knepley @*/ 944c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetType(PetscFV fvm, PetscFVType name) 945c0ce001eSMatthew G. Knepley { 946c0ce001eSMatthew G. Knepley PetscErrorCode (*r)(PetscFV); 947c0ce001eSMatthew G. Knepley PetscBool match; 948c0ce001eSMatthew G. Knepley 949c0ce001eSMatthew G. Knepley PetscFunctionBegin; 950c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 9519566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) fvm, name, &match)); 952c0ce001eSMatthew G. Knepley if (match) PetscFunctionReturn(0); 953c0ce001eSMatthew G. Knepley 9549566063dSJacob Faibussowitsch PetscCall(PetscFVRegisterAll()); 9559566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(PetscFVList, name, &r)); 95628b400f6SJacob Faibussowitsch PetscCheck(r,PetscObjectComm((PetscObject) fvm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscFV type: %s", name); 957c0ce001eSMatthew G. Knepley 958c0ce001eSMatthew G. Knepley if (fvm->ops->destroy) { 9599566063dSJacob Faibussowitsch PetscCall((*fvm->ops->destroy)(fvm)); 960c0ce001eSMatthew G. Knepley fvm->ops->destroy = NULL; 961c0ce001eSMatthew G. Knepley } 9629566063dSJacob Faibussowitsch PetscCall((*r)(fvm)); 9639566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject) fvm, name)); 964c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 965c0ce001eSMatthew G. Knepley } 966c0ce001eSMatthew G. Knepley 967c0ce001eSMatthew G. Knepley /*@C 968c0ce001eSMatthew G. Knepley PetscFVGetType - Gets the PetscFV type name (as a string) from the object. 969c0ce001eSMatthew G. Knepley 970c0ce001eSMatthew G. Knepley Not Collective 971c0ce001eSMatthew G. Knepley 972c0ce001eSMatthew G. Knepley Input Parameter: 973c0ce001eSMatthew G. Knepley . fvm - The PetscFV 974c0ce001eSMatthew G. Knepley 975c0ce001eSMatthew G. Knepley Output Parameter: 976c0ce001eSMatthew G. Knepley . name - The PetscFV type name 977c0ce001eSMatthew G. Knepley 978c0ce001eSMatthew G. Knepley Level: intermediate 979c0ce001eSMatthew G. Knepley 980c0ce001eSMatthew G. Knepley .seealso: PetscFVSetType(), PetscFVCreate() 981c0ce001eSMatthew G. Knepley @*/ 982c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetType(PetscFV fvm, PetscFVType *name) 983c0ce001eSMatthew G. Knepley { 984c0ce001eSMatthew G. Knepley PetscFunctionBegin; 985c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 986c0ce001eSMatthew G. Knepley PetscValidPointer(name, 2); 9879566063dSJacob Faibussowitsch PetscCall(PetscFVRegisterAll()); 988c0ce001eSMatthew G. Knepley *name = ((PetscObject) fvm)->type_name; 989c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 990c0ce001eSMatthew G. Knepley } 991c0ce001eSMatthew G. Knepley 992c0ce001eSMatthew G. Knepley /*@C 993fe2efc57SMark PetscFVViewFromOptions - View from Options 994fe2efc57SMark 995fe2efc57SMark Collective on PetscFV 996fe2efc57SMark 997fe2efc57SMark Input Parameters: 998fe2efc57SMark + A - the PetscFV object 999736c3998SJose E. Roman . obj - Optional object 1000736c3998SJose E. Roman - name - command line option 1001fe2efc57SMark 1002fe2efc57SMark Level: intermediate 1003fe2efc57SMark .seealso: PetscFV, PetscFVView, PetscObjectViewFromOptions(), PetscFVCreate() 1004fe2efc57SMark @*/ 1005fe2efc57SMark PetscErrorCode PetscFVViewFromOptions(PetscFV A,PetscObject obj,const char name[]) 1006fe2efc57SMark { 1007fe2efc57SMark PetscFunctionBegin; 1008fe2efc57SMark PetscValidHeaderSpecific(A,PETSCFV_CLASSID,1); 10099566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name)); 1010fe2efc57SMark PetscFunctionReturn(0); 1011fe2efc57SMark } 1012fe2efc57SMark 1013fe2efc57SMark /*@C 1014c0ce001eSMatthew G. Knepley PetscFVView - Views a PetscFV 1015c0ce001eSMatthew G. Knepley 1016c0ce001eSMatthew G. Knepley Collective on fvm 1017c0ce001eSMatthew G. Knepley 1018d8d19677SJose E. Roman Input Parameters: 1019c0ce001eSMatthew G. Knepley + fvm - the PetscFV object to view 1020c0ce001eSMatthew G. Knepley - v - the viewer 1021c0ce001eSMatthew G. Knepley 102288f5f89eSMatthew G. Knepley Level: beginner 1023c0ce001eSMatthew G. Knepley 1024c0ce001eSMatthew G. Knepley .seealso: PetscFVDestroy() 1025c0ce001eSMatthew G. Knepley @*/ 1026c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVView(PetscFV fvm, PetscViewer v) 1027c0ce001eSMatthew G. Knepley { 1028c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1029c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 10309566063dSJacob Faibussowitsch if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) fvm), &v)); 10319566063dSJacob Faibussowitsch if (fvm->ops->view) PetscCall((*fvm->ops->view)(fvm, v)); 1032c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1033c0ce001eSMatthew G. Knepley } 1034c0ce001eSMatthew G. Knepley 1035c0ce001eSMatthew G. Knepley /*@ 1036c0ce001eSMatthew G. Knepley PetscFVSetFromOptions - sets parameters in a PetscFV from the options database 1037c0ce001eSMatthew G. Knepley 1038c0ce001eSMatthew G. Knepley Collective on fvm 1039c0ce001eSMatthew G. Knepley 1040c0ce001eSMatthew G. Knepley Input Parameter: 1041c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to set options for 1042c0ce001eSMatthew G. Knepley 1043c0ce001eSMatthew G. Knepley Options Database Key: 1044c0ce001eSMatthew G. Knepley . -petscfv_compute_gradients <bool> - Determines whether cell gradients are calculated 1045c0ce001eSMatthew G. Knepley 104688f5f89eSMatthew G. Knepley Level: intermediate 1047c0ce001eSMatthew G. Knepley 1048c0ce001eSMatthew G. Knepley .seealso: PetscFVView() 1049c0ce001eSMatthew G. Knepley @*/ 1050c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetFromOptions(PetscFV fvm) 1051c0ce001eSMatthew G. Knepley { 1052c0ce001eSMatthew G. Knepley const char *defaultType; 1053c0ce001eSMatthew G. Knepley char name[256]; 1054c0ce001eSMatthew G. Knepley PetscBool flg; 1055c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1056c0ce001eSMatthew G. Knepley 1057c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1058c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1059c0ce001eSMatthew G. Knepley if (!((PetscObject) fvm)->type_name) defaultType = PETSCFVUPWIND; 1060c0ce001eSMatthew G. Knepley else defaultType = ((PetscObject) fvm)->type_name; 10619566063dSJacob Faibussowitsch PetscCall(PetscFVRegisterAll()); 1062c0ce001eSMatthew G. Knepley 10639566063dSJacob Faibussowitsch ierr = PetscObjectOptionsBegin((PetscObject) fvm);PetscCall(ierr); 10649566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-petscfv_type", "Finite volume discretization", "PetscFVSetType", PetscFVList, defaultType, name, 256, &flg)); 1065c0ce001eSMatthew G. Knepley if (flg) { 10669566063dSJacob Faibussowitsch PetscCall(PetscFVSetType(fvm, name)); 1067c0ce001eSMatthew G. Knepley } else if (!((PetscObject) fvm)->type_name) { 10689566063dSJacob Faibussowitsch PetscCall(PetscFVSetType(fvm, defaultType)); 1069c0ce001eSMatthew G. Knepley 1070c0ce001eSMatthew G. Knepley } 10719566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-petscfv_compute_gradients", "Compute cell gradients", "PetscFVSetComputeGradients", fvm->computeGradients, &fvm->computeGradients, NULL)); 10729566063dSJacob Faibussowitsch if (fvm->ops->setfromoptions) PetscCall((*fvm->ops->setfromoptions)(fvm)); 1073c0ce001eSMatthew G. Knepley /* process any options handlers added with PetscObjectAddOptionsHandler() */ 10749566063dSJacob Faibussowitsch PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) fvm)); 10759566063dSJacob Faibussowitsch PetscCall(PetscLimiterSetFromOptions(fvm->limiter)); 10769566063dSJacob Faibussowitsch ierr = PetscOptionsEnd();PetscCall(ierr); 10779566063dSJacob Faibussowitsch PetscCall(PetscFVViewFromOptions(fvm, NULL, "-petscfv_view")); 1078c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1079c0ce001eSMatthew G. Knepley } 1080c0ce001eSMatthew G. Knepley 1081c0ce001eSMatthew G. Knepley /*@ 1082c0ce001eSMatthew G. Knepley PetscFVSetUp - Construct data structures for the PetscFV 1083c0ce001eSMatthew G. Knepley 1084c0ce001eSMatthew G. Knepley Collective on fvm 1085c0ce001eSMatthew G. Knepley 1086c0ce001eSMatthew G. Knepley Input Parameter: 1087c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to setup 1088c0ce001eSMatthew G. Knepley 108988f5f89eSMatthew G. Knepley Level: intermediate 1090c0ce001eSMatthew G. Knepley 1091c0ce001eSMatthew G. Knepley .seealso: PetscFVView(), PetscFVDestroy() 1092c0ce001eSMatthew G. Knepley @*/ 1093c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetUp(PetscFV fvm) 1094c0ce001eSMatthew G. Knepley { 1095c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1096c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 10979566063dSJacob Faibussowitsch PetscCall(PetscLimiterSetUp(fvm->limiter)); 10989566063dSJacob Faibussowitsch if (fvm->ops->setup) PetscCall((*fvm->ops->setup)(fvm)); 1099c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1100c0ce001eSMatthew G. Knepley } 1101c0ce001eSMatthew G. Knepley 1102c0ce001eSMatthew G. Knepley /*@ 1103c0ce001eSMatthew G. Knepley PetscFVDestroy - Destroys a PetscFV object 1104c0ce001eSMatthew G. Knepley 1105c0ce001eSMatthew G. Knepley Collective on fvm 1106c0ce001eSMatthew G. Knepley 1107c0ce001eSMatthew G. Knepley Input Parameter: 1108c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to destroy 1109c0ce001eSMatthew G. Knepley 111088f5f89eSMatthew G. Knepley Level: beginner 1111c0ce001eSMatthew G. Knepley 1112c0ce001eSMatthew G. Knepley .seealso: PetscFVView() 1113c0ce001eSMatthew G. Knepley @*/ 1114c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVDestroy(PetscFV *fvm) 1115c0ce001eSMatthew G. Knepley { 1116c0ce001eSMatthew G. Knepley PetscInt i; 1117c0ce001eSMatthew G. Knepley 1118c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1119c0ce001eSMatthew G. Knepley if (!*fvm) PetscFunctionReturn(0); 1120c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific((*fvm), PETSCFV_CLASSID, 1); 1121c0ce001eSMatthew G. Knepley 1122ea78f98cSLisandro Dalcin if (--((PetscObject)(*fvm))->refct > 0) {*fvm = NULL; PetscFunctionReturn(0);} 1123c0ce001eSMatthew G. Knepley ((PetscObject) (*fvm))->refct = 0; 1124c0ce001eSMatthew G. Knepley 1125c0ce001eSMatthew G. Knepley for (i = 0; i < (*fvm)->numComponents; i++) { 11269566063dSJacob Faibussowitsch PetscCall(PetscFree((*fvm)->componentNames[i])); 1127c0ce001eSMatthew G. Knepley } 11289566063dSJacob Faibussowitsch PetscCall(PetscFree((*fvm)->componentNames)); 11299566063dSJacob Faibussowitsch PetscCall(PetscLimiterDestroy(&(*fvm)->limiter)); 11309566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&(*fvm)->dualSpace)); 11319566063dSJacob Faibussowitsch PetscCall(PetscFree((*fvm)->fluxWork)); 11329566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&(*fvm)->quadrature)); 11339566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&(*fvm)->T)); 1134c0ce001eSMatthew G. Knepley 11359566063dSJacob Faibussowitsch if ((*fvm)->ops->destroy) PetscCall((*(*fvm)->ops->destroy)(*fvm)); 11369566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(fvm)); 1137c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1138c0ce001eSMatthew G. Knepley } 1139c0ce001eSMatthew G. Knepley 1140c0ce001eSMatthew G. Knepley /*@ 1141c0ce001eSMatthew G. Knepley PetscFVCreate - Creates an empty PetscFV object. The type can then be set with PetscFVSetType(). 1142c0ce001eSMatthew G. Knepley 1143c0ce001eSMatthew G. Knepley Collective 1144c0ce001eSMatthew G. Knepley 1145c0ce001eSMatthew G. Knepley Input Parameter: 1146c0ce001eSMatthew G. Knepley . comm - The communicator for the PetscFV object 1147c0ce001eSMatthew G. Knepley 1148c0ce001eSMatthew G. Knepley Output Parameter: 1149c0ce001eSMatthew G. Knepley . fvm - The PetscFV object 1150c0ce001eSMatthew G. Knepley 1151c0ce001eSMatthew G. Knepley Level: beginner 1152c0ce001eSMatthew G. Knepley 1153c0ce001eSMatthew G. Knepley .seealso: PetscFVSetType(), PETSCFVUPWIND 1154c0ce001eSMatthew G. Knepley @*/ 1155c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVCreate(MPI_Comm comm, PetscFV *fvm) 1156c0ce001eSMatthew G. Knepley { 1157c0ce001eSMatthew G. Knepley PetscFV f; 1158c0ce001eSMatthew G. Knepley 1159c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1160c0ce001eSMatthew G. Knepley PetscValidPointer(fvm, 2); 1161c0ce001eSMatthew G. Knepley *fvm = NULL; 11629566063dSJacob Faibussowitsch PetscCall(PetscFVInitializePackage()); 1163c0ce001eSMatthew G. Knepley 11649566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(f, PETSCFV_CLASSID, "PetscFV", "Finite Volume", "PetscFV", comm, PetscFVDestroy, PetscFVView)); 11659566063dSJacob Faibussowitsch PetscCall(PetscMemzero(f->ops, sizeof(struct _PetscFVOps))); 1166c0ce001eSMatthew G. Knepley 11679566063dSJacob Faibussowitsch PetscCall(PetscLimiterCreate(comm, &f->limiter)); 1168c0ce001eSMatthew G. Knepley f->numComponents = 1; 1169c0ce001eSMatthew G. Knepley f->dim = 0; 1170c0ce001eSMatthew G. Knepley f->computeGradients = PETSC_FALSE; 1171c0ce001eSMatthew G. Knepley f->fluxWork = NULL; 11729566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(f->numComponents,&f->componentNames)); 1173c0ce001eSMatthew G. Knepley 1174c0ce001eSMatthew G. Knepley *fvm = f; 1175c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1176c0ce001eSMatthew G. Knepley } 1177c0ce001eSMatthew G. Knepley 1178c0ce001eSMatthew G. Knepley /*@ 1179c0ce001eSMatthew G. Knepley PetscFVSetLimiter - Set the limiter object 1180c0ce001eSMatthew G. Knepley 1181c0ce001eSMatthew G. Knepley Logically collective on fvm 1182c0ce001eSMatthew G. Knepley 1183c0ce001eSMatthew G. Knepley Input Parameters: 1184c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1185c0ce001eSMatthew G. Knepley - lim - The PetscLimiter 1186c0ce001eSMatthew G. Knepley 118788f5f89eSMatthew G. Knepley Level: intermediate 1188c0ce001eSMatthew G. Knepley 1189c0ce001eSMatthew G. Knepley .seealso: PetscFVGetLimiter() 1190c0ce001eSMatthew G. Knepley @*/ 1191c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetLimiter(PetscFV fvm, PetscLimiter lim) 1192c0ce001eSMatthew G. Knepley { 1193c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1194c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1195c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 2); 11969566063dSJacob Faibussowitsch PetscCall(PetscLimiterDestroy(&fvm->limiter)); 11979566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) lim)); 1198c0ce001eSMatthew G. Knepley fvm->limiter = lim; 1199c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1200c0ce001eSMatthew G. Knepley } 1201c0ce001eSMatthew G. Knepley 1202c0ce001eSMatthew G. Knepley /*@ 1203c0ce001eSMatthew G. Knepley PetscFVGetLimiter - Get the limiter object 1204c0ce001eSMatthew G. Knepley 1205c0ce001eSMatthew G. Knepley Not collective 1206c0ce001eSMatthew G. Knepley 1207c0ce001eSMatthew G. Knepley Input Parameter: 1208c0ce001eSMatthew G. Knepley . fvm - the PetscFV object 1209c0ce001eSMatthew G. Knepley 1210c0ce001eSMatthew G. Knepley Output Parameter: 1211c0ce001eSMatthew G. Knepley . lim - The PetscLimiter 1212c0ce001eSMatthew G. Knepley 121388f5f89eSMatthew G. Knepley Level: intermediate 1214c0ce001eSMatthew G. Knepley 1215c0ce001eSMatthew G. Knepley .seealso: PetscFVSetLimiter() 1216c0ce001eSMatthew G. Knepley @*/ 1217c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetLimiter(PetscFV fvm, PetscLimiter *lim) 1218c0ce001eSMatthew G. Knepley { 1219c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1220c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1221c0ce001eSMatthew G. Knepley PetscValidPointer(lim, 2); 1222c0ce001eSMatthew G. Knepley *lim = fvm->limiter; 1223c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1224c0ce001eSMatthew G. Knepley } 1225c0ce001eSMatthew G. Knepley 1226c0ce001eSMatthew G. Knepley /*@ 1227c0ce001eSMatthew G. Knepley PetscFVSetNumComponents - Set the number of field components 1228c0ce001eSMatthew G. Knepley 1229c0ce001eSMatthew G. Knepley Logically collective on fvm 1230c0ce001eSMatthew G. Knepley 1231c0ce001eSMatthew G. Knepley Input Parameters: 1232c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1233c0ce001eSMatthew G. Knepley - comp - The number of components 1234c0ce001eSMatthew G. Knepley 123588f5f89eSMatthew G. Knepley Level: intermediate 1236c0ce001eSMatthew G. Knepley 1237c0ce001eSMatthew G. Knepley .seealso: PetscFVGetNumComponents() 1238c0ce001eSMatthew G. Knepley @*/ 1239c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetNumComponents(PetscFV fvm, PetscInt comp) 1240c0ce001eSMatthew G. Knepley { 1241c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1242c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1243c0ce001eSMatthew G. Knepley if (fvm->numComponents != comp) { 1244c0ce001eSMatthew G. Knepley PetscInt i; 1245c0ce001eSMatthew G. Knepley 1246c0ce001eSMatthew G. Knepley for (i = 0; i < fvm->numComponents; i++) { 12479566063dSJacob Faibussowitsch PetscCall(PetscFree(fvm->componentNames[i])); 1248c0ce001eSMatthew G. Knepley } 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)); 1255c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1256c0ce001eSMatthew G. Knepley } 1257c0ce001eSMatthew G. Knepley 1258c0ce001eSMatthew G. Knepley /*@ 1259c0ce001eSMatthew G. Knepley PetscFVGetNumComponents - Get the number of field components 1260c0ce001eSMatthew G. Knepley 1261c0ce001eSMatthew G. Knepley Not collective 1262c0ce001eSMatthew G. Knepley 1263c0ce001eSMatthew G. Knepley Input Parameter: 1264c0ce001eSMatthew G. Knepley . fvm - the PetscFV object 1265c0ce001eSMatthew G. Knepley 1266c0ce001eSMatthew G. Knepley Output Parameter: 1267c0ce001eSMatthew G. Knepley , comp - The number of components 1268c0ce001eSMatthew G. Knepley 126988f5f89eSMatthew G. Knepley Level: intermediate 1270c0ce001eSMatthew G. Knepley 1271c0ce001eSMatthew G. Knepley .seealso: PetscFVSetNumComponents() 1272c0ce001eSMatthew G. Knepley @*/ 1273c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetNumComponents(PetscFV fvm, PetscInt *comp) 1274c0ce001eSMatthew G. Knepley { 1275c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1276c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1277dadcf809SJacob Faibussowitsch PetscValidIntPointer(comp, 2); 1278c0ce001eSMatthew G. Knepley *comp = fvm->numComponents; 1279c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1280c0ce001eSMatthew G. Knepley } 1281c0ce001eSMatthew G. Knepley 1282c0ce001eSMatthew G. Knepley /*@C 1283c0ce001eSMatthew G. Knepley PetscFVSetComponentName - Set the name of a component (used in output and viewing) 1284c0ce001eSMatthew G. Knepley 1285c0ce001eSMatthew G. Knepley Logically collective on fvm 1286c0ce001eSMatthew G. Knepley Input Parameters: 1287c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1288c0ce001eSMatthew G. Knepley . comp - the component number 1289c0ce001eSMatthew G. Knepley - name - the component name 1290c0ce001eSMatthew G. Knepley 129188f5f89eSMatthew G. Knepley Level: intermediate 1292c0ce001eSMatthew G. Knepley 1293c0ce001eSMatthew G. Knepley .seealso: PetscFVGetComponentName() 1294c0ce001eSMatthew G. Knepley @*/ 1295c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetComponentName(PetscFV fvm, PetscInt comp, const char *name) 1296c0ce001eSMatthew G. Knepley { 1297c0ce001eSMatthew G. Knepley PetscFunctionBegin; 12989566063dSJacob Faibussowitsch PetscCall(PetscFree(fvm->componentNames[comp])); 12999566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name,&fvm->componentNames[comp])); 1300c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1301c0ce001eSMatthew G. Knepley } 1302c0ce001eSMatthew G. Knepley 1303c0ce001eSMatthew G. Knepley /*@C 1304c0ce001eSMatthew G. Knepley PetscFVGetComponentName - Get the name of a component (used in output and viewing) 1305c0ce001eSMatthew G. Knepley 1306c0ce001eSMatthew G. Knepley Logically collective on fvm 1307c0ce001eSMatthew G. Knepley Input Parameters: 1308c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1309c0ce001eSMatthew G. Knepley - comp - the component number 1310c0ce001eSMatthew G. Knepley 1311c0ce001eSMatthew G. Knepley Output Parameter: 1312c0ce001eSMatthew G. Knepley . name - the component name 1313c0ce001eSMatthew G. Knepley 131488f5f89eSMatthew G. Knepley Level: intermediate 1315c0ce001eSMatthew G. Knepley 1316c0ce001eSMatthew G. Knepley .seealso: PetscFVSetComponentName() 1317c0ce001eSMatthew G. Knepley @*/ 1318c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetComponentName(PetscFV fvm, PetscInt comp, const char **name) 1319c0ce001eSMatthew G. Knepley { 1320c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1321c0ce001eSMatthew G. Knepley *name = fvm->componentNames[comp]; 1322c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1323c0ce001eSMatthew G. Knepley } 1324c0ce001eSMatthew G. Knepley 1325c0ce001eSMatthew G. Knepley /*@ 1326c0ce001eSMatthew G. Knepley PetscFVSetSpatialDimension - Set the spatial dimension 1327c0ce001eSMatthew G. Knepley 1328c0ce001eSMatthew G. Knepley Logically collective on fvm 1329c0ce001eSMatthew G. Knepley 1330c0ce001eSMatthew G. Knepley Input Parameters: 1331c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1332c0ce001eSMatthew G. Knepley - dim - The spatial dimension 1333c0ce001eSMatthew G. Knepley 133488f5f89eSMatthew G. Knepley Level: intermediate 1335c0ce001eSMatthew G. Knepley 1336c0ce001eSMatthew G. Knepley .seealso: PetscFVGetSpatialDimension() 1337c0ce001eSMatthew G. Knepley @*/ 1338c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetSpatialDimension(PetscFV fvm, PetscInt dim) 1339c0ce001eSMatthew G. Knepley { 1340c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1341c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1342c0ce001eSMatthew G. Knepley fvm->dim = dim; 1343c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1344c0ce001eSMatthew G. Knepley } 1345c0ce001eSMatthew G. Knepley 1346c0ce001eSMatthew G. Knepley /*@ 1347c0ce001eSMatthew G. Knepley PetscFVGetSpatialDimension - Get the spatial dimension 1348c0ce001eSMatthew G. Knepley 1349c0ce001eSMatthew G. Knepley Logically collective on fvm 1350c0ce001eSMatthew G. Knepley 1351c0ce001eSMatthew G. Knepley Input Parameter: 1352c0ce001eSMatthew G. Knepley . fvm - the PetscFV object 1353c0ce001eSMatthew G. Knepley 1354c0ce001eSMatthew G. Knepley Output Parameter: 1355c0ce001eSMatthew G. Knepley . dim - The spatial dimension 1356c0ce001eSMatthew G. Knepley 135788f5f89eSMatthew G. Knepley Level: intermediate 1358c0ce001eSMatthew G. Knepley 1359c0ce001eSMatthew G. Knepley .seealso: PetscFVSetSpatialDimension() 1360c0ce001eSMatthew G. Knepley @*/ 1361c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetSpatialDimension(PetscFV fvm, PetscInt *dim) 1362c0ce001eSMatthew G. Knepley { 1363c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1364c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1365dadcf809SJacob Faibussowitsch PetscValidIntPointer(dim, 2); 1366c0ce001eSMatthew G. Knepley *dim = fvm->dim; 1367c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1368c0ce001eSMatthew G. Knepley } 1369c0ce001eSMatthew G. Knepley 1370c0ce001eSMatthew G. Knepley /*@ 1371c0ce001eSMatthew G. Knepley PetscFVSetComputeGradients - Toggle computation of cell gradients 1372c0ce001eSMatthew G. Knepley 1373c0ce001eSMatthew G. Knepley Logically collective on fvm 1374c0ce001eSMatthew G. Knepley 1375c0ce001eSMatthew G. Knepley Input Parameters: 1376c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1377c0ce001eSMatthew G. Knepley - computeGradients - Flag to compute cell gradients 1378c0ce001eSMatthew G. Knepley 137988f5f89eSMatthew G. Knepley Level: intermediate 1380c0ce001eSMatthew G. Knepley 1381c0ce001eSMatthew G. Knepley .seealso: PetscFVGetComputeGradients() 1382c0ce001eSMatthew G. Knepley @*/ 1383c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetComputeGradients(PetscFV fvm, PetscBool computeGradients) 1384c0ce001eSMatthew G. Knepley { 1385c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1386c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1387c0ce001eSMatthew G. Knepley fvm->computeGradients = computeGradients; 1388c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1389c0ce001eSMatthew G. Knepley } 1390c0ce001eSMatthew G. Knepley 1391c0ce001eSMatthew G. Knepley /*@ 1392c0ce001eSMatthew G. Knepley PetscFVGetComputeGradients - Return flag for computation of cell gradients 1393c0ce001eSMatthew G. Knepley 1394c0ce001eSMatthew G. Knepley Not collective 1395c0ce001eSMatthew G. Knepley 1396c0ce001eSMatthew G. Knepley Input Parameter: 1397c0ce001eSMatthew G. Knepley . fvm - the PetscFV object 1398c0ce001eSMatthew G. Knepley 1399c0ce001eSMatthew G. Knepley Output Parameter: 1400c0ce001eSMatthew G. Knepley . computeGradients - Flag to compute cell gradients 1401c0ce001eSMatthew G. Knepley 140288f5f89eSMatthew G. Knepley Level: intermediate 1403c0ce001eSMatthew G. Knepley 1404c0ce001eSMatthew G. Knepley .seealso: PetscFVSetComputeGradients() 1405c0ce001eSMatthew G. Knepley @*/ 1406c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetComputeGradients(PetscFV fvm, PetscBool *computeGradients) 1407c0ce001eSMatthew G. Knepley { 1408c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1409c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1410dadcf809SJacob Faibussowitsch PetscValidBoolPointer(computeGradients, 2); 1411c0ce001eSMatthew G. Knepley *computeGradients = fvm->computeGradients; 1412c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1413c0ce001eSMatthew G. Knepley } 1414c0ce001eSMatthew G. Knepley 1415c0ce001eSMatthew G. Knepley /*@ 1416c0ce001eSMatthew G. Knepley PetscFVSetQuadrature - Set the quadrature object 1417c0ce001eSMatthew G. Knepley 1418c0ce001eSMatthew G. Knepley Logically collective on fvm 1419c0ce001eSMatthew G. Knepley 1420c0ce001eSMatthew G. Knepley Input Parameters: 1421c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1422c0ce001eSMatthew G. Knepley - q - The PetscQuadrature 1423c0ce001eSMatthew G. Knepley 142488f5f89eSMatthew G. Knepley Level: intermediate 1425c0ce001eSMatthew G. Knepley 1426c0ce001eSMatthew G. Knepley .seealso: PetscFVGetQuadrature() 1427c0ce001eSMatthew G. Knepley @*/ 1428c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetQuadrature(PetscFV fvm, PetscQuadrature q) 1429c0ce001eSMatthew G. Knepley { 1430c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1431c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 14329566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&fvm->quadrature)); 14339566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) q)); 1434c0ce001eSMatthew G. Knepley fvm->quadrature = q; 1435c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1436c0ce001eSMatthew G. Knepley } 1437c0ce001eSMatthew G. Knepley 1438c0ce001eSMatthew G. Knepley /*@ 1439c0ce001eSMatthew G. Knepley PetscFVGetQuadrature - Get the quadrature object 1440c0ce001eSMatthew G. Knepley 1441c0ce001eSMatthew G. Knepley Not collective 1442c0ce001eSMatthew G. Knepley 1443c0ce001eSMatthew G. Knepley Input Parameter: 1444c0ce001eSMatthew G. Knepley . fvm - the PetscFV object 1445c0ce001eSMatthew G. Knepley 1446c0ce001eSMatthew G. Knepley Output Parameter: 1447c0ce001eSMatthew G. Knepley . lim - The PetscQuadrature 1448c0ce001eSMatthew G. Knepley 144988f5f89eSMatthew G. Knepley Level: intermediate 1450c0ce001eSMatthew G. Knepley 1451c0ce001eSMatthew G. Knepley .seealso: PetscFVSetQuadrature() 1452c0ce001eSMatthew G. Knepley @*/ 1453c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetQuadrature(PetscFV fvm, PetscQuadrature *q) 1454c0ce001eSMatthew G. Knepley { 1455c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1456c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1457c0ce001eSMatthew G. Knepley PetscValidPointer(q, 2); 1458c0ce001eSMatthew G. Knepley if (!fvm->quadrature) { 1459c0ce001eSMatthew G. Knepley /* Create default 1-point quadrature */ 1460c0ce001eSMatthew G. Knepley PetscReal *points, *weights; 1461c0ce001eSMatthew G. Knepley 14629566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &fvm->quadrature)); 14639566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(fvm->dim, &points)); 14649566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, &weights)); 1465c0ce001eSMatthew G. Knepley weights[0] = 1.0; 14669566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(fvm->quadrature, fvm->dim, 1, 1, points, weights)); 1467c0ce001eSMatthew G. Knepley } 1468c0ce001eSMatthew G. Knepley *q = fvm->quadrature; 1469c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1470c0ce001eSMatthew G. Knepley } 1471c0ce001eSMatthew G. Knepley 1472c0ce001eSMatthew G. Knepley /*@ 1473c0ce001eSMatthew G. Knepley PetscFVGetDualSpace - Returns the PetscDualSpace used to define the inner product 1474c0ce001eSMatthew G. Knepley 1475c0ce001eSMatthew G. Knepley Not collective 1476c0ce001eSMatthew G. Knepley 1477c0ce001eSMatthew G. Knepley Input Parameter: 1478c0ce001eSMatthew G. Knepley . fvm - The PetscFV object 1479c0ce001eSMatthew G. Knepley 1480c0ce001eSMatthew G. Knepley Output Parameter: 1481c0ce001eSMatthew G. Knepley . sp - The PetscDualSpace object 1482c0ce001eSMatthew G. Knepley 1483c0ce001eSMatthew G. Knepley Note: A simple dual space is provided automatically, and the user typically will not need to override it. 1484c0ce001eSMatthew G. Knepley 148588f5f89eSMatthew G. Knepley Level: intermediate 1486c0ce001eSMatthew G. Knepley 1487c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate() 1488c0ce001eSMatthew G. Knepley @*/ 1489c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetDualSpace(PetscFV fvm, PetscDualSpace *sp) 1490c0ce001eSMatthew G. Knepley { 1491c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1492c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1493c0ce001eSMatthew G. Knepley PetscValidPointer(sp, 2); 1494c0ce001eSMatthew G. Knepley if (!fvm->dualSpace) { 1495c0ce001eSMatthew G. Knepley DM K; 1496c0ce001eSMatthew G. Knepley PetscInt dim, Nc, c; 1497c0ce001eSMatthew G. Knepley 14989566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 14999566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &Nc)); 15009566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceCreate(PetscObjectComm((PetscObject) fvm), &fvm->dualSpace)); 15019566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetType(fvm->dualSpace, PETSCDUALSPACESIMPLE)); 15029566063dSJacob Faibussowitsch PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, DMPolytopeTypeSimpleShape(dim, PETSC_FALSE), &K)); 15039566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetNumComponents(fvm->dualSpace, Nc)); 15049566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(fvm->dualSpace, K)); 15059566063dSJacob Faibussowitsch PetscCall(DMDestroy(&K)); 15069566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetDimension(fvm->dualSpace, Nc)); 1507c0ce001eSMatthew G. Knepley /* Should we be using PetscFVGetQuadrature() here? */ 1508c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; ++c) { 1509c0ce001eSMatthew G. Knepley PetscQuadrature qc; 1510c0ce001eSMatthew G. Knepley PetscReal *points, *weights; 1511c0ce001eSMatthew G. Knepley 15129566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qc)); 15139566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(dim, &points)); 15149566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nc, &weights)); 1515c0ce001eSMatthew G. Knepley weights[c] = 1.0; 15169566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(qc, dim, Nc, 1, points, weights)); 15179566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetFunctional(fvm->dualSpace, c, qc)); 15189566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qc)); 1519c0ce001eSMatthew G. Knepley } 15209566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(fvm->dualSpace)); 1521c0ce001eSMatthew G. Knepley } 1522c0ce001eSMatthew G. Knepley *sp = fvm->dualSpace; 1523c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1524c0ce001eSMatthew G. Knepley } 1525c0ce001eSMatthew G. Knepley 1526c0ce001eSMatthew G. Knepley /*@ 1527c0ce001eSMatthew G. Knepley PetscFVSetDualSpace - Sets the PetscDualSpace used to define the inner product 1528c0ce001eSMatthew G. Knepley 1529c0ce001eSMatthew G. Knepley Not collective 1530c0ce001eSMatthew G. Knepley 1531c0ce001eSMatthew G. Knepley Input Parameters: 1532c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 1533c0ce001eSMatthew G. Knepley - sp - The PetscDualSpace object 1534c0ce001eSMatthew G. Knepley 1535c0ce001eSMatthew G. Knepley Level: intermediate 1536c0ce001eSMatthew G. Knepley 1537c0ce001eSMatthew G. Knepley Note: A simple dual space is provided automatically, and the user typically will not need to override it. 1538c0ce001eSMatthew G. Knepley 1539c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate() 1540c0ce001eSMatthew G. Knepley @*/ 1541c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetDualSpace(PetscFV fvm, PetscDualSpace sp) 1542c0ce001eSMatthew G. Knepley { 1543c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1544c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1545c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 2); 15469566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&fvm->dualSpace)); 1547c0ce001eSMatthew G. Knepley fvm->dualSpace = sp; 15489566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) fvm->dualSpace)); 1549c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1550c0ce001eSMatthew G. Knepley } 1551c0ce001eSMatthew G. Knepley 155288f5f89eSMatthew G. Knepley /*@C 1553ef0bb6c7SMatthew G. Knepley PetscFVGetCellTabulation - Returns the tabulation of the basis functions at the quadrature points 155488f5f89eSMatthew G. Knepley 155588f5f89eSMatthew G. Knepley Not collective 155688f5f89eSMatthew G. Knepley 155788f5f89eSMatthew G. Knepley Input Parameter: 155888f5f89eSMatthew G. Knepley . fvm - The PetscFV object 155988f5f89eSMatthew G. Knepley 1560ef0bb6c7SMatthew G. Knepley Output Parameter: 1561a5b23f4aSJose E. Roman . T - The basis function values and derivatives at quadrature points 156288f5f89eSMatthew G. Knepley 156388f5f89eSMatthew G. Knepley Note: 1564ef0bb6c7SMatthew G. Knepley $ T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 1565ef0bb6c7SMatthew G. Knepley $ 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 1566ef0bb6c7SMatthew G. Knepley $ 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 156788f5f89eSMatthew G. Knepley 156888f5f89eSMatthew G. Knepley Level: intermediate 156988f5f89eSMatthew G. Knepley 1570ef0bb6c7SMatthew G. Knepley .seealso: PetscFEGetCellTabulation(), PetscFVCreateTabulation(), PetscFVGetQuadrature(), PetscQuadratureGetData() 157188f5f89eSMatthew G. Knepley @*/ 1572ef0bb6c7SMatthew G. Knepley PetscErrorCode PetscFVGetCellTabulation(PetscFV fvm, PetscTabulation *T) 1573c0ce001eSMatthew G. Knepley { 1574c0ce001eSMatthew G. Knepley PetscInt npoints; 1575c0ce001eSMatthew G. Knepley const PetscReal *points; 1576c0ce001eSMatthew G. Knepley 1577c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1578c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1579ef0bb6c7SMatthew G. Knepley PetscValidPointer(T, 2); 15809566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(fvm->quadrature, NULL, NULL, &npoints, &points, NULL)); 15819566063dSJacob Faibussowitsch if (!fvm->T) PetscCall(PetscFVCreateTabulation(fvm, 1, npoints, points, 1, &fvm->T)); 1582ef0bb6c7SMatthew G. Knepley *T = fvm->T; 1583c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1584c0ce001eSMatthew G. Knepley } 1585c0ce001eSMatthew G. Knepley 158688f5f89eSMatthew G. Knepley /*@C 1587ef0bb6c7SMatthew G. Knepley PetscFVCreateTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided. 158888f5f89eSMatthew G. Knepley 158988f5f89eSMatthew G. Knepley Not collective 159088f5f89eSMatthew G. Knepley 159188f5f89eSMatthew G. Knepley Input Parameters: 159288f5f89eSMatthew G. Knepley + fvm - The PetscFV object 1593ef0bb6c7SMatthew G. Knepley . nrepl - The number of replicas 1594ef0bb6c7SMatthew G. Knepley . npoints - The number of tabulation points in a replica 1595ef0bb6c7SMatthew G. Knepley . points - The tabulation point coordinates 1596ef0bb6c7SMatthew G. Knepley - K - The order of derivative to tabulate 159788f5f89eSMatthew G. Knepley 1598ef0bb6c7SMatthew G. Knepley Output Parameter: 1599a5b23f4aSJose E. Roman . T - The basis function values and derivative at tabulation points 160088f5f89eSMatthew G. Knepley 160188f5f89eSMatthew G. Knepley Note: 1602ef0bb6c7SMatthew G. Knepley $ T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 1603ef0bb6c7SMatthew G. Knepley $ 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 1604ef0bb6c7SMatthew G. Knepley $ 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 160588f5f89eSMatthew G. Knepley 160688f5f89eSMatthew G. Knepley Level: intermediate 160788f5f89eSMatthew G. Knepley 1608ef0bb6c7SMatthew G. Knepley .seealso: PetscFECreateTabulation(), PetscTabulationDestroy(), PetscFEGetCellTabulation() 160988f5f89eSMatthew G. Knepley @*/ 1610ef0bb6c7SMatthew G. Knepley PetscErrorCode PetscFVCreateTabulation(PetscFV fvm, PetscInt nrepl, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation *T) 1611c0ce001eSMatthew G. Knepley { 1612c0ce001eSMatthew G. Knepley PetscInt pdim = 1; /* Dimension of approximation space P */ 1613ef0bb6c7SMatthew G. Knepley PetscInt cdim; /* Spatial dimension */ 1614ef0bb6c7SMatthew G. Knepley PetscInt Nc; /* Field components */ 1615ef0bb6c7SMatthew G. Knepley PetscInt k, p, d, c, e; 1616c0ce001eSMatthew G. Knepley 1617c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1618ef0bb6c7SMatthew G. Knepley if (!npoints || K < 0) { 1619ef0bb6c7SMatthew G. Knepley *T = NULL; 1620c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1621c0ce001eSMatthew G. Knepley } 1622c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1623dadcf809SJacob Faibussowitsch PetscValidRealPointer(points, 4); 162440a2aa30SMatthew G. Knepley PetscValidPointer(T, 6); 16259566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &cdim)); 16269566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &Nc)); 16279566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, T)); 1628ef0bb6c7SMatthew G. Knepley (*T)->K = !cdim ? 0 : K; 1629ef0bb6c7SMatthew G. Knepley (*T)->Nr = nrepl; 1630ef0bb6c7SMatthew G. Knepley (*T)->Np = npoints; 1631ef0bb6c7SMatthew G. Knepley (*T)->Nb = pdim; 1632ef0bb6c7SMatthew G. Knepley (*T)->Nc = Nc; 1633ef0bb6c7SMatthew G. Knepley (*T)->cdim = cdim; 16349566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*T)->K+1, &(*T)->T)); 1635ef0bb6c7SMatthew G. Knepley for (k = 0; k <= (*T)->K; ++k) { 16369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nrepl*npoints*pdim*Nc*PetscPowInt(cdim, k), &(*T)->T[k])); 1637ef0bb6c7SMatthew G. Knepley } 1638ef0bb6c7SMatthew G. Knepley if (K >= 0) {for (p = 0; p < nrepl*npoints; ++p) for (d = 0; d < pdim; ++d) for (c = 0; c < Nc; ++c) (*T)->T[0][(p*pdim + d)*Nc + c] = 1.0;} 1639ef0bb6c7SMatthew G. Knepley if (K >= 1) {for (p = 0; p < nrepl*npoints; ++p) for (d = 0; d < pdim; ++d) for (c = 0; c < Nc; ++c) for (e = 0; e < cdim; ++e) (*T)->T[1][((p*pdim + d)*Nc + c)*cdim + e] = 0.0;} 1640ef0bb6c7SMatthew G. Knepley if (K >= 2) {for (p = 0; p < nrepl*npoints; ++p) for (d = 0; d < pdim; ++d) for (c = 0; c < Nc; ++c) for (e = 0; e < cdim*cdim; ++e) (*T)->T[2][((p*pdim + d)*Nc + c)*cdim*cdim + e] = 0.0;} 1641c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1642c0ce001eSMatthew G. Knepley } 1643c0ce001eSMatthew G. Knepley 1644c0ce001eSMatthew G. Knepley /*@C 1645c0ce001eSMatthew G. Knepley PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell 1646c0ce001eSMatthew G. Knepley 1647c0ce001eSMatthew G. Knepley Input Parameters: 1648c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 1649c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained 1650c0ce001eSMatthew G. Knepley - dx - The vector from the cell centroid to the neighboring cell centroid for each face 1651c0ce001eSMatthew G. Knepley 165288f5f89eSMatthew G. Knepley Level: advanced 1653c0ce001eSMatthew G. Knepley 1654c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate() 1655c0ce001eSMatthew G. Knepley @*/ 1656c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVComputeGradient(PetscFV fvm, PetscInt numFaces, PetscScalar dx[], PetscScalar grad[]) 1657c0ce001eSMatthew G. Knepley { 1658c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1659c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 16609566063dSJacob Faibussowitsch if (fvm->ops->computegradient) PetscCall((*fvm->ops->computegradient)(fvm, numFaces, dx, grad)); 1661c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1662c0ce001eSMatthew G. Knepley } 1663c0ce001eSMatthew G. Knepley 166488f5f89eSMatthew G. Knepley /*@C 1665c0ce001eSMatthew G. Knepley PetscFVIntegrateRHSFunction - Produce the cell residual vector for a chunk of elements by quadrature integration 1666c0ce001eSMatthew G. Knepley 1667c0ce001eSMatthew G. Knepley Not collective 1668c0ce001eSMatthew G. Knepley 1669c0ce001eSMatthew G. Knepley Input Parameters: 1670c0ce001eSMatthew G. Knepley + fvm - The PetscFV object for the field being integrated 1671c0ce001eSMatthew G. Knepley . prob - The PetscDS specifing the discretizations and continuum functions 1672c0ce001eSMatthew G. Knepley . field - The field being integrated 1673c0ce001eSMatthew G. Knepley . Nf - The number of faces in the chunk 1674c0ce001eSMatthew G. Knepley . fgeom - The face geometry for each face in the chunk 1675c0ce001eSMatthew G. Knepley . neighborVol - The volume for each pair of cells in the chunk 1676c0ce001eSMatthew G. Knepley . uL - The state from the cell on the left 1677c0ce001eSMatthew G. Knepley - uR - The state from the cell on the right 1678c0ce001eSMatthew G. Knepley 1679d8d19677SJose E. Roman Output Parameters: 1680c0ce001eSMatthew G. Knepley + fluxL - the left fluxes for each face 1681c0ce001eSMatthew G. Knepley - fluxR - the right fluxes for each face 168288f5f89eSMatthew G. Knepley 168388f5f89eSMatthew G. Knepley Level: developer 168488f5f89eSMatthew G. Knepley 168588f5f89eSMatthew G. Knepley .seealso: PetscFVCreate() 168688f5f89eSMatthew G. Knepley @*/ 1687c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVIntegrateRHSFunction(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, 1688c0ce001eSMatthew G. Knepley PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) 1689c0ce001eSMatthew G. Knepley { 1690c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1691c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 16929566063dSJacob Faibussowitsch if (fvm->ops->integraterhsfunction) PetscCall((*fvm->ops->integraterhsfunction)(fvm, prob, field, Nf, fgeom, neighborVol, uL, uR, fluxL, fluxR)); 1693c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1694c0ce001eSMatthew G. Knepley } 1695c0ce001eSMatthew G. Knepley 1696c0ce001eSMatthew G. Knepley /*@ 1697c0ce001eSMatthew G. Knepley PetscFVRefine - Create a "refined" PetscFV object that refines the reference cell into smaller copies. This is typically used 1698c0ce001eSMatthew G. Knepley to precondition a higher order method with a lower order method on a refined mesh having the same number of dofs (but more 1699c0ce001eSMatthew G. Knepley sparsity). It is also used to create an interpolation between regularly refined meshes. 1700c0ce001eSMatthew G. Knepley 1701c0ce001eSMatthew G. Knepley Input Parameter: 1702c0ce001eSMatthew G. Knepley . fv - The initial PetscFV 1703c0ce001eSMatthew G. Knepley 1704c0ce001eSMatthew G. Knepley Output Parameter: 1705c0ce001eSMatthew G. Knepley . fvRef - The refined PetscFV 1706c0ce001eSMatthew G. Knepley 170788f5f89eSMatthew G. Knepley Level: advanced 1708c0ce001eSMatthew G. Knepley 1709c0ce001eSMatthew G. Knepley .seealso: PetscFVType, PetscFVCreate(), PetscFVSetType() 1710c0ce001eSMatthew G. Knepley @*/ 1711c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVRefine(PetscFV fv, PetscFV *fvRef) 1712c0ce001eSMatthew G. Knepley { 1713c0ce001eSMatthew G. Knepley PetscDualSpace Q, Qref; 1714c0ce001eSMatthew G. Knepley DM K, Kref; 1715c0ce001eSMatthew G. Knepley PetscQuadrature q, qref; 1716412e9a14SMatthew G. Knepley DMPolytopeType ct; 1717012bc364SMatthew G. Knepley DMPlexTransform tr; 1718c0ce001eSMatthew G. Knepley PetscReal *v0; 1719c0ce001eSMatthew G. Knepley PetscReal *jac, *invjac; 1720c0ce001eSMatthew G. Knepley PetscInt numComp, numSubelements, s; 1721c0ce001eSMatthew G. Knepley 1722c0ce001eSMatthew G. Knepley PetscFunctionBegin; 17239566063dSJacob Faibussowitsch PetscCall(PetscFVGetDualSpace(fv, &Q)); 17249566063dSJacob Faibussowitsch PetscCall(PetscFVGetQuadrature(fv, &q)); 17259566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &K)); 1726c0ce001eSMatthew G. Knepley /* Create dual space */ 17279566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDuplicate(Q, &Qref)); 17289566063dSJacob Faibussowitsch PetscCall(DMRefine(K, PetscObjectComm((PetscObject) fv), &Kref)); 17299566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(Qref, Kref)); 17309566063dSJacob Faibussowitsch PetscCall(DMDestroy(&Kref)); 17319566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(Qref)); 1732c0ce001eSMatthew G. Knepley /* Create volume */ 17339566063dSJacob Faibussowitsch PetscCall(PetscFVCreate(PetscObjectComm((PetscObject) fv), fvRef)); 17349566063dSJacob Faibussowitsch PetscCall(PetscFVSetDualSpace(*fvRef, Qref)); 17359566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &numComp)); 17369566063dSJacob Faibussowitsch PetscCall(PetscFVSetNumComponents(*fvRef, numComp)); 17379566063dSJacob Faibussowitsch PetscCall(PetscFVSetUp(*fvRef)); 1738c0ce001eSMatthew G. Knepley /* Create quadrature */ 17399566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(K, 0, &ct)); 17409566063dSJacob Faibussowitsch PetscCall(DMPlexTransformCreate(PETSC_COMM_SELF, &tr)); 17419566063dSJacob Faibussowitsch PetscCall(DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR)); 17429566063dSJacob Faibussowitsch PetscCall(DMPlexRefineRegularGetAffineTransforms(tr, ct, &numSubelements, &v0, &jac, &invjac)); 17439566063dSJacob Faibussowitsch PetscCall(PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref)); 17449566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetDimension(Qref, numSubelements)); 1745c0ce001eSMatthew G. Knepley for (s = 0; s < numSubelements; ++s) { 1746c0ce001eSMatthew G. Knepley PetscQuadrature qs; 1747c0ce001eSMatthew G. Knepley const PetscReal *points, *weights; 1748c0ce001eSMatthew G. Knepley PetscReal *p, *w; 1749c0ce001eSMatthew G. Knepley PetscInt dim, Nc, npoints, np; 1750c0ce001eSMatthew G. Knepley 17519566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &qs)); 17529566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(q, &dim, &Nc, &npoints, &points, &weights)); 1753c0ce001eSMatthew G. Knepley np = npoints/numSubelements; 17549566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(np*dim,&p)); 17559566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(np*Nc,&w)); 17569566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(p, &points[s*np*dim], np*dim)); 17579566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(w, &weights[s*np*Nc], np*Nc)); 17589566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(qs, dim, Nc, np, p, w)); 17599566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSimpleSetFunctional(Qref, s, qs)); 17609566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qs)); 1761c0ce001eSMatthew G. Knepley } 17629566063dSJacob Faibussowitsch PetscCall(PetscFVSetQuadrature(*fvRef, qref)); 17639566063dSJacob Faibussowitsch PetscCall(DMPlexTransformDestroy(&tr)); 17649566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qref)); 17659566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&Qref)); 1766c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1767c0ce001eSMatthew G. Knepley } 1768c0ce001eSMatthew G. Knepley 176988f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVDestroy_Upwind(PetscFV fvm) 1770c0ce001eSMatthew G. Knepley { 1771c0ce001eSMatthew G. Knepley PetscFV_Upwind *b = (PetscFV_Upwind *) fvm->data; 1772c0ce001eSMatthew G. Knepley 1773c0ce001eSMatthew G. Knepley PetscFunctionBegin; 17749566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 1775c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1776c0ce001eSMatthew G. Knepley } 1777c0ce001eSMatthew G. Knepley 177888f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_Upwind_Ascii(PetscFV fv, PetscViewer viewer) 1779c0ce001eSMatthew G. Knepley { 1780c0ce001eSMatthew G. Knepley PetscInt Nc, c; 1781c0ce001eSMatthew G. Knepley PetscViewerFormat format; 1782c0ce001eSMatthew G. Knepley 1783c0ce001eSMatthew G. Knepley PetscFunctionBegin; 17849566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &Nc)); 17859566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 17869566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Upwind Finite Volume:\n")); 17879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " num components: %d\n", Nc)); 1788c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; c++) { 1789c0ce001eSMatthew G. Knepley if (fv->componentNames[c]) { 17909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " component %d: %s\n", c, fv->componentNames[c])); 1791c0ce001eSMatthew G. Knepley } 1792c0ce001eSMatthew G. Knepley } 1793c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1794c0ce001eSMatthew G. Knepley } 1795c0ce001eSMatthew G. Knepley 179688f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_Upwind(PetscFV fv, PetscViewer viewer) 1797c0ce001eSMatthew G. Knepley { 1798c0ce001eSMatthew G. Knepley PetscBool iascii; 1799c0ce001eSMatthew G. Knepley 1800c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1801c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1); 1802c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 18039566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 18049566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscFVView_Upwind_Ascii(fv, viewer)); 1805c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1806c0ce001eSMatthew G. Knepley } 1807c0ce001eSMatthew G. Knepley 180888f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVSetUp_Upwind(PetscFV fvm) 1809c0ce001eSMatthew G. Knepley { 1810c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1811c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1812c0ce001eSMatthew G. Knepley } 1813c0ce001eSMatthew G. Knepley 1814c0ce001eSMatthew G. Knepley /* 1815c0ce001eSMatthew G. Knepley neighborVol[f*2+0] contains the left geom 1816c0ce001eSMatthew G. Knepley neighborVol[f*2+1] contains the right geom 1817c0ce001eSMatthew G. Knepley */ 181888f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVIntegrateRHSFunction_Upwind(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, 1819c0ce001eSMatthew G. Knepley PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) 1820c0ce001eSMatthew G. Knepley { 1821c0ce001eSMatthew G. Knepley void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *); 1822c0ce001eSMatthew G. Knepley void *rctx; 1823c0ce001eSMatthew G. Knepley PetscScalar *flux = fvm->fluxWork; 1824c0ce001eSMatthew G. Knepley const PetscScalar *constants; 1825c0ce001eSMatthew G. Knepley PetscInt dim, numConstants, pdim, totDim, Nc, off, f, d; 1826c0ce001eSMatthew G. Knepley 1827c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18289566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalComponents(prob, &Nc)); 18299566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalDimension(prob, &totDim)); 18309566063dSJacob Faibussowitsch PetscCall(PetscDSGetFieldOffset(prob, field, &off)); 18319566063dSJacob Faibussowitsch PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann)); 18329566063dSJacob Faibussowitsch PetscCall(PetscDSGetContext(prob, field, &rctx)); 18339566063dSJacob Faibussowitsch PetscCall(PetscDSGetConstants(prob, &numConstants, &constants)); 18349566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 18359566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &pdim)); 1836c0ce001eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 1837c0ce001eSMatthew G. Knepley (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f*Nc], &uR[f*Nc], numConstants, constants, flux, rctx); 1838c0ce001eSMatthew G. Knepley for (d = 0; d < pdim; ++d) { 1839c0ce001eSMatthew G. Knepley fluxL[f*totDim+off+d] = flux[d] / neighborVol[f*2+0]; 1840c0ce001eSMatthew G. Knepley fluxR[f*totDim+off+d] = flux[d] / neighborVol[f*2+1]; 1841c0ce001eSMatthew G. Knepley } 1842c0ce001eSMatthew G. Knepley } 1843c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1844c0ce001eSMatthew G. Knepley } 1845c0ce001eSMatthew G. Knepley 184688f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVInitialize_Upwind(PetscFV fvm) 1847c0ce001eSMatthew G. Knepley { 1848c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1849c0ce001eSMatthew G. Knepley fvm->ops->setfromoptions = NULL; 1850c0ce001eSMatthew G. Knepley fvm->ops->setup = PetscFVSetUp_Upwind; 1851c0ce001eSMatthew G. Knepley fvm->ops->view = PetscFVView_Upwind; 1852c0ce001eSMatthew G. Knepley fvm->ops->destroy = PetscFVDestroy_Upwind; 1853c0ce001eSMatthew G. Knepley fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_Upwind; 1854c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1855c0ce001eSMatthew G. Knepley } 1856c0ce001eSMatthew G. Knepley 1857c0ce001eSMatthew G. Knepley /*MC 1858c0ce001eSMatthew G. Knepley PETSCFVUPWIND = "upwind" - A PetscFV object 1859c0ce001eSMatthew G. Knepley 1860c0ce001eSMatthew G. Knepley Level: intermediate 1861c0ce001eSMatthew G. Knepley 1862c0ce001eSMatthew G. Knepley .seealso: PetscFVType, PetscFVCreate(), PetscFVSetType() 1863c0ce001eSMatthew G. Knepley M*/ 1864c0ce001eSMatthew G. Knepley 1865c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscFVCreate_Upwind(PetscFV fvm) 1866c0ce001eSMatthew G. Knepley { 1867c0ce001eSMatthew G. Knepley PetscFV_Upwind *b; 1868c0ce001eSMatthew G. Knepley 1869c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1870c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 18719566063dSJacob Faibussowitsch PetscCall(PetscNewLog(fvm,&b)); 1872c0ce001eSMatthew G. Knepley fvm->data = b; 1873c0ce001eSMatthew G. Knepley 18749566063dSJacob Faibussowitsch PetscCall(PetscFVInitialize_Upwind(fvm)); 1875c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1876c0ce001eSMatthew G. Knepley } 1877c0ce001eSMatthew G. Knepley 1878c0ce001eSMatthew G. Knepley #include <petscblaslapack.h> 1879c0ce001eSMatthew G. Knepley 188088f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVDestroy_LeastSquares(PetscFV fvm) 1881c0ce001eSMatthew G. Knepley { 1882c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *) fvm->data; 1883c0ce001eSMatthew G. Knepley 1884c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18859566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject) fvm, "PetscFVLeastSquaresSetMaxFaces_C", NULL)); 18869566063dSJacob Faibussowitsch PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work)); 18879566063dSJacob Faibussowitsch PetscCall(PetscFree(ls)); 1888c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1889c0ce001eSMatthew G. Knepley } 1890c0ce001eSMatthew G. Knepley 189188f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_LeastSquares_Ascii(PetscFV fv, PetscViewer viewer) 1892c0ce001eSMatthew G. Knepley { 1893c0ce001eSMatthew G. Knepley PetscInt Nc, c; 1894c0ce001eSMatthew G. Knepley PetscViewerFormat format; 1895c0ce001eSMatthew G. Knepley 1896c0ce001eSMatthew G. Knepley PetscFunctionBegin; 18979566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fv, &Nc)); 18989566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 18999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Finite Volume with Least Squares Reconstruction:\n")); 19009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " num components: %d\n", Nc)); 1901c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; c++) { 1902c0ce001eSMatthew G. Knepley if (fv->componentNames[c]) { 19039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " component %d: %s\n", c, fv->componentNames[c])); 1904c0ce001eSMatthew G. Knepley } 1905c0ce001eSMatthew G. Knepley } 1906c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1907c0ce001eSMatthew G. Knepley } 1908c0ce001eSMatthew G. Knepley 190988f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_LeastSquares(PetscFV fv, PetscViewer viewer) 1910c0ce001eSMatthew G. Knepley { 1911c0ce001eSMatthew G. Knepley PetscBool iascii; 1912c0ce001eSMatthew G. Knepley 1913c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1914c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1); 1915c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 19169566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 19179566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscFVView_LeastSquares_Ascii(fv, viewer)); 1918c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1919c0ce001eSMatthew G. Knepley } 1920c0ce001eSMatthew G. Knepley 192188f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVSetUp_LeastSquares(PetscFV fvm) 1922c0ce001eSMatthew G. Knepley { 1923c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1924c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1925c0ce001eSMatthew G. Knepley } 1926c0ce001eSMatthew G. Knepley 1927c0ce001eSMatthew G. Knepley /* Overwrites A. Can only handle full-rank problems with m>=n */ 1928c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresPseudoInverse_Static(PetscInt m,PetscInt mstride,PetscInt n,PetscScalar *A,PetscScalar *Ainv,PetscScalar *tau,PetscInt worksize,PetscScalar *work) 1929c0ce001eSMatthew G. Knepley { 1930c0ce001eSMatthew G. Knepley PetscBool debug = PETSC_FALSE; 1931c0ce001eSMatthew G. Knepley PetscBLASInt M,N,K,lda,ldb,ldwork,info; 1932c0ce001eSMatthew G. Knepley PetscScalar *R,*Q,*Aback,Alpha; 1933c0ce001eSMatthew G. Knepley 1934c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1935c0ce001eSMatthew G. Knepley if (debug) { 19369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m*n,&Aback)); 19379566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(Aback,A,m*n)); 1938c0ce001eSMatthew G. Knepley } 1939c0ce001eSMatthew G. Knepley 19409566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m,&M)); 19419566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n,&N)); 19429566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(mstride,&lda)); 19439566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(worksize,&ldwork)); 19449566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 194573cf7048SBarry Smith PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&M,&N,A,&lda,tau,work,&ldwork,&info)); 19469566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 194728b400f6SJacob Faibussowitsch PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"xGEQRF error"); 1948c0ce001eSMatthew G. Knepley R = A; /* Upper triangular part of A now contains R, the rest contains the elementary reflectors */ 1949c0ce001eSMatthew G. Knepley 1950c0ce001eSMatthew G. Knepley /* Extract an explicit representation of Q */ 1951c0ce001eSMatthew G. Knepley Q = Ainv; 19529566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(Q,A,mstride*n)); 1953c0ce001eSMatthew G. Knepley K = N; /* full rank */ 1954c0ce001eSMatthew G. Knepley PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&M,&N,&K,Q,&lda,tau,work,&ldwork,&info)); 195528b400f6SJacob Faibussowitsch PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"xORGQR/xUNGQR error"); 1956c0ce001eSMatthew G. Knepley 1957c0ce001eSMatthew G. Knepley /* Compute A^{-T} = (R^{-1} Q^T)^T = Q R^{-T} */ 1958c0ce001eSMatthew G. Knepley Alpha = 1.0; 1959c0ce001eSMatthew G. Knepley ldb = lda; 1960c0ce001eSMatthew G. Knepley BLAStrsm_("Right","Upper","ConjugateTranspose","NotUnitTriangular",&M,&N,&Alpha,R,&lda,Q,&ldb); 1961c0ce001eSMatthew G. Knepley /* Ainv is Q, overwritten with inverse */ 1962c0ce001eSMatthew G. Knepley 1963c0ce001eSMatthew G. Knepley if (debug) { /* Check that pseudo-inverse worked */ 1964c0ce001eSMatthew G. Knepley PetscScalar Beta = 0.0; 1965c0ce001eSMatthew G. Knepley PetscBLASInt ldc; 1966c0ce001eSMatthew G. Knepley K = N; 1967c0ce001eSMatthew G. Knepley ldc = N; 1968c0ce001eSMatthew G. Knepley BLASgemm_("ConjugateTranspose","Normal",&N,&K,&M,&Alpha,Ainv,&lda,Aback,&ldb,&Beta,work,&ldc); 19699566063dSJacob Faibussowitsch PetscCall(PetscScalarView(n*n,work,PETSC_VIEWER_STDOUT_SELF)); 19709566063dSJacob Faibussowitsch PetscCall(PetscFree(Aback)); 1971c0ce001eSMatthew G. Knepley } 1972c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1973c0ce001eSMatthew G. Knepley } 1974c0ce001eSMatthew G. Knepley 1975c0ce001eSMatthew G. Knepley /* Overwrites A. Can handle degenerate problems and m<n. */ 1976c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresPseudoInverseSVD_Static(PetscInt m,PetscInt mstride,PetscInt n,PetscScalar *A,PetscScalar *Ainv,PetscScalar *tau,PetscInt worksize,PetscScalar *work) 1977c0ce001eSMatthew G. Knepley { 1978c0ce001eSMatthew G. Knepley PetscBool debug = PETSC_FALSE; 1979c0ce001eSMatthew G. Knepley PetscScalar *Brhs, *Aback; 1980c0ce001eSMatthew G. Knepley PetscScalar *tmpwork; 1981c0ce001eSMatthew G. Knepley PetscReal rcond; 1982c0ce001eSMatthew G. Knepley #if defined (PETSC_USE_COMPLEX) 1983c0ce001eSMatthew G. Knepley PetscInt rworkSize; 1984c0ce001eSMatthew G. Knepley PetscReal *rwork; 1985c0ce001eSMatthew G. Knepley #endif 1986c0ce001eSMatthew G. Knepley PetscInt i, j, maxmn; 1987c0ce001eSMatthew G. Knepley PetscBLASInt M, N, lda, ldb, ldwork; 1988c0ce001eSMatthew G. Knepley PetscBLASInt nrhs, irank, info; 1989c0ce001eSMatthew G. Knepley 1990c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1991c0ce001eSMatthew G. Knepley if (debug) { 19929566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m*n,&Aback)); 19939566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(Aback,A,m*n)); 1994c0ce001eSMatthew G. Knepley } 1995c0ce001eSMatthew G. Knepley 1996c0ce001eSMatthew G. Knepley /* initialize to identity */ 1997736d4f42SpierreXVI tmpwork = work; 1998736d4f42SpierreXVI Brhs = Ainv; 1999c0ce001eSMatthew G. Knepley maxmn = PetscMax(m,n); 2000c0ce001eSMatthew G. Knepley for (j=0; j<maxmn; j++) { 2001c0ce001eSMatthew G. Knepley for (i=0; i<maxmn; i++) Brhs[i + j*maxmn] = 1.0*(i == j); 2002c0ce001eSMatthew G. Knepley } 2003c0ce001eSMatthew G. Knepley 20049566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m,&M)); 20059566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n,&N)); 20069566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(mstride,&lda)); 20079566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(maxmn,&ldb)); 20089566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(worksize,&ldwork)); 2009c0ce001eSMatthew G. Knepley rcond = -1; 20109566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 2011c0ce001eSMatthew G. Knepley nrhs = M; 2012c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX) 2013c0ce001eSMatthew G. Knepley rworkSize = 5 * PetscMin(M,N); 20149566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(rworkSize,&rwork)); 201573cf7048SBarry Smith PetscStackCallBLAS("LAPACKgelss",LAPACKgelss_(&M,&N,&nrhs,A,&lda,Brhs,&ldb, (PetscReal *) tau,&rcond,&irank,tmpwork,&ldwork,rwork,&info)); 20169566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 20179566063dSJacob Faibussowitsch PetscCall(PetscFree(rwork)); 2018c0ce001eSMatthew G. Knepley #else 2019c0ce001eSMatthew G. Knepley nrhs = M; 202073cf7048SBarry Smith PetscStackCallBLAS("LAPACKgelss",LAPACKgelss_(&M,&N,&nrhs,A,&lda,Brhs,&ldb, (PetscReal *) tau,&rcond,&irank,tmpwork,&ldwork,&info)); 20219566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 2022c0ce001eSMatthew G. Knepley #endif 202328b400f6SJacob Faibussowitsch PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"xGELSS error"); 2024c0ce001eSMatthew G. Knepley /* The following check should be turned into a diagnostic as soon as someone wants to do this intentionally */ 20252c71b3e2SJacob Faibussowitsch PetscCheckFalse(irank < PetscMin(M,N),PETSC_COMM_SELF,PETSC_ERR_USER,"Rank deficient least squares fit, indicates an isolated cell with two colinear points"); 2026c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2027c0ce001eSMatthew G. Knepley } 2028c0ce001eSMatthew G. Knepley 2029c0ce001eSMatthew G. Knepley #if 0 2030c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresDebugCell_Static(PetscFV fvm, PetscInt cell, DM dm, DM dmFace, PetscScalar *fgeom, DM dmCell, PetscScalar *cgeom) 2031c0ce001eSMatthew G. Knepley { 2032c0ce001eSMatthew G. Knepley PetscReal grad[2] = {0, 0}; 2033c0ce001eSMatthew G. Knepley const PetscInt *faces; 2034c0ce001eSMatthew G. Knepley PetscInt numFaces, f; 2035c0ce001eSMatthew G. Knepley 2036c0ce001eSMatthew G. Knepley PetscFunctionBegin; 20379566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, cell, &numFaces)); 20389566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, cell, &faces)); 2039c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2040c0ce001eSMatthew G. Knepley const PetscInt *fcells; 2041c0ce001eSMatthew G. Knepley const CellGeom *cg1; 2042c0ce001eSMatthew G. Knepley const FaceGeom *fg; 2043c0ce001eSMatthew G. Knepley 20449566063dSJacob Faibussowitsch PetscCall(DMPlexGetSupport(dm, faces[f], &fcells)); 20459566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmFace, faces[f], fgeom, &fg)); 2046c0ce001eSMatthew G. Knepley for (i = 0; i < 2; ++i) { 2047c0ce001eSMatthew G. Knepley PetscScalar du; 2048c0ce001eSMatthew G. Knepley 2049c0ce001eSMatthew G. Knepley if (fcells[i] == c) continue; 20509566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(dmCell, fcells[i], cgeom, &cg1)); 2051c0ce001eSMatthew G. Knepley du = cg1->centroid[0] + 3*cg1->centroid[1] - (cg->centroid[0] + 3*cg->centroid[1]); 2052c0ce001eSMatthew G. Knepley grad[0] += fg->grad[!i][0] * du; 2053c0ce001eSMatthew G. Knepley grad[1] += fg->grad[!i][1] * du; 2054c0ce001eSMatthew G. Knepley } 2055c0ce001eSMatthew G. Knepley } 20569566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "cell[%d] grad (%g, %g)\n", cell, grad[0], grad[1])); 2057c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2058c0ce001eSMatthew G. Knepley } 2059c0ce001eSMatthew G. Knepley #endif 2060c0ce001eSMatthew G. Knepley 2061c0ce001eSMatthew G. Knepley /* 2062c0ce001eSMatthew G. Knepley PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell 2063c0ce001eSMatthew G. Knepley 2064c0ce001eSMatthew G. Knepley Input Parameters: 2065c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 2066c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained 2067c0ce001eSMatthew G. Knepley . dx - The vector from the cell centroid to the neighboring cell centroid for each face 2068c0ce001eSMatthew G. Knepley 2069c0ce001eSMatthew G. Knepley Level: developer 2070c0ce001eSMatthew G. Knepley 2071c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate() 2072c0ce001eSMatthew G. Knepley */ 207388f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVComputeGradient_LeastSquares(PetscFV fvm, PetscInt numFaces, const PetscScalar dx[], PetscScalar grad[]) 2074c0ce001eSMatthew G. Knepley { 2075c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *) fvm->data; 2076c0ce001eSMatthew G. Knepley const PetscBool useSVD = PETSC_TRUE; 2077c0ce001eSMatthew G. Knepley const PetscInt maxFaces = ls->maxFaces; 2078c0ce001eSMatthew G. Knepley PetscInt dim, f, d; 2079c0ce001eSMatthew G. Knepley 2080c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2081c0ce001eSMatthew G. Knepley if (numFaces > maxFaces) { 20822c71b3e2SJacob Faibussowitsch PetscCheckFalse(maxFaces < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Reconstruction has not been initialized, call PetscFVLeastSquaresSetMaxFaces()"); 208398921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of input faces %D > %D maxfaces", numFaces, maxFaces); 2084c0ce001eSMatthew G. Knepley } 20859566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 2086c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2087c0ce001eSMatthew G. Knepley for (d = 0; d < dim; ++d) ls->B[d*maxFaces+f] = dx[f*dim+d]; 2088c0ce001eSMatthew G. Knepley } 2089c0ce001eSMatthew G. Knepley /* Overwrites B with garbage, returns Binv in row-major format */ 2090736d4f42SpierreXVI if (useSVD) { 2091736d4f42SpierreXVI PetscInt maxmn = PetscMax(numFaces, dim); 20929566063dSJacob Faibussowitsch PetscCall(PetscFVLeastSquaresPseudoInverseSVD_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work)); 2093736d4f42SpierreXVI /* Binv shaped in column-major, coldim=maxmn.*/ 2094736d4f42SpierreXVI for (f = 0; f < numFaces; ++f) { 2095736d4f42SpierreXVI for (d = 0; d < dim; ++d) grad[f*dim+d] = ls->Binv[d + maxmn*f]; 2096736d4f42SpierreXVI } 2097736d4f42SpierreXVI } else { 20989566063dSJacob Faibussowitsch PetscCall(PetscFVLeastSquaresPseudoInverse_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work)); 2099736d4f42SpierreXVI /* Binv shaped in row-major, rowdim=maxFaces.*/ 2100c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2101c0ce001eSMatthew G. Knepley for (d = 0; d < dim; ++d) grad[f*dim+d] = ls->Binv[d*maxFaces + f]; 2102c0ce001eSMatthew G. Knepley } 2103736d4f42SpierreXVI } 2104c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2105c0ce001eSMatthew G. Knepley } 2106c0ce001eSMatthew G. Knepley 2107c0ce001eSMatthew G. Knepley /* 2108c0ce001eSMatthew G. Knepley neighborVol[f*2+0] contains the left geom 2109c0ce001eSMatthew G. Knepley neighborVol[f*2+1] contains the right geom 2110c0ce001eSMatthew G. Knepley */ 211188f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVIntegrateRHSFunction_LeastSquares(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, 2112c0ce001eSMatthew G. Knepley PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) 2113c0ce001eSMatthew G. Knepley { 2114c0ce001eSMatthew G. Knepley void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *); 2115c0ce001eSMatthew G. Knepley void *rctx; 2116c0ce001eSMatthew G. Knepley PetscScalar *flux = fvm->fluxWork; 2117c0ce001eSMatthew G. Knepley const PetscScalar *constants; 2118c0ce001eSMatthew G. Knepley PetscInt dim, numConstants, pdim, Nc, totDim, off, f, d; 2119c0ce001eSMatthew G. Knepley 2120c0ce001eSMatthew G. Knepley PetscFunctionBegin; 21219566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalComponents(prob, &Nc)); 21229566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalDimension(prob, &totDim)); 21239566063dSJacob Faibussowitsch PetscCall(PetscDSGetFieldOffset(prob, field, &off)); 21249566063dSJacob Faibussowitsch PetscCall(PetscDSGetRiemannSolver(prob, field, &riemann)); 21259566063dSJacob Faibussowitsch PetscCall(PetscDSGetContext(prob, field, &rctx)); 21269566063dSJacob Faibussowitsch PetscCall(PetscDSGetConstants(prob, &numConstants, &constants)); 21279566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 21289566063dSJacob Faibussowitsch PetscCall(PetscFVGetNumComponents(fvm, &pdim)); 2129c0ce001eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2130c0ce001eSMatthew G. Knepley (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f*Nc], &uR[f*Nc], numConstants, constants, flux, rctx); 2131c0ce001eSMatthew G. Knepley for (d = 0; d < pdim; ++d) { 2132c0ce001eSMatthew G. Knepley fluxL[f*totDim+off+d] = flux[d] / neighborVol[f*2+0]; 2133c0ce001eSMatthew G. Knepley fluxR[f*totDim+off+d] = flux[d] / neighborVol[f*2+1]; 2134c0ce001eSMatthew G. Knepley } 2135c0ce001eSMatthew G. Knepley } 2136c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2137c0ce001eSMatthew G. Knepley } 2138c0ce001eSMatthew G. Knepley 2139c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresSetMaxFaces_LS(PetscFV fvm, PetscInt maxFaces) 2140c0ce001eSMatthew G. Knepley { 2141c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *) fvm->data; 2142736d4f42SpierreXVI PetscInt dim,m,n,nrhs,minmn,maxmn; 2143c0ce001eSMatthew G. Knepley 2144c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2145c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 21469566063dSJacob Faibussowitsch PetscCall(PetscFVGetSpatialDimension(fvm, &dim)); 21479566063dSJacob Faibussowitsch PetscCall(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work)); 2148c0ce001eSMatthew G. Knepley ls->maxFaces = maxFaces; 2149c0ce001eSMatthew G. Knepley m = ls->maxFaces; 2150c0ce001eSMatthew G. Knepley n = dim; 2151c0ce001eSMatthew G. Knepley nrhs = ls->maxFaces; 2152736d4f42SpierreXVI minmn = PetscMin(m,n); 2153736d4f42SpierreXVI maxmn = PetscMax(m,n); 2154736d4f42SpierreXVI ls->workSize = 3*minmn + PetscMax(2*minmn, PetscMax(maxmn, nrhs)); /* required by LAPACK */ 21559566063dSJacob Faibussowitsch PetscCall(PetscMalloc4(m*n,&ls->B,maxmn*maxmn,&ls->Binv,minmn,&ls->tau,ls->workSize,&ls->work)); 2156c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2157c0ce001eSMatthew G. Knepley } 2158c0ce001eSMatthew G. Knepley 2159c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVInitialize_LeastSquares(PetscFV fvm) 2160c0ce001eSMatthew G. Knepley { 2161c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2162c0ce001eSMatthew G. Knepley fvm->ops->setfromoptions = NULL; 2163c0ce001eSMatthew G. Knepley fvm->ops->setup = PetscFVSetUp_LeastSquares; 2164c0ce001eSMatthew G. Knepley fvm->ops->view = PetscFVView_LeastSquares; 2165c0ce001eSMatthew G. Knepley fvm->ops->destroy = PetscFVDestroy_LeastSquares; 2166c0ce001eSMatthew G. Knepley fvm->ops->computegradient = PetscFVComputeGradient_LeastSquares; 2167c0ce001eSMatthew G. Knepley fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_LeastSquares; 2168c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2169c0ce001eSMatthew G. Knepley } 2170c0ce001eSMatthew G. Knepley 2171c0ce001eSMatthew G. Knepley /*MC 2172c0ce001eSMatthew G. Knepley PETSCFVLEASTSQUARES = "leastsquares" - A PetscFV object 2173c0ce001eSMatthew G. Knepley 2174c0ce001eSMatthew G. Knepley Level: intermediate 2175c0ce001eSMatthew G. Knepley 2176c0ce001eSMatthew G. Knepley .seealso: PetscFVType, PetscFVCreate(), PetscFVSetType() 2177c0ce001eSMatthew G. Knepley M*/ 2178c0ce001eSMatthew G. Knepley 2179c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscFVCreate_LeastSquares(PetscFV fvm) 2180c0ce001eSMatthew G. Knepley { 2181c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls; 2182c0ce001eSMatthew G. Knepley 2183c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2184c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 21859566063dSJacob Faibussowitsch PetscCall(PetscNewLog(fvm, &ls)); 2186c0ce001eSMatthew G. Knepley fvm->data = ls; 2187c0ce001eSMatthew G. Knepley 2188c0ce001eSMatthew G. Knepley ls->maxFaces = -1; 2189c0ce001eSMatthew G. Knepley ls->workSize = -1; 2190c0ce001eSMatthew G. Knepley ls->B = NULL; 2191c0ce001eSMatthew G. Knepley ls->Binv = NULL; 2192c0ce001eSMatthew G. Knepley ls->tau = NULL; 2193c0ce001eSMatthew G. Knepley ls->work = NULL; 2194c0ce001eSMatthew G. Knepley 21959566063dSJacob Faibussowitsch PetscCall(PetscFVSetComputeGradients(fvm, PETSC_TRUE)); 21969566063dSJacob Faibussowitsch PetscCall(PetscFVInitialize_LeastSquares(fvm)); 21979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject) fvm, "PetscFVLeastSquaresSetMaxFaces_C", PetscFVLeastSquaresSetMaxFaces_LS)); 2198c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2199c0ce001eSMatthew G. Knepley } 2200c0ce001eSMatthew G. Knepley 2201c0ce001eSMatthew G. Knepley /*@ 2202c0ce001eSMatthew G. Knepley PetscFVLeastSquaresSetMaxFaces - Set the maximum number of cell faces for gradient reconstruction 2203c0ce001eSMatthew G. Knepley 2204c0ce001eSMatthew G. Knepley Not collective 2205c0ce001eSMatthew G. Knepley 2206c0ce001eSMatthew G. Knepley Input parameters: 2207c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 2208c0ce001eSMatthew G. Knepley - maxFaces - The maximum number of cell faces 2209c0ce001eSMatthew G. Knepley 2210c0ce001eSMatthew G. Knepley Level: intermediate 2211c0ce001eSMatthew G. Knepley 2212c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate(), PETSCFVLEASTSQUARES 2213c0ce001eSMatthew G. Knepley @*/ 2214c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVLeastSquaresSetMaxFaces(PetscFV fvm, PetscInt maxFaces) 2215c0ce001eSMatthew G. Knepley { 2216c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2217c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 2218*cac4c232SBarry Smith PetscTryMethod(fvm, "PetscFVLeastSquaresSetMaxFaces_C", (PetscFV,PetscInt), (fvm,maxFaces)); 2219c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2220c0ce001eSMatthew G. Knepley } 2221