1 #include <petsc/private/petscdsimpl.h> /*I "petscds.h" I*/ 2 3 PetscClassId PETSCDS_CLASSID = 0; 4 5 PetscFunctionList PetscDSList = NULL; 6 PetscBool PetscDSRegisterAllCalled = PETSC_FALSE; 7 8 #undef __FUNCT__ 9 #define __FUNCT__ "PetscDSRegister" 10 /*@C 11 PetscDSRegister - Adds a new PetscDS implementation 12 13 Not Collective 14 15 Input Parameters: 16 + name - The name of a new user-defined creation routine 17 - create_func - The creation routine itself 18 19 Notes: 20 PetscDSRegister() may be called multiple times to add several user-defined PetscDSs 21 22 Sample usage: 23 .vb 24 PetscDSRegister("my_ds", MyPetscDSCreate); 25 .ve 26 27 Then, your PetscDS type can be chosen with the procedural interface via 28 .vb 29 PetscDSCreate(MPI_Comm, PetscDS *); 30 PetscDSSetType(PetscDS, "my_ds"); 31 .ve 32 or at runtime via the option 33 .vb 34 -petscds_type my_ds 35 .ve 36 37 Level: advanced 38 39 .keywords: PetscDS, register 40 .seealso: PetscDSRegisterAll(), PetscDSRegisterDestroy() 41 42 @*/ 43 PetscErrorCode PetscDSRegister(const char sname[], PetscErrorCode (*function)(PetscDS)) 44 { 45 PetscErrorCode ierr; 46 47 PetscFunctionBegin; 48 ierr = PetscFunctionListAdd(&PetscDSList, sname, function);CHKERRQ(ierr); 49 PetscFunctionReturn(0); 50 } 51 52 #undef __FUNCT__ 53 #define __FUNCT__ "PetscDSSetType" 54 /*@C 55 PetscDSSetType - Builds a particular PetscDS 56 57 Collective on PetscDS 58 59 Input Parameters: 60 + prob - The PetscDS object 61 - name - The kind of system 62 63 Options Database Key: 64 . -petscds_type <type> - Sets the PetscDS type; use -help for a list of available types 65 66 Level: intermediate 67 68 .keywords: PetscDS, set, type 69 .seealso: PetscDSGetType(), PetscDSCreate() 70 @*/ 71 PetscErrorCode PetscDSSetType(PetscDS prob, PetscDSType name) 72 { 73 PetscErrorCode (*r)(PetscDS); 74 PetscBool match; 75 PetscErrorCode ierr; 76 77 PetscFunctionBegin; 78 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 79 ierr = PetscObjectTypeCompare((PetscObject) prob, name, &match);CHKERRQ(ierr); 80 if (match) PetscFunctionReturn(0); 81 82 ierr = PetscDSRegisterAll();CHKERRQ(ierr); 83 ierr = PetscFunctionListFind(PetscDSList, name, &r);CHKERRQ(ierr); 84 if (!r) SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscDS type: %s", name); 85 86 if (prob->ops->destroy) { 87 ierr = (*prob->ops->destroy)(prob);CHKERRQ(ierr); 88 prob->ops->destroy = NULL; 89 } 90 ierr = (*r)(prob);CHKERRQ(ierr); 91 ierr = PetscObjectChangeTypeName((PetscObject) prob, name);CHKERRQ(ierr); 92 PetscFunctionReturn(0); 93 } 94 95 #undef __FUNCT__ 96 #define __FUNCT__ "PetscDSGetType" 97 /*@C 98 PetscDSGetType - Gets the PetscDS type name (as a string) from the object. 99 100 Not Collective 101 102 Input Parameter: 103 . prob - The PetscDS 104 105 Output Parameter: 106 . name - The PetscDS type name 107 108 Level: intermediate 109 110 .keywords: PetscDS, get, type, name 111 .seealso: PetscDSSetType(), PetscDSCreate() 112 @*/ 113 PetscErrorCode PetscDSGetType(PetscDS prob, PetscDSType *name) 114 { 115 PetscErrorCode ierr; 116 117 PetscFunctionBegin; 118 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 119 PetscValidPointer(name, 2); 120 ierr = PetscDSRegisterAll();CHKERRQ(ierr); 121 *name = ((PetscObject) prob)->type_name; 122 PetscFunctionReturn(0); 123 } 124 125 #undef __FUNCT__ 126 #define __FUNCT__ "PetscDSView_Ascii" 127 static PetscErrorCode PetscDSView_Ascii(PetscDS prob, PetscViewer viewer) 128 { 129 PetscViewerFormat format; 130 PetscInt f; 131 PetscErrorCode ierr; 132 133 PetscFunctionBegin; 134 ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 135 ierr = PetscViewerASCIIPrintf(viewer, "Discrete System with %d fields\n", prob->Nf);CHKERRQ(ierr); 136 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 137 for (f = 0; f < prob->Nf; ++f) { 138 PetscObject obj; 139 PetscClassId id; 140 const char *name; 141 PetscInt Nc; 142 143 ierr = PetscDSGetDiscretization(prob, f, &obj);CHKERRQ(ierr); 144 ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 145 ierr = PetscObjectGetName(obj, &name);CHKERRQ(ierr); 146 ierr = PetscViewerASCIIPrintf(viewer, "Field %s", name ? name : "<unknown>");CHKERRQ(ierr); 147 if (id == PETSCFE_CLASSID) { 148 ierr = PetscFEGetNumComponents((PetscFE) obj, &Nc);CHKERRQ(ierr); 149 ierr = PetscViewerASCIIPrintf(viewer, " FEM");CHKERRQ(ierr); 150 } else if (id == PETSCFV_CLASSID) { 151 ierr = PetscFVGetNumComponents((PetscFV) obj, &Nc);CHKERRQ(ierr); 152 ierr = PetscViewerASCIIPrintf(viewer, " FVM");CHKERRQ(ierr); 153 } 154 else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", f); 155 if (Nc > 1) {ierr = PetscViewerASCIIPrintf(viewer, "%d components", Nc);CHKERRQ(ierr);} 156 else {ierr = PetscViewerASCIIPrintf(viewer, "%d component ", Nc);CHKERRQ(ierr);} 157 if (prob->implicit[f]) {ierr = PetscViewerASCIIPrintf(viewer, " (implicit)");CHKERRQ(ierr);} 158 else {ierr = PetscViewerASCIIPrintf(viewer, " (explicit)");CHKERRQ(ierr);} 159 if (prob->adjacency[f*2+0]) { 160 if (prob->adjacency[f*2+1]) {ierr = PetscViewerASCIIPrintf(viewer, " (adj FVM++)");CHKERRQ(ierr);} 161 else {ierr = PetscViewerASCIIPrintf(viewer, " (adj FVM)");CHKERRQ(ierr);} 162 } else { 163 if (prob->adjacency[f*2+1]) {ierr = PetscViewerASCIIPrintf(viewer, " (adj FEM)");CHKERRQ(ierr);} 164 else {ierr = PetscViewerASCIIPrintf(viewer, " (adj FUNKY)");CHKERRQ(ierr);} 165 } 166 ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 167 if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 168 if (id == PETSCFE_CLASSID) {ierr = PetscFEView((PetscFE) obj, viewer);CHKERRQ(ierr);} 169 else if (id == PETSCFV_CLASSID) {ierr = PetscFVView((PetscFV) obj, viewer);CHKERRQ(ierr);} 170 } 171 } 172 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 173 PetscFunctionReturn(0); 174 } 175 176 #undef __FUNCT__ 177 #define __FUNCT__ "PetscDSView" 178 /*@C 179 PetscDSView - Views a PetscDS 180 181 Collective on PetscDS 182 183 Input Parameter: 184 + prob - the PetscDS object to view 185 - v - the viewer 186 187 Level: developer 188 189 .seealso PetscDSDestroy() 190 @*/ 191 PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v) 192 { 193 PetscBool iascii; 194 PetscErrorCode ierr; 195 196 PetscFunctionBegin; 197 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 198 if (!v) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) prob), &v);CHKERRQ(ierr);} 199 else {PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);} 200 ierr = PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 201 if (iascii) {ierr = PetscDSView_Ascii(prob, v);CHKERRQ(ierr);} 202 if (prob->ops->view) {ierr = (*prob->ops->view)(prob, v);CHKERRQ(ierr);} 203 PetscFunctionReturn(0); 204 } 205 206 #undef __FUNCT__ 207 #define __FUNCT__ "PetscDSSetFromOptions" 208 /*@ 209 PetscDSSetFromOptions - sets parameters in a PetscDS from the options database 210 211 Collective on PetscDS 212 213 Input Parameter: 214 . prob - the PetscDS object to set options for 215 216 Options Database: 217 218 Level: developer 219 220 .seealso PetscDSView() 221 @*/ 222 PetscErrorCode PetscDSSetFromOptions(PetscDS prob) 223 { 224 DSBoundary b; 225 const char *defaultType; 226 char name[256]; 227 PetscBool flg; 228 PetscErrorCode ierr; 229 230 PetscFunctionBegin; 231 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 232 if (!((PetscObject) prob)->type_name) { 233 defaultType = PETSCDSBASIC; 234 } else { 235 defaultType = ((PetscObject) prob)->type_name; 236 } 237 ierr = PetscDSRegisterAll();CHKERRQ(ierr); 238 239 ierr = PetscObjectOptionsBegin((PetscObject) prob);CHKERRQ(ierr); 240 for (b = prob->boundary; b; b = b->next) { 241 char optname[1024]; 242 PetscInt ids[1024], len = 1024; 243 PetscBool flg; 244 245 ierr = PetscSNPrintf(optname, sizeof(optname), "-bc_%s", b->name);CHKERRQ(ierr); 246 ierr = PetscMemzero(ids, sizeof(ids));CHKERRQ(ierr); 247 ierr = PetscOptionsIntArray(optname, "List of boundary IDs", "", ids, &len, &flg);CHKERRQ(ierr); 248 if (flg) { 249 b->numids = len; 250 ierr = PetscFree(b->ids);CHKERRQ(ierr); 251 ierr = PetscMalloc1(len, &b->ids);CHKERRQ(ierr); 252 ierr = PetscMemcpy(b->ids, ids, len*sizeof(PetscInt));CHKERRQ(ierr); 253 } 254 ierr = PetscSNPrintf(optname, sizeof(optname), "-bc_%s_comp", b->name);CHKERRQ(ierr); 255 ierr = PetscMemzero(ids, sizeof(ids));CHKERRQ(ierr); 256 ierr = PetscOptionsIntArray(optname, "List of boundary field components", "", ids, &len, &flg);CHKERRQ(ierr); 257 if (flg) { 258 b->numcomps = len; 259 ierr = PetscFree(b->comps);CHKERRQ(ierr); 260 ierr = PetscMalloc1(len, &b->comps);CHKERRQ(ierr); 261 ierr = PetscMemcpy(b->comps, ids, len*sizeof(PetscInt));CHKERRQ(ierr); 262 } 263 } 264 ierr = PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg);CHKERRQ(ierr); 265 if (flg) { 266 ierr = PetscDSSetType(prob, name);CHKERRQ(ierr); 267 } else if (!((PetscObject) prob)->type_name) { 268 ierr = PetscDSSetType(prob, defaultType);CHKERRQ(ierr); 269 } 270 if (prob->ops->setfromoptions) {ierr = (*prob->ops->setfromoptions)(prob);CHKERRQ(ierr);} 271 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 272 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) prob);CHKERRQ(ierr); 273 ierr = PetscOptionsEnd();CHKERRQ(ierr); 274 ierr = PetscDSViewFromOptions(prob, NULL, "-petscds_view");CHKERRQ(ierr); 275 PetscFunctionReturn(0); 276 } 277 278 #undef __FUNCT__ 279 #define __FUNCT__ "PetscDSSetUp" 280 /*@C 281 PetscDSSetUp - Construct data structures for the PetscDS 282 283 Collective on PetscDS 284 285 Input Parameter: 286 . prob - the PetscDS object to setup 287 288 Level: developer 289 290 .seealso PetscDSView(), PetscDSDestroy() 291 @*/ 292 PetscErrorCode PetscDSSetUp(PetscDS prob) 293 { 294 const PetscInt Nf = prob->Nf; 295 PetscInt dim, work, NcMax = 0, NqMax = 0, f; 296 PetscErrorCode ierr; 297 298 PetscFunctionBegin; 299 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 300 if (prob->setup) PetscFunctionReturn(0); 301 /* Calculate sizes */ 302 ierr = PetscDSGetSpatialDimension(prob, &dim);CHKERRQ(ierr); 303 prob->totDim = prob->totDimBd = prob->totComp = 0; 304 ierr = PetscMalloc2(Nf,&prob->Nc,Nf,&prob->Nb);CHKERRQ(ierr); 305 ierr = PetscCalloc4(Nf+1,&prob->off,Nf+1,&prob->offDer,Nf+1,&prob->offBd,Nf+1,&prob->offDerBd);CHKERRQ(ierr); 306 ierr = PetscMalloc6(Nf,&prob->basis,Nf,&prob->basisDer,Nf,&prob->basisBd,Nf,&prob->basisDerBd,Nf,&prob->basisFace,Nf,&prob->basisDerFace);CHKERRQ(ierr); 307 for (f = 0; f < Nf; ++f) { 308 PetscFE feBd = (PetscFE) prob->discBd[f]; 309 PetscObject obj; 310 PetscClassId id; 311 PetscQuadrature q; 312 PetscInt Nq = 0, Nb, Nc; 313 314 ierr = PetscDSGetDiscretization(prob, f, &obj);CHKERRQ(ierr); 315 ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 316 if (id == PETSCFE_CLASSID) { 317 PetscFE fe = (PetscFE) obj; 318 319 ierr = PetscFEGetQuadrature(fe, &q);CHKERRQ(ierr); 320 ierr = PetscFEGetDimension(fe, &Nb);CHKERRQ(ierr); 321 ierr = PetscFEGetNumComponents(fe, &Nc);CHKERRQ(ierr); 322 ierr = PetscFEGetDefaultTabulation(fe, &prob->basis[f], &prob->basisDer[f], NULL);CHKERRQ(ierr); 323 ierr = PetscFEGetFaceTabulation(fe, &prob->basisFace[f], &prob->basisDerFace[f], NULL);CHKERRQ(ierr); 324 } else if (id == PETSCFV_CLASSID) { 325 PetscFV fv = (PetscFV) obj; 326 327 ierr = PetscFVGetQuadrature(fv, &q);CHKERRQ(ierr); 328 Nb = 1; 329 ierr = PetscFVGetNumComponents(fv, &Nc);CHKERRQ(ierr); 330 ierr = PetscFVGetDefaultTabulation(fv, &prob->basis[f], &prob->basisDer[f], NULL);CHKERRQ(ierr); 331 /* TODO: should PetscFV also have face tabulation? Otherwise there will be a null pointer in prob->basisFace */ 332 } else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", f); 333 prob->Nc[f] = Nc; 334 prob->Nb[f] = Nb; 335 prob->off[f+1] = Nc + prob->off[f]; 336 prob->offDer[f+1] = Nc*dim + prob->offDer[f]; 337 if (q) {ierr = PetscQuadratureGetData(q, NULL, &Nq, NULL, NULL);CHKERRQ(ierr);} 338 NqMax = PetscMax(NqMax, Nq); 339 NcMax = PetscMax(NcMax, Nc); 340 prob->totDim += Nb*Nc; 341 prob->totComp += Nc; 342 if (feBd) { 343 ierr = PetscFEGetDimension(feBd, &Nb);CHKERRQ(ierr); 344 ierr = PetscFEGetNumComponents(feBd, &Nc);CHKERRQ(ierr); 345 ierr = PetscFEGetDefaultTabulation(feBd, &prob->basisBd[f], &prob->basisDerBd[f], NULL);CHKERRQ(ierr); 346 prob->totDimBd += Nb*Nc; 347 prob->offBd[f+1] = Nc + prob->offBd[f]; 348 prob->offDerBd[f+1] = Nc*dim + prob->offDerBd[f]; 349 } 350 } 351 work = PetscMax(prob->totComp*dim, PetscSqr(NcMax*dim)); 352 /* Allocate works space */ 353 ierr = PetscMalloc5(prob->totComp,&prob->u,prob->totComp,&prob->u_t,prob->totComp*dim,&prob->u_x,dim,&prob->x,work,&prob->refSpaceDer);CHKERRQ(ierr); 354 ierr = PetscMalloc6(NqMax*NcMax,&prob->f0,NqMax*NcMax*dim,&prob->f1,NqMax*NcMax*NcMax,&prob->g0,NqMax*NcMax*NcMax*dim,&prob->g1,NqMax*NcMax*NcMax*dim,&prob->g2,NqMax*NcMax*NcMax*dim*dim,&prob->g3);CHKERRQ(ierr); 355 if (prob->ops->setup) {ierr = (*prob->ops->setup)(prob);CHKERRQ(ierr);} 356 prob->setup = PETSC_TRUE; 357 PetscFunctionReturn(0); 358 } 359 360 #undef __FUNCT__ 361 #define __FUNCT__ "PetscDSDestroyStructs_Static" 362 static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob) 363 { 364 PetscErrorCode ierr; 365 366 PetscFunctionBegin; 367 ierr = PetscFree2(prob->Nc,prob->Nb);CHKERRQ(ierr); 368 ierr = PetscFree4(prob->off,prob->offDer,prob->offBd,prob->offDerBd);CHKERRQ(ierr); 369 ierr = PetscFree6(prob->basis,prob->basisDer,prob->basisBd,prob->basisDerBd,prob->basisFace,prob->basisDerFace);CHKERRQ(ierr); 370 ierr = PetscFree5(prob->u,prob->u_t,prob->u_x,prob->x,prob->refSpaceDer);CHKERRQ(ierr); 371 ierr = PetscFree6(prob->f0,prob->f1,prob->g0,prob->g1,prob->g2,prob->g3);CHKERRQ(ierr); 372 PetscFunctionReturn(0); 373 } 374 375 #undef __FUNCT__ 376 #define __FUNCT__ "PetscDSEnlarge_Static" 377 static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew) 378 { 379 PetscObject *tmpd, *tmpdbd; 380 PetscBool *tmpi, *tmpa; 381 PetscPointFunc *tmpobj, *tmpf; 382 PetscPointJac *tmpg, *tmpgp, *tmpgt; 383 PetscBdPointFunc *tmpfbd; 384 PetscBdPointJac *tmpgbd; 385 PetscRiemannFunc *tmpr; 386 void **tmpctx; 387 PetscInt Nf = prob->Nf, f, i; 388 PetscErrorCode ierr; 389 390 PetscFunctionBegin; 391 if (Nf >= NfNew) PetscFunctionReturn(0); 392 prob->setup = PETSC_FALSE; 393 ierr = PetscDSDestroyStructs_Static(prob);CHKERRQ(ierr); 394 ierr = PetscMalloc4(NfNew, &tmpd, NfNew, &tmpdbd, NfNew, &tmpi, NfNew*2, &tmpa);CHKERRQ(ierr); 395 for (f = 0; f < Nf; ++f) {tmpd[f] = prob->disc[f]; tmpdbd[f] = prob->discBd[f]; tmpi[f] = prob->implicit[f]; for (i = 0; i < 2; ++i) tmpa[f*2+i] = prob->adjacency[f*2+i];} 396 for (f = Nf; f < NfNew; ++f) {tmpd[f] = NULL, tmpdbd[f] = NULL; tmpi[f] = PETSC_TRUE; tmpa[f*2+0] = PETSC_FALSE; tmpa[f*2+1] = PETSC_TRUE;} 397 ierr = PetscFree4(prob->disc, prob->discBd, prob->implicit, prob->adjacency);CHKERRQ(ierr); 398 prob->Nf = NfNew; 399 prob->disc = tmpd; 400 prob->discBd = tmpdbd; 401 prob->implicit = tmpi; 402 prob->adjacency = tmpa; 403 ierr = PetscCalloc7(NfNew, &tmpobj, NfNew*2, &tmpf, NfNew*NfNew*4, &tmpg, NfNew*NfNew*4, &tmpgp, NfNew*NfNew*4, &tmpgt, NfNew, &tmpr, NfNew, &tmpctx);CHKERRQ(ierr); 404 for (f = 0; f < Nf; ++f) tmpobj[f] = prob->obj[f]; 405 for (f = 0; f < Nf*2; ++f) tmpf[f] = prob->f[f]; 406 for (f = 0; f < Nf*Nf*4; ++f) tmpg[f] = prob->g[f]; 407 for (f = 0; f < Nf*Nf*4; ++f) tmpgp[f] = prob->gp[f]; 408 for (f = 0; f < Nf; ++f) tmpr[f] = prob->r[f]; 409 for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f]; 410 for (f = Nf; f < NfNew; ++f) tmpobj[f] = NULL; 411 for (f = Nf*2; f < NfNew*2; ++f) tmpf[f] = NULL; 412 for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpg[f] = NULL; 413 for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpgp[f] = NULL; 414 for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpgt[f] = NULL; 415 for (f = Nf; f < NfNew; ++f) tmpr[f] = NULL; 416 for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL; 417 ierr = PetscFree7(prob->obj, prob->f, prob->g, prob->gp, prob->gt, prob->r, prob->ctx);CHKERRQ(ierr); 418 prob->obj = tmpobj; 419 prob->f = tmpf; 420 prob->g = tmpg; 421 prob->gp = tmpgp; 422 prob->gt = tmpgt; 423 prob->r = tmpr; 424 prob->ctx = tmpctx; 425 ierr = PetscCalloc2(NfNew*2, &tmpfbd, NfNew*NfNew*4, &tmpgbd);CHKERRQ(ierr); 426 for (f = 0; f < Nf*2; ++f) tmpfbd[f] = prob->fBd[f]; 427 for (f = 0; f < Nf*Nf*4; ++f) tmpgbd[f] = prob->gBd[f]; 428 for (f = Nf*2; f < NfNew*2; ++f) tmpfbd[f] = NULL; 429 for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpgbd[f] = NULL; 430 ierr = PetscFree2(prob->fBd, prob->gBd);CHKERRQ(ierr); 431 prob->fBd = tmpfbd; 432 prob->gBd = tmpgbd; 433 PetscFunctionReturn(0); 434 } 435 436 #undef __FUNCT__ 437 #define __FUNCT__ "PetscDSDestroy" 438 /*@ 439 PetscDSDestroy - Destroys a PetscDS object 440 441 Collective on PetscDS 442 443 Input Parameter: 444 . prob - the PetscDS object to destroy 445 446 Level: developer 447 448 .seealso PetscDSView() 449 @*/ 450 PetscErrorCode PetscDSDestroy(PetscDS *prob) 451 { 452 PetscInt f; 453 DSBoundary next; 454 PetscErrorCode ierr; 455 456 PetscFunctionBegin; 457 if (!*prob) PetscFunctionReturn(0); 458 PetscValidHeaderSpecific((*prob), PETSCDS_CLASSID, 1); 459 460 if (--((PetscObject)(*prob))->refct > 0) {*prob = 0; PetscFunctionReturn(0);} 461 ((PetscObject) (*prob))->refct = 0; 462 ierr = PetscDSDestroyStructs_Static(*prob);CHKERRQ(ierr); 463 for (f = 0; f < (*prob)->Nf; ++f) { 464 ierr = PetscObjectDereference((*prob)->disc[f]);CHKERRQ(ierr); 465 ierr = PetscObjectDereference((*prob)->discBd[f]);CHKERRQ(ierr); 466 } 467 ierr = PetscFree4((*prob)->disc, (*prob)->discBd, (*prob)->implicit, (*prob)->adjacency);CHKERRQ(ierr); 468 ierr = PetscFree7((*prob)->obj,(*prob)->f,(*prob)->g,(*prob)->gp,(*prob)->gt,(*prob)->r,(*prob)->ctx);CHKERRQ(ierr); 469 ierr = PetscFree2((*prob)->fBd,(*prob)->gBd);CHKERRQ(ierr); 470 if ((*prob)->ops->destroy) {ierr = (*(*prob)->ops->destroy)(*prob);CHKERRQ(ierr);} 471 next = (*prob)->boundary; 472 while (next) { 473 DSBoundary b = next; 474 475 next = b->next; 476 ierr = PetscFree(b->comps);CHKERRQ(ierr); 477 ierr = PetscFree(b->ids);CHKERRQ(ierr); 478 ierr = PetscFree(b->name);CHKERRQ(ierr); 479 ierr = PetscFree(b->labelname);CHKERRQ(ierr); 480 ierr = PetscFree(b);CHKERRQ(ierr); 481 } 482 ierr = PetscHeaderDestroy(prob);CHKERRQ(ierr); 483 PetscFunctionReturn(0); 484 } 485 486 #undef __FUNCT__ 487 #define __FUNCT__ "PetscDSCreate" 488 /*@ 489 PetscDSCreate - Creates an empty PetscDS object. The type can then be set with PetscDSSetType(). 490 491 Collective on MPI_Comm 492 493 Input Parameter: 494 . comm - The communicator for the PetscDS object 495 496 Output Parameter: 497 . prob - The PetscDS object 498 499 Level: beginner 500 501 .seealso: PetscDSSetType(), PETSCDSBASIC 502 @*/ 503 PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *prob) 504 { 505 PetscDS p; 506 PetscErrorCode ierr; 507 508 PetscFunctionBegin; 509 PetscValidPointer(prob, 2); 510 *prob = NULL; 511 ierr = PetscDSInitializePackage();CHKERRQ(ierr); 512 513 ierr = PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView);CHKERRQ(ierr); 514 515 p->Nf = 0; 516 p->setup = PETSC_FALSE; 517 518 *prob = p; 519 PetscFunctionReturn(0); 520 } 521 522 #undef __FUNCT__ 523 #define __FUNCT__ "PetscDSGetNumFields" 524 /*@ 525 PetscDSGetNumFields - Returns the number of fields in the DS 526 527 Not collective 528 529 Input Parameter: 530 . prob - The PetscDS object 531 532 Output Parameter: 533 . Nf - The number of fields 534 535 Level: beginner 536 537 .seealso: PetscDSGetSpatialDimension(), PetscDSCreate() 538 @*/ 539 PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf) 540 { 541 PetscFunctionBegin; 542 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 543 PetscValidPointer(Nf, 2); 544 *Nf = prob->Nf; 545 PetscFunctionReturn(0); 546 } 547 548 #undef __FUNCT__ 549 #define __FUNCT__ "PetscDSGetSpatialDimension" 550 /*@ 551 PetscDSGetSpatialDimension - Returns the spatial dimension of the DS 552 553 Not collective 554 555 Input Parameter: 556 . prob - The PetscDS object 557 558 Output Parameter: 559 . dim - The spatial dimension 560 561 Level: beginner 562 563 .seealso: PetscDSGetNumFields(), PetscDSCreate() 564 @*/ 565 PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim) 566 { 567 PetscErrorCode ierr; 568 569 PetscFunctionBegin; 570 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 571 PetscValidPointer(dim, 2); 572 *dim = 0; 573 if (prob->Nf) { 574 PetscObject obj; 575 PetscClassId id; 576 577 ierr = PetscDSGetDiscretization(prob, 0, &obj);CHKERRQ(ierr); 578 ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 579 if (id == PETSCFE_CLASSID) {ierr = PetscFEGetSpatialDimension((PetscFE) obj, dim);CHKERRQ(ierr);} 580 else if (id == PETSCFV_CLASSID) {ierr = PetscFVGetSpatialDimension((PetscFV) obj, dim);CHKERRQ(ierr);} 581 else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0); 582 } 583 PetscFunctionReturn(0); 584 } 585 586 #undef __FUNCT__ 587 #define __FUNCT__ "PetscDSGetTotalDimension" 588 /*@ 589 PetscDSGetTotalDimension - Returns the total size of the approximation space for this system 590 591 Not collective 592 593 Input Parameter: 594 . prob - The PetscDS object 595 596 Output Parameter: 597 . dim - The total problem dimension 598 599 Level: beginner 600 601 .seealso: PetscDSGetNumFields(), PetscDSCreate() 602 @*/ 603 PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim) 604 { 605 PetscErrorCode ierr; 606 607 PetscFunctionBegin; 608 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 609 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 610 PetscValidPointer(dim, 2); 611 *dim = prob->totDim; 612 PetscFunctionReturn(0); 613 } 614 615 #undef __FUNCT__ 616 #define __FUNCT__ "PetscDSGetTotalBdDimension" 617 /*@ 618 PetscDSGetTotalBdDimension - Returns the total size of the boundary approximation space for this system 619 620 Not collective 621 622 Input Parameter: 623 . prob - The PetscDS object 624 625 Output Parameter: 626 . dim - The total boundary problem dimension 627 628 Level: beginner 629 630 .seealso: PetscDSGetNumFields(), PetscDSCreate() 631 @*/ 632 PetscErrorCode PetscDSGetTotalBdDimension(PetscDS prob, PetscInt *dim) 633 { 634 PetscErrorCode ierr; 635 636 PetscFunctionBegin; 637 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 638 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 639 PetscValidPointer(dim, 2); 640 *dim = prob->totDimBd; 641 PetscFunctionReturn(0); 642 } 643 644 #undef __FUNCT__ 645 #define __FUNCT__ "PetscDSGetTotalComponents" 646 /*@ 647 PetscDSGetTotalComponents - Returns the total number of components in this system 648 649 Not collective 650 651 Input Parameter: 652 . prob - The PetscDS object 653 654 Output Parameter: 655 . dim - The total number of components 656 657 Level: beginner 658 659 .seealso: PetscDSGetNumFields(), PetscDSCreate() 660 @*/ 661 PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc) 662 { 663 PetscErrorCode ierr; 664 665 PetscFunctionBegin; 666 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 667 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 668 PetscValidPointer(Nc, 2); 669 *Nc = prob->totComp; 670 PetscFunctionReturn(0); 671 } 672 673 #undef __FUNCT__ 674 #define __FUNCT__ "PetscDSGetDiscretization" 675 /*@ 676 PetscDSGetDiscretization - Returns the discretization object for the given field 677 678 Not collective 679 680 Input Parameters: 681 + prob - The PetscDS object 682 - f - The field number 683 684 Output Parameter: 685 . disc - The discretization object 686 687 Level: beginner 688 689 .seealso: PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetBdDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 690 @*/ 691 PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc) 692 { 693 PetscFunctionBegin; 694 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 695 PetscValidPointer(disc, 3); 696 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 697 *disc = prob->disc[f]; 698 PetscFunctionReturn(0); 699 } 700 701 #undef __FUNCT__ 702 #define __FUNCT__ "PetscDSGetBdDiscretization" 703 /*@ 704 PetscDSGetBdDiscretization - Returns the boundary discretization object for the given field 705 706 Not collective 707 708 Input Parameters: 709 + prob - The PetscDS object 710 - f - The field number 711 712 Output Parameter: 713 . disc - The boundary discretization object 714 715 Level: beginner 716 717 .seealso: PetscDSSetBdDiscretization(), PetscDSAddBdDiscretization(), PetscDSGetDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 718 @*/ 719 PetscErrorCode PetscDSGetBdDiscretization(PetscDS prob, PetscInt f, PetscObject *disc) 720 { 721 PetscFunctionBegin; 722 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 723 PetscValidPointer(disc, 3); 724 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 725 *disc = prob->discBd[f]; 726 PetscFunctionReturn(0); 727 } 728 729 #undef __FUNCT__ 730 #define __FUNCT__ "PetscDSSetDiscretization" 731 /*@ 732 PetscDSSetDiscretization - Sets the discretization object for the given field 733 734 Not collective 735 736 Input Parameters: 737 + prob - The PetscDS object 738 . f - The field number 739 - disc - The discretization object 740 741 Level: beginner 742 743 .seealso: PetscDSGetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 744 @*/ 745 PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc) 746 { 747 PetscErrorCode ierr; 748 749 PetscFunctionBegin; 750 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 751 PetscValidPointer(disc, 3); 752 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 753 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr); 754 if (prob->disc[f]) {ierr = PetscObjectDereference(prob->disc[f]);CHKERRQ(ierr);} 755 prob->disc[f] = disc; 756 ierr = PetscObjectReference(disc);CHKERRQ(ierr); 757 { 758 PetscClassId id; 759 760 ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr); 761 if (id == PETSCFV_CLASSID) { 762 prob->implicit[f] = PETSC_FALSE; 763 prob->adjacency[f*2+0] = PETSC_TRUE; 764 prob->adjacency[f*2+1] = PETSC_FALSE; 765 } 766 } 767 PetscFunctionReturn(0); 768 } 769 770 #undef __FUNCT__ 771 #define __FUNCT__ "PetscDSSetBdDiscretization" 772 /*@ 773 PetscDSSetBdDiscretization - Sets the boundary discretization object for the given field 774 775 Not collective 776 777 Input Parameters: 778 + prob - The PetscDS object 779 . f - The field number 780 - disc - The boundary discretization object 781 782 Level: beginner 783 784 .seealso: PetscDSGetBdDiscretization(), PetscDSAddBdDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 785 @*/ 786 PetscErrorCode PetscDSSetBdDiscretization(PetscDS prob, PetscInt f, PetscObject disc) 787 { 788 PetscErrorCode ierr; 789 790 PetscFunctionBegin; 791 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 792 if (disc) PetscValidPointer(disc, 3); 793 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 794 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr); 795 if (prob->discBd[f]) {ierr = PetscObjectDereference(prob->discBd[f]);CHKERRQ(ierr);} 796 prob->discBd[f] = disc; 797 ierr = PetscObjectReference(disc);CHKERRQ(ierr); 798 PetscFunctionReturn(0); 799 } 800 801 #undef __FUNCT__ 802 #define __FUNCT__ "PetscDSAddDiscretization" 803 /*@ 804 PetscDSAddDiscretization - Adds a discretization object 805 806 Not collective 807 808 Input Parameters: 809 + prob - The PetscDS object 810 - disc - The boundary discretization object 811 812 Level: beginner 813 814 .seealso: PetscDSGetDiscretization(), PetscDSSetDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 815 @*/ 816 PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc) 817 { 818 PetscErrorCode ierr; 819 820 PetscFunctionBegin; 821 ierr = PetscDSSetDiscretization(prob, prob->Nf, disc);CHKERRQ(ierr); 822 PetscFunctionReturn(0); 823 } 824 825 #undef __FUNCT__ 826 #define __FUNCT__ "PetscDSAddBdDiscretization" 827 /*@ 828 PetscDSAddBdDiscretization - Adds a boundary discretization object 829 830 Not collective 831 832 Input Parameters: 833 + prob - The PetscDS object 834 - disc - The boundary discretization object 835 836 Level: beginner 837 838 .seealso: PetscDSGetBdDiscretization(), PetscDSSetBdDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 839 @*/ 840 PetscErrorCode PetscDSAddBdDiscretization(PetscDS prob, PetscObject disc) 841 { 842 PetscErrorCode ierr; 843 844 PetscFunctionBegin; 845 ierr = PetscDSSetBdDiscretization(prob, prob->Nf, disc);CHKERRQ(ierr); 846 PetscFunctionReturn(0); 847 } 848 849 #undef __FUNCT__ 850 #define __FUNCT__ "PetscDSGetImplicit" 851 /*@ 852 PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for IMEX 853 854 Not collective 855 856 Input Parameters: 857 + prob - The PetscDS object 858 - f - The field number 859 860 Output Parameter: 861 . implicit - The flag indicating what kind of solve to use for this field 862 863 Level: developer 864 865 .seealso: PetscDSSetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetBdDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 866 @*/ 867 PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit) 868 { 869 PetscFunctionBegin; 870 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 871 PetscValidPointer(implicit, 3); 872 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 873 *implicit = prob->implicit[f]; 874 PetscFunctionReturn(0); 875 } 876 877 #undef __FUNCT__ 878 #define __FUNCT__ "PetscDSSetImplicit" 879 /*@ 880 PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for IMEX 881 882 Not collective 883 884 Input Parameters: 885 + prob - The PetscDS object 886 . f - The field number 887 - implicit - The flag indicating what kind of solve to use for this field 888 889 Level: developer 890 891 .seealso: PetscDSGetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetBdDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 892 @*/ 893 PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit) 894 { 895 PetscFunctionBegin; 896 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 897 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 898 prob->implicit[f] = implicit; 899 PetscFunctionReturn(0); 900 } 901 902 #undef __FUNCT__ 903 #define __FUNCT__ "PetscDSGetAdjacency" 904 /*@ 905 PetscDSGetAdjacency - Returns the flags for determining variable influence 906 907 Not collective 908 909 Input Parameters: 910 + prob - The PetscDS object 911 - f - The field number 912 913 Output Parameter: 914 + useCone - Flag for variable influence starting with the cone operation 915 - useClosure - Flag for variable influence using transitive closure 916 917 Note: See the discussion in DMPlexGetAdjacencyUseCone() and DMPlexGetAdjacencyUseClosure() 918 919 Level: developer 920 921 .seealso: PetscDSSetAdjacency(), DMPlexGetAdjacencyUseCone(), DMPlexGetAdjacencyUseClosure(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetBdDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 922 @*/ 923 PetscErrorCode PetscDSGetAdjacency(PetscDS prob, PetscInt f, PetscBool *useCone, PetscBool *useClosure) 924 { 925 PetscFunctionBegin; 926 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 927 PetscValidPointer(useCone, 3); 928 PetscValidPointer(useClosure, 4); 929 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 930 *useCone = prob->adjacency[f*2+0]; 931 *useClosure = prob->adjacency[f*2+1]; 932 PetscFunctionReturn(0); 933 } 934 935 #undef __FUNCT__ 936 #define __FUNCT__ "PetscDSSetAdjacency" 937 /*@ 938 PetscDSSetAdjacency - Set the flags for determining variable influence 939 940 Not collective 941 942 Input Parameters: 943 + prob - The PetscDS object 944 . f - The field number 945 . useCone - Flag for variable influence starting with the cone operation 946 - useClosure - Flag for variable influence using transitive closure 947 948 Note: See the discussion in DMPlexGetAdjacencyUseCone() and DMPlexGetAdjacencyUseClosure() 949 950 Level: developer 951 952 .seealso: PetscDSGetAdjacency(), DMPlexGetAdjacencyUseCone(), DMPlexGetAdjacencyUseClosure(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetBdDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 953 @*/ 954 PetscErrorCode PetscDSSetAdjacency(PetscDS prob, PetscInt f, PetscBool useCone, PetscBool useClosure) 955 { 956 PetscFunctionBegin; 957 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 958 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 959 prob->adjacency[f*2+0] = useCone; 960 prob->adjacency[f*2+1] = useClosure; 961 PetscFunctionReturn(0); 962 } 963 964 #undef __FUNCT__ 965 #define __FUNCT__ "PetscDSGetObjective" 966 PetscErrorCode PetscDSGetObjective(PetscDS prob, PetscInt f, 967 void (**obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 968 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 969 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 970 PetscReal t, const PetscReal x[], PetscScalar obj[])) 971 { 972 PetscFunctionBegin; 973 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 974 PetscValidPointer(obj, 2); 975 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 976 *obj = prob->obj[f]; 977 PetscFunctionReturn(0); 978 } 979 980 #undef __FUNCT__ 981 #define __FUNCT__ "PetscDSSetObjective" 982 PetscErrorCode PetscDSSetObjective(PetscDS prob, PetscInt f, 983 void (*obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 984 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 985 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 986 PetscReal t, const PetscReal x[], PetscScalar obj[])) 987 { 988 PetscErrorCode ierr; 989 990 PetscFunctionBegin; 991 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 992 if (obj) PetscValidFunction(obj, 2); 993 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 994 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr); 995 prob->obj[f] = obj; 996 PetscFunctionReturn(0); 997 } 998 999 #undef __FUNCT__ 1000 #define __FUNCT__ "PetscDSGetResidual" 1001 /*@C 1002 PetscDSGetResidual - Get the pointwise residual function for a given test field 1003 1004 Not collective 1005 1006 Input Parameters: 1007 + prob - The PetscDS 1008 - f - The test field number 1009 1010 Output Parameters: 1011 + f0 - integrand for the test function term 1012 - f1 - integrand for the test function gradient term 1013 1014 Note: We are using a first order FEM model for the weak form: 1015 1016 \int_\Omega \phi f_0(u, u_t, \nabla u, x, t) + \nabla\phi \cdot {\vec f}_1(u, u_t, \nabla u, x, t) 1017 1018 The calling sequence for the callbacks f0 and f1 is given by: 1019 1020 $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1021 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1022 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1023 $ PetscReal t, const PetscReal x[], PetscScalar f0[]) 1024 1025 + dim - the spatial dimension 1026 . Nf - the number of fields 1027 . uOff - the offset into u[] and u_t[] for each field 1028 . uOff_x - the offset into u_x[] for each field 1029 . u - each field evaluated at the current point 1030 . u_t - the time derivative of each field evaluated at the current point 1031 . u_x - the gradient of each field evaluated at the current point 1032 . aOff - the offset into a[] and a_t[] for each auxiliary field 1033 . aOff_x - the offset into a_x[] for each auxiliary field 1034 . a - each auxiliary field evaluated at the current point 1035 . a_t - the time derivative of each auxiliary field evaluated at the current point 1036 . a_x - the gradient of auxiliary each field evaluated at the current point 1037 . t - current time 1038 . x - coordinates of the current point 1039 - f0 - output values at the current point 1040 1041 Level: intermediate 1042 1043 .seealso: PetscDSSetResidual() 1044 @*/ 1045 PetscErrorCode PetscDSGetResidual(PetscDS prob, PetscInt f, 1046 void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1047 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1048 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1049 PetscReal t, const PetscReal x[], PetscScalar f0[]), 1050 void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1051 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1052 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1053 PetscReal t, const PetscReal x[], PetscScalar f1[])) 1054 { 1055 PetscFunctionBegin; 1056 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1057 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 1058 if (f0) {PetscValidPointer(f0, 3); *f0 = prob->f[f*2+0];} 1059 if (f1) {PetscValidPointer(f1, 4); *f1 = prob->f[f*2+1];} 1060 PetscFunctionReturn(0); 1061 } 1062 1063 #undef __FUNCT__ 1064 #define __FUNCT__ "PetscDSSetResidual" 1065 /*@C 1066 PetscDSSetResidual - Set the pointwise residual function for a given test field 1067 1068 Not collective 1069 1070 Input Parameters: 1071 + prob - The PetscDS 1072 . f - The test field number 1073 . f0 - integrand for the test function term 1074 - f1 - integrand for the test function gradient term 1075 1076 Note: We are using a first order FEM model for the weak form: 1077 1078 \int_\Omega \phi f_0(u, u_t, \nabla u, x, t) + \nabla\phi \cdot {\vec f}_1(u, u_t, \nabla u, x, t) 1079 1080 The calling sequence for the callbacks f0 and f1 is given by: 1081 1082 $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1083 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1084 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1085 $ PetscReal t, const PetscReal x[], PetscScalar f0[]) 1086 1087 + dim - the spatial dimension 1088 . Nf - the number of fields 1089 . uOff - the offset into u[] and u_t[] for each field 1090 . uOff_x - the offset into u_x[] for each field 1091 . u - each field evaluated at the current point 1092 . u_t - the time derivative of each field evaluated at the current point 1093 . u_x - the gradient of each field evaluated at the current point 1094 . aOff - the offset into a[] and a_t[] for each auxiliary field 1095 . aOff_x - the offset into a_x[] for each auxiliary field 1096 . a - each auxiliary field evaluated at the current point 1097 . a_t - the time derivative of each auxiliary field evaluated at the current point 1098 . a_x - the gradient of auxiliary each field evaluated at the current point 1099 . t - current time 1100 . x - coordinates of the current point 1101 - f0 - output values at the current point 1102 1103 Level: intermediate 1104 1105 .seealso: PetscDSGetResidual() 1106 @*/ 1107 PetscErrorCode PetscDSSetResidual(PetscDS prob, PetscInt f, 1108 void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1109 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1110 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1111 PetscReal t, const PetscReal x[], PetscScalar f0[]), 1112 void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1113 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1114 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1115 PetscReal t, const PetscReal x[], PetscScalar f1[])) 1116 { 1117 PetscErrorCode ierr; 1118 1119 PetscFunctionBegin; 1120 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1121 if (f0) PetscValidFunction(f0, 3); 1122 if (f1) PetscValidFunction(f1, 4); 1123 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 1124 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr); 1125 prob->f[f*2+0] = f0; 1126 prob->f[f*2+1] = f1; 1127 PetscFunctionReturn(0); 1128 } 1129 1130 #undef __FUNCT__ 1131 #define __FUNCT__ "PetscDSHasJacobian" 1132 /*@C 1133 PetscDSHasJacobian - Signals that Jacobian functions have been set 1134 1135 Not collective 1136 1137 Input Parameter: 1138 . prob - The PetscDS 1139 1140 Output Parameter: 1141 . hasJac - flag that pointwise function for the Jacobian has been set 1142 1143 Level: intermediate 1144 1145 .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian() 1146 @*/ 1147 PetscErrorCode PetscDSHasJacobian(PetscDS prob, PetscBool *hasJac) 1148 { 1149 PetscInt f, g, h; 1150 1151 PetscFunctionBegin; 1152 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1153 *hasJac = PETSC_FALSE; 1154 for (f = 0; f < prob->Nf; ++f) { 1155 for (g = 0; g < prob->Nf; ++g) { 1156 for (h = 0; h < 4; ++h) { 1157 if (prob->g[(f*prob->Nf + g)*4+h]) *hasJac = PETSC_TRUE; 1158 } 1159 } 1160 } 1161 PetscFunctionReturn(0); 1162 } 1163 1164 #undef __FUNCT__ 1165 #define __FUNCT__ "PetscDSGetJacobian" 1166 /*@C 1167 PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field 1168 1169 Not collective 1170 1171 Input Parameters: 1172 + prob - The PetscDS 1173 . f - The test field number 1174 - g - The field number 1175 1176 Output Parameters: 1177 + g0 - integrand for the test and basis function term 1178 . g1 - integrand for the test function and basis function gradient term 1179 . g2 - integrand for the test function gradient and basis function term 1180 - g3 - integrand for the test function gradient and basis function gradient term 1181 1182 Note: We are using a first order FEM model for the weak form: 1183 1184 \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi 1185 1186 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 1187 1188 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1189 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1190 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1191 $ PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[]) 1192 1193 + dim - the spatial dimension 1194 . Nf - the number of fields 1195 . uOff - the offset into u[] and u_t[] for each field 1196 . uOff_x - the offset into u_x[] for each field 1197 . u - each field evaluated at the current point 1198 . u_t - the time derivative of each field evaluated at the current point 1199 . u_x - the gradient of each field evaluated at the current point 1200 . aOff - the offset into a[] and a_t[] for each auxiliary field 1201 . aOff_x - the offset into a_x[] for each auxiliary field 1202 . a - each auxiliary field evaluated at the current point 1203 . a_t - the time derivative of each auxiliary field evaluated at the current point 1204 . a_x - the gradient of auxiliary each field evaluated at the current point 1205 . t - current time 1206 . u_tShift - the multiplier a for dF/dU_t 1207 . x - coordinates of the current point 1208 - g0 - output values at the current point 1209 1210 Level: intermediate 1211 1212 .seealso: PetscDSSetJacobian() 1213 @*/ 1214 PetscErrorCode PetscDSGetJacobian(PetscDS prob, PetscInt f, PetscInt g, 1215 void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1216 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1217 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1218 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g0[]), 1219 void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1220 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1221 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1222 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g1[]), 1223 void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1224 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1225 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1226 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g2[]), 1227 void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1228 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1229 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1230 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g3[])) 1231 { 1232 PetscFunctionBegin; 1233 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1234 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 1235 if ((g < 0) || (g >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, prob->Nf); 1236 if (g0) {PetscValidPointer(g0, 4); *g0 = prob->g[(f*prob->Nf + g)*4+0];} 1237 if (g1) {PetscValidPointer(g1, 5); *g1 = prob->g[(f*prob->Nf + g)*4+1];} 1238 if (g2) {PetscValidPointer(g2, 6); *g2 = prob->g[(f*prob->Nf + g)*4+2];} 1239 if (g3) {PetscValidPointer(g3, 7); *g3 = prob->g[(f*prob->Nf + g)*4+3];} 1240 PetscFunctionReturn(0); 1241 } 1242 1243 #undef __FUNCT__ 1244 #define __FUNCT__ "PetscDSSetJacobian" 1245 /*@C 1246 PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields 1247 1248 Not collective 1249 1250 Input Parameters: 1251 + prob - The PetscDS 1252 . f - The test field number 1253 . g - The field number 1254 . g0 - integrand for the test and basis function term 1255 . g1 - integrand for the test function and basis function gradient term 1256 . g2 - integrand for the test function gradient and basis function term 1257 - g3 - integrand for the test function gradient and basis function gradient term 1258 1259 Note: We are using a first order FEM model for the weak form: 1260 1261 \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi 1262 1263 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 1264 1265 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1266 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1267 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1268 $ PetscReal t, const PetscReal x[], PetscScalar g0[]) 1269 1270 + dim - the spatial dimension 1271 . Nf - the number of fields 1272 . uOff - the offset into u[] and u_t[] for each field 1273 . uOff_x - the offset into u_x[] for each field 1274 . u - each field evaluated at the current point 1275 . u_t - the time derivative of each field evaluated at the current point 1276 . u_x - the gradient of each field evaluated at the current point 1277 . aOff - the offset into a[] and a_t[] for each auxiliary field 1278 . aOff_x - the offset into a_x[] for each auxiliary field 1279 . a - each auxiliary field evaluated at the current point 1280 . a_t - the time derivative of each auxiliary field evaluated at the current point 1281 . a_x - the gradient of auxiliary each field evaluated at the current point 1282 . t - current time 1283 . u_tShift - the multiplier a for dF/dU_t 1284 . x - coordinates of the current point 1285 - g0 - output values at the current point 1286 1287 Level: intermediate 1288 1289 .seealso: PetscDSGetJacobian() 1290 @*/ 1291 PetscErrorCode PetscDSSetJacobian(PetscDS prob, PetscInt f, PetscInt g, 1292 void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1293 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1294 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1295 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g0[]), 1296 void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1297 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1298 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1299 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g1[]), 1300 void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1301 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1302 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1303 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g2[]), 1304 void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1305 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1306 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1307 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g3[])) 1308 { 1309 PetscErrorCode ierr; 1310 1311 PetscFunctionBegin; 1312 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1313 if (g0) PetscValidFunction(g0, 4); 1314 if (g1) PetscValidFunction(g1, 5); 1315 if (g2) PetscValidFunction(g2, 6); 1316 if (g3) PetscValidFunction(g3, 7); 1317 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 1318 if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g); 1319 ierr = PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);CHKERRQ(ierr); 1320 prob->g[(f*prob->Nf + g)*4+0] = g0; 1321 prob->g[(f*prob->Nf + g)*4+1] = g1; 1322 prob->g[(f*prob->Nf + g)*4+2] = g2; 1323 prob->g[(f*prob->Nf + g)*4+3] = g3; 1324 PetscFunctionReturn(0); 1325 } 1326 1327 #undef __FUNCT__ 1328 #define __FUNCT__ "PetscDSHasJacobianPreconditioner" 1329 /*@C 1330 PetscDSHasJacobianPreconditioner - Signals that a Jacobian preconditioner matrix has been set 1331 1332 Not collective 1333 1334 Input Parameter: 1335 . prob - The PetscDS 1336 1337 Output Parameter: 1338 . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set 1339 1340 Level: intermediate 1341 1342 .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian() 1343 @*/ 1344 PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS prob, PetscBool *hasJacPre) 1345 { 1346 PetscInt f, g, h; 1347 1348 PetscFunctionBegin; 1349 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1350 *hasJacPre = PETSC_FALSE; 1351 for (f = 0; f < prob->Nf; ++f) { 1352 for (g = 0; g < prob->Nf; ++g) { 1353 for (h = 0; h < 4; ++h) { 1354 if (prob->gp[(f*prob->Nf + g)*4+h]) *hasJacPre = PETSC_TRUE; 1355 } 1356 } 1357 } 1358 PetscFunctionReturn(0); 1359 } 1360 1361 #undef __FUNCT__ 1362 #define __FUNCT__ "PetscDSGetJacobianPreconditioner" 1363 /*@C 1364 PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian preconditioner function for given test and basis field. If this is missing, the system matrix is used to build the preconditioner. 1365 1366 Not collective 1367 1368 Input Parameters: 1369 + prob - The PetscDS 1370 . f - The test field number 1371 - g - The field number 1372 1373 Output Parameters: 1374 + g0 - integrand for the test and basis function term 1375 . g1 - integrand for the test function and basis function gradient term 1376 . g2 - integrand for the test function gradient and basis function term 1377 - g3 - integrand for the test function gradient and basis function gradient term 1378 1379 Note: We are using a first order FEM model for the weak form: 1380 1381 \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi 1382 1383 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 1384 1385 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1386 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1387 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1388 $ PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[]) 1389 1390 + dim - the spatial dimension 1391 . Nf - the number of fields 1392 . uOff - the offset into u[] and u_t[] for each field 1393 . uOff_x - the offset into u_x[] for each field 1394 . u - each field evaluated at the current point 1395 . u_t - the time derivative of each field evaluated at the current point 1396 . u_x - the gradient of each field evaluated at the current point 1397 . aOff - the offset into a[] and a_t[] for each auxiliary field 1398 . aOff_x - the offset into a_x[] for each auxiliary field 1399 . a - each auxiliary field evaluated at the current point 1400 . a_t - the time derivative of each auxiliary field evaluated at the current point 1401 . a_x - the gradient of auxiliary each field evaluated at the current point 1402 . t - current time 1403 . u_tShift - the multiplier a for dF/dU_t 1404 . x - coordinates of the current point 1405 - g0 - output values at the current point 1406 1407 Level: intermediate 1408 1409 .seealso: PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian() 1410 @*/ 1411 PetscErrorCode PetscDSGetJacobianPreconditioner(PetscDS prob, PetscInt f, PetscInt g, 1412 void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1413 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1414 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1415 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g0[]), 1416 void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1417 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1418 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1419 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g1[]), 1420 void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1421 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1422 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1423 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g2[]), 1424 void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1425 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1426 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1427 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g3[])) 1428 { 1429 PetscFunctionBegin; 1430 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1431 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 1432 if ((g < 0) || (g >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, prob->Nf); 1433 if (g0) {PetscValidPointer(g0, 4); *g0 = prob->gp[(f*prob->Nf + g)*4+0];} 1434 if (g1) {PetscValidPointer(g1, 5); *g1 = prob->gp[(f*prob->Nf + g)*4+1];} 1435 if (g2) {PetscValidPointer(g2, 6); *g2 = prob->gp[(f*prob->Nf + g)*4+2];} 1436 if (g3) {PetscValidPointer(g3, 7); *g3 = prob->gp[(f*prob->Nf + g)*4+3];} 1437 PetscFunctionReturn(0); 1438 } 1439 1440 #undef __FUNCT__ 1441 #define __FUNCT__ "PetscDSSetJacobianPreconditioner" 1442 /*@C 1443 PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian preconditioner function for given test and basis fields. If this is missing, the system matrix is used to build the preconditioner. 1444 1445 Not collective 1446 1447 Input Parameters: 1448 + prob - The PetscDS 1449 . f - The test field number 1450 . g - The field number 1451 . g0 - integrand for the test and basis function term 1452 . g1 - integrand for the test function and basis function gradient term 1453 . g2 - integrand for the test function gradient and basis function term 1454 - g3 - integrand for the test function gradient and basis function gradient term 1455 1456 Note: We are using a first order FEM model for the weak form: 1457 1458 \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi 1459 1460 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 1461 1462 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1463 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1464 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1465 $ PetscReal t, const PetscReal x[], PetscScalar g0[]) 1466 1467 + dim - the spatial dimension 1468 . Nf - the number of fields 1469 . uOff - the offset into u[] and u_t[] for each field 1470 . uOff_x - the offset into u_x[] for each field 1471 . u - each field evaluated at the current point 1472 . u_t - the time derivative of each field evaluated at the current point 1473 . u_x - the gradient of each field evaluated at the current point 1474 . aOff - the offset into a[] and a_t[] for each auxiliary field 1475 . aOff_x - the offset into a_x[] for each auxiliary field 1476 . a - each auxiliary field evaluated at the current point 1477 . a_t - the time derivative of each auxiliary field evaluated at the current point 1478 . a_x - the gradient of auxiliary each field evaluated at the current point 1479 . t - current time 1480 . u_tShift - the multiplier a for dF/dU_t 1481 . x - coordinates of the current point 1482 - g0 - output values at the current point 1483 1484 Level: intermediate 1485 1486 .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobian() 1487 @*/ 1488 PetscErrorCode PetscDSSetJacobianPreconditioner(PetscDS prob, PetscInt f, PetscInt g, 1489 void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1490 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1491 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1492 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g0[]), 1493 void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1494 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1495 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1496 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g1[]), 1497 void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1498 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1499 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1500 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g2[]), 1501 void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1502 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1503 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1504 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g3[])) 1505 { 1506 PetscErrorCode ierr; 1507 1508 PetscFunctionBegin; 1509 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1510 if (g0) PetscValidFunction(g0, 4); 1511 if (g1) PetscValidFunction(g1, 5); 1512 if (g2) PetscValidFunction(g2, 6); 1513 if (g3) PetscValidFunction(g3, 7); 1514 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 1515 if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g); 1516 ierr = PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);CHKERRQ(ierr); 1517 prob->gp[(f*prob->Nf + g)*4+0] = g0; 1518 prob->gp[(f*prob->Nf + g)*4+1] = g1; 1519 prob->gp[(f*prob->Nf + g)*4+2] = g2; 1520 prob->gp[(f*prob->Nf + g)*4+3] = g3; 1521 PetscFunctionReturn(0); 1522 } 1523 1524 #undef __FUNCT__ 1525 #define __FUNCT__ "PetscDSHasDynamicJacobian" 1526 /*@C 1527 PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set 1528 1529 Not collective 1530 1531 Input Parameter: 1532 . prob - The PetscDS 1533 1534 Output Parameter: 1535 . hasDynJac - flag that pointwise function for dynamic Jacobian has been set 1536 1537 Level: intermediate 1538 1539 .seealso: PetscDSGetDynamicJacobian(), PetscDSSetDynamicJacobian(), PetscDSGetJacobian() 1540 @*/ 1541 PetscErrorCode PetscDSHasDynamicJacobian(PetscDS prob, PetscBool *hasDynJac) 1542 { 1543 PetscInt f, g, h; 1544 1545 PetscFunctionBegin; 1546 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1547 *hasDynJac = PETSC_FALSE; 1548 for (f = 0; f < prob->Nf; ++f) { 1549 for (g = 0; g < prob->Nf; ++g) { 1550 for (h = 0; h < 4; ++h) { 1551 if (prob->gt[(f*prob->Nf + g)*4+h]) *hasDynJac = PETSC_TRUE; 1552 } 1553 } 1554 } 1555 PetscFunctionReturn(0); 1556 } 1557 1558 #undef __FUNCT__ 1559 #define __FUNCT__ "PetscDSGetDynamicJacobian" 1560 /*@C 1561 PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field 1562 1563 Not collective 1564 1565 Input Parameters: 1566 + prob - The PetscDS 1567 . f - The test field number 1568 - g - The field number 1569 1570 Output Parameters: 1571 + g0 - integrand for the test and basis function term 1572 . g1 - integrand for the test function and basis function gradient term 1573 . g2 - integrand for the test function gradient and basis function term 1574 - g3 - integrand for the test function gradient and basis function gradient term 1575 1576 Note: We are using a first order FEM model for the weak form: 1577 1578 \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi 1579 1580 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 1581 1582 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1583 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1584 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1585 $ PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[]) 1586 1587 + dim - the spatial dimension 1588 . Nf - the number of fields 1589 . uOff - the offset into u[] and u_t[] for each field 1590 . uOff_x - the offset into u_x[] for each field 1591 . u - each field evaluated at the current point 1592 . u_t - the time derivative of each field evaluated at the current point 1593 . u_x - the gradient of each field evaluated at the current point 1594 . aOff - the offset into a[] and a_t[] for each auxiliary field 1595 . aOff_x - the offset into a_x[] for each auxiliary field 1596 . a - each auxiliary field evaluated at the current point 1597 . a_t - the time derivative of each auxiliary field evaluated at the current point 1598 . a_x - the gradient of auxiliary each field evaluated at the current point 1599 . t - current time 1600 . u_tShift - the multiplier a for dF/dU_t 1601 . x - coordinates of the current point 1602 - g0 - output values at the current point 1603 1604 Level: intermediate 1605 1606 .seealso: PetscDSSetJacobian() 1607 @*/ 1608 PetscErrorCode PetscDSGetDynamicJacobian(PetscDS prob, PetscInt f, PetscInt g, 1609 void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1610 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1611 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1612 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g0[]), 1613 void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1614 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1615 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1616 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g1[]), 1617 void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1618 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1619 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1620 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g2[]), 1621 void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1622 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1623 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1624 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g3[])) 1625 { 1626 PetscFunctionBegin; 1627 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1628 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 1629 if ((g < 0) || (g >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, prob->Nf); 1630 if (g0) {PetscValidPointer(g0, 4); *g0 = prob->gt[(f*prob->Nf + g)*4+0];} 1631 if (g1) {PetscValidPointer(g1, 5); *g1 = prob->gt[(f*prob->Nf + g)*4+1];} 1632 if (g2) {PetscValidPointer(g2, 6); *g2 = prob->gt[(f*prob->Nf + g)*4+2];} 1633 if (g3) {PetscValidPointer(g3, 7); *g3 = prob->gt[(f*prob->Nf + g)*4+3];} 1634 PetscFunctionReturn(0); 1635 } 1636 1637 #undef __FUNCT__ 1638 #define __FUNCT__ "PetscDSSetDynamicJacobian" 1639 /*@C 1640 PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields 1641 1642 Not collective 1643 1644 Input Parameters: 1645 + prob - The PetscDS 1646 . f - The test field number 1647 . g - The field number 1648 . g0 - integrand for the test and basis function term 1649 . g1 - integrand for the test function and basis function gradient term 1650 . g2 - integrand for the test function gradient and basis function term 1651 - g3 - integrand for the test function gradient and basis function gradient term 1652 1653 Note: We are using a first order FEM model for the weak form: 1654 1655 \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi 1656 1657 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 1658 1659 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1660 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1661 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1662 $ PetscReal t, const PetscReal x[], PetscScalar g0[]) 1663 1664 + dim - the spatial dimension 1665 . Nf - the number of fields 1666 . uOff - the offset into u[] and u_t[] for each field 1667 . uOff_x - the offset into u_x[] for each field 1668 . u - each field evaluated at the current point 1669 . u_t - the time derivative of each field evaluated at the current point 1670 . u_x - the gradient of each field evaluated at the current point 1671 . aOff - the offset into a[] and a_t[] for each auxiliary field 1672 . aOff_x - the offset into a_x[] for each auxiliary field 1673 . a - each auxiliary field evaluated at the current point 1674 . a_t - the time derivative of each auxiliary field evaluated at the current point 1675 . a_x - the gradient of auxiliary each field evaluated at the current point 1676 . t - current time 1677 . u_tShift - the multiplier a for dF/dU_t 1678 . x - coordinates of the current point 1679 - g0 - output values at the current point 1680 1681 Level: intermediate 1682 1683 .seealso: PetscDSGetJacobian() 1684 @*/ 1685 PetscErrorCode PetscDSSetDynamicJacobian(PetscDS prob, PetscInt f, PetscInt g, 1686 void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1687 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1688 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1689 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g0[]), 1690 void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1691 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1692 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1693 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g1[]), 1694 void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1695 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1696 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1697 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g2[]), 1698 void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1699 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1700 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1701 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g3[])) 1702 { 1703 PetscErrorCode ierr; 1704 1705 PetscFunctionBegin; 1706 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1707 if (g0) PetscValidFunction(g0, 4); 1708 if (g1) PetscValidFunction(g1, 5); 1709 if (g2) PetscValidFunction(g2, 6); 1710 if (g3) PetscValidFunction(g3, 7); 1711 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 1712 if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g); 1713 ierr = PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);CHKERRQ(ierr); 1714 prob->gt[(f*prob->Nf + g)*4+0] = g0; 1715 prob->gt[(f*prob->Nf + g)*4+1] = g1; 1716 prob->gt[(f*prob->Nf + g)*4+2] = g2; 1717 prob->gt[(f*prob->Nf + g)*4+3] = g3; 1718 PetscFunctionReturn(0); 1719 } 1720 1721 #undef __FUNCT__ 1722 #define __FUNCT__ "PetscDSGetRiemannSolver" 1723 /*@C 1724 PetscDSGetRiemannSolver - Returns the Riemann solver for the given field 1725 1726 Not collective 1727 1728 Input Arguments: 1729 + prob - The PetscDS object 1730 - f - The field number 1731 1732 Output Argument: 1733 . r - Riemann solver 1734 1735 Calling sequence for r: 1736 1737 $ r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx) 1738 1739 + dim - The spatial dimension 1740 . Nf - The number of fields 1741 . x - The coordinates at a point on the interface 1742 . n - The normal vector to the interface 1743 . uL - The state vector to the left of the interface 1744 . uR - The state vector to the right of the interface 1745 . flux - output array of flux through the interface 1746 - ctx - optional user context 1747 1748 Level: intermediate 1749 1750 .seealso: PetscDSSetRiemannSolver() 1751 @*/ 1752 PetscErrorCode PetscDSGetRiemannSolver(PetscDS prob, PetscInt f, 1753 void (**r)(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)) 1754 { 1755 PetscFunctionBegin; 1756 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1757 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 1758 PetscValidPointer(r, 3); 1759 *r = prob->r[f]; 1760 PetscFunctionReturn(0); 1761 } 1762 1763 #undef __FUNCT__ 1764 #define __FUNCT__ "PetscDSSetRiemannSolver" 1765 /*@C 1766 PetscDSSetRiemannSolver - Sets the Riemann solver for the given field 1767 1768 Not collective 1769 1770 Input Arguments: 1771 + prob - The PetscDS object 1772 . f - The field number 1773 - r - Riemann solver 1774 1775 Calling sequence for r: 1776 1777 $ r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx) 1778 1779 + dim - The spatial dimension 1780 . Nf - The number of fields 1781 . x - The coordinates at a point on the interface 1782 . n - The normal vector to the interface 1783 . uL - The state vector to the left of the interface 1784 . uR - The state vector to the right of the interface 1785 . flux - output array of flux through the interface 1786 - ctx - optional user context 1787 1788 Level: intermediate 1789 1790 .seealso: PetscDSGetRiemannSolver() 1791 @*/ 1792 PetscErrorCode PetscDSSetRiemannSolver(PetscDS prob, PetscInt f, 1793 void (*r)(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)) 1794 { 1795 PetscErrorCode ierr; 1796 1797 PetscFunctionBegin; 1798 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1799 if (r) PetscValidFunction(r, 3); 1800 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 1801 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr); 1802 prob->r[f] = r; 1803 PetscFunctionReturn(0); 1804 } 1805 1806 #undef __FUNCT__ 1807 #define __FUNCT__ "PetscDSGetContext" 1808 PetscErrorCode PetscDSGetContext(PetscDS prob, PetscInt f, void **ctx) 1809 { 1810 PetscFunctionBegin; 1811 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1812 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 1813 PetscValidPointer(ctx, 3); 1814 *ctx = prob->ctx[f]; 1815 PetscFunctionReturn(0); 1816 } 1817 1818 #undef __FUNCT__ 1819 #define __FUNCT__ "PetscDSSetContext" 1820 PetscErrorCode PetscDSSetContext(PetscDS prob, PetscInt f, void *ctx) 1821 { 1822 PetscErrorCode ierr; 1823 1824 PetscFunctionBegin; 1825 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1826 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 1827 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr); 1828 prob->ctx[f] = ctx; 1829 PetscFunctionReturn(0); 1830 } 1831 1832 #undef __FUNCT__ 1833 #define __FUNCT__ "PetscDSGetBdResidual" 1834 /*@C 1835 PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field 1836 1837 Not collective 1838 1839 Input Parameters: 1840 + prob - The PetscDS 1841 - f - The test field number 1842 1843 Output Parameters: 1844 + f0 - boundary integrand for the test function term 1845 - f1 - boundary integrand for the test function gradient term 1846 1847 Note: We are using a first order FEM model for the weak form: 1848 1849 \int_\Gamma \phi {\vec f}_0(u, u_t, \nabla u, x, t) \cdot \hat n + \nabla\phi \cdot {\overleftrightarrow f}_1(u, u_t, \nabla u, x, t) \cdot \hat n 1850 1851 The calling sequence for the callbacks f0 and f1 is given by: 1852 1853 $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1854 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1855 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1856 $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[]) 1857 1858 + dim - the spatial dimension 1859 . Nf - the number of fields 1860 . uOff - the offset into u[] and u_t[] for each field 1861 . uOff_x - the offset into u_x[] for each field 1862 . u - each field evaluated at the current point 1863 . u_t - the time derivative of each field evaluated at the current point 1864 . u_x - the gradient of each field evaluated at the current point 1865 . aOff - the offset into a[] and a_t[] for each auxiliary field 1866 . aOff_x - the offset into a_x[] for each auxiliary field 1867 . a - each auxiliary field evaluated at the current point 1868 . a_t - the time derivative of each auxiliary field evaluated at the current point 1869 . a_x - the gradient of auxiliary each field evaluated at the current point 1870 . t - current time 1871 . x - coordinates of the current point 1872 . n - unit normal at the current point 1873 - f0 - output values at the current point 1874 1875 Level: intermediate 1876 1877 .seealso: PetscDSSetBdResidual() 1878 @*/ 1879 PetscErrorCode PetscDSGetBdResidual(PetscDS prob, PetscInt f, 1880 void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1881 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1882 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1883 PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[]), 1884 void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1885 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1886 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1887 PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f1[])) 1888 { 1889 PetscFunctionBegin; 1890 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1891 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 1892 if (f0) {PetscValidPointer(f0, 3); *f0 = prob->fBd[f*2+0];} 1893 if (f1) {PetscValidPointer(f1, 4); *f1 = prob->fBd[f*2+1];} 1894 PetscFunctionReturn(0); 1895 } 1896 1897 #undef __FUNCT__ 1898 #define __FUNCT__ "PetscDSSetBdResidual" 1899 /*@C 1900 PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field 1901 1902 Not collective 1903 1904 Input Parameters: 1905 + prob - The PetscDS 1906 . f - The test field number 1907 . f0 - boundary integrand for the test function term 1908 - f1 - boundary integrand for the test function gradient term 1909 1910 Note: We are using a first order FEM model for the weak form: 1911 1912 \int_\Gamma \phi {\vec f}_0(u, u_t, \nabla u, x, t) \cdot \hat n + \nabla\phi \cdot {\overleftrightarrow f}_1(u, u_t, \nabla u, x, t) \cdot \hat n 1913 1914 The calling sequence for the callbacks f0 and f1 is given by: 1915 1916 $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1917 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1918 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1919 $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[]) 1920 1921 + dim - the spatial dimension 1922 . Nf - the number of fields 1923 . uOff - the offset into u[] and u_t[] for each field 1924 . uOff_x - the offset into u_x[] for each field 1925 . u - each field evaluated at the current point 1926 . u_t - the time derivative of each field evaluated at the current point 1927 . u_x - the gradient of each field evaluated at the current point 1928 . aOff - the offset into a[] and a_t[] for each auxiliary field 1929 . aOff_x - the offset into a_x[] for each auxiliary field 1930 . a - each auxiliary field evaluated at the current point 1931 . a_t - the time derivative of each auxiliary field evaluated at the current point 1932 . a_x - the gradient of auxiliary each field evaluated at the current point 1933 . t - current time 1934 . x - coordinates of the current point 1935 . n - unit normal at the current point 1936 - f0 - output values at the current point 1937 1938 Level: intermediate 1939 1940 .seealso: PetscDSGetBdResidual() 1941 @*/ 1942 PetscErrorCode PetscDSSetBdResidual(PetscDS prob, PetscInt f, 1943 void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1944 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1945 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1946 PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[]), 1947 void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1948 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1949 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1950 PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f1[])) 1951 { 1952 PetscErrorCode ierr; 1953 1954 PetscFunctionBegin; 1955 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1956 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 1957 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr); 1958 if (f0) {PetscValidFunction(f0, 3); prob->fBd[f*2+0] = f0;} 1959 if (f1) {PetscValidFunction(f1, 4); prob->fBd[f*2+1] = f1;} 1960 PetscFunctionReturn(0); 1961 } 1962 1963 #undef __FUNCT__ 1964 #define __FUNCT__ "PetscDSGetBdJacobian" 1965 /*@C 1966 PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field 1967 1968 Not collective 1969 1970 Input Parameters: 1971 + prob - The PetscDS 1972 . f - The test field number 1973 - g - The field number 1974 1975 Output Parameters: 1976 + g0 - integrand for the test and basis function term 1977 . g1 - integrand for the test function and basis function gradient term 1978 . g2 - integrand for the test function gradient and basis function term 1979 - g3 - integrand for the test function gradient and basis function gradient term 1980 1981 Note: We are using a first order FEM model for the weak form: 1982 1983 \int_\Gamma \phi {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi 1984 1985 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 1986 1987 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1988 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1989 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1990 $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[]) 1991 1992 + dim - the spatial dimension 1993 . Nf - the number of fields 1994 . uOff - the offset into u[] and u_t[] for each field 1995 . uOff_x - the offset into u_x[] for each field 1996 . u - each field evaluated at the current point 1997 . u_t - the time derivative of each field evaluated at the current point 1998 . u_x - the gradient of each field evaluated at the current point 1999 . aOff - the offset into a[] and a_t[] for each auxiliary field 2000 . aOff_x - the offset into a_x[] for each auxiliary field 2001 . a - each auxiliary field evaluated at the current point 2002 . a_t - the time derivative of each auxiliary field evaluated at the current point 2003 . a_x - the gradient of auxiliary each field evaluated at the current point 2004 . t - current time 2005 . u_tShift - the multiplier a for dF/dU_t 2006 . x - coordinates of the current point 2007 . n - normal at the current point 2008 - g0 - output values at the current point 2009 2010 Level: intermediate 2011 2012 .seealso: PetscDSSetBdJacobian() 2013 @*/ 2014 PetscErrorCode PetscDSGetBdJacobian(PetscDS prob, PetscInt f, PetscInt g, 2015 void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2016 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2017 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2018 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscScalar g0[]), 2019 void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2020 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2021 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2022 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscScalar g1[]), 2023 void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2024 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2025 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2026 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscScalar g2[]), 2027 void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2028 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2029 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2030 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscScalar g3[])) 2031 { 2032 PetscFunctionBegin; 2033 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2034 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 2035 if ((g < 0) || (g >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, prob->Nf); 2036 if (g0) {PetscValidPointer(g0, 4); *g0 = prob->gBd[(f*prob->Nf + g)*4+0];} 2037 if (g1) {PetscValidPointer(g1, 5); *g1 = prob->gBd[(f*prob->Nf + g)*4+1];} 2038 if (g2) {PetscValidPointer(g2, 6); *g2 = prob->gBd[(f*prob->Nf + g)*4+2];} 2039 if (g3) {PetscValidPointer(g3, 7); *g3 = prob->gBd[(f*prob->Nf + g)*4+3];} 2040 PetscFunctionReturn(0); 2041 } 2042 2043 #undef __FUNCT__ 2044 #define __FUNCT__ "PetscDSSetBdJacobian" 2045 /*@C 2046 PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field 2047 2048 Not collective 2049 2050 Input Parameters: 2051 + prob - The PetscDS 2052 . f - The test field number 2053 . g - The field number 2054 . g0 - integrand for the test and basis function term 2055 . g1 - integrand for the test function and basis function gradient term 2056 . g2 - integrand for the test function gradient and basis function term 2057 - g3 - integrand for the test function gradient and basis function gradient term 2058 2059 Note: We are using a first order FEM model for the weak form: 2060 2061 \int_\Gamma \phi {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi 2062 2063 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 2064 2065 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2066 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2067 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2068 $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[]) 2069 2070 + dim - the spatial dimension 2071 . Nf - the number of fields 2072 . uOff - the offset into u[] and u_t[] for each field 2073 . uOff_x - the offset into u_x[] for each field 2074 . u - each field evaluated at the current point 2075 . u_t - the time derivative of each field evaluated at the current point 2076 . u_x - the gradient of each field evaluated at the current point 2077 . aOff - the offset into a[] and a_t[] for each auxiliary field 2078 . aOff_x - the offset into a_x[] for each auxiliary field 2079 . a - each auxiliary field evaluated at the current point 2080 . a_t - the time derivative of each auxiliary field evaluated at the current point 2081 . a_x - the gradient of auxiliary each field evaluated at the current point 2082 . t - current time 2083 . u_tShift - the multiplier a for dF/dU_t 2084 . x - coordinates of the current point 2085 . n - normal at the current point 2086 - g0 - output values at the current point 2087 2088 Level: intermediate 2089 2090 .seealso: PetscDSGetBdJacobian() 2091 @*/ 2092 PetscErrorCode PetscDSSetBdJacobian(PetscDS prob, PetscInt f, PetscInt g, 2093 void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2094 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2095 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2096 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscScalar g0[]), 2097 void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2098 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2099 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2100 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscScalar g1[]), 2101 void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2102 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2103 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2104 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscScalar g2[]), 2105 void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2106 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2107 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2108 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscScalar g3[])) 2109 { 2110 PetscErrorCode ierr; 2111 2112 PetscFunctionBegin; 2113 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2114 if (g0) PetscValidFunction(g0, 4); 2115 if (g1) PetscValidFunction(g1, 5); 2116 if (g2) PetscValidFunction(g2, 6); 2117 if (g3) PetscValidFunction(g3, 7); 2118 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 2119 if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g); 2120 ierr = PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);CHKERRQ(ierr); 2121 prob->gBd[(f*prob->Nf + g)*4+0] = g0; 2122 prob->gBd[(f*prob->Nf + g)*4+1] = g1; 2123 prob->gBd[(f*prob->Nf + g)*4+2] = g2; 2124 prob->gBd[(f*prob->Nf + g)*4+3] = g3; 2125 PetscFunctionReturn(0); 2126 } 2127 2128 #undef __FUNCT__ 2129 #define __FUNCT__ "PetscDSGetFieldIndex" 2130 /*@ 2131 PetscDSGetFieldIndex - Returns the index of the given field 2132 2133 Not collective 2134 2135 Input Parameters: 2136 + prob - The PetscDS object 2137 - disc - The discretization object 2138 2139 Output Parameter: 2140 . f - The field number 2141 2142 Level: beginner 2143 2144 .seealso: PetscGetDiscretization(), PetscDSGetBdFieldOffset(), PetscDSGetNumFields(), PetscDSCreate() 2145 @*/ 2146 PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f) 2147 { 2148 PetscInt g; 2149 2150 PetscFunctionBegin; 2151 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2152 PetscValidPointer(f, 3); 2153 *f = -1; 2154 for (g = 0; g < prob->Nf; ++g) {if (disc == prob->disc[g]) break;} 2155 if (g == prob->Nf) SETERRQ(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS."); 2156 *f = g; 2157 PetscFunctionReturn(0); 2158 } 2159 2160 #undef __FUNCT__ 2161 #define __FUNCT__ "PetscDSGetFieldSize" 2162 /*@ 2163 PetscDSGetFieldSize - Returns the size of the given field in the full space basis 2164 2165 Not collective 2166 2167 Input Parameters: 2168 + prob - The PetscDS object 2169 - f - The field number 2170 2171 Output Parameter: 2172 . size - The size 2173 2174 Level: beginner 2175 2176 .seealso: PetscDSGetFieldOffset(), PetscDSGetBdFieldOffset(), PetscDSGetNumFields(), PetscDSCreate() 2177 @*/ 2178 PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size) 2179 { 2180 PetscInt Nb, Nc; 2181 PetscErrorCode ierr; 2182 2183 PetscFunctionBegin; 2184 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2185 PetscValidPointer(size, 3); 2186 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 2187 *size = prob->Nc[f] * prob->Nb[f]; 2188 PetscFunctionReturn(0); 2189 } 2190 2191 #undef __FUNCT__ 2192 #define __FUNCT__ "PetscDSGetFieldOffset" 2193 /*@ 2194 PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis 2195 2196 Not collective 2197 2198 Input Parameters: 2199 + prob - The PetscDS object 2200 - f - The field number 2201 2202 Output Parameter: 2203 . off - The offset 2204 2205 Level: beginner 2206 2207 .seealso: PetscDSGetFieldSize(), PetscDSGetBdFieldOffset(), PetscDSGetNumFields(), PetscDSCreate() 2208 @*/ 2209 PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off) 2210 { 2211 PetscInt size, g; 2212 PetscErrorCode ierr; 2213 2214 PetscFunctionBegin; 2215 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2216 PetscValidPointer(off, 3); 2217 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 2218 *off = 0; 2219 for (g = 0; g < f; ++g) { 2220 ierr = PetscDSGetFieldSize(prob, g, &size);CHKERRQ(ierr); 2221 *off += size; 2222 } 2223 PetscFunctionReturn(0); 2224 } 2225 2226 #undef __FUNCT__ 2227 #define __FUNCT__ "PetscDSGetBdFieldOffset" 2228 /*@ 2229 PetscDSGetBdFieldOffset - Returns the offset of the given field in the full space boundary basis 2230 2231 Not collective 2232 2233 Input Parameters: 2234 + prob - The PetscDS object 2235 - f - The field number 2236 2237 Output Parameter: 2238 . off - The boundary offset 2239 2240 Level: beginner 2241 2242 .seealso: PetscDSGetFieldOffset(), PetscDSGetNumFields(), PetscDSCreate() 2243 @*/ 2244 PetscErrorCode PetscDSGetBdFieldOffset(PetscDS prob, PetscInt f, PetscInt *off) 2245 { 2246 PetscInt g; 2247 PetscErrorCode ierr; 2248 2249 PetscFunctionBegin; 2250 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2251 PetscValidPointer(off, 3); 2252 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 2253 *off = 0; 2254 for (g = 0; g < f; ++g) { 2255 PetscFE fe = (PetscFE) prob->discBd[g]; 2256 PetscInt Nb, Nc; 2257 2258 ierr = PetscFEGetDimension(fe, &Nb);CHKERRQ(ierr); 2259 ierr = PetscFEGetNumComponents(fe, &Nc);CHKERRQ(ierr); 2260 *off += Nb*Nc; 2261 } 2262 PetscFunctionReturn(0); 2263 } 2264 2265 #undef __FUNCT__ 2266 #define __FUNCT__ "PetscDSGetDimensions" 2267 /*@ 2268 PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point 2269 2270 Not collective 2271 2272 Input Parameter: 2273 . prob - The PetscDS object 2274 2275 Output Parameter: 2276 . dimensions - The number of dimensions 2277 2278 Level: beginner 2279 2280 .seealso: PetscDSGetComponentOffsets(), PetscDSGetNumFields(), PetscDSCreate() 2281 @*/ 2282 PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[]) 2283 { 2284 PetscErrorCode ierr; 2285 2286 PetscFunctionBegin; 2287 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2288 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 2289 PetscValidPointer(dimensions, 2); 2290 *dimensions = prob->Nb; 2291 PetscFunctionReturn(0); 2292 } 2293 2294 #undef __FUNCT__ 2295 #define __FUNCT__ "PetscDSGetComponents" 2296 /*@ 2297 PetscDSGetComponents - Returns the number of components for each field on an evaluation point 2298 2299 Not collective 2300 2301 Input Parameter: 2302 . prob - The PetscDS object 2303 2304 Output Parameter: 2305 . components - The number of components 2306 2307 Level: beginner 2308 2309 .seealso: PetscDSGetComponentOffsets(), PetscDSGetNumFields(), PetscDSCreate() 2310 @*/ 2311 PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[]) 2312 { 2313 PetscErrorCode ierr; 2314 2315 PetscFunctionBegin; 2316 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2317 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 2318 PetscValidPointer(components, 2); 2319 *components = prob->Nc; 2320 PetscFunctionReturn(0); 2321 } 2322 2323 #undef __FUNCT__ 2324 #define __FUNCT__ "PetscDSGetComponentOffset" 2325 /*@ 2326 PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point 2327 2328 Not collective 2329 2330 Input Parameters: 2331 + prob - The PetscDS object 2332 - f - The field number 2333 2334 Output Parameter: 2335 . off - The offset 2336 2337 Level: beginner 2338 2339 .seealso: PetscDSGetBdFieldOffset(), PetscDSGetNumFields(), PetscDSCreate() 2340 @*/ 2341 PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off) 2342 { 2343 PetscInt g; 2344 PetscErrorCode ierr; 2345 2346 PetscFunctionBegin; 2347 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2348 PetscValidPointer(off, 3); 2349 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf); 2350 *off = prob->off[f]; 2351 PetscFunctionReturn(0); 2352 } 2353 2354 #undef __FUNCT__ 2355 #define __FUNCT__ "PetscDSGetComponentOffsets" 2356 /*@ 2357 PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point 2358 2359 Not collective 2360 2361 Input Parameter: 2362 . prob - The PetscDS object 2363 2364 Output Parameter: 2365 . offsets - The offsets 2366 2367 Level: beginner 2368 2369 .seealso: PetscDSGetBdFieldOffset(), PetscDSGetNumFields(), PetscDSCreate() 2370 @*/ 2371 PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[]) 2372 { 2373 PetscFunctionBegin; 2374 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2375 PetscValidPointer(offsets, 2); 2376 *offsets = prob->off; 2377 PetscFunctionReturn(0); 2378 } 2379 2380 #undef __FUNCT__ 2381 #define __FUNCT__ "PetscDSGetComponentDerivativeOffsets" 2382 /*@ 2383 PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point 2384 2385 Not collective 2386 2387 Input Parameter: 2388 . prob - The PetscDS object 2389 2390 Output Parameter: 2391 . offsets - The offsets 2392 2393 Level: beginner 2394 2395 .seealso: PetscDSGetBdFieldOffset(), PetscDSGetNumFields(), PetscDSCreate() 2396 @*/ 2397 PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[]) 2398 { 2399 PetscFunctionBegin; 2400 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2401 PetscValidPointer(offsets, 2); 2402 *offsets = prob->offDer; 2403 PetscFunctionReturn(0); 2404 } 2405 2406 #undef __FUNCT__ 2407 #define __FUNCT__ "PetscDSGetComponentBdOffsets" 2408 /*@ 2409 PetscDSGetComponentBdOffsets - Returns the offset of each field on a boundary evaluation point 2410 2411 Not collective 2412 2413 Input Parameter: 2414 . prob - The PetscDS object 2415 2416 Output Parameter: 2417 . offsets - The offsets 2418 2419 Level: beginner 2420 2421 .seealso: PetscDSGetBdFieldOffset(), PetscDSGetNumFields(), PetscDSCreate() 2422 @*/ 2423 PetscErrorCode PetscDSGetComponentBdOffsets(PetscDS prob, PetscInt *offsets[]) 2424 { 2425 PetscFunctionBegin; 2426 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2427 PetscValidPointer(offsets, 2); 2428 *offsets = prob->offBd; 2429 PetscFunctionReturn(0); 2430 } 2431 2432 #undef __FUNCT__ 2433 #define __FUNCT__ "PetscDSGetComponentBdDerivativeOffsets" 2434 /*@ 2435 PetscDSGetComponentBdDerivativeOffsets - Returns the offset of each field derivative on a boundary evaluation point 2436 2437 Not collective 2438 2439 Input Parameter: 2440 . prob - The PetscDS object 2441 2442 Output Parameter: 2443 . offsets - The offsets 2444 2445 Level: beginner 2446 2447 .seealso: PetscDSGetBdFieldOffset(), PetscDSGetNumFields(), PetscDSCreate() 2448 @*/ 2449 PetscErrorCode PetscDSGetComponentBdDerivativeOffsets(PetscDS prob, PetscInt *offsets[]) 2450 { 2451 PetscFunctionBegin; 2452 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2453 PetscValidPointer(offsets, 2); 2454 *offsets = prob->offDerBd; 2455 PetscFunctionReturn(0); 2456 } 2457 2458 #undef __FUNCT__ 2459 #define __FUNCT__ "PetscDSGetTabulation" 2460 /*@C 2461 PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization 2462 2463 Not collective 2464 2465 Input Parameter: 2466 . prob - The PetscDS object 2467 2468 Output Parameters: 2469 + basis - The basis function tabulation at quadrature points 2470 - basisDer - The basis function derivative tabulation at quadrature points 2471 2472 Level: intermediate 2473 2474 .seealso: PetscDSGetBdTabulation(), PetscDSCreate() 2475 @*/ 2476 PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscReal ***basis, PetscReal ***basisDer) 2477 { 2478 PetscErrorCode ierr; 2479 2480 PetscFunctionBegin; 2481 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2482 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 2483 if (basis) {PetscValidPointer(basis, 2); *basis = prob->basis;} 2484 if (basisDer) {PetscValidPointer(basisDer, 3); *basisDer = prob->basisDer;} 2485 PetscFunctionReturn(0); 2486 } 2487 2488 #undef __FUNCT__ 2489 #define __FUNCT__ "PetscDSGetFaceTabulation" 2490 /*@C 2491 PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces 2492 2493 Not collective 2494 2495 Input Parameter: 2496 . prob - The PetscDS object 2497 2498 Output Parameters: 2499 + basisFace - The basis function tabulation at quadrature points 2500 - basisDerFace - The basis function derivative tabulation at quadrature points 2501 2502 Level: intermediate 2503 2504 .seealso: PetscDSGetTabulation(), PetscDSCreate() 2505 @*/ 2506 PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscReal ***basis, PetscReal ***basisDer) 2507 { 2508 PetscErrorCode ierr; 2509 2510 PetscFunctionBegin; 2511 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2512 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 2513 if (basis) {PetscValidPointer(basis, 2); *basis = prob->basisFace;} 2514 if (basisDer) {PetscValidPointer(basisDer, 3); *basisDer = prob->basisDerFace;} 2515 PetscFunctionReturn(0); 2516 } 2517 2518 2519 #undef __FUNCT__ 2520 #define __FUNCT__ "PetscDSGetBdTabulation" 2521 /*@C 2522 PetscDSGetBdTabulation - Return the basis tabulation at quadrature points for the boundary discretization 2523 2524 Not collective 2525 2526 Input Parameter: 2527 . prob - The PetscDS object 2528 2529 Output Parameters: 2530 + basis - The basis function tabulation at quadrature points 2531 - basisDer - The basis function derivative tabulation at quadrature points 2532 2533 Level: intermediate 2534 2535 .seealso: PetscDSGetTabulation(), PetscDSCreate() 2536 @*/ 2537 PetscErrorCode PetscDSGetBdTabulation(PetscDS prob, PetscReal ***basis, PetscReal ***basisDer) 2538 { 2539 PetscErrorCode ierr; 2540 2541 PetscFunctionBegin; 2542 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2543 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 2544 if (basis) {PetscValidPointer(basis, 2); *basis = prob->basisBd;} 2545 if (basisDer) {PetscValidPointer(basisDer, 3); *basisDer = prob->basisDerBd;} 2546 PetscFunctionReturn(0); 2547 } 2548 2549 #undef __FUNCT__ 2550 #define __FUNCT__ "PetscDSGetEvaluationArrays" 2551 PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x) 2552 { 2553 PetscErrorCode ierr; 2554 2555 PetscFunctionBegin; 2556 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2557 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 2558 if (u) {PetscValidPointer(u, 2); *u = prob->u;} 2559 if (u_t) {PetscValidPointer(u_t, 3); *u_t = prob->u_t;} 2560 if (u_x) {PetscValidPointer(u_x, 4); *u_x = prob->u_x;} 2561 PetscFunctionReturn(0); 2562 } 2563 2564 #undef __FUNCT__ 2565 #define __FUNCT__ "PetscDSGetWeakFormArrays" 2566 PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3) 2567 { 2568 PetscErrorCode ierr; 2569 2570 PetscFunctionBegin; 2571 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2572 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 2573 if (f0) {PetscValidPointer(f0, 2); *f0 = prob->f0;} 2574 if (f1) {PetscValidPointer(f1, 3); *f1 = prob->f1;} 2575 if (g0) {PetscValidPointer(g0, 4); *g0 = prob->g0;} 2576 if (g1) {PetscValidPointer(g1, 5); *g1 = prob->g1;} 2577 if (g2) {PetscValidPointer(g2, 6); *g2 = prob->g2;} 2578 if (g3) {PetscValidPointer(g3, 7); *g3 = prob->g3;} 2579 PetscFunctionReturn(0); 2580 } 2581 2582 #undef __FUNCT__ 2583 #define __FUNCT__ "PetscDSGetRefCoordArrays" 2584 PetscErrorCode PetscDSGetRefCoordArrays(PetscDS prob, PetscReal **x, PetscScalar **refSpaceDer) 2585 { 2586 PetscErrorCode ierr; 2587 2588 PetscFunctionBegin; 2589 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2590 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 2591 if (x) {PetscValidPointer(x, 2); *x = prob->x;} 2592 if (refSpaceDer) {PetscValidPointer(refSpaceDer, 3); *refSpaceDer = prob->refSpaceDer;} 2593 PetscFunctionReturn(0); 2594 } 2595 2596 #undef __FUNCT__ 2597 #define __FUNCT__ "PetscDSAddBoundary" 2598 /*@C 2599 PetscDSAddBoundary - Add a boundary condition to the model 2600 2601 Input Parameters: 2602 + ds - The PetscDS object 2603 . isEssential - Flag for an essential (Dirichlet) condition, as opposed to a natural (Neumann) condition 2604 . name - The BC name 2605 . labelname - The label defining constrained points 2606 . field - The field to constrain 2607 . numcomps - The number of constrained field components 2608 . comps - An array of constrained component numbers 2609 . bcFunc - A pointwise function giving boundary values 2610 . numids - The number of DMLabel ids for constrained points 2611 . ids - An array of ids for constrained points 2612 - ctx - An optional user context for bcFunc 2613 2614 Options Database Keys: 2615 + -bc_<boundary name> <num> - Overrides the boundary ids 2616 - -bc_<boundary name>_comp <num> - Overrides the boundary components 2617 2618 Level: developer 2619 2620 .seealso: PetscDSGetBoundary() 2621 @*/ 2622 PetscErrorCode PetscDSAddBoundary(PetscDS ds, PetscBool isEssential, const char name[], const char labelname[], PetscInt field, PetscInt numcomps, const PetscInt *comps, void (*bcFunc)(), PetscInt numids, const PetscInt *ids, void *ctx) 2623 { 2624 DSBoundary b; 2625 PetscErrorCode ierr; 2626 2627 PetscFunctionBegin; 2628 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 2629 ierr = PetscNew(&b);CHKERRQ(ierr); 2630 ierr = PetscStrallocpy(name, (char **) &b->name);CHKERRQ(ierr); 2631 ierr = PetscStrallocpy(labelname, (char **) &b->labelname);CHKERRQ(ierr); 2632 ierr = PetscMalloc1(numcomps, &b->comps);CHKERRQ(ierr); 2633 if (numcomps) {ierr = PetscMemcpy(b->comps, comps, numcomps*sizeof(PetscInt));CHKERRQ(ierr);} 2634 ierr = PetscMalloc1(numids, &b->ids);CHKERRQ(ierr); 2635 if (numids) {ierr = PetscMemcpy(b->ids, ids, numids*sizeof(PetscInt));CHKERRQ(ierr);} 2636 b->essential = isEssential; 2637 b->field = field; 2638 b->numcomps = numcomps; 2639 b->func = bcFunc; 2640 b->numids = numids; 2641 b->ctx = ctx; 2642 b->next = ds->boundary; 2643 ds->boundary = b; 2644 PetscFunctionReturn(0); 2645 } 2646 2647 #undef __FUNCT__ 2648 #define __FUNCT__ "PetscDSGetNumBoundary" 2649 /*@ 2650 PetscDSGetNumBoundary - Get the number of registered BC 2651 2652 Input Parameters: 2653 . ds - The PetscDS object 2654 2655 Output Parameters: 2656 . numBd - The number of BC 2657 2658 Level: intermediate 2659 2660 .seealso: PetscDSAddBoundary(), PetscDSGetBoundary() 2661 @*/ 2662 PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd) 2663 { 2664 DSBoundary b = ds->boundary; 2665 2666 PetscFunctionBegin; 2667 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 2668 PetscValidPointer(numBd, 2); 2669 *numBd = 0; 2670 while (b) {++(*numBd); b = b->next;} 2671 PetscFunctionReturn(0); 2672 } 2673 2674 #undef __FUNCT__ 2675 #define __FUNCT__ "PetscDSGetBoundary" 2676 /*@C 2677 PetscDSGetBoundary - Add a boundary condition to the model 2678 2679 Input Parameters: 2680 + ds - The PetscDS object 2681 - bd - The BC number 2682 2683 Output Parameters: 2684 + isEssential - Flag for an essential (Dirichlet) condition, as opposed to a natural (Neumann) condition 2685 . name - The BC name 2686 . labelname - The label defining constrained points 2687 . field - The field to constrain 2688 . numcomps - The number of constrained field components 2689 . comps - An array of constrained component numbers 2690 . bcFunc - A pointwise function giving boundary values 2691 . numids - The number of DMLabel ids for constrained points 2692 . ids - An array of ids for constrained points 2693 - ctx - An optional user context for bcFunc 2694 2695 Options Database Keys: 2696 + -bc_<boundary name> <num> - Overrides the boundary ids 2697 - -bc_<boundary name>_comp <num> - Overrides the boundary components 2698 2699 Level: developer 2700 2701 .seealso: PetscDSAddBoundary() 2702 @*/ 2703 PetscErrorCode PetscDSGetBoundary(PetscDS ds, PetscInt bd, PetscBool *isEssential, const char **name, const char **labelname, PetscInt *field, PetscInt *numcomps, const PetscInt **comps, void (**func)(), PetscInt *numids, const PetscInt **ids, void **ctx) 2704 { 2705 DSBoundary b = ds->boundary; 2706 PetscInt n = 0; 2707 2708 PetscFunctionBegin; 2709 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 2710 while (b) { 2711 if (n == bd) break; 2712 b = b->next; 2713 ++n; 2714 } 2715 if (!b) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %d is not in [0, %d)", bd, n); 2716 if (isEssential) { 2717 PetscValidPointer(isEssential, 3); 2718 *isEssential = b->essential; 2719 } 2720 if (name) { 2721 PetscValidPointer(name, 4); 2722 *name = b->name; 2723 } 2724 if (labelname) { 2725 PetscValidPointer(labelname, 5); 2726 *labelname = b->labelname; 2727 } 2728 if (field) { 2729 PetscValidPointer(field, 6); 2730 *field = b->field; 2731 } 2732 if (numcomps) { 2733 PetscValidPointer(numcomps, 7); 2734 *numcomps = b->numcomps; 2735 } 2736 if (comps) { 2737 PetscValidPointer(comps, 8); 2738 *comps = b->comps; 2739 } 2740 if (func) { 2741 PetscValidPointer(func, 9); 2742 *func = b->func; 2743 } 2744 if (numids) { 2745 PetscValidPointer(numids, 10); 2746 *numids = b->numids; 2747 } 2748 if (ids) { 2749 PetscValidPointer(ids, 11); 2750 *ids = b->ids; 2751 } 2752 if (ctx) { 2753 PetscValidPointer(ctx, 12); 2754 *ctx = b->ctx; 2755 } 2756 PetscFunctionReturn(0); 2757 } 2758 2759 #undef __FUNCT__ 2760 #define __FUNCT__ "PetscDSCopyBoundary" 2761 PetscErrorCode PetscDSCopyBoundary(PetscDS probA, PetscDS probB) 2762 { 2763 DSBoundary b, next, *lastnext; 2764 PetscErrorCode ierr; 2765 2766 PetscFunctionBegin; 2767 PetscValidHeaderSpecific(probA, PETSCDS_CLASSID, 1); 2768 PetscValidHeaderSpecific(probB, PETSCDS_CLASSID, 2); 2769 if (probA == probB) PetscFunctionReturn(0); 2770 next = probB->boundary; 2771 while (next) { 2772 DSBoundary b = next; 2773 2774 next = b->next; 2775 ierr = PetscFree(b->comps);CHKERRQ(ierr); 2776 ierr = PetscFree(b->ids);CHKERRQ(ierr); 2777 ierr = PetscFree(b->name);CHKERRQ(ierr); 2778 ierr = PetscFree(b->labelname);CHKERRQ(ierr); 2779 ierr = PetscFree(b);CHKERRQ(ierr); 2780 } 2781 lastnext = &(probB->boundary); 2782 for (b = probA->boundary; b; b = b->next) { 2783 DSBoundary bNew; 2784 2785 ierr = PetscNew(&bNew); 2786 bNew->numcomps = b->numcomps; 2787 ierr = PetscMalloc1(bNew->numcomps, &bNew->comps);CHKERRQ(ierr); 2788 ierr = PetscMemcpy(bNew->comps, b->comps, bNew->numcomps*sizeof(PetscInt));CHKERRQ(ierr); 2789 bNew->numids = b->numids; 2790 ierr = PetscMalloc1(bNew->numids, &bNew->ids);CHKERRQ(ierr); 2791 ierr = PetscMemcpy(bNew->ids, b->ids, bNew->numids*sizeof(PetscInt));CHKERRQ(ierr); 2792 ierr = PetscStrallocpy(b->labelname,(char **) &(bNew->labelname));CHKERRQ(ierr); 2793 ierr = PetscStrallocpy(b->name,(char **) &(bNew->name));CHKERRQ(ierr); 2794 bNew->ctx = b->ctx; 2795 bNew->essential = b->essential; 2796 bNew->field = b->field; 2797 bNew->func = b->func; 2798 2799 *lastnext = bNew; 2800 lastnext = &(bNew->next); 2801 } 2802 PetscFunctionReturn(0); 2803 } 2804 2805 #undef __FUNCT__ 2806 #define __FUNCT__ "PetscDSCopyEquations" 2807 /*@ 2808 PetscDSCopyEquations - Copy all pointwise function pointers to the new problem 2809 2810 Not collective 2811 2812 Input Parameter: 2813 . prob - The PetscDS object 2814 2815 Output Parameter: 2816 . newprob - The PetscDS copy 2817 2818 Level: intermediate 2819 2820 .seealso: PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate() 2821 @*/ 2822 PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob) 2823 { 2824 PetscInt Nf, Ng, f, g; 2825 PetscErrorCode ierr; 2826 2827 PetscFunctionBegin; 2828 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2829 PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2); 2830 ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 2831 ierr = PetscDSGetNumFields(newprob, &Ng);CHKERRQ(ierr); 2832 if (Nf != Ng) SETERRQ2(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %D != %D", Nf, Ng);CHKERRQ(ierr); 2833 for (f = 0; f < Nf; ++f) { 2834 PetscPointFunc obj; 2835 PetscPointFunc f0, f1; 2836 PetscPointJac g0, g1, g2, g3; 2837 PetscBdPointFunc f0Bd, f1Bd; 2838 PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd; 2839 PetscRiemannFunc r; 2840 2841 ierr = PetscDSGetObjective(prob, f, &obj);CHKERRQ(ierr); 2842 ierr = PetscDSGetResidual(prob, f, &f0, &f1);CHKERRQ(ierr); 2843 ierr = PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd);CHKERRQ(ierr); 2844 ierr = PetscDSGetRiemannSolver(prob, f, &r);CHKERRQ(ierr); 2845 ierr = PetscDSSetObjective(newprob, f, obj);CHKERRQ(ierr); 2846 ierr = PetscDSSetResidual(newprob, f, f0, f1);CHKERRQ(ierr); 2847 ierr = PetscDSSetBdResidual(newprob, f, f0Bd, f1Bd);CHKERRQ(ierr); 2848 ierr = PetscDSSetRiemannSolver(newprob, f, r);CHKERRQ(ierr); 2849 for (g = 0; g < Nf; ++g) { 2850 ierr = PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3);CHKERRQ(ierr); 2851 ierr = PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd);CHKERRQ(ierr); 2852 ierr = PetscDSSetJacobian(newprob, f, g, g0, g1, g2, g3);CHKERRQ(ierr); 2853 ierr = PetscDSSetBdJacobian(newprob, f, g, g0Bd, g1Bd, g2Bd, g3Bd);CHKERRQ(ierr); 2854 } 2855 } 2856 PetscFunctionReturn(0); 2857 } 2858 2859 #undef __FUNCT__ 2860 #define __FUNCT__ "PetscDSDestroy_Basic" 2861 static PetscErrorCode PetscDSDestroy_Basic(PetscDS prob) 2862 { 2863 PetscErrorCode ierr; 2864 2865 PetscFunctionBegin; 2866 ierr = PetscFree(prob->data);CHKERRQ(ierr); 2867 PetscFunctionReturn(0); 2868 } 2869 2870 #undef __FUNCT__ 2871 #define __FUNCT__ "PetscDSInitialize_Basic" 2872 static PetscErrorCode PetscDSInitialize_Basic(PetscDS prob) 2873 { 2874 PetscFunctionBegin; 2875 prob->ops->setfromoptions = NULL; 2876 prob->ops->setup = NULL; 2877 prob->ops->view = NULL; 2878 prob->ops->destroy = PetscDSDestroy_Basic; 2879 PetscFunctionReturn(0); 2880 } 2881 2882 /*MC 2883 PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions 2884 2885 Level: intermediate 2886 2887 .seealso: PetscDSType, PetscDSCreate(), PetscDSSetType() 2888 M*/ 2889 2890 #undef __FUNCT__ 2891 #define __FUNCT__ "PetscDSCreate_Basic" 2892 PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS prob) 2893 { 2894 PetscDS_Basic *b; 2895 PetscErrorCode ierr; 2896 2897 PetscFunctionBegin; 2898 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2899 ierr = PetscNewLog(prob, &b);CHKERRQ(ierr); 2900 prob->data = b; 2901 2902 ierr = PetscDSInitialize_Basic(prob);CHKERRQ(ierr); 2903 PetscFunctionReturn(0); 2904 } 2905