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; 545f80ce2aSJacob Faibussowitsch CHKERRQ(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); 815f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject) lim, name, &match)); 82c0ce001eSMatthew G. Knepley if (match) PetscFunctionReturn(0); 83c0ce001eSMatthew G. Knepley 845f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLimiterRegisterAll()); 855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFunctionListFind(PetscLimiterList, name, &r)); 86*28b400f6SJacob 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) { 895f80ce2aSJacob Faibussowitsch CHKERRQ((*lim->ops->destroy)(lim)); 90c0ce001eSMatthew G. Knepley lim->ops->destroy = NULL; 91c0ce001eSMatthew G. Knepley } 925f80ce2aSJacob Faibussowitsch CHKERRQ((*r)(lim)); 935f80ce2aSJacob Faibussowitsch CHKERRQ(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); 1175f80ce2aSJacob Faibussowitsch CHKERRQ(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); 1395f80ce2aSJacob Faibussowitsch CHKERRQ(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); 1605f80ce2aSJacob Faibussowitsch if (!v) CHKERRQ(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) lim), &v)); 1615f80ce2aSJacob Faibussowitsch if (lim->ops->view) CHKERRQ((*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; 1885f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLimiterRegisterAll()); 189c0ce001eSMatthew G. Knepley 190c0ce001eSMatthew G. Knepley ierr = PetscObjectOptionsBegin((PetscObject) lim);CHKERRQ(ierr); 1915f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsFList("-petsclimiter_type", "Finite volume slope limiter", "PetscLimiterSetType", PetscLimiterList, defaultType, name, 256, &flg)); 192c0ce001eSMatthew G. Knepley if (flg) { 1935f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLimiterSetType(lim, name)); 194c0ce001eSMatthew G. Knepley } else if (!((PetscObject) lim)->type_name) { 1955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLimiterSetType(lim, defaultType)); 196c0ce001eSMatthew G. Knepley } 1975f80ce2aSJacob Faibussowitsch if (lim->ops->setfromoptions) CHKERRQ((*lim->ops->setfromoptions)(lim)); 198c0ce001eSMatthew G. Knepley /* process any options handlers added with PetscObjectAddOptionsHandler() */ 1995f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) lim)); 200c0ce001eSMatthew G. Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 2015f80ce2aSJacob Faibussowitsch CHKERRQ(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); 2215f80ce2aSJacob Faibussowitsch if (lim->ops->setup) CHKERRQ((*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 2465f80ce2aSJacob Faibussowitsch if ((*lim)->ops->destroy) CHKERRQ((*(*lim)->ops->destroy)(*lim)); 2475f80ce2aSJacob Faibussowitsch CHKERRQ(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); 2725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCitationsRegister(LimiterCitation,&Limitercite)); 273c0ce001eSMatthew G. Knepley *lim = NULL; 2745f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVInitializePackage()); 275c0ce001eSMatthew G. Knepley 2765f80ce2aSJacob Faibussowitsch CHKERRQ(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); 334c0ce001eSMatthew G. Knepley PetscValidPointer(phi, 3); 3355f80ce2aSJacob Faibussowitsch CHKERRQ((*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; 3445f80ce2aSJacob Faibussowitsch CHKERRQ(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; 3535f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerGetFormat(viewer, &format)); 3545f80ce2aSJacob Faibussowitsch CHKERRQ(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); 3655f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 3665f80ce2aSJacob Faibussowitsch if (iascii) CHKERRQ(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); 4005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNewLog(lim, &l)); 401c0ce001eSMatthew G. Knepley lim->data = l; 402c0ce001eSMatthew G. Knepley 4035f80ce2aSJacob Faibussowitsch CHKERRQ(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; 4125f80ce2aSJacob Faibussowitsch CHKERRQ(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; 4215f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerGetFormat(viewer, &format)); 4225f80ce2aSJacob Faibussowitsch CHKERRQ(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); 4335f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 4345f80ce2aSJacob Faibussowitsch if (iascii) CHKERRQ(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); 4685f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNewLog(lim, &l)); 469c0ce001eSMatthew G. Knepley lim->data = l; 470c0ce001eSMatthew G. Knepley 4715f80ce2aSJacob Faibussowitsch CHKERRQ(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; 4805f80ce2aSJacob Faibussowitsch CHKERRQ(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; 4895f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerGetFormat(viewer, &format)); 4905f80ce2aSJacob Faibussowitsch CHKERRQ(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); 5015f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 5025f80ce2aSJacob Faibussowitsch if (iascii) CHKERRQ(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); 5365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNewLog(lim, &l)); 537c0ce001eSMatthew G. Knepley lim->data = l; 538c0ce001eSMatthew G. Knepley 5395f80ce2aSJacob Faibussowitsch CHKERRQ(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; 5485f80ce2aSJacob Faibussowitsch CHKERRQ(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; 5575f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerGetFormat(viewer, &format)); 5585f80ce2aSJacob Faibussowitsch CHKERRQ(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); 5695f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 5705f80ce2aSJacob Faibussowitsch if (iascii) CHKERRQ(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); 6045f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNewLog(lim, &l)); 605c0ce001eSMatthew G. Knepley lim->data = l; 606c0ce001eSMatthew G. Knepley 6075f80ce2aSJacob Faibussowitsch CHKERRQ(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; 6165f80ce2aSJacob Faibussowitsch CHKERRQ(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; 6255f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerGetFormat(viewer, &format)); 6265f80ce2aSJacob Faibussowitsch CHKERRQ(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); 6375f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 6385f80ce2aSJacob Faibussowitsch if (iascii) CHKERRQ(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); 6725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNewLog(lim, &l)); 673c0ce001eSMatthew G. Knepley lim->data = l; 674c0ce001eSMatthew G. Knepley 6755f80ce2aSJacob Faibussowitsch CHKERRQ(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; 6845f80ce2aSJacob Faibussowitsch CHKERRQ(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; 6935f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerGetFormat(viewer, &format)); 6945f80ce2aSJacob Faibussowitsch CHKERRQ(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); 7055f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 7065f80ce2aSJacob Faibussowitsch if (iascii) CHKERRQ(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); 7405f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNewLog(lim, &l)); 741c0ce001eSMatthew G. Knepley lim->data = l; 742c0ce001eSMatthew G. Knepley 7435f80ce2aSJacob Faibussowitsch CHKERRQ(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; 7525f80ce2aSJacob Faibussowitsch CHKERRQ(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; 7615f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerGetFormat(viewer, &format)); 7625f80ce2aSJacob Faibussowitsch CHKERRQ(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); 7735f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 7745f80ce2aSJacob Faibussowitsch if (iascii) CHKERRQ(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); 8085f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNewLog(lim, &l)); 809c0ce001eSMatthew G. Knepley lim->data = l; 810c0ce001eSMatthew G. Knepley 8115f80ce2aSJacob Faibussowitsch CHKERRQ(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; 8205f80ce2aSJacob Faibussowitsch CHKERRQ(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; 8295f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerGetFormat(viewer, &format)); 8305f80ce2aSJacob Faibussowitsch CHKERRQ(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); 8415f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 8425f80ce2aSJacob Faibussowitsch if (iascii) CHKERRQ(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); 8775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNewLog(lim, &l)); 878c0ce001eSMatthew G. Knepley lim->data = l; 879c0ce001eSMatthew G. Knepley 8805f80ce2aSJacob Faibussowitsch CHKERRQ(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; 9245f80ce2aSJacob Faibussowitsch CHKERRQ(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); 9515f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject) fvm, name, &match)); 952c0ce001eSMatthew G. Knepley if (match) PetscFunctionReturn(0); 953c0ce001eSMatthew G. Knepley 9545f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVRegisterAll()); 9555f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFunctionListFind(PetscFVList, name, &r)); 956*28b400f6SJacob 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) { 9595f80ce2aSJacob Faibussowitsch CHKERRQ((*fvm->ops->destroy)(fvm)); 960c0ce001eSMatthew G. Knepley fvm->ops->destroy = NULL; 961c0ce001eSMatthew G. Knepley } 9625f80ce2aSJacob Faibussowitsch CHKERRQ((*r)(fvm)); 9635f80ce2aSJacob Faibussowitsch CHKERRQ(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); 9875f80ce2aSJacob Faibussowitsch CHKERRQ(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); 10095f80ce2aSJacob Faibussowitsch CHKERRQ(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); 10305f80ce2aSJacob Faibussowitsch if (!v) CHKERRQ(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) fvm), &v)); 10315f80ce2aSJacob Faibussowitsch if (fvm->ops->view) CHKERRQ((*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; 10615f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVRegisterAll()); 1062c0ce001eSMatthew G. Knepley 1063c0ce001eSMatthew G. Knepley ierr = PetscObjectOptionsBegin((PetscObject) fvm);CHKERRQ(ierr); 10645f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsFList("-petscfv_type", "Finite volume discretization", "PetscFVSetType", PetscFVList, defaultType, name, 256, &flg)); 1065c0ce001eSMatthew G. Knepley if (flg) { 10665f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVSetType(fvm, name)); 1067c0ce001eSMatthew G. Knepley } else if (!((PetscObject) fvm)->type_name) { 10685f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVSetType(fvm, defaultType)); 1069c0ce001eSMatthew G. Knepley 1070c0ce001eSMatthew G. Knepley } 10715f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsBool("-petscfv_compute_gradients", "Compute cell gradients", "PetscFVSetComputeGradients", fvm->computeGradients, &fvm->computeGradients, NULL)); 10725f80ce2aSJacob Faibussowitsch if (fvm->ops->setfromoptions) CHKERRQ((*fvm->ops->setfromoptions)(fvm)); 1073c0ce001eSMatthew G. Knepley /* process any options handlers added with PetscObjectAddOptionsHandler() */ 10745f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) fvm)); 10755f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLimiterSetFromOptions(fvm->limiter)); 1076c0ce001eSMatthew G. Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 10775f80ce2aSJacob Faibussowitsch CHKERRQ(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); 10975f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLimiterSetUp(fvm->limiter)); 10985f80ce2aSJacob Faibussowitsch if (fvm->ops->setup) CHKERRQ((*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++) { 11265f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree((*fvm)->componentNames[i])); 1127c0ce001eSMatthew G. Knepley } 11285f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree((*fvm)->componentNames)); 11295f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLimiterDestroy(&(*fvm)->limiter)); 11305f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceDestroy(&(*fvm)->dualSpace)); 11315f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree((*fvm)->fluxWork)); 11325f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&(*fvm)->quadrature)); 11335f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTabulationDestroy(&(*fvm)->T)); 1134c0ce001eSMatthew G. Knepley 11355f80ce2aSJacob Faibussowitsch if ((*fvm)->ops->destroy) CHKERRQ((*(*fvm)->ops->destroy)(*fvm)); 11365f80ce2aSJacob Faibussowitsch CHKERRQ(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; 11625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVInitializePackage()); 1163c0ce001eSMatthew G. Knepley 11645f80ce2aSJacob Faibussowitsch CHKERRQ(PetscHeaderCreate(f, PETSCFV_CLASSID, "PetscFV", "Finite Volume", "PetscFV", comm, PetscFVDestroy, PetscFVView)); 11655f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemzero(f->ops, sizeof(struct _PetscFVOps))); 1166c0ce001eSMatthew G. Knepley 11675f80ce2aSJacob Faibussowitsch CHKERRQ(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; 11725f80ce2aSJacob Faibussowitsch CHKERRQ(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); 11965f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLimiterDestroy(&fvm->limiter)); 11975f80ce2aSJacob Faibussowitsch CHKERRQ(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++) { 12475f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(fvm->componentNames[i])); 1248c0ce001eSMatthew G. Knepley } 12495f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(fvm->componentNames)); 12505f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(comp,&fvm->componentNames)); 1251c0ce001eSMatthew G. Knepley } 1252c0ce001eSMatthew G. Knepley fvm->numComponents = comp; 12535f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(fvm->fluxWork)); 12545f80ce2aSJacob Faibussowitsch CHKERRQ(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); 1277c0ce001eSMatthew G. Knepley PetscValidPointer(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; 12985f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(fvm->componentNames[comp])); 12995f80ce2aSJacob Faibussowitsch CHKERRQ(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); 1365c0ce001eSMatthew G. Knepley PetscValidPointer(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); 1410c0ce001eSMatthew G. Knepley PetscValidPointer(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); 14325f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&fvm->quadrature)); 14335f80ce2aSJacob Faibussowitsch CHKERRQ(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 14625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureCreate(PETSC_COMM_SELF, &fvm->quadrature)); 14635f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(fvm->dim, &points)); 14645f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(1, &weights)); 1465c0ce001eSMatthew G. Knepley weights[0] = 1.0; 14665f80ce2aSJacob Faibussowitsch CHKERRQ(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 14985f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVGetSpatialDimension(fvm, &dim)); 14995f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVGetNumComponents(fvm, &Nc)); 15005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceCreate(PetscObjectComm((PetscObject) fvm), &fvm->dualSpace)); 15015f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceSetType(fvm->dualSpace, PETSCDUALSPACESIMPLE)); 15025f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexCreateReferenceCell(PETSC_COMM_SELF, DMPolytopeTypeSimpleShape(dim, PETSC_FALSE), &K)); 15035f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceSetNumComponents(fvm->dualSpace, Nc)); 15045f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceSetDM(fvm->dualSpace, K)); 15055f80ce2aSJacob Faibussowitsch CHKERRQ(DMDestroy(&K)); 15065f80ce2aSJacob Faibussowitsch CHKERRQ(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 15125f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureCreate(PETSC_COMM_SELF, &qc)); 15135f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(dim, &points)); 15145f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(Nc, &weights)); 1515c0ce001eSMatthew G. Knepley weights[c] = 1.0; 15165f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureSetData(qc, dim, Nc, 1, points, weights)); 15175f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceSimpleSetFunctional(fvm->dualSpace, c, qc)); 15185f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&qc)); 1519c0ce001eSMatthew G. Knepley } 15205f80ce2aSJacob Faibussowitsch CHKERRQ(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); 15465f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceDestroy(&fvm->dualSpace)); 1547c0ce001eSMatthew G. Knepley fvm->dualSpace = sp; 15485f80ce2aSJacob Faibussowitsch CHKERRQ(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); 15805f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(fvm->quadrature, NULL, NULL, &npoints, &points, NULL)); 15815f80ce2aSJacob Faibussowitsch if (!fvm->T) CHKERRQ(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); 162340a2aa30SMatthew G. Knepley PetscValidPointer(points, 4); 162440a2aa30SMatthew G. Knepley PetscValidPointer(T, 6); 16255f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVGetSpatialDimension(fvm, &cdim)); 16265f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVGetNumComponents(fvm, &Nc)); 16275f80ce2aSJacob Faibussowitsch CHKERRQ(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; 16345f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1((*T)->K+1, &(*T)->T)); 1635ef0bb6c7SMatthew G. Knepley for (k = 0; k <= (*T)->K; ++k) { 16365f80ce2aSJacob Faibussowitsch CHKERRQ(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); 16605f80ce2aSJacob Faibussowitsch if (fvm->ops->computegradient) CHKERRQ((*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); 16925f80ce2aSJacob Faibussowitsch if (fvm->ops->integraterhsfunction) CHKERRQ((*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; 17235f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVGetDualSpace(fv, &Q)); 17245f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVGetQuadrature(fv, &q)); 17255f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDM(Q, &K)); 1726c0ce001eSMatthew G. Knepley /* Create dual space */ 17275f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceDuplicate(Q, &Qref)); 17285f80ce2aSJacob Faibussowitsch CHKERRQ(DMRefine(K, PetscObjectComm((PetscObject) fv), &Kref)); 17295f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceSetDM(Qref, Kref)); 17305f80ce2aSJacob Faibussowitsch CHKERRQ(DMDestroy(&Kref)); 17315f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceSetUp(Qref)); 1732c0ce001eSMatthew G. Knepley /* Create volume */ 17335f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVCreate(PetscObjectComm((PetscObject) fv), fvRef)); 17345f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVSetDualSpace(*fvRef, Qref)); 17355f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVGetNumComponents(fv, &numComp)); 17365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVSetNumComponents(*fvRef, numComp)); 17375f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVSetUp(*fvRef)); 1738c0ce001eSMatthew G. Knepley /* Create quadrature */ 17395f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetCellType(K, 0, &ct)); 17405f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexTransformCreate(PETSC_COMM_SELF, &tr)); 17415f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR)); 17425f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexRefineRegularGetAffineTransforms(tr, ct, &numSubelements, &v0, &jac, &invjac)); 17435f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref)); 17445f80ce2aSJacob Faibussowitsch CHKERRQ(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 17515f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureCreate(PETSC_COMM_SELF, &qs)); 17525f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(q, &dim, &Nc, &npoints, &points, &weights)); 1753c0ce001eSMatthew G. Knepley np = npoints/numSubelements; 17545f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(np*dim,&p)); 17555f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(np*Nc,&w)); 17565f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(p, &points[s*np*dim], np*dim)); 17575f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(w, &weights[s*np*Nc], np*Nc)); 17585f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureSetData(qs, dim, Nc, np, p, w)); 17595f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceSimpleSetFunctional(Qref, s, qs)); 17605f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&qs)); 1761c0ce001eSMatthew G. Knepley } 17625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVSetQuadrature(*fvRef, qref)); 17635f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexTransformDestroy(&tr)); 17645f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&qref)); 17655f80ce2aSJacob Faibussowitsch CHKERRQ(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; 17745f80ce2aSJacob Faibussowitsch CHKERRQ(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; 17845f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVGetNumComponents(fv, &Nc)); 17855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerGetFormat(viewer, &format)); 17865f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer, "Upwind Finite Volume:\n")); 17875f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer, " num components: %d\n", Nc)); 1788c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; c++) { 1789c0ce001eSMatthew G. Knepley if (fv->componentNames[c]) { 17905f80ce2aSJacob Faibussowitsch CHKERRQ(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); 18035f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 18045f80ce2aSJacob Faibussowitsch if (iascii) CHKERRQ(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; 18285f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalComponents(prob, &Nc)); 18295f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(prob, &totDim)); 18305f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetFieldOffset(prob, field, &off)); 18315f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetRiemannSolver(prob, field, &riemann)); 18325f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetContext(prob, field, &rctx)); 18335f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetConstants(prob, &numConstants, &constants)); 18345f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVGetSpatialDimension(fvm, &dim)); 18355f80ce2aSJacob Faibussowitsch CHKERRQ(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); 18715f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNewLog(fvm,&b)); 1872c0ce001eSMatthew G. Knepley fvm->data = b; 1873c0ce001eSMatthew G. Knepley 18745f80ce2aSJacob Faibussowitsch CHKERRQ(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; 18855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject) fvm, "PetscFVLeastSquaresSetMaxFaces_C", NULL)); 18865f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work)); 18875f80ce2aSJacob Faibussowitsch CHKERRQ(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; 18975f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVGetNumComponents(fv, &Nc)); 18985f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerGetFormat(viewer, &format)); 18995f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer, "Finite Volume with Least Squares Reconstruction:\n")); 19005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer, " num components: %d\n", Nc)); 1901c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; c++) { 1902c0ce001eSMatthew G. Knepley if (fv->componentNames[c]) { 19035f80ce2aSJacob Faibussowitsch CHKERRQ(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); 19165f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 19175f80ce2aSJacob Faibussowitsch if (iascii) CHKERRQ(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) { 19365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(m*n,&Aback)); 19375f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(Aback,A,m*n)); 1938c0ce001eSMatthew G. Knepley } 1939c0ce001eSMatthew G. Knepley 19405f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBLASIntCast(m,&M)); 19415f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBLASIntCast(n,&N)); 19425f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBLASIntCast(mstride,&lda)); 19435f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBLASIntCast(worksize,&ldwork)); 19445f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 194573cf7048SBarry Smith PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&M,&N,A,&lda,tau,work,&ldwork,&info)); 19465f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFPTrapPop()); 1947*28b400f6SJacob 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; 19525f80ce2aSJacob Faibussowitsch CHKERRQ(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)); 1955*28b400f6SJacob 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); 19695f80ce2aSJacob Faibussowitsch CHKERRQ(PetscScalarView(n*n,work,PETSC_VIEWER_STDOUT_SELF)); 19705f80ce2aSJacob Faibussowitsch CHKERRQ(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) { 19925f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(m*n,&Aback)); 19935f80ce2aSJacob Faibussowitsch CHKERRQ(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 20045f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBLASIntCast(m,&M)); 20055f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBLASIntCast(n,&N)); 20065f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBLASIntCast(mstride,&lda)); 20075f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBLASIntCast(maxmn,&ldb)); 20085f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBLASIntCast(worksize,&ldwork)); 2009c0ce001eSMatthew G. Knepley rcond = -1; 20105f80ce2aSJacob Faibussowitsch CHKERRQ(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); 20145f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(rworkSize,&rwork)); 201573cf7048SBarry Smith PetscStackCallBLAS("LAPACKgelss",LAPACKgelss_(&M,&N,&nrhs,A,&lda,Brhs,&ldb, (PetscReal *) tau,&rcond,&irank,tmpwork,&ldwork,rwork,&info)); 20165f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFPTrapPop()); 20175f80ce2aSJacob Faibussowitsch CHKERRQ(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)); 20215f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFPTrapPop()); 2022c0ce001eSMatthew G. Knepley #endif 2023*28b400f6SJacob 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 PetscErrorCode ierr; 2036c0ce001eSMatthew G. Knepley 2037c0ce001eSMatthew G. Knepley PetscFunctionBegin; 20385f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetConeSize(dm, cell, &numFaces)); 20395f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetCone(dm, cell, &faces)); 2040c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2041c0ce001eSMatthew G. Knepley const PetscInt *fcells; 2042c0ce001eSMatthew G. Knepley const CellGeom *cg1; 2043c0ce001eSMatthew G. Knepley const FaceGeom *fg; 2044c0ce001eSMatthew G. Knepley 20455f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetSupport(dm, faces[f], &fcells)); 20465f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexPointLocalRead(dmFace, faces[f], fgeom, &fg)); 2047c0ce001eSMatthew G. Knepley for (i = 0; i < 2; ++i) { 2048c0ce001eSMatthew G. Knepley PetscScalar du; 2049c0ce001eSMatthew G. Knepley 2050c0ce001eSMatthew G. Knepley if (fcells[i] == c) continue; 20515f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexPointLocalRead(dmCell, fcells[i], cgeom, &cg1)); 2052c0ce001eSMatthew G. Knepley du = cg1->centroid[0] + 3*cg1->centroid[1] - (cg->centroid[0] + 3*cg->centroid[1]); 2053c0ce001eSMatthew G. Knepley grad[0] += fg->grad[!i][0] * du; 2054c0ce001eSMatthew G. Knepley grad[1] += fg->grad[!i][1] * du; 2055c0ce001eSMatthew G. Knepley } 2056c0ce001eSMatthew G. Knepley } 20575f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, "cell[%d] grad (%g, %g)\n", cell, grad[0], grad[1])); 2058c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2059c0ce001eSMatthew G. Knepley } 2060c0ce001eSMatthew G. Knepley #endif 2061c0ce001eSMatthew G. Knepley 2062c0ce001eSMatthew G. Knepley /* 2063c0ce001eSMatthew G. Knepley PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell 2064c0ce001eSMatthew G. Knepley 2065c0ce001eSMatthew G. Knepley Input Parameters: 2066c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 2067c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained 2068c0ce001eSMatthew G. Knepley . dx - The vector from the cell centroid to the neighboring cell centroid for each face 2069c0ce001eSMatthew G. Knepley 2070c0ce001eSMatthew G. Knepley Level: developer 2071c0ce001eSMatthew G. Knepley 2072c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate() 2073c0ce001eSMatthew G. Knepley */ 207488f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVComputeGradient_LeastSquares(PetscFV fvm, PetscInt numFaces, const PetscScalar dx[], PetscScalar grad[]) 2075c0ce001eSMatthew G. Knepley { 2076c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *) fvm->data; 2077c0ce001eSMatthew G. Knepley const PetscBool useSVD = PETSC_TRUE; 2078c0ce001eSMatthew G. Knepley const PetscInt maxFaces = ls->maxFaces; 2079c0ce001eSMatthew G. Knepley PetscInt dim, f, d; 2080c0ce001eSMatthew G. Knepley 2081c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2082c0ce001eSMatthew G. Knepley if (numFaces > maxFaces) { 20832c71b3e2SJacob Faibussowitsch PetscCheckFalse(maxFaces < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Reconstruction has not been initialized, call PetscFVLeastSquaresSetMaxFaces()"); 208498921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of input faces %D > %D maxfaces", numFaces, maxFaces); 2085c0ce001eSMatthew G. Knepley } 20865f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVGetSpatialDimension(fvm, &dim)); 2087c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2088c0ce001eSMatthew G. Knepley for (d = 0; d < dim; ++d) ls->B[d*maxFaces+f] = dx[f*dim+d]; 2089c0ce001eSMatthew G. Knepley } 2090c0ce001eSMatthew G. Knepley /* Overwrites B with garbage, returns Binv in row-major format */ 2091736d4f42SpierreXVI if (useSVD) { 2092736d4f42SpierreXVI PetscInt maxmn = PetscMax(numFaces, dim); 20935f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVLeastSquaresPseudoInverseSVD_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work)); 2094736d4f42SpierreXVI /* Binv shaped in column-major, coldim=maxmn.*/ 2095736d4f42SpierreXVI for (f = 0; f < numFaces; ++f) { 2096736d4f42SpierreXVI for (d = 0; d < dim; ++d) grad[f*dim+d] = ls->Binv[d + maxmn*f]; 2097736d4f42SpierreXVI } 2098736d4f42SpierreXVI } else { 20995f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVLeastSquaresPseudoInverse_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work)); 2100736d4f42SpierreXVI /* Binv shaped in row-major, rowdim=maxFaces.*/ 2101c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2102c0ce001eSMatthew G. Knepley for (d = 0; d < dim; ++d) grad[f*dim+d] = ls->Binv[d*maxFaces + f]; 2103c0ce001eSMatthew G. Knepley } 2104736d4f42SpierreXVI } 2105c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2106c0ce001eSMatthew G. Knepley } 2107c0ce001eSMatthew G. Knepley 2108c0ce001eSMatthew G. Knepley /* 2109c0ce001eSMatthew G. Knepley neighborVol[f*2+0] contains the left geom 2110c0ce001eSMatthew G. Knepley neighborVol[f*2+1] contains the right geom 2111c0ce001eSMatthew G. Knepley */ 211288f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVIntegrateRHSFunction_LeastSquares(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, 2113c0ce001eSMatthew G. Knepley PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) 2114c0ce001eSMatthew G. Knepley { 2115c0ce001eSMatthew G. Knepley void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *); 2116c0ce001eSMatthew G. Knepley void *rctx; 2117c0ce001eSMatthew G. Knepley PetscScalar *flux = fvm->fluxWork; 2118c0ce001eSMatthew G. Knepley const PetscScalar *constants; 2119c0ce001eSMatthew G. Knepley PetscInt dim, numConstants, pdim, Nc, totDim, off, f, d; 2120c0ce001eSMatthew G. Knepley 2121c0ce001eSMatthew G. Knepley PetscFunctionBegin; 21225f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalComponents(prob, &Nc)); 21235f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(prob, &totDim)); 21245f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetFieldOffset(prob, field, &off)); 21255f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetRiemannSolver(prob, field, &riemann)); 21265f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetContext(prob, field, &rctx)); 21275f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetConstants(prob, &numConstants, &constants)); 21285f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVGetSpatialDimension(fvm, &dim)); 21295f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVGetNumComponents(fvm, &pdim)); 2130c0ce001eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2131c0ce001eSMatthew G. Knepley (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f*Nc], &uR[f*Nc], numConstants, constants, flux, rctx); 2132c0ce001eSMatthew G. Knepley for (d = 0; d < pdim; ++d) { 2133c0ce001eSMatthew G. Knepley fluxL[f*totDim+off+d] = flux[d] / neighborVol[f*2+0]; 2134c0ce001eSMatthew G. Knepley fluxR[f*totDim+off+d] = flux[d] / neighborVol[f*2+1]; 2135c0ce001eSMatthew G. Knepley } 2136c0ce001eSMatthew G. Knepley } 2137c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2138c0ce001eSMatthew G. Knepley } 2139c0ce001eSMatthew G. Knepley 2140c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresSetMaxFaces_LS(PetscFV fvm, PetscInt maxFaces) 2141c0ce001eSMatthew G. Knepley { 2142c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *) fvm->data; 2143736d4f42SpierreXVI PetscInt dim,m,n,nrhs,minmn,maxmn; 2144c0ce001eSMatthew G. Knepley 2145c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2146c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 21475f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVGetSpatialDimension(fvm, &dim)); 21485f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree4(ls->B, ls->Binv, ls->tau, ls->work)); 2149c0ce001eSMatthew G. Knepley ls->maxFaces = maxFaces; 2150c0ce001eSMatthew G. Knepley m = ls->maxFaces; 2151c0ce001eSMatthew G. Knepley n = dim; 2152c0ce001eSMatthew G. Knepley nrhs = ls->maxFaces; 2153736d4f42SpierreXVI minmn = PetscMin(m,n); 2154736d4f42SpierreXVI maxmn = PetscMax(m,n); 2155736d4f42SpierreXVI ls->workSize = 3*minmn + PetscMax(2*minmn, PetscMax(maxmn, nrhs)); /* required by LAPACK */ 21565f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc4(m*n,&ls->B,maxmn*maxmn,&ls->Binv,minmn,&ls->tau,ls->workSize,&ls->work)); 2157c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2158c0ce001eSMatthew G. Knepley } 2159c0ce001eSMatthew G. Knepley 2160c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVInitialize_LeastSquares(PetscFV fvm) 2161c0ce001eSMatthew G. Knepley { 2162c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2163c0ce001eSMatthew G. Knepley fvm->ops->setfromoptions = NULL; 2164c0ce001eSMatthew G. Knepley fvm->ops->setup = PetscFVSetUp_LeastSquares; 2165c0ce001eSMatthew G. Knepley fvm->ops->view = PetscFVView_LeastSquares; 2166c0ce001eSMatthew G. Knepley fvm->ops->destroy = PetscFVDestroy_LeastSquares; 2167c0ce001eSMatthew G. Knepley fvm->ops->computegradient = PetscFVComputeGradient_LeastSquares; 2168c0ce001eSMatthew G. Knepley fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_LeastSquares; 2169c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2170c0ce001eSMatthew G. Knepley } 2171c0ce001eSMatthew G. Knepley 2172c0ce001eSMatthew G. Knepley /*MC 2173c0ce001eSMatthew G. Knepley PETSCFVLEASTSQUARES = "leastsquares" - A PetscFV object 2174c0ce001eSMatthew G. Knepley 2175c0ce001eSMatthew G. Knepley Level: intermediate 2176c0ce001eSMatthew G. Knepley 2177c0ce001eSMatthew G. Knepley .seealso: PetscFVType, PetscFVCreate(), PetscFVSetType() 2178c0ce001eSMatthew G. Knepley M*/ 2179c0ce001eSMatthew G. Knepley 2180c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscFVCreate_LeastSquares(PetscFV fvm) 2181c0ce001eSMatthew G. Knepley { 2182c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls; 2183c0ce001eSMatthew G. Knepley 2184c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2185c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 21865f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNewLog(fvm, &ls)); 2187c0ce001eSMatthew G. Knepley fvm->data = ls; 2188c0ce001eSMatthew G. Knepley 2189c0ce001eSMatthew G. Knepley ls->maxFaces = -1; 2190c0ce001eSMatthew G. Knepley ls->workSize = -1; 2191c0ce001eSMatthew G. Knepley ls->B = NULL; 2192c0ce001eSMatthew G. Knepley ls->Binv = NULL; 2193c0ce001eSMatthew G. Knepley ls->tau = NULL; 2194c0ce001eSMatthew G. Knepley ls->work = NULL; 2195c0ce001eSMatthew G. Knepley 21965f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVSetComputeGradients(fvm, PETSC_TRUE)); 21975f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVInitialize_LeastSquares(fvm)); 21985f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject) fvm, "PetscFVLeastSquaresSetMaxFaces_C", PetscFVLeastSquaresSetMaxFaces_LS)); 2199c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2200c0ce001eSMatthew G. Knepley } 2201c0ce001eSMatthew G. Knepley 2202c0ce001eSMatthew G. Knepley /*@ 2203c0ce001eSMatthew G. Knepley PetscFVLeastSquaresSetMaxFaces - Set the maximum number of cell faces for gradient reconstruction 2204c0ce001eSMatthew G. Knepley 2205c0ce001eSMatthew G. Knepley Not collective 2206c0ce001eSMatthew G. Knepley 2207c0ce001eSMatthew G. Knepley Input parameters: 2208c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 2209c0ce001eSMatthew G. Knepley - maxFaces - The maximum number of cell faces 2210c0ce001eSMatthew G. Knepley 2211c0ce001eSMatthew G. Knepley Level: intermediate 2212c0ce001eSMatthew G. Knepley 2213c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate(), PETSCFVLEASTSQUARES 2214c0ce001eSMatthew G. Knepley @*/ 2215c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVLeastSquaresSetMaxFaces(PetscFV fvm, PetscInt maxFaces) 2216c0ce001eSMatthew G. Knepley { 2217c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2218c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 22195f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTryMethod(fvm, "PetscFVLeastSquaresSetMaxFaces_C", (PetscFV,PetscInt), (fvm,maxFaces))); 2220c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2221c0ce001eSMatthew G. Knepley } 2222