1 #include <petscsnes.h> 2 #include <petsc-private/dmimpl.h> /*I "petscdm.h" I*/ 3 4 PetscClassId DM_CLASSID; 5 PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal; 6 7 #undef __FUNCT__ 8 #define __FUNCT__ "DMCreate" 9 /*@ 10 DMCreate - Creates an empty DM object. The type can then be set with DMSetType(). 11 12 If you never call DMSetType() it will generate an 13 error when you try to use the vector. 14 15 Collective on MPI_Comm 16 17 Input Parameter: 18 . comm - The communicator for the DM object 19 20 Output Parameter: 21 . dm - The DM object 22 23 Level: beginner 24 25 .seealso: DMSetType(), DMDA, DMSLICED, DMCOMPOSITE 26 @*/ 27 PetscErrorCode DMCreate(MPI_Comm comm,DM *dm) 28 { 29 DM v; 30 PetscErrorCode ierr; 31 32 PetscFunctionBegin; 33 PetscValidPointer(dm,2); 34 *dm = PETSC_NULL; 35 #ifndef PETSC_USE_DYNAMIC_LIBRARIES 36 ierr = VecInitializePackage(PETSC_NULL);CHKERRQ(ierr); 37 ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr); 38 ierr = DMInitializePackage(PETSC_NULL);CHKERRQ(ierr); 39 #endif 40 41 ierr = PetscHeaderCreate(v, _p_DM, struct _DMOps, DM_CLASSID, -1, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView);CHKERRQ(ierr); 42 ierr = PetscMemzero(v->ops, sizeof(struct _DMOps));CHKERRQ(ierr); 43 44 45 v->workSize = 0; 46 v->workArray = PETSC_NULL; 47 v->ltogmap = PETSC_NULL; 48 v->ltogmapb = PETSC_NULL; 49 v->bs = 1; 50 v->coloringtype = IS_COLORING_GLOBAL; 51 v->lf = PETSC_NULL; 52 v->lj = PETSC_NULL; 53 ierr = PetscSFCreate(comm, &v->sf);CHKERRQ(ierr); 54 ierr = PetscSFCreate(comm, &v->defaultSF);CHKERRQ(ierr); 55 v->defaultSection = PETSC_NULL; 56 v->defaultGlobalSection = PETSC_NULL; 57 58 *dm = v; 59 PetscFunctionReturn(0); 60 } 61 62 63 #undef __FUNCT__ 64 #define __FUNCT__ "DMSetVecType" 65 /*@C 66 DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector() 67 68 Logically Collective on DMDA 69 70 Input Parameter: 71 + da - initial distributed array 72 . ctype - the vector type, currently either VECSTANDARD or VECCUSP 73 74 Options Database: 75 . -dm_vec_type ctype 76 77 Level: intermediate 78 79 .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDA, DMDAInterpolationType, VecType 80 @*/ 81 PetscErrorCode DMSetVecType(DM da,const VecType ctype) 82 { 83 PetscErrorCode ierr; 84 85 PetscFunctionBegin; 86 PetscValidHeaderSpecific(da,DM_CLASSID,1); 87 ierr = PetscFree(da->vectype);CHKERRQ(ierr); 88 ierr = PetscStrallocpy(ctype,&da->vectype);CHKERRQ(ierr); 89 PetscFunctionReturn(0); 90 } 91 92 #undef __FUNCT__ 93 #define __FUNCT__ "DMSetMatType" 94 /*@C 95 DMSetMatType - Sets the type of matrix created with DMCreateMatrix() 96 97 Logically Collective on DM 98 99 Input Parameter: 100 + dm - the DM context 101 . ctype - the matrix type 102 103 Options Database: 104 . -dm_mat_type ctype 105 106 Level: intermediate 107 108 .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType 109 @*/ 110 PetscErrorCode DMSetMatType(DM dm,const MatType ctype) 111 { 112 PetscErrorCode ierr; 113 PetscFunctionBegin; 114 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 115 ierr = PetscFree(dm->mattype);CHKERRQ(ierr); 116 ierr = PetscStrallocpy(ctype,&dm->mattype);CHKERRQ(ierr); 117 PetscFunctionReturn(0); 118 } 119 120 #undef __FUNCT__ 121 #define __FUNCT__ "DMSetOptionsPrefix" 122 /*@C 123 DMSetOptionsPrefix - Sets the prefix used for searching for all 124 DMDA options in the database. 125 126 Logically Collective on DMDA 127 128 Input Parameter: 129 + da - the DMDA context 130 - prefix - the prefix to prepend to all option names 131 132 Notes: 133 A hyphen (-) must NOT be given at the beginning of the prefix name. 134 The first character of all runtime options is AUTOMATICALLY the hyphen. 135 136 Level: advanced 137 138 .keywords: DMDA, set, options, prefix, database 139 140 .seealso: DMSetFromOptions() 141 @*/ 142 PetscErrorCode DMSetOptionsPrefix(DM dm,const char prefix[]) 143 { 144 PetscErrorCode ierr; 145 146 PetscFunctionBegin; 147 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 148 ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 149 PetscFunctionReturn(0); 150 } 151 152 #undef __FUNCT__ 153 #define __FUNCT__ "DMDestroy" 154 /*@ 155 DMDestroy - Destroys a vector packer or DMDA. 156 157 Collective on DM 158 159 Input Parameter: 160 . dm - the DM object to destroy 161 162 Level: developer 163 164 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 165 166 @*/ 167 PetscErrorCode DMDestroy(DM *dm) 168 { 169 PetscInt i, cnt = 0; 170 DMNamedVecLink nlink,nnext; 171 PetscErrorCode ierr; 172 173 PetscFunctionBegin; 174 if (!*dm) PetscFunctionReturn(0); 175 PetscValidHeaderSpecific((*dm),DM_CLASSID,1); 176 177 /* count all the circular references of DM and its contained Vecs */ 178 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 179 if ((*dm)->localin[i]) {cnt++;} 180 if ((*dm)->globalin[i]) {cnt++;} 181 } 182 for (nlink=(*dm)->namedglobal; nlink; nlink=nlink->next) cnt++; 183 if ((*dm)->x) { 184 PetscObject obj; 185 ierr = PetscObjectQuery((PetscObject)(*dm)->x,"DM",&obj);CHKERRQ(ierr); 186 if (obj == (PetscObject)*dm) cnt++; 187 } 188 189 if (--((PetscObject)(*dm))->refct - cnt > 0) {*dm = 0; PetscFunctionReturn(0);} 190 /* 191 Need this test because the dm references the vectors that 192 reference the dm, so destroying the dm calls destroy on the 193 vectors that cause another destroy on the dm 194 */ 195 if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0); 196 ((PetscObject) (*dm))->refct = 0; 197 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 198 if ((*dm)->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Destroying a DM that has a local vector obtained with DMGetLocalVector()"); 199 ierr = VecDestroy(&(*dm)->localin[i]);CHKERRQ(ierr); 200 } 201 for (nlink=(*dm)->namedglobal; nlink; nlink=nnext) { /* Destroy the named vectors */ 202 nnext = nlink->next; 203 if (nlink->status != DMVEC_STATUS_IN) SETERRQ1(((PetscObject)*dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"DM still has Vec named '%s' checked out",nlink->name); 204 ierr = PetscFree(nlink->name);CHKERRQ(ierr); 205 ierr = VecDestroy(&nlink->X);CHKERRQ(ierr); 206 ierr = PetscFree(nlink);CHKERRQ(ierr); 207 } 208 (*dm)->namedglobal = PETSC_NULL; 209 210 /* Destroy the list of hooks */ 211 { 212 DMCoarsenHookLink link,next; 213 for (link=(*dm)->coarsenhook; link; link=next) { 214 next = link->next; 215 ierr = PetscFree(link);CHKERRQ(ierr); 216 } 217 (*dm)->coarsenhook = PETSC_NULL; 218 } 219 { 220 DMRefineHookLink link,next; 221 for (link=(*dm)->refinehook; link; link=next) { 222 next = link->next; 223 ierr = PetscFree(link);CHKERRQ(ierr); 224 } 225 (*dm)->refinehook = PETSC_NULL; 226 } 227 228 if ((*dm)->ctx && (*dm)->ctxdestroy) { 229 ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr); 230 } 231 ierr = VecDestroy(&(*dm)->x);CHKERRQ(ierr); 232 ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr); 233 ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr); 234 ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr); 235 ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmapb);CHKERRQ(ierr); 236 ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr); 237 ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr); 238 ierr = PetscFree((*dm)->workArray);CHKERRQ(ierr); 239 240 ierr = PetscSectionDestroy(&(*dm)->defaultSection);CHKERRQ(ierr); 241 ierr = PetscSectionDestroy(&(*dm)->defaultGlobalSection);CHKERRQ(ierr); 242 ierr = PetscSFDestroy(&(*dm)->sf);CHKERRQ(ierr); 243 ierr = PetscSFDestroy(&(*dm)->defaultSF);CHKERRQ(ierr); 244 /* if memory was published with AMS then destroy it */ 245 ierr = PetscObjectDepublish(*dm);CHKERRQ(ierr); 246 247 ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr); 248 ierr = PetscFree((*dm)->data);CHKERRQ(ierr); 249 ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr); 250 PetscFunctionReturn(0); 251 } 252 253 #undef __FUNCT__ 254 #define __FUNCT__ "DMSetUp" 255 /*@ 256 DMSetUp - sets up the data structures inside a DM object 257 258 Collective on DM 259 260 Input Parameter: 261 . dm - the DM object to setup 262 263 Level: developer 264 265 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 266 267 @*/ 268 PetscErrorCode DMSetUp(DM dm) 269 { 270 PetscErrorCode ierr; 271 272 PetscFunctionBegin; 273 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 274 if (dm->setupcalled) PetscFunctionReturn(0); 275 if (dm->ops->setup) { 276 ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr); 277 } 278 dm->setupcalled = PETSC_TRUE; 279 PetscFunctionReturn(0); 280 } 281 282 #undef __FUNCT__ 283 #define __FUNCT__ "DMSetFromOptions" 284 /*@ 285 DMSetFromOptions - sets parameters in a DM from the options database 286 287 Collective on DM 288 289 Input Parameter: 290 . dm - the DM object to set options for 291 292 Options Database: 293 + -dm_preallocate_only: Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros 294 . -dm_vec_type <type> type of vector to create inside DM 295 . -dm_mat_type <type> type of matrix to create inside DM 296 - -dm_coloring_type <global or ghosted> 297 298 Level: developer 299 300 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 301 302 @*/ 303 PetscErrorCode DMSetFromOptions(DM dm) 304 { 305 PetscBool flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg; 306 PetscErrorCode ierr; 307 char typeName[256] = MATAIJ; 308 309 PetscFunctionBegin; 310 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 311 ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr); 312 ierr = PetscOptionsBool("-dm_view", "Information on DM", "DMView", flg1, &flg1, PETSC_NULL);CHKERRQ(ierr); 313 ierr = PetscOptionsBool("-dm_view_detail", "Exhaustive mesh description", "DMView", flg2, &flg2, PETSC_NULL);CHKERRQ(ierr); 314 ierr = PetscOptionsBool("-dm_view_vtk", "Output mesh in VTK format", "DMView", flg3, &flg3, PETSC_NULL);CHKERRQ(ierr); 315 ierr = PetscOptionsBool("-dm_view_latex", "Output mesh in LaTeX TikZ format", "DMView", flg4, &flg4, PETSC_NULL);CHKERRQ(ierr); 316 ierr = PetscOptionsBool("-dm_preallocate_only","only preallocate matrix, but do not set column indices","DMSetMatrixPreallocateOnly",dm->prealloc_only,&dm->prealloc_only,PETSC_NULL);CHKERRQ(ierr); 317 ierr = PetscOptionsList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr); 318 if (flg) { 319 ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr); 320 } 321 ierr = PetscOptionsList("-dm_mat_type","Matrix type used for created matrices","DMSetMatType",MatList,dm->mattype?dm->mattype:typeName,typeName,sizeof typeName,&flg);CHKERRQ(ierr); 322 if (flg) { 323 ierr = DMSetMatType(dm,typeName);CHKERRQ(ierr); 324 } 325 ierr = PetscOptionsEnum("-dm_is_coloring_type","Global or local coloring of Jacobian","ISColoringType",ISColoringTypes,(PetscEnum)dm->coloringtype,(PetscEnum*)&dm->coloringtype,PETSC_NULL);CHKERRQ(ierr); 326 if (dm->ops->setfromoptions) { 327 ierr = (*dm->ops->setfromoptions)(dm);CHKERRQ(ierr); 328 } 329 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 330 ierr = PetscObjectProcessOptionsHandlers((PetscObject) dm);CHKERRQ(ierr); 331 ierr = PetscOptionsEnd();CHKERRQ(ierr); 332 if (flg1) { 333 ierr = DMView(dm, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 334 } 335 if (flg2) { 336 PetscViewer viewer; 337 338 ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr); 339 ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr); 340 ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr); 341 ierr = DMView(dm, viewer);CHKERRQ(ierr); 342 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 343 } 344 if (flg3) { 345 PetscViewer viewer; 346 347 ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr); 348 ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr); 349 ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr); 350 ierr = PetscViewerFileSetName(viewer, "mesh.vtk");CHKERRQ(ierr); 351 ierr = DMView(dm, viewer);CHKERRQ(ierr); 352 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 353 } 354 if (flg4) { 355 PetscViewer viewer; 356 357 ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr); 358 ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr); 359 ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_LATEX);CHKERRQ(ierr); 360 ierr = PetscViewerFileSetName(viewer, "mesh.tex");CHKERRQ(ierr); 361 ierr = DMView(dm, viewer);CHKERRQ(ierr); 362 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 363 } 364 PetscFunctionReturn(0); 365 } 366 367 #undef __FUNCT__ 368 #define __FUNCT__ "DMView" 369 /*@C 370 DMView - Views a vector packer or DMDA. 371 372 Collective on DM 373 374 Input Parameter: 375 + dm - the DM object to view 376 - v - the viewer 377 378 Level: developer 379 380 .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 381 382 @*/ 383 PetscErrorCode DMView(DM dm,PetscViewer v) 384 { 385 PetscErrorCode ierr; 386 387 PetscFunctionBegin; 388 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 389 if (!v) { 390 ierr = PetscViewerASCIIGetStdout(((PetscObject)dm)->comm,&v);CHKERRQ(ierr); 391 } 392 if (dm->ops->view) { 393 ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr); 394 } 395 PetscFunctionReturn(0); 396 } 397 398 #undef __FUNCT__ 399 #define __FUNCT__ "DMCreateGlobalVector" 400 /*@ 401 DMCreateGlobalVector - Creates a global vector from a DMDA or DMComposite object 402 403 Collective on DM 404 405 Input Parameter: 406 . dm - the DM object 407 408 Output Parameter: 409 . vec - the global vector 410 411 Level: beginner 412 413 .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 414 415 @*/ 416 PetscErrorCode DMCreateGlobalVector(DM dm,Vec *vec) 417 { 418 PetscErrorCode ierr; 419 420 PetscFunctionBegin; 421 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 422 if (dm->defaultSection) { 423 PetscSection gSection; 424 PetscInt localSize; 425 426 ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr); 427 ierr = PetscSectionGetConstrainedStorageSize(dm->defaultGlobalSection, &localSize);CHKERRQ(ierr); 428 ierr = VecCreate(((PetscObject) dm)->comm, vec);CHKERRQ(ierr); 429 ierr = VecSetSizes(*vec, localSize, PETSC_DETERMINE);CHKERRQ(ierr); 430 /* ierr = VecSetType(*vec, dm->vectype);CHKERRQ(ierr); */ 431 ierr = VecSetFromOptions(*vec);CHKERRQ(ierr); 432 ierr = PetscObjectCompose((PetscObject) *vec, "DM", (PetscObject) dm);CHKERRQ(ierr); 433 /* ierr = VecSetLocalToGlobalMapping(*vec, dm->ltogmap);CHKERRQ(ierr); */ 434 /* ierr = VecSetLocalToGlobalMappingBlock(*vec, dm->ltogmapb);CHKERRQ(ierr); */ 435 /* ierr = VecSetOperation(*vec, VECOP_DUPLICATE, (void(*)(void)) VecDuplicate_MPI_DM);CHKERRQ(ierr); */ 436 } else { 437 ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr); 438 } 439 PetscFunctionReturn(0); 440 } 441 442 #undef __FUNCT__ 443 #define __FUNCT__ "DMCreateLocalVector" 444 /*@ 445 DMCreateLocalVector - Creates a local vector from a DMDA or DMComposite object 446 447 Not Collective 448 449 Input Parameter: 450 . dm - the DM object 451 452 Output Parameter: 453 . vec - the local vector 454 455 Level: beginner 456 457 .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 458 459 @*/ 460 PetscErrorCode DMCreateLocalVector(DM dm,Vec *vec) 461 { 462 PetscErrorCode ierr; 463 464 PetscFunctionBegin; 465 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 466 if (dm->defaultSection) { 467 PetscInt localSize; 468 469 ierr = PetscSectionGetStorageSize(dm->defaultSection, &localSize);CHKERRQ(ierr); 470 ierr = VecCreate(PETSC_COMM_SELF, vec);CHKERRQ(ierr); 471 ierr = VecSetSizes(*vec, localSize, localSize);CHKERRQ(ierr); 472 ierr = VecSetFromOptions(*vec);CHKERRQ(ierr); 473 ierr = PetscObjectCompose((PetscObject) *vec, "DM", (PetscObject) dm);CHKERRQ(ierr); 474 } else { 475 ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr); 476 } 477 PetscFunctionReturn(0); 478 } 479 480 #undef __FUNCT__ 481 #define __FUNCT__ "DMGetLocalToGlobalMapping" 482 /*@ 483 DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM. 484 485 Collective on DM 486 487 Input Parameter: 488 . dm - the DM that provides the mapping 489 490 Output Parameter: 491 . ltog - the mapping 492 493 Level: intermediate 494 495 Notes: 496 This mapping can then be used by VecSetLocalToGlobalMapping() or 497 MatSetLocalToGlobalMapping(). 498 499 .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMappingBlock() 500 @*/ 501 PetscErrorCode DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog) 502 { 503 PetscErrorCode ierr; 504 505 PetscFunctionBegin; 506 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 507 PetscValidPointer(ltog,2); 508 if (!dm->ltogmap) { 509 PetscSection section, sectionGlobal; 510 511 ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 512 if (section) { 513 PetscInt *ltog; 514 PetscInt pStart, pEnd, size, p, l; 515 516 ierr = DMGetDefaultGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 517 ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 518 ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 519 ierr = PetscMalloc(size * sizeof(PetscInt), <og);CHKERRQ(ierr); /* We want the local+overlap size */ 520 for(p = pStart, l = 0; p < pEnd; ++p) { 521 PetscInt dof, off, c; 522 523 /* Should probably use constrained dofs */ 524 ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 525 ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr); 526 for(c = 0; c < dof; ++c, ++l) { 527 ltog[l] = off+c; 528 } 529 } 530 ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF, size, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr); 531 ierr = PetscLogObjectParent(dm, dm->ltogmap);CHKERRQ(ierr); 532 } else { 533 if (!dm->ops->createlocaltoglobalmapping) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMapping"); 534 ierr = (*dm->ops->createlocaltoglobalmapping)(dm);CHKERRQ(ierr); 535 } 536 } 537 *ltog = dm->ltogmap; 538 PetscFunctionReturn(0); 539 } 540 541 #undef __FUNCT__ 542 #define __FUNCT__ "DMGetLocalToGlobalMappingBlock" 543 /*@ 544 DMGetLocalToGlobalMappingBlock - Accesses the blocked local-to-global mapping in a DM. 545 546 Collective on DM 547 548 Input Parameter: 549 . da - the distributed array that provides the mapping 550 551 Output Parameter: 552 . ltog - the block mapping 553 554 Level: intermediate 555 556 Notes: 557 This mapping can then be used by VecSetLocalToGlobalMappingBlock() or 558 MatSetLocalToGlobalMappingBlock(). 559 560 .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMapping(), DMGetBlockSize(), VecSetBlockSize(), MatSetBlockSize() 561 @*/ 562 PetscErrorCode DMGetLocalToGlobalMappingBlock(DM dm,ISLocalToGlobalMapping *ltog) 563 { 564 PetscErrorCode ierr; 565 566 PetscFunctionBegin; 567 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 568 PetscValidPointer(ltog,2); 569 if (!dm->ltogmapb) { 570 PetscInt bs; 571 ierr = DMGetBlockSize(dm,&bs);CHKERRQ(ierr); 572 if (bs > 1) { 573 if (!dm->ops->createlocaltoglobalmappingblock) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMappingBlock"); 574 ierr = (*dm->ops->createlocaltoglobalmappingblock)(dm);CHKERRQ(ierr); 575 } else { 576 ierr = DMGetLocalToGlobalMapping(dm,&dm->ltogmapb);CHKERRQ(ierr); 577 ierr = PetscObjectReference((PetscObject)dm->ltogmapb);CHKERRQ(ierr); 578 } 579 } 580 *ltog = dm->ltogmapb; 581 PetscFunctionReturn(0); 582 } 583 584 #undef __FUNCT__ 585 #define __FUNCT__ "DMGetBlockSize" 586 /*@ 587 DMGetBlockSize - Gets the inherent block size associated with a DM 588 589 Not Collective 590 591 Input Parameter: 592 . dm - the DM with block structure 593 594 Output Parameter: 595 . bs - the block size, 1 implies no exploitable block structure 596 597 Level: intermediate 598 599 .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMappingBlock() 600 @*/ 601 PetscErrorCode DMGetBlockSize(DM dm,PetscInt *bs) 602 { 603 PetscFunctionBegin; 604 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 605 PetscValidPointer(bs,2); 606 if (dm->bs < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"DM does not have enough information to provide a block size yet"); 607 *bs = dm->bs; 608 PetscFunctionReturn(0); 609 } 610 611 #undef __FUNCT__ 612 #define __FUNCT__ "DMCreateInterpolation" 613 /*@ 614 DMCreateInterpolation - Gets interpolation matrix between two DMDA or DMComposite objects 615 616 Collective on DM 617 618 Input Parameter: 619 + dm1 - the DM object 620 - dm2 - the second, finer DM object 621 622 Output Parameter: 623 + mat - the interpolation 624 - vec - the scaling (optional) 625 626 Level: developer 627 628 Notes: For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by 629 DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation. 630 631 For DMDA objects you can use this interpolation (more precisely the interpolation from the DMDAGetCoordinateDA()) to interpolate the mesh coordinate vectors 632 EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic. 633 634 635 .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen() 636 637 @*/ 638 PetscErrorCode DMCreateInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec) 639 { 640 PetscErrorCode ierr; 641 642 PetscFunctionBegin; 643 PetscValidHeaderSpecific(dm1,DM_CLASSID,1); 644 PetscValidHeaderSpecific(dm2,DM_CLASSID,2); 645 ierr = (*dm1->ops->createinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr); 646 PetscFunctionReturn(0); 647 } 648 649 #undef __FUNCT__ 650 #define __FUNCT__ "DMCreateInjection" 651 /*@ 652 DMCreateInjection - Gets injection matrix between two DMDA or DMComposite objects 653 654 Collective on DM 655 656 Input Parameter: 657 + dm1 - the DM object 658 - dm2 - the second, finer DM object 659 660 Output Parameter: 661 . ctx - the injection 662 663 Level: developer 664 665 Notes: For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by 666 DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection. 667 668 .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation() 669 670 @*/ 671 PetscErrorCode DMCreateInjection(DM dm1,DM dm2,VecScatter *ctx) 672 { 673 PetscErrorCode ierr; 674 675 PetscFunctionBegin; 676 PetscValidHeaderSpecific(dm1,DM_CLASSID,1); 677 PetscValidHeaderSpecific(dm2,DM_CLASSID,2); 678 ierr = (*dm1->ops->getinjection)(dm1,dm2,ctx);CHKERRQ(ierr); 679 PetscFunctionReturn(0); 680 } 681 682 #undef __FUNCT__ 683 #define __FUNCT__ "DMCreateColoring" 684 /*@C 685 DMCreateColoring - Gets coloring for a DMDA or DMComposite 686 687 Collective on DM 688 689 Input Parameter: 690 + dm - the DM object 691 . ctype - IS_COLORING_GHOSTED or IS_COLORING_GLOBAL 692 - matype - either MATAIJ or MATBAIJ 693 694 Output Parameter: 695 . coloring - the coloring 696 697 Level: developer 698 699 .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix() 700 701 @*/ 702 PetscErrorCode DMCreateColoring(DM dm,ISColoringType ctype,const MatType mtype,ISColoring *coloring) 703 { 704 PetscErrorCode ierr; 705 706 PetscFunctionBegin; 707 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 708 if (!dm->ops->getcoloring) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No coloring for this type of DM yet"); 709 ierr = (*dm->ops->getcoloring)(dm,ctype,mtype,coloring);CHKERRQ(ierr); 710 PetscFunctionReturn(0); 711 } 712 713 #undef __FUNCT__ 714 #define __FUNCT__ "DMCreateMatrix" 715 /*@C 716 DMCreateMatrix - Gets empty Jacobian for a DMDA or DMComposite 717 718 Collective on DM 719 720 Input Parameter: 721 + dm - the DM object 722 - mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, or 723 any type which inherits from one of these (such as MATAIJ) 724 725 Output Parameter: 726 . mat - the empty Jacobian 727 728 Level: beginner 729 730 Notes: This properly preallocates the number of nonzeros in the sparse matrix so you 731 do not need to do it yourself. 732 733 By default it also sets the nonzero structure and puts in the zero entries. To prevent setting 734 the nonzero pattern call DMDASetMatPreallocateOnly() 735 736 For structured grid problems, when you call MatView() on this matrix it is displayed using the global natural ordering, NOT in the ordering used 737 internally by PETSc. 738 739 For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires 740 the indices for the global numbering for DMDAs which is complicated. 741 742 .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 743 744 @*/ 745 PetscErrorCode DMCreateMatrix(DM dm,const MatType mtype,Mat *mat) 746 { 747 PetscErrorCode ierr; 748 749 PetscFunctionBegin; 750 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 751 #ifndef PETSC_USE_DYNAMIC_LIBRARIES 752 ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr); 753 #endif 754 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 755 PetscValidPointer(mat,3); 756 if (dm->mattype) { 757 ierr = (*dm->ops->creatematrix)(dm,dm->mattype,mat);CHKERRQ(ierr); 758 } else { 759 ierr = (*dm->ops->creatematrix)(dm,mtype,mat);CHKERRQ(ierr); 760 } 761 PetscFunctionReturn(0); 762 } 763 764 #undef __FUNCT__ 765 #define __FUNCT__ "DMSetMatrixPreallocateOnly" 766 /*@ 767 DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly 768 preallocated but the nonzero structure and zero values will not be set. 769 770 Logically Collective on DMDA 771 772 Input Parameter: 773 + dm - the DM 774 - only - PETSC_TRUE if only want preallocation 775 776 Level: developer 777 .seealso DMCreateMatrix() 778 @*/ 779 PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only) 780 { 781 PetscFunctionBegin; 782 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 783 dm->prealloc_only = only; 784 PetscFunctionReturn(0); 785 } 786 787 #undef __FUNCT__ 788 #define __FUNCT__ "DMGetWorkArray" 789 /*@C 790 DMGetWorkArray - Gets a work array guaranteed to be at least the input size 791 792 Not Collective 793 794 Input Parameters: 795 + dm - the DM object 796 - size - The minium size 797 798 Output Parameter: 799 . array - the work array 800 801 Level: developer 802 803 .seealso DMDestroy(), DMCreate() 804 @*/ 805 PetscErrorCode DMGetWorkArray(DM dm,PetscInt size,PetscScalar **array) 806 { 807 PetscErrorCode ierr; 808 809 PetscFunctionBegin; 810 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 811 PetscValidPointer(array,3); 812 if (size > dm->workSize) { 813 dm->workSize = size; 814 ierr = PetscFree(dm->workArray);CHKERRQ(ierr); 815 ierr = PetscMalloc(dm->workSize * sizeof(PetscScalar), &dm->workArray);CHKERRQ(ierr); 816 } 817 *array = dm->workArray; 818 PetscFunctionReturn(0); 819 } 820 821 822 #undef __FUNCT__ 823 #define __FUNCT__ "DMCreateFieldIS" 824 /*@C 825 DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field 826 827 Not collective 828 829 Input Parameter: 830 . dm - the DM object 831 832 Output Parameters: 833 + numFields - The number of fields (or PETSC_NULL if not requested) 834 . fieldNames - The name for each field (or PETSC_NULL if not requested) 835 - fields - The global indices for each field (or PETSC_NULL if not requested) 836 837 Level: intermediate 838 839 Notes: 840 The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 841 PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with 842 PetscFree(). 843 844 .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 845 @*/ 846 PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields) 847 { 848 PetscSection section, sectionGlobal; 849 PetscErrorCode ierr; 850 851 PetscFunctionBegin; 852 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 853 if (numFields) { 854 PetscValidPointer(numFields,2); 855 *numFields = 0; 856 } 857 if (fieldNames) { 858 PetscValidPointer(fieldNames,3); 859 *fieldNames = PETSC_NULL; 860 } 861 if (fields) { 862 PetscValidPointer(fields,4); 863 *fields = PETSC_NULL; 864 } 865 ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 866 if (section) { 867 PetscInt *fieldSizes, **fieldIndices; 868 PetscInt nF, f, pStart, pEnd, p; 869 870 ierr = DMGetDefaultGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 871 ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr); 872 ierr = PetscMalloc2(nF,PetscInt,&fieldSizes,nF,PetscInt *,&fieldIndices);CHKERRQ(ierr); 873 ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 874 for(f = 0; f < nF; ++f) { 875 fieldSizes[f] = 0; 876 } 877 for(p = pStart; p < pEnd; ++p) { 878 PetscInt gdof; 879 880 ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 881 if (gdof > 0) { 882 for(f = 0; f < nF; ++f) { 883 PetscInt fdof, fcdof; 884 885 ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 886 ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 887 fieldSizes[f] += fdof-fcdof; 888 } 889 } 890 } 891 for(f = 0; f < nF; ++f) { 892 ierr = PetscMalloc(fieldSizes[f] * sizeof(PetscInt), &fieldIndices[f]);CHKERRQ(ierr); 893 fieldSizes[f] = 0; 894 } 895 for(p = pStart; p < pEnd; ++p) { 896 PetscInt gdof, goff; 897 898 ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 899 if (gdof > 0) { 900 ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr); 901 for(f = 0; f < nF; ++f) { 902 PetscInt fdof, fcdof, fc; 903 904 ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 905 ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 906 for(fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) { 907 fieldIndices[f][fieldSizes[f]] = goff++; 908 } 909 } 910 } 911 } 912 if (numFields) {*numFields = nF;} 913 if (fieldNames) { 914 ierr = PetscMalloc(nF * sizeof(char *), fieldNames);CHKERRQ(ierr); 915 for(f = 0; f < nF; ++f) { 916 const char *fieldName; 917 918 ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr); 919 ierr = PetscStrallocpy(fieldName, (char **) &(*fieldNames)[f]);CHKERRQ(ierr); 920 } 921 } 922 if (fields) { 923 ierr = PetscMalloc(nF * sizeof(IS), fields);CHKERRQ(ierr); 924 for(f = 0; f < nF; ++f) { 925 ierr = ISCreateGeneral(((PetscObject) dm)->comm, fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr); 926 } 927 } 928 ierr = PetscFree2(fieldSizes,fieldIndices);CHKERRQ(ierr); 929 } else { 930 if(dm->ops->createfieldis) {ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr);} 931 } 932 PetscFunctionReturn(0); 933 } 934 935 936 #undef __FUNCT__ 937 #define __FUNCT__ "DMCreateFieldDecompositionDM" 938 /*@C 939 DMCreateFieldDecompositionDM - creates a DM that encapsulates a decomposition of the original DM into fields. 940 941 Not Collective 942 943 Input Parameters: 944 + dm - the DM object 945 - name - the name of the field decomposition 946 947 Output Parameter: 948 . ddm - the field decomposition DM (PETSC_NULL, if no such decomposition is known) 949 950 Level: advanced 951 952 .seealso DMDestroy(), DMCreate(), DMCreateFieldDecomposition(), DMCreateDomainDecompositionDM() 953 @*/ 954 PetscErrorCode DMCreateFieldDecompositionDM(DM dm, const char* name, DM *ddm) 955 { 956 PetscErrorCode ierr; 957 958 PetscFunctionBegin; 959 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 960 PetscValidCharPointer(name,2); 961 PetscValidPointer(ddm,3); 962 *ddm = PETSC_NULL; 963 if(dm->ops->createfielddecompositiondm) { 964 ierr = (*dm->ops->createfielddecompositiondm)(dm,name,ddm); CHKERRQ(ierr); 965 } 966 PetscFunctionReturn(0); 967 } 968 969 970 #undef __FUNCT__ 971 #define __FUNCT__ "DMCreateFieldDecomposition" 972 /*@C 973 DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems 974 corresponding to different fields: each IS contains the global indices of the dofs of the 975 corresponding field. The optional list of DMs define the DM for each subproblem. 976 Generalizes DMCreateFieldIS(). 977 978 Not collective 979 980 Input Parameter: 981 . dm - the DM object 982 983 Output Parameters: 984 + len - The number of subproblems in the field decomposition (or PETSC_NULL if not requested) 985 . namelist - The name for each field (or PETSC_NULL if not requested) 986 . islist - The global indices for each field (or PETSC_NULL if not requested) 987 - dmlist - The DMs for each field subproblem (or PETSC_NULL, if not requested; if PETSC_NULL is returned, no DMs are defined) 988 989 Level: intermediate 990 991 Notes: 992 The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 993 PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(), 994 and all of the arrays should be freed with PetscFree(). 995 996 .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 997 @*/ 998 PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist) 999 { 1000 PetscErrorCode ierr; 1001 1002 PetscFunctionBegin; 1003 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1004 if (len) {PetscValidPointer(len,2); *len = 0;} 1005 if (namelist) {PetscValidPointer(namelist,3); *namelist = 0;} 1006 if (islist) {PetscValidPointer(islist,4); *islist = 0;} 1007 if (dmlist) {PetscValidPointer(dmlist,5); *dmlist = 0;} 1008 if(!dm->ops->createfielddecomposition) { 1009 ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr); 1010 /* By default there are no DMs associated with subproblems. */ 1011 if(dmlist) *dmlist = PETSC_NULL; 1012 } 1013 else { 1014 ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist); CHKERRQ(ierr); 1015 } 1016 PetscFunctionReturn(0); 1017 } 1018 1019 #undef __FUNCT__ 1020 #define __FUNCT__ "DMCreateDomainDecompositionDM" 1021 /*@C 1022 DMCreateDomainDecompositionDM - creates a DM that encapsulates a decomposition of the original DM into subdomains. 1023 1024 Not Collective 1025 1026 Input Parameters: 1027 + dm - the DM object 1028 - name - the name of the subdomain decomposition 1029 1030 Output Parameter: 1031 . ddm - the subdomain decomposition DM (PETSC_NULL, if no such decomposition is known) 1032 1033 Level: advanced 1034 1035 .seealso DMDestroy(), DMCreate(), DMCreateFieldDecomposition(), DMCreateDomainDecompositionDM() 1036 @*/ 1037 PetscErrorCode DMCreateDomainDecompositionDM(DM dm, const char* name, DM *ddm) 1038 { 1039 PetscErrorCode ierr; 1040 1041 PetscFunctionBegin; 1042 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1043 PetscValidCharPointer(name,2); 1044 PetscValidPointer(ddm,3); 1045 *ddm = PETSC_NULL; 1046 if(dm->ops->createdomaindecompositiondm) { 1047 ierr = (*dm->ops->createdomaindecompositiondm)(dm,name,ddm); CHKERRQ(ierr); 1048 } 1049 PetscFunctionReturn(0); 1050 } 1051 1052 1053 #undef __FUNCT__ 1054 #define __FUNCT__ "DMCreateDomainDecomposition" 1055 /*@C 1056 DMCreateDomainDecomposition - Returns lists of IS objects defining a decomposition of a problem into subproblems 1057 corresponding to restrictions to pairs nested subdomains: each IS contains the global 1058 indices of the dofs of the corresponding subdomains. The inner subdomains conceptually 1059 define a nonoverlapping covering, while outer subdomains can overlap. 1060 The optional list of DMs define the DM for each subproblem. 1061 1062 Not collective 1063 1064 Input Parameter: 1065 . dm - the DM object 1066 1067 Output Parameters: 1068 + len - The number of subproblems in the domain decomposition (or PETSC_NULL if not requested) 1069 . namelist - The name for each subdomain (or PETSC_NULL if not requested) 1070 . innerislist - The global indices for each inner subdomain (or PETSC_NULL, if not requested) 1071 . outerislist - The global indices for each outer subdomain (or PETSC_NULL, if not requested) 1072 - dmlist - The DMs for each subdomain subproblem (or PETSC_NULL, if not requested; if PETSC_NULL is returned, no DMs are defined) 1073 1074 Level: intermediate 1075 1076 Notes: 1077 The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 1078 PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(), 1079 and all of the arrays should be freed with PetscFree(). 1080 1081 .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateDomainDecompositionDM(), DMCreateFieldDecomposition() 1082 @*/ 1083 PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist) 1084 { 1085 PetscErrorCode ierr; 1086 1087 PetscFunctionBegin; 1088 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1089 if (len) {PetscValidPointer(len,2); *len = PETSC_NULL;} 1090 if (namelist) {PetscValidPointer(namelist,3); *namelist = PETSC_NULL;} 1091 if (innerislist) {PetscValidPointer(innerislist,4); *innerislist = PETSC_NULL;} 1092 if (outerislist) {PetscValidPointer(outerislist,5); *outerislist = PETSC_NULL;} 1093 if (dmlist) {PetscValidPointer(dmlist,6); *dmlist = PETSC_NULL;} 1094 if(dm->ops->createdomaindecomposition) { 1095 ierr = (*dm->ops->createdomaindecomposition)(dm,len,namelist,innerislist,outerislist,dmlist); CHKERRQ(ierr); 1096 } 1097 PetscFunctionReturn(0); 1098 } 1099 1100 #undef __FUNCT__ 1101 #define __FUNCT__ "DMRefine" 1102 /*@ 1103 DMRefine - Refines a DM object 1104 1105 Collective on DM 1106 1107 Input Parameter: 1108 + dm - the DM object 1109 - comm - the communicator to contain the new DM object (or MPI_COMM_NULL) 1110 1111 Output Parameter: 1112 . dmf - the refined DM, or PETSC_NULL 1113 1114 Note: If no refinement was done, the return value is PETSC_NULL 1115 1116 Level: developer 1117 1118 .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 1119 @*/ 1120 PetscErrorCode DMRefine(DM dm,MPI_Comm comm,DM *dmf) 1121 { 1122 PetscErrorCode ierr; 1123 DMRefineHookLink link; 1124 1125 PetscFunctionBegin; 1126 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1127 ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr); 1128 if (*dmf) { 1129 (*dmf)->ops->creatematrix = dm->ops->creatematrix; 1130 (*dmf)->ops->initialguess = dm->ops->initialguess; 1131 (*dmf)->ops->function = dm->ops->function; 1132 (*dmf)->ops->functionj = dm->ops->functionj; 1133 if (dm->ops->jacobian != DMComputeJacobianDefault) { 1134 (*dmf)->ops->jacobian = dm->ops->jacobian; 1135 } 1136 ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr); 1137 (*dmf)->ctx = dm->ctx; 1138 (*dmf)->leveldown = dm->leveldown; 1139 (*dmf)->levelup = dm->levelup + 1; 1140 ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr); 1141 for (link=dm->refinehook; link; link=link->next) { 1142 if (link->refinehook) {ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr);} 1143 } 1144 } 1145 PetscFunctionReturn(0); 1146 } 1147 1148 #undef __FUNCT__ 1149 #define __FUNCT__ "DMRefineHookAdd" 1150 /*@ 1151 DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid 1152 1153 Logically Collective 1154 1155 Input Arguments: 1156 + coarse - nonlinear solver context on which to run a hook when restricting to a coarser level 1157 . refinehook - function to run when setting up a coarser level 1158 . interphook - function to run to update data on finer levels (once per SNESSolve()) 1159 - ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL) 1160 1161 Calling sequence of refinehook: 1162 $ refinehook(DM coarse,DM fine,void *ctx); 1163 1164 + coarse - coarse level DM 1165 . fine - fine level DM to interpolate problem to 1166 - ctx - optional user-defined function context 1167 1168 Calling sequence for interphook: 1169 $ interphook(DM coarse,Mat interp,DM fine,void *ctx) 1170 1171 + coarse - coarse level DM 1172 . interp - matrix interpolating a coarse-level solution to the finer grid 1173 . fine - fine level DM to update 1174 - ctx - optional user-defined function context 1175 1176 Level: advanced 1177 1178 Notes: 1179 This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing 1180 1181 If this function is called multiple times, the hooks will be run in the order they are added. 1182 1183 .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 1184 @*/ 1185 PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx) 1186 { 1187 PetscErrorCode ierr; 1188 DMRefineHookLink link,*p; 1189 1190 PetscFunctionBegin; 1191 PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 1192 for (p=&coarse->refinehook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 1193 ierr = PetscMalloc(sizeof(struct _DMRefineHookLink),&link);CHKERRQ(ierr); 1194 link->refinehook = refinehook; 1195 link->interphook = interphook; 1196 link->ctx = ctx; 1197 link->next = PETSC_NULL; 1198 *p = link; 1199 PetscFunctionReturn(0); 1200 } 1201 1202 #undef __FUNCT__ 1203 #define __FUNCT__ "DMInterpolate" 1204 /*@ 1205 DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd() 1206 1207 Collective if any hooks are 1208 1209 Input Arguments: 1210 + coarse - coarser DM to use as a base 1211 . restrct - interpolation matrix, apply using MatInterpolate() 1212 - fine - finer DM to update 1213 1214 Level: developer 1215 1216 .seealso: DMRefineHookAdd(), MatInterpolate() 1217 @*/ 1218 PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine) 1219 { 1220 PetscErrorCode ierr; 1221 DMRefineHookLink link; 1222 1223 PetscFunctionBegin; 1224 for (link=fine->refinehook; link; link=link->next) { 1225 if (link->interphook) {ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr);} 1226 } 1227 PetscFunctionReturn(0); 1228 } 1229 1230 #undef __FUNCT__ 1231 #define __FUNCT__ "DMGetRefineLevel" 1232 /*@ 1233 DMGetRefineLevel - Get's the number of refinements that have generated this DM. 1234 1235 Not Collective 1236 1237 Input Parameter: 1238 . dm - the DM object 1239 1240 Output Parameter: 1241 . level - number of refinements 1242 1243 Level: developer 1244 1245 .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 1246 1247 @*/ 1248 PetscErrorCode DMGetRefineLevel(DM dm,PetscInt *level) 1249 { 1250 PetscFunctionBegin; 1251 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1252 *level = dm->levelup; 1253 PetscFunctionReturn(0); 1254 } 1255 1256 #undef __FUNCT__ 1257 #define __FUNCT__ "DMGlobalToLocalBegin" 1258 /*@ 1259 DMGlobalToLocalBegin - Begins updating local vectors from global vector 1260 1261 Neighbor-wise Collective on DM 1262 1263 Input Parameters: 1264 + dm - the DM object 1265 . g - the global vector 1266 . mode - INSERT_VALUES or ADD_VALUES 1267 - l - the local vector 1268 1269 1270 Level: beginner 1271 1272 .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 1273 1274 @*/ 1275 PetscErrorCode DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l) 1276 { 1277 PetscSF sf; 1278 PetscErrorCode ierr; 1279 1280 PetscFunctionBegin; 1281 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1282 ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr); 1283 if (sf) { 1284 PetscScalar *lArray, *gArray; 1285 1286 if (mode == ADD_VALUES) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 1287 ierr = VecGetArray(l, &lArray);CHKERRQ(ierr); 1288 ierr = VecGetArray(g, &gArray);CHKERRQ(ierr); 1289 ierr = PetscSFBcastBegin(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr); 1290 ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr); 1291 ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr); 1292 } else { 1293 ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 1294 } 1295 PetscFunctionReturn(0); 1296 } 1297 1298 #undef __FUNCT__ 1299 #define __FUNCT__ "DMGlobalToLocalEnd" 1300 /*@ 1301 DMGlobalToLocalEnd - Ends updating local vectors from global vector 1302 1303 Neighbor-wise Collective on DM 1304 1305 Input Parameters: 1306 + dm - the DM object 1307 . g - the global vector 1308 . mode - INSERT_VALUES or ADD_VALUES 1309 - l - the local vector 1310 1311 1312 Level: beginner 1313 1314 .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 1315 1316 @*/ 1317 PetscErrorCode DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l) 1318 { 1319 PetscSF sf; 1320 PetscErrorCode ierr; 1321 PetscScalar *lArray, *gArray; 1322 1323 PetscFunctionBegin; 1324 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1325 ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr); 1326 if (sf) { 1327 if (mode == ADD_VALUES) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 1328 1329 ierr = VecGetArray(l, &lArray);CHKERRQ(ierr); 1330 ierr = VecGetArray(g, &gArray);CHKERRQ(ierr); 1331 ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr); 1332 ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr); 1333 ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr); 1334 } else { 1335 ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 1336 } 1337 PetscFunctionReturn(0); 1338 } 1339 1340 #undef __FUNCT__ 1341 #define __FUNCT__ "DMLocalToGlobalBegin" 1342 /*@ 1343 DMLocalToGlobalBegin - updates global vectors from local vectors 1344 1345 Neighbor-wise Collective on DM 1346 1347 Input Parameters: 1348 + dm - the DM object 1349 . l - the local vector 1350 . mode - if INSERT_VALUES then no parallel communication is used, if ADD_VALUES then all ghost points from the same base point accumulate into that 1351 base point. 1352 - - the global vector 1353 1354 Notes: In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation. If you would like to simply add the non-ghosted values in the local 1355 array into the global array you need to either (1) zero the ghosted locations and use ADD_VALUES or (2) use INSERT_VALUES into a work global array and then add the work 1356 global array to the final global array with VecAXPY(). 1357 1358 Level: beginner 1359 1360 .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin() 1361 1362 @*/ 1363 PetscErrorCode DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g) 1364 { 1365 PetscSF sf; 1366 PetscErrorCode ierr; 1367 1368 PetscFunctionBegin; 1369 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1370 ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr); 1371 if (sf) { 1372 MPI_Op op; 1373 PetscScalar *lArray, *gArray; 1374 1375 switch(mode) { 1376 case INSERT_VALUES: 1377 case INSERT_ALL_VALUES: 1378 #if defined(PETSC_HAVE_MPI_REPLACE) 1379 op = MPI_REPLACE; break; 1380 #else 1381 SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No support for INSERT_VALUES without an MPI-2 implementation"); 1382 #endif 1383 case ADD_VALUES: 1384 case ADD_ALL_VALUES: 1385 op = MPI_SUM; break; 1386 default: 1387 SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 1388 } 1389 ierr = VecGetArray(l, &lArray);CHKERRQ(ierr); 1390 ierr = VecGetArray(g, &gArray);CHKERRQ(ierr); 1391 ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr); 1392 ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr); 1393 ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr); 1394 } else { 1395 ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr); 1396 } 1397 PetscFunctionReturn(0); 1398 } 1399 1400 #undef __FUNCT__ 1401 #define __FUNCT__ "DMLocalToGlobalEnd" 1402 /*@ 1403 DMLocalToGlobalEnd - updates global vectors from local vectors 1404 1405 Neighbor-wise Collective on DM 1406 1407 Input Parameters: 1408 + dm - the DM object 1409 . l - the local vector 1410 . mode - INSERT_VALUES or ADD_VALUES 1411 - g - the global vector 1412 1413 1414 Level: beginner 1415 1416 .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd() 1417 1418 @*/ 1419 PetscErrorCode DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g) 1420 { 1421 PetscSF sf; 1422 PetscErrorCode ierr; 1423 1424 PetscFunctionBegin; 1425 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1426 ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr); 1427 if (sf) { 1428 MPI_Op op; 1429 PetscScalar *lArray, *gArray; 1430 1431 switch(mode) { 1432 case INSERT_VALUES: 1433 case INSERT_ALL_VALUES: 1434 #if defined(PETSC_HAVE_MPI_REPLACE) 1435 op = MPI_REPLACE; break; 1436 #else 1437 SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No support for INSERT_VALUES without an MPI-2 implementation"); 1438 #endif 1439 case ADD_VALUES: 1440 case ADD_ALL_VALUES: 1441 op = MPI_SUM; break; 1442 default: 1443 SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 1444 } 1445 ierr = VecGetArray(l, &lArray);CHKERRQ(ierr); 1446 ierr = VecGetArray(g, &gArray);CHKERRQ(ierr); 1447 ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr); 1448 ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr); 1449 ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr); 1450 } else { 1451 ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr); 1452 } 1453 PetscFunctionReturn(0); 1454 } 1455 1456 #undef __FUNCT__ 1457 #define __FUNCT__ "DMComputeJacobianDefault" 1458 /*@ 1459 DMComputeJacobianDefault - computes the Jacobian using the DMComputeFunction() if Jacobian computer is not provided 1460 1461 Collective on DM 1462 1463 Input Parameter: 1464 + dm - the DM object 1465 . x - location to compute Jacobian at; may be ignored for linear problems 1466 . A - matrix that defines the operator for the linear solve 1467 - B - the matrix used to construct the preconditioner 1468 1469 Level: developer 1470 1471 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(), 1472 DMSetFunction() 1473 1474 @*/ 1475 PetscErrorCode DMComputeJacobianDefault(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag) 1476 { 1477 PetscErrorCode ierr; 1478 1479 PetscFunctionBegin; 1480 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1481 *stflag = SAME_NONZERO_PATTERN; 1482 ierr = MatFDColoringApply(B,dm->fd,x,stflag,dm);CHKERRQ(ierr); 1483 if (A != B) { 1484 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1485 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1486 } 1487 PetscFunctionReturn(0); 1488 } 1489 1490 #undef __FUNCT__ 1491 #define __FUNCT__ "DMCoarsen" 1492 /*@ 1493 DMCoarsen - Coarsens a DM object 1494 1495 Collective on DM 1496 1497 Input Parameter: 1498 + dm - the DM object 1499 - comm - the communicator to contain the new DM object (or MPI_COMM_NULL) 1500 1501 Output Parameter: 1502 . dmc - the coarsened DM 1503 1504 Level: developer 1505 1506 .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 1507 1508 @*/ 1509 PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc) 1510 { 1511 PetscErrorCode ierr; 1512 DMCoarsenHookLink link; 1513 1514 PetscFunctionBegin; 1515 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1516 ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr); 1517 (*dmc)->ops->creatematrix = dm->ops->creatematrix; 1518 (*dmc)->ops->initialguess = dm->ops->initialguess; 1519 (*dmc)->ops->function = dm->ops->function; 1520 (*dmc)->ops->functionj = dm->ops->functionj; 1521 if (dm->ops->jacobian != DMComputeJacobianDefault) { 1522 (*dmc)->ops->jacobian = dm->ops->jacobian; 1523 } 1524 ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr); 1525 (*dmc)->ctx = dm->ctx; 1526 (*dmc)->levelup = dm->levelup; 1527 (*dmc)->leveldown = dm->leveldown + 1; 1528 ierr = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr); 1529 for (link=dm->coarsenhook; link; link=link->next) { 1530 if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);} 1531 } 1532 PetscFunctionReturn(0); 1533 } 1534 1535 #undef __FUNCT__ 1536 #define __FUNCT__ "DMCoarsenHookAdd" 1537 /*@ 1538 DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid 1539 1540 Logically Collective 1541 1542 Input Arguments: 1543 + fine - nonlinear solver context on which to run a hook when restricting to a coarser level 1544 . coarsenhook - function to run when setting up a coarser level 1545 . restricthook - function to run to update data on coarser levels (once per SNESSolve()) 1546 - ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL) 1547 1548 Calling sequence of coarsenhook: 1549 $ coarsenhook(DM fine,DM coarse,void *ctx); 1550 1551 + fine - fine level DM 1552 . coarse - coarse level DM to restrict problem to 1553 - ctx - optional user-defined function context 1554 1555 Calling sequence for restricthook: 1556 $ restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx) 1557 1558 + fine - fine level DM 1559 . mrestrict - matrix restricting a fine-level solution to the coarse grid 1560 . rscale - scaling vector for restriction 1561 . inject - matrix restricting by injection 1562 . coarse - coarse level DM to update 1563 - ctx - optional user-defined function context 1564 1565 Level: advanced 1566 1567 Notes: 1568 This function is only needed if auxiliary data needs to be set up on coarse grids. 1569 1570 If this function is called multiple times, the hooks will be run in the order they are added. 1571 1572 In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 1573 extract the finest level information from its context (instead of from the SNES). 1574 1575 .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 1576 @*/ 1577 PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx) 1578 { 1579 PetscErrorCode ierr; 1580 DMCoarsenHookLink link,*p; 1581 1582 PetscFunctionBegin; 1583 PetscValidHeaderSpecific(fine,DM_CLASSID,1); 1584 for (p=&fine->coarsenhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 1585 ierr = PetscMalloc(sizeof(struct _DMCoarsenHookLink),&link);CHKERRQ(ierr); 1586 link->coarsenhook = coarsenhook; 1587 link->restricthook = restricthook; 1588 link->ctx = ctx; 1589 link->next = PETSC_NULL; 1590 *p = link; 1591 PetscFunctionReturn(0); 1592 } 1593 1594 #undef __FUNCT__ 1595 #define __FUNCT__ "DMRestrict" 1596 /*@ 1597 DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd() 1598 1599 Collective if any hooks are 1600 1601 Input Arguments: 1602 + fine - finer DM to use as a base 1603 . restrct - restriction matrix, apply using MatRestrict() 1604 . inject - injection matrix, also use MatRestrict() 1605 - coarse - coarer DM to update 1606 1607 Level: developer 1608 1609 .seealso: DMCoarsenHookAdd(), MatRestrict() 1610 @*/ 1611 PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse) 1612 { 1613 PetscErrorCode ierr; 1614 DMCoarsenHookLink link; 1615 1616 PetscFunctionBegin; 1617 for (link=fine->coarsenhook; link; link=link->next) { 1618 if (link->restricthook) {ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr);} 1619 } 1620 PetscFunctionReturn(0); 1621 } 1622 1623 #undef __FUNCT__ 1624 #define __FUNCT__ "DMGetCoarsenLevel" 1625 /*@ 1626 DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM. 1627 1628 Not Collective 1629 1630 Input Parameter: 1631 . dm - the DM object 1632 1633 Output Parameter: 1634 . level - number of coarsenings 1635 1636 Level: developer 1637 1638 .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 1639 1640 @*/ 1641 PetscErrorCode DMGetCoarsenLevel(DM dm,PetscInt *level) 1642 { 1643 PetscFunctionBegin; 1644 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1645 *level = dm->leveldown; 1646 PetscFunctionReturn(0); 1647 } 1648 1649 1650 1651 #undef __FUNCT__ 1652 #define __FUNCT__ "DMRefineHierarchy" 1653 /*@C 1654 DMRefineHierarchy - Refines a DM object, all levels at once 1655 1656 Collective on DM 1657 1658 Input Parameter: 1659 + dm - the DM object 1660 - nlevels - the number of levels of refinement 1661 1662 Output Parameter: 1663 . dmf - the refined DM hierarchy 1664 1665 Level: developer 1666 1667 .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 1668 1669 @*/ 1670 PetscErrorCode DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[]) 1671 { 1672 PetscErrorCode ierr; 1673 1674 PetscFunctionBegin; 1675 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1676 if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 1677 if (nlevels == 0) PetscFunctionReturn(0); 1678 if (dm->ops->refinehierarchy) { 1679 ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr); 1680 } else if (dm->ops->refine) { 1681 PetscInt i; 1682 1683 ierr = DMRefine(dm,((PetscObject)dm)->comm,&dmf[0]);CHKERRQ(ierr); 1684 for (i=1; i<nlevels; i++) { 1685 ierr = DMRefine(dmf[i-1],((PetscObject)dm)->comm,&dmf[i]);CHKERRQ(ierr); 1686 } 1687 } else { 1688 SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No RefineHierarchy for this DM yet"); 1689 } 1690 PetscFunctionReturn(0); 1691 } 1692 1693 #undef __FUNCT__ 1694 #define __FUNCT__ "DMCoarsenHierarchy" 1695 /*@C 1696 DMCoarsenHierarchy - Coarsens a DM object, all levels at once 1697 1698 Collective on DM 1699 1700 Input Parameter: 1701 + dm - the DM object 1702 - nlevels - the number of levels of coarsening 1703 1704 Output Parameter: 1705 . dmc - the coarsened DM hierarchy 1706 1707 Level: developer 1708 1709 .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 1710 1711 @*/ 1712 PetscErrorCode DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[]) 1713 { 1714 PetscErrorCode ierr; 1715 1716 PetscFunctionBegin; 1717 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1718 if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 1719 if (nlevels == 0) PetscFunctionReturn(0); 1720 PetscValidPointer(dmc,3); 1721 if (dm->ops->coarsenhierarchy) { 1722 ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr); 1723 } else if (dm->ops->coarsen) { 1724 PetscInt i; 1725 1726 ierr = DMCoarsen(dm,((PetscObject)dm)->comm,&dmc[0]);CHKERRQ(ierr); 1727 for (i=1; i<nlevels; i++) { 1728 ierr = DMCoarsen(dmc[i-1],((PetscObject)dm)->comm,&dmc[i]);CHKERRQ(ierr); 1729 } 1730 } else { 1731 SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet"); 1732 } 1733 PetscFunctionReturn(0); 1734 } 1735 1736 #undef __FUNCT__ 1737 #define __FUNCT__ "DMCreateAggregates" 1738 /*@ 1739 DMCreateAggregates - Gets the aggregates that map between 1740 grids associated with two DMs. 1741 1742 Collective on DM 1743 1744 Input Parameters: 1745 + dmc - the coarse grid DM 1746 - dmf - the fine grid DM 1747 1748 Output Parameters: 1749 . rest - the restriction matrix (transpose of the projection matrix) 1750 1751 Level: intermediate 1752 1753 .keywords: interpolation, restriction, multigrid 1754 1755 .seealso: DMRefine(), DMCreateInjection(), DMCreateInterpolation() 1756 @*/ 1757 PetscErrorCode DMCreateAggregates(DM dmc, DM dmf, Mat *rest) 1758 { 1759 PetscErrorCode ierr; 1760 1761 PetscFunctionBegin; 1762 PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 1763 PetscValidHeaderSpecific(dmf,DM_CLASSID,2); 1764 ierr = (*dmc->ops->getaggregates)(dmc, dmf, rest);CHKERRQ(ierr); 1765 PetscFunctionReturn(0); 1766 } 1767 1768 #undef __FUNCT__ 1769 #define __FUNCT__ "DMSetApplicationContextDestroy" 1770 /*@C 1771 DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed 1772 1773 Not Collective 1774 1775 Input Parameters: 1776 + dm - the DM object 1777 - destroy - the destroy function 1778 1779 Level: intermediate 1780 1781 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 1782 1783 @*/ 1784 PetscErrorCode DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**)) 1785 { 1786 PetscFunctionBegin; 1787 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1788 dm->ctxdestroy = destroy; 1789 PetscFunctionReturn(0); 1790 } 1791 1792 #undef __FUNCT__ 1793 #define __FUNCT__ "DMSetApplicationContext" 1794 /*@ 1795 DMSetApplicationContext - Set a user context into a DM object 1796 1797 Not Collective 1798 1799 Input Parameters: 1800 + dm - the DM object 1801 - ctx - the user context 1802 1803 Level: intermediate 1804 1805 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 1806 1807 @*/ 1808 PetscErrorCode DMSetApplicationContext(DM dm,void *ctx) 1809 { 1810 PetscFunctionBegin; 1811 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1812 dm->ctx = ctx; 1813 PetscFunctionReturn(0); 1814 } 1815 1816 #undef __FUNCT__ 1817 #define __FUNCT__ "DMGetApplicationContext" 1818 /*@ 1819 DMGetApplicationContext - Gets a user context from a DM object 1820 1821 Not Collective 1822 1823 Input Parameter: 1824 . dm - the DM object 1825 1826 Output Parameter: 1827 . ctx - the user context 1828 1829 Level: intermediate 1830 1831 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 1832 1833 @*/ 1834 PetscErrorCode DMGetApplicationContext(DM dm,void *ctx) 1835 { 1836 PetscFunctionBegin; 1837 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1838 *(void**)ctx = dm->ctx; 1839 PetscFunctionReturn(0); 1840 } 1841 1842 #undef __FUNCT__ 1843 #define __FUNCT__ "DMSetInitialGuess" 1844 /*@C 1845 DMSetInitialGuess - sets a function to compute an initial guess vector entries for the solvers 1846 1847 Logically Collective on DM 1848 1849 Input Parameter: 1850 + dm - the DM object to destroy 1851 - f - the function to compute the initial guess 1852 1853 Level: intermediate 1854 1855 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian() 1856 1857 @*/ 1858 PetscErrorCode DMSetInitialGuess(DM dm,PetscErrorCode (*f)(DM,Vec)) 1859 { 1860 PetscFunctionBegin; 1861 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1862 dm->ops->initialguess = f; 1863 PetscFunctionReturn(0); 1864 } 1865 1866 #undef __FUNCT__ 1867 #define __FUNCT__ "DMSetFunction" 1868 /*@C 1869 DMSetFunction - sets a function to compute the right hand side vector entries for the KSP solver or nonlinear function for SNES 1870 1871 Logically Collective on DM 1872 1873 Input Parameter: 1874 + dm - the DM object 1875 - f - the function to compute (use PETSC_NULL to cancel a previous function that was set) 1876 1877 Level: intermediate 1878 1879 Notes: This sets both the function for function evaluations and the function used to compute Jacobians via finite differences if no Jacobian 1880 computer is provided with DMSetJacobian(). Canceling cancels the function, but not the function used to compute the Jacobian. 1881 1882 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(), 1883 DMSetJacobian() 1884 1885 @*/ 1886 PetscErrorCode DMSetFunction(DM dm,PetscErrorCode (*f)(DM,Vec,Vec)) 1887 { 1888 PetscFunctionBegin; 1889 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1890 dm->ops->function = f; 1891 if (f) { 1892 dm->ops->functionj = f; 1893 } 1894 PetscFunctionReturn(0); 1895 } 1896 1897 #undef __FUNCT__ 1898 #define __FUNCT__ "DMSetJacobian" 1899 /*@C 1900 DMSetJacobian - sets a function to compute the matrix entries for the KSP solver or Jacobian for SNES 1901 1902 Logically Collective on DM 1903 1904 Input Parameter: 1905 + dm - the DM object to destroy 1906 - f - the function to compute the matrix entries 1907 1908 Level: intermediate 1909 1910 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(), 1911 DMSetFunction() 1912 1913 @*/ 1914 PetscErrorCode DMSetJacobian(DM dm,PetscErrorCode (*f)(DM,Vec,Mat,Mat,MatStructure*)) 1915 { 1916 PetscFunctionBegin; 1917 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1918 dm->ops->jacobian = f; 1919 PetscFunctionReturn(0); 1920 } 1921 1922 #undef __FUNCT__ 1923 #define __FUNCT__ "DMSetVariableBounds" 1924 /*@C 1925 DMSetVariableBounds - sets a function to compute the the lower and upper bound vectors for SNESVI. 1926 1927 Logically Collective on DM 1928 1929 Input Parameter: 1930 + dm - the DM object 1931 - f - the function that computes variable bounds used by SNESVI (use PETSC_NULL to cancel a previous function that was set) 1932 1933 Level: intermediate 1934 1935 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(), 1936 DMSetJacobian() 1937 1938 @*/ 1939 PetscErrorCode DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec)) 1940 { 1941 PetscFunctionBegin; 1942 dm->ops->computevariablebounds = f; 1943 PetscFunctionReturn(0); 1944 } 1945 1946 #undef __FUNCT__ 1947 #define __FUNCT__ "DMHasVariableBounds" 1948 /*@ 1949 DMHasVariableBounds - does the DM object have a variable bounds function? 1950 1951 Not Collective 1952 1953 Input Parameter: 1954 . dm - the DM object to destroy 1955 1956 Output Parameter: 1957 . flg - PETSC_TRUE if the variable bounds function exists 1958 1959 Level: developer 1960 1961 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian() 1962 1963 @*/ 1964 PetscErrorCode DMHasVariableBounds(DM dm,PetscBool *flg) 1965 { 1966 PetscFunctionBegin; 1967 *flg = (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE; 1968 PetscFunctionReturn(0); 1969 } 1970 1971 #undef __FUNCT__ 1972 #define __FUNCT__ "DMComputeVariableBounds" 1973 /*@C 1974 DMComputeVariableBounds - compute variable bounds used by SNESVI. 1975 1976 Logically Collective on DM 1977 1978 Input Parameters: 1979 + dm - the DM object to destroy 1980 - x - current solution at which the bounds are computed 1981 1982 Output parameters: 1983 + xl - lower bound 1984 - xu - upper bound 1985 1986 Level: intermediate 1987 1988 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(), 1989 DMSetFunction(), DMSetVariableBounds() 1990 1991 @*/ 1992 PetscErrorCode DMComputeVariableBounds(DM dm, Vec xl, Vec xu) 1993 { 1994 PetscErrorCode ierr; 1995 PetscFunctionBegin; 1996 PetscValidHeaderSpecific(xl,VEC_CLASSID,2); 1997 PetscValidHeaderSpecific(xu,VEC_CLASSID,2); 1998 if(dm->ops->computevariablebounds) { 1999 ierr = (*dm->ops->computevariablebounds)(dm, xl,xu); CHKERRQ(ierr); 2000 } 2001 else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "This DM is incapable of computing variable bounds."); 2002 PetscFunctionReturn(0); 2003 } 2004 2005 #undef __FUNCT__ 2006 #define __FUNCT__ "DMComputeInitialGuess" 2007 /*@ 2008 DMComputeInitialGuess - computes an initial guess vector entries for the KSP solvers 2009 2010 Collective on DM 2011 2012 Input Parameter: 2013 + dm - the DM object to destroy 2014 - x - the vector to hold the initial guess values 2015 2016 Level: developer 2017 2018 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetRhs(), DMSetMat() 2019 2020 @*/ 2021 PetscErrorCode DMComputeInitialGuess(DM dm,Vec x) 2022 { 2023 PetscErrorCode ierr; 2024 PetscFunctionBegin; 2025 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2026 if (!dm->ops->initialguess) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetInitialGuess()"); 2027 ierr = (*dm->ops->initialguess)(dm,x);CHKERRQ(ierr); 2028 PetscFunctionReturn(0); 2029 } 2030 2031 #undef __FUNCT__ 2032 #define __FUNCT__ "DMHasInitialGuess" 2033 /*@ 2034 DMHasInitialGuess - does the DM object have an initial guess function 2035 2036 Not Collective 2037 2038 Input Parameter: 2039 . dm - the DM object to destroy 2040 2041 Output Parameter: 2042 . flg - PETSC_TRUE if function exists 2043 2044 Level: developer 2045 2046 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian() 2047 2048 @*/ 2049 PetscErrorCode DMHasInitialGuess(DM dm,PetscBool *flg) 2050 { 2051 PetscFunctionBegin; 2052 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2053 *flg = (dm->ops->initialguess) ? PETSC_TRUE : PETSC_FALSE; 2054 PetscFunctionReturn(0); 2055 } 2056 2057 #undef __FUNCT__ 2058 #define __FUNCT__ "DMHasFunction" 2059 /*@ 2060 DMHasFunction - does the DM object have a function 2061 2062 Not Collective 2063 2064 Input Parameter: 2065 . dm - the DM object to destroy 2066 2067 Output Parameter: 2068 . flg - PETSC_TRUE if function exists 2069 2070 Level: developer 2071 2072 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian() 2073 2074 @*/ 2075 PetscErrorCode DMHasFunction(DM dm,PetscBool *flg) 2076 { 2077 PetscFunctionBegin; 2078 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2079 *flg = (dm->ops->function) ? PETSC_TRUE : PETSC_FALSE; 2080 PetscFunctionReturn(0); 2081 } 2082 2083 #undef __FUNCT__ 2084 #define __FUNCT__ "DMHasJacobian" 2085 /*@ 2086 DMHasJacobian - does the DM object have a matrix function 2087 2088 Not Collective 2089 2090 Input Parameter: 2091 . dm - the DM object to destroy 2092 2093 Output Parameter: 2094 . flg - PETSC_TRUE if function exists 2095 2096 Level: developer 2097 2098 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian() 2099 2100 @*/ 2101 PetscErrorCode DMHasJacobian(DM dm,PetscBool *flg) 2102 { 2103 PetscFunctionBegin; 2104 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2105 *flg = (dm->ops->jacobian) ? PETSC_TRUE : PETSC_FALSE; 2106 PetscFunctionReturn(0); 2107 } 2108 2109 #undef __FUNCT__ 2110 #define __FUNCT__ "DMSetVec" 2111 /*@C 2112 DMSetVec - set the vector at which to compute residual, Jacobian and VI bounds, if the problem is nonlinear. 2113 2114 Collective on DM 2115 2116 Input Parameter: 2117 + dm - the DM object 2118 - x - location to compute residual and Jacobian, if PETSC_NULL is passed to those routines; will be PETSC_NULL for linear problems. 2119 2120 Level: developer 2121 2122 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(), 2123 DMSetFunction(), DMSetJacobian(), DMSetVariableBounds() 2124 2125 @*/ 2126 PetscErrorCode DMSetVec(DM dm,Vec x) 2127 { 2128 PetscErrorCode ierr; 2129 PetscFunctionBegin; 2130 if (x) { 2131 if (!dm->x) { 2132 ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr); 2133 } 2134 ierr = VecCopy(x,dm->x);CHKERRQ(ierr); 2135 } 2136 else if(dm->x) { 2137 ierr = VecDestroy(&dm->x); CHKERRQ(ierr); 2138 } 2139 PetscFunctionReturn(0); 2140 } 2141 2142 2143 #undef __FUNCT__ 2144 #define __FUNCT__ "DMComputeFunction" 2145 /*@ 2146 DMComputeFunction - computes the right hand side vector entries for the KSP solver or nonlinear function for SNES 2147 2148 Collective on DM 2149 2150 Input Parameter: 2151 + dm - the DM object to destroy 2152 . x - the location where the function is evaluationed, may be ignored for linear problems 2153 - b - the vector to hold the right hand side entries 2154 2155 Level: developer 2156 2157 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(), 2158 DMSetJacobian() 2159 2160 @*/ 2161 PetscErrorCode DMComputeFunction(DM dm,Vec x,Vec b) 2162 { 2163 PetscErrorCode ierr; 2164 PetscFunctionBegin; 2165 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2166 if (!dm->ops->function) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetFunction()"); 2167 PetscStackPush("DM user function"); 2168 ierr = (*dm->ops->function)(dm,x,b);CHKERRQ(ierr); 2169 PetscStackPop; 2170 PetscFunctionReturn(0); 2171 } 2172 2173 2174 2175 #undef __FUNCT__ 2176 #define __FUNCT__ "DMComputeJacobian" 2177 /*@ 2178 DMComputeJacobian - compute the matrix entries for the solver 2179 2180 Collective on DM 2181 2182 Input Parameter: 2183 + dm - the DM object 2184 . x - location to compute Jacobian at; will be PETSC_NULL for linear problems, for nonlinear problems if not provided then pulled from DM 2185 . A - matrix that defines the operator for the linear solve 2186 - B - the matrix used to construct the preconditioner 2187 2188 Level: developer 2189 2190 .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(), 2191 DMSetFunction() 2192 2193 @*/ 2194 PetscErrorCode DMComputeJacobian(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag) 2195 { 2196 PetscErrorCode ierr; 2197 2198 PetscFunctionBegin; 2199 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2200 if (!dm->ops->jacobian) { 2201 ISColoring coloring; 2202 MatFDColoring fd; 2203 const MatType mtype; 2204 2205 ierr = PetscObjectGetType((PetscObject)B,&mtype);CHKERRQ(ierr); 2206 ierr = DMCreateColoring(dm,dm->coloringtype,mtype,&coloring);CHKERRQ(ierr); 2207 ierr = MatFDColoringCreate(B,coloring,&fd);CHKERRQ(ierr); 2208 ierr = ISColoringDestroy(&coloring);CHKERRQ(ierr); 2209 ierr = MatFDColoringSetFunction(fd,(PetscErrorCode (*)(void))dm->ops->functionj,dm);CHKERRQ(ierr); 2210 ierr = PetscObjectSetOptionsPrefix((PetscObject)fd,((PetscObject)dm)->prefix);CHKERRQ(ierr); 2211 ierr = MatFDColoringSetFromOptions(fd);CHKERRQ(ierr); 2212 2213 dm->fd = fd; 2214 dm->ops->jacobian = DMComputeJacobianDefault; 2215 2216 /* don't know why this is needed */ 2217 ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr); 2218 } 2219 if (!x) x = dm->x; 2220 ierr = (*dm->ops->jacobian)(dm,x,A,B,stflag);CHKERRQ(ierr); 2221 2222 /* if matrix depends on x; i.e. nonlinear problem, keep copy of input vector since needed by multigrid methods to generate coarse grid matrices */ 2223 if (x) { 2224 if (!dm->x) { 2225 ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr); 2226 } 2227 ierr = VecCopy(x,dm->x);CHKERRQ(ierr); 2228 } 2229 if (A != B) { 2230 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2231 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2232 } 2233 PetscFunctionReturn(0); 2234 } 2235 2236 2237 PetscFList DMList = PETSC_NULL; 2238 PetscBool DMRegisterAllCalled = PETSC_FALSE; 2239 2240 #undef __FUNCT__ 2241 #define __FUNCT__ "DMSetType" 2242 /*@C 2243 DMSetType - Builds a DM, for a particular DM implementation. 2244 2245 Collective on DM 2246 2247 Input Parameters: 2248 + dm - The DM object 2249 - method - The name of the DM type 2250 2251 Options Database Key: 2252 . -dm_type <type> - Sets the DM type; use -help for a list of available types 2253 2254 Notes: 2255 See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D). 2256 2257 Level: intermediate 2258 2259 .keywords: DM, set, type 2260 .seealso: DMGetType(), DMCreate() 2261 @*/ 2262 PetscErrorCode DMSetType(DM dm, const DMType method) 2263 { 2264 PetscErrorCode (*r)(DM); 2265 PetscBool match; 2266 PetscErrorCode ierr; 2267 2268 PetscFunctionBegin; 2269 PetscValidHeaderSpecific(dm, DM_CLASSID,1); 2270 ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr); 2271 if (match) PetscFunctionReturn(0); 2272 2273 if (!DMRegisterAllCalled) {ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 2274 ierr = PetscFListFind(DMList, ((PetscObject)dm)->comm, method,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 2275 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method); 2276 2277 if (dm->ops->destroy) { 2278 ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr); 2279 dm->ops->destroy = PETSC_NULL; 2280 } 2281 ierr = (*r)(dm);CHKERRQ(ierr); 2282 ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr); 2283 PetscFunctionReturn(0); 2284 } 2285 2286 #undef __FUNCT__ 2287 #define __FUNCT__ "DMGetType" 2288 /*@C 2289 DMGetType - Gets the DM type name (as a string) from the DM. 2290 2291 Not Collective 2292 2293 Input Parameter: 2294 . dm - The DM 2295 2296 Output Parameter: 2297 . type - The DM type name 2298 2299 Level: intermediate 2300 2301 .keywords: DM, get, type, name 2302 .seealso: DMSetType(), DMCreate() 2303 @*/ 2304 PetscErrorCode DMGetType(DM dm, const DMType *type) 2305 { 2306 PetscErrorCode ierr; 2307 2308 PetscFunctionBegin; 2309 PetscValidHeaderSpecific(dm, DM_CLASSID,1); 2310 PetscValidCharPointer(type,2); 2311 if (!DMRegisterAllCalled) { 2312 ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr); 2313 } 2314 *type = ((PetscObject)dm)->type_name; 2315 PetscFunctionReturn(0); 2316 } 2317 2318 #undef __FUNCT__ 2319 #define __FUNCT__ "DMConvert" 2320 /*@C 2321 DMConvert - Converts a DM to another DM, either of the same or different type. 2322 2323 Collective on DM 2324 2325 Input Parameters: 2326 + dm - the DM 2327 - newtype - new DM type (use "same" for the same type) 2328 2329 Output Parameter: 2330 . M - pointer to new DM 2331 2332 Notes: 2333 Cannot be used to convert a sequential DM to parallel or parallel to sequential, 2334 the MPI communicator of the generated DM is always the same as the communicator 2335 of the input DM. 2336 2337 Level: intermediate 2338 2339 .seealso: DMCreate() 2340 @*/ 2341 PetscErrorCode DMConvert(DM dm, const DMType newtype, DM *M) 2342 { 2343 DM B; 2344 char convname[256]; 2345 PetscBool sametype, issame; 2346 PetscErrorCode ierr; 2347 2348 PetscFunctionBegin; 2349 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2350 PetscValidType(dm,1); 2351 PetscValidPointer(M,3); 2352 ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr); 2353 ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr); 2354 { 2355 PetscErrorCode (*conv)(DM, const DMType, DM *) = PETSC_NULL; 2356 2357 /* 2358 Order of precedence: 2359 1) See if a specialized converter is known to the current DM. 2360 2) See if a specialized converter is known to the desired DM class. 2361 3) See if a good general converter is registered for the desired class 2362 4) See if a good general converter is known for the current matrix. 2363 5) Use a really basic converter. 2364 */ 2365 2366 /* 1) See if a specialized converter is known to the current DM and the desired class */ 2367 ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr); 2368 ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr); 2369 ierr = PetscStrcat(convname,"_");CHKERRQ(ierr); 2370 ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr); 2371 ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr); 2372 ierr = PetscObjectQueryFunction((PetscObject)dm,convname,(void (**)(void))&conv);CHKERRQ(ierr); 2373 if (conv) goto foundconv; 2374 2375 /* 2) See if a specialized converter is known to the desired DM class. */ 2376 ierr = DMCreate(((PetscObject) dm)->comm, &B);CHKERRQ(ierr); 2377 ierr = DMSetType(B, newtype);CHKERRQ(ierr); 2378 ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr); 2379 ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr); 2380 ierr = PetscStrcat(convname,"_");CHKERRQ(ierr); 2381 ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr); 2382 ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr); 2383 ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr); 2384 if (conv) { 2385 ierr = DMDestroy(&B);CHKERRQ(ierr); 2386 goto foundconv; 2387 } 2388 2389 #if 0 2390 /* 3) See if a good general converter is registered for the desired class */ 2391 conv = B->ops->convertfrom; 2392 ierr = DMDestroy(&B);CHKERRQ(ierr); 2393 if (conv) goto foundconv; 2394 2395 /* 4) See if a good general converter is known for the current matrix */ 2396 if (dm->ops->convert) { 2397 conv = dm->ops->convert; 2398 } 2399 if (conv) goto foundconv; 2400 #endif 2401 2402 /* 5) Use a really basic converter. */ 2403 SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype); 2404 2405 foundconv: 2406 ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr); 2407 ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr); 2408 ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr); 2409 } 2410 ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr); 2411 PetscFunctionReturn(0); 2412 } 2413 2414 /*--------------------------------------------------------------------------------------------------------------------*/ 2415 2416 #undef __FUNCT__ 2417 #define __FUNCT__ "DMRegister" 2418 /*@C 2419 DMRegister - See DMRegisterDynamic() 2420 2421 Level: advanced 2422 @*/ 2423 PetscErrorCode DMRegister(const char sname[], const char path[], const char name[], PetscErrorCode (*function)(DM)) 2424 { 2425 char fullname[PETSC_MAX_PATH_LEN]; 2426 PetscErrorCode ierr; 2427 2428 PetscFunctionBegin; 2429 ierr = PetscStrcpy(fullname, path);CHKERRQ(ierr); 2430 ierr = PetscStrcat(fullname, ":");CHKERRQ(ierr); 2431 ierr = PetscStrcat(fullname, name);CHKERRQ(ierr); 2432 ierr = PetscFListAdd(&DMList, sname, fullname, (void (*)(void)) function);CHKERRQ(ierr); 2433 PetscFunctionReturn(0); 2434 } 2435 2436 2437 /*--------------------------------------------------------------------------------------------------------------------*/ 2438 #undef __FUNCT__ 2439 #define __FUNCT__ "DMRegisterDestroy" 2440 /*@C 2441 DMRegisterDestroy - Frees the list of DM methods that were registered by DMRegister()/DMRegisterDynamic(). 2442 2443 Not Collective 2444 2445 Level: advanced 2446 2447 .keywords: DM, register, destroy 2448 .seealso: DMRegister(), DMRegisterAll(), DMRegisterDynamic() 2449 @*/ 2450 PetscErrorCode DMRegisterDestroy(void) 2451 { 2452 PetscErrorCode ierr; 2453 2454 PetscFunctionBegin; 2455 ierr = PetscFListDestroy(&DMList);CHKERRQ(ierr); 2456 DMRegisterAllCalled = PETSC_FALSE; 2457 PetscFunctionReturn(0); 2458 } 2459 2460 #if defined(PETSC_HAVE_MATLAB_ENGINE) 2461 #include <mex.h> 2462 2463 typedef struct {char *funcname; char *jacname; mxArray *ctx;} DMMatlabContext; 2464 2465 #undef __FUNCT__ 2466 #define __FUNCT__ "DMComputeFunction_Matlab" 2467 /* 2468 DMComputeFunction_Matlab - Calls the function that has been set with 2469 DMSetFunctionMatlab(). 2470 2471 For linear problems x is null 2472 2473 .seealso: DMSetFunction(), DMGetFunction() 2474 */ 2475 PetscErrorCode DMComputeFunction_Matlab(DM dm,Vec x,Vec y) 2476 { 2477 PetscErrorCode ierr; 2478 DMMatlabContext *sctx; 2479 int nlhs = 1,nrhs = 4; 2480 mxArray *plhs[1],*prhs[4]; 2481 long long int lx = 0,ly = 0,ls = 0; 2482 2483 PetscFunctionBegin; 2484 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2485 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2486 PetscCheckSameComm(dm,1,y,3); 2487 2488 /* call Matlab function in ctx with arguments x and y */ 2489 ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr); 2490 ierr = PetscMemcpy(&ls,&dm,sizeof(dm));CHKERRQ(ierr); 2491 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 2492 ierr = PetscMemcpy(&ly,&y,sizeof(y));CHKERRQ(ierr); 2493 prhs[0] = mxCreateDoubleScalar((double)ls); 2494 prhs[1] = mxCreateDoubleScalar((double)lx); 2495 prhs[2] = mxCreateDoubleScalar((double)ly); 2496 prhs[3] = mxCreateString(sctx->funcname); 2497 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeFunctionInternal");CHKERRQ(ierr); 2498 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 2499 mxDestroyArray(prhs[0]); 2500 mxDestroyArray(prhs[1]); 2501 mxDestroyArray(prhs[2]); 2502 mxDestroyArray(prhs[3]); 2503 mxDestroyArray(plhs[0]); 2504 PetscFunctionReturn(0); 2505 } 2506 2507 2508 #undef __FUNCT__ 2509 #define __FUNCT__ "DMSetFunctionMatlab" 2510 /* 2511 DMSetFunctionMatlab - Sets the function evaluation routine 2512 2513 */ 2514 PetscErrorCode DMSetFunctionMatlab(DM dm,const char *func) 2515 { 2516 PetscErrorCode ierr; 2517 DMMatlabContext *sctx; 2518 2519 PetscFunctionBegin; 2520 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2521 /* currently sctx is memory bleed */ 2522 ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr); 2523 if (!sctx) { 2524 ierr = PetscMalloc(sizeof(DMMatlabContext),&sctx);CHKERRQ(ierr); 2525 } 2526 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 2527 ierr = DMSetApplicationContext(dm,sctx);CHKERRQ(ierr); 2528 ierr = DMSetFunction(dm,DMComputeFunction_Matlab);CHKERRQ(ierr); 2529 PetscFunctionReturn(0); 2530 } 2531 2532 #undef __FUNCT__ 2533 #define __FUNCT__ "DMComputeJacobian_Matlab" 2534 /* 2535 DMComputeJacobian_Matlab - Calls the function that has been set with 2536 DMSetJacobianMatlab(). 2537 2538 For linear problems x is null 2539 2540 .seealso: DMSetFunction(), DMGetFunction() 2541 */ 2542 PetscErrorCode DMComputeJacobian_Matlab(DM dm,Vec x,Mat A,Mat B,MatStructure *str) 2543 { 2544 PetscErrorCode ierr; 2545 DMMatlabContext *sctx; 2546 int nlhs = 2,nrhs = 5; 2547 mxArray *plhs[2],*prhs[5]; 2548 long long int lx = 0,lA = 0,lB = 0,ls = 0; 2549 2550 PetscFunctionBegin; 2551 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2552 PetscValidHeaderSpecific(A,MAT_CLASSID,3); 2553 2554 /* call MATLAB function in ctx with arguments x, A, and B */ 2555 ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr); 2556 ierr = PetscMemcpy(&ls,&dm,sizeof(dm));CHKERRQ(ierr); 2557 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 2558 ierr = PetscMemcpy(&lA,&A,sizeof(A));CHKERRQ(ierr); 2559 ierr = PetscMemcpy(&lB,&B,sizeof(B));CHKERRQ(ierr); 2560 prhs[0] = mxCreateDoubleScalar((double)ls); 2561 prhs[1] = mxCreateDoubleScalar((double)lx); 2562 prhs[2] = mxCreateDoubleScalar((double)lA); 2563 prhs[3] = mxCreateDoubleScalar((double)lB); 2564 prhs[4] = mxCreateString(sctx->jacname); 2565 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeJacobianInternal");CHKERRQ(ierr); 2566 *str = (MatStructure) mxGetScalar(plhs[0]); 2567 ierr = (PetscInt) mxGetScalar(plhs[1]);CHKERRQ(ierr); 2568 mxDestroyArray(prhs[0]); 2569 mxDestroyArray(prhs[1]); 2570 mxDestroyArray(prhs[2]); 2571 mxDestroyArray(prhs[3]); 2572 mxDestroyArray(prhs[4]); 2573 mxDestroyArray(plhs[0]); 2574 mxDestroyArray(plhs[1]); 2575 PetscFunctionReturn(0); 2576 } 2577 2578 2579 #undef __FUNCT__ 2580 #define __FUNCT__ "DMSetJacobianMatlab" 2581 /* 2582 DMSetJacobianMatlab - Sets the Jacobian function evaluation routine 2583 2584 */ 2585 PetscErrorCode DMSetJacobianMatlab(DM dm,const char *func) 2586 { 2587 PetscErrorCode ierr; 2588 DMMatlabContext *sctx; 2589 2590 PetscFunctionBegin; 2591 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2592 /* currently sctx is memory bleed */ 2593 ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr); 2594 if (!sctx) { 2595 ierr = PetscMalloc(sizeof(DMMatlabContext),&sctx);CHKERRQ(ierr); 2596 } 2597 ierr = PetscStrallocpy(func,&sctx->jacname);CHKERRQ(ierr); 2598 ierr = DMSetApplicationContext(dm,sctx);CHKERRQ(ierr); 2599 ierr = DMSetJacobian(dm,DMComputeJacobian_Matlab);CHKERRQ(ierr); 2600 PetscFunctionReturn(0); 2601 } 2602 #endif 2603 2604 #undef __FUNCT__ 2605 #define __FUNCT__ "DMLoad" 2606 /*@C 2607 DMLoad - Loads a DM that has been stored in binary or HDF5 format 2608 with DMView(). 2609 2610 Collective on PetscViewer 2611 2612 Input Parameters: 2613 + newdm - the newly loaded DM, this needs to have been created with DMCreate() or 2614 some related function before a call to DMLoad(). 2615 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or 2616 HDF5 file viewer, obtained from PetscViewerHDF5Open() 2617 2618 Level: intermediate 2619 2620 Notes: 2621 Defaults to the DM DA. 2622 2623 Notes for advanced users: 2624 Most users should not need to know the details of the binary storage 2625 format, since DMLoad() and DMView() completely hide these details. 2626 But for anyone who's interested, the standard binary matrix storage 2627 format is 2628 .vb 2629 has not yet been determined 2630 .ve 2631 2632 In addition, PETSc automatically does the byte swapping for 2633 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 2634 linux, Windows and the paragon; thus if you write your own binary 2635 read/write routines you have to swap the bytes; see PetscBinaryRead() 2636 and PetscBinaryWrite() to see how this may be done. 2637 2638 Concepts: vector^loading from file 2639 2640 .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad() 2641 @*/ 2642 PetscErrorCode DMLoad(DM newdm, PetscViewer viewer) 2643 { 2644 PetscErrorCode ierr; 2645 2646 PetscFunctionBegin; 2647 PetscValidHeaderSpecific(newdm,DM_CLASSID,1); 2648 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 2649 2650 if (!((PetscObject)newdm)->type_name) { 2651 ierr = DMSetType(newdm, DMDA);CHKERRQ(ierr); 2652 } 2653 ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr); 2654 PetscFunctionReturn(0); 2655 } 2656 2657 /******************************** FEM Support **********************************/ 2658 2659 #undef __FUNCT__ 2660 #define __FUNCT__ "DMPrintCellVector" 2661 PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) { 2662 PetscInt f; 2663 PetscErrorCode ierr; 2664 2665 PetscFunctionBegin; 2666 ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr); 2667 for(f = 0; f < len; ++f) { 2668 ierr = PetscPrintf(PETSC_COMM_SELF, " | %G |\n", PetscRealPart(x[f]));CHKERRQ(ierr); 2669 } 2670 PetscFunctionReturn(0); 2671 } 2672 2673 #undef __FUNCT__ 2674 #define __FUNCT__ "DMPrintCellMatrix" 2675 PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) { 2676 PetscInt f, g; 2677 PetscErrorCode ierr; 2678 2679 PetscFunctionBegin; 2680 ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr); 2681 for(f = 0; f < rows; ++f) { 2682 ierr = PetscPrintf(PETSC_COMM_SELF, " |");CHKERRQ(ierr); 2683 for(g = 0; g < cols; ++g) { 2684 ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5G", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr); 2685 } 2686 ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr); 2687 } 2688 PetscFunctionReturn(0); 2689 } 2690 2691 #undef __FUNCT__ 2692 #define __FUNCT__ "DMGetLocalFunction" 2693 /*@C 2694 DMGetLocalFunction - Get the local residual function from this DM 2695 2696 Not collective 2697 2698 Input Parameter: 2699 . dm - The DM 2700 2701 Output Parameter: 2702 . lf - The local residual function 2703 2704 Calling sequence of lf: 2705 $ lf (SNES snes, Vec x, Vec f, void *ctx); 2706 2707 + snes - the SNES context 2708 . x - local vector with the state at which to evaluate residual 2709 . f - local vector to put residual in 2710 - ctx - optional user-defined function context 2711 2712 Level: intermediate 2713 2714 .seealso DMSetLocalFunction(), DMGetLocalJacobian(), DMSetLocalJacobian() 2715 @*/ 2716 PetscErrorCode DMGetLocalFunction(DM dm, PetscErrorCode (**lf)(DM, Vec, Vec, void *)) 2717 { 2718 PetscFunctionBegin; 2719 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2720 if (lf) *lf = dm->lf; 2721 PetscFunctionReturn(0); 2722 } 2723 2724 #undef __FUNCT__ 2725 #define __FUNCT__ "DMSetLocalFunction" 2726 /*@C 2727 DMSetLocalFunction - Set the local residual function from this DM 2728 2729 Not collective 2730 2731 Input Parameters: 2732 + dm - The DM 2733 - lf - The local residual function 2734 2735 Calling sequence of lf: 2736 $ lf (SNES snes, Vec x, Vec f, void *ctx); 2737 2738 + snes - the SNES context 2739 . x - local vector with the state at which to evaluate residual 2740 . f - local vector to put residual in 2741 - ctx - optional user-defined function context 2742 2743 Level: intermediate 2744 2745 .seealso DMGetLocalFunction(), DMGetLocalJacobian(), DMSetLocalJacobian() 2746 @*/ 2747 PetscErrorCode DMSetLocalFunction(DM dm, PetscErrorCode (*lf)(DM, Vec, Vec, void *)) 2748 { 2749 PetscFunctionBegin; 2750 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2751 dm->lf = lf; 2752 PetscFunctionReturn(0); 2753 } 2754 2755 #undef __FUNCT__ 2756 #define __FUNCT__ "DMGetLocalJacobian" 2757 /*@C 2758 DMGetLocalJacobian - Get the local Jacobian function from this DM 2759 2760 Not collective 2761 2762 Input Parameter: 2763 . dm - The DM 2764 2765 Output Parameter: 2766 . lj - The local Jacobian function 2767 2768 Calling sequence of lj: 2769 $ lj (SNES snes, Vec x, Mat J, Mat M, void *ctx); 2770 2771 + snes - the SNES context 2772 . x - local vector with the state at which to evaluate residual 2773 . J - matrix to put Jacobian in 2774 . M - matrix to use for defining Jacobian preconditioner 2775 - ctx - optional user-defined function context 2776 2777 Level: intermediate 2778 2779 .seealso DMSetLocalJacobian(), DMGetLocalFunction(), DMSetLocalFunction() 2780 @*/ 2781 PetscErrorCode DMGetLocalJacobian(DM dm, PetscErrorCode (**lj)(DM, Vec, Mat, Mat, void *)) 2782 { 2783 PetscFunctionBegin; 2784 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2785 if (lj) *lj = dm->lj; 2786 PetscFunctionReturn(0); 2787 } 2788 2789 #undef __FUNCT__ 2790 #define __FUNCT__ "DMSetLocalJacobian" 2791 /*@C 2792 DMSetLocalJacobian - Set the local Jacobian function from this DM 2793 2794 Not collective 2795 2796 Input Parameters: 2797 + dm - The DM 2798 - lj - The local Jacobian function 2799 2800 Calling sequence of lj: 2801 $ lj (SNES snes, Vec x, Mat J, Mat M, void *ctx); 2802 2803 + snes - the SNES context 2804 . x - local vector with the state at which to evaluate residual 2805 . J - matrix to put Jacobian in 2806 . M - matrix to use for defining Jacobian preconditioner 2807 - ctx - optional user-defined function context 2808 2809 Level: intermediate 2810 2811 .seealso DMGetLocalJacobian(), DMGetLocalFunction(), DMSetLocalFunction() 2812 @*/ 2813 PetscErrorCode DMSetLocalJacobian(DM dm, PetscErrorCode (*lj)(DM, Vec, Mat, Mat, void *)) 2814 { 2815 PetscFunctionBegin; 2816 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2817 dm->lj = lj; 2818 PetscFunctionReturn(0); 2819 } 2820 2821 #undef __FUNCT__ 2822 #define __FUNCT__ "DMGetDefaultSection" 2823 /*@ 2824 DMGetDefaultSection - Get the PetscSection encoding the local data layout for the DM. 2825 2826 Input Parameter: 2827 . dm - The DM 2828 2829 Output Parameter: 2830 . section - The PetscSection 2831 2832 Level: intermediate 2833 2834 Note: This gets a borrowed reference, so the user should not destroy this PetscSection. 2835 2836 .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection() 2837 @*/ 2838 PetscErrorCode DMGetDefaultSection(DM dm, PetscSection *section) { 2839 PetscFunctionBegin; 2840 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2841 PetscValidPointer(section, 2); 2842 *section = dm->defaultSection; 2843 PetscFunctionReturn(0); 2844 } 2845 2846 #undef __FUNCT__ 2847 #define __FUNCT__ "DMSetDefaultSection" 2848 /*@ 2849 DMSetDefaultSection - Set the PetscSection encoding the local data layout for the DM. 2850 2851 Input Parameters: 2852 + dm - The DM 2853 - section - The PetscSection 2854 2855 Level: intermediate 2856 2857 Note: Any existing Section will be destroyed 2858 2859 .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection() 2860 @*/ 2861 PetscErrorCode DMSetDefaultSection(DM dm, PetscSection section) { 2862 PetscErrorCode ierr; 2863 2864 PetscFunctionBegin; 2865 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2866 ierr = PetscSectionDestroy(&dm->defaultSection);CHKERRQ(ierr); 2867 ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr); 2868 dm->defaultSection = section; 2869 PetscFunctionReturn(0); 2870 } 2871 2872 #undef __FUNCT__ 2873 #define __FUNCT__ "DMGetDefaultGlobalSection" 2874 /*@ 2875 DMGetDefaultGlobalSection - Get the PetscSection encoding the global data layout for the DM. 2876 2877 Input Parameter: 2878 . dm - The DM 2879 2880 Output Parameter: 2881 . section - The PetscSection 2882 2883 Level: intermediate 2884 2885 Note: This gets a borrowed reference, so the user should not destroy this PetscSection. 2886 2887 .seealso: DMSetDefaultSection(), DMGetDefaultSection() 2888 @*/ 2889 PetscErrorCode DMGetDefaultGlobalSection(DM dm, PetscSection *section) { 2890 PetscErrorCode ierr; 2891 2892 PetscFunctionBegin; 2893 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2894 PetscValidPointer(section, 2); 2895 if (!dm->defaultGlobalSection) { 2896 ierr = PetscSectionCreateGlobalSection(dm->defaultSection, dm->sf, &dm->defaultGlobalSection);CHKERRQ(ierr); 2897 } 2898 *section = dm->defaultGlobalSection; 2899 PetscFunctionReturn(0); 2900 } 2901 2902 #undef __FUNCT__ 2903 #define __FUNCT__ "DMGetDefaultSF" 2904 /*@ 2905 DMGetDefaultSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set, 2906 it is created from the default PetscSection layouts in the DM. 2907 2908 Input Parameter: 2909 . dm - The DM 2910 2911 Output Parameter: 2912 . sf - The PetscSF 2913 2914 Level: intermediate 2915 2916 Note: This gets a borrowed reference, so the user should not destroy this PetscSF. 2917 2918 .seealso: DMSetDefaultSF(), DMCreateDefaultSF() 2919 @*/ 2920 PetscErrorCode DMGetDefaultSF(DM dm, PetscSF *sf) { 2921 PetscInt nroots; 2922 PetscErrorCode ierr; 2923 2924 PetscFunctionBegin; 2925 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2926 PetscValidPointer(sf, 2); 2927 ierr = PetscSFGetGraph(dm->defaultSF, &nroots, PETSC_NULL, PETSC_NULL, PETSC_NULL);CHKERRQ(ierr); 2928 if (nroots < 0) { 2929 PetscSection section, gSection; 2930 2931 ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 2932 if (section) { 2933 ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr); 2934 ierr = DMCreateDefaultSF(dm, section, gSection);CHKERRQ(ierr); 2935 } else { 2936 *sf = PETSC_NULL; 2937 PetscFunctionReturn(0); 2938 } 2939 } 2940 *sf = dm->defaultSF; 2941 PetscFunctionReturn(0); 2942 } 2943 2944 #undef __FUNCT__ 2945 #define __FUNCT__ "DMSetDefaultSF" 2946 /*@ 2947 DMSetDefaultSF - Set the PetscSF encoding the parallel dof overlap for the DM 2948 2949 Input Parameters: 2950 + dm - The DM 2951 - sf - The PetscSF 2952 2953 Level: intermediate 2954 2955 Note: Any previous SF is destroyed 2956 2957 .seealso: DMGetDefaultSF(), DMCreateDefaultSF() 2958 @*/ 2959 PetscErrorCode DMSetDefaultSF(DM dm, PetscSF sf) { 2960 PetscErrorCode ierr; 2961 2962 PetscFunctionBegin; 2963 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2964 PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 2965 ierr = PetscSFDestroy(&dm->defaultSF);CHKERRQ(ierr); 2966 dm->defaultSF = sf; 2967 PetscFunctionReturn(0); 2968 } 2969 2970 #undef __FUNCT__ 2971 #define __FUNCT__ "DMCreateDefaultSF" 2972 /*@C 2973 DMCreateDefaultSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections 2974 describing the data layout. 2975 2976 Input Parameters: 2977 + dm - The DM 2978 . localSection - PetscSection describing the local data layout 2979 - globalSection - PetscSection describing the global data layout 2980 2981 Level: intermediate 2982 2983 .seealso: DMGetDefaultSF(), DMSetDefaultSF() 2984 @*/ 2985 PetscErrorCode DMCreateDefaultSF(DM dm, PetscSection localSection, PetscSection globalSection) 2986 { 2987 MPI_Comm comm = ((PetscObject) dm)->comm; 2988 PetscLayout layout; 2989 const PetscInt *ranges; 2990 PetscInt *local; 2991 PetscSFNode *remote; 2992 PetscInt pStart, pEnd, p, nroots, nleaves, l; 2993 PetscMPIInt size, rank; 2994 PetscErrorCode ierr; 2995 2996 PetscFunctionBegin; 2997 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2998 ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 2999 ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 3000 ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr); 3001 ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr); 3002 ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr); 3003 ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr); 3004 ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr); 3005 ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr); 3006 ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr); 3007 for(p = pStart, nleaves = 0; p < pEnd; ++p) { 3008 PetscInt dof, cdof; 3009 3010 ierr = PetscSectionGetDof(globalSection, p, &dof);CHKERRQ(ierr); 3011 ierr = PetscSectionGetConstraintDof(globalSection, p, &cdof);CHKERRQ(ierr); 3012 nleaves += dof < 0 ? -(dof+1)-cdof : dof-cdof; 3013 } 3014 ierr = PetscMalloc(nleaves * sizeof(PetscInt), &local);CHKERRQ(ierr); 3015 ierr = PetscMalloc(nleaves * sizeof(PetscSFNode), &remote);CHKERRQ(ierr); 3016 for(p = pStart, l = 0; p < pEnd; ++p) { 3017 PetscInt *cind; 3018 PetscInt dof, gdof, cdof, dim, off, goff, d, c; 3019 3020 ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr); 3021 ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr); 3022 ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr); 3023 ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr); 3024 ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr); 3025 ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr); 3026 dim = dof-cdof; 3027 for(d = 0, c = 0; d < dof; ++d) { 3028 if ((c < cdof) && (cind[c] == d)) {++c; continue;} 3029 local[l+d-c] = off+d; 3030 } 3031 if (gdof < 0) { 3032 for(d = 0; d < dim; ++d, ++l) { 3033 PetscInt offset = -(goff+1) + d, r; 3034 3035 for(r = 0; r < size; ++r) { 3036 if ((offset >= ranges[r]) && (offset < ranges[r+1])) break; 3037 } 3038 remote[l].rank = r; 3039 remote[l].index = offset - ranges[r]; 3040 } 3041 } else { 3042 for(d = 0; d < dim; ++d, ++l) { 3043 remote[l].rank = rank; 3044 remote[l].index = goff+d - ranges[rank]; 3045 } 3046 } 3047 } 3048 ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 3049 ierr = PetscSFSetGraph(dm->defaultSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr); 3050 PetscFunctionReturn(0); 3051 } 3052