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 /* A PetscDS (Discrete System) encodes a set of equations posed in a discrete space, which represents a set of 9 nonlinear continuum equations. The equations can have multiple fields, each field having a different 10 discretization. In addition, different pieces of the domain can have different field combinations and equations. 11 12 The DS provides the user a description of the approximation space on any given cell. It also gives pointwise 13 functions representing the equations. 14 15 Each field is associated with a label, marking the cells on which it is supported. Note that a field can be 16 supported on the closure of a cell not in the label due to overlap of the boundary of neighboring cells. The DM 17 then creates a DS for each set of cells with identical approximation spaces. When assembling, the user asks for 18 the space associated with a given cell. DMPlex uses the labels associated with each DS in the default integration loop. 19 */ 20 21 /*@C 22 PetscDSRegister - Adds a new PetscDS implementation 23 24 Not Collective 25 26 Input Parameters: 27 + name - The name of a new user-defined creation routine 28 - create_func - The creation routine itself 29 30 Notes: 31 PetscDSRegister() may be called multiple times to add several user-defined PetscDSs 32 33 Sample usage: 34 .vb 35 PetscDSRegister("my_ds", MyPetscDSCreate); 36 .ve 37 38 Then, your PetscDS type can be chosen with the procedural interface via 39 .vb 40 PetscDSCreate(MPI_Comm, PetscDS *); 41 PetscDSSetType(PetscDS, "my_ds"); 42 .ve 43 or at runtime via the option 44 .vb 45 -petscds_type my_ds 46 .ve 47 48 Level: advanced 49 50 Not available from Fortran 51 52 .seealso: PetscDSRegisterAll(), PetscDSRegisterDestroy() 53 54 @*/ 55 PetscErrorCode PetscDSRegister(const char sname[], PetscErrorCode (*function)(PetscDS)) 56 { 57 PetscErrorCode ierr; 58 59 PetscFunctionBegin; 60 ierr = PetscFunctionListAdd(&PetscDSList, sname, function);CHKERRQ(ierr); 61 PetscFunctionReturn(0); 62 } 63 64 /*@C 65 PetscDSSetType - Builds a particular PetscDS 66 67 Collective on prob 68 69 Input Parameters: 70 + prob - The PetscDS object 71 - name - The kind of system 72 73 Options Database Key: 74 . -petscds_type <type> - Sets the PetscDS type; use -help for a list of available types 75 76 Level: intermediate 77 78 Not available from Fortran 79 80 .seealso: PetscDSGetType(), PetscDSCreate() 81 @*/ 82 PetscErrorCode PetscDSSetType(PetscDS prob, PetscDSType name) 83 { 84 PetscErrorCode (*r)(PetscDS); 85 PetscBool match; 86 PetscErrorCode ierr; 87 88 PetscFunctionBegin; 89 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 90 ierr = PetscObjectTypeCompare((PetscObject) prob, name, &match);CHKERRQ(ierr); 91 if (match) PetscFunctionReturn(0); 92 93 ierr = PetscDSRegisterAll();CHKERRQ(ierr); 94 ierr = PetscFunctionListFind(PetscDSList, name, &r);CHKERRQ(ierr); 95 if (!r) SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscDS type: %s", name); 96 97 if (prob->ops->destroy) { 98 ierr = (*prob->ops->destroy)(prob);CHKERRQ(ierr); 99 prob->ops->destroy = NULL; 100 } 101 ierr = (*r)(prob);CHKERRQ(ierr); 102 ierr = PetscObjectChangeTypeName((PetscObject) prob, name);CHKERRQ(ierr); 103 PetscFunctionReturn(0); 104 } 105 106 /*@C 107 PetscDSGetType - Gets the PetscDS type name (as a string) from the object. 108 109 Not Collective 110 111 Input Parameter: 112 . prob - The PetscDS 113 114 Output Parameter: 115 . name - The PetscDS type name 116 117 Level: intermediate 118 119 Not available from Fortran 120 121 .seealso: PetscDSSetType(), PetscDSCreate() 122 @*/ 123 PetscErrorCode PetscDSGetType(PetscDS prob, PetscDSType *name) 124 { 125 PetscErrorCode ierr; 126 127 PetscFunctionBegin; 128 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 129 PetscValidPointer(name, 2); 130 ierr = PetscDSRegisterAll();CHKERRQ(ierr); 131 *name = ((PetscObject) prob)->type_name; 132 PetscFunctionReturn(0); 133 } 134 135 static PetscErrorCode PetscDSView_Ascii(PetscDS prob, PetscViewer viewer) 136 { 137 PetscViewerFormat format; 138 const PetscScalar *constants; 139 PetscInt numConstants, f; 140 PetscErrorCode ierr; 141 142 PetscFunctionBegin; 143 ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 144 ierr = PetscViewerASCIIPrintf(viewer, "Discrete System with %d fields\n", prob->Nf);CHKERRQ(ierr); 145 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 146 ierr = PetscViewerASCIIPrintf(viewer, " cell total dim %D total comp %D\n", prob->totDim, prob->totComp);CHKERRQ(ierr); 147 if (prob->isHybrid) {ierr = PetscViewerASCIIPrintf(viewer, " hybrid cell\n");CHKERRQ(ierr);} 148 for (f = 0; f < prob->Nf; ++f) { 149 DSBoundary b; 150 PetscObject obj; 151 PetscClassId id; 152 PetscQuadrature q; 153 const char *name; 154 PetscInt Nc, Nq, Nqc; 155 156 ierr = PetscDSGetDiscretization(prob, f, &obj);CHKERRQ(ierr); 157 ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 158 ierr = PetscObjectGetName(obj, &name);CHKERRQ(ierr); 159 ierr = PetscViewerASCIIPrintf(viewer, "Field %s", name ? name : "<unknown>");CHKERRQ(ierr); 160 ierr = PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);CHKERRQ(ierr); 161 if (id == PETSCFE_CLASSID) { 162 ierr = PetscFEGetNumComponents((PetscFE) obj, &Nc);CHKERRQ(ierr); 163 ierr = PetscFEGetQuadrature((PetscFE) obj, &q);CHKERRQ(ierr); 164 ierr = PetscViewerASCIIPrintf(viewer, " FEM");CHKERRQ(ierr); 165 } else if (id == PETSCFV_CLASSID) { 166 ierr = PetscFVGetNumComponents((PetscFV) obj, &Nc);CHKERRQ(ierr); 167 ierr = PetscFVGetQuadrature((PetscFV) obj, &q);CHKERRQ(ierr); 168 ierr = PetscViewerASCIIPrintf(viewer, " FVM");CHKERRQ(ierr); 169 } 170 else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %D", f); 171 if (Nc > 1) {ierr = PetscViewerASCIIPrintf(viewer, " %D components", Nc);CHKERRQ(ierr);} 172 else {ierr = PetscViewerASCIIPrintf(viewer, " %D component ", Nc);CHKERRQ(ierr);} 173 if (prob->implicit[f]) {ierr = PetscViewerASCIIPrintf(viewer, " (implicit)");CHKERRQ(ierr);} 174 else {ierr = PetscViewerASCIIPrintf(viewer, " (explicit)");CHKERRQ(ierr);} 175 if (q) { 176 ierr = PetscQuadratureGetData(q, NULL, &Nqc, &Nq, NULL, NULL);CHKERRQ(ierr); 177 ierr = PetscViewerASCIIPrintf(viewer, " (Nq %D Nqc %D)", Nq, Nqc);CHKERRQ(ierr); 178 } 179 ierr = PetscViewerASCIIPrintf(viewer, " %D-jet", prob->jetDegree[f]);CHKERRQ(ierr); 180 ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 181 ierr = PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);CHKERRQ(ierr); 182 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 183 if (id == PETSCFE_CLASSID) {ierr = PetscFEView((PetscFE) obj, viewer);CHKERRQ(ierr);} 184 else if (id == PETSCFV_CLASSID) {ierr = PetscFVView((PetscFV) obj, viewer);CHKERRQ(ierr);} 185 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 186 187 for (b = prob->boundary; b; b = b->next) { 188 char *name; 189 PetscInt c, i; 190 191 if (b->field != f) continue; 192 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 193 ierr = PetscViewerASCIIPrintf(viewer, "Boundary %s (%s) %s\n", b->name, b->lname, DMBoundaryConditionTypes[b->type]);CHKERRQ(ierr); 194 if (!b->Nc) { 195 ierr = PetscViewerASCIIPrintf(viewer, " all components\n");CHKERRQ(ierr); 196 } else { 197 ierr = PetscViewerASCIIPrintf(viewer, " components: ");CHKERRQ(ierr); 198 ierr = PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);CHKERRQ(ierr); 199 for (c = 0; c < b->Nc; ++c) { 200 if (c > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 201 ierr = PetscViewerASCIIPrintf(viewer, "%D", b->comps[c]);CHKERRQ(ierr); 202 } 203 ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 204 ierr = PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);CHKERRQ(ierr); 205 } 206 ierr = PetscViewerASCIIPrintf(viewer, " values: ");CHKERRQ(ierr); 207 ierr = PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);CHKERRQ(ierr); 208 for (i = 0; i < b->Nv; ++i) { 209 if (i > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 210 ierr = PetscViewerASCIIPrintf(viewer, "%D", b->values[i]);CHKERRQ(ierr); 211 } 212 ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 213 ierr = PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);CHKERRQ(ierr); 214 if (b->func) { 215 ierr = PetscDLAddr(b->func, &name);CHKERRQ(ierr); 216 if (name) {ierr = PetscViewerASCIIPrintf(viewer, " func: %s\n", name);CHKERRQ(ierr);} 217 else {ierr = PetscViewerASCIIPrintf(viewer, " func: %p\n", b->func);CHKERRQ(ierr);} 218 ierr = PetscFree(name);CHKERRQ(ierr); 219 } 220 if (b->func_t) { 221 ierr = PetscDLAddr(b->func_t, &name);CHKERRQ(ierr); 222 if (name) {ierr = PetscViewerASCIIPrintf(viewer, " func_t: %s\n", name);CHKERRQ(ierr);} 223 else {ierr = PetscViewerASCIIPrintf(viewer, " func_t: %p\n", b->func_t);CHKERRQ(ierr);} 224 ierr = PetscFree(name);CHKERRQ(ierr); 225 } 226 ierr = PetscWeakFormView(b->wf, viewer);CHKERRQ(ierr); 227 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 228 } 229 } 230 ierr = PetscDSGetConstants(prob, &numConstants, &constants);CHKERRQ(ierr); 231 if (numConstants) { 232 ierr = PetscViewerASCIIPrintf(viewer, "%D constants\n", numConstants);CHKERRQ(ierr); 233 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 234 for (f = 0; f < numConstants; ++f) {ierr = PetscViewerASCIIPrintf(viewer, "%g\n", (double) PetscRealPart(constants[f]));CHKERRQ(ierr);} 235 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 236 } 237 ierr = PetscWeakFormView(prob->wf, viewer);CHKERRQ(ierr); 238 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 239 PetscFunctionReturn(0); 240 } 241 242 /*@C 243 PetscDSViewFromOptions - View from Options 244 245 Collective on PetscDS 246 247 Input Parameters: 248 + A - the PetscDS object 249 . obj - Optional object 250 - name - command line option 251 252 Level: intermediate 253 .seealso: PetscDS, PetscDSView, PetscObjectViewFromOptions(), PetscDSCreate() 254 @*/ 255 PetscErrorCode PetscDSViewFromOptions(PetscDS A,PetscObject obj,const char name[]) 256 { 257 PetscErrorCode ierr; 258 259 PetscFunctionBegin; 260 PetscValidHeaderSpecific(A,PETSCDS_CLASSID,1); 261 ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr); 262 PetscFunctionReturn(0); 263 } 264 265 /*@C 266 PetscDSView - Views a PetscDS 267 268 Collective on prob 269 270 Input Parameter: 271 + prob - the PetscDS object to view 272 - v - the viewer 273 274 Level: developer 275 276 .seealso PetscDSDestroy() 277 @*/ 278 PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v) 279 { 280 PetscBool iascii; 281 PetscErrorCode ierr; 282 283 PetscFunctionBegin; 284 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 285 if (!v) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) prob), &v);CHKERRQ(ierr);} 286 else {PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);} 287 ierr = PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 288 if (iascii) {ierr = PetscDSView_Ascii(prob, v);CHKERRQ(ierr);} 289 if (prob->ops->view) {ierr = (*prob->ops->view)(prob, v);CHKERRQ(ierr);} 290 PetscFunctionReturn(0); 291 } 292 293 /*@ 294 PetscDSSetFromOptions - sets parameters in a PetscDS from the options database 295 296 Collective on prob 297 298 Input Parameter: 299 . prob - the PetscDS object to set options for 300 301 Options Database: 302 + -petscds_type <type> : Set the DS type 303 . -petscds_view <view opt> : View the DS 304 . -petscds_jac_pre : Turn formation of a separate Jacobian preconditioner on and off 305 . -bc_<name> <ids> : Specify a list of label ids for a boundary condition 306 - -bc_<name>_comp <comps> : Specify a list of field components to constrain for a boundary condition 307 308 Level: developer 309 310 .seealso PetscDSView() 311 @*/ 312 PetscErrorCode PetscDSSetFromOptions(PetscDS prob) 313 { 314 DSBoundary b; 315 const char *defaultType; 316 char name[256]; 317 PetscBool flg; 318 PetscErrorCode ierr; 319 320 PetscFunctionBegin; 321 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 322 if (!((PetscObject) prob)->type_name) { 323 defaultType = PETSCDSBASIC; 324 } else { 325 defaultType = ((PetscObject) prob)->type_name; 326 } 327 ierr = PetscDSRegisterAll();CHKERRQ(ierr); 328 329 ierr = PetscObjectOptionsBegin((PetscObject) prob);CHKERRQ(ierr); 330 for (b = prob->boundary; b; b = b->next) { 331 char optname[1024]; 332 PetscInt ids[1024], len = 1024; 333 PetscBool flg; 334 335 ierr = PetscSNPrintf(optname, sizeof(optname), "-bc_%s", b->name);CHKERRQ(ierr); 336 ierr = PetscMemzero(ids, sizeof(ids));CHKERRQ(ierr); 337 ierr = PetscOptionsIntArray(optname, "List of boundary IDs", "", ids, &len, &flg);CHKERRQ(ierr); 338 if (flg) { 339 b->Nv = len; 340 ierr = PetscFree(b->values);CHKERRQ(ierr); 341 ierr = PetscMalloc1(len, &b->values);CHKERRQ(ierr); 342 ierr = PetscArraycpy(b->values, ids, len);CHKERRQ(ierr); 343 ierr = PetscWeakFormRewriteKeys(b->wf, b->label, len, b->values);CHKERRQ(ierr); 344 } 345 len = 1024; 346 ierr = PetscSNPrintf(optname, sizeof(optname), "-bc_%s_comp", b->name);CHKERRQ(ierr); 347 ierr = PetscMemzero(ids, sizeof(ids));CHKERRQ(ierr); 348 ierr = PetscOptionsIntArray(optname, "List of boundary field components", "", ids, &len, &flg);CHKERRQ(ierr); 349 if (flg) { 350 b->Nc = len; 351 ierr = PetscFree(b->comps);CHKERRQ(ierr); 352 ierr = PetscMalloc1(len, &b->comps);CHKERRQ(ierr); 353 ierr = PetscArraycpy(b->comps, ids, len);CHKERRQ(ierr); 354 } 355 } 356 ierr = PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg);CHKERRQ(ierr); 357 if (flg) { 358 ierr = PetscDSSetType(prob, name);CHKERRQ(ierr); 359 } else if (!((PetscObject) prob)->type_name) { 360 ierr = PetscDSSetType(prob, defaultType);CHKERRQ(ierr); 361 } 362 ierr = PetscOptionsBool("-petscds_jac_pre", "Discrete System", "PetscDSUseJacobianPreconditioner", prob->useJacPre, &prob->useJacPre, &flg);CHKERRQ(ierr); 363 if (prob->ops->setfromoptions) {ierr = (*prob->ops->setfromoptions)(prob);CHKERRQ(ierr);} 364 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 365 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) prob);CHKERRQ(ierr); 366 ierr = PetscOptionsEnd();CHKERRQ(ierr); 367 if (prob->Nf) {ierr = PetscDSViewFromOptions(prob, NULL, "-petscds_view");CHKERRQ(ierr);} 368 PetscFunctionReturn(0); 369 } 370 371 /*@C 372 PetscDSSetUp - Construct data structures for the PetscDS 373 374 Collective on prob 375 376 Input Parameter: 377 . prob - the PetscDS object to setup 378 379 Level: developer 380 381 .seealso PetscDSView(), PetscDSDestroy() 382 @*/ 383 PetscErrorCode PetscDSSetUp(PetscDS prob) 384 { 385 const PetscInt Nf = prob->Nf; 386 PetscBool hasH = PETSC_FALSE; 387 PetscInt dim, dimEmbed, NbMax = 0, NcMax = 0, NqMax = 0, NsMax = 1, f; 388 PetscErrorCode ierr; 389 390 PetscFunctionBegin; 391 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 392 if (prob->setup) PetscFunctionReturn(0); 393 /* Calculate sizes */ 394 ierr = PetscDSGetSpatialDimension(prob, &dim);CHKERRQ(ierr); 395 ierr = PetscDSGetCoordinateDimension(prob, &dimEmbed);CHKERRQ(ierr); 396 prob->totDim = prob->totComp = 0; 397 ierr = PetscMalloc2(Nf,&prob->Nc,Nf,&prob->Nb);CHKERRQ(ierr); 398 ierr = PetscCalloc2(Nf+1,&prob->off,Nf+1,&prob->offDer);CHKERRQ(ierr); 399 ierr = PetscMalloc2(Nf,&prob->T,Nf,&prob->Tf);CHKERRQ(ierr); 400 for (f = 0; f < Nf; ++f) { 401 PetscObject obj; 402 PetscClassId id; 403 PetscQuadrature q = NULL; 404 PetscInt Nq = 0, Nb, Nc; 405 406 ierr = PetscDSGetDiscretization(prob, f, &obj);CHKERRQ(ierr); 407 if (prob->jetDegree[f] > 1) hasH = PETSC_TRUE; 408 if (!obj) { 409 /* Empty mesh */ 410 Nb = Nc = 0; 411 prob->T[f] = prob->Tf[f] = NULL; 412 } else { 413 ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 414 if (id == PETSCFE_CLASSID) { 415 PetscFE fe = (PetscFE) obj; 416 417 ierr = PetscFEGetQuadrature(fe, &q);CHKERRQ(ierr); 418 ierr = PetscFEGetDimension(fe, &Nb);CHKERRQ(ierr); 419 ierr = PetscFEGetNumComponents(fe, &Nc);CHKERRQ(ierr); 420 ierr = PetscFEGetCellTabulation(fe, prob->jetDegree[f], &prob->T[f]);CHKERRQ(ierr); 421 ierr = PetscFEGetFaceTabulation(fe, prob->jetDegree[f], &prob->Tf[f]);CHKERRQ(ierr); 422 } else if (id == PETSCFV_CLASSID) { 423 PetscFV fv = (PetscFV) obj; 424 425 ierr = PetscFVGetQuadrature(fv, &q);CHKERRQ(ierr); 426 ierr = PetscFVGetNumComponents(fv, &Nc);CHKERRQ(ierr); 427 Nb = Nc; 428 ierr = PetscFVGetCellTabulation(fv, &prob->T[f]);CHKERRQ(ierr); 429 /* TODO: should PetscFV also have face tabulation? Otherwise there will be a null pointer in prob->basisFace */ 430 } else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", f); 431 } 432 prob->Nc[f] = Nc; 433 prob->Nb[f] = Nb; 434 prob->off[f+1] = Nc + prob->off[f]; 435 prob->offDer[f+1] = Nc*dim + prob->offDer[f]; 436 if (q) {ierr = PetscQuadratureGetData(q, NULL, NULL, &Nq, NULL, NULL);CHKERRQ(ierr);} 437 NqMax = PetscMax(NqMax, Nq); 438 NbMax = PetscMax(NbMax, Nb); 439 NcMax = PetscMax(NcMax, Nc); 440 prob->totDim += Nb; 441 prob->totComp += Nc; 442 /* There are two faces for all fields but the cohesive field on a hybrid cell */ 443 if (prob->isHybrid && (f < Nf-1)) prob->totDim += Nb; 444 } 445 /* Allocate works space */ 446 NsMax = 2; /* Even non-hybrid discretizations can be used in a hybrid integration, so we need this extra workspace */ 447 ierr = PetscMalloc3(NsMax*prob->totComp,&prob->u,NsMax*prob->totComp,&prob->u_t,NsMax*prob->totComp*dimEmbed + (hasH ? NsMax*prob->totComp*dimEmbed*dimEmbed : 0),&prob->u_x);CHKERRQ(ierr); 448 ierr = PetscMalloc5(dimEmbed,&prob->x,NbMax*NcMax,&prob->basisReal,NbMax*NcMax*dimEmbed,&prob->basisDerReal,NbMax*NcMax,&prob->testReal,NbMax*NcMax*dimEmbed,&prob->testDerReal);CHKERRQ(ierr); 449 ierr = PetscMalloc6(NsMax*NqMax*NcMax,&prob->f0,NsMax*NqMax*NcMax*dimEmbed,&prob->f1, 450 NsMax*NsMax*NqMax*NcMax*NcMax,&prob->g0,NsMax*NsMax*NqMax*NcMax*NcMax*dimEmbed,&prob->g1, 451 NsMax*NsMax*NqMax*NcMax*NcMax*dimEmbed,&prob->g2,NsMax*NsMax*NqMax*NcMax*NcMax*dimEmbed*dimEmbed,&prob->g3);CHKERRQ(ierr); 452 if (prob->ops->setup) {ierr = (*prob->ops->setup)(prob);CHKERRQ(ierr);} 453 prob->setup = PETSC_TRUE; 454 PetscFunctionReturn(0); 455 } 456 457 static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob) 458 { 459 PetscErrorCode ierr; 460 461 PetscFunctionBegin; 462 ierr = PetscFree2(prob->Nc,prob->Nb);CHKERRQ(ierr); 463 ierr = PetscFree2(prob->off,prob->offDer);CHKERRQ(ierr); 464 ierr = PetscFree2(prob->T,prob->Tf);CHKERRQ(ierr); 465 ierr = PetscFree3(prob->u,prob->u_t,prob->u_x);CHKERRQ(ierr); 466 ierr = PetscFree5(prob->x,prob->basisReal, prob->basisDerReal,prob->testReal,prob->testDerReal);CHKERRQ(ierr); 467 ierr = PetscFree6(prob->f0,prob->f1,prob->g0,prob->g1,prob->g2,prob->g3);CHKERRQ(ierr); 468 PetscFunctionReturn(0); 469 } 470 471 static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew) 472 { 473 PetscObject *tmpd; 474 PetscBool *tmpi; 475 PetscInt *tmpk; 476 PetscPointFunc *tmpup; 477 PetscSimplePointFunc *tmpexactSol, *tmpexactSol_t; 478 void **tmpexactCtx, **tmpexactCtx_t; 479 void **tmpctx; 480 PetscInt Nf = prob->Nf, f; 481 PetscErrorCode ierr; 482 483 PetscFunctionBegin; 484 if (Nf >= NfNew) PetscFunctionReturn(0); 485 prob->setup = PETSC_FALSE; 486 ierr = PetscDSDestroyStructs_Static(prob);CHKERRQ(ierr); 487 ierr = PetscMalloc3(NfNew, &tmpd, NfNew, &tmpi, NfNew, &tmpk);CHKERRQ(ierr); 488 for (f = 0; f < Nf; ++f) {tmpd[f] = prob->disc[f]; tmpi[f] = prob->implicit[f]; tmpk[f] = prob->jetDegree[f];} 489 for (f = Nf; f < NfNew; ++f) {tmpd[f] = NULL; tmpi[f] = PETSC_TRUE; tmpk[f] = 1;} 490 ierr = PetscFree3(prob->disc, prob->implicit, prob->jetDegree);CHKERRQ(ierr); 491 ierr = PetscWeakFormSetNumFields(prob->wf, NfNew);CHKERRQ(ierr); 492 prob->Nf = NfNew; 493 prob->disc = tmpd; 494 prob->implicit = tmpi; 495 prob->jetDegree = tmpk; 496 ierr = PetscCalloc2(NfNew, &tmpup, NfNew, &tmpctx);CHKERRQ(ierr); 497 for (f = 0; f < Nf; ++f) tmpup[f] = prob->update[f]; 498 for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f]; 499 for (f = Nf; f < NfNew; ++f) tmpup[f] = NULL; 500 for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL; 501 ierr = PetscFree2(prob->update, prob->ctx);CHKERRQ(ierr); 502 prob->update = tmpup; 503 prob->ctx = tmpctx; 504 ierr = PetscCalloc4(NfNew, &tmpexactSol, NfNew, &tmpexactCtx, NfNew, &tmpexactSol_t, NfNew, &tmpexactCtx_t);CHKERRQ(ierr); 505 for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f]; 506 for (f = 0; f < Nf; ++f) tmpexactCtx[f] = prob->exactCtx[f]; 507 for (f = 0; f < Nf; ++f) tmpexactSol_t[f] = prob->exactSol_t[f]; 508 for (f = 0; f < Nf; ++f) tmpexactCtx_t[f] = prob->exactCtx_t[f]; 509 for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL; 510 for (f = Nf; f < NfNew; ++f) tmpexactCtx[f] = NULL; 511 for (f = Nf; f < NfNew; ++f) tmpexactSol_t[f] = NULL; 512 for (f = Nf; f < NfNew; ++f) tmpexactCtx_t[f] = NULL; 513 ierr = PetscFree4(prob->exactSol, prob->exactCtx, prob->exactSol_t, prob->exactCtx_t);CHKERRQ(ierr); 514 prob->exactSol = tmpexactSol; 515 prob->exactCtx = tmpexactCtx; 516 prob->exactSol_t = tmpexactSol_t; 517 prob->exactCtx_t = tmpexactCtx_t; 518 PetscFunctionReturn(0); 519 } 520 521 /*@ 522 PetscDSDestroy - Destroys a PetscDS object 523 524 Collective on prob 525 526 Input Parameter: 527 . prob - the PetscDS object to destroy 528 529 Level: developer 530 531 .seealso PetscDSView() 532 @*/ 533 PetscErrorCode PetscDSDestroy(PetscDS *ds) 534 { 535 PetscInt f; 536 PetscErrorCode ierr; 537 538 PetscFunctionBegin; 539 if (!*ds) PetscFunctionReturn(0); 540 PetscValidHeaderSpecific((*ds), PETSCDS_CLASSID, 1); 541 542 if (--((PetscObject)(*ds))->refct > 0) {*ds = NULL; PetscFunctionReturn(0);} 543 ((PetscObject) (*ds))->refct = 0; 544 if ((*ds)->subprobs) { 545 PetscInt dim, d; 546 547 ierr = PetscDSGetSpatialDimension(*ds, &dim);CHKERRQ(ierr); 548 for (d = 0; d < dim; ++d) {ierr = PetscDSDestroy(&(*ds)->subprobs[d]);CHKERRQ(ierr);} 549 } 550 ierr = PetscFree((*ds)->subprobs);CHKERRQ(ierr); 551 ierr = PetscDSDestroyStructs_Static(*ds);CHKERRQ(ierr); 552 for (f = 0; f < (*ds)->Nf; ++f) { 553 ierr = PetscObjectDereference((*ds)->disc[f]);CHKERRQ(ierr); 554 } 555 ierr = PetscFree3((*ds)->disc, (*ds)->implicit, (*ds)->jetDegree);CHKERRQ(ierr); 556 ierr = PetscWeakFormDestroy(&(*ds)->wf);CHKERRQ(ierr); 557 ierr = PetscFree2((*ds)->update,(*ds)->ctx);CHKERRQ(ierr); 558 ierr = PetscFree4((*ds)->exactSol,(*ds)->exactCtx,(*ds)->exactSol_t,(*ds)->exactCtx_t);CHKERRQ(ierr); 559 if ((*ds)->ops->destroy) {ierr = (*(*ds)->ops->destroy)(*ds);CHKERRQ(ierr);} 560 ierr = PetscDSDestroyBoundary(*ds);CHKERRQ(ierr); 561 ierr = PetscFree((*ds)->constants);CHKERRQ(ierr); 562 ierr = PetscHeaderDestroy(ds);CHKERRQ(ierr); 563 PetscFunctionReturn(0); 564 } 565 566 /*@ 567 PetscDSCreate - Creates an empty PetscDS object. The type can then be set with PetscDSSetType(). 568 569 Collective 570 571 Input Parameter: 572 . comm - The communicator for the PetscDS object 573 574 Output Parameter: 575 . ds - The PetscDS object 576 577 Level: beginner 578 579 .seealso: PetscDSSetType(), PETSCDSBASIC 580 @*/ 581 PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *ds) 582 { 583 PetscDS p; 584 PetscErrorCode ierr; 585 586 PetscFunctionBegin; 587 PetscValidPointer(ds, 2); 588 *ds = NULL; 589 ierr = PetscDSInitializePackage();CHKERRQ(ierr); 590 591 ierr = PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView);CHKERRQ(ierr); 592 593 p->Nf = 0; 594 p->setup = PETSC_FALSE; 595 p->numConstants = 0; 596 p->constants = NULL; 597 p->dimEmbed = -1; 598 p->useJacPre = PETSC_TRUE; 599 ierr = PetscWeakFormCreate(comm, &p->wf);CHKERRQ(ierr); 600 601 *ds = p; 602 PetscFunctionReturn(0); 603 } 604 605 /*@ 606 PetscDSGetNumFields - Returns the number of fields in the DS 607 608 Not collective 609 610 Input Parameter: 611 . prob - The PetscDS object 612 613 Output Parameter: 614 . Nf - The number of fields 615 616 Level: beginner 617 618 .seealso: PetscDSGetSpatialDimension(), PetscDSCreate() 619 @*/ 620 PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf) 621 { 622 PetscFunctionBegin; 623 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 624 PetscValidPointer(Nf, 2); 625 *Nf = prob->Nf; 626 PetscFunctionReturn(0); 627 } 628 629 /*@ 630 PetscDSGetSpatialDimension - Returns the spatial dimension of the DS, meaning the topological dimension of the discretizations 631 632 Not collective 633 634 Input Parameter: 635 . prob - The PetscDS object 636 637 Output Parameter: 638 . dim - The spatial dimension 639 640 Level: beginner 641 642 .seealso: PetscDSGetCoordinateDimension(), PetscDSGetNumFields(), PetscDSCreate() 643 @*/ 644 PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim) 645 { 646 PetscErrorCode ierr; 647 648 PetscFunctionBegin; 649 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 650 PetscValidPointer(dim, 2); 651 *dim = 0; 652 if (prob->Nf) { 653 PetscObject obj; 654 PetscClassId id; 655 656 ierr = PetscDSGetDiscretization(prob, 0, &obj);CHKERRQ(ierr); 657 if (obj) { 658 ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 659 if (id == PETSCFE_CLASSID) {ierr = PetscFEGetSpatialDimension((PetscFE) obj, dim);CHKERRQ(ierr);} 660 else if (id == PETSCFV_CLASSID) {ierr = PetscFVGetSpatialDimension((PetscFV) obj, dim);CHKERRQ(ierr);} 661 else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0); 662 } 663 } 664 PetscFunctionReturn(0); 665 } 666 667 /*@ 668 PetscDSGetCoordinateDimension - Returns the coordinate dimension of the DS, meaning the dimension of the space into which the discretiaztions are embedded 669 670 Not collective 671 672 Input Parameter: 673 . prob - The PetscDS object 674 675 Output Parameter: 676 . dimEmbed - The coordinate dimension 677 678 Level: beginner 679 680 .seealso: PetscDSSetCoordinateDimension(), PetscDSGetSpatialDimension(), PetscDSGetNumFields(), PetscDSCreate() 681 @*/ 682 PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed) 683 { 684 PetscFunctionBegin; 685 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 686 PetscValidPointer(dimEmbed, 2); 687 if (prob->dimEmbed < 0) SETERRQ(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONGSTATE, "No coordinate dimension set for this DS"); 688 *dimEmbed = prob->dimEmbed; 689 PetscFunctionReturn(0); 690 } 691 692 /*@ 693 PetscDSSetCoordinateDimension - Set the coordinate dimension of the DS, meaning the dimension of the space into which the discretiaztions are embedded 694 695 Logically collective on prob 696 697 Input Parameters: 698 + prob - The PetscDS object 699 - dimEmbed - The coordinate dimension 700 701 Level: beginner 702 703 .seealso: PetscDSGetCoordinateDimension(), PetscDSGetSpatialDimension(), PetscDSGetNumFields(), PetscDSCreate() 704 @*/ 705 PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed) 706 { 707 PetscFunctionBegin; 708 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 709 if (dimEmbed < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Coordinate dimension must be non-negative, not %D", dimEmbed); 710 prob->dimEmbed = dimEmbed; 711 PetscFunctionReturn(0); 712 } 713 714 /*@ 715 PetscDSGetHybrid - Returns the flag for a hybrid (cohesive) cell 716 717 Not collective 718 719 Input Parameter: 720 . prob - The PetscDS object 721 722 Output Parameter: 723 . isHybrid - The flag 724 725 Level: developer 726 727 .seealso: PetscDSSetHybrid(), PetscDSCreate() 728 @*/ 729 PetscErrorCode PetscDSGetHybrid(PetscDS prob, PetscBool *isHybrid) 730 { 731 PetscFunctionBegin; 732 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 733 PetscValidPointer(isHybrid, 2); 734 *isHybrid = prob->isHybrid; 735 PetscFunctionReturn(0); 736 } 737 738 /*@ 739 PetscDSSetHybrid - Set the flag for a hybrid (cohesive) cell 740 741 Not collective 742 743 Input Parameters: 744 + prob - The PetscDS object 745 - isHybrid - The flag 746 747 Level: developer 748 749 .seealso: PetscDSGetHybrid(), PetscDSCreate() 750 @*/ 751 PetscErrorCode PetscDSSetHybrid(PetscDS prob, PetscBool isHybrid) 752 { 753 PetscFunctionBegin; 754 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 755 prob->isHybrid = isHybrid; 756 PetscFunctionReturn(0); 757 } 758 759 /*@ 760 PetscDSGetTotalDimension - Returns the total size of the approximation space for this system 761 762 Not collective 763 764 Input Parameter: 765 . prob - The PetscDS object 766 767 Output Parameter: 768 . dim - The total problem dimension 769 770 Level: beginner 771 772 .seealso: PetscDSGetNumFields(), PetscDSCreate() 773 @*/ 774 PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim) 775 { 776 PetscErrorCode ierr; 777 778 PetscFunctionBegin; 779 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 780 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 781 PetscValidPointer(dim, 2); 782 *dim = prob->totDim; 783 PetscFunctionReturn(0); 784 } 785 786 /*@ 787 PetscDSGetTotalComponents - Returns the total number of components in this system 788 789 Not collective 790 791 Input Parameter: 792 . prob - The PetscDS object 793 794 Output Parameter: 795 . dim - The total number of components 796 797 Level: beginner 798 799 .seealso: PetscDSGetNumFields(), PetscDSCreate() 800 @*/ 801 PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc) 802 { 803 PetscErrorCode ierr; 804 805 PetscFunctionBegin; 806 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 807 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 808 PetscValidPointer(Nc, 2); 809 *Nc = prob->totComp; 810 PetscFunctionReturn(0); 811 } 812 813 /*@ 814 PetscDSGetDiscretization - Returns the discretization object for the given field 815 816 Not collective 817 818 Input Parameters: 819 + prob - The PetscDS object 820 - f - The field number 821 822 Output Parameter: 823 . disc - The discretization object 824 825 Level: beginner 826 827 .seealso: PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 828 @*/ 829 PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc) 830 { 831 PetscFunctionBeginHot; 832 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 833 PetscValidPointer(disc, 3); 834 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); 835 *disc = prob->disc[f]; 836 PetscFunctionReturn(0); 837 } 838 839 /*@ 840 PetscDSSetDiscretization - Sets the discretization object for the given field 841 842 Not collective 843 844 Input Parameters: 845 + prob - The PetscDS object 846 . f - The field number 847 - disc - The discretization object 848 849 Level: beginner 850 851 .seealso: PetscDSGetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 852 @*/ 853 PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc) 854 { 855 PetscErrorCode ierr; 856 857 PetscFunctionBegin; 858 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 859 if (disc) PetscValidPointer(disc, 3); 860 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 861 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr); 862 ierr = PetscObjectDereference(prob->disc[f]);CHKERRQ(ierr); 863 prob->disc[f] = disc; 864 ierr = PetscObjectReference(disc);CHKERRQ(ierr); 865 if (disc) { 866 PetscClassId id; 867 868 ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr); 869 if (id == PETSCFE_CLASSID) { 870 ierr = PetscDSSetImplicit(prob, f, PETSC_TRUE);CHKERRQ(ierr); 871 } else if (id == PETSCFV_CLASSID) { 872 ierr = PetscDSSetImplicit(prob, f, PETSC_FALSE);CHKERRQ(ierr); 873 } 874 ierr = PetscDSSetJetDegree(prob, f, 1);CHKERRQ(ierr); 875 } 876 PetscFunctionReturn(0); 877 } 878 879 /*@ 880 PetscDSGetWeakForm - Returns the weak form object 881 882 Not collective 883 884 Input Parameter: 885 . ds - The PetscDS object 886 887 Output Parameter: 888 . wf - The weak form object 889 890 Level: beginner 891 892 .seealso: PetscDSSetWeakForm(), PetscDSGetNumFields(), PetscDSCreate() 893 @*/ 894 PetscErrorCode PetscDSGetWeakForm(PetscDS ds, PetscWeakForm *wf) 895 { 896 PetscFunctionBegin; 897 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 898 PetscValidPointer(wf, 2); 899 *wf = ds->wf; 900 PetscFunctionReturn(0); 901 } 902 903 /*@ 904 PetscDSSetWeakForm - Sets the weak form object 905 906 Not collective 907 908 Input Parameters: 909 + ds - The PetscDS object 910 - wf - The weak form object 911 912 Level: beginner 913 914 .seealso: PetscDSGetWeakForm(), PetscDSGetNumFields(), PetscDSCreate() 915 @*/ 916 PetscErrorCode PetscDSSetWeakForm(PetscDS ds, PetscWeakForm wf) 917 { 918 PetscErrorCode ierr; 919 920 PetscFunctionBegin; 921 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 922 PetscValidHeaderSpecific(wf, PETSCWEAKFORM_CLASSID, 2); 923 ierr = PetscObjectDereference((PetscObject) ds->wf);CHKERRQ(ierr); 924 ds->wf = wf; 925 ierr = PetscObjectReference((PetscObject) wf);CHKERRQ(ierr); 926 ierr = PetscWeakFormSetNumFields(wf, ds->Nf);CHKERRQ(ierr); 927 PetscFunctionReturn(0); 928 } 929 930 /*@ 931 PetscDSAddDiscretization - Adds a discretization object 932 933 Not collective 934 935 Input Parameters: 936 + prob - The PetscDS object 937 - disc - The boundary discretization object 938 939 Level: beginner 940 941 .seealso: PetscDSGetDiscretization(), PetscDSSetDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 942 @*/ 943 PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc) 944 { 945 PetscErrorCode ierr; 946 947 PetscFunctionBegin; 948 ierr = PetscDSSetDiscretization(prob, prob->Nf, disc);CHKERRQ(ierr); 949 PetscFunctionReturn(0); 950 } 951 952 /*@ 953 PetscDSGetQuadrature - Returns the quadrature, which must agree for all fields in the DS 954 955 Not collective 956 957 Input Parameter: 958 . prob - The PetscDS object 959 960 Output Parameter: 961 . q - The quadrature object 962 963 Level: intermediate 964 965 .seealso: PetscDSSetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 966 @*/ 967 PetscErrorCode PetscDSGetQuadrature(PetscDS prob, PetscQuadrature *q) 968 { 969 PetscObject obj; 970 PetscClassId id; 971 PetscErrorCode ierr; 972 973 PetscFunctionBegin; 974 *q = NULL; 975 if (!prob->Nf) PetscFunctionReturn(0); 976 ierr = PetscDSGetDiscretization(prob, 0, &obj);CHKERRQ(ierr); 977 ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 978 if (id == PETSCFE_CLASSID) {ierr = PetscFEGetQuadrature((PetscFE) obj, q);CHKERRQ(ierr);} 979 else if (id == PETSCFV_CLASSID) {ierr = PetscFVGetQuadrature((PetscFV) obj, q);CHKERRQ(ierr);} 980 else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0); 981 PetscFunctionReturn(0); 982 } 983 984 /*@ 985 PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for IMEX 986 987 Not collective 988 989 Input Parameters: 990 + prob - The PetscDS object 991 - f - The field number 992 993 Output Parameter: 994 . implicit - The flag indicating what kind of solve to use for this field 995 996 Level: developer 997 998 .seealso: PetscDSSetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 999 @*/ 1000 PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit) 1001 { 1002 PetscFunctionBegin; 1003 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1004 PetscValidPointer(implicit, 3); 1005 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); 1006 *implicit = prob->implicit[f]; 1007 PetscFunctionReturn(0); 1008 } 1009 1010 /*@ 1011 PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for IMEX 1012 1013 Not collective 1014 1015 Input Parameters: 1016 + prob - The PetscDS object 1017 . f - The field number 1018 - implicit - The flag indicating what kind of solve to use for this field 1019 1020 Level: developer 1021 1022 .seealso: PetscDSGetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 1023 @*/ 1024 PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit) 1025 { 1026 PetscFunctionBegin; 1027 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1028 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); 1029 prob->implicit[f] = implicit; 1030 PetscFunctionReturn(0); 1031 } 1032 1033 /*@ 1034 PetscDSGetJetDegree - Returns the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate. 1035 1036 Not collective 1037 1038 Input Parameters: 1039 + ds - The PetscDS object 1040 - f - The field number 1041 1042 Output Parameter: 1043 . k - The highest derivative we need to tabulate 1044 1045 Level: developer 1046 1047 .seealso: PetscDSSetJetDegree(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 1048 @*/ 1049 PetscErrorCode PetscDSGetJetDegree(PetscDS ds, PetscInt f, PetscInt *k) 1050 { 1051 PetscFunctionBegin; 1052 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1053 PetscValidPointer(k, 3); 1054 if ((f < 0) || (f >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, ds->Nf); 1055 *k = ds->jetDegree[f]; 1056 PetscFunctionReturn(0); 1057 } 1058 1059 /*@ 1060 PetscDSSetJetDegree - Set the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate. 1061 1062 Not collective 1063 1064 Input Parameters: 1065 + ds - The PetscDS object 1066 . f - The field number 1067 - k - The highest derivative we need to tabulate 1068 1069 Level: developer 1070 1071 .seealso: PetscDSGetJetDegree(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 1072 @*/ 1073 PetscErrorCode PetscDSSetJetDegree(PetscDS ds, PetscInt f, PetscInt k) 1074 { 1075 PetscFunctionBegin; 1076 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1077 if ((f < 0) || (f >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, ds->Nf); 1078 ds->jetDegree[f] = k; 1079 PetscFunctionReturn(0); 1080 } 1081 1082 PetscErrorCode PetscDSGetObjective(PetscDS ds, PetscInt f, 1083 void (**obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1084 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1085 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1086 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[])) 1087 { 1088 PetscPointFunc *tmp; 1089 PetscInt n; 1090 PetscErrorCode ierr; 1091 1092 PetscFunctionBegin; 1093 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1094 PetscValidPointer(obj, 3); 1095 if ((f < 0) || (f >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, ds->Nf); 1096 ierr = PetscWeakFormGetObjective(ds->wf, NULL, 0, f, 0, &n, &tmp);CHKERRQ(ierr); 1097 *obj = tmp ? tmp[0] : NULL; 1098 PetscFunctionReturn(0); 1099 } 1100 1101 PetscErrorCode PetscDSSetObjective(PetscDS ds, PetscInt f, 1102 void (*obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1103 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1104 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1105 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[])) 1106 { 1107 PetscErrorCode ierr; 1108 1109 PetscFunctionBegin; 1110 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1111 if (obj) PetscValidFunction(obj, 3); 1112 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 1113 ierr = PetscWeakFormSetIndexObjective(ds->wf, NULL, 0, f, 0, 0, obj);CHKERRQ(ierr); 1114 PetscFunctionReturn(0); 1115 } 1116 1117 /*@C 1118 PetscDSGetResidual - Get the pointwise residual function for a given test field 1119 1120 Not collective 1121 1122 Input Parameters: 1123 + ds - The PetscDS 1124 - f - The test field number 1125 1126 Output Parameters: 1127 + f0 - integrand for the test function term 1128 - f1 - integrand for the test function gradient term 1129 1130 Note: We are using a first order FEM model for the weak form: 1131 1132 \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) 1133 1134 The calling sequence for the callbacks f0 and f1 is given by: 1135 1136 $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1137 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1138 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1139 $ PetscReal t, const PetscReal x[], PetscScalar f0[]) 1140 1141 + dim - the spatial dimension 1142 . Nf - the number of fields 1143 . uOff - the offset into u[] and u_t[] for each field 1144 . uOff_x - the offset into u_x[] for each field 1145 . u - each field evaluated at the current point 1146 . u_t - the time derivative of each field evaluated at the current point 1147 . u_x - the gradient of each field evaluated at the current point 1148 . aOff - the offset into a[] and a_t[] for each auxiliary field 1149 . aOff_x - the offset into a_x[] for each auxiliary field 1150 . a - each auxiliary field evaluated at the current point 1151 . a_t - the time derivative of each auxiliary field evaluated at the current point 1152 . a_x - the gradient of auxiliary each field evaluated at the current point 1153 . t - current time 1154 . x - coordinates of the current point 1155 . numConstants - number of constant parameters 1156 . constants - constant parameters 1157 - f0 - output values at the current point 1158 1159 Level: intermediate 1160 1161 .seealso: PetscDSSetResidual() 1162 @*/ 1163 PetscErrorCode PetscDSGetResidual(PetscDS ds, PetscInt f, 1164 void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1165 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1166 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1167 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), 1168 void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1169 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1170 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1171 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[])) 1172 { 1173 PetscPointFunc *tmp0, *tmp1; 1174 PetscInt n0, n1; 1175 PetscErrorCode ierr; 1176 1177 PetscFunctionBegin; 1178 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1179 if ((f < 0) || (f >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, ds->Nf); 1180 ierr = PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1);CHKERRQ(ierr); 1181 *f0 = tmp0 ? tmp0[0] : NULL; 1182 *f1 = tmp1 ? tmp1[0] : NULL; 1183 PetscFunctionReturn(0); 1184 } 1185 1186 /*@C 1187 PetscDSSetResidual - Set the pointwise residual function for a given test field 1188 1189 Not collective 1190 1191 Input Parameters: 1192 + ds - The PetscDS 1193 . f - The test field number 1194 . f0 - integrand for the test function term 1195 - f1 - integrand for the test function gradient term 1196 1197 Note: We are using a first order FEM model for the weak form: 1198 1199 \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) 1200 1201 The calling sequence for the callbacks f0 and f1 is given by: 1202 1203 $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1204 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1205 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1206 $ PetscReal t, const PetscReal x[], PetscScalar f0[]) 1207 1208 + dim - the spatial dimension 1209 . Nf - the number of fields 1210 . uOff - the offset into u[] and u_t[] for each field 1211 . uOff_x - the offset into u_x[] for each field 1212 . u - each field evaluated at the current point 1213 . u_t - the time derivative of each field evaluated at the current point 1214 . u_x - the gradient of each field evaluated at the current point 1215 . aOff - the offset into a[] and a_t[] for each auxiliary field 1216 . aOff_x - the offset into a_x[] for each auxiliary field 1217 . a - each auxiliary field evaluated at the current point 1218 . a_t - the time derivative of each auxiliary field evaluated at the current point 1219 . a_x - the gradient of auxiliary each field evaluated at the current point 1220 . t - current time 1221 . x - coordinates of the current point 1222 . numConstants - number of constant parameters 1223 . constants - constant parameters 1224 - f0 - output values at the current point 1225 1226 Level: intermediate 1227 1228 .seealso: PetscDSGetResidual() 1229 @*/ 1230 PetscErrorCode PetscDSSetResidual(PetscDS ds, PetscInt f, 1231 void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1232 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1233 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1234 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), 1235 void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1236 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1237 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1238 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[])) 1239 { 1240 PetscErrorCode ierr; 1241 1242 PetscFunctionBegin; 1243 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1244 if (f0) PetscValidFunction(f0, 3); 1245 if (f1) PetscValidFunction(f1, 4); 1246 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 1247 ierr = PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1);CHKERRQ(ierr); 1248 PetscFunctionReturn(0); 1249 } 1250 1251 /*@C 1252 PetscDSHasJacobian - Signals that Jacobian functions have been set 1253 1254 Not collective 1255 1256 Input Parameter: 1257 . prob - The PetscDS 1258 1259 Output Parameter: 1260 . hasJac - flag that pointwise function for the Jacobian has been set 1261 1262 Level: intermediate 1263 1264 .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian() 1265 @*/ 1266 PetscErrorCode PetscDSHasJacobian(PetscDS ds, PetscBool *hasJac) 1267 { 1268 PetscErrorCode ierr; 1269 1270 PetscFunctionBegin; 1271 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1272 ierr = PetscWeakFormHasJacobian(ds->wf, hasJac);CHKERRQ(ierr); 1273 PetscFunctionReturn(0); 1274 } 1275 1276 /*@C 1277 PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field 1278 1279 Not collective 1280 1281 Input Parameters: 1282 + ds - The PetscDS 1283 . f - The test field number 1284 - g - The field number 1285 1286 Output Parameters: 1287 + g0 - integrand for the test and basis function term 1288 . g1 - integrand for the test function and basis function gradient term 1289 . g2 - integrand for the test function gradient and basis function term 1290 - g3 - integrand for the test function gradient and basis function gradient term 1291 1292 Note: We are using a first order FEM model for the weak form: 1293 1294 \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 1295 1296 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 1297 1298 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1299 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1300 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1301 $ PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[]) 1302 1303 + dim - the spatial dimension 1304 . Nf - the number of fields 1305 . uOff - the offset into u[] and u_t[] for each field 1306 . uOff_x - the offset into u_x[] for each field 1307 . u - each field evaluated at the current point 1308 . u_t - the time derivative of each field evaluated at the current point 1309 . u_x - the gradient of each field evaluated at the current point 1310 . aOff - the offset into a[] and a_t[] for each auxiliary field 1311 . aOff_x - the offset into a_x[] for each auxiliary field 1312 . a - each auxiliary field evaluated at the current point 1313 . a_t - the time derivative of each auxiliary field evaluated at the current point 1314 . a_x - the gradient of auxiliary each field evaluated at the current point 1315 . t - current time 1316 . u_tShift - the multiplier a for dF/dU_t 1317 . x - coordinates of the current point 1318 . numConstants - number of constant parameters 1319 . constants - constant parameters 1320 - g0 - output values at the current point 1321 1322 Level: intermediate 1323 1324 .seealso: PetscDSSetJacobian() 1325 @*/ 1326 PetscErrorCode PetscDSGetJacobian(PetscDS ds, PetscInt f, PetscInt g, 1327 void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1328 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1329 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1330 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), 1331 void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1332 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1333 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1334 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), 1335 void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1336 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1337 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1338 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), 1339 void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1340 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1341 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1342 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])) 1343 { 1344 PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3; 1345 PetscInt n0, n1, n2, n3; 1346 PetscErrorCode ierr; 1347 1348 PetscFunctionBegin; 1349 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1350 if ((f < 0) || (f >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, ds->Nf); 1351 if ((g < 0) || (g >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, ds->Nf); 1352 ierr = PetscWeakFormGetJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3);CHKERRQ(ierr); 1353 *g0 = tmp0 ? tmp0[0] : NULL; 1354 *g1 = tmp1 ? tmp1[0] : NULL; 1355 *g2 = tmp2 ? tmp2[0] : NULL; 1356 *g3 = tmp3 ? tmp3[0] : NULL; 1357 PetscFunctionReturn(0); 1358 } 1359 1360 /*@C 1361 PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields 1362 1363 Not collective 1364 1365 Input Parameters: 1366 + ds - The PetscDS 1367 . f - The test field number 1368 . g - The field number 1369 . g0 - integrand for the test and basis function term 1370 . g1 - integrand for the test function and basis function gradient term 1371 . g2 - integrand for the test function gradient and basis function term 1372 - g3 - integrand for the test function gradient and basis function gradient term 1373 1374 Note: We are using a first order FEM model for the weak form: 1375 1376 \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 1377 1378 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 1379 1380 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1381 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1382 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1383 $ PetscReal t, const PetscReal x[], PetscScalar g0[]) 1384 1385 + dim - the spatial dimension 1386 . Nf - the number of fields 1387 . uOff - the offset into u[] and u_t[] for each field 1388 . uOff_x - the offset into u_x[] for each field 1389 . u - each field evaluated at the current point 1390 . u_t - the time derivative of each field evaluated at the current point 1391 . u_x - the gradient of each field evaluated at the current point 1392 . aOff - the offset into a[] and a_t[] for each auxiliary field 1393 . aOff_x - the offset into a_x[] for each auxiliary field 1394 . a - each auxiliary field evaluated at the current point 1395 . a_t - the time derivative of each auxiliary field evaluated at the current point 1396 . a_x - the gradient of auxiliary each field evaluated at the current point 1397 . t - current time 1398 . u_tShift - the multiplier a for dF/dU_t 1399 . x - coordinates of the current point 1400 . numConstants - number of constant parameters 1401 . constants - constant parameters 1402 - g0 - output values at the current point 1403 1404 Level: intermediate 1405 1406 .seealso: PetscDSGetJacobian() 1407 @*/ 1408 PetscErrorCode PetscDSSetJacobian(PetscDS ds, PetscInt f, PetscInt g, 1409 void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1410 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1411 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1412 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), 1413 void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1414 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1415 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1416 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), 1417 void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1418 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1419 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1420 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), 1421 void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1422 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1423 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1424 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])) 1425 { 1426 PetscErrorCode ierr; 1427 1428 PetscFunctionBegin; 1429 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1430 if (g0) PetscValidFunction(g0, 4); 1431 if (g1) PetscValidFunction(g1, 5); 1432 if (g2) PetscValidFunction(g2, 6); 1433 if (g3) PetscValidFunction(g3, 7); 1434 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 1435 if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g); 1436 ierr = PetscWeakFormSetIndexJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3);CHKERRQ(ierr); 1437 PetscFunctionReturn(0); 1438 } 1439 1440 /*@C 1441 PetscDSUseJacobianPreconditioner - Whether to construct a Jacobian preconditioner 1442 1443 Not collective 1444 1445 Input Parameters: 1446 + prob - The PetscDS 1447 - useJacPre - flag that enables construction of a Jacobian preconditioner 1448 1449 Level: intermediate 1450 1451 .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian() 1452 @*/ 1453 PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre) 1454 { 1455 PetscFunctionBegin; 1456 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 1457 prob->useJacPre = useJacPre; 1458 PetscFunctionReturn(0); 1459 } 1460 1461 /*@C 1462 PetscDSHasJacobianPreconditioner - Signals that a Jacobian preconditioner matrix has been set 1463 1464 Not collective 1465 1466 Input Parameter: 1467 . prob - The PetscDS 1468 1469 Output Parameter: 1470 . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set 1471 1472 Level: intermediate 1473 1474 .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian() 1475 @*/ 1476 PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre) 1477 { 1478 PetscErrorCode ierr; 1479 1480 PetscFunctionBegin; 1481 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1482 *hasJacPre = PETSC_FALSE; 1483 if (!ds->useJacPre) PetscFunctionReturn(0); 1484 ierr = PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre);CHKERRQ(ierr); 1485 PetscFunctionReturn(0); 1486 } 1487 1488 /*@C 1489 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. 1490 1491 Not collective 1492 1493 Input Parameters: 1494 + ds - The PetscDS 1495 . f - The test field number 1496 - g - The field number 1497 1498 Output Parameters: 1499 + g0 - integrand for the test and basis function term 1500 . g1 - integrand for the test function and basis function gradient term 1501 . g2 - integrand for the test function gradient and basis function term 1502 - g3 - integrand for the test function gradient and basis function gradient term 1503 1504 Note: We are using a first order FEM model for the weak form: 1505 1506 \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 1507 1508 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 1509 1510 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1511 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1512 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1513 $ PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[]) 1514 1515 + dim - the spatial dimension 1516 . Nf - the number of fields 1517 . uOff - the offset into u[] and u_t[] for each field 1518 . uOff_x - the offset into u_x[] for each field 1519 . u - each field evaluated at the current point 1520 . u_t - the time derivative of each field evaluated at the current point 1521 . u_x - the gradient of each field evaluated at the current point 1522 . aOff - the offset into a[] and a_t[] for each auxiliary field 1523 . aOff_x - the offset into a_x[] for each auxiliary field 1524 . a - each auxiliary field evaluated at the current point 1525 . a_t - the time derivative of each auxiliary field evaluated at the current point 1526 . a_x - the gradient of auxiliary each field evaluated at the current point 1527 . t - current time 1528 . u_tShift - the multiplier a for dF/dU_t 1529 . x - coordinates of the current point 1530 . numConstants - number of constant parameters 1531 . constants - constant parameters 1532 - g0 - output values at the current point 1533 1534 Level: intermediate 1535 1536 .seealso: PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian() 1537 @*/ 1538 PetscErrorCode PetscDSGetJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, 1539 void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1540 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1541 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1542 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), 1543 void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1544 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1545 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1546 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), 1547 void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1548 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1549 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1550 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), 1551 void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1552 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1553 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1554 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])) 1555 { 1556 PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3; 1557 PetscInt n0, n1, n2, n3; 1558 PetscErrorCode ierr; 1559 1560 PetscFunctionBegin; 1561 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1562 if ((f < 0) || (f >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, ds->Nf); 1563 if ((g < 0) || (g >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, ds->Nf); 1564 ierr = PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3);CHKERRQ(ierr); 1565 *g0 = tmp0 ? tmp0[0] : NULL; 1566 *g1 = tmp1 ? tmp1[0] : NULL; 1567 *g2 = tmp2 ? tmp2[0] : NULL; 1568 *g3 = tmp3 ? tmp3[0] : NULL; 1569 PetscFunctionReturn(0); 1570 } 1571 1572 /*@C 1573 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. 1574 1575 Not collective 1576 1577 Input Parameters: 1578 + ds - The PetscDS 1579 . f - The test field number 1580 . g - The field number 1581 . g0 - integrand for the test and basis function term 1582 . g1 - integrand for the test function and basis function gradient term 1583 . g2 - integrand for the test function gradient and basis function term 1584 - g3 - integrand for the test function gradient and basis function gradient term 1585 1586 Note: We are using a first order FEM model for the weak form: 1587 1588 \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 1589 1590 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 1591 1592 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1593 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1594 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1595 $ PetscReal t, const PetscReal x[], PetscScalar g0[]) 1596 1597 + dim - the spatial dimension 1598 . Nf - the number of fields 1599 . uOff - the offset into u[] and u_t[] for each field 1600 . uOff_x - the offset into u_x[] for each field 1601 . u - each field evaluated at the current point 1602 . u_t - the time derivative of each field evaluated at the current point 1603 . u_x - the gradient of each field evaluated at the current point 1604 . aOff - the offset into a[] and a_t[] for each auxiliary field 1605 . aOff_x - the offset into a_x[] for each auxiliary field 1606 . a - each auxiliary field evaluated at the current point 1607 . a_t - the time derivative of each auxiliary field evaluated at the current point 1608 . a_x - the gradient of auxiliary each field evaluated at the current point 1609 . t - current time 1610 . u_tShift - the multiplier a for dF/dU_t 1611 . x - coordinates of the current point 1612 . numConstants - number of constant parameters 1613 . constants - constant parameters 1614 - g0 - output values at the current point 1615 1616 Level: intermediate 1617 1618 .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobian() 1619 @*/ 1620 PetscErrorCode PetscDSSetJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, 1621 void (*g0)(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[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), 1625 void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1626 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1627 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1628 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), 1629 void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1630 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1631 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1632 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), 1633 void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1634 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1635 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1636 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])) 1637 { 1638 PetscErrorCode ierr; 1639 1640 PetscFunctionBegin; 1641 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1642 if (g0) PetscValidFunction(g0, 4); 1643 if (g1) PetscValidFunction(g1, 5); 1644 if (g2) PetscValidFunction(g2, 6); 1645 if (g3) PetscValidFunction(g3, 7); 1646 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 1647 if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g); 1648 ierr = PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3);CHKERRQ(ierr); 1649 PetscFunctionReturn(0); 1650 } 1651 1652 /*@C 1653 PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set 1654 1655 Not collective 1656 1657 Input Parameter: 1658 . ds - The PetscDS 1659 1660 Output Parameter: 1661 . hasDynJac - flag that pointwise function for dynamic Jacobian has been set 1662 1663 Level: intermediate 1664 1665 .seealso: PetscDSGetDynamicJacobian(), PetscDSSetDynamicJacobian(), PetscDSGetJacobian() 1666 @*/ 1667 PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac) 1668 { 1669 PetscErrorCode ierr; 1670 1671 PetscFunctionBegin; 1672 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1673 ierr = PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac);CHKERRQ(ierr); 1674 PetscFunctionReturn(0); 1675 } 1676 1677 /*@C 1678 PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field 1679 1680 Not collective 1681 1682 Input Parameters: 1683 + ds - The PetscDS 1684 . f - The test field number 1685 - g - The field number 1686 1687 Output Parameters: 1688 + g0 - integrand for the test and basis function term 1689 . g1 - integrand for the test function and basis function gradient term 1690 . g2 - integrand for the test function gradient and basis function term 1691 - g3 - integrand for the test function gradient and basis function gradient term 1692 1693 Note: We are using a first order FEM model for the weak form: 1694 1695 \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 1696 1697 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 1698 1699 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1700 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1701 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1702 $ PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[]) 1703 1704 + dim - the spatial dimension 1705 . Nf - the number of fields 1706 . uOff - the offset into u[] and u_t[] for each field 1707 . uOff_x - the offset into u_x[] for each field 1708 . u - each field evaluated at the current point 1709 . u_t - the time derivative of each field evaluated at the current point 1710 . u_x - the gradient of each field evaluated at the current point 1711 . aOff - the offset into a[] and a_t[] for each auxiliary field 1712 . aOff_x - the offset into a_x[] for each auxiliary field 1713 . a - each auxiliary field evaluated at the current point 1714 . a_t - the time derivative of each auxiliary field evaluated at the current point 1715 . a_x - the gradient of auxiliary each field evaluated at the current point 1716 . t - current time 1717 . u_tShift - the multiplier a for dF/dU_t 1718 . x - coordinates of the current point 1719 . numConstants - number of constant parameters 1720 . constants - constant parameters 1721 - g0 - output values at the current point 1722 1723 Level: intermediate 1724 1725 .seealso: PetscDSSetJacobian() 1726 @*/ 1727 PetscErrorCode PetscDSGetDynamicJacobian(PetscDS ds, PetscInt f, PetscInt g, 1728 void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1729 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1730 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1731 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), 1732 void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1733 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1734 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1735 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), 1736 void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1737 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1738 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1739 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), 1740 void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1741 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1742 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1743 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])) 1744 { 1745 PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3; 1746 PetscInt n0, n1, n2, n3; 1747 PetscErrorCode ierr; 1748 1749 PetscFunctionBegin; 1750 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1751 if ((f < 0) || (f >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, ds->Nf); 1752 if ((g < 0) || (g >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, ds->Nf); 1753 ierr = PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3);CHKERRQ(ierr); 1754 *g0 = tmp0 ? tmp0[0] : NULL; 1755 *g1 = tmp1 ? tmp1[0] : NULL; 1756 *g2 = tmp2 ? tmp2[0] : NULL; 1757 *g3 = tmp3 ? tmp3[0] : NULL; 1758 PetscFunctionReturn(0); 1759 } 1760 1761 /*@C 1762 PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields 1763 1764 Not collective 1765 1766 Input Parameters: 1767 + ds - The PetscDS 1768 . f - The test field number 1769 . g - The field number 1770 . g0 - integrand for the test and basis function term 1771 . g1 - integrand for the test function and basis function gradient term 1772 . g2 - integrand for the test function gradient and basis function term 1773 - g3 - integrand for the test function gradient and basis function gradient term 1774 1775 Note: We are using a first order FEM model for the weak form: 1776 1777 \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 1778 1779 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 1780 1781 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1782 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1783 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1784 $ PetscReal t, const PetscReal x[], PetscScalar g0[]) 1785 1786 + dim - the spatial dimension 1787 . Nf - the number of fields 1788 . uOff - the offset into u[] and u_t[] for each field 1789 . uOff_x - the offset into u_x[] for each field 1790 . u - each field evaluated at the current point 1791 . u_t - the time derivative of each field evaluated at the current point 1792 . u_x - the gradient of each field evaluated at the current point 1793 . aOff - the offset into a[] and a_t[] for each auxiliary field 1794 . aOff_x - the offset into a_x[] for each auxiliary field 1795 . a - each auxiliary field evaluated at the current point 1796 . a_t - the time derivative of each auxiliary field evaluated at the current point 1797 . a_x - the gradient of auxiliary each field evaluated at the current point 1798 . t - current time 1799 . u_tShift - the multiplier a for dF/dU_t 1800 . x - coordinates of the current point 1801 . numConstants - number of constant parameters 1802 . constants - constant parameters 1803 - g0 - output values at the current point 1804 1805 Level: intermediate 1806 1807 .seealso: PetscDSGetJacobian() 1808 @*/ 1809 PetscErrorCode PetscDSSetDynamicJacobian(PetscDS ds, PetscInt f, PetscInt g, 1810 void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1811 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1812 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1813 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), 1814 void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1815 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1816 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1817 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), 1818 void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1819 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1820 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1821 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), 1822 void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1823 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1824 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1825 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])) 1826 { 1827 PetscErrorCode ierr; 1828 1829 PetscFunctionBegin; 1830 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1831 if (g0) PetscValidFunction(g0, 4); 1832 if (g1) PetscValidFunction(g1, 5); 1833 if (g2) PetscValidFunction(g2, 6); 1834 if (g3) PetscValidFunction(g3, 7); 1835 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 1836 if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g); 1837 ierr = PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3);CHKERRQ(ierr); 1838 PetscFunctionReturn(0); 1839 } 1840 1841 /*@C 1842 PetscDSGetRiemannSolver - Returns the Riemann solver for the given field 1843 1844 Not collective 1845 1846 Input Arguments: 1847 + ds - The PetscDS object 1848 - f - The field number 1849 1850 Output Argument: 1851 . r - Riemann solver 1852 1853 Calling sequence for r: 1854 1855 $ r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx) 1856 1857 + dim - The spatial dimension 1858 . Nf - The number of fields 1859 . x - The coordinates at a point on the interface 1860 . n - The normal vector to the interface 1861 . uL - The state vector to the left of the interface 1862 . uR - The state vector to the right of the interface 1863 . flux - output array of flux through the interface 1864 . numConstants - number of constant parameters 1865 . constants - constant parameters 1866 - ctx - optional user context 1867 1868 Level: intermediate 1869 1870 .seealso: PetscDSSetRiemannSolver() 1871 @*/ 1872 PetscErrorCode PetscDSGetRiemannSolver(PetscDS ds, PetscInt f, 1873 void (**r)(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscInt numConstants, const PetscScalar constants[], PetscScalar flux[], void *ctx)) 1874 { 1875 PetscRiemannFunc *tmp; 1876 PetscInt n; 1877 PetscErrorCode ierr; 1878 1879 PetscFunctionBegin; 1880 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1881 PetscValidPointer(r, 3); 1882 if ((f < 0) || (f >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, ds->Nf); 1883 ierr = PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp);CHKERRQ(ierr); 1884 *r = tmp ? tmp[0] : NULL; 1885 PetscFunctionReturn(0); 1886 } 1887 1888 /*@C 1889 PetscDSSetRiemannSolver - Sets the Riemann solver for the given field 1890 1891 Not collective 1892 1893 Input Arguments: 1894 + ds - The PetscDS object 1895 . f - The field number 1896 - r - Riemann solver 1897 1898 Calling sequence for r: 1899 1900 $ r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx) 1901 1902 + dim - The spatial dimension 1903 . Nf - The number of fields 1904 . x - The coordinates at a point on the interface 1905 . n - The normal vector to the interface 1906 . uL - The state vector to the left of the interface 1907 . uR - The state vector to the right of the interface 1908 . flux - output array of flux through the interface 1909 . numConstants - number of constant parameters 1910 . constants - constant parameters 1911 - ctx - optional user context 1912 1913 Level: intermediate 1914 1915 .seealso: PetscDSGetRiemannSolver() 1916 @*/ 1917 PetscErrorCode PetscDSSetRiemannSolver(PetscDS ds, PetscInt f, 1918 void (*r)(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscInt numConstants, const PetscScalar constants[], PetscScalar flux[], void *ctx)) 1919 { 1920 PetscErrorCode ierr; 1921 1922 PetscFunctionBegin; 1923 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1924 if (r) PetscValidFunction(r, 3); 1925 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 1926 ierr = PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r);CHKERRQ(ierr); 1927 PetscFunctionReturn(0); 1928 } 1929 1930 /*@C 1931 PetscDSGetUpdate - Get the pointwise update function for a given field 1932 1933 Not collective 1934 1935 Input Parameters: 1936 + ds - The PetscDS 1937 - f - The field number 1938 1939 Output Parameters: 1940 . update - update function 1941 1942 Note: The calling sequence for the callback update is given by: 1943 1944 $ update(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1945 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1946 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1947 $ PetscReal t, const PetscReal x[], PetscScalar uNew[]) 1948 1949 + dim - the spatial dimension 1950 . Nf - the number of fields 1951 . uOff - the offset into u[] and u_t[] for each field 1952 . uOff_x - the offset into u_x[] for each field 1953 . u - each field evaluated at the current point 1954 . u_t - the time derivative of each field evaluated at the current point 1955 . u_x - the gradient of each field evaluated at the current point 1956 . aOff - the offset into a[] and a_t[] for each auxiliary field 1957 . aOff_x - the offset into a_x[] for each auxiliary field 1958 . a - each auxiliary field evaluated at the current point 1959 . a_t - the time derivative of each auxiliary field evaluated at the current point 1960 . a_x - the gradient of auxiliary each field evaluated at the current point 1961 . t - current time 1962 . x - coordinates of the current point 1963 - uNew - new value for field at the current point 1964 1965 Level: intermediate 1966 1967 .seealso: PetscDSSetUpdate(), PetscDSSetResidual() 1968 @*/ 1969 PetscErrorCode PetscDSGetUpdate(PetscDS ds, PetscInt f, 1970 void (**update)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1971 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1972 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1973 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar uNew[])) 1974 { 1975 PetscFunctionBegin; 1976 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 1977 if ((f < 0) || (f >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, ds->Nf); 1978 if (update) {PetscValidPointer(update, 3); *update = ds->update[f];} 1979 PetscFunctionReturn(0); 1980 } 1981 1982 /*@C 1983 PetscDSSetUpdate - Set the pointwise update function for a given field 1984 1985 Not collective 1986 1987 Input Parameters: 1988 + ds - The PetscDS 1989 . f - The field number 1990 - update - update function 1991 1992 Note: The calling sequence for the callback update is given by: 1993 1994 $ update(PetscInt dim, PetscInt Nf, PetscInt NfAux, 1995 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 1996 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 1997 $ PetscReal t, const PetscReal x[], PetscScalar uNew[]) 1998 1999 + dim - the spatial dimension 2000 . Nf - the number of fields 2001 . uOff - the offset into u[] and u_t[] for each field 2002 . uOff_x - the offset into u_x[] for each field 2003 . u - each field evaluated at the current point 2004 . u_t - the time derivative of each field evaluated at the current point 2005 . u_x - the gradient of each field evaluated at the current point 2006 . aOff - the offset into a[] and a_t[] for each auxiliary field 2007 . aOff_x - the offset into a_x[] for each auxiliary field 2008 . a - each auxiliary field evaluated at the current point 2009 . a_t - the time derivative of each auxiliary field evaluated at the current point 2010 . a_x - the gradient of auxiliary each field evaluated at the current point 2011 . t - current time 2012 . x - coordinates of the current point 2013 - uNew - new field values at the current point 2014 2015 Level: intermediate 2016 2017 .seealso: PetscDSGetResidual() 2018 @*/ 2019 PetscErrorCode PetscDSSetUpdate(PetscDS ds, PetscInt f, 2020 void (*update)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2021 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2022 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2023 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar uNew[])) 2024 { 2025 PetscErrorCode ierr; 2026 2027 PetscFunctionBegin; 2028 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 2029 if (update) PetscValidFunction(update, 3); 2030 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 2031 ierr = PetscDSEnlarge_Static(ds, f+1);CHKERRQ(ierr); 2032 ds->update[f] = update; 2033 PetscFunctionReturn(0); 2034 } 2035 2036 PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx) 2037 { 2038 PetscFunctionBegin; 2039 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 2040 if ((f < 0) || (f >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, ds->Nf); 2041 PetscValidPointer(ctx, 3); 2042 *(void**)ctx = ds->ctx[f]; 2043 PetscFunctionReturn(0); 2044 } 2045 2046 PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx) 2047 { 2048 PetscErrorCode ierr; 2049 2050 PetscFunctionBegin; 2051 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 2052 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 2053 ierr = PetscDSEnlarge_Static(ds, f+1);CHKERRQ(ierr); 2054 ds->ctx[f] = ctx; 2055 PetscFunctionReturn(0); 2056 } 2057 2058 /*@C 2059 PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field 2060 2061 Not collective 2062 2063 Input Parameters: 2064 + ds - The PetscDS 2065 - f - The test field number 2066 2067 Output Parameters: 2068 + f0 - boundary integrand for the test function term 2069 - f1 - boundary integrand for the test function gradient term 2070 2071 Note: We are using a first order FEM model for the weak form: 2072 2073 \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 2074 2075 The calling sequence for the callbacks f0 and f1 is given by: 2076 2077 $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2078 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2079 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2080 $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[]) 2081 2082 + dim - the spatial dimension 2083 . Nf - the number of fields 2084 . uOff - the offset into u[] and u_t[] for each field 2085 . uOff_x - the offset into u_x[] for each field 2086 . u - each field evaluated at the current point 2087 . u_t - the time derivative of each field evaluated at the current point 2088 . u_x - the gradient of each field evaluated at the current point 2089 . aOff - the offset into a[] and a_t[] for each auxiliary field 2090 . aOff_x - the offset into a_x[] for each auxiliary field 2091 . a - each auxiliary field evaluated at the current point 2092 . a_t - the time derivative of each auxiliary field evaluated at the current point 2093 . a_x - the gradient of auxiliary each field evaluated at the current point 2094 . t - current time 2095 . x - coordinates of the current point 2096 . n - unit normal at the current point 2097 . numConstants - number of constant parameters 2098 . constants - constant parameters 2099 - f0 - output values at the current point 2100 2101 Level: intermediate 2102 2103 .seealso: PetscDSSetBdResidual() 2104 @*/ 2105 PetscErrorCode PetscDSGetBdResidual(PetscDS ds, PetscInt f, 2106 void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2107 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2108 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2109 PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), 2110 void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2111 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2112 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2113 PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[])) 2114 { 2115 PetscBdPointFunc *tmp0, *tmp1; 2116 PetscInt n0, n1; 2117 PetscErrorCode ierr; 2118 2119 PetscFunctionBegin; 2120 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 2121 if ((f < 0) || (f >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, ds->Nf); 2122 ierr = PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1);CHKERRQ(ierr); 2123 *f0 = tmp0 ? tmp0[0] : NULL; 2124 *f1 = tmp1 ? tmp1[0] : NULL; 2125 PetscFunctionReturn(0); 2126 } 2127 2128 /*@C 2129 PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field 2130 2131 Not collective 2132 2133 Input Parameters: 2134 + ds - The PetscDS 2135 . f - The test field number 2136 . f0 - boundary integrand for the test function term 2137 - f1 - boundary integrand for the test function gradient term 2138 2139 Note: We are using a first order FEM model for the weak form: 2140 2141 \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 2142 2143 The calling sequence for the callbacks f0 and f1 is given by: 2144 2145 $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2146 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2147 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2148 $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[]) 2149 2150 + dim - the spatial dimension 2151 . Nf - the number of fields 2152 . uOff - the offset into u[] and u_t[] for each field 2153 . uOff_x - the offset into u_x[] for each field 2154 . u - each field evaluated at the current point 2155 . u_t - the time derivative of each field evaluated at the current point 2156 . u_x - the gradient of each field evaluated at the current point 2157 . aOff - the offset into a[] and a_t[] for each auxiliary field 2158 . aOff_x - the offset into a_x[] for each auxiliary field 2159 . a - each auxiliary field evaluated at the current point 2160 . a_t - the time derivative of each auxiliary field evaluated at the current point 2161 . a_x - the gradient of auxiliary each field evaluated at the current point 2162 . t - current time 2163 . x - coordinates of the current point 2164 . n - unit normal at the current point 2165 . numConstants - number of constant parameters 2166 . constants - constant parameters 2167 - f0 - output values at the current point 2168 2169 Level: intermediate 2170 2171 .seealso: PetscDSGetBdResidual() 2172 @*/ 2173 PetscErrorCode PetscDSSetBdResidual(PetscDS ds, PetscInt f, 2174 void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2175 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2176 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2177 PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), 2178 void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2179 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2180 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2181 PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[])) 2182 { 2183 PetscErrorCode ierr; 2184 2185 PetscFunctionBegin; 2186 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 2187 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 2188 ierr = PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1);CHKERRQ(ierr); 2189 PetscFunctionReturn(0); 2190 } 2191 2192 /*@ 2193 PetscDSHasBdJacobian - Signals that boundary Jacobian functions have been set 2194 2195 Not collective 2196 2197 Input Parameter: 2198 . ds - The PetscDS 2199 2200 Output Parameter: 2201 . hasBdJac - flag that pointwise function for the boundary Jacobian has been set 2202 2203 Level: intermediate 2204 2205 .seealso: PetscDSHasJacobian(), PetscDSSetBdJacobian(), PetscDSGetBdJacobian() 2206 @*/ 2207 PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac) 2208 { 2209 PetscErrorCode ierr; 2210 2211 PetscFunctionBegin; 2212 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 2213 PetscValidBoolPointer(hasBdJac, 2); 2214 ierr = PetscWeakFormHasBdJacobian(ds->wf, hasBdJac);CHKERRQ(ierr); 2215 PetscFunctionReturn(0); 2216 } 2217 2218 /*@C 2219 PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field 2220 2221 Not collective 2222 2223 Input Parameters: 2224 + ds - The PetscDS 2225 . f - The test field number 2226 - g - The field number 2227 2228 Output Parameters: 2229 + g0 - integrand for the test and basis function term 2230 . g1 - integrand for the test function and basis function gradient term 2231 . g2 - integrand for the test function gradient and basis function term 2232 - g3 - integrand for the test function gradient and basis function gradient term 2233 2234 Note: We are using a first order FEM model for the weak form: 2235 2236 \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 2237 2238 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 2239 2240 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2241 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2242 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2243 $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[]) 2244 2245 + dim - the spatial dimension 2246 . Nf - the number of fields 2247 . uOff - the offset into u[] and u_t[] for each field 2248 . uOff_x - the offset into u_x[] for each field 2249 . u - each field evaluated at the current point 2250 . u_t - the time derivative of each field evaluated at the current point 2251 . u_x - the gradient of each field evaluated at the current point 2252 . aOff - the offset into a[] and a_t[] for each auxiliary field 2253 . aOff_x - the offset into a_x[] for each auxiliary field 2254 . a - each auxiliary field evaluated at the current point 2255 . a_t - the time derivative of each auxiliary field evaluated at the current point 2256 . a_x - the gradient of auxiliary each field evaluated at the current point 2257 . t - current time 2258 . u_tShift - the multiplier a for dF/dU_t 2259 . x - coordinates of the current point 2260 . n - normal at the current point 2261 . numConstants - number of constant parameters 2262 . constants - constant parameters 2263 - g0 - output values at the current point 2264 2265 Level: intermediate 2266 2267 .seealso: PetscDSSetBdJacobian() 2268 @*/ 2269 PetscErrorCode PetscDSGetBdJacobian(PetscDS ds, PetscInt f, PetscInt g, 2270 void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2271 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2272 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2273 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), 2274 void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2275 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2276 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2277 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), 2278 void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2279 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2280 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2281 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), 2282 void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2283 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2284 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2285 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])) 2286 { 2287 PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3; 2288 PetscInt n0, n1, n2, n3; 2289 PetscErrorCode ierr; 2290 2291 PetscFunctionBegin; 2292 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 2293 if ((f < 0) || (f >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, ds->Nf); 2294 if ((g < 0) || (g >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, ds->Nf); 2295 ierr = PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3);CHKERRQ(ierr); 2296 *g0 = tmp0 ? tmp0[0] : NULL; 2297 *g1 = tmp1 ? tmp1[0] : NULL; 2298 *g2 = tmp2 ? tmp2[0] : NULL; 2299 *g3 = tmp3 ? tmp3[0] : NULL; 2300 PetscFunctionReturn(0); 2301 } 2302 2303 /*@C 2304 PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field 2305 2306 Not collective 2307 2308 Input Parameters: 2309 + ds - The PetscDS 2310 . f - The test field number 2311 . g - The field number 2312 . g0 - integrand for the test and basis function term 2313 . g1 - integrand for the test function and basis function gradient term 2314 . g2 - integrand for the test function gradient and basis function term 2315 - g3 - integrand for the test function gradient and basis function gradient term 2316 2317 Note: We are using a first order FEM model for the weak form: 2318 2319 \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 2320 2321 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 2322 2323 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2324 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2325 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2326 $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[]) 2327 2328 + dim - the spatial dimension 2329 . Nf - the number of fields 2330 . uOff - the offset into u[] and u_t[] for each field 2331 . uOff_x - the offset into u_x[] for each field 2332 . u - each field evaluated at the current point 2333 . u_t - the time derivative of each field evaluated at the current point 2334 . u_x - the gradient of each field evaluated at the current point 2335 . aOff - the offset into a[] and a_t[] for each auxiliary field 2336 . aOff_x - the offset into a_x[] for each auxiliary field 2337 . a - each auxiliary field evaluated at the current point 2338 . a_t - the time derivative of each auxiliary field evaluated at the current point 2339 . a_x - the gradient of auxiliary each field evaluated at the current point 2340 . t - current time 2341 . u_tShift - the multiplier a for dF/dU_t 2342 . x - coordinates of the current point 2343 . n - normal at the current point 2344 . numConstants - number of constant parameters 2345 . constants - constant parameters 2346 - g0 - output values at the current point 2347 2348 Level: intermediate 2349 2350 .seealso: PetscDSGetBdJacobian() 2351 @*/ 2352 PetscErrorCode PetscDSSetBdJacobian(PetscDS ds, PetscInt f, PetscInt g, 2353 void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2354 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2355 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2356 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), 2357 void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2358 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2359 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2360 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), 2361 void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2362 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2363 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2364 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), 2365 void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2366 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2367 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2368 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])) 2369 { 2370 PetscErrorCode ierr; 2371 2372 PetscFunctionBegin; 2373 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 2374 if (g0) PetscValidFunction(g0, 4); 2375 if (g1) PetscValidFunction(g1, 5); 2376 if (g2) PetscValidFunction(g2, 6); 2377 if (g3) PetscValidFunction(g3, 7); 2378 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 2379 if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g); 2380 ierr = PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3);CHKERRQ(ierr); 2381 PetscFunctionReturn(0); 2382 } 2383 2384 /*@ 2385 PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set 2386 2387 Not collective 2388 2389 Input Parameter: 2390 . ds - The PetscDS 2391 2392 Output Parameter: 2393 . hasBdJac - flag that pointwise function for the boundary Jacobian preconditioner has been set 2394 2395 Level: intermediate 2396 2397 .seealso: PetscDSHasJacobian(), PetscDSSetBdJacobian(), PetscDSGetBdJacobian() 2398 @*/ 2399 PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre) 2400 { 2401 PetscErrorCode ierr; 2402 2403 PetscFunctionBegin; 2404 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 2405 PetscValidBoolPointer(hasBdJacPre, 2); 2406 ierr = PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre);CHKERRQ(ierr); 2407 PetscFunctionReturn(0); 2408 } 2409 2410 /*@C 2411 PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field 2412 2413 Not collective 2414 2415 Input Parameters: 2416 + ds - The PetscDS 2417 . f - The test field number 2418 - g - The field number 2419 2420 Output Parameters: 2421 + g0 - integrand for the test and basis function term 2422 . g1 - integrand for the test function and basis function gradient term 2423 . g2 - integrand for the test function gradient and basis function term 2424 - g3 - integrand for the test function gradient and basis function gradient term 2425 2426 Note: We are using a first order FEM model for the weak form: 2427 2428 \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 2429 2430 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 2431 2432 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2433 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2434 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2435 $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 2436 2437 + dim - the spatial dimension 2438 . Nf - the number of fields 2439 . NfAux - the number of auxiliary fields 2440 . uOff - the offset into u[] and u_t[] for each field 2441 . uOff_x - the offset into u_x[] for each field 2442 . u - each field evaluated at the current point 2443 . u_t - the time derivative of each field evaluated at the current point 2444 . u_x - the gradient of each field evaluated at the current point 2445 . aOff - the offset into a[] and a_t[] for each auxiliary field 2446 . aOff_x - the offset into a_x[] for each auxiliary field 2447 . a - each auxiliary field evaluated at the current point 2448 . a_t - the time derivative of each auxiliary field evaluated at the current point 2449 . a_x - the gradient of auxiliary each field evaluated at the current point 2450 . t - current time 2451 . u_tShift - the multiplier a for dF/dU_t 2452 . x - coordinates of the current point 2453 . n - normal at the current point 2454 . numConstants - number of constant parameters 2455 . constants - constant parameters 2456 - g0 - output values at the current point 2457 2458 This is not yet available in Fortran. 2459 2460 Level: intermediate 2461 2462 .seealso: PetscDSSetBdJacobianPreconditioner() 2463 @*/ 2464 PetscErrorCode PetscDSGetBdJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, 2465 void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2466 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2467 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2468 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), 2469 void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2470 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2471 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2472 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), 2473 void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2474 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2475 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2476 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), 2477 void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2478 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2479 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2480 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])) 2481 { 2482 PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3; 2483 PetscInt n0, n1, n2, n3; 2484 PetscErrorCode ierr; 2485 2486 PetscFunctionBegin; 2487 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 2488 if ((f < 0) || (f >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, ds->Nf); 2489 if ((g < 0) || (g >= ds->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, ds->Nf); 2490 ierr = PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3);CHKERRQ(ierr); 2491 *g0 = tmp0 ? tmp0[0] : NULL; 2492 *g1 = tmp1 ? tmp1[0] : NULL; 2493 *g2 = tmp2 ? tmp2[0] : NULL; 2494 *g3 = tmp3 ? tmp3[0] : NULL; 2495 PetscFunctionReturn(0); 2496 } 2497 2498 /*@C 2499 PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field 2500 2501 Not collective 2502 2503 Input Parameters: 2504 + ds - The PetscDS 2505 . f - The test field number 2506 . g - The field number 2507 . g0 - integrand for the test and basis function term 2508 . g1 - integrand for the test function and basis function gradient term 2509 . g2 - integrand for the test function gradient and basis function term 2510 - g3 - integrand for the test function gradient and basis function gradient term 2511 2512 Note: We are using a first order FEM model for the weak form: 2513 2514 \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 2515 2516 The calling sequence for the callbacks g0, g1, g2 and g3 is given by: 2517 2518 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2519 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2520 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2521 $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 2522 2523 + dim - the spatial dimension 2524 . Nf - the number of fields 2525 . NfAux - the number of auxiliary fields 2526 . uOff - the offset into u[] and u_t[] for each field 2527 . uOff_x - the offset into u_x[] for each field 2528 . u - each field evaluated at the current point 2529 . u_t - the time derivative of each field evaluated at the current point 2530 . u_x - the gradient of each field evaluated at the current point 2531 . aOff - the offset into a[] and a_t[] for each auxiliary field 2532 . aOff_x - the offset into a_x[] for each auxiliary field 2533 . a - each auxiliary field evaluated at the current point 2534 . a_t - the time derivative of each auxiliary field evaluated at the current point 2535 . a_x - the gradient of auxiliary each field evaluated at the current point 2536 . t - current time 2537 . u_tShift - the multiplier a for dF/dU_t 2538 . x - coordinates of the current point 2539 . n - normal at the current point 2540 . numConstants - number of constant parameters 2541 . constants - constant parameters 2542 - g0 - output values at the current point 2543 2544 This is not yet available in Fortran. 2545 2546 Level: intermediate 2547 2548 .seealso: PetscDSGetBdJacobianPreconditioner() 2549 @*/ 2550 PetscErrorCode PetscDSSetBdJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, 2551 void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2552 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2553 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2554 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), 2555 void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2556 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2557 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2558 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), 2559 void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2560 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2561 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2562 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), 2563 void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, 2564 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 2565 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 2566 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])) 2567 { 2568 PetscErrorCode ierr; 2569 2570 PetscFunctionBegin; 2571 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 2572 if (g0) PetscValidFunction(g0, 4); 2573 if (g1) PetscValidFunction(g1, 5); 2574 if (g2) PetscValidFunction(g2, 6); 2575 if (g3) PetscValidFunction(g3, 7); 2576 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 2577 if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g); 2578 ierr = PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3);CHKERRQ(ierr); 2579 PetscFunctionReturn(0); 2580 } 2581 2582 /*@C 2583 PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field 2584 2585 Not collective 2586 2587 Input Parameters: 2588 + prob - The PetscDS 2589 - f - The test field number 2590 2591 Output Parameter: 2592 + exactSol - exact solution for the test field 2593 - exactCtx - exact solution context 2594 2595 Note: The calling sequence for the solution functions is given by: 2596 2597 $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx) 2598 2599 + dim - the spatial dimension 2600 . t - current time 2601 . x - coordinates of the current point 2602 . Nc - the number of field components 2603 . u - the solution field evaluated at the current point 2604 - ctx - a user context 2605 2606 Level: intermediate 2607 2608 .seealso: PetscDSSetExactSolution(), PetscDSGetExactSolutionTimeDerivative() 2609 @*/ 2610 PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx) 2611 { 2612 PetscFunctionBegin; 2613 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2614 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); 2615 if (sol) {PetscValidPointer(sol, 3); *sol = prob->exactSol[f];} 2616 if (ctx) {PetscValidPointer(ctx, 4); *ctx = prob->exactCtx[f];} 2617 PetscFunctionReturn(0); 2618 } 2619 2620 /*@C 2621 PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field 2622 2623 Not collective 2624 2625 Input Parameters: 2626 + prob - The PetscDS 2627 . f - The test field number 2628 . sol - solution function for the test fields 2629 - ctx - solution context or NULL 2630 2631 Note: The calling sequence for solution functions is given by: 2632 2633 $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx) 2634 2635 + dim - the spatial dimension 2636 . t - current time 2637 . x - coordinates of the current point 2638 . Nc - the number of field components 2639 . u - the solution field evaluated at the current point 2640 - ctx - a user context 2641 2642 Level: intermediate 2643 2644 .seealso: PetscDSGetExactSolution() 2645 @*/ 2646 PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx) 2647 { 2648 PetscErrorCode ierr; 2649 2650 PetscFunctionBegin; 2651 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2652 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 2653 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr); 2654 if (sol) {PetscValidFunction(sol, 3); prob->exactSol[f] = sol;} 2655 if (ctx) {PetscValidFunction(ctx, 4); prob->exactCtx[f] = ctx;} 2656 PetscFunctionReturn(0); 2657 } 2658 2659 /*@C 2660 PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field 2661 2662 Not collective 2663 2664 Input Parameters: 2665 + prob - The PetscDS 2666 - f - The test field number 2667 2668 Output Parameter: 2669 + exactSol - time derivative of the exact solution for the test field 2670 - exactCtx - time derivative of the exact solution context 2671 2672 Note: The calling sequence for the solution functions is given by: 2673 2674 $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx) 2675 2676 + dim - the spatial dimension 2677 . t - current time 2678 . x - coordinates of the current point 2679 . Nc - the number of field components 2680 . u - the solution field evaluated at the current point 2681 - ctx - a user context 2682 2683 Level: intermediate 2684 2685 .seealso: PetscDSSetExactSolutionTimeDerivative(), PetscDSGetExactSolution() 2686 @*/ 2687 PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx) 2688 { 2689 PetscFunctionBegin; 2690 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2691 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); 2692 if (sol) {PetscValidPointer(sol, 3); *sol = prob->exactSol_t[f];} 2693 if (ctx) {PetscValidPointer(ctx, 4); *ctx = prob->exactCtx_t[f];} 2694 PetscFunctionReturn(0); 2695 } 2696 2697 /*@C 2698 PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field 2699 2700 Not collective 2701 2702 Input Parameters: 2703 + prob - The PetscDS 2704 . f - The test field number 2705 . sol - time derivative of the solution function for the test fields 2706 - ctx - time derivative of the solution context or NULL 2707 2708 Note: The calling sequence for solution functions is given by: 2709 2710 $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx) 2711 2712 + dim - the spatial dimension 2713 . t - current time 2714 . x - coordinates of the current point 2715 . Nc - the number of field components 2716 . u - the solution field evaluated at the current point 2717 - ctx - a user context 2718 2719 Level: intermediate 2720 2721 .seealso: PetscDSGetExactSolutionTimeDerivative(), PetscDSSetExactSolution() 2722 @*/ 2723 PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx) 2724 { 2725 PetscErrorCode ierr; 2726 2727 PetscFunctionBegin; 2728 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2729 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 2730 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr); 2731 if (sol) {PetscValidFunction(sol, 3); prob->exactSol_t[f] = sol;} 2732 if (ctx) {PetscValidFunction(ctx, 4); prob->exactCtx_t[f] = ctx;} 2733 PetscFunctionReturn(0); 2734 } 2735 2736 /*@C 2737 PetscDSGetConstants - Returns the array of constants passed to point functions 2738 2739 Not collective 2740 2741 Input Parameter: 2742 . prob - The PetscDS object 2743 2744 Output Parameters: 2745 + numConstants - The number of constants 2746 - constants - The array of constants, NULL if there are none 2747 2748 Level: intermediate 2749 2750 .seealso: PetscDSSetConstants(), PetscDSCreate() 2751 @*/ 2752 PetscErrorCode PetscDSGetConstants(PetscDS prob, PetscInt *numConstants, const PetscScalar *constants[]) 2753 { 2754 PetscFunctionBegin; 2755 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2756 if (numConstants) {PetscValidPointer(numConstants, 2); *numConstants = prob->numConstants;} 2757 if (constants) {PetscValidPointer(constants, 3); *constants = prob->constants;} 2758 PetscFunctionReturn(0); 2759 } 2760 2761 /*@C 2762 PetscDSSetConstants - Set the array of constants passed to point functions 2763 2764 Not collective 2765 2766 Input Parameters: 2767 + prob - The PetscDS object 2768 . numConstants - The number of constants 2769 - constants - The array of constants, NULL if there are none 2770 2771 Level: intermediate 2772 2773 .seealso: PetscDSGetConstants(), PetscDSCreate() 2774 @*/ 2775 PetscErrorCode PetscDSSetConstants(PetscDS prob, PetscInt numConstants, PetscScalar constants[]) 2776 { 2777 PetscErrorCode ierr; 2778 2779 PetscFunctionBegin; 2780 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2781 if (numConstants != prob->numConstants) { 2782 ierr = PetscFree(prob->constants);CHKERRQ(ierr); 2783 prob->numConstants = numConstants; 2784 if (prob->numConstants) { 2785 ierr = PetscMalloc1(prob->numConstants, &prob->constants);CHKERRQ(ierr); 2786 } else { 2787 prob->constants = NULL; 2788 } 2789 } 2790 if (prob->numConstants) { 2791 PetscValidPointer(constants, 3); 2792 ierr = PetscArraycpy(prob->constants, constants, prob->numConstants);CHKERRQ(ierr); 2793 } 2794 PetscFunctionReturn(0); 2795 } 2796 2797 /*@ 2798 PetscDSGetFieldIndex - Returns the index of the given field 2799 2800 Not collective 2801 2802 Input Parameters: 2803 + prob - The PetscDS object 2804 - disc - The discretization object 2805 2806 Output Parameter: 2807 . f - The field number 2808 2809 Level: beginner 2810 2811 .seealso: PetscGetDiscretization(), PetscDSGetNumFields(), PetscDSCreate() 2812 @*/ 2813 PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f) 2814 { 2815 PetscInt g; 2816 2817 PetscFunctionBegin; 2818 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2819 PetscValidPointer(f, 3); 2820 *f = -1; 2821 for (g = 0; g < prob->Nf; ++g) {if (disc == prob->disc[g]) break;} 2822 if (g == prob->Nf) SETERRQ(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS."); 2823 *f = g; 2824 PetscFunctionReturn(0); 2825 } 2826 2827 /*@ 2828 PetscDSGetFieldSize - Returns the size of the given field in the full space basis 2829 2830 Not collective 2831 2832 Input Parameters: 2833 + prob - The PetscDS object 2834 - f - The field number 2835 2836 Output Parameter: 2837 . size - The size 2838 2839 Level: beginner 2840 2841 .seealso: PetscDSGetFieldOffset(), PetscDSGetNumFields(), PetscDSCreate() 2842 @*/ 2843 PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size) 2844 { 2845 PetscErrorCode ierr; 2846 2847 PetscFunctionBegin; 2848 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2849 PetscValidPointer(size, 3); 2850 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); 2851 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 2852 *size = prob->Nb[f]; 2853 PetscFunctionReturn(0); 2854 } 2855 2856 /*@ 2857 PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis 2858 2859 Not collective 2860 2861 Input Parameters: 2862 + prob - The PetscDS object 2863 - f - The field number 2864 2865 Output Parameter: 2866 . off - The offset 2867 2868 Level: beginner 2869 2870 .seealso: PetscDSGetFieldSize(), PetscDSGetNumFields(), PetscDSCreate() 2871 @*/ 2872 PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off) 2873 { 2874 PetscInt size, g; 2875 PetscErrorCode ierr; 2876 2877 PetscFunctionBegin; 2878 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2879 PetscValidPointer(off, 3); 2880 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); 2881 *off = 0; 2882 for (g = 0; g < f; ++g) { 2883 ierr = PetscDSGetFieldSize(prob, g, &size);CHKERRQ(ierr); 2884 *off += size; 2885 } 2886 PetscFunctionReturn(0); 2887 } 2888 2889 /*@ 2890 PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point 2891 2892 Not collective 2893 2894 Input Parameter: 2895 . prob - The PetscDS object 2896 2897 Output Parameter: 2898 . dimensions - The number of dimensions 2899 2900 Level: beginner 2901 2902 .seealso: PetscDSGetComponentOffsets(), PetscDSGetNumFields(), PetscDSCreate() 2903 @*/ 2904 PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[]) 2905 { 2906 PetscErrorCode ierr; 2907 2908 PetscFunctionBegin; 2909 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2910 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 2911 PetscValidPointer(dimensions, 2); 2912 *dimensions = prob->Nb; 2913 PetscFunctionReturn(0); 2914 } 2915 2916 /*@ 2917 PetscDSGetComponents - Returns the number of components for each field on an evaluation point 2918 2919 Not collective 2920 2921 Input Parameter: 2922 . prob - The PetscDS object 2923 2924 Output Parameter: 2925 . components - The number of components 2926 2927 Level: beginner 2928 2929 .seealso: PetscDSGetComponentOffsets(), PetscDSGetNumFields(), PetscDSCreate() 2930 @*/ 2931 PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[]) 2932 { 2933 PetscErrorCode ierr; 2934 2935 PetscFunctionBegin; 2936 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2937 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 2938 PetscValidPointer(components, 2); 2939 *components = prob->Nc; 2940 PetscFunctionReturn(0); 2941 } 2942 2943 /*@ 2944 PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point 2945 2946 Not collective 2947 2948 Input Parameters: 2949 + prob - The PetscDS object 2950 - f - The field number 2951 2952 Output Parameter: 2953 . off - The offset 2954 2955 Level: beginner 2956 2957 .seealso: PetscDSGetNumFields(), PetscDSCreate() 2958 @*/ 2959 PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off) 2960 { 2961 PetscErrorCode ierr; 2962 2963 PetscFunctionBegin; 2964 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2965 PetscValidPointer(off, 3); 2966 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); 2967 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 2968 *off = prob->off[f]; 2969 PetscFunctionReturn(0); 2970 } 2971 2972 /*@ 2973 PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point 2974 2975 Not collective 2976 2977 Input Parameter: 2978 . prob - The PetscDS object 2979 2980 Output Parameter: 2981 . offsets - The offsets 2982 2983 Level: beginner 2984 2985 .seealso: PetscDSGetNumFields(), PetscDSCreate() 2986 @*/ 2987 PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[]) 2988 { 2989 PetscErrorCode ierr; 2990 2991 PetscFunctionBegin; 2992 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 2993 PetscValidPointer(offsets, 2); 2994 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 2995 *offsets = prob->off; 2996 PetscFunctionReturn(0); 2997 } 2998 2999 /*@ 3000 PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point 3001 3002 Not collective 3003 3004 Input Parameter: 3005 . prob - The PetscDS object 3006 3007 Output Parameter: 3008 . offsets - The offsets 3009 3010 Level: beginner 3011 3012 .seealso: PetscDSGetNumFields(), PetscDSCreate() 3013 @*/ 3014 PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[]) 3015 { 3016 PetscErrorCode ierr; 3017 3018 PetscFunctionBegin; 3019 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 3020 PetscValidPointer(offsets, 2); 3021 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 3022 *offsets = prob->offDer; 3023 PetscFunctionReturn(0); 3024 } 3025 3026 /*@C 3027 PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization 3028 3029 Not collective 3030 3031 Input Parameter: 3032 . prob - The PetscDS object 3033 3034 Output Parameter: 3035 . T - The basis function and derivatives tabulation at quadrature points for each field 3036 3037 Level: intermediate 3038 3039 .seealso: PetscDSCreate() 3040 @*/ 3041 PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[]) 3042 { 3043 PetscErrorCode ierr; 3044 3045 PetscFunctionBegin; 3046 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 3047 PetscValidPointer(T, 2); 3048 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 3049 *T = prob->T; 3050 PetscFunctionReturn(0); 3051 } 3052 3053 /*@C 3054 PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces 3055 3056 Not collective 3057 3058 Input Parameter: 3059 . prob - The PetscDS object 3060 3061 Output Parameter: 3062 . Tf - The basis function and derviative tabulation on each local face at quadrature points for each and field 3063 3064 Level: intermediate 3065 3066 .seealso: PetscDSGetTabulation(), PetscDSCreate() 3067 @*/ 3068 PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[]) 3069 { 3070 PetscErrorCode ierr; 3071 3072 PetscFunctionBegin; 3073 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 3074 PetscValidPointer(Tf, 2); 3075 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 3076 *Tf = prob->Tf; 3077 PetscFunctionReturn(0); 3078 } 3079 3080 PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x) 3081 { 3082 PetscErrorCode ierr; 3083 3084 PetscFunctionBegin; 3085 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 3086 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 3087 if (u) {PetscValidPointer(u, 2); *u = prob->u;} 3088 if (u_t) {PetscValidPointer(u_t, 3); *u_t = prob->u_t;} 3089 if (u_x) {PetscValidPointer(u_x, 4); *u_x = prob->u_x;} 3090 PetscFunctionReturn(0); 3091 } 3092 3093 PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3) 3094 { 3095 PetscErrorCode ierr; 3096 3097 PetscFunctionBegin; 3098 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 3099 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 3100 if (f0) {PetscValidPointer(f0, 2); *f0 = prob->f0;} 3101 if (f1) {PetscValidPointer(f1, 3); *f1 = prob->f1;} 3102 if (g0) {PetscValidPointer(g0, 4); *g0 = prob->g0;} 3103 if (g1) {PetscValidPointer(g1, 5); *g1 = prob->g1;} 3104 if (g2) {PetscValidPointer(g2, 6); *g2 = prob->g2;} 3105 if (g3) {PetscValidPointer(g3, 7); *g3 = prob->g3;} 3106 PetscFunctionReturn(0); 3107 } 3108 3109 PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal) 3110 { 3111 PetscErrorCode ierr; 3112 3113 PetscFunctionBegin; 3114 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 3115 ierr = PetscDSSetUp(prob);CHKERRQ(ierr); 3116 if (x) {PetscValidPointer(x, 2); *x = prob->x;} 3117 if (basisReal) {PetscValidPointer(basisReal, 3); *basisReal = prob->basisReal;} 3118 if (basisDerReal) {PetscValidPointer(basisDerReal, 4); *basisDerReal = prob->basisDerReal;} 3119 if (testReal) {PetscValidPointer(testReal, 5); *testReal = prob->testReal;} 3120 if (testDerReal) {PetscValidPointer(testDerReal, 6); *testDerReal = prob->testDerReal;} 3121 PetscFunctionReturn(0); 3122 } 3123 3124 /*@C 3125 PetscDSAddBoundary - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions. In FEM, they are acting upon by dual basis functionals to generate FEM coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary integrals should be performaed, using the kernels from PetscDSSetBdResidual(). 3126 3127 Collective on ds 3128 3129 Input Parameters: 3130 + ds - The PetscDS object 3131 . type - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann) 3132 . name - The BC name 3133 . label - The label defining constrained points 3134 . Nv - The number of DMLabel values for constrained points 3135 . values - An array of label values for constrained points 3136 . field - The field to constrain 3137 . Nc - The number of constrained field components (0 will constrain all fields) 3138 . comps - An array of constrained component numbers 3139 . bcFunc - A pointwise function giving boundary values 3140 . bcFunc_t - A pointwise function giving the time derviative of the boundary values, or NULL 3141 - ctx - An optional user context for bcFunc 3142 3143 Output Parameters: 3144 - bd - The boundary number 3145 3146 Options Database Keys: 3147 + -bc_<boundary name> <num> - Overrides the boundary ids 3148 - -bc_<boundary name>_comp <num> - Overrides the boundary components 3149 3150 Note: 3151 Both bcFunc abd bcFunc_t will depend on the boundary condition type. If the type if DM_BC_ESSENTIAL, Then the calling sequence is: 3152 3153 $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[]) 3154 3155 If the type is DM_BC_ESSENTIAL_FIELD or other _FIELD value, then the calling sequence is: 3156 3157 $ bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux, 3158 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 3159 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 3160 $ PetscReal time, const PetscReal x[], PetscScalar bcval[]) 3161 3162 + dim - the spatial dimension 3163 . Nf - the number of fields 3164 . uOff - the offset into u[] and u_t[] for each field 3165 . uOff_x - the offset into u_x[] for each field 3166 . u - each field evaluated at the current point 3167 . u_t - the time derivative of each field evaluated at the current point 3168 . u_x - the gradient of each field evaluated at the current point 3169 . aOff - the offset into a[] and a_t[] for each auxiliary field 3170 . aOff_x - the offset into a_x[] for each auxiliary field 3171 . a - each auxiliary field evaluated at the current point 3172 . a_t - the time derivative of each auxiliary field evaluated at the current point 3173 . a_x - the gradient of auxiliary each field evaluated at the current point 3174 . t - current time 3175 . x - coordinates of the current point 3176 . numConstants - number of constant parameters 3177 . constants - constant parameters 3178 - bcval - output values at the current point 3179 3180 Level: developer 3181 3182 .seealso: PetscDSAddBoundaryByName(), PetscDSGetBoundary(), PetscDSSetResidual(), PetscDSSetBdResidual() 3183 @*/ 3184 PetscErrorCode PetscDSAddBoundary(PetscDS ds, DMBoundaryConditionType type, const char name[], DMLabel label, PetscInt Nv, const PetscInt values[], PetscInt field, PetscInt Nc, const PetscInt comps[], void (*bcFunc)(void), void (*bcFunc_t)(void), void *ctx, PetscInt *bd) 3185 { 3186 DSBoundary head = ds->boundary, b; 3187 PetscInt n = 0; 3188 const char *lname; 3189 PetscErrorCode ierr; 3190 3191 PetscFunctionBegin; 3192 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 3193 PetscValidLogicalCollectiveEnum(ds, type, 2); 3194 PetscValidCharPointer(name, 3); 3195 PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 3196 PetscValidLogicalCollectiveInt(ds, Nv, 5); 3197 PetscValidLogicalCollectiveInt(ds, field, 7); 3198 PetscValidLogicalCollectiveInt(ds, Nc, 8); 3199 if (Nc > 0) { 3200 PetscInt *fcomps; 3201 PetscInt c; 3202 3203 ierr = PetscDSGetComponents(ds, &fcomps);CHKERRQ(ierr); 3204 if (Nc > fcomps[field]) SETERRQ3(PetscObjectComm((PetscObject) ds), PETSC_ERR_ARG_OUTOFRANGE, "Number of constrained components %D > %D components for field %D", Nc, fcomps[field], field); 3205 for (c = 0; c < Nc; ++c) { 3206 if (comps[c] < 0 || comps[c] >= fcomps[field]) SETERRQ4(PetscObjectComm((PetscObject) ds), PETSC_ERR_ARG_OUTOFRANGE, "Constrained component[%D] %D not in [0, %D) components for field %D", c, comps[c], fcomps[field], field); 3207 } 3208 } 3209 ierr = PetscNew(&b);CHKERRQ(ierr); 3210 ierr = PetscStrallocpy(name, (char **) &b->name);CHKERRQ(ierr); 3211 ierr = PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf);CHKERRQ(ierr); 3212 ierr = PetscWeakFormSetNumFields(b->wf, ds->Nf);CHKERRQ(ierr); 3213 ierr = PetscMalloc1(Nv, &b->values);CHKERRQ(ierr); 3214 if (Nv) {ierr = PetscArraycpy(b->values, values, Nv);CHKERRQ(ierr);} 3215 ierr = PetscMalloc1(Nc, &b->comps);CHKERRQ(ierr); 3216 if (Nc) {ierr = PetscArraycpy(b->comps, comps, Nc);CHKERRQ(ierr);} 3217 ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 3218 ierr = PetscStrallocpy(lname, (char **) &b->lname);CHKERRQ(ierr); 3219 b->type = type; 3220 b->label = label; 3221 b->Nv = Nv; 3222 b->field = field; 3223 b->Nc = Nc; 3224 b->func = bcFunc; 3225 b->func_t = bcFunc_t; 3226 b->ctx = ctx; 3227 b->next = NULL; 3228 /* Append to linked list so that we can preserve the order */ 3229 if (!head) ds->boundary = b; 3230 while (head) { 3231 if (!head->next) { 3232 head->next = b; 3233 head = b; 3234 } 3235 head = head->next; 3236 ++n; 3237 } 3238 if (bd) {PetscValidIntPointer(bd, 13); *bd = n;} 3239 PetscFunctionReturn(0); 3240 } 3241 3242 /*@C 3243 PetscDSAddBoundaryByName - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions. In FEM, they are acting upon by dual basis functionals to generate FEM coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary integrals should be performaed, using the kernels from PetscDSSetBdResidual(). 3244 3245 Collective on ds 3246 3247 Input Parameters: 3248 + ds - The PetscDS object 3249 . type - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann) 3250 . name - The BC name 3251 . lname - The naem of the label defining constrained points 3252 . Nv - The number of DMLabel values for constrained points 3253 . values - An array of label values for constrained points 3254 . field - The field to constrain 3255 . Nc - The number of constrained field components (0 will constrain all fields) 3256 . comps - An array of constrained component numbers 3257 . bcFunc - A pointwise function giving boundary values 3258 . bcFunc_t - A pointwise function giving the time derviative of the boundary values, or NULL 3259 - ctx - An optional user context for bcFunc 3260 3261 Output Parameters: 3262 - bd - The boundary number 3263 3264 Options Database Keys: 3265 + -bc_<boundary name> <num> - Overrides the boundary ids 3266 - -bc_<boundary name>_comp <num> - Overrides the boundary components 3267 3268 Note: 3269 This function should only be used with DMForest currently, since labels cannot be defined before the underlygin Plex is built. 3270 3271 Both bcFunc abd bcFunc_t will depend on the boundary condition type. If the type if DM_BC_ESSENTIAL, Then the calling sequence is: 3272 3273 $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[]) 3274 3275 If the type is DM_BC_ESSENTIAL_FIELD or other _FIELD value, then the calling sequence is: 3276 3277 $ bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux, 3278 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 3279 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 3280 $ PetscReal time, const PetscReal x[], PetscScalar bcval[]) 3281 3282 + dim - the spatial dimension 3283 . Nf - the number of fields 3284 . uOff - the offset into u[] and u_t[] for each field 3285 . uOff_x - the offset into u_x[] for each field 3286 . u - each field evaluated at the current point 3287 . u_t - the time derivative of each field evaluated at the current point 3288 . u_x - the gradient of each field evaluated at the current point 3289 . aOff - the offset into a[] and a_t[] for each auxiliary field 3290 . aOff_x - the offset into a_x[] for each auxiliary field 3291 . a - each auxiliary field evaluated at the current point 3292 . a_t - the time derivative of each auxiliary field evaluated at the current point 3293 . a_x - the gradient of auxiliary each field evaluated at the current point 3294 . t - current time 3295 . x - coordinates of the current point 3296 . numConstants - number of constant parameters 3297 . constants - constant parameters 3298 - bcval - output values at the current point 3299 3300 Level: developer 3301 3302 .seealso: PetscDSAddBoundary(), PetscDSGetBoundary(), PetscDSSetResidual(), PetscDSSetBdResidual() 3303 @*/ 3304 PetscErrorCode PetscDSAddBoundaryByName(PetscDS ds, DMBoundaryConditionType type, const char name[], const char lname[], PetscInt Nv, const PetscInt values[], PetscInt field, PetscInt Nc, const PetscInt comps[], void (*bcFunc)(void), void (*bcFunc_t)(void), void *ctx, PetscInt *bd) 3305 { 3306 DSBoundary head = ds->boundary, b; 3307 PetscInt n = 0; 3308 PetscErrorCode ierr; 3309 3310 PetscFunctionBegin; 3311 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 3312 PetscValidLogicalCollectiveEnum(ds, type, 2); 3313 PetscValidCharPointer(name, 3); 3314 PetscValidCharPointer(lname, 4); 3315 PetscValidLogicalCollectiveInt(ds, Nv, 5); 3316 PetscValidLogicalCollectiveInt(ds, field, 7); 3317 PetscValidLogicalCollectiveInt(ds, Nc, 8); 3318 ierr = PetscNew(&b);CHKERRQ(ierr); 3319 ierr = PetscStrallocpy(name, (char **) &b->name);CHKERRQ(ierr); 3320 ierr = PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf);CHKERRQ(ierr); 3321 ierr = PetscWeakFormSetNumFields(b->wf, ds->Nf);CHKERRQ(ierr); 3322 ierr = PetscMalloc1(Nv, &b->values);CHKERRQ(ierr); 3323 if (Nv) {ierr = PetscArraycpy(b->values, values, Nv);CHKERRQ(ierr);} 3324 ierr = PetscMalloc1(Nc, &b->comps);CHKERRQ(ierr); 3325 if (Nc) {ierr = PetscArraycpy(b->comps, comps, Nc);CHKERRQ(ierr);} 3326 ierr = PetscStrallocpy(lname, (char **) &b->lname);CHKERRQ(ierr); 3327 b->type = type; 3328 b->label = NULL; 3329 b->Nv = Nv; 3330 b->field = field; 3331 b->Nc = Nc; 3332 b->func = bcFunc; 3333 b->func_t = bcFunc_t; 3334 b->ctx = ctx; 3335 b->next = NULL; 3336 /* Append to linked list so that we can preserve the order */ 3337 if (!head) ds->boundary = b; 3338 while (head) { 3339 if (!head->next) { 3340 head->next = b; 3341 head = b; 3342 } 3343 head = head->next; 3344 ++n; 3345 } 3346 if (bd) {PetscValidIntPointer(bd, 13); *bd = n;} 3347 PetscFunctionReturn(0); 3348 } 3349 3350 /*@C 3351 PetscDSUpdateBoundary - Change a boundary condition for the model. The pointwise functions are used to provide boundary values for essential boundary conditions. In FEM, they are acting upon by dual basis functionals to generate FEM coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary integrals should be performaed, using the kernels from PetscDSSetBdResidual(). 3352 3353 Input Parameters: 3354 + ds - The PetscDS object 3355 . bd - The boundary condition number 3356 . type - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann) 3357 . name - The BC name 3358 . label - The label defining constrained points 3359 . Nv - The number of DMLabel ids for constrained points 3360 . values - An array of ids for constrained points 3361 . field - The field to constrain 3362 . Nc - The number of constrained field components 3363 . comps - An array of constrained component numbers 3364 . bcFunc - A pointwise function giving boundary values 3365 . bcFunc_t - A pointwise function giving the time derviative of the boundary values, or NULL 3366 - ctx - An optional user context for bcFunc 3367 3368 Note: 3369 The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from PetscDSGetNumBoundary(). See PetscDSAddBoundary() for a description of the calling sequences for the callbacks. 3370 3371 Level: developer 3372 3373 .seealso: PetscDSAddBoundary(), PetscDSGetBoundary(), PetscDSGetNumBoundary() 3374 @*/ 3375 PetscErrorCode PetscDSUpdateBoundary(PetscDS ds, PetscInt bd, DMBoundaryConditionType type, const char name[], DMLabel label, PetscInt Nv, const PetscInt values[], PetscInt field, PetscInt Nc, const PetscInt comps[], void (*bcFunc)(void), void (*bcFunc_t)(void), void *ctx) 3376 { 3377 DSBoundary b = ds->boundary; 3378 PetscInt n = 0; 3379 PetscErrorCode ierr; 3380 3381 PetscFunctionBegin; 3382 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 3383 while (b) { 3384 if (n == bd) break; 3385 b = b->next; 3386 ++n; 3387 } 3388 if (!b) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %d is not in [0, %d)", bd, n); 3389 if (name) { 3390 ierr = PetscFree(b->name);CHKERRQ(ierr); 3391 ierr = PetscStrallocpy(name, (char **) &b->name);CHKERRQ(ierr); 3392 } 3393 b->type = type; 3394 if (label) { 3395 const char *name; 3396 3397 b->label = label; 3398 ierr = PetscFree(b->lname);CHKERRQ(ierr); 3399 ierr = PetscObjectGetName((PetscObject) label, &name);CHKERRQ(ierr); 3400 ierr = PetscStrallocpy(name, (char **) &b->lname);CHKERRQ(ierr); 3401 } 3402 if (Nv >= 0) { 3403 b->Nv = Nv; 3404 ierr = PetscFree(b->values);CHKERRQ(ierr); 3405 ierr = PetscMalloc1(Nv, &b->values);CHKERRQ(ierr); 3406 if (Nv) {ierr = PetscArraycpy(b->values, values, Nv);CHKERRQ(ierr);} 3407 } 3408 if (field >= 0) b->field = field; 3409 if (Nc >= 0) { 3410 b->Nc = Nc; 3411 ierr = PetscFree(b->comps);CHKERRQ(ierr); 3412 ierr = PetscMalloc1(Nc, &b->comps);CHKERRQ(ierr); 3413 if (Nc) {ierr = PetscArraycpy(b->comps, comps, Nc);CHKERRQ(ierr);} 3414 } 3415 if (bcFunc) b->func = bcFunc; 3416 if (bcFunc_t) b->func_t = bcFunc_t; 3417 if (ctx) b->ctx = ctx; 3418 PetscFunctionReturn(0); 3419 } 3420 3421 /*@ 3422 PetscDSGetNumBoundary - Get the number of registered BC 3423 3424 Input Parameters: 3425 . ds - The PetscDS object 3426 3427 Output Parameters: 3428 . numBd - The number of BC 3429 3430 Level: intermediate 3431 3432 .seealso: PetscDSAddBoundary(), PetscDSGetBoundary() 3433 @*/ 3434 PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd) 3435 { 3436 DSBoundary b = ds->boundary; 3437 3438 PetscFunctionBegin; 3439 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 3440 PetscValidPointer(numBd, 2); 3441 *numBd = 0; 3442 while (b) {++(*numBd); b = b->next;} 3443 PetscFunctionReturn(0); 3444 } 3445 3446 /*@C 3447 PetscDSGetBoundary - Gets a boundary condition to the model 3448 3449 Input Parameters: 3450 + ds - The PetscDS object 3451 - bd - The BC number 3452 3453 Output Parameters: 3454 + wf - The PetscWeakForm holding the pointwise functions 3455 . type - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann) 3456 . name - The BC name 3457 . label - The label defining constrained points 3458 . Nv - The number of DMLabel ids for constrained points 3459 . values - An array of ids for constrained points 3460 . field - The field to constrain 3461 . Nc - The number of constrained field components 3462 . comps - An array of constrained component numbers 3463 . bcFunc - A pointwise function giving boundary values 3464 . bcFunc_t - A pointwise function giving the time derviative of the boundary values 3465 - ctx - An optional user context for bcFunc 3466 3467 Options Database Keys: 3468 + -bc_<boundary name> <num> - Overrides the boundary ids 3469 - -bc_<boundary name>_comp <num> - Overrides the boundary components 3470 3471 Level: developer 3472 3473 .seealso: PetscDSAddBoundary() 3474 @*/ 3475 PetscErrorCode PetscDSGetBoundary(PetscDS ds, PetscInt bd, PetscWeakForm *wf, DMBoundaryConditionType *type, const char *name[], DMLabel *label, PetscInt *Nv, const PetscInt *values[], PetscInt *field, PetscInt *Nc, const PetscInt *comps[], void (**func)(void), void (**func_t)(void), void **ctx) 3476 { 3477 DSBoundary b = ds->boundary; 3478 PetscInt n = 0; 3479 3480 PetscFunctionBegin; 3481 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 3482 while (b) { 3483 if (n == bd) break; 3484 b = b->next; 3485 ++n; 3486 } 3487 if (!b) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %d is not in [0, %d)", bd, n); 3488 if (wf) { 3489 PetscValidPointer(wf, 3); 3490 *wf = b->wf; 3491 } 3492 if (type) { 3493 PetscValidPointer(type, 4); 3494 *type = b->type; 3495 } 3496 if (name) { 3497 PetscValidPointer(name, 5); 3498 *name = b->name; 3499 } 3500 if (label) { 3501 PetscValidPointer(label, 6); 3502 *label = b->label; 3503 } 3504 if (Nv) { 3505 PetscValidIntPointer(Nv, 7); 3506 *Nv = b->Nv; 3507 } 3508 if (values) { 3509 PetscValidPointer(values, 8); 3510 *values = b->values; 3511 } 3512 if (field) { 3513 PetscValidIntPointer(field, 9); 3514 *field = b->field; 3515 } 3516 if (Nc) { 3517 PetscValidIntPointer(Nc, 10); 3518 *Nc = b->Nc; 3519 } 3520 if (comps) { 3521 PetscValidPointer(comps, 11); 3522 *comps = b->comps; 3523 } 3524 if (func) { 3525 PetscValidPointer(func, 12); 3526 *func = b->func; 3527 } 3528 if (func_t) { 3529 PetscValidPointer(func_t, 13); 3530 *func_t = b->func_t; 3531 } 3532 if (ctx) { 3533 PetscValidPointer(ctx, 14); 3534 *ctx = b->ctx; 3535 } 3536 PetscFunctionReturn(0); 3537 } 3538 3539 static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew) 3540 { 3541 PetscErrorCode ierr; 3542 3543 PetscFunctionBegin; 3544 ierr = PetscNew(bNew);CHKERRQ(ierr); 3545 ierr = PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf);CHKERRQ(ierr); 3546 ierr = PetscWeakFormCopy(b->wf, (*bNew)->wf);CHKERRQ(ierr); 3547 ierr = PetscStrallocpy(b->name,(char **) &((*bNew)->name));CHKERRQ(ierr); 3548 ierr = PetscStrallocpy(b->lname,(char **) &((*bNew)->lname));CHKERRQ(ierr); 3549 (*bNew)->type = b->type; 3550 (*bNew)->label = b->label; 3551 (*bNew)->Nv = b->Nv; 3552 ierr = PetscMalloc1(b->Nv, &(*bNew)->values);CHKERRQ(ierr); 3553 ierr = PetscArraycpy((*bNew)->values, b->values, b->Nv);CHKERRQ(ierr); 3554 (*bNew)->field = b->field; 3555 (*bNew)->Nc = b->Nc; 3556 ierr = PetscMalloc1(b->Nc, &(*bNew)->comps);CHKERRQ(ierr); 3557 ierr = PetscArraycpy((*bNew)->comps, b->comps, b->Nc);CHKERRQ(ierr); 3558 (*bNew)->func = b->func; 3559 (*bNew)->func_t = b->func_t; 3560 (*bNew)->ctx = b->ctx; 3561 PetscFunctionReturn(0); 3562 } 3563 3564 /*@ 3565 PetscDSCopyBoundary - Copy all boundary condition objects to the new problem 3566 3567 Not collective 3568 3569 Input Parameters: 3570 + ds - The source PetscDS object 3571 . numFields - The number of selected fields, or PETSC_DEFAULT for all fields 3572 - fields - The selected fields, or NULL for all fields 3573 3574 Output Parameter: 3575 . newds - The target PetscDS, now with a copy of the boundary conditions 3576 3577 Level: intermediate 3578 3579 .seealso: PetscDSCopyEquations(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate() 3580 @*/ 3581 PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds) 3582 { 3583 DSBoundary b, *lastnext; 3584 PetscErrorCode ierr; 3585 3586 PetscFunctionBegin; 3587 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 3588 PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 4); 3589 if (ds == newds) PetscFunctionReturn(0); 3590 ierr = PetscDSDestroyBoundary(newds);CHKERRQ(ierr); 3591 lastnext = &(newds->boundary); 3592 for (b = ds->boundary; b; b = b->next) { 3593 DSBoundary bNew; 3594 PetscInt fieldNew = -1; 3595 3596 if (numFields > 0 && fields) { 3597 PetscInt f; 3598 3599 for (f = 0; f < numFields; ++f) if (b->field == fields[f]) break; 3600 if (f == numFields) continue; 3601 fieldNew = f; 3602 } 3603 ierr = DSBoundaryDuplicate_Internal(b, &bNew);CHKERRQ(ierr); 3604 bNew->field = fieldNew < 0 ? b->field : fieldNew; 3605 *lastnext = bNew; 3606 lastnext = &(bNew->next); 3607 } 3608 PetscFunctionReturn(0); 3609 } 3610 3611 /*@ 3612 PetscDSDestroyBoundary - Remove all DMBoundary objects from the PetscDS 3613 3614 Not collective 3615 3616 Input Parameter: 3617 . ds - The PetscDS object 3618 3619 Level: intermediate 3620 3621 .seealso: PetscDSCopyBoundary(), PetscDSCopyEquations() 3622 @*/ 3623 PetscErrorCode PetscDSDestroyBoundary(PetscDS ds) 3624 { 3625 DSBoundary next = ds->boundary; 3626 PetscErrorCode ierr; 3627 3628 PetscFunctionBegin; 3629 while (next) { 3630 DSBoundary b = next; 3631 3632 next = b->next; 3633 ierr = PetscWeakFormDestroy(&b->wf);CHKERRQ(ierr); 3634 ierr = PetscFree(b->name);CHKERRQ(ierr); 3635 ierr = PetscFree(b->lname);CHKERRQ(ierr); 3636 ierr = PetscFree(b->values);CHKERRQ(ierr); 3637 ierr = PetscFree(b->comps);CHKERRQ(ierr); 3638 ierr = PetscFree(b);CHKERRQ(ierr); 3639 } 3640 PetscFunctionReturn(0); 3641 } 3642 3643 /*@ 3644 PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout 3645 3646 Not collective 3647 3648 Input Parameter: 3649 + prob - The PetscDS object 3650 . numFields - Number of new fields 3651 - fields - Old field number for each new field 3652 3653 Output Parameter: 3654 . newprob - The PetscDS copy 3655 3656 Level: intermediate 3657 3658 .seealso: PetscDSSelectEquations(), PetscDSCopyBoundary(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate() 3659 @*/ 3660 PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob) 3661 { 3662 PetscInt Nf, Nfn, fn; 3663 PetscErrorCode ierr; 3664 3665 PetscFunctionBegin; 3666 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 3667 if (fields) PetscValidPointer(fields, 3); 3668 PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4); 3669 ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 3670 ierr = PetscDSGetNumFields(newprob, &Nfn);CHKERRQ(ierr); 3671 numFields = numFields < 0 ? Nf : numFields; 3672 for (fn = 0; fn < numFields; ++fn) { 3673 const PetscInt f = fields ? fields[fn] : fn; 3674 PetscObject disc; 3675 3676 if (f >= Nf) continue; 3677 ierr = PetscDSGetDiscretization(prob, f, &disc);CHKERRQ(ierr); 3678 ierr = PetscDSSetDiscretization(newprob, fn, disc);CHKERRQ(ierr); 3679 } 3680 PetscFunctionReturn(0); 3681 } 3682 3683 /*@ 3684 PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout 3685 3686 Not collective 3687 3688 Input Parameter: 3689 + prob - The PetscDS object 3690 . numFields - Number of new fields 3691 - fields - Old field number for each new field 3692 3693 Output Parameter: 3694 . newprob - The PetscDS copy 3695 3696 Level: intermediate 3697 3698 .seealso: PetscDSSelectDiscretizations(), PetscDSCopyBoundary(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate() 3699 @*/ 3700 PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob) 3701 { 3702 PetscInt Nf, Nfn, fn, gn; 3703 PetscErrorCode ierr; 3704 3705 PetscFunctionBegin; 3706 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 3707 if (fields) PetscValidPointer(fields, 3); 3708 PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4); 3709 ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 3710 ierr = PetscDSGetNumFields(newprob, &Nfn);CHKERRQ(ierr); 3711 if (numFields > Nfn) SETERRQ2(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_SIZ, "Number of fields %D to transfer must not be greater then the total number of fields %D", numFields, Nfn); 3712 for (fn = 0; fn < numFields; ++fn) { 3713 const PetscInt f = fields ? fields[fn] : fn; 3714 PetscPointFunc obj; 3715 PetscPointFunc f0, f1; 3716 PetscBdPointFunc f0Bd, f1Bd; 3717 PetscRiemannFunc r; 3718 3719 if (f >= Nf) continue; 3720 ierr = PetscDSGetObjective(prob, f, &obj);CHKERRQ(ierr); 3721 ierr = PetscDSGetResidual(prob, f, &f0, &f1);CHKERRQ(ierr); 3722 ierr = PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd);CHKERRQ(ierr); 3723 ierr = PetscDSGetRiemannSolver(prob, f, &r);CHKERRQ(ierr); 3724 ierr = PetscDSSetObjective(newprob, fn, obj);CHKERRQ(ierr); 3725 ierr = PetscDSSetResidual(newprob, fn, f0, f1);CHKERRQ(ierr); 3726 ierr = PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd);CHKERRQ(ierr); 3727 ierr = PetscDSSetRiemannSolver(newprob, fn, r);CHKERRQ(ierr); 3728 for (gn = 0; gn < numFields; ++gn) { 3729 const PetscInt g = fields ? fields[gn] : gn; 3730 PetscPointJac g0, g1, g2, g3; 3731 PetscPointJac g0p, g1p, g2p, g3p; 3732 PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd; 3733 3734 if (g >= Nf) continue; 3735 ierr = PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3);CHKERRQ(ierr); 3736 ierr = PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p);CHKERRQ(ierr); 3737 ierr = PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd);CHKERRQ(ierr); 3738 ierr = PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3);CHKERRQ(ierr); 3739 ierr = PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p);CHKERRQ(ierr); 3740 ierr = PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd);CHKERRQ(ierr); 3741 } 3742 } 3743 PetscFunctionReturn(0); 3744 } 3745 3746 /*@ 3747 PetscDSCopyEquations - Copy all pointwise function pointers to the new problem 3748 3749 Not collective 3750 3751 Input Parameter: 3752 . prob - The PetscDS object 3753 3754 Output Parameter: 3755 . newprob - The PetscDS copy 3756 3757 Level: intermediate 3758 3759 .seealso: PetscDSCopyBoundary(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate() 3760 @*/ 3761 PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob) 3762 { 3763 PetscInt Nf, Ng; 3764 PetscErrorCode ierr; 3765 3766 PetscFunctionBegin; 3767 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 3768 PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2); 3769 ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 3770 ierr = PetscDSGetNumFields(newprob, &Ng);CHKERRQ(ierr); 3771 if (Nf != Ng) SETERRQ2(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %D != %D", Nf, Ng); 3772 ierr = PetscDSSelectEquations(prob, Nf, NULL, newprob);CHKERRQ(ierr); 3773 PetscFunctionReturn(0); 3774 } 3775 3776 /*@ 3777 PetscDSCopyConstants - Copy all constants to the new problem 3778 3779 Not collective 3780 3781 Input Parameter: 3782 . prob - The PetscDS object 3783 3784 Output Parameter: 3785 . newprob - The PetscDS copy 3786 3787 Level: intermediate 3788 3789 .seealso: PetscDSCopyBoundary(), PetscDSCopyEquations(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate() 3790 @*/ 3791 PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob) 3792 { 3793 PetscInt Nc; 3794 const PetscScalar *constants; 3795 PetscErrorCode ierr; 3796 3797 PetscFunctionBegin; 3798 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 3799 PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2); 3800 ierr = PetscDSGetConstants(prob, &Nc, &constants);CHKERRQ(ierr); 3801 ierr = PetscDSSetConstants(newprob, Nc, (PetscScalar *) constants);CHKERRQ(ierr); 3802 PetscFunctionReturn(0); 3803 } 3804 3805 /*@ 3806 PetscDSCopyExactSolutions - Copy all exact solutions to the new problem 3807 3808 Not collective 3809 3810 Input Parameter: 3811 . ds - The PetscDS object 3812 3813 Output Parameter: 3814 . newds - The PetscDS copy 3815 3816 Level: intermediate 3817 3818 .seealso: PetscDSCopyBoundary(), PetscDSCopyEquations(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate() 3819 @*/ 3820 PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds) 3821 { 3822 PetscSimplePointFunc sol; 3823 void *ctx; 3824 PetscInt Nf, f; 3825 PetscErrorCode ierr; 3826 3827 PetscFunctionBegin; 3828 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 3829 PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2); 3830 ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 3831 for (f = 0; f < Nf; ++f) { 3832 ierr = PetscDSGetExactSolution(ds, f, &sol, &ctx);CHKERRQ(ierr); 3833 ierr = PetscDSSetExactSolution(newds, f, sol, ctx);CHKERRQ(ierr); 3834 ierr = PetscDSGetExactSolutionTimeDerivative(ds, f, &sol, &ctx);CHKERRQ(ierr); 3835 ierr = PetscDSSetExactSolutionTimeDerivative(newds, f, sol, ctx);CHKERRQ(ierr); 3836 } 3837 PetscFunctionReturn(0); 3838 } 3839 3840 PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob) 3841 { 3842 PetscInt dim, Nf, f; 3843 PetscErrorCode ierr; 3844 3845 PetscFunctionBegin; 3846 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 3847 PetscValidPointer(subprob, 3); 3848 if (height == 0) {*subprob = prob; PetscFunctionReturn(0);} 3849 ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 3850 ierr = PetscDSGetSpatialDimension(prob, &dim);CHKERRQ(ierr); 3851 if (height > dim) SETERRQ2(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_OUTOFRANGE, "DS can only handle height in [0, %D], not %D", dim, height); 3852 if (!prob->subprobs) {ierr = PetscCalloc1(dim, &prob->subprobs);CHKERRQ(ierr);} 3853 if (!prob->subprobs[height-1]) { 3854 PetscInt cdim; 3855 3856 ierr = PetscDSCreate(PetscObjectComm((PetscObject) prob), &prob->subprobs[height-1]);CHKERRQ(ierr); 3857 ierr = PetscDSGetCoordinateDimension(prob, &cdim);CHKERRQ(ierr); 3858 ierr = PetscDSSetCoordinateDimension(prob->subprobs[height-1], cdim);CHKERRQ(ierr); 3859 for (f = 0; f < Nf; ++f) { 3860 PetscFE subfe; 3861 PetscObject obj; 3862 PetscClassId id; 3863 3864 ierr = PetscDSGetDiscretization(prob, f, &obj);CHKERRQ(ierr); 3865 ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 3866 if (id == PETSCFE_CLASSID) {ierr = PetscFEGetHeightSubspace((PetscFE) obj, height, &subfe);CHKERRQ(ierr);} 3867 else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %d", f); 3868 ierr = PetscDSSetDiscretization(prob->subprobs[height-1], f, (PetscObject) subfe);CHKERRQ(ierr); 3869 } 3870 } 3871 *subprob = prob->subprobs[height-1]; 3872 PetscFunctionReturn(0); 3873 } 3874 3875 PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype) 3876 { 3877 PetscObject obj; 3878 PetscClassId id; 3879 PetscInt Nf; 3880 PetscErrorCode ierr; 3881 3882 PetscFunctionBegin; 3883 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 3884 PetscValidPointer(disctype, 3); 3885 *disctype = PETSC_DISC_NONE; 3886 ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 3887 if (f >= Nf) SETERRQ2(PetscObjectComm((PetscObject) ds), PETSC_ERR_ARG_SIZ, "Field %D must be in [0, %D)", f, Nf); 3888 ierr = PetscDSGetDiscretization(ds, f, &obj);CHKERRQ(ierr); 3889 if (obj) { 3890 ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 3891 if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE; 3892 else *disctype = PETSC_DISC_FV; 3893 } 3894 PetscFunctionReturn(0); 3895 } 3896 3897 static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds) 3898 { 3899 PetscErrorCode ierr; 3900 3901 PetscFunctionBegin; 3902 ierr = PetscFree(ds->data);CHKERRQ(ierr); 3903 PetscFunctionReturn(0); 3904 } 3905 3906 static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds) 3907 { 3908 PetscFunctionBegin; 3909 ds->ops->setfromoptions = NULL; 3910 ds->ops->setup = NULL; 3911 ds->ops->view = NULL; 3912 ds->ops->destroy = PetscDSDestroy_Basic; 3913 PetscFunctionReturn(0); 3914 } 3915 3916 /*MC 3917 PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions 3918 3919 Level: intermediate 3920 3921 .seealso: PetscDSType, PetscDSCreate(), PetscDSSetType() 3922 M*/ 3923 3924 PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds) 3925 { 3926 PetscDS_Basic *b; 3927 PetscErrorCode ierr; 3928 3929 PetscFunctionBegin; 3930 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 3931 ierr = PetscNewLog(ds, &b);CHKERRQ(ierr); 3932 ds->data = b; 3933 3934 ierr = PetscDSInitialize_Basic(ds);CHKERRQ(ierr); 3935 PetscFunctionReturn(0); 3936 } 3937