1c0ce001eSMatthew G. Knepley #include <petsc/private/petscfvimpl.h> /*I "petscfv.h" I*/ 2c0ce001eSMatthew G. Knepley #include <petsc/private/dmpleximpl.h> /* For CellRefiner */ 3c0ce001eSMatthew G. Knepley #include <petscds.h> 4c0ce001eSMatthew G. Knepley 5c0ce001eSMatthew G. Knepley PetscClassId PETSCLIMITER_CLASSID = 0; 6c0ce001eSMatthew G. Knepley 7c0ce001eSMatthew G. Knepley PetscFunctionList PetscLimiterList = NULL; 8c0ce001eSMatthew G. Knepley PetscBool PetscLimiterRegisterAllCalled = PETSC_FALSE; 9c0ce001eSMatthew G. Knepley 10c0ce001eSMatthew G. Knepley PetscBool Limitercite = PETSC_FALSE; 11c0ce001eSMatthew G. Knepley const char LimiterCitation[] = "@article{BergerAftosmisMurman2005,\n" 12c0ce001eSMatthew G. Knepley " title = {Analysis of slope limiters on irregular grids},\n" 13c0ce001eSMatthew G. Knepley " journal = {AIAA paper},\n" 14c0ce001eSMatthew G. Knepley " author = {Marsha Berger and Michael J. Aftosmis and Scott M. Murman},\n" 15c0ce001eSMatthew G. Knepley " volume = {490},\n" 16c0ce001eSMatthew G. Knepley " year = {2005}\n}\n"; 17c0ce001eSMatthew G. Knepley 18c0ce001eSMatthew G. Knepley /*@C 19c0ce001eSMatthew G. Knepley PetscLimiterRegister - Adds a new PetscLimiter implementation 20c0ce001eSMatthew G. Knepley 21c0ce001eSMatthew G. Knepley Not Collective 22c0ce001eSMatthew G. Knepley 23c0ce001eSMatthew G. Knepley Input Parameters: 24c0ce001eSMatthew G. Knepley + name - The name of a new user-defined creation routine 25c0ce001eSMatthew G. Knepley - create_func - The creation routine itself 26c0ce001eSMatthew G. Knepley 27c0ce001eSMatthew G. Knepley Notes: 28c0ce001eSMatthew G. Knepley PetscLimiterRegister() may be called multiple times to add several user-defined PetscLimiters 29c0ce001eSMatthew G. Knepley 30c0ce001eSMatthew G. Knepley Sample usage: 31c0ce001eSMatthew G. Knepley .vb 32c0ce001eSMatthew G. Knepley PetscLimiterRegister("my_lim", MyPetscLimiterCreate); 33c0ce001eSMatthew G. Knepley .ve 34c0ce001eSMatthew G. Knepley 35c0ce001eSMatthew G. Knepley Then, your PetscLimiter type can be chosen with the procedural interface via 36c0ce001eSMatthew G. Knepley .vb 37c0ce001eSMatthew G. Knepley PetscLimiterCreate(MPI_Comm, PetscLimiter *); 38c0ce001eSMatthew G. Knepley PetscLimiterSetType(PetscLimiter, "my_lim"); 39c0ce001eSMatthew G. Knepley .ve 40c0ce001eSMatthew G. Knepley or at runtime via the option 41c0ce001eSMatthew G. Knepley .vb 42c0ce001eSMatthew G. Knepley -petsclimiter_type my_lim 43c0ce001eSMatthew G. Knepley .ve 44c0ce001eSMatthew G. Knepley 45c0ce001eSMatthew G. Knepley Level: advanced 46c0ce001eSMatthew G. Knepley 47c0ce001eSMatthew G. Knepley .seealso: PetscLimiterRegisterAll(), PetscLimiterRegisterDestroy() 48c0ce001eSMatthew G. Knepley 49c0ce001eSMatthew G. Knepley @*/ 50c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterRegister(const char sname[], PetscErrorCode (*function)(PetscLimiter)) 51c0ce001eSMatthew G. Knepley { 52c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 53c0ce001eSMatthew G. Knepley 54c0ce001eSMatthew G. Knepley PetscFunctionBegin; 55c0ce001eSMatthew G. Knepley ierr = PetscFunctionListAdd(&PetscLimiterList, sname, function);CHKERRQ(ierr); 56c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 57c0ce001eSMatthew G. Knepley } 58c0ce001eSMatthew G. Knepley 59c0ce001eSMatthew G. Knepley /*@C 60c0ce001eSMatthew G. Knepley PetscLimiterSetType - Builds a particular PetscLimiter 61c0ce001eSMatthew G. Knepley 62c0ce001eSMatthew G. Knepley Collective on lim 63c0ce001eSMatthew G. Knepley 64c0ce001eSMatthew G. Knepley Input Parameters: 65c0ce001eSMatthew G. Knepley + lim - The PetscLimiter object 66c0ce001eSMatthew G. Knepley - name - The kind of limiter 67c0ce001eSMatthew G. Knepley 68c0ce001eSMatthew G. Knepley Options Database Key: 69c0ce001eSMatthew G. Knepley . -petsclimiter_type <type> - Sets the PetscLimiter type; use -help for a list of available types 70c0ce001eSMatthew G. Knepley 71c0ce001eSMatthew G. Knepley Level: intermediate 72c0ce001eSMatthew G. Knepley 73c0ce001eSMatthew G. Knepley .seealso: PetscLimiterGetType(), PetscLimiterCreate() 74c0ce001eSMatthew G. Knepley @*/ 75c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterSetType(PetscLimiter lim, PetscLimiterType name) 76c0ce001eSMatthew G. Knepley { 77c0ce001eSMatthew G. Knepley PetscErrorCode (*r)(PetscLimiter); 78c0ce001eSMatthew G. Knepley PetscBool match; 79c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 80c0ce001eSMatthew G. Knepley 81c0ce001eSMatthew G. Knepley PetscFunctionBegin; 82c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 83c0ce001eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) lim, name, &match);CHKERRQ(ierr); 84c0ce001eSMatthew G. Knepley if (match) PetscFunctionReturn(0); 85c0ce001eSMatthew G. Knepley 86c0ce001eSMatthew G. Knepley ierr = PetscLimiterRegisterAll();CHKERRQ(ierr); 87c0ce001eSMatthew G. Knepley ierr = PetscFunctionListFind(PetscLimiterList, name, &r);CHKERRQ(ierr); 88c0ce001eSMatthew G. Knepley if (!r) SETERRQ1(PetscObjectComm((PetscObject) lim), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscLimiter type: %s", name); 89c0ce001eSMatthew G. Knepley 90c0ce001eSMatthew G. Knepley if (lim->ops->destroy) { 91c0ce001eSMatthew G. Knepley ierr = (*lim->ops->destroy)(lim);CHKERRQ(ierr); 92c0ce001eSMatthew G. Knepley lim->ops->destroy = NULL; 93c0ce001eSMatthew G. Knepley } 94c0ce001eSMatthew G. Knepley ierr = (*r)(lim);CHKERRQ(ierr); 95c0ce001eSMatthew G. Knepley ierr = PetscObjectChangeTypeName((PetscObject) lim, name);CHKERRQ(ierr); 96c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 97c0ce001eSMatthew G. Knepley } 98c0ce001eSMatthew G. Knepley 99c0ce001eSMatthew G. Knepley /*@C 100c0ce001eSMatthew G. Knepley PetscLimiterGetType - Gets the PetscLimiter type name (as a string) from the object. 101c0ce001eSMatthew G. Knepley 102c0ce001eSMatthew G. Knepley Not Collective 103c0ce001eSMatthew G. Knepley 104c0ce001eSMatthew G. Knepley Input Parameter: 105c0ce001eSMatthew G. Knepley . lim - The PetscLimiter 106c0ce001eSMatthew G. Knepley 107c0ce001eSMatthew G. Knepley Output Parameter: 108c0ce001eSMatthew G. Knepley . name - The PetscLimiter type name 109c0ce001eSMatthew G. Knepley 110c0ce001eSMatthew G. Knepley Level: intermediate 111c0ce001eSMatthew G. Knepley 112c0ce001eSMatthew G. Knepley .seealso: PetscLimiterSetType(), PetscLimiterCreate() 113c0ce001eSMatthew G. Knepley @*/ 114c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterGetType(PetscLimiter lim, PetscLimiterType *name) 115c0ce001eSMatthew G. Knepley { 116c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 117c0ce001eSMatthew G. Knepley 118c0ce001eSMatthew G. Knepley PetscFunctionBegin; 119c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 120c0ce001eSMatthew G. Knepley PetscValidPointer(name, 2); 121c0ce001eSMatthew G. Knepley ierr = PetscLimiterRegisterAll();CHKERRQ(ierr); 122c0ce001eSMatthew G. Knepley *name = ((PetscObject) lim)->type_name; 123c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 124c0ce001eSMatthew G. Knepley } 125c0ce001eSMatthew G. Knepley 126c0ce001eSMatthew G. Knepley /*@C 127c0ce001eSMatthew G. Knepley PetscLimiterView - Views a PetscLimiter 128c0ce001eSMatthew G. Knepley 129c0ce001eSMatthew G. Knepley Collective on lim 130c0ce001eSMatthew G. Knepley 131c0ce001eSMatthew G. Knepley Input Parameter: 132c0ce001eSMatthew G. Knepley + lim - the PetscLimiter object to view 133c0ce001eSMatthew G. Knepley - v - the viewer 134c0ce001eSMatthew G. Knepley 13588f5f89eSMatthew G. Knepley Level: beginner 136c0ce001eSMatthew G. Knepley 137c0ce001eSMatthew G. Knepley .seealso: PetscLimiterDestroy() 138c0ce001eSMatthew G. Knepley @*/ 139c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterView(PetscLimiter lim, PetscViewer v) 140c0ce001eSMatthew G. Knepley { 141c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 142c0ce001eSMatthew G. Knepley 143c0ce001eSMatthew G. Knepley PetscFunctionBegin; 144c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 145c0ce001eSMatthew G. Knepley if (!v) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) lim), &v);CHKERRQ(ierr);} 146c0ce001eSMatthew G. Knepley if (lim->ops->view) {ierr = (*lim->ops->view)(lim, v);CHKERRQ(ierr);} 147c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 148c0ce001eSMatthew G. Knepley } 149c0ce001eSMatthew G. Knepley 150c0ce001eSMatthew G. Knepley /*@ 151c0ce001eSMatthew G. Knepley PetscLimiterSetFromOptions - sets parameters in a PetscLimiter from the options database 152c0ce001eSMatthew G. Knepley 153c0ce001eSMatthew G. Knepley Collective on lim 154c0ce001eSMatthew G. Knepley 155c0ce001eSMatthew G. Knepley Input Parameter: 156c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to set options for 157c0ce001eSMatthew G. Knepley 15888f5f89eSMatthew G. Knepley Level: intermediate 159c0ce001eSMatthew G. Knepley 160c0ce001eSMatthew G. Knepley .seealso: PetscLimiterView() 161c0ce001eSMatthew G. Knepley @*/ 162c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterSetFromOptions(PetscLimiter lim) 163c0ce001eSMatthew G. Knepley { 164c0ce001eSMatthew G. Knepley const char *defaultType; 165c0ce001eSMatthew G. Knepley char name[256]; 166c0ce001eSMatthew G. Knepley PetscBool flg; 167c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 168c0ce001eSMatthew G. Knepley 169c0ce001eSMatthew G. Knepley PetscFunctionBegin; 170c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 171c0ce001eSMatthew G. Knepley if (!((PetscObject) lim)->type_name) defaultType = PETSCLIMITERSIN; 172c0ce001eSMatthew G. Knepley else defaultType = ((PetscObject) lim)->type_name; 173c0ce001eSMatthew G. Knepley ierr = PetscLimiterRegisterAll();CHKERRQ(ierr); 174c0ce001eSMatthew G. Knepley 175c0ce001eSMatthew G. Knepley ierr = PetscObjectOptionsBegin((PetscObject) lim);CHKERRQ(ierr); 176c0ce001eSMatthew G. Knepley ierr = PetscOptionsFList("-petsclimiter_type", "Finite volume slope limiter", "PetscLimiterSetType", PetscLimiterList, defaultType, name, 256, &flg);CHKERRQ(ierr); 177c0ce001eSMatthew G. Knepley if (flg) { 178c0ce001eSMatthew G. Knepley ierr = PetscLimiterSetType(lim, name);CHKERRQ(ierr); 179c0ce001eSMatthew G. Knepley } else if (!((PetscObject) lim)->type_name) { 180c0ce001eSMatthew G. Knepley ierr = PetscLimiterSetType(lim, defaultType);CHKERRQ(ierr); 181c0ce001eSMatthew G. Knepley } 182c0ce001eSMatthew G. Knepley if (lim->ops->setfromoptions) {ierr = (*lim->ops->setfromoptions)(lim);CHKERRQ(ierr);} 183c0ce001eSMatthew G. Knepley /* process any options handlers added with PetscObjectAddOptionsHandler() */ 184c0ce001eSMatthew G. Knepley ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) lim);CHKERRQ(ierr); 185c0ce001eSMatthew G. Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 186c0ce001eSMatthew G. Knepley ierr = PetscLimiterViewFromOptions(lim, NULL, "-petsclimiter_view");CHKERRQ(ierr); 187c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 188c0ce001eSMatthew G. Knepley } 189c0ce001eSMatthew G. Knepley 190c0ce001eSMatthew G. Knepley /*@C 191c0ce001eSMatthew G. Knepley PetscLimiterSetUp - Construct data structures for the PetscLimiter 192c0ce001eSMatthew G. Knepley 193c0ce001eSMatthew G. Knepley Collective on lim 194c0ce001eSMatthew G. Knepley 195c0ce001eSMatthew G. Knepley Input Parameter: 196c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to setup 197c0ce001eSMatthew G. Knepley 19888f5f89eSMatthew G. Knepley Level: intermediate 199c0ce001eSMatthew G. Knepley 200c0ce001eSMatthew G. Knepley .seealso: PetscLimiterView(), PetscLimiterDestroy() 201c0ce001eSMatthew G. Knepley @*/ 202c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterSetUp(PetscLimiter lim) 203c0ce001eSMatthew G. Knepley { 204c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 205c0ce001eSMatthew G. Knepley 206c0ce001eSMatthew G. Knepley PetscFunctionBegin; 207c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 208c0ce001eSMatthew G. Knepley if (lim->ops->setup) {ierr = (*lim->ops->setup)(lim);CHKERRQ(ierr);} 209c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 210c0ce001eSMatthew G. Knepley } 211c0ce001eSMatthew G. Knepley 212c0ce001eSMatthew G. Knepley /*@ 213c0ce001eSMatthew G. Knepley PetscLimiterDestroy - Destroys a PetscLimiter object 214c0ce001eSMatthew G. Knepley 215c0ce001eSMatthew G. Knepley Collective on lim 216c0ce001eSMatthew G. Knepley 217c0ce001eSMatthew G. Knepley Input Parameter: 218c0ce001eSMatthew G. Knepley . lim - the PetscLimiter object to destroy 219c0ce001eSMatthew G. Knepley 22088f5f89eSMatthew G. Knepley Level: beginner 221c0ce001eSMatthew G. Knepley 222c0ce001eSMatthew G. Knepley .seealso: PetscLimiterView() 223c0ce001eSMatthew G. Knepley @*/ 224c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterDestroy(PetscLimiter *lim) 225c0ce001eSMatthew G. Knepley { 226c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 227c0ce001eSMatthew G. Knepley 228c0ce001eSMatthew G. Knepley PetscFunctionBegin; 229c0ce001eSMatthew G. Knepley if (!*lim) PetscFunctionReturn(0); 230c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific((*lim), PETSCLIMITER_CLASSID, 1); 231c0ce001eSMatthew G. Knepley 232c0ce001eSMatthew G. Knepley if (--((PetscObject)(*lim))->refct > 0) {*lim = 0; PetscFunctionReturn(0);} 233c0ce001eSMatthew G. Knepley ((PetscObject) (*lim))->refct = 0; 234c0ce001eSMatthew G. Knepley 235c0ce001eSMatthew G. Knepley if ((*lim)->ops->destroy) {ierr = (*(*lim)->ops->destroy)(*lim);CHKERRQ(ierr);} 236c0ce001eSMatthew G. Knepley ierr = PetscHeaderDestroy(lim);CHKERRQ(ierr); 237c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 238c0ce001eSMatthew G. Knepley } 239c0ce001eSMatthew G. Knepley 240c0ce001eSMatthew G. Knepley /*@ 241c0ce001eSMatthew G. Knepley PetscLimiterCreate - Creates an empty PetscLimiter object. The type can then be set with PetscLimiterSetType(). 242c0ce001eSMatthew G. Knepley 243c0ce001eSMatthew G. Knepley Collective 244c0ce001eSMatthew G. Knepley 245c0ce001eSMatthew G. Knepley Input Parameter: 246c0ce001eSMatthew G. Knepley . comm - The communicator for the PetscLimiter object 247c0ce001eSMatthew G. Knepley 248c0ce001eSMatthew G. Knepley Output Parameter: 249c0ce001eSMatthew G. Knepley . lim - The PetscLimiter object 250c0ce001eSMatthew G. Knepley 251c0ce001eSMatthew G. Knepley Level: beginner 252c0ce001eSMatthew G. Knepley 253c0ce001eSMatthew G. Knepley .seealso: PetscLimiterSetType(), PETSCLIMITERSIN 254c0ce001eSMatthew G. Knepley @*/ 255c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterCreate(MPI_Comm comm, PetscLimiter *lim) 256c0ce001eSMatthew G. Knepley { 257c0ce001eSMatthew G. Knepley PetscLimiter l; 258c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 259c0ce001eSMatthew G. Knepley 260c0ce001eSMatthew G. Knepley PetscFunctionBegin; 261c0ce001eSMatthew G. Knepley PetscValidPointer(lim, 2); 262c0ce001eSMatthew G. Knepley ierr = PetscCitationsRegister(LimiterCitation,&Limitercite);CHKERRQ(ierr); 263c0ce001eSMatthew G. Knepley *lim = NULL; 264c0ce001eSMatthew G. Knepley ierr = PetscFVInitializePackage();CHKERRQ(ierr); 265c0ce001eSMatthew G. Knepley 266c0ce001eSMatthew G. Knepley ierr = PetscHeaderCreate(l, PETSCLIMITER_CLASSID, "PetscLimiter", "Finite Volume Slope Limiter", "PetscLimiter", comm, PetscLimiterDestroy, PetscLimiterView);CHKERRQ(ierr); 267c0ce001eSMatthew G. Knepley 268c0ce001eSMatthew G. Knepley *lim = l; 269c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 270c0ce001eSMatthew G. Knepley } 271c0ce001eSMatthew G. Knepley 27288f5f89eSMatthew G. Knepley /*@ 27388f5f89eSMatthew G. Knepley PetscLimiterLimit - Limit the flux 27488f5f89eSMatthew G. Knepley 27588f5f89eSMatthew G. Knepley Input Parameters: 27688f5f89eSMatthew G. Knepley + lim - The PetscLimiter 27788f5f89eSMatthew G. Knepley - flim - The input field 27888f5f89eSMatthew G. Knepley 27988f5f89eSMatthew G. Knepley Output Parameter: 28088f5f89eSMatthew G. Knepley . phi - The limited field 28188f5f89eSMatthew G. Knepley 28288f5f89eSMatthew G. Knepley Note: Limiters given in symmetric form following Berger, Aftosmis, and Murman 2005 28388f5f89eSMatthew G. Knepley $ The classical flux-limited formulation is psi(r) where 28488f5f89eSMatthew G. Knepley $ 28588f5f89eSMatthew G. Knepley $ r = (u[0] - u[-1]) / (u[1] - u[0]) 28688f5f89eSMatthew G. Knepley $ 28788f5f89eSMatthew G. Knepley $ The second order TVD region is bounded by 28888f5f89eSMatthew G. Knepley $ 28988f5f89eSMatthew G. Knepley $ psi_minmod(r) = min(r,1) and psi_superbee(r) = min(2, 2r, max(1,r)) 29088f5f89eSMatthew G. Knepley $ 29188f5f89eSMatthew G. Knepley $ where all limiters are implicitly clipped to be non-negative. A more convenient slope-limited form is psi(r) = 29288f5f89eSMatthew G. Knepley $ phi(r)(r+1)/2 in which the reconstructed interface values are 29388f5f89eSMatthew G. Knepley $ 29488f5f89eSMatthew G. Knepley $ u(v) = u[0] + phi(r) (grad u)[0] v 29588f5f89eSMatthew G. Knepley $ 29688f5f89eSMatthew G. Knepley $ where v is the vector from centroid to quadrature point. In these variables, the usual limiters become 29788f5f89eSMatthew G. Knepley $ 29888f5f89eSMatthew 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)) 29988f5f89eSMatthew G. Knepley $ 30088f5f89eSMatthew G. Knepley $ For a nicer symmetric formulation, rewrite in terms of 30188f5f89eSMatthew G. Knepley $ 30288f5f89eSMatthew G. Knepley $ f = (u[0] - u[-1]) / (u[1] - u[-1]) 30388f5f89eSMatthew G. Knepley $ 30488f5f89eSMatthew G. Knepley $ where r(f) = f/(1-f). Not that r(1-f) = (1-f)/f = 1/r(f) so the symmetry condition 30588f5f89eSMatthew G. Knepley $ 30688f5f89eSMatthew G. Knepley $ phi(r) = phi(1/r) 30788f5f89eSMatthew G. Knepley $ 30888f5f89eSMatthew G. Knepley $ becomes 30988f5f89eSMatthew G. Knepley $ 31088f5f89eSMatthew G. Knepley $ w(f) = w(1-f). 31188f5f89eSMatthew G. Knepley $ 31288f5f89eSMatthew G. Knepley $ The limiters below implement this final form w(f). The reference methods are 31388f5f89eSMatthew G. Knepley $ 31488f5f89eSMatthew G. Knepley $ w_minmod(f) = 2 min(f,(1-f)) w_superbee(r) = 4 min((1-f), f) 31588f5f89eSMatthew G. Knepley 31688f5f89eSMatthew G. Knepley Level: beginner 31788f5f89eSMatthew G. Knepley 31888f5f89eSMatthew G. Knepley .seealso: PetscLimiterSetType(), PetscLimiterCreate() 31988f5f89eSMatthew G. Knepley @*/ 320c0ce001eSMatthew G. Knepley PetscErrorCode PetscLimiterLimit(PetscLimiter lim, PetscReal flim, PetscReal *phi) 321c0ce001eSMatthew G. Knepley { 322c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 323c0ce001eSMatthew G. Knepley 324c0ce001eSMatthew G. Knepley PetscFunctionBegin; 325c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 326c0ce001eSMatthew G. Knepley PetscValidPointer(phi, 3); 327c0ce001eSMatthew G. Knepley ierr = (*lim->ops->limit)(lim, flim, phi);CHKERRQ(ierr); 328c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 329c0ce001eSMatthew G. Knepley } 330c0ce001eSMatthew G. Knepley 33188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Sin(PetscLimiter lim) 332c0ce001eSMatthew G. Knepley { 333c0ce001eSMatthew G. Knepley PetscLimiter_Sin *l = (PetscLimiter_Sin *) lim->data; 334c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 335c0ce001eSMatthew G. Knepley 336c0ce001eSMatthew G. Knepley PetscFunctionBegin; 337c0ce001eSMatthew G. Knepley ierr = PetscFree(l);CHKERRQ(ierr); 338c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 339c0ce001eSMatthew G. Knepley } 340c0ce001eSMatthew G. Knepley 34188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Sin_Ascii(PetscLimiter lim, PetscViewer viewer) 342c0ce001eSMatthew G. Knepley { 343c0ce001eSMatthew G. Knepley PetscViewerFormat format; 344c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 345c0ce001eSMatthew G. Knepley 346c0ce001eSMatthew G. Knepley PetscFunctionBegin; 347c0ce001eSMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 348c0ce001eSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Sin Slope Limiter:\n");CHKERRQ(ierr); 349c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 350c0ce001eSMatthew G. Knepley } 351c0ce001eSMatthew G. Knepley 35288f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Sin(PetscLimiter lim, PetscViewer viewer) 353c0ce001eSMatthew G. Knepley { 354c0ce001eSMatthew G. Knepley PetscBool iascii; 355c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 356c0ce001eSMatthew G. Knepley 357c0ce001eSMatthew G. Knepley PetscFunctionBegin; 358c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 359c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 360c0ce001eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 361c0ce001eSMatthew G. Knepley if (iascii) {ierr = PetscLimiterView_Sin_Ascii(lim, viewer);CHKERRQ(ierr);} 362c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 363c0ce001eSMatthew G. Knepley } 364c0ce001eSMatthew G. Knepley 36588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Sin(PetscLimiter lim, PetscReal f, PetscReal *phi) 366c0ce001eSMatthew G. Knepley { 367c0ce001eSMatthew G. Knepley PetscFunctionBegin; 368c0ce001eSMatthew G. Knepley *phi = PetscSinReal(PETSC_PI*PetscMax(0, PetscMin(f, 1))); 369c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 370c0ce001eSMatthew G. Knepley } 371c0ce001eSMatthew G. Knepley 37288f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Sin(PetscLimiter lim) 373c0ce001eSMatthew G. Knepley { 374c0ce001eSMatthew G. Knepley PetscFunctionBegin; 375c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Sin; 376c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Sin; 377c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Sin; 378c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 379c0ce001eSMatthew G. Knepley } 380c0ce001eSMatthew G. Knepley 381c0ce001eSMatthew G. Knepley /*MC 382c0ce001eSMatthew G. Knepley PETSCLIMITERSIN = "sin" - A PetscLimiter object 383c0ce001eSMatthew G. Knepley 384c0ce001eSMatthew G. Knepley Level: intermediate 385c0ce001eSMatthew G. Knepley 386c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType() 387c0ce001eSMatthew G. Knepley M*/ 388c0ce001eSMatthew G. Knepley 389c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Sin(PetscLimiter lim) 390c0ce001eSMatthew G. Knepley { 391c0ce001eSMatthew G. Knepley PetscLimiter_Sin *l; 392c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 393c0ce001eSMatthew G. Knepley 394c0ce001eSMatthew G. Knepley PetscFunctionBegin; 395c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 396c0ce001eSMatthew G. Knepley ierr = PetscNewLog(lim, &l);CHKERRQ(ierr); 397c0ce001eSMatthew G. Knepley lim->data = l; 398c0ce001eSMatthew G. Knepley 399c0ce001eSMatthew G. Knepley ierr = PetscLimiterInitialize_Sin(lim);CHKERRQ(ierr); 400c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 401c0ce001eSMatthew G. Knepley } 402c0ce001eSMatthew G. Knepley 40388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Zero(PetscLimiter lim) 404c0ce001eSMatthew G. Knepley { 405c0ce001eSMatthew G. Knepley PetscLimiter_Zero *l = (PetscLimiter_Zero *) lim->data; 406c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 407c0ce001eSMatthew G. Knepley 408c0ce001eSMatthew G. Knepley PetscFunctionBegin; 409c0ce001eSMatthew G. Knepley ierr = PetscFree(l);CHKERRQ(ierr); 410c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 411c0ce001eSMatthew G. Knepley } 412c0ce001eSMatthew G. Knepley 41388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Zero_Ascii(PetscLimiter lim, PetscViewer viewer) 414c0ce001eSMatthew G. Knepley { 415c0ce001eSMatthew G. Knepley PetscViewerFormat format; 416c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 417c0ce001eSMatthew G. Knepley 418c0ce001eSMatthew G. Knepley PetscFunctionBegin; 419c0ce001eSMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 420c0ce001eSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Zero Slope Limiter:\n");CHKERRQ(ierr); 421c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 422c0ce001eSMatthew G. Knepley } 423c0ce001eSMatthew G. Knepley 42488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Zero(PetscLimiter lim, PetscViewer viewer) 425c0ce001eSMatthew G. Knepley { 426c0ce001eSMatthew G. Knepley PetscBool iascii; 427c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 428c0ce001eSMatthew G. Knepley 429c0ce001eSMatthew G. Knepley PetscFunctionBegin; 430c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 431c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 432c0ce001eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 433c0ce001eSMatthew G. Knepley if (iascii) {ierr = PetscLimiterView_Zero_Ascii(lim, viewer);CHKERRQ(ierr);} 434c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 435c0ce001eSMatthew G. Knepley } 436c0ce001eSMatthew G. Knepley 43788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Zero(PetscLimiter lim, PetscReal f, PetscReal *phi) 438c0ce001eSMatthew G. Knepley { 439c0ce001eSMatthew G. Knepley PetscFunctionBegin; 440c0ce001eSMatthew G. Knepley *phi = 0.0; 441c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 442c0ce001eSMatthew G. Knepley } 443c0ce001eSMatthew G. Knepley 44488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Zero(PetscLimiter lim) 445c0ce001eSMatthew G. Knepley { 446c0ce001eSMatthew G. Knepley PetscFunctionBegin; 447c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Zero; 448c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Zero; 449c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Zero; 450c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 451c0ce001eSMatthew G. Knepley } 452c0ce001eSMatthew G. Knepley 453c0ce001eSMatthew G. Knepley /*MC 454c0ce001eSMatthew G. Knepley PETSCLIMITERZERO = "zero" - A PetscLimiter object 455c0ce001eSMatthew G. Knepley 456c0ce001eSMatthew G. Knepley Level: intermediate 457c0ce001eSMatthew G. Knepley 458c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType() 459c0ce001eSMatthew G. Knepley M*/ 460c0ce001eSMatthew G. Knepley 461c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Zero(PetscLimiter lim) 462c0ce001eSMatthew G. Knepley { 463c0ce001eSMatthew G. Knepley PetscLimiter_Zero *l; 464c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 465c0ce001eSMatthew G. Knepley 466c0ce001eSMatthew G. Knepley PetscFunctionBegin; 467c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 468c0ce001eSMatthew G. Knepley ierr = PetscNewLog(lim, &l);CHKERRQ(ierr); 469c0ce001eSMatthew G. Knepley lim->data = l; 470c0ce001eSMatthew G. Knepley 471c0ce001eSMatthew G. Knepley ierr = PetscLimiterInitialize_Zero(lim);CHKERRQ(ierr); 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 PetscErrorCode ierr; 479c0ce001eSMatthew G. Knepley 480c0ce001eSMatthew G. Knepley PetscFunctionBegin; 481c0ce001eSMatthew G. Knepley ierr = PetscFree(l);CHKERRQ(ierr); 482c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 483c0ce001eSMatthew G. Knepley } 484c0ce001eSMatthew G. Knepley 48588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_None_Ascii(PetscLimiter lim, PetscViewer viewer) 486c0ce001eSMatthew G. Knepley { 487c0ce001eSMatthew G. Knepley PetscViewerFormat format; 488c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 489c0ce001eSMatthew G. Knepley 490c0ce001eSMatthew G. Knepley PetscFunctionBegin; 491c0ce001eSMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 492c0ce001eSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "None Slope Limiter:\n");CHKERRQ(ierr); 493c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 494c0ce001eSMatthew G. Knepley } 495c0ce001eSMatthew G. Knepley 49688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_None(PetscLimiter lim, PetscViewer viewer) 497c0ce001eSMatthew G. Knepley { 498c0ce001eSMatthew G. Knepley PetscBool iascii; 499c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 500c0ce001eSMatthew G. Knepley 501c0ce001eSMatthew G. Knepley PetscFunctionBegin; 502c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 503c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 504c0ce001eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 505c0ce001eSMatthew G. Knepley if (iascii) {ierr = PetscLimiterView_None_Ascii(lim, viewer);CHKERRQ(ierr);} 506c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 507c0ce001eSMatthew G. Knepley } 508c0ce001eSMatthew G. Knepley 50988f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_None(PetscLimiter lim, PetscReal f, PetscReal *phi) 510c0ce001eSMatthew G. Knepley { 511c0ce001eSMatthew G. Knepley PetscFunctionBegin; 512c0ce001eSMatthew G. Knepley *phi = 1.0; 513c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 514c0ce001eSMatthew G. Knepley } 515c0ce001eSMatthew G. Knepley 51688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_None(PetscLimiter lim) 517c0ce001eSMatthew G. Knepley { 518c0ce001eSMatthew G. Knepley PetscFunctionBegin; 519c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_None; 520c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_None; 521c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_None; 522c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 523c0ce001eSMatthew G. Knepley } 524c0ce001eSMatthew G. Knepley 525c0ce001eSMatthew G. Knepley /*MC 526c0ce001eSMatthew G. Knepley PETSCLIMITERNONE = "none" - A PetscLimiter object 527c0ce001eSMatthew G. Knepley 528c0ce001eSMatthew G. Knepley Level: intermediate 529c0ce001eSMatthew G. Knepley 530c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType() 531c0ce001eSMatthew G. Knepley M*/ 532c0ce001eSMatthew G. Knepley 533c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_None(PetscLimiter lim) 534c0ce001eSMatthew G. Knepley { 535c0ce001eSMatthew G. Knepley PetscLimiter_None *l; 536c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 537c0ce001eSMatthew G. Knepley 538c0ce001eSMatthew G. Knepley PetscFunctionBegin; 539c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 540c0ce001eSMatthew G. Knepley ierr = PetscNewLog(lim, &l);CHKERRQ(ierr); 541c0ce001eSMatthew G. Knepley lim->data = l; 542c0ce001eSMatthew G. Knepley 543c0ce001eSMatthew G. Knepley ierr = PetscLimiterInitialize_None(lim);CHKERRQ(ierr); 544c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 545c0ce001eSMatthew G. Knepley } 546c0ce001eSMatthew G. Knepley 54788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Minmod(PetscLimiter lim) 548c0ce001eSMatthew G. Knepley { 549c0ce001eSMatthew G. Knepley PetscLimiter_Minmod *l = (PetscLimiter_Minmod *) lim->data; 550c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 551c0ce001eSMatthew G. Knepley 552c0ce001eSMatthew G. Knepley PetscFunctionBegin; 553c0ce001eSMatthew G. Knepley ierr = PetscFree(l);CHKERRQ(ierr); 554c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 555c0ce001eSMatthew G. Knepley } 556c0ce001eSMatthew G. Knepley 55788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Minmod_Ascii(PetscLimiter lim, PetscViewer viewer) 558c0ce001eSMatthew G. Knepley { 559c0ce001eSMatthew G. Knepley PetscViewerFormat format; 560c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 561c0ce001eSMatthew G. Knepley 562c0ce001eSMatthew G. Knepley PetscFunctionBegin; 563c0ce001eSMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 564c0ce001eSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Minmod Slope Limiter:\n");CHKERRQ(ierr); 565c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 566c0ce001eSMatthew G. Knepley } 567c0ce001eSMatthew G. Knepley 56888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Minmod(PetscLimiter lim, PetscViewer viewer) 569c0ce001eSMatthew G. Knepley { 570c0ce001eSMatthew G. Knepley PetscBool iascii; 571c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 572c0ce001eSMatthew G. Knepley 573c0ce001eSMatthew G. Knepley PetscFunctionBegin; 574c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 575c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 576c0ce001eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 577c0ce001eSMatthew G. Knepley if (iascii) {ierr = PetscLimiterView_Minmod_Ascii(lim, viewer);CHKERRQ(ierr);} 578c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 579c0ce001eSMatthew G. Knepley } 580c0ce001eSMatthew G. Knepley 58188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Minmod(PetscLimiter lim, PetscReal f, PetscReal *phi) 582c0ce001eSMatthew G. Knepley { 583c0ce001eSMatthew G. Knepley PetscFunctionBegin; 584c0ce001eSMatthew G. Knepley *phi = 2*PetscMax(0, PetscMin(f, 1-f)); 585c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 586c0ce001eSMatthew G. Knepley } 587c0ce001eSMatthew G. Knepley 58888f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Minmod(PetscLimiter lim) 589c0ce001eSMatthew G. Knepley { 590c0ce001eSMatthew G. Knepley PetscFunctionBegin; 591c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Minmod; 592c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Minmod; 593c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Minmod; 594c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 595c0ce001eSMatthew G. Knepley } 596c0ce001eSMatthew G. Knepley 597c0ce001eSMatthew G. Knepley /*MC 598c0ce001eSMatthew G. Knepley PETSCLIMITERMINMOD = "minmod" - A PetscLimiter object 599c0ce001eSMatthew G. Knepley 600c0ce001eSMatthew G. Knepley Level: intermediate 601c0ce001eSMatthew G. Knepley 602c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType() 603c0ce001eSMatthew G. Knepley M*/ 604c0ce001eSMatthew G. Knepley 605c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Minmod(PetscLimiter lim) 606c0ce001eSMatthew G. Knepley { 607c0ce001eSMatthew G. Knepley PetscLimiter_Minmod *l; 608c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 609c0ce001eSMatthew G. Knepley 610c0ce001eSMatthew G. Knepley PetscFunctionBegin; 611c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 612c0ce001eSMatthew G. Knepley ierr = PetscNewLog(lim, &l);CHKERRQ(ierr); 613c0ce001eSMatthew G. Knepley lim->data = l; 614c0ce001eSMatthew G. Knepley 615c0ce001eSMatthew G. Knepley ierr = PetscLimiterInitialize_Minmod(lim);CHKERRQ(ierr); 616c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 617c0ce001eSMatthew G. Knepley } 618c0ce001eSMatthew G. Knepley 61988f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_VanLeer(PetscLimiter lim) 620c0ce001eSMatthew G. Knepley { 621c0ce001eSMatthew G. Knepley PetscLimiter_VanLeer *l = (PetscLimiter_VanLeer *) lim->data; 622c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 623c0ce001eSMatthew G. Knepley 624c0ce001eSMatthew G. Knepley PetscFunctionBegin; 625c0ce001eSMatthew G. Knepley ierr = PetscFree(l);CHKERRQ(ierr); 626c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 627c0ce001eSMatthew G. Knepley } 628c0ce001eSMatthew G. Knepley 62988f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanLeer_Ascii(PetscLimiter lim, PetscViewer viewer) 630c0ce001eSMatthew G. Knepley { 631c0ce001eSMatthew G. Knepley PetscViewerFormat format; 632c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 633c0ce001eSMatthew G. Knepley 634c0ce001eSMatthew G. Knepley PetscFunctionBegin; 635c0ce001eSMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 636c0ce001eSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Van Leer Slope Limiter:\n");CHKERRQ(ierr); 637c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 638c0ce001eSMatthew G. Knepley } 639c0ce001eSMatthew G. Knepley 64088f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanLeer(PetscLimiter lim, PetscViewer viewer) 641c0ce001eSMatthew G. Knepley { 642c0ce001eSMatthew G. Knepley PetscBool iascii; 643c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 644c0ce001eSMatthew G. Knepley 645c0ce001eSMatthew G. Knepley PetscFunctionBegin; 646c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 647c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 648c0ce001eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 649c0ce001eSMatthew G. Knepley if (iascii) {ierr = PetscLimiterView_VanLeer_Ascii(lim, viewer);CHKERRQ(ierr);} 650c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 651c0ce001eSMatthew G. Knepley } 652c0ce001eSMatthew G. Knepley 65388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_VanLeer(PetscLimiter lim, PetscReal f, PetscReal *phi) 654c0ce001eSMatthew G. Knepley { 655c0ce001eSMatthew G. Knepley PetscFunctionBegin; 656c0ce001eSMatthew G. Knepley *phi = PetscMax(0, 4*f*(1-f)); 657c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 658c0ce001eSMatthew G. Knepley } 659c0ce001eSMatthew G. Knepley 66088f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_VanLeer(PetscLimiter lim) 661c0ce001eSMatthew G. Knepley { 662c0ce001eSMatthew G. Knepley PetscFunctionBegin; 663c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_VanLeer; 664c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_VanLeer; 665c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_VanLeer; 666c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 667c0ce001eSMatthew G. Knepley } 668c0ce001eSMatthew G. Knepley 669c0ce001eSMatthew G. Knepley /*MC 670c0ce001eSMatthew G. Knepley PETSCLIMITERVANLEER = "vanleer" - A PetscLimiter object 671c0ce001eSMatthew G. Knepley 672c0ce001eSMatthew G. Knepley Level: intermediate 673c0ce001eSMatthew G. Knepley 674c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType() 675c0ce001eSMatthew G. Knepley M*/ 676c0ce001eSMatthew G. Knepley 677c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanLeer(PetscLimiter lim) 678c0ce001eSMatthew G. Knepley { 679c0ce001eSMatthew G. Knepley PetscLimiter_VanLeer *l; 680c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 681c0ce001eSMatthew G. Knepley 682c0ce001eSMatthew G. Knepley PetscFunctionBegin; 683c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 684c0ce001eSMatthew G. Knepley ierr = PetscNewLog(lim, &l);CHKERRQ(ierr); 685c0ce001eSMatthew G. Knepley lim->data = l; 686c0ce001eSMatthew G. Knepley 687c0ce001eSMatthew G. Knepley ierr = PetscLimiterInitialize_VanLeer(lim);CHKERRQ(ierr); 688c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 689c0ce001eSMatthew G. Knepley } 690c0ce001eSMatthew G. Knepley 69188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_VanAlbada(PetscLimiter lim) 692c0ce001eSMatthew G. Knepley { 693c0ce001eSMatthew G. Knepley PetscLimiter_VanAlbada *l = (PetscLimiter_VanAlbada *) lim->data; 694c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 695c0ce001eSMatthew G. Knepley 696c0ce001eSMatthew G. Knepley PetscFunctionBegin; 697c0ce001eSMatthew G. Knepley ierr = PetscFree(l);CHKERRQ(ierr); 698c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 699c0ce001eSMatthew G. Knepley } 700c0ce001eSMatthew G. Knepley 70188f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanAlbada_Ascii(PetscLimiter lim, PetscViewer viewer) 702c0ce001eSMatthew G. Knepley { 703c0ce001eSMatthew G. Knepley PetscViewerFormat format; 704c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 705c0ce001eSMatthew G. Knepley 706c0ce001eSMatthew G. Knepley PetscFunctionBegin; 707c0ce001eSMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 708c0ce001eSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Van Albada Slope Limiter:\n");CHKERRQ(ierr); 709c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 710c0ce001eSMatthew G. Knepley } 711c0ce001eSMatthew G. Knepley 71288f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_VanAlbada(PetscLimiter lim, PetscViewer viewer) 713c0ce001eSMatthew G. Knepley { 714c0ce001eSMatthew G. Knepley PetscBool iascii; 715c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 716c0ce001eSMatthew G. Knepley 717c0ce001eSMatthew G. Knepley PetscFunctionBegin; 718c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 719c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 720c0ce001eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 721c0ce001eSMatthew G. Knepley if (iascii) {ierr = PetscLimiterView_VanAlbada_Ascii(lim, viewer);CHKERRQ(ierr);} 722c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 723c0ce001eSMatthew G. Knepley } 724c0ce001eSMatthew G. Knepley 72588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_VanAlbada(PetscLimiter lim, PetscReal f, PetscReal *phi) 726c0ce001eSMatthew G. Knepley { 727c0ce001eSMatthew G. Knepley PetscFunctionBegin; 728c0ce001eSMatthew G. Knepley *phi = PetscMax(0, 2*f*(1-f) / (PetscSqr(f) + PetscSqr(1-f))); 729c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 730c0ce001eSMatthew G. Knepley } 731c0ce001eSMatthew G. Knepley 73288f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_VanAlbada(PetscLimiter lim) 733c0ce001eSMatthew G. Knepley { 734c0ce001eSMatthew G. Knepley PetscFunctionBegin; 735c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_VanAlbada; 736c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_VanAlbada; 737c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_VanAlbada; 738c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 739c0ce001eSMatthew G. Knepley } 740c0ce001eSMatthew G. Knepley 741c0ce001eSMatthew G. Knepley /*MC 742c0ce001eSMatthew G. Knepley PETSCLIMITERVANALBADA = "vanalbada" - A PetscLimiter object 743c0ce001eSMatthew G. Knepley 744c0ce001eSMatthew G. Knepley Level: intermediate 745c0ce001eSMatthew G. Knepley 746c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType() 747c0ce001eSMatthew G. Knepley M*/ 748c0ce001eSMatthew G. Knepley 749c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_VanAlbada(PetscLimiter lim) 750c0ce001eSMatthew G. Knepley { 751c0ce001eSMatthew G. Knepley PetscLimiter_VanAlbada *l; 752c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 753c0ce001eSMatthew G. Knepley 754c0ce001eSMatthew G. Knepley PetscFunctionBegin; 755c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 756c0ce001eSMatthew G. Knepley ierr = PetscNewLog(lim, &l);CHKERRQ(ierr); 757c0ce001eSMatthew G. Knepley lim->data = l; 758c0ce001eSMatthew G. Knepley 759c0ce001eSMatthew G. Knepley ierr = PetscLimiterInitialize_VanAlbada(lim);CHKERRQ(ierr); 760c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 761c0ce001eSMatthew G. Knepley } 762c0ce001eSMatthew G. Knepley 76388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_Superbee(PetscLimiter lim) 764c0ce001eSMatthew G. Knepley { 765c0ce001eSMatthew G. Knepley PetscLimiter_Superbee *l = (PetscLimiter_Superbee *) lim->data; 766c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 767c0ce001eSMatthew G. Knepley 768c0ce001eSMatthew G. Knepley PetscFunctionBegin; 769c0ce001eSMatthew G. Knepley ierr = PetscFree(l);CHKERRQ(ierr); 770c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 771c0ce001eSMatthew G. Knepley } 772c0ce001eSMatthew G. Knepley 77388f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Superbee_Ascii(PetscLimiter lim, PetscViewer viewer) 774c0ce001eSMatthew G. Knepley { 775c0ce001eSMatthew G. Knepley PetscViewerFormat format; 776c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 777c0ce001eSMatthew G. Knepley 778c0ce001eSMatthew G. Knepley PetscFunctionBegin; 779c0ce001eSMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 780c0ce001eSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Superbee Slope Limiter:\n");CHKERRQ(ierr); 781c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 782c0ce001eSMatthew G. Knepley } 783c0ce001eSMatthew G. Knepley 78488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_Superbee(PetscLimiter lim, PetscViewer viewer) 785c0ce001eSMatthew G. Knepley { 786c0ce001eSMatthew G. Knepley PetscBool iascii; 787c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 788c0ce001eSMatthew G. Knepley 789c0ce001eSMatthew G. Knepley PetscFunctionBegin; 790c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 791c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 792c0ce001eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 793c0ce001eSMatthew G. Knepley if (iascii) {ierr = PetscLimiterView_Superbee_Ascii(lim, viewer);CHKERRQ(ierr);} 794c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 795c0ce001eSMatthew G. Knepley } 796c0ce001eSMatthew G. Knepley 79788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_Superbee(PetscLimiter lim, PetscReal f, PetscReal *phi) 798c0ce001eSMatthew G. Knepley { 799c0ce001eSMatthew G. Knepley PetscFunctionBegin; 800c0ce001eSMatthew G. Knepley *phi = 4*PetscMax(0, PetscMin(f, 1-f)); 801c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 802c0ce001eSMatthew G. Knepley } 803c0ce001eSMatthew G. Knepley 80488f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_Superbee(PetscLimiter lim) 805c0ce001eSMatthew G. Knepley { 806c0ce001eSMatthew G. Knepley PetscFunctionBegin; 807c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_Superbee; 808c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_Superbee; 809c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_Superbee; 810c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 811c0ce001eSMatthew G. Knepley } 812c0ce001eSMatthew G. Knepley 813c0ce001eSMatthew G. Knepley /*MC 814c0ce001eSMatthew G. Knepley PETSCLIMITERSUPERBEE = "superbee" - A PetscLimiter object 815c0ce001eSMatthew G. Knepley 816c0ce001eSMatthew G. Knepley Level: intermediate 817c0ce001eSMatthew G. Knepley 818c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType() 819c0ce001eSMatthew G. Knepley M*/ 820c0ce001eSMatthew G. Knepley 821c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_Superbee(PetscLimiter lim) 822c0ce001eSMatthew G. Knepley { 823c0ce001eSMatthew G. Knepley PetscLimiter_Superbee *l; 824c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 825c0ce001eSMatthew G. Knepley 826c0ce001eSMatthew G. Knepley PetscFunctionBegin; 827c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 828c0ce001eSMatthew G. Knepley ierr = PetscNewLog(lim, &l);CHKERRQ(ierr); 829c0ce001eSMatthew G. Knepley lim->data = l; 830c0ce001eSMatthew G. Knepley 831c0ce001eSMatthew G. Knepley ierr = PetscLimiterInitialize_Superbee(lim);CHKERRQ(ierr); 832c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 833c0ce001eSMatthew G. Knepley } 834c0ce001eSMatthew G. Knepley 83588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterDestroy_MC(PetscLimiter lim) 836c0ce001eSMatthew G. Knepley { 837c0ce001eSMatthew G. Knepley PetscLimiter_MC *l = (PetscLimiter_MC *) lim->data; 838c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 839c0ce001eSMatthew G. Knepley 840c0ce001eSMatthew G. Knepley PetscFunctionBegin; 841c0ce001eSMatthew G. Knepley ierr = PetscFree(l);CHKERRQ(ierr); 842c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 843c0ce001eSMatthew G. Knepley } 844c0ce001eSMatthew G. Knepley 84588f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_MC_Ascii(PetscLimiter lim, PetscViewer viewer) 846c0ce001eSMatthew G. Knepley { 847c0ce001eSMatthew G. Knepley PetscViewerFormat format; 848c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 849c0ce001eSMatthew G. Knepley 850c0ce001eSMatthew G. Knepley PetscFunctionBegin; 851c0ce001eSMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 852c0ce001eSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "MC Slope Limiter:\n");CHKERRQ(ierr); 853c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 854c0ce001eSMatthew G. Knepley } 855c0ce001eSMatthew G. Knepley 85688f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterView_MC(PetscLimiter lim, PetscViewer viewer) 857c0ce001eSMatthew G. Knepley { 858c0ce001eSMatthew G. Knepley PetscBool iascii; 859c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 860c0ce001eSMatthew G. Knepley 861c0ce001eSMatthew G. Knepley PetscFunctionBegin; 862c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 863c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 864c0ce001eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 865c0ce001eSMatthew G. Knepley if (iascii) {ierr = PetscLimiterView_MC_Ascii(lim, viewer);CHKERRQ(ierr);} 866c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 867c0ce001eSMatthew G. Knepley } 868c0ce001eSMatthew G. Knepley 869c0ce001eSMatthew G. Knepley /* aka Barth-Jespersen */ 87088f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterLimit_MC(PetscLimiter lim, PetscReal f, PetscReal *phi) 871c0ce001eSMatthew G. Knepley { 872c0ce001eSMatthew G. Knepley PetscFunctionBegin; 873c0ce001eSMatthew G. Knepley *phi = PetscMin(1, 4*PetscMax(0, PetscMin(f, 1-f))); 874c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 875c0ce001eSMatthew G. Knepley } 876c0ce001eSMatthew G. Knepley 87788f5f89eSMatthew G. Knepley static PetscErrorCode PetscLimiterInitialize_MC(PetscLimiter lim) 878c0ce001eSMatthew G. Knepley { 879c0ce001eSMatthew G. Knepley PetscFunctionBegin; 880c0ce001eSMatthew G. Knepley lim->ops->view = PetscLimiterView_MC; 881c0ce001eSMatthew G. Knepley lim->ops->destroy = PetscLimiterDestroy_MC; 882c0ce001eSMatthew G. Knepley lim->ops->limit = PetscLimiterLimit_MC; 883c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 884c0ce001eSMatthew G. Knepley } 885c0ce001eSMatthew G. Knepley 886c0ce001eSMatthew G. Knepley /*MC 887c0ce001eSMatthew G. Knepley PETSCLIMITERMC = "mc" - A PetscLimiter object 888c0ce001eSMatthew G. Knepley 889c0ce001eSMatthew G. Knepley Level: intermediate 890c0ce001eSMatthew G. Knepley 891c0ce001eSMatthew G. Knepley .seealso: PetscLimiterType, PetscLimiterCreate(), PetscLimiterSetType() 892c0ce001eSMatthew G. Knepley M*/ 893c0ce001eSMatthew G. Knepley 894c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscLimiterCreate_MC(PetscLimiter lim) 895c0ce001eSMatthew G. Knepley { 896c0ce001eSMatthew G. Knepley PetscLimiter_MC *l; 897c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 898c0ce001eSMatthew G. Knepley 899c0ce001eSMatthew G. Knepley PetscFunctionBegin; 900c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 1); 901c0ce001eSMatthew G. Knepley ierr = PetscNewLog(lim, &l);CHKERRQ(ierr); 902c0ce001eSMatthew G. Knepley lim->data = l; 903c0ce001eSMatthew G. Knepley 904c0ce001eSMatthew G. Knepley ierr = PetscLimiterInitialize_MC(lim);CHKERRQ(ierr); 905c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 906c0ce001eSMatthew G. Knepley } 907c0ce001eSMatthew G. Knepley 908c0ce001eSMatthew G. Knepley PetscClassId PETSCFV_CLASSID = 0; 909c0ce001eSMatthew G. Knepley 910c0ce001eSMatthew G. Knepley PetscFunctionList PetscFVList = NULL; 911c0ce001eSMatthew G. Knepley PetscBool PetscFVRegisterAllCalled = PETSC_FALSE; 912c0ce001eSMatthew G. Knepley 913c0ce001eSMatthew G. Knepley /*@C 914c0ce001eSMatthew G. Knepley PetscFVRegister - Adds a new PetscFV implementation 915c0ce001eSMatthew G. Knepley 916c0ce001eSMatthew G. Knepley Not Collective 917c0ce001eSMatthew G. Knepley 918c0ce001eSMatthew G. Knepley Input Parameters: 919c0ce001eSMatthew G. Knepley + name - The name of a new user-defined creation routine 920c0ce001eSMatthew G. Knepley - create_func - The creation routine itself 921c0ce001eSMatthew G. Knepley 922c0ce001eSMatthew G. Knepley Notes: 923c0ce001eSMatthew G. Knepley PetscFVRegister() may be called multiple times to add several user-defined PetscFVs 924c0ce001eSMatthew G. Knepley 925c0ce001eSMatthew G. Knepley Sample usage: 926c0ce001eSMatthew G. Knepley .vb 927c0ce001eSMatthew G. Knepley PetscFVRegister("my_fv", MyPetscFVCreate); 928c0ce001eSMatthew G. Knepley .ve 929c0ce001eSMatthew G. Knepley 930c0ce001eSMatthew G. Knepley Then, your PetscFV type can be chosen with the procedural interface via 931c0ce001eSMatthew G. Knepley .vb 932c0ce001eSMatthew G. Knepley PetscFVCreate(MPI_Comm, PetscFV *); 933c0ce001eSMatthew G. Knepley PetscFVSetType(PetscFV, "my_fv"); 934c0ce001eSMatthew G. Knepley .ve 935c0ce001eSMatthew G. Knepley or at runtime via the option 936c0ce001eSMatthew G. Knepley .vb 937c0ce001eSMatthew G. Knepley -petscfv_type my_fv 938c0ce001eSMatthew G. Knepley .ve 939c0ce001eSMatthew G. Knepley 940c0ce001eSMatthew G. Knepley Level: advanced 941c0ce001eSMatthew G. Knepley 942c0ce001eSMatthew G. Knepley .seealso: PetscFVRegisterAll(), PetscFVRegisterDestroy() 943c0ce001eSMatthew G. Knepley 944c0ce001eSMatthew G. Knepley @*/ 945c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVRegister(const char sname[], PetscErrorCode (*function)(PetscFV)) 946c0ce001eSMatthew G. Knepley { 947c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 948c0ce001eSMatthew G. Knepley 949c0ce001eSMatthew G. Knepley PetscFunctionBegin; 950c0ce001eSMatthew G. Knepley ierr = PetscFunctionListAdd(&PetscFVList, sname, function);CHKERRQ(ierr); 951c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 952c0ce001eSMatthew G. Knepley } 953c0ce001eSMatthew G. Knepley 954c0ce001eSMatthew G. Knepley /*@C 955c0ce001eSMatthew G. Knepley PetscFVSetType - Builds a particular PetscFV 956c0ce001eSMatthew G. Knepley 957c0ce001eSMatthew G. Knepley Collective on fvm 958c0ce001eSMatthew G. Knepley 959c0ce001eSMatthew G. Knepley Input Parameters: 960c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 961c0ce001eSMatthew G. Knepley - name - The kind of FVM space 962c0ce001eSMatthew G. Knepley 963c0ce001eSMatthew G. Knepley Options Database Key: 964c0ce001eSMatthew G. Knepley . -petscfv_type <type> - Sets the PetscFV type; use -help for a list of available types 965c0ce001eSMatthew G. Knepley 966c0ce001eSMatthew G. Knepley Level: intermediate 967c0ce001eSMatthew G. Knepley 968c0ce001eSMatthew G. Knepley .seealso: PetscFVGetType(), PetscFVCreate() 969c0ce001eSMatthew G. Knepley @*/ 970c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetType(PetscFV fvm, PetscFVType name) 971c0ce001eSMatthew G. Knepley { 972c0ce001eSMatthew G. Knepley PetscErrorCode (*r)(PetscFV); 973c0ce001eSMatthew G. Knepley PetscBool match; 974c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 975c0ce001eSMatthew G. Knepley 976c0ce001eSMatthew G. Knepley PetscFunctionBegin; 977c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 978c0ce001eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) fvm, name, &match);CHKERRQ(ierr); 979c0ce001eSMatthew G. Knepley if (match) PetscFunctionReturn(0); 980c0ce001eSMatthew G. Knepley 981c0ce001eSMatthew G. Knepley ierr = PetscFVRegisterAll();CHKERRQ(ierr); 982c0ce001eSMatthew G. Knepley ierr = PetscFunctionListFind(PetscFVList, name, &r);CHKERRQ(ierr); 983c0ce001eSMatthew G. Knepley if (!r) SETERRQ1(PetscObjectComm((PetscObject) fvm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscFV type: %s", name); 984c0ce001eSMatthew G. Knepley 985c0ce001eSMatthew G. Knepley if (fvm->ops->destroy) { 986c0ce001eSMatthew G. Knepley ierr = (*fvm->ops->destroy)(fvm);CHKERRQ(ierr); 987c0ce001eSMatthew G. Knepley fvm->ops->destroy = NULL; 988c0ce001eSMatthew G. Knepley } 989c0ce001eSMatthew G. Knepley ierr = (*r)(fvm);CHKERRQ(ierr); 990c0ce001eSMatthew G. Knepley ierr = PetscObjectChangeTypeName((PetscObject) fvm, name);CHKERRQ(ierr); 991c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 992c0ce001eSMatthew G. Knepley } 993c0ce001eSMatthew G. Knepley 994c0ce001eSMatthew G. Knepley /*@C 995c0ce001eSMatthew G. Knepley PetscFVGetType - Gets the PetscFV type name (as a string) from the object. 996c0ce001eSMatthew G. Knepley 997c0ce001eSMatthew G. Knepley Not Collective 998c0ce001eSMatthew G. Knepley 999c0ce001eSMatthew G. Knepley Input Parameter: 1000c0ce001eSMatthew G. Knepley . fvm - The PetscFV 1001c0ce001eSMatthew G. Knepley 1002c0ce001eSMatthew G. Knepley Output Parameter: 1003c0ce001eSMatthew G. Knepley . name - The PetscFV type name 1004c0ce001eSMatthew G. Knepley 1005c0ce001eSMatthew G. Knepley Level: intermediate 1006c0ce001eSMatthew G. Knepley 1007c0ce001eSMatthew G. Knepley .seealso: PetscFVSetType(), PetscFVCreate() 1008c0ce001eSMatthew G. Knepley @*/ 1009c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetType(PetscFV fvm, PetscFVType *name) 1010c0ce001eSMatthew G. Knepley { 1011c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1012c0ce001eSMatthew G. Knepley 1013c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1014c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1015c0ce001eSMatthew G. Knepley PetscValidPointer(name, 2); 1016c0ce001eSMatthew G. Knepley ierr = PetscFVRegisterAll();CHKERRQ(ierr); 1017c0ce001eSMatthew G. Knepley *name = ((PetscObject) fvm)->type_name; 1018c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1019c0ce001eSMatthew G. Knepley } 1020c0ce001eSMatthew G. Knepley 1021c0ce001eSMatthew G. Knepley /*@C 1022c0ce001eSMatthew G. Knepley PetscFVView - Views a PetscFV 1023c0ce001eSMatthew G. Knepley 1024c0ce001eSMatthew G. Knepley Collective on fvm 1025c0ce001eSMatthew G. Knepley 1026c0ce001eSMatthew G. Knepley Input Parameter: 1027c0ce001eSMatthew G. Knepley + fvm - the PetscFV object to view 1028c0ce001eSMatthew G. Knepley - v - the viewer 1029c0ce001eSMatthew G. Knepley 103088f5f89eSMatthew G. Knepley Level: beginner 1031c0ce001eSMatthew G. Knepley 1032c0ce001eSMatthew G. Knepley .seealso: PetscFVDestroy() 1033c0ce001eSMatthew G. Knepley @*/ 1034c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVView(PetscFV fvm, PetscViewer v) 1035c0ce001eSMatthew G. Knepley { 1036c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1037c0ce001eSMatthew G. Knepley 1038c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1039c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1040c0ce001eSMatthew G. Knepley if (!v) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) fvm), &v);CHKERRQ(ierr);} 1041c0ce001eSMatthew G. Knepley if (fvm->ops->view) {ierr = (*fvm->ops->view)(fvm, v);CHKERRQ(ierr);} 1042c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1043c0ce001eSMatthew G. Knepley } 1044c0ce001eSMatthew G. Knepley 1045c0ce001eSMatthew G. Knepley /*@ 1046c0ce001eSMatthew G. Knepley PetscFVSetFromOptions - sets parameters in a PetscFV from the options database 1047c0ce001eSMatthew G. Knepley 1048c0ce001eSMatthew G. Knepley Collective on fvm 1049c0ce001eSMatthew G. Knepley 1050c0ce001eSMatthew G. Knepley Input Parameter: 1051c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to set options for 1052c0ce001eSMatthew G. Knepley 1053c0ce001eSMatthew G. Knepley Options Database Key: 1054c0ce001eSMatthew G. Knepley . -petscfv_compute_gradients <bool> - Determines whether cell gradients are calculated 1055c0ce001eSMatthew G. Knepley 105688f5f89eSMatthew G. Knepley Level: intermediate 1057c0ce001eSMatthew G. Knepley 1058c0ce001eSMatthew G. Knepley .seealso: PetscFVView() 1059c0ce001eSMatthew G. Knepley @*/ 1060c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetFromOptions(PetscFV fvm) 1061c0ce001eSMatthew G. Knepley { 1062c0ce001eSMatthew G. Knepley const char *defaultType; 1063c0ce001eSMatthew G. Knepley char name[256]; 1064c0ce001eSMatthew G. Knepley PetscBool flg; 1065c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1066c0ce001eSMatthew G. Knepley 1067c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1068c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1069c0ce001eSMatthew G. Knepley if (!((PetscObject) fvm)->type_name) defaultType = PETSCFVUPWIND; 1070c0ce001eSMatthew G. Knepley else defaultType = ((PetscObject) fvm)->type_name; 1071c0ce001eSMatthew G. Knepley ierr = PetscFVRegisterAll();CHKERRQ(ierr); 1072c0ce001eSMatthew G. Knepley 1073c0ce001eSMatthew G. Knepley ierr = PetscObjectOptionsBegin((PetscObject) fvm);CHKERRQ(ierr); 1074c0ce001eSMatthew G. Knepley ierr = PetscOptionsFList("-petscfv_type", "Finite volume discretization", "PetscFVSetType", PetscFVList, defaultType, name, 256, &flg);CHKERRQ(ierr); 1075c0ce001eSMatthew G. Knepley if (flg) { 1076c0ce001eSMatthew G. Knepley ierr = PetscFVSetType(fvm, name);CHKERRQ(ierr); 1077c0ce001eSMatthew G. Knepley } else if (!((PetscObject) fvm)->type_name) { 1078c0ce001eSMatthew G. Knepley ierr = PetscFVSetType(fvm, defaultType);CHKERRQ(ierr); 1079c0ce001eSMatthew G. Knepley 1080c0ce001eSMatthew G. Knepley } 1081c0ce001eSMatthew G. Knepley ierr = PetscOptionsBool("-petscfv_compute_gradients", "Compute cell gradients", "PetscFVSetComputeGradients", fvm->computeGradients, &fvm->computeGradients, NULL);CHKERRQ(ierr); 1082c0ce001eSMatthew G. Knepley if (fvm->ops->setfromoptions) {ierr = (*fvm->ops->setfromoptions)(fvm);CHKERRQ(ierr);} 1083c0ce001eSMatthew G. Knepley /* process any options handlers added with PetscObjectAddOptionsHandler() */ 1084c0ce001eSMatthew G. Knepley ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) fvm);CHKERRQ(ierr); 1085c0ce001eSMatthew G. Knepley ierr = PetscLimiterSetFromOptions(fvm->limiter);CHKERRQ(ierr); 1086c0ce001eSMatthew G. Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 1087c0ce001eSMatthew G. Knepley ierr = PetscFVViewFromOptions(fvm, NULL, "-petscfv_view");CHKERRQ(ierr); 1088c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1089c0ce001eSMatthew G. Knepley } 1090c0ce001eSMatthew G. Knepley 1091c0ce001eSMatthew G. Knepley /*@ 1092c0ce001eSMatthew G. Knepley PetscFVSetUp - Construct data structures for the PetscFV 1093c0ce001eSMatthew G. Knepley 1094c0ce001eSMatthew G. Knepley Collective on fvm 1095c0ce001eSMatthew G. Knepley 1096c0ce001eSMatthew G. Knepley Input Parameter: 1097c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to setup 1098c0ce001eSMatthew G. Knepley 109988f5f89eSMatthew G. Knepley Level: intermediate 1100c0ce001eSMatthew G. Knepley 1101c0ce001eSMatthew G. Knepley .seealso: PetscFVView(), PetscFVDestroy() 1102c0ce001eSMatthew G. Knepley @*/ 1103c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetUp(PetscFV fvm) 1104c0ce001eSMatthew G. Knepley { 1105c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1106c0ce001eSMatthew G. Knepley 1107c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1108c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1109c0ce001eSMatthew G. Knepley ierr = PetscLimiterSetUp(fvm->limiter);CHKERRQ(ierr); 1110c0ce001eSMatthew G. Knepley if (fvm->ops->setup) {ierr = (*fvm->ops->setup)(fvm);CHKERRQ(ierr);} 1111c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1112c0ce001eSMatthew G. Knepley } 1113c0ce001eSMatthew G. Knepley 1114c0ce001eSMatthew G. Knepley /*@ 1115c0ce001eSMatthew G. Knepley PetscFVDestroy - Destroys a PetscFV object 1116c0ce001eSMatthew G. Knepley 1117c0ce001eSMatthew G. Knepley Collective on fvm 1118c0ce001eSMatthew G. Knepley 1119c0ce001eSMatthew G. Knepley Input Parameter: 1120c0ce001eSMatthew G. Knepley . fvm - the PetscFV object to destroy 1121c0ce001eSMatthew G. Knepley 112288f5f89eSMatthew G. Knepley Level: beginner 1123c0ce001eSMatthew G. Knepley 1124c0ce001eSMatthew G. Knepley .seealso: PetscFVView() 1125c0ce001eSMatthew G. Knepley @*/ 1126c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVDestroy(PetscFV *fvm) 1127c0ce001eSMatthew G. Knepley { 1128c0ce001eSMatthew G. Knepley PetscInt i; 1129c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1130c0ce001eSMatthew G. Knepley 1131c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1132c0ce001eSMatthew G. Knepley if (!*fvm) PetscFunctionReturn(0); 1133c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific((*fvm), PETSCFV_CLASSID, 1); 1134c0ce001eSMatthew G. Knepley 1135c0ce001eSMatthew G. Knepley if (--((PetscObject)(*fvm))->refct > 0) {*fvm = 0; PetscFunctionReturn(0);} 1136c0ce001eSMatthew G. Knepley ((PetscObject) (*fvm))->refct = 0; 1137c0ce001eSMatthew G. Knepley 1138c0ce001eSMatthew G. Knepley for (i = 0; i < (*fvm)->numComponents; i++) { 1139c0ce001eSMatthew G. Knepley ierr = PetscFree((*fvm)->componentNames[i]);CHKERRQ(ierr); 1140c0ce001eSMatthew G. Knepley } 1141c0ce001eSMatthew G. Knepley ierr = PetscFree((*fvm)->componentNames);CHKERRQ(ierr); 1142c0ce001eSMatthew G. Knepley ierr = PetscLimiterDestroy(&(*fvm)->limiter);CHKERRQ(ierr); 1143c0ce001eSMatthew G. Knepley ierr = PetscDualSpaceDestroy(&(*fvm)->dualSpace);CHKERRQ(ierr); 1144c0ce001eSMatthew G. Knepley ierr = PetscFree((*fvm)->fluxWork);CHKERRQ(ierr); 1145c0ce001eSMatthew G. Knepley ierr = PetscQuadratureDestroy(&(*fvm)->quadrature);CHKERRQ(ierr); 1146c0ce001eSMatthew G. Knepley ierr = PetscFVRestoreTabulation((*fvm), 0, NULL, &(*fvm)->B, &(*fvm)->D, NULL /*&(*fvm)->H*/);CHKERRQ(ierr); 1147c0ce001eSMatthew G. Knepley 1148c0ce001eSMatthew G. Knepley if ((*fvm)->ops->destroy) {ierr = (*(*fvm)->ops->destroy)(*fvm);CHKERRQ(ierr);} 1149c0ce001eSMatthew G. Knepley ierr = PetscHeaderDestroy(fvm);CHKERRQ(ierr); 1150c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1151c0ce001eSMatthew G. Knepley } 1152c0ce001eSMatthew G. Knepley 1153c0ce001eSMatthew G. Knepley /*@ 1154c0ce001eSMatthew G. Knepley PetscFVCreate - Creates an empty PetscFV object. The type can then be set with PetscFVSetType(). 1155c0ce001eSMatthew G. Knepley 1156c0ce001eSMatthew G. Knepley Collective 1157c0ce001eSMatthew G. Knepley 1158c0ce001eSMatthew G. Knepley Input Parameter: 1159c0ce001eSMatthew G. Knepley . comm - The communicator for the PetscFV object 1160c0ce001eSMatthew G. Knepley 1161c0ce001eSMatthew G. Knepley Output Parameter: 1162c0ce001eSMatthew G. Knepley . fvm - The PetscFV object 1163c0ce001eSMatthew G. Knepley 1164c0ce001eSMatthew G. Knepley Level: beginner 1165c0ce001eSMatthew G. Knepley 1166c0ce001eSMatthew G. Knepley .seealso: PetscFVSetType(), PETSCFVUPWIND 1167c0ce001eSMatthew G. Knepley @*/ 1168c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVCreate(MPI_Comm comm, PetscFV *fvm) 1169c0ce001eSMatthew G. Knepley { 1170c0ce001eSMatthew G. Knepley PetscFV f; 1171c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1172c0ce001eSMatthew G. Knepley 1173c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1174c0ce001eSMatthew G. Knepley PetscValidPointer(fvm, 2); 1175c0ce001eSMatthew G. Knepley *fvm = NULL; 1176c0ce001eSMatthew G. Knepley ierr = PetscFVInitializePackage();CHKERRQ(ierr); 1177c0ce001eSMatthew G. Knepley 1178c0ce001eSMatthew G. Knepley ierr = PetscHeaderCreate(f, PETSCFV_CLASSID, "PetscFV", "Finite Volume", "PetscFV", comm, PetscFVDestroy, PetscFVView);CHKERRQ(ierr); 1179c0ce001eSMatthew G. Knepley ierr = PetscMemzero(f->ops, sizeof(struct _PetscFVOps));CHKERRQ(ierr); 1180c0ce001eSMatthew G. Knepley 1181c0ce001eSMatthew G. Knepley ierr = PetscLimiterCreate(comm, &f->limiter);CHKERRQ(ierr); 1182c0ce001eSMatthew G. Knepley f->numComponents = 1; 1183c0ce001eSMatthew G. Knepley f->dim = 0; 1184c0ce001eSMatthew G. Knepley f->computeGradients = PETSC_FALSE; 1185c0ce001eSMatthew G. Knepley f->fluxWork = NULL; 1186c0ce001eSMatthew G. Knepley ierr = PetscCalloc1(f->numComponents,&f->componentNames);CHKERRQ(ierr); 1187c0ce001eSMatthew G. Knepley 1188c0ce001eSMatthew G. Knepley *fvm = f; 1189c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1190c0ce001eSMatthew G. Knepley } 1191c0ce001eSMatthew G. Knepley 1192c0ce001eSMatthew G. Knepley /*@ 1193c0ce001eSMatthew G. Knepley PetscFVSetLimiter - Set the limiter object 1194c0ce001eSMatthew G. Knepley 1195c0ce001eSMatthew G. Knepley Logically collective on fvm 1196c0ce001eSMatthew G. Knepley 1197c0ce001eSMatthew G. Knepley Input Parameters: 1198c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1199c0ce001eSMatthew G. Knepley - lim - The PetscLimiter 1200c0ce001eSMatthew G. Knepley 120188f5f89eSMatthew G. Knepley Level: intermediate 1202c0ce001eSMatthew G. Knepley 1203c0ce001eSMatthew G. Knepley .seealso: PetscFVGetLimiter() 1204c0ce001eSMatthew G. Knepley @*/ 1205c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetLimiter(PetscFV fvm, PetscLimiter lim) 1206c0ce001eSMatthew G. Knepley { 1207c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1208c0ce001eSMatthew G. Knepley 1209c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1210c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1211c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(lim, PETSCLIMITER_CLASSID, 2); 1212c0ce001eSMatthew G. Knepley ierr = PetscLimiterDestroy(&fvm->limiter);CHKERRQ(ierr); 1213c0ce001eSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) lim);CHKERRQ(ierr); 1214c0ce001eSMatthew G. Knepley fvm->limiter = lim; 1215c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1216c0ce001eSMatthew G. Knepley } 1217c0ce001eSMatthew G. Knepley 1218c0ce001eSMatthew G. Knepley /*@ 1219c0ce001eSMatthew G. Knepley PetscFVGetLimiter - Get the limiter object 1220c0ce001eSMatthew G. Knepley 1221c0ce001eSMatthew G. Knepley Not collective 1222c0ce001eSMatthew G. Knepley 1223c0ce001eSMatthew G. Knepley Input Parameter: 1224c0ce001eSMatthew G. Knepley . fvm - the PetscFV object 1225c0ce001eSMatthew G. Knepley 1226c0ce001eSMatthew G. Knepley Output Parameter: 1227c0ce001eSMatthew G. Knepley . lim - The PetscLimiter 1228c0ce001eSMatthew G. Knepley 122988f5f89eSMatthew G. Knepley Level: intermediate 1230c0ce001eSMatthew G. Knepley 1231c0ce001eSMatthew G. Knepley .seealso: PetscFVSetLimiter() 1232c0ce001eSMatthew G. Knepley @*/ 1233c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetLimiter(PetscFV fvm, PetscLimiter *lim) 1234c0ce001eSMatthew G. Knepley { 1235c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1236c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1237c0ce001eSMatthew G. Knepley PetscValidPointer(lim, 2); 1238c0ce001eSMatthew G. Knepley *lim = fvm->limiter; 1239c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1240c0ce001eSMatthew G. Knepley } 1241c0ce001eSMatthew G. Knepley 1242c0ce001eSMatthew G. Knepley /*@ 1243c0ce001eSMatthew G. Knepley PetscFVSetNumComponents - Set the number of field components 1244c0ce001eSMatthew G. Knepley 1245c0ce001eSMatthew G. Knepley Logically collective on fvm 1246c0ce001eSMatthew G. Knepley 1247c0ce001eSMatthew G. Knepley Input Parameters: 1248c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1249c0ce001eSMatthew G. Knepley - comp - The number of components 1250c0ce001eSMatthew G. Knepley 125188f5f89eSMatthew G. Knepley Level: intermediate 1252c0ce001eSMatthew G. Knepley 1253c0ce001eSMatthew G. Knepley .seealso: PetscFVGetNumComponents() 1254c0ce001eSMatthew G. Knepley @*/ 1255c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetNumComponents(PetscFV fvm, PetscInt comp) 1256c0ce001eSMatthew G. Knepley { 1257c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1258c0ce001eSMatthew G. Knepley 1259c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1260c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1261c0ce001eSMatthew G. Knepley if (fvm->numComponents != comp) { 1262c0ce001eSMatthew G. Knepley PetscInt i; 1263c0ce001eSMatthew G. Knepley 1264c0ce001eSMatthew G. Knepley for (i = 0; i < fvm->numComponents; i++) { 1265c0ce001eSMatthew G. Knepley ierr = PetscFree(fvm->componentNames[i]);CHKERRQ(ierr); 1266c0ce001eSMatthew G. Knepley } 1267c0ce001eSMatthew G. Knepley ierr = PetscFree(fvm->componentNames);CHKERRQ(ierr); 1268c0ce001eSMatthew G. Knepley ierr = PetscCalloc1(comp,&fvm->componentNames);CHKERRQ(ierr); 1269c0ce001eSMatthew G. Knepley } 1270c0ce001eSMatthew G. Knepley fvm->numComponents = comp; 1271c0ce001eSMatthew G. Knepley ierr = PetscFree(fvm->fluxWork);CHKERRQ(ierr); 1272c0ce001eSMatthew G. Knepley ierr = PetscMalloc1(comp, &fvm->fluxWork);CHKERRQ(ierr); 1273c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1274c0ce001eSMatthew G. Knepley } 1275c0ce001eSMatthew G. Knepley 1276c0ce001eSMatthew G. Knepley /*@ 1277c0ce001eSMatthew G. Knepley PetscFVGetNumComponents - Get the number of field components 1278c0ce001eSMatthew G. Knepley 1279c0ce001eSMatthew G. Knepley Not collective 1280c0ce001eSMatthew G. Knepley 1281c0ce001eSMatthew G. Knepley Input Parameter: 1282c0ce001eSMatthew G. Knepley . fvm - the PetscFV object 1283c0ce001eSMatthew G. Knepley 1284c0ce001eSMatthew G. Knepley Output Parameter: 1285c0ce001eSMatthew G. Knepley , comp - The number of components 1286c0ce001eSMatthew G. Knepley 128788f5f89eSMatthew G. Knepley Level: intermediate 1288c0ce001eSMatthew G. Knepley 1289c0ce001eSMatthew G. Knepley .seealso: PetscFVSetNumComponents() 1290c0ce001eSMatthew G. Knepley @*/ 1291c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetNumComponents(PetscFV fvm, PetscInt *comp) 1292c0ce001eSMatthew G. Knepley { 1293c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1294c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1295c0ce001eSMatthew G. Knepley PetscValidPointer(comp, 2); 1296c0ce001eSMatthew G. Knepley *comp = fvm->numComponents; 1297c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1298c0ce001eSMatthew G. Knepley } 1299c0ce001eSMatthew G. Knepley 1300c0ce001eSMatthew G. Knepley /*@C 1301c0ce001eSMatthew G. Knepley PetscFVSetComponentName - Set the name of a component (used in output and viewing) 1302c0ce001eSMatthew G. Knepley 1303c0ce001eSMatthew G. Knepley Logically collective on fvm 1304c0ce001eSMatthew G. Knepley Input Parameters: 1305c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1306c0ce001eSMatthew G. Knepley . comp - the component number 1307c0ce001eSMatthew G. Knepley - name - the component name 1308c0ce001eSMatthew G. Knepley 130988f5f89eSMatthew G. Knepley Level: intermediate 1310c0ce001eSMatthew G. Knepley 1311c0ce001eSMatthew G. Knepley .seealso: PetscFVGetComponentName() 1312c0ce001eSMatthew G. Knepley @*/ 1313c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetComponentName(PetscFV fvm, PetscInt comp, const char *name) 1314c0ce001eSMatthew G. Knepley { 1315c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1316c0ce001eSMatthew G. Knepley 1317c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1318c0ce001eSMatthew G. Knepley ierr = PetscFree(fvm->componentNames[comp]);CHKERRQ(ierr); 1319c0ce001eSMatthew G. Knepley ierr = PetscStrallocpy(name,&fvm->componentNames[comp]);CHKERRQ(ierr); 1320c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1321c0ce001eSMatthew G. Knepley } 1322c0ce001eSMatthew G. Knepley 1323c0ce001eSMatthew G. Knepley /*@C 1324c0ce001eSMatthew G. Knepley PetscFVGetComponentName - Get the name of a component (used in output and viewing) 1325c0ce001eSMatthew G. Knepley 1326c0ce001eSMatthew G. Knepley Logically collective on fvm 1327c0ce001eSMatthew G. Knepley Input Parameters: 1328c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1329c0ce001eSMatthew G. Knepley - comp - the component number 1330c0ce001eSMatthew G. Knepley 1331c0ce001eSMatthew G. Knepley Output Parameter: 1332c0ce001eSMatthew G. Knepley . name - the component name 1333c0ce001eSMatthew G. Knepley 133488f5f89eSMatthew G. Knepley Level: intermediate 1335c0ce001eSMatthew G. Knepley 1336c0ce001eSMatthew G. Knepley .seealso: PetscFVSetComponentName() 1337c0ce001eSMatthew G. Knepley @*/ 1338c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetComponentName(PetscFV fvm, PetscInt comp, const char **name) 1339c0ce001eSMatthew G. Knepley { 1340c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1341c0ce001eSMatthew G. Knepley *name = fvm->componentNames[comp]; 1342c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1343c0ce001eSMatthew G. Knepley } 1344c0ce001eSMatthew G. Knepley 1345c0ce001eSMatthew G. Knepley /*@ 1346c0ce001eSMatthew G. Knepley PetscFVSetSpatialDimension - Set the spatial dimension 1347c0ce001eSMatthew G. Knepley 1348c0ce001eSMatthew G. Knepley Logically collective on fvm 1349c0ce001eSMatthew G. Knepley 1350c0ce001eSMatthew G. Knepley Input Parameters: 1351c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1352c0ce001eSMatthew G. Knepley - dim - The spatial dimension 1353c0ce001eSMatthew G. Knepley 135488f5f89eSMatthew G. Knepley Level: intermediate 1355c0ce001eSMatthew G. Knepley 1356c0ce001eSMatthew G. Knepley .seealso: PetscFVGetSpatialDimension() 1357c0ce001eSMatthew G. Knepley @*/ 1358c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetSpatialDimension(PetscFV fvm, PetscInt dim) 1359c0ce001eSMatthew G. Knepley { 1360c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1361c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1362c0ce001eSMatthew G. Knepley fvm->dim = dim; 1363c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1364c0ce001eSMatthew G. Knepley } 1365c0ce001eSMatthew G. Knepley 1366c0ce001eSMatthew G. Knepley /*@ 1367c0ce001eSMatthew G. Knepley PetscFVGetSpatialDimension - Get the spatial dimension 1368c0ce001eSMatthew G. Knepley 1369c0ce001eSMatthew G. Knepley Logically collective on fvm 1370c0ce001eSMatthew G. Knepley 1371c0ce001eSMatthew G. Knepley Input Parameter: 1372c0ce001eSMatthew G. Knepley . fvm - the PetscFV object 1373c0ce001eSMatthew G. Knepley 1374c0ce001eSMatthew G. Knepley Output Parameter: 1375c0ce001eSMatthew G. Knepley . dim - The spatial dimension 1376c0ce001eSMatthew G. Knepley 137788f5f89eSMatthew G. Knepley Level: intermediate 1378c0ce001eSMatthew G. Knepley 1379c0ce001eSMatthew G. Knepley .seealso: PetscFVSetSpatialDimension() 1380c0ce001eSMatthew G. Knepley @*/ 1381c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetSpatialDimension(PetscFV fvm, PetscInt *dim) 1382c0ce001eSMatthew G. Knepley { 1383c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1384c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1385c0ce001eSMatthew G. Knepley PetscValidPointer(dim, 2); 1386c0ce001eSMatthew G. Knepley *dim = fvm->dim; 1387c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1388c0ce001eSMatthew G. Knepley } 1389c0ce001eSMatthew G. Knepley 1390c0ce001eSMatthew G. Knepley /*@ 1391c0ce001eSMatthew G. Knepley PetscFVSetComputeGradients - Toggle computation of cell gradients 1392c0ce001eSMatthew G. Knepley 1393c0ce001eSMatthew G. Knepley Logically collective on fvm 1394c0ce001eSMatthew G. Knepley 1395c0ce001eSMatthew G. Knepley Input Parameters: 1396c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1397c0ce001eSMatthew G. Knepley - computeGradients - Flag to compute cell gradients 1398c0ce001eSMatthew G. Knepley 139988f5f89eSMatthew G. Knepley Level: intermediate 1400c0ce001eSMatthew G. Knepley 1401c0ce001eSMatthew G. Knepley .seealso: PetscFVGetComputeGradients() 1402c0ce001eSMatthew G. Knepley @*/ 1403c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetComputeGradients(PetscFV fvm, PetscBool computeGradients) 1404c0ce001eSMatthew G. Knepley { 1405c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1406c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1407c0ce001eSMatthew G. Knepley fvm->computeGradients = computeGradients; 1408c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1409c0ce001eSMatthew G. Knepley } 1410c0ce001eSMatthew G. Knepley 1411c0ce001eSMatthew G. Knepley /*@ 1412c0ce001eSMatthew G. Knepley PetscFVGetComputeGradients - Return flag for computation of cell gradients 1413c0ce001eSMatthew G. Knepley 1414c0ce001eSMatthew G. Knepley Not collective 1415c0ce001eSMatthew G. Knepley 1416c0ce001eSMatthew G. Knepley Input Parameter: 1417c0ce001eSMatthew G. Knepley . fvm - the PetscFV object 1418c0ce001eSMatthew G. Knepley 1419c0ce001eSMatthew G. Knepley Output Parameter: 1420c0ce001eSMatthew G. Knepley . computeGradients - Flag to compute cell gradients 1421c0ce001eSMatthew G. Knepley 142288f5f89eSMatthew G. Knepley Level: intermediate 1423c0ce001eSMatthew G. Knepley 1424c0ce001eSMatthew G. Knepley .seealso: PetscFVSetComputeGradients() 1425c0ce001eSMatthew G. Knepley @*/ 1426c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetComputeGradients(PetscFV fvm, PetscBool *computeGradients) 1427c0ce001eSMatthew G. Knepley { 1428c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1429c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1430c0ce001eSMatthew G. Knepley PetscValidPointer(computeGradients, 2); 1431c0ce001eSMatthew G. Knepley *computeGradients = fvm->computeGradients; 1432c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1433c0ce001eSMatthew G. Knepley } 1434c0ce001eSMatthew G. Knepley 1435c0ce001eSMatthew G. Knepley /*@ 1436c0ce001eSMatthew G. Knepley PetscFVSetQuadrature - Set the quadrature object 1437c0ce001eSMatthew G. Knepley 1438c0ce001eSMatthew G. Knepley Logically collective on fvm 1439c0ce001eSMatthew G. Knepley 1440c0ce001eSMatthew G. Knepley Input Parameters: 1441c0ce001eSMatthew G. Knepley + fvm - the PetscFV object 1442c0ce001eSMatthew G. Knepley - q - The PetscQuadrature 1443c0ce001eSMatthew G. Knepley 144488f5f89eSMatthew G. Knepley Level: intermediate 1445c0ce001eSMatthew G. Knepley 1446c0ce001eSMatthew G. Knepley .seealso: PetscFVGetQuadrature() 1447c0ce001eSMatthew G. Knepley @*/ 1448c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetQuadrature(PetscFV fvm, PetscQuadrature q) 1449c0ce001eSMatthew G. Knepley { 1450c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1451c0ce001eSMatthew G. Knepley 1452c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1453c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1454c0ce001eSMatthew G. Knepley ierr = PetscQuadratureDestroy(&fvm->quadrature);CHKERRQ(ierr); 1455c0ce001eSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) q);CHKERRQ(ierr); 1456c0ce001eSMatthew G. Knepley fvm->quadrature = q; 1457c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1458c0ce001eSMatthew G. Knepley } 1459c0ce001eSMatthew G. Knepley 1460c0ce001eSMatthew G. Knepley /*@ 1461c0ce001eSMatthew G. Knepley PetscFVGetQuadrature - Get the quadrature object 1462c0ce001eSMatthew G. Knepley 1463c0ce001eSMatthew G. Knepley Not collective 1464c0ce001eSMatthew G. Knepley 1465c0ce001eSMatthew G. Knepley Input Parameter: 1466c0ce001eSMatthew G. Knepley . fvm - the PetscFV object 1467c0ce001eSMatthew G. Knepley 1468c0ce001eSMatthew G. Knepley Output Parameter: 1469c0ce001eSMatthew G. Knepley . lim - The PetscQuadrature 1470c0ce001eSMatthew G. Knepley 147188f5f89eSMatthew G. Knepley Level: intermediate 1472c0ce001eSMatthew G. Knepley 1473c0ce001eSMatthew G. Knepley .seealso: PetscFVSetQuadrature() 1474c0ce001eSMatthew G. Knepley @*/ 1475c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetQuadrature(PetscFV fvm, PetscQuadrature *q) 1476c0ce001eSMatthew G. Knepley { 1477c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1478c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1479c0ce001eSMatthew G. Knepley PetscValidPointer(q, 2); 1480c0ce001eSMatthew G. Knepley if (!fvm->quadrature) { 1481c0ce001eSMatthew G. Knepley /* Create default 1-point quadrature */ 1482c0ce001eSMatthew G. Knepley PetscReal *points, *weights; 1483c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1484c0ce001eSMatthew G. Knepley 1485c0ce001eSMatthew G. Knepley ierr = PetscQuadratureCreate(PETSC_COMM_SELF, &fvm->quadrature);CHKERRQ(ierr); 1486c0ce001eSMatthew G. Knepley ierr = PetscCalloc1(fvm->dim, &points);CHKERRQ(ierr); 1487c0ce001eSMatthew G. Knepley ierr = PetscMalloc1(1, &weights);CHKERRQ(ierr); 1488c0ce001eSMatthew G. Knepley weights[0] = 1.0; 1489c0ce001eSMatthew G. Knepley ierr = PetscQuadratureSetData(fvm->quadrature, fvm->dim, 1, 1, points, weights);CHKERRQ(ierr); 1490c0ce001eSMatthew G. Knepley } 1491c0ce001eSMatthew G. Knepley *q = fvm->quadrature; 1492c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1493c0ce001eSMatthew G. Knepley } 1494c0ce001eSMatthew G. Knepley 1495c0ce001eSMatthew G. Knepley /*@ 1496c0ce001eSMatthew G. Knepley PetscFVGetDualSpace - Returns the PetscDualSpace used to define the inner product 1497c0ce001eSMatthew G. Knepley 1498c0ce001eSMatthew G. Knepley Not collective 1499c0ce001eSMatthew G. Knepley 1500c0ce001eSMatthew G. Knepley Input Parameter: 1501c0ce001eSMatthew G. Knepley . fvm - The PetscFV object 1502c0ce001eSMatthew G. Knepley 1503c0ce001eSMatthew G. Knepley Output Parameter: 1504c0ce001eSMatthew G. Knepley . sp - The PetscDualSpace object 1505c0ce001eSMatthew G. Knepley 1506c0ce001eSMatthew G. Knepley Note: A simple dual space is provided automatically, and the user typically will not need to override it. 1507c0ce001eSMatthew G. Knepley 150888f5f89eSMatthew G. Knepley Level: intermediate 1509c0ce001eSMatthew G. Knepley 1510c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate() 1511c0ce001eSMatthew G. Knepley @*/ 1512c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetDualSpace(PetscFV fvm, PetscDualSpace *sp) 1513c0ce001eSMatthew G. Knepley { 1514c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1515c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1516c0ce001eSMatthew G. Knepley PetscValidPointer(sp, 2); 1517c0ce001eSMatthew G. Knepley if (!fvm->dualSpace) { 1518c0ce001eSMatthew G. Knepley DM K; 1519c0ce001eSMatthew G. Knepley PetscInt dim, Nc, c; 1520c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1521c0ce001eSMatthew G. Knepley 1522c0ce001eSMatthew G. Knepley ierr = PetscFVGetSpatialDimension(fvm, &dim);CHKERRQ(ierr); 1523c0ce001eSMatthew G. Knepley ierr = PetscFVGetNumComponents(fvm, &Nc);CHKERRQ(ierr); 1524c0ce001eSMatthew G. Knepley ierr = PetscDualSpaceCreate(PetscObjectComm((PetscObject) fvm), &fvm->dualSpace);CHKERRQ(ierr); 1525c0ce001eSMatthew G. Knepley ierr = PetscDualSpaceSetType(fvm->dualSpace, PETSCDUALSPACESIMPLE);CHKERRQ(ierr); 1526c0ce001eSMatthew G. Knepley ierr = PetscDualSpaceCreateReferenceCell(fvm->dualSpace, dim, PETSC_FALSE, &K);CHKERRQ(ierr); /* TODO: The reference cell type should be held by the discretization object */ 1527c0ce001eSMatthew G. Knepley ierr = PetscDualSpaceSetNumComponents(fvm->dualSpace, Nc);CHKERRQ(ierr); 1528c0ce001eSMatthew G. Knepley ierr = PetscDualSpaceSetDM(fvm->dualSpace, K);CHKERRQ(ierr); 1529c0ce001eSMatthew G. Knepley ierr = DMDestroy(&K);CHKERRQ(ierr); 1530c0ce001eSMatthew G. Knepley ierr = PetscDualSpaceSimpleSetDimension(fvm->dualSpace, Nc);CHKERRQ(ierr); 1531c0ce001eSMatthew G. Knepley /* Should we be using PetscFVGetQuadrature() here? */ 1532c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; ++c) { 1533c0ce001eSMatthew G. Knepley PetscQuadrature qc; 1534c0ce001eSMatthew G. Knepley PetscReal *points, *weights; 1535c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1536c0ce001eSMatthew G. Knepley 1537c0ce001eSMatthew G. Knepley ierr = PetscQuadratureCreate(PETSC_COMM_SELF, &qc);CHKERRQ(ierr); 1538c0ce001eSMatthew G. Knepley ierr = PetscCalloc1(dim, &points);CHKERRQ(ierr); 1539c0ce001eSMatthew G. Knepley ierr = PetscCalloc1(Nc, &weights);CHKERRQ(ierr); 1540c0ce001eSMatthew G. Knepley weights[c] = 1.0; 1541c0ce001eSMatthew G. Knepley ierr = PetscQuadratureSetData(qc, dim, Nc, 1, points, weights);CHKERRQ(ierr); 1542c0ce001eSMatthew G. Knepley ierr = PetscDualSpaceSimpleSetFunctional(fvm->dualSpace, c, qc);CHKERRQ(ierr); 1543c0ce001eSMatthew G. Knepley ierr = PetscQuadratureDestroy(&qc);CHKERRQ(ierr); 1544c0ce001eSMatthew G. Knepley } 1545c0ce001eSMatthew G. Knepley } 1546c0ce001eSMatthew G. Knepley *sp = fvm->dualSpace; 1547c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1548c0ce001eSMatthew G. Knepley } 1549c0ce001eSMatthew G. Knepley 1550c0ce001eSMatthew G. Knepley /*@ 1551c0ce001eSMatthew G. Knepley PetscFVSetDualSpace - Sets the PetscDualSpace used to define the inner product 1552c0ce001eSMatthew G. Knepley 1553c0ce001eSMatthew G. Knepley Not collective 1554c0ce001eSMatthew G. Knepley 1555c0ce001eSMatthew G. Knepley Input Parameters: 1556c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 1557c0ce001eSMatthew G. Knepley - sp - The PetscDualSpace object 1558c0ce001eSMatthew G. Knepley 1559c0ce001eSMatthew G. Knepley Level: intermediate 1560c0ce001eSMatthew G. Knepley 1561c0ce001eSMatthew G. Knepley Note: A simple dual space is provided automatically, and the user typically will not need to override it. 1562c0ce001eSMatthew G. Knepley 1563c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate() 1564c0ce001eSMatthew G. Knepley @*/ 1565c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVSetDualSpace(PetscFV fvm, PetscDualSpace sp) 1566c0ce001eSMatthew G. Knepley { 1567c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1568c0ce001eSMatthew G. Knepley 1569c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1570c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1571c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 2); 1572c0ce001eSMatthew G. Knepley ierr = PetscDualSpaceDestroy(&fvm->dualSpace);CHKERRQ(ierr); 1573c0ce001eSMatthew G. Knepley fvm->dualSpace = sp; 1574c0ce001eSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) fvm->dualSpace);CHKERRQ(ierr); 1575c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1576c0ce001eSMatthew G. Knepley } 1577c0ce001eSMatthew G. Knepley 157888f5f89eSMatthew G. Knepley /*@C 157988f5f89eSMatthew G. Knepley PetscFVGetDefaultTabulation - Returns the tabulation of the basis functions at the quadrature points 158088f5f89eSMatthew G. Knepley 158188f5f89eSMatthew G. Knepley Not collective 158288f5f89eSMatthew G. Knepley 158388f5f89eSMatthew G. Knepley Input Parameter: 158488f5f89eSMatthew G. Knepley . fvm - The PetscFV object 158588f5f89eSMatthew G. Knepley 158688f5f89eSMatthew G. Knepley Output Parameters: 158788f5f89eSMatthew G. Knepley + B - The basis function values at quadrature points 158888f5f89eSMatthew G. Knepley . D - The basis function derivatives at quadrature points 158988f5f89eSMatthew G. Knepley - H - The basis function second derivatives at quadrature points 159088f5f89eSMatthew G. Knepley 159188f5f89eSMatthew G. Knepley Note: 159288f5f89eSMatthew G. Knepley $ B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 159388f5f89eSMatthew G. Knepley $ D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d 159488f5f89eSMatthew G. Knepley $ 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 159588f5f89eSMatthew G. Knepley 159688f5f89eSMatthew G. Knepley Level: intermediate 159788f5f89eSMatthew G. Knepley 1598*02a061ebSMatthew G. Knepley .seealso: PetscFEGetDefaultTabulation(), PetscFEGetTabulation(), PetscFERestoreTabulation(), PetscFVGetQuadrature(), PetscQuadratureGetData() 159988f5f89eSMatthew G. Knepley @*/ 1600c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetDefaultTabulation(PetscFV fvm, PetscReal **B, PetscReal **D, PetscReal **H) 1601c0ce001eSMatthew G. Knepley { 1602c0ce001eSMatthew G. Knepley PetscInt npoints; 1603c0ce001eSMatthew G. Knepley const PetscReal *points; 1604c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1605c0ce001eSMatthew G. Knepley 1606c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1607c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1608c0ce001eSMatthew G. Knepley if (B) PetscValidPointer(B, 2); 1609c0ce001eSMatthew G. Knepley if (D) PetscValidPointer(D, 3); 1610c0ce001eSMatthew G. Knepley if (H) PetscValidPointer(H, 4); 1611c0ce001eSMatthew G. Knepley ierr = PetscQuadratureGetData(fvm->quadrature, NULL, NULL, &npoints, &points, NULL);CHKERRQ(ierr); 1612c0ce001eSMatthew G. Knepley if (!fvm->B) {ierr = PetscFVGetTabulation(fvm, npoints, points, &fvm->B, &fvm->D, NULL/*&fvm->H*/);CHKERRQ(ierr);} 1613c0ce001eSMatthew G. Knepley if (B) *B = fvm->B; 1614c0ce001eSMatthew G. Knepley if (D) *D = fvm->D; 1615c0ce001eSMatthew G. Knepley if (H) *H = fvm->H; 1616c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1617c0ce001eSMatthew G. Knepley } 1618c0ce001eSMatthew G. Knepley 161988f5f89eSMatthew G. Knepley /*@C 162088f5f89eSMatthew G. Knepley PetscFVGetTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided. 162188f5f89eSMatthew G. Knepley 162288f5f89eSMatthew G. Knepley Not collective 162388f5f89eSMatthew G. Knepley 162488f5f89eSMatthew G. Knepley Input Parameters: 162588f5f89eSMatthew G. Knepley + fvm - The PetscFV object 162688f5f89eSMatthew G. Knepley . npoints - The number of tabulation points 162788f5f89eSMatthew G. Knepley - points - The tabulation point coordinates 162888f5f89eSMatthew G. Knepley 162988f5f89eSMatthew G. Knepley Output Parameters: 163088f5f89eSMatthew G. Knepley + B - The basis function values at tabulation points 163188f5f89eSMatthew G. Knepley . D - The basis function derivatives at tabulation points 163288f5f89eSMatthew G. Knepley - H - The basis function second derivatives at tabulation points 163388f5f89eSMatthew G. Knepley 163488f5f89eSMatthew G. Knepley Note: 163588f5f89eSMatthew G. Knepley $ B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 163688f5f89eSMatthew G. Knepley $ D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d 163788f5f89eSMatthew G. Knepley $ 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 163888f5f89eSMatthew G. Knepley 163988f5f89eSMatthew G. Knepley Level: intermediate 164088f5f89eSMatthew G. Knepley 164188f5f89eSMatthew G. Knepley .seealso: PetscFEGetTabulation(), PetscFERestoreTabulation(), PetscFEGetDefaultTabulation() 164288f5f89eSMatthew G. Knepley @*/ 1643c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVGetTabulation(PetscFV fvm, PetscInt npoints, const PetscReal points[], PetscReal **B, PetscReal **D, PetscReal **H) 1644c0ce001eSMatthew G. Knepley { 1645c0ce001eSMatthew G. Knepley PetscInt pdim = 1; /* Dimension of approximation space P */ 1646c0ce001eSMatthew G. Knepley PetscInt dim; /* Spatial dimension */ 1647c0ce001eSMatthew G. Knepley PetscInt comp; /* Field components */ 1648c0ce001eSMatthew G. Knepley PetscInt p, d, c, e; 1649c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1650c0ce001eSMatthew G. Knepley 1651c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1652c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1653c0ce001eSMatthew G. Knepley PetscValidPointer(points, 3); 1654c0ce001eSMatthew G. Knepley if (B) PetscValidPointer(B, 4); 1655c0ce001eSMatthew G. Knepley if (D) PetscValidPointer(D, 5); 1656c0ce001eSMatthew G. Knepley if (H) PetscValidPointer(H, 6); 1657c0ce001eSMatthew G. Knepley ierr = PetscFVGetSpatialDimension(fvm, &dim);CHKERRQ(ierr); 1658c0ce001eSMatthew G. Knepley ierr = PetscFVGetNumComponents(fvm, &comp);CHKERRQ(ierr); 1659c0ce001eSMatthew G. Knepley if (B) {ierr = PetscMalloc1(npoints*pdim*comp, B);CHKERRQ(ierr);} 1660c0ce001eSMatthew G. Knepley if (D) {ierr = PetscMalloc1(npoints*pdim*comp*dim, D);CHKERRQ(ierr);} 1661c0ce001eSMatthew G. Knepley if (H) {ierr = PetscMalloc1(npoints*pdim*comp*dim*dim, H);CHKERRQ(ierr);} 1662c0ce001eSMatthew G. Knepley if (B) {for (p = 0; p < npoints; ++p) for (d = 0; d < pdim; ++d) for (c = 0; c < comp; ++c) (*B)[(p*pdim + d)*comp + c] = 1.0;} 1663c0ce001eSMatthew G. Knepley if (D) {for (p = 0; p < npoints; ++p) for (d = 0; d < pdim; ++d) for (c = 0; c < comp; ++c) for (e = 0; e < dim; ++e) (*D)[((p*pdim + d)*comp + c)*dim + e] = 0.0;} 1664c0ce001eSMatthew G. Knepley if (H) {for (p = 0; p < npoints; ++p) for (d = 0; d < pdim; ++d) for (c = 0; c < comp; ++c) for (e = 0; e < dim*dim; ++e) (*H)[((p*pdim + d)*comp + c)*dim*dim + e] = 0.0;} 1665c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1666c0ce001eSMatthew G. Knepley } 1667c0ce001eSMatthew G. Knepley 166888f5f89eSMatthew G. Knepley /*@C 166988f5f89eSMatthew G. Knepley PetscFVRestoreTabulation - Frees memory from the associated tabulation. 167088f5f89eSMatthew G. Knepley 167188f5f89eSMatthew G. Knepley Not collective 167288f5f89eSMatthew G. Knepley 167388f5f89eSMatthew G. Knepley Input Parameters: 167488f5f89eSMatthew G. Knepley + fvm - The PetscFV object 167588f5f89eSMatthew G. Knepley . npoints - The number of tabulation points 167688f5f89eSMatthew G. Knepley . points - The tabulation point coordinates 167788f5f89eSMatthew G. Knepley . B - The basis function values at tabulation points 167888f5f89eSMatthew G. Knepley . D - The basis function derivatives at tabulation points 167988f5f89eSMatthew G. Knepley - H - The basis function second derivatives at tabulation points 168088f5f89eSMatthew G. Knepley 168188f5f89eSMatthew G. Knepley Note: 168288f5f89eSMatthew G. Knepley $ B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 168388f5f89eSMatthew G. Knepley $ D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d 168488f5f89eSMatthew G. Knepley $ 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 168588f5f89eSMatthew G. Knepley 168688f5f89eSMatthew G. Knepley Level: intermediate 168788f5f89eSMatthew G. Knepley 168888f5f89eSMatthew G. Knepley .seealso: PetscFVGetTabulation(), PetscFVGetDefaultTabulation() 168988f5f89eSMatthew G. Knepley @*/ 1690c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVRestoreTabulation(PetscFV fvm, PetscInt npoints, const PetscReal points[], PetscReal **B, PetscReal **D, PetscReal **H) 1691c0ce001eSMatthew G. Knepley { 1692c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1693c0ce001eSMatthew G. Knepley 1694c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1695c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1696c0ce001eSMatthew G. Knepley if (B && *B) {ierr = PetscFree(*B);CHKERRQ(ierr);} 1697c0ce001eSMatthew G. Knepley if (D && *D) {ierr = PetscFree(*D);CHKERRQ(ierr);} 1698c0ce001eSMatthew G. Knepley if (H && *H) {ierr = PetscFree(*H);CHKERRQ(ierr);} 1699c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1700c0ce001eSMatthew G. Knepley } 1701c0ce001eSMatthew G. Knepley 1702c0ce001eSMatthew G. Knepley /*@C 1703c0ce001eSMatthew G. Knepley PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell 1704c0ce001eSMatthew G. Knepley 1705c0ce001eSMatthew G. Knepley Input Parameters: 1706c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 1707c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained 1708c0ce001eSMatthew G. Knepley - dx - The vector from the cell centroid to the neighboring cell centroid for each face 1709c0ce001eSMatthew G. Knepley 171088f5f89eSMatthew G. Knepley Level: advanced 1711c0ce001eSMatthew G. Knepley 1712c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate() 1713c0ce001eSMatthew G. Knepley @*/ 1714c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVComputeGradient(PetscFV fvm, PetscInt numFaces, PetscScalar dx[], PetscScalar grad[]) 1715c0ce001eSMatthew G. Knepley { 1716c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1717c0ce001eSMatthew G. Knepley 1718c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1719c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1720c0ce001eSMatthew G. Knepley if (fvm->ops->computegradient) {ierr = (*fvm->ops->computegradient)(fvm, numFaces, dx, grad);CHKERRQ(ierr);} 1721c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1722c0ce001eSMatthew G. Knepley } 1723c0ce001eSMatthew G. Knepley 172488f5f89eSMatthew G. Knepley /*@C 1725c0ce001eSMatthew G. Knepley PetscFVIntegrateRHSFunction - Produce the cell residual vector for a chunk of elements by quadrature integration 1726c0ce001eSMatthew G. Knepley 1727c0ce001eSMatthew G. Knepley Not collective 1728c0ce001eSMatthew G. Knepley 1729c0ce001eSMatthew G. Knepley Input Parameters: 1730c0ce001eSMatthew G. Knepley + fvm - The PetscFV object for the field being integrated 1731c0ce001eSMatthew G. Knepley . prob - The PetscDS specifing the discretizations and continuum functions 1732c0ce001eSMatthew G. Knepley . field - The field being integrated 1733c0ce001eSMatthew G. Knepley . Nf - The number of faces in the chunk 1734c0ce001eSMatthew G. Knepley . fgeom - The face geometry for each face in the chunk 1735c0ce001eSMatthew G. Knepley . neighborVol - The volume for each pair of cells in the chunk 1736c0ce001eSMatthew G. Knepley . uL - The state from the cell on the left 1737c0ce001eSMatthew G. Knepley - uR - The state from the cell on the right 1738c0ce001eSMatthew G. Knepley 1739c0ce001eSMatthew G. Knepley Output Parameter 1740c0ce001eSMatthew G. Knepley + fluxL - the left fluxes for each face 1741c0ce001eSMatthew G. Knepley - fluxR - the right fluxes for each face 174288f5f89eSMatthew G. Knepley 174388f5f89eSMatthew G. Knepley Level: developer 174488f5f89eSMatthew G. Knepley 174588f5f89eSMatthew G. Knepley .seealso: PetscFVCreate() 174688f5f89eSMatthew G. Knepley @*/ 1747c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVIntegrateRHSFunction(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, 1748c0ce001eSMatthew G. Knepley PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) 1749c0ce001eSMatthew G. Knepley { 1750c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1751c0ce001eSMatthew G. Knepley 1752c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1753c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1754c0ce001eSMatthew G. Knepley if (fvm->ops->integraterhsfunction) {ierr = (*fvm->ops->integraterhsfunction)(fvm, prob, field, Nf, fgeom, neighborVol, uL, uR, fluxL, fluxR);CHKERRQ(ierr);} 1755c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1756c0ce001eSMatthew G. Knepley } 1757c0ce001eSMatthew G. Knepley 1758c0ce001eSMatthew G. Knepley /*@ 1759c0ce001eSMatthew G. Knepley PetscFVRefine - Create a "refined" PetscFV object that refines the reference cell into smaller copies. This is typically used 1760c0ce001eSMatthew 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 1761c0ce001eSMatthew G. Knepley sparsity). It is also used to create an interpolation between regularly refined meshes. 1762c0ce001eSMatthew G. Knepley 1763c0ce001eSMatthew G. Knepley Input Parameter: 1764c0ce001eSMatthew G. Knepley . fv - The initial PetscFV 1765c0ce001eSMatthew G. Knepley 1766c0ce001eSMatthew G. Knepley Output Parameter: 1767c0ce001eSMatthew G. Knepley . fvRef - The refined PetscFV 1768c0ce001eSMatthew G. Knepley 176988f5f89eSMatthew G. Knepley Level: advanced 1770c0ce001eSMatthew G. Knepley 1771c0ce001eSMatthew G. Knepley .seealso: PetscFVType, PetscFVCreate(), PetscFVSetType() 1772c0ce001eSMatthew G. Knepley @*/ 1773c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVRefine(PetscFV fv, PetscFV *fvRef) 1774c0ce001eSMatthew G. Knepley { 1775c0ce001eSMatthew G. Knepley PetscDualSpace Q, Qref; 1776c0ce001eSMatthew G. Knepley DM K, Kref; 1777c0ce001eSMatthew G. Knepley PetscQuadrature q, qref; 1778c0ce001eSMatthew G. Knepley CellRefiner cellRefiner; 1779c0ce001eSMatthew G. Knepley PetscReal *v0; 1780c0ce001eSMatthew G. Knepley PetscReal *jac, *invjac; 1781c0ce001eSMatthew G. Knepley PetscInt numComp, numSubelements, s; 1782c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1783c0ce001eSMatthew G. Knepley 1784c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1785c0ce001eSMatthew G. Knepley ierr = PetscFVGetDualSpace(fv, &Q);CHKERRQ(ierr); 1786c0ce001eSMatthew G. Knepley ierr = PetscFVGetQuadrature(fv, &q);CHKERRQ(ierr); 1787c0ce001eSMatthew G. Knepley ierr = PetscDualSpaceGetDM(Q, &K);CHKERRQ(ierr); 1788c0ce001eSMatthew G. Knepley /* Create dual space */ 1789c0ce001eSMatthew G. Knepley ierr = PetscDualSpaceDuplicate(Q, &Qref);CHKERRQ(ierr); 1790c0ce001eSMatthew G. Knepley ierr = DMRefine(K, PetscObjectComm((PetscObject) fv), &Kref);CHKERRQ(ierr); 1791c0ce001eSMatthew G. Knepley ierr = PetscDualSpaceSetDM(Qref, Kref);CHKERRQ(ierr); 1792c0ce001eSMatthew G. Knepley ierr = DMDestroy(&Kref);CHKERRQ(ierr); 1793c0ce001eSMatthew G. Knepley ierr = PetscDualSpaceSetUp(Qref);CHKERRQ(ierr); 1794c0ce001eSMatthew G. Knepley /* Create volume */ 1795c0ce001eSMatthew G. Knepley ierr = PetscFVCreate(PetscObjectComm((PetscObject) fv), fvRef);CHKERRQ(ierr); 1796c0ce001eSMatthew G. Knepley ierr = PetscFVSetDualSpace(*fvRef, Qref);CHKERRQ(ierr); 1797c0ce001eSMatthew G. Knepley ierr = PetscFVGetNumComponents(fv, &numComp);CHKERRQ(ierr); 1798c0ce001eSMatthew G. Knepley ierr = PetscFVSetNumComponents(*fvRef, numComp);CHKERRQ(ierr); 1799c0ce001eSMatthew G. Knepley ierr = PetscFVSetUp(*fvRef);CHKERRQ(ierr); 1800c0ce001eSMatthew G. Knepley /* Create quadrature */ 1801c0ce001eSMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(K, &cellRefiner);CHKERRQ(ierr); 1802c0ce001eSMatthew G. Knepley ierr = CellRefinerGetAffineTransforms_Internal(cellRefiner, &numSubelements, &v0, &jac, &invjac);CHKERRQ(ierr); 1803c0ce001eSMatthew G. Knepley ierr = PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref);CHKERRQ(ierr); 1804c0ce001eSMatthew G. Knepley ierr = PetscDualSpaceSimpleSetDimension(Qref, numSubelements);CHKERRQ(ierr); 1805c0ce001eSMatthew G. Knepley for (s = 0; s < numSubelements; ++s) { 1806c0ce001eSMatthew G. Knepley PetscQuadrature qs; 1807c0ce001eSMatthew G. Knepley const PetscReal *points, *weights; 1808c0ce001eSMatthew G. Knepley PetscReal *p, *w; 1809c0ce001eSMatthew G. Knepley PetscInt dim, Nc, npoints, np; 1810c0ce001eSMatthew G. Knepley 1811c0ce001eSMatthew G. Knepley ierr = PetscQuadratureCreate(PETSC_COMM_SELF, &qs);CHKERRQ(ierr); 1812c0ce001eSMatthew G. Knepley ierr = PetscQuadratureGetData(q, &dim, &Nc, &npoints, &points, &weights);CHKERRQ(ierr); 1813c0ce001eSMatthew G. Knepley np = npoints/numSubelements; 1814c0ce001eSMatthew G. Knepley ierr = PetscMalloc1(np*dim,&p);CHKERRQ(ierr); 1815c0ce001eSMatthew G. Knepley ierr = PetscMalloc1(np*Nc,&w);CHKERRQ(ierr); 1816c0ce001eSMatthew G. Knepley ierr = PetscArraycpy(p, &points[s*np*dim], np*dim);CHKERRQ(ierr); 1817c0ce001eSMatthew G. Knepley ierr = PetscArraycpy(w, &weights[s*np*Nc], np*Nc);CHKERRQ(ierr); 1818c0ce001eSMatthew G. Knepley ierr = PetscQuadratureSetData(qs, dim, Nc, np, p, w);CHKERRQ(ierr); 1819c0ce001eSMatthew G. Knepley ierr = PetscDualSpaceSimpleSetFunctional(Qref, s, qs);CHKERRQ(ierr); 1820c0ce001eSMatthew G. Knepley ierr = PetscQuadratureDestroy(&qs);CHKERRQ(ierr); 1821c0ce001eSMatthew G. Knepley } 1822c0ce001eSMatthew G. Knepley ierr = CellRefinerRestoreAffineTransforms_Internal(cellRefiner, &numSubelements, &v0, &jac, &invjac);CHKERRQ(ierr); 1823c0ce001eSMatthew G. Knepley ierr = PetscFVSetQuadrature(*fvRef, qref);CHKERRQ(ierr); 1824c0ce001eSMatthew G. Knepley ierr = PetscQuadratureDestroy(&qref);CHKERRQ(ierr); 1825c0ce001eSMatthew G. Knepley ierr = PetscDualSpaceDestroy(&Qref);CHKERRQ(ierr); 1826c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1827c0ce001eSMatthew G. Knepley } 1828c0ce001eSMatthew G. Knepley 182988f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVDestroy_Upwind(PetscFV fvm) 1830c0ce001eSMatthew G. Knepley { 1831c0ce001eSMatthew G. Knepley PetscFV_Upwind *b = (PetscFV_Upwind *) fvm->data; 1832c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1833c0ce001eSMatthew G. Knepley 1834c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1835c0ce001eSMatthew G. Knepley ierr = PetscFree(b);CHKERRQ(ierr); 1836c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1837c0ce001eSMatthew G. Knepley } 1838c0ce001eSMatthew G. Knepley 183988f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_Upwind_Ascii(PetscFV fv, PetscViewer viewer) 1840c0ce001eSMatthew G. Knepley { 1841c0ce001eSMatthew G. Knepley PetscInt Nc, c; 1842c0ce001eSMatthew G. Knepley PetscViewerFormat format; 1843c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1844c0ce001eSMatthew G. Knepley 1845c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1846c0ce001eSMatthew G. Knepley ierr = PetscFVGetNumComponents(fv, &Nc);CHKERRQ(ierr); 1847c0ce001eSMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 1848c0ce001eSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Upwind Finite Volume:\n");CHKERRQ(ierr); 1849c0ce001eSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " num components: %d\n", Nc);CHKERRQ(ierr); 1850c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; c++) { 1851c0ce001eSMatthew G. Knepley if (fv->componentNames[c]) { 1852c0ce001eSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " component %d: %s\n", c, fv->componentNames[c]);CHKERRQ(ierr); 1853c0ce001eSMatthew G. Knepley } 1854c0ce001eSMatthew G. Knepley } 1855c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1856c0ce001eSMatthew G. Knepley } 1857c0ce001eSMatthew G. Knepley 185888f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_Upwind(PetscFV fv, PetscViewer viewer) 1859c0ce001eSMatthew G. Knepley { 1860c0ce001eSMatthew G. Knepley PetscBool iascii; 1861c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1862c0ce001eSMatthew G. Knepley 1863c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1864c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1); 1865c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1866c0ce001eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1867c0ce001eSMatthew G. Knepley if (iascii) {ierr = PetscFVView_Upwind_Ascii(fv, viewer);CHKERRQ(ierr);} 1868c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1869c0ce001eSMatthew G. Knepley } 1870c0ce001eSMatthew G. Knepley 187188f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVSetUp_Upwind(PetscFV fvm) 1872c0ce001eSMatthew G. Knepley { 1873c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1874c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1875c0ce001eSMatthew G. Knepley } 1876c0ce001eSMatthew G. Knepley 1877c0ce001eSMatthew G. Knepley /* 1878c0ce001eSMatthew G. Knepley neighborVol[f*2+0] contains the left geom 1879c0ce001eSMatthew G. Knepley neighborVol[f*2+1] contains the right geom 1880c0ce001eSMatthew G. Knepley */ 188188f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVIntegrateRHSFunction_Upwind(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, 1882c0ce001eSMatthew G. Knepley PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) 1883c0ce001eSMatthew G. Knepley { 1884c0ce001eSMatthew G. Knepley void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *); 1885c0ce001eSMatthew G. Knepley void *rctx; 1886c0ce001eSMatthew G. Knepley PetscScalar *flux = fvm->fluxWork; 1887c0ce001eSMatthew G. Knepley const PetscScalar *constants; 1888c0ce001eSMatthew G. Knepley PetscInt dim, numConstants, pdim, totDim, Nc, off, f, d; 1889c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1890c0ce001eSMatthew G. Knepley 1891c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1892c0ce001eSMatthew G. Knepley ierr = PetscDSGetTotalComponents(prob, &Nc);CHKERRQ(ierr); 1893c0ce001eSMatthew G. Knepley ierr = PetscDSGetTotalDimension(prob, &totDim);CHKERRQ(ierr); 1894c0ce001eSMatthew G. Knepley ierr = PetscDSGetFieldOffset(prob, field, &off);CHKERRQ(ierr); 1895c0ce001eSMatthew G. Knepley ierr = PetscDSGetRiemannSolver(prob, field, &riemann);CHKERRQ(ierr); 1896c0ce001eSMatthew G. Knepley ierr = PetscDSGetContext(prob, field, &rctx);CHKERRQ(ierr); 1897c0ce001eSMatthew G. Knepley ierr = PetscDSGetConstants(prob, &numConstants, &constants);CHKERRQ(ierr); 1898c0ce001eSMatthew G. Knepley ierr = PetscFVGetSpatialDimension(fvm, &dim);CHKERRQ(ierr); 1899c0ce001eSMatthew G. Knepley ierr = PetscFVGetNumComponents(fvm, &pdim);CHKERRQ(ierr); 1900c0ce001eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 1901c0ce001eSMatthew G. Knepley (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f*Nc], &uR[f*Nc], numConstants, constants, flux, rctx); 1902c0ce001eSMatthew G. Knepley for (d = 0; d < pdim; ++d) { 1903c0ce001eSMatthew G. Knepley fluxL[f*totDim+off+d] = flux[d] / neighborVol[f*2+0]; 1904c0ce001eSMatthew G. Knepley fluxR[f*totDim+off+d] = flux[d] / neighborVol[f*2+1]; 1905c0ce001eSMatthew G. Knepley } 1906c0ce001eSMatthew G. Knepley } 1907c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1908c0ce001eSMatthew G. Knepley } 1909c0ce001eSMatthew G. Knepley 191088f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVInitialize_Upwind(PetscFV fvm) 1911c0ce001eSMatthew G. Knepley { 1912c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1913c0ce001eSMatthew G. Knepley fvm->ops->setfromoptions = NULL; 1914c0ce001eSMatthew G. Knepley fvm->ops->setup = PetscFVSetUp_Upwind; 1915c0ce001eSMatthew G. Knepley fvm->ops->view = PetscFVView_Upwind; 1916c0ce001eSMatthew G. Knepley fvm->ops->destroy = PetscFVDestroy_Upwind; 1917c0ce001eSMatthew G. Knepley fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_Upwind; 1918c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1919c0ce001eSMatthew G. Knepley } 1920c0ce001eSMatthew G. Knepley 1921c0ce001eSMatthew G. Knepley /*MC 1922c0ce001eSMatthew G. Knepley PETSCFVUPWIND = "upwind" - A PetscFV object 1923c0ce001eSMatthew G. Knepley 1924c0ce001eSMatthew G. Knepley Level: intermediate 1925c0ce001eSMatthew G. Knepley 1926c0ce001eSMatthew G. Knepley .seealso: PetscFVType, PetscFVCreate(), PetscFVSetType() 1927c0ce001eSMatthew G. Knepley M*/ 1928c0ce001eSMatthew G. Knepley 1929c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscFVCreate_Upwind(PetscFV fvm) 1930c0ce001eSMatthew G. Knepley { 1931c0ce001eSMatthew G. Knepley PetscFV_Upwind *b; 1932c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1933c0ce001eSMatthew G. Knepley 1934c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1935c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 1936c0ce001eSMatthew G. Knepley ierr = PetscNewLog(fvm,&b);CHKERRQ(ierr); 1937c0ce001eSMatthew G. Knepley fvm->data = b; 1938c0ce001eSMatthew G. Knepley 1939c0ce001eSMatthew G. Knepley ierr = PetscFVInitialize_Upwind(fvm);CHKERRQ(ierr); 1940c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1941c0ce001eSMatthew G. Knepley } 1942c0ce001eSMatthew G. Knepley 1943c0ce001eSMatthew G. Knepley #include <petscblaslapack.h> 1944c0ce001eSMatthew G. Knepley 194588f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVDestroy_LeastSquares(PetscFV fvm) 1946c0ce001eSMatthew G. Knepley { 1947c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *) fvm->data; 1948c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1949c0ce001eSMatthew G. Knepley 1950c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1951c0ce001eSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject) fvm, "PetscFVLeastSquaresSetMaxFaces_C", NULL);CHKERRQ(ierr); 1952c0ce001eSMatthew G. Knepley ierr = PetscFree4(ls->B, ls->Binv, ls->tau, ls->work);CHKERRQ(ierr); 1953c0ce001eSMatthew G. Knepley ierr = PetscFree(ls);CHKERRQ(ierr); 1954c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1955c0ce001eSMatthew G. Knepley } 1956c0ce001eSMatthew G. Knepley 195788f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_LeastSquares_Ascii(PetscFV fv, PetscViewer viewer) 1958c0ce001eSMatthew G. Knepley { 1959c0ce001eSMatthew G. Knepley PetscInt Nc, c; 1960c0ce001eSMatthew G. Knepley PetscViewerFormat format; 1961c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1962c0ce001eSMatthew G. Knepley 1963c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1964c0ce001eSMatthew G. Knepley ierr = PetscFVGetNumComponents(fv, &Nc);CHKERRQ(ierr); 1965c0ce001eSMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 1966c0ce001eSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Finite Volume with Least Squares Reconstruction:\n");CHKERRQ(ierr); 1967c0ce001eSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " num components: %d\n", Nc);CHKERRQ(ierr); 1968c0ce001eSMatthew G. Knepley for (c = 0; c < Nc; c++) { 1969c0ce001eSMatthew G. Knepley if (fv->componentNames[c]) { 1970c0ce001eSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " component %d: %s\n", c, fv->componentNames[c]);CHKERRQ(ierr); 1971c0ce001eSMatthew G. Knepley } 1972c0ce001eSMatthew G. Knepley } 1973c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1974c0ce001eSMatthew G. Knepley } 1975c0ce001eSMatthew G. Knepley 197688f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVView_LeastSquares(PetscFV fv, PetscViewer viewer) 1977c0ce001eSMatthew G. Knepley { 1978c0ce001eSMatthew G. Knepley PetscBool iascii; 1979c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 1980c0ce001eSMatthew G. Knepley 1981c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1982c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 1); 1983c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1984c0ce001eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1985c0ce001eSMatthew G. Knepley if (iascii) {ierr = PetscFVView_LeastSquares_Ascii(fv, viewer);CHKERRQ(ierr);} 1986c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1987c0ce001eSMatthew G. Knepley } 1988c0ce001eSMatthew G. Knepley 198988f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVSetUp_LeastSquares(PetscFV fvm) 1990c0ce001eSMatthew G. Knepley { 1991c0ce001eSMatthew G. Knepley PetscFunctionBegin; 1992c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 1993c0ce001eSMatthew G. Knepley } 1994c0ce001eSMatthew G. Knepley 1995c0ce001eSMatthew G. Knepley /* Overwrites A. Can only handle full-rank problems with m>=n */ 1996c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresPseudoInverse_Static(PetscInt m,PetscInt mstride,PetscInt n,PetscScalar *A,PetscScalar *Ainv,PetscScalar *tau,PetscInt worksize,PetscScalar *work) 1997c0ce001eSMatthew G. Knepley { 1998c0ce001eSMatthew G. Knepley PetscBool debug = PETSC_FALSE; 1999c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 2000c0ce001eSMatthew G. Knepley PetscBLASInt M,N,K,lda,ldb,ldwork,info; 2001c0ce001eSMatthew G. Knepley PetscScalar *R,*Q,*Aback,Alpha; 2002c0ce001eSMatthew G. Knepley 2003c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2004c0ce001eSMatthew G. Knepley if (debug) { 2005c0ce001eSMatthew G. Knepley ierr = PetscMalloc1(m*n,&Aback);CHKERRQ(ierr); 2006c0ce001eSMatthew G. Knepley ierr = PetscArraycpy(Aback,A,m*n);CHKERRQ(ierr); 2007c0ce001eSMatthew G. Knepley } 2008c0ce001eSMatthew G. Knepley 2009c0ce001eSMatthew G. Knepley ierr = PetscBLASIntCast(m,&M);CHKERRQ(ierr); 2010c0ce001eSMatthew G. Knepley ierr = PetscBLASIntCast(n,&N);CHKERRQ(ierr); 2011c0ce001eSMatthew G. Knepley ierr = PetscBLASIntCast(mstride,&lda);CHKERRQ(ierr); 2012c0ce001eSMatthew G. Knepley ierr = PetscBLASIntCast(worksize,&ldwork);CHKERRQ(ierr); 2013c0ce001eSMatthew G. Knepley ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2014c0ce001eSMatthew G. Knepley LAPACKgeqrf_(&M,&N,A,&lda,tau,work,&ldwork,&info); 2015c0ce001eSMatthew G. Knepley ierr = PetscFPTrapPop();CHKERRQ(ierr); 2016c0ce001eSMatthew G. Knepley if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"xGEQRF error"); 2017c0ce001eSMatthew G. Knepley R = A; /* Upper triangular part of A now contains R, the rest contains the elementary reflectors */ 2018c0ce001eSMatthew G. Knepley 2019c0ce001eSMatthew G. Knepley /* Extract an explicit representation of Q */ 2020c0ce001eSMatthew G. Knepley Q = Ainv; 2021c0ce001eSMatthew G. Knepley ierr = PetscArraycpy(Q,A,mstride*n);CHKERRQ(ierr); 2022c0ce001eSMatthew G. Knepley K = N; /* full rank */ 2023c0ce001eSMatthew G. Knepley PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&M,&N,&K,Q,&lda,tau,work,&ldwork,&info)); 2024c0ce001eSMatthew G. Knepley if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"xORGQR/xUNGQR error"); 2025c0ce001eSMatthew G. Knepley 2026c0ce001eSMatthew G. Knepley /* Compute A^{-T} = (R^{-1} Q^T)^T = Q R^{-T} */ 2027c0ce001eSMatthew G. Knepley Alpha = 1.0; 2028c0ce001eSMatthew G. Knepley ldb = lda; 2029c0ce001eSMatthew G. Knepley BLAStrsm_("Right","Upper","ConjugateTranspose","NotUnitTriangular",&M,&N,&Alpha,R,&lda,Q,&ldb); 2030c0ce001eSMatthew G. Knepley /* Ainv is Q, overwritten with inverse */ 2031c0ce001eSMatthew G. Knepley 2032c0ce001eSMatthew G. Knepley if (debug) { /* Check that pseudo-inverse worked */ 2033c0ce001eSMatthew G. Knepley PetscScalar Beta = 0.0; 2034c0ce001eSMatthew G. Knepley PetscBLASInt ldc; 2035c0ce001eSMatthew G. Knepley K = N; 2036c0ce001eSMatthew G. Knepley ldc = N; 2037c0ce001eSMatthew G. Knepley BLASgemm_("ConjugateTranspose","Normal",&N,&K,&M,&Alpha,Ainv,&lda,Aback,&ldb,&Beta,work,&ldc); 2038c0ce001eSMatthew G. Knepley ierr = PetscScalarView(n*n,work,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 2039c0ce001eSMatthew G. Knepley ierr = PetscFree(Aback);CHKERRQ(ierr); 2040c0ce001eSMatthew G. Knepley } 2041c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2042c0ce001eSMatthew G. Knepley } 2043c0ce001eSMatthew G. Knepley 2044c0ce001eSMatthew G. Knepley /* Overwrites A. Can handle degenerate problems and m<n. */ 2045c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresPseudoInverseSVD_Static(PetscInt m,PetscInt mstride,PetscInt n,PetscScalar *A,PetscScalar *Ainv,PetscScalar *tau,PetscInt worksize,PetscScalar *work) 2046c0ce001eSMatthew G. Knepley { 2047c0ce001eSMatthew G. Knepley PetscBool debug = PETSC_FALSE; 2048c0ce001eSMatthew G. Knepley PetscScalar *Brhs, *Aback; 2049c0ce001eSMatthew G. Knepley PetscScalar *tmpwork; 2050c0ce001eSMatthew G. Knepley PetscReal rcond; 2051c0ce001eSMatthew G. Knepley #if defined (PETSC_USE_COMPLEX) 2052c0ce001eSMatthew G. Knepley PetscInt rworkSize; 2053c0ce001eSMatthew G. Knepley PetscReal *rwork; 2054c0ce001eSMatthew G. Knepley #endif 2055c0ce001eSMatthew G. Knepley PetscInt i, j, maxmn; 2056c0ce001eSMatthew G. Knepley PetscBLASInt M, N, lda, ldb, ldwork; 2057c0ce001eSMatthew G. Knepley PetscBLASInt nrhs, irank, info; 2058c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 2059c0ce001eSMatthew G. Knepley 2060c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2061c0ce001eSMatthew G. Knepley if (debug) { 2062c0ce001eSMatthew G. Knepley ierr = PetscMalloc1(m*n,&Aback);CHKERRQ(ierr); 2063c0ce001eSMatthew G. Knepley ierr = PetscArraycpy(Aback,A,m*n);CHKERRQ(ierr); 2064c0ce001eSMatthew G. Knepley } 2065c0ce001eSMatthew G. Knepley 2066c0ce001eSMatthew G. Knepley /* initialize to identity */ 2067c0ce001eSMatthew G. Knepley tmpwork = Ainv; 2068c0ce001eSMatthew G. Knepley Brhs = work; 2069c0ce001eSMatthew G. Knepley maxmn = PetscMax(m,n); 2070c0ce001eSMatthew G. Knepley for (j=0; j<maxmn; j++) { 2071c0ce001eSMatthew G. Knepley for (i=0; i<maxmn; i++) Brhs[i + j*maxmn] = 1.0*(i == j); 2072c0ce001eSMatthew G. Knepley } 2073c0ce001eSMatthew G. Knepley 2074c0ce001eSMatthew G. Knepley ierr = PetscBLASIntCast(m,&M);CHKERRQ(ierr); 2075c0ce001eSMatthew G. Knepley ierr = PetscBLASIntCast(n,&N);CHKERRQ(ierr); 2076c0ce001eSMatthew G. Knepley ierr = PetscBLASIntCast(mstride,&lda);CHKERRQ(ierr); 2077c0ce001eSMatthew G. Knepley ierr = PetscBLASIntCast(maxmn,&ldb);CHKERRQ(ierr); 2078c0ce001eSMatthew G. Knepley ierr = PetscBLASIntCast(worksize,&ldwork);CHKERRQ(ierr); 2079c0ce001eSMatthew G. Knepley rcond = -1; 2080c0ce001eSMatthew G. Knepley ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2081c0ce001eSMatthew G. Knepley nrhs = M; 2082c0ce001eSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX) 2083c0ce001eSMatthew G. Knepley rworkSize = 5 * PetscMin(M,N); 2084c0ce001eSMatthew G. Knepley ierr = PetscMalloc1(rworkSize,&rwork);CHKERRQ(ierr); 2085c0ce001eSMatthew G. Knepley LAPACKgelss_(&M,&N,&nrhs,A,&lda,Brhs,&ldb, (PetscReal *) tau,&rcond,&irank,tmpwork,&ldwork,rwork,&info); 2086c0ce001eSMatthew G. Knepley ierr = PetscFPTrapPop();CHKERRQ(ierr); 2087c0ce001eSMatthew G. Knepley ierr = PetscFree(rwork);CHKERRQ(ierr); 2088c0ce001eSMatthew G. Knepley #else 2089c0ce001eSMatthew G. Knepley nrhs = M; 2090c0ce001eSMatthew G. Knepley LAPACKgelss_(&M,&N,&nrhs,A,&lda,Brhs,&ldb, (PetscReal *) tau,&rcond,&irank,tmpwork,&ldwork,&info); 2091c0ce001eSMatthew G. Knepley ierr = PetscFPTrapPop();CHKERRQ(ierr); 2092c0ce001eSMatthew G. Knepley #endif 2093c0ce001eSMatthew G. Knepley if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"xGELSS error"); 2094c0ce001eSMatthew G. Knepley /* The following check should be turned into a diagnostic as soon as someone wants to do this intentionally */ 2095c0ce001eSMatthew G. Knepley if (irank < PetscMin(M,N)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Rank deficient least squares fit, indicates an isolated cell with two colinear points"); 2096c0ce001eSMatthew G. Knepley 2097c0ce001eSMatthew G. Knepley /* Brhs shaped (M,nrhs) column-major coldim=mstride was overwritten by Ainv shaped (N,nrhs) column-major coldim=maxmn. 2098c0ce001eSMatthew G. Knepley * Here we transpose to (N,nrhs) row-major rowdim=mstride. */ 2099c0ce001eSMatthew G. Knepley for (i=0; i<n; i++) { 2100c0ce001eSMatthew G. Knepley for (j=0; j<nrhs; j++) Ainv[i*mstride+j] = Brhs[i + j*maxmn]; 2101c0ce001eSMatthew G. Knepley } 2102c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2103c0ce001eSMatthew G. Knepley } 2104c0ce001eSMatthew G. Knepley 2105c0ce001eSMatthew G. Knepley #if 0 2106c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresDebugCell_Static(PetscFV fvm, PetscInt cell, DM dm, DM dmFace, PetscScalar *fgeom, DM dmCell, PetscScalar *cgeom) 2107c0ce001eSMatthew G. Knepley { 2108c0ce001eSMatthew G. Knepley PetscReal grad[2] = {0, 0}; 2109c0ce001eSMatthew G. Knepley const PetscInt *faces; 2110c0ce001eSMatthew G. Knepley PetscInt numFaces, f; 2111c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 2112c0ce001eSMatthew G. Knepley 2113c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2114c0ce001eSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cell, &numFaces);CHKERRQ(ierr); 2115c0ce001eSMatthew G. Knepley ierr = DMPlexGetCone(dm, cell, &faces);CHKERRQ(ierr); 2116c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2117c0ce001eSMatthew G. Knepley const PetscInt *fcells; 2118c0ce001eSMatthew G. Knepley const CellGeom *cg1; 2119c0ce001eSMatthew G. Knepley const FaceGeom *fg; 2120c0ce001eSMatthew G. Knepley 2121c0ce001eSMatthew G. Knepley ierr = DMPlexGetSupport(dm, faces[f], &fcells);CHKERRQ(ierr); 2122c0ce001eSMatthew G. Knepley ierr = DMPlexPointLocalRead(dmFace, faces[f], fgeom, &fg);CHKERRQ(ierr); 2123c0ce001eSMatthew G. Knepley for (i = 0; i < 2; ++i) { 2124c0ce001eSMatthew G. Knepley PetscScalar du; 2125c0ce001eSMatthew G. Knepley 2126c0ce001eSMatthew G. Knepley if (fcells[i] == c) continue; 2127c0ce001eSMatthew G. Knepley ierr = DMPlexPointLocalRead(dmCell, fcells[i], cgeom, &cg1);CHKERRQ(ierr); 2128c0ce001eSMatthew G. Knepley du = cg1->centroid[0] + 3*cg1->centroid[1] - (cg->centroid[0] + 3*cg->centroid[1]); 2129c0ce001eSMatthew G. Knepley grad[0] += fg->grad[!i][0] * du; 2130c0ce001eSMatthew G. Knepley grad[1] += fg->grad[!i][1] * du; 2131c0ce001eSMatthew G. Knepley } 2132c0ce001eSMatthew G. Knepley } 2133c0ce001eSMatthew G. Knepley PetscPrintf(PETSC_COMM_SELF, "cell[%d] grad (%g, %g)\n", cell, grad[0], grad[1]);CHKERRQ(ierr); 2134c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2135c0ce001eSMatthew G. Knepley } 2136c0ce001eSMatthew G. Knepley #endif 2137c0ce001eSMatthew G. Knepley 2138c0ce001eSMatthew G. Knepley /* 2139c0ce001eSMatthew G. Knepley PetscFVComputeGradient - Compute the gradient reconstruction matrix for a given cell 2140c0ce001eSMatthew G. Knepley 2141c0ce001eSMatthew G. Knepley Input Parameters: 2142c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 2143c0ce001eSMatthew G. Knepley . numFaces - The number of cell faces which are not constrained 2144c0ce001eSMatthew G. Knepley . dx - The vector from the cell centroid to the neighboring cell centroid for each face 2145c0ce001eSMatthew G. Knepley 2146c0ce001eSMatthew G. Knepley Level: developer 2147c0ce001eSMatthew G. Knepley 2148c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate() 2149c0ce001eSMatthew G. Knepley */ 215088f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVComputeGradient_LeastSquares(PetscFV fvm, PetscInt numFaces, const PetscScalar dx[], PetscScalar grad[]) 2151c0ce001eSMatthew G. Knepley { 2152c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *) fvm->data; 2153c0ce001eSMatthew G. Knepley const PetscBool useSVD = PETSC_TRUE; 2154c0ce001eSMatthew G. Knepley const PetscInt maxFaces = ls->maxFaces; 2155c0ce001eSMatthew G. Knepley PetscInt dim, f, d; 2156c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 2157c0ce001eSMatthew G. Knepley 2158c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2159c0ce001eSMatthew G. Knepley if (numFaces > maxFaces) { 2160c0ce001eSMatthew G. Knepley if (maxFaces < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Reconstruction has not been initialized, call PetscFVLeastSquaresSetMaxFaces()"); 2161c0ce001eSMatthew G. Knepley SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of input faces %D > %D maxfaces", numFaces, maxFaces); 2162c0ce001eSMatthew G. Knepley } 2163c0ce001eSMatthew G. Knepley ierr = PetscFVGetSpatialDimension(fvm, &dim);CHKERRQ(ierr); 2164c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2165c0ce001eSMatthew G. Knepley for (d = 0; d < dim; ++d) ls->B[d*maxFaces+f] = dx[f*dim+d]; 2166c0ce001eSMatthew G. Knepley } 2167c0ce001eSMatthew G. Knepley /* Overwrites B with garbage, returns Binv in row-major format */ 2168c0ce001eSMatthew G. Knepley if (useSVD) {ierr = PetscFVLeastSquaresPseudoInverseSVD_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work);CHKERRQ(ierr);} 2169c0ce001eSMatthew G. Knepley else {ierr = PetscFVLeastSquaresPseudoInverse_Static(numFaces, maxFaces, dim, ls->B, ls->Binv, ls->tau, ls->workSize, ls->work);CHKERRQ(ierr);} 2170c0ce001eSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 2171c0ce001eSMatthew G. Knepley for (d = 0; d < dim; ++d) grad[f*dim+d] = ls->Binv[d*maxFaces+f]; 2172c0ce001eSMatthew G. Knepley } 2173c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2174c0ce001eSMatthew G. Knepley } 2175c0ce001eSMatthew G. Knepley 2176c0ce001eSMatthew G. Knepley /* 2177c0ce001eSMatthew G. Knepley neighborVol[f*2+0] contains the left geom 2178c0ce001eSMatthew G. Knepley neighborVol[f*2+1] contains the right geom 2179c0ce001eSMatthew G. Knepley */ 218088f5f89eSMatthew G. Knepley static PetscErrorCode PetscFVIntegrateRHSFunction_LeastSquares(PetscFV fvm, PetscDS prob, PetscInt field, PetscInt Nf, PetscFVFaceGeom *fgeom, PetscReal *neighborVol, 2181c0ce001eSMatthew G. Knepley PetscScalar uL[], PetscScalar uR[], PetscScalar fluxL[], PetscScalar fluxR[]) 2182c0ce001eSMatthew G. Knepley { 2183c0ce001eSMatthew G. Knepley void (*riemann)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *); 2184c0ce001eSMatthew G. Knepley void *rctx; 2185c0ce001eSMatthew G. Knepley PetscScalar *flux = fvm->fluxWork; 2186c0ce001eSMatthew G. Knepley const PetscScalar *constants; 2187c0ce001eSMatthew G. Knepley PetscInt dim, numConstants, pdim, Nc, totDim, off, f, d; 2188c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 2189c0ce001eSMatthew G. Knepley 2190c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2191c0ce001eSMatthew G. Knepley ierr = PetscDSGetTotalComponents(prob, &Nc);CHKERRQ(ierr); 2192c0ce001eSMatthew G. Knepley ierr = PetscDSGetTotalDimension(prob, &totDim);CHKERRQ(ierr); 2193c0ce001eSMatthew G. Knepley ierr = PetscDSGetFieldOffset(prob, field, &off);CHKERRQ(ierr); 2194c0ce001eSMatthew G. Knepley ierr = PetscDSGetRiemannSolver(prob, field, &riemann);CHKERRQ(ierr); 2195c0ce001eSMatthew G. Knepley ierr = PetscDSGetContext(prob, field, &rctx);CHKERRQ(ierr); 2196c0ce001eSMatthew G. Knepley ierr = PetscDSGetConstants(prob, &numConstants, &constants);CHKERRQ(ierr); 2197c0ce001eSMatthew G. Knepley ierr = PetscFVGetSpatialDimension(fvm, &dim);CHKERRQ(ierr); 2198c0ce001eSMatthew G. Knepley ierr = PetscFVGetNumComponents(fvm, &pdim);CHKERRQ(ierr); 2199c0ce001eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2200c0ce001eSMatthew G. Knepley (*riemann)(dim, pdim, fgeom[f].centroid, fgeom[f].normal, &uL[f*Nc], &uR[f*Nc], numConstants, constants, flux, rctx); 2201c0ce001eSMatthew G. Knepley for (d = 0; d < pdim; ++d) { 2202c0ce001eSMatthew G. Knepley fluxL[f*totDim+off+d] = flux[d] / neighborVol[f*2+0]; 2203c0ce001eSMatthew G. Knepley fluxR[f*totDim+off+d] = flux[d] / neighborVol[f*2+1]; 2204c0ce001eSMatthew G. Knepley } 2205c0ce001eSMatthew G. Knepley } 2206c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2207c0ce001eSMatthew G. Knepley } 2208c0ce001eSMatthew G. Knepley 2209c0ce001eSMatthew G. Knepley static PetscErrorCode PetscFVLeastSquaresSetMaxFaces_LS(PetscFV fvm, PetscInt maxFaces) 2210c0ce001eSMatthew G. Knepley { 2211c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls = (PetscFV_LeastSquares *) fvm->data; 2212c0ce001eSMatthew G. Knepley PetscInt dim, m, n, nrhs, minwork; 2213c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 2214c0ce001eSMatthew G. Knepley 2215c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2216c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 2217c0ce001eSMatthew G. Knepley ierr = PetscFVGetSpatialDimension(fvm, &dim);CHKERRQ(ierr); 2218c0ce001eSMatthew G. Knepley ierr = PetscFree4(ls->B, ls->Binv, ls->tau, ls->work);CHKERRQ(ierr); 2219c0ce001eSMatthew G. Knepley ls->maxFaces = maxFaces; 2220c0ce001eSMatthew G. Knepley m = ls->maxFaces; 2221c0ce001eSMatthew G. Knepley n = dim; 2222c0ce001eSMatthew G. Knepley nrhs = ls->maxFaces; 2223c0ce001eSMatthew G. Knepley minwork = 3*PetscMin(m,n) + PetscMax(2*PetscMin(m,n), PetscMax(PetscMax(m,n), nrhs)); /* required by LAPACK */ 2224c0ce001eSMatthew G. Knepley ls->workSize = 5*minwork; /* We can afford to be extra generous */ 2225c0ce001eSMatthew G. Knepley ierr = PetscMalloc4(ls->maxFaces*dim,&ls->B,ls->workSize,&ls->Binv,ls->maxFaces,&ls->tau,ls->workSize,&ls->work);CHKERRQ(ierr); 2226c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2227c0ce001eSMatthew G. Knepley } 2228c0ce001eSMatthew G. Knepley 2229c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVInitialize_LeastSquares(PetscFV fvm) 2230c0ce001eSMatthew G. Knepley { 2231c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2232c0ce001eSMatthew G. Knepley fvm->ops->setfromoptions = NULL; 2233c0ce001eSMatthew G. Knepley fvm->ops->setup = PetscFVSetUp_LeastSquares; 2234c0ce001eSMatthew G. Knepley fvm->ops->view = PetscFVView_LeastSquares; 2235c0ce001eSMatthew G. Knepley fvm->ops->destroy = PetscFVDestroy_LeastSquares; 2236c0ce001eSMatthew G. Knepley fvm->ops->computegradient = PetscFVComputeGradient_LeastSquares; 2237c0ce001eSMatthew G. Knepley fvm->ops->integraterhsfunction = PetscFVIntegrateRHSFunction_LeastSquares; 2238c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2239c0ce001eSMatthew G. Knepley } 2240c0ce001eSMatthew G. Knepley 2241c0ce001eSMatthew G. Knepley /*MC 2242c0ce001eSMatthew G. Knepley PETSCFVLEASTSQUARES = "leastsquares" - A PetscFV object 2243c0ce001eSMatthew G. Knepley 2244c0ce001eSMatthew G. Knepley Level: intermediate 2245c0ce001eSMatthew G. Knepley 2246c0ce001eSMatthew G. Knepley .seealso: PetscFVType, PetscFVCreate(), PetscFVSetType() 2247c0ce001eSMatthew G. Knepley M*/ 2248c0ce001eSMatthew G. Knepley 2249c0ce001eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscFVCreate_LeastSquares(PetscFV fvm) 2250c0ce001eSMatthew G. Knepley { 2251c0ce001eSMatthew G. Knepley PetscFV_LeastSquares *ls; 2252c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 2253c0ce001eSMatthew G. Knepley 2254c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2255c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 2256c0ce001eSMatthew G. Knepley ierr = PetscNewLog(fvm, &ls);CHKERRQ(ierr); 2257c0ce001eSMatthew G. Knepley fvm->data = ls; 2258c0ce001eSMatthew G. Knepley 2259c0ce001eSMatthew G. Knepley ls->maxFaces = -1; 2260c0ce001eSMatthew G. Knepley ls->workSize = -1; 2261c0ce001eSMatthew G. Knepley ls->B = NULL; 2262c0ce001eSMatthew G. Knepley ls->Binv = NULL; 2263c0ce001eSMatthew G. Knepley ls->tau = NULL; 2264c0ce001eSMatthew G. Knepley ls->work = NULL; 2265c0ce001eSMatthew G. Knepley 2266c0ce001eSMatthew G. Knepley ierr = PetscFVSetComputeGradients(fvm, PETSC_TRUE);CHKERRQ(ierr); 2267c0ce001eSMatthew G. Knepley ierr = PetscFVInitialize_LeastSquares(fvm);CHKERRQ(ierr); 2268c0ce001eSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject) fvm, "PetscFVLeastSquaresSetMaxFaces_C", PetscFVLeastSquaresSetMaxFaces_LS);CHKERRQ(ierr); 2269c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2270c0ce001eSMatthew G. Knepley } 2271c0ce001eSMatthew G. Knepley 2272c0ce001eSMatthew G. Knepley /*@ 2273c0ce001eSMatthew G. Knepley PetscFVLeastSquaresSetMaxFaces - Set the maximum number of cell faces for gradient reconstruction 2274c0ce001eSMatthew G. Knepley 2275c0ce001eSMatthew G. Knepley Not collective 2276c0ce001eSMatthew G. Knepley 2277c0ce001eSMatthew G. Knepley Input parameters: 2278c0ce001eSMatthew G. Knepley + fvm - The PetscFV object 2279c0ce001eSMatthew G. Knepley - maxFaces - The maximum number of cell faces 2280c0ce001eSMatthew G. Knepley 2281c0ce001eSMatthew G. Knepley Level: intermediate 2282c0ce001eSMatthew G. Knepley 2283c0ce001eSMatthew G. Knepley .seealso: PetscFVCreate(), PETSCFVLEASTSQUARES 2284c0ce001eSMatthew G. Knepley @*/ 2285c0ce001eSMatthew G. Knepley PetscErrorCode PetscFVLeastSquaresSetMaxFaces(PetscFV fvm, PetscInt maxFaces) 2286c0ce001eSMatthew G. Knepley { 2287c0ce001eSMatthew G. Knepley PetscErrorCode ierr; 2288c0ce001eSMatthew G. Knepley 2289c0ce001eSMatthew G. Knepley PetscFunctionBegin; 2290c0ce001eSMatthew G. Knepley PetscValidHeaderSpecific(fvm, PETSCFV_CLASSID, 1); 2291c0ce001eSMatthew G. Knepley ierr = PetscTryMethod(fvm, "PetscFVLeastSquaresSetMaxFaces_C", (PetscFV,PetscInt), (fvm,maxFaces));CHKERRQ(ierr); 2292c0ce001eSMatthew G. Knepley PetscFunctionReturn(0); 2293c0ce001eSMatthew G. Knepley } 2294