1af0996ceSBarry Smith #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/ 2c58f1c22SToby Isaac #include <petsc/private/dmlabelimpl.h> /*I "petscdmlabel.h" I*/ 3e6f8dbb6SToby Isaac #include <petsc/private/petscdsimpl.h> /*I "petscds.h" I*/ 43e922f36SToby Isaac #include <petscdmplex.h> 50c312b8eSJed Brown #include <petscsf.h> 62764a2aaSMatthew G. Knepley #include <petscds.h> 747c6ae99SBarry Smith 8732e2eb9SMatthew G Knepley PetscClassId DM_CLASSID; 91ac00216SMatthew G. Knepley PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal, DM_LocalToLocal, DM_LocatePoints, DM_Coarsen, DM_Refine, DM_CreateInterpolation, DM_CreateRestriction; 1067a56275SMatthew G Knepley 11bff4a2f0SMatthew G. Knepley const char *const DMBoundaryTypes[] = {"NONE","GHOSTED","MIRROR","PERIODIC","TWIST","DM_BOUNDARY_",0}; 12bff4a2f0SMatthew G. Knepley 13a4121054SBarry Smith /*@ 14de043629SMatthew G Knepley DMCreate - Creates an empty DM object. The type can then be set with DMSetType(). 15a4121054SBarry Smith 16a4121054SBarry Smith If you never call DMSetType() it will generate an 17a4121054SBarry Smith error when you try to use the vector. 18a4121054SBarry Smith 19a4121054SBarry Smith Collective on MPI_Comm 20a4121054SBarry Smith 21a4121054SBarry Smith Input Parameter: 22a4121054SBarry Smith . comm - The communicator for the DM object 23a4121054SBarry Smith 24a4121054SBarry Smith Output Parameter: 25a4121054SBarry Smith . dm - The DM object 26a4121054SBarry Smith 27a4121054SBarry Smith Level: beginner 28a4121054SBarry Smith 298472ad0fSDave May .seealso: DMSetType(), DMDA, DMSLICED, DMCOMPOSITE, DMPLEX, DMMOAB, DMNETWORK 30a4121054SBarry Smith @*/ 317087cfbeSBarry Smith PetscErrorCode DMCreate(MPI_Comm comm,DM *dm) 32a4121054SBarry Smith { 33a4121054SBarry Smith DM v; 34a4121054SBarry Smith PetscErrorCode ierr; 35a4121054SBarry Smith 36a4121054SBarry Smith PetscFunctionBegin; 371411c6eeSJed Brown PetscValidPointer(dm,2); 380298fd71SBarry Smith *dm = NULL; 398b984314SMatthew G. Knepley ierr = PetscSysInitializePackage();CHKERRQ(ierr); 40607a6623SBarry Smith ierr = VecInitializePackage();CHKERRQ(ierr); 41607a6623SBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 42607a6623SBarry Smith ierr = DMInitializePackage();CHKERRQ(ierr); 43a4121054SBarry Smith 4473107ff1SLisandro Dalcin ierr = PetscHeaderCreate(v, DM_CLASSID, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView);CHKERRQ(ierr); 45e7c4fc90SDmitry Karpeev 460298fd71SBarry Smith v->ltogmap = NULL; 471411c6eeSJed Brown v->bs = 1; 48171400e9SBarry Smith v->coloringtype = IS_COLORING_GLOBAL; 4988ed4aceSMatthew G Knepley ierr = PetscSFCreate(comm, &v->sf);CHKERRQ(ierr); 5088ed4aceSMatthew G Knepley ierr = PetscSFCreate(comm, &v->defaultSF);CHKERRQ(ierr); 51c58f1c22SToby Isaac v->labels = NULL; 52c58f1c22SToby Isaac v->depthLabel = NULL; 530298fd71SBarry Smith v->defaultSection = NULL; 540298fd71SBarry Smith v->defaultGlobalSection = NULL; 55fba222abSToby Isaac v->defaultConstraintSection = NULL; 56fba222abSToby Isaac v->defaultConstraintMat = NULL; 57c6b900c6SMatthew G. Knepley v->L = NULL; 58c6b900c6SMatthew G. Knepley v->maxCell = NULL; 595dc8c3f7SMatthew G. Knepley v->bdtype = NULL; 609a9a41abSToby Isaac v->dimEmbed = PETSC_DEFAULT; 61435a35e8SMatthew G Knepley { 62435a35e8SMatthew G Knepley PetscInt i; 63435a35e8SMatthew G Knepley for (i = 0; i < 10; ++i) { 640298fd71SBarry Smith v->nullspaceConstructors[i] = NULL; 65435a35e8SMatthew G Knepley } 66435a35e8SMatthew G Knepley } 672764a2aaSMatthew G. Knepley ierr = PetscDSCreate(comm, &v->prob);CHKERRQ(ierr); 6814f150ffSMatthew G. Knepley v->dmBC = NULL; 69a8fb8f29SToby Isaac v->coarseMesh = NULL; 70f4d763aaSMatthew G. Knepley v->outputSequenceNum = -1; 71cdb7a50dSMatthew G. Knepley v->outputSequenceVal = 0.0; 72c0dedaeaSBarry Smith ierr = DMSetVecType(v,VECSTANDARD);CHKERRQ(ierr); 73b412c318SBarry Smith ierr = DMSetMatType(v,MATAIJ);CHKERRQ(ierr); 74bcc5ffd9SToby Isaac ierr = PetscNew(&(v->labels));CHKERRQ(ierr); 75c58f1c22SToby Isaac v->labels->refct = 1; 761411c6eeSJed Brown *dm = v; 77a4121054SBarry Smith PetscFunctionReturn(0); 78a4121054SBarry Smith } 79a4121054SBarry Smith 8038221697SMatthew G. Knepley /*@ 8138221697SMatthew G. Knepley DMClone - Creates a DM object with the same topology as the original. 8238221697SMatthew G. Knepley 8338221697SMatthew G. Knepley Collective on MPI_Comm 8438221697SMatthew G. Knepley 8538221697SMatthew G. Knepley Input Parameter: 8638221697SMatthew G. Knepley . dm - The original DM object 8738221697SMatthew G. Knepley 8838221697SMatthew G. Knepley Output Parameter: 8938221697SMatthew G. Knepley . newdm - The new DM object 9038221697SMatthew G. Knepley 9138221697SMatthew G. Knepley Level: beginner 9238221697SMatthew G. Knepley 9338221697SMatthew G. Knepley .keywords: DM, topology, create 9438221697SMatthew G. Knepley @*/ 9538221697SMatthew G. Knepley PetscErrorCode DMClone(DM dm, DM *newdm) 9638221697SMatthew G. Knepley { 9738221697SMatthew G. Knepley PetscSF sf; 9838221697SMatthew G. Knepley Vec coords; 9938221697SMatthew G. Knepley void *ctx; 100a3219837SMatthew G. Knepley PetscInt dim, cdim; 10138221697SMatthew G. Knepley PetscErrorCode ierr; 10238221697SMatthew G. Knepley 10338221697SMatthew G. Knepley PetscFunctionBegin; 10438221697SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10538221697SMatthew G. Knepley PetscValidPointer(newdm,2); 10638221697SMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject) dm), newdm);CHKERRQ(ierr); 107c58f1c22SToby Isaac ierr = PetscFree((*newdm)->labels);CHKERRQ(ierr); 108c58f1c22SToby Isaac dm->labels->refct++; 109c58f1c22SToby Isaac (*newdm)->labels = dm->labels; 110c58f1c22SToby Isaac (*newdm)->depthLabel = dm->depthLabel; 1111de53e9aSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1121de53e9aSMatthew G. Knepley ierr = DMSetDimension(*newdm, dim);CHKERRQ(ierr); 11338221697SMatthew G. Knepley if (dm->ops->clone) { 11438221697SMatthew G. Knepley ierr = (*dm->ops->clone)(dm, newdm);CHKERRQ(ierr); 11538221697SMatthew G. Knepley } 1163f22bcbcSToby Isaac (*newdm)->setupcalled = dm->setupcalled; 11738221697SMatthew G. Knepley ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 11838221697SMatthew G. Knepley ierr = DMSetPointSF(*newdm, sf);CHKERRQ(ierr); 11938221697SMatthew G. Knepley ierr = DMGetApplicationContext(dm, &ctx);CHKERRQ(ierr); 12038221697SMatthew G. Knepley ierr = DMSetApplicationContext(*newdm, ctx);CHKERRQ(ierr); 121be4c1c3eSMatthew G. Knepley if (dm->coordinateDM) { 122be4c1c3eSMatthew G. Knepley DM ncdm; 123be4c1c3eSMatthew G. Knepley PetscSection cs; 1245a0206caSToby Isaac PetscInt pEnd = -1, pEndMax = -1; 125be4c1c3eSMatthew G. Knepley 126be4c1c3eSMatthew G. Knepley ierr = DMGetDefaultSection(dm->coordinateDM, &cs);CHKERRQ(ierr); 127be4c1c3eSMatthew G. Knepley if (cs) {ierr = PetscSectionGetChart(cs, NULL, &pEnd);CHKERRQ(ierr);} 1285a0206caSToby Isaac ierr = MPI_Allreduce(&pEnd,&pEndMax,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 1295a0206caSToby Isaac if (pEndMax >= 0) { 130be4c1c3eSMatthew G. Knepley ierr = DMClone(dm->coordinateDM, &ncdm);CHKERRQ(ierr); 13113bffc4cSMatthew G. Knepley ierr = DMSetDefaultSection(ncdm, cs);CHKERRQ(ierr); 132a61e840bSMatthew G. Knepley ierr = DMSetCoordinateDM(*newdm, ncdm);CHKERRQ(ierr); 133be4c1c3eSMatthew G. Knepley ierr = DMDestroy(&ncdm);CHKERRQ(ierr); 134be4c1c3eSMatthew G. Knepley } 135be4c1c3eSMatthew G. Knepley } 136a3219837SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 137a3219837SMatthew G. Knepley ierr = DMSetCoordinateDim(*newdm, cdim);CHKERRQ(ierr); 13838221697SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coords);CHKERRQ(ierr); 13938221697SMatthew G. Knepley if (coords) { 14038221697SMatthew G. Knepley ierr = DMSetCoordinatesLocal(*newdm, coords);CHKERRQ(ierr); 14138221697SMatthew G. Knepley } else { 14238221697SMatthew G. Knepley ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr); 14338221697SMatthew G. Knepley if (coords) {ierr = DMSetCoordinates(*newdm, coords);CHKERRQ(ierr);} 14438221697SMatthew G. Knepley } 145c6b900c6SMatthew G. Knepley if (dm->maxCell) { 146c6b900c6SMatthew G. Knepley const PetscReal *maxCell, *L; 1475dc8c3f7SMatthew G. Knepley const DMBoundaryType *bd; 1485dc8c3f7SMatthew G. Knepley ierr = DMGetPeriodicity(dm, &maxCell, &L, &bd);CHKERRQ(ierr); 1495dc8c3f7SMatthew G. Knepley ierr = DMSetPeriodicity(*newdm, maxCell, L, bd);CHKERRQ(ierr); 150c6b900c6SMatthew G. Knepley } 15138221697SMatthew G. Knepley PetscFunctionReturn(0); 15238221697SMatthew G. Knepley } 15338221697SMatthew G. Knepley 1549a42bb27SBarry Smith /*@C 155564755cdSBarry Smith DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector() 1569a42bb27SBarry Smith 1578472ad0fSDave May Logically Collective on DM 1589a42bb27SBarry Smith 1599a42bb27SBarry Smith Input Parameter: 1609a42bb27SBarry Smith + da - initial distributed array 1618154be41SBarry Smith . ctype - the vector type, currently either VECSTANDARD or VECCUSP 1629a42bb27SBarry Smith 1639a42bb27SBarry Smith Options Database: 164dd85299cSBarry Smith . -dm_vec_type ctype 1659a42bb27SBarry Smith 1669a42bb27SBarry Smith Level: intermediate 1679a42bb27SBarry Smith 1688472ad0fSDave May .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType, DMGetVecType() 1699a42bb27SBarry Smith @*/ 17019fd82e9SBarry Smith PetscErrorCode DMSetVecType(DM da,VecType ctype) 1719a42bb27SBarry Smith { 1729a42bb27SBarry Smith PetscErrorCode ierr; 1739a42bb27SBarry Smith 1749a42bb27SBarry Smith PetscFunctionBegin; 1759a42bb27SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 1769a42bb27SBarry Smith ierr = PetscFree(da->vectype);CHKERRQ(ierr); 17719fd82e9SBarry Smith ierr = PetscStrallocpy(ctype,(char**)&da->vectype);CHKERRQ(ierr); 1789a42bb27SBarry Smith PetscFunctionReturn(0); 1799a42bb27SBarry Smith } 1809a42bb27SBarry Smith 181c0dedaeaSBarry Smith /*@C 182c0dedaeaSBarry Smith DMGetVecType - Gets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector() 183c0dedaeaSBarry Smith 1848472ad0fSDave May Logically Collective on DM 185c0dedaeaSBarry Smith 186c0dedaeaSBarry Smith Input Parameter: 187c0dedaeaSBarry Smith . da - initial distributed array 188c0dedaeaSBarry Smith 189c0dedaeaSBarry Smith Output Parameter: 190c0dedaeaSBarry Smith . ctype - the vector type 191c0dedaeaSBarry Smith 192c0dedaeaSBarry Smith Level: intermediate 193c0dedaeaSBarry Smith 1948472ad0fSDave May .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType 195c0dedaeaSBarry Smith @*/ 196c0dedaeaSBarry Smith PetscErrorCode DMGetVecType(DM da,VecType *ctype) 197c0dedaeaSBarry Smith { 198c0dedaeaSBarry Smith PetscFunctionBegin; 199c0dedaeaSBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 200c0dedaeaSBarry Smith *ctype = da->vectype; 201c0dedaeaSBarry Smith PetscFunctionReturn(0); 202c0dedaeaSBarry Smith } 203c0dedaeaSBarry Smith 2045f1ad066SMatthew G Knepley /*@ 20534f98d34SBarry Smith VecGetDM - Gets the DM defining the data layout of the vector 2065f1ad066SMatthew G Knepley 2075f1ad066SMatthew G Knepley Not collective 2085f1ad066SMatthew G Knepley 2095f1ad066SMatthew G Knepley Input Parameter: 2105f1ad066SMatthew G Knepley . v - The Vec 2115f1ad066SMatthew G Knepley 2125f1ad066SMatthew G Knepley Output Parameter: 2135f1ad066SMatthew G Knepley . dm - The DM 2145f1ad066SMatthew G Knepley 2155f1ad066SMatthew G Knepley Level: intermediate 2165f1ad066SMatthew G Knepley 2175f1ad066SMatthew G Knepley .seealso: VecSetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType() 2185f1ad066SMatthew G Knepley @*/ 2195f1ad066SMatthew G Knepley PetscErrorCode VecGetDM(Vec v, DM *dm) 2205f1ad066SMatthew G Knepley { 2215f1ad066SMatthew G Knepley PetscErrorCode ierr; 2225f1ad066SMatthew G Knepley 2235f1ad066SMatthew G Knepley PetscFunctionBegin; 2245f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,1); 2255f1ad066SMatthew G Knepley PetscValidPointer(dm,2); 2265f1ad066SMatthew G Knepley ierr = PetscObjectQuery((PetscObject) v, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr); 2275f1ad066SMatthew G Knepley PetscFunctionReturn(0); 2285f1ad066SMatthew G Knepley } 2295f1ad066SMatthew G Knepley 2305f1ad066SMatthew G Knepley /*@ 231d9805387SMatthew G. Knepley VecSetDM - Sets the DM defining the data layout of the vector. 2325f1ad066SMatthew G Knepley 2335f1ad066SMatthew G Knepley Not collective 2345f1ad066SMatthew G Knepley 2355f1ad066SMatthew G Knepley Input Parameters: 2365f1ad066SMatthew G Knepley + v - The Vec 2375f1ad066SMatthew G Knepley - dm - The DM 2385f1ad066SMatthew G Knepley 239d9805387SMatthew G. Knepley Note: This is NOT the same as DMCreateGlobalVector() since it does not change the view methods or perform other customization, but merely sets the DM member. 240d9805387SMatthew G. Knepley 2415f1ad066SMatthew G Knepley Level: intermediate 2425f1ad066SMatthew G Knepley 2435f1ad066SMatthew G Knepley .seealso: VecGetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType() 2445f1ad066SMatthew G Knepley @*/ 2455f1ad066SMatthew G Knepley PetscErrorCode VecSetDM(Vec v, DM dm) 2465f1ad066SMatthew G Knepley { 2475f1ad066SMatthew G Knepley PetscErrorCode ierr; 2485f1ad066SMatthew G Knepley 2495f1ad066SMatthew G Knepley PetscFunctionBegin; 2505f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,1); 251d7f50e27SLisandro Dalcin if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2); 2525f1ad066SMatthew G Knepley ierr = PetscObjectCompose((PetscObject) v, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 2535f1ad066SMatthew G Knepley PetscFunctionReturn(0); 2545f1ad066SMatthew G Knepley } 2555f1ad066SMatthew G Knepley 256521d9a4cSLisandro Dalcin /*@C 257521d9a4cSLisandro Dalcin DMSetMatType - Sets the type of matrix created with DMCreateMatrix() 258521d9a4cSLisandro Dalcin 259521d9a4cSLisandro Dalcin Logically Collective on DM 260521d9a4cSLisandro Dalcin 261521d9a4cSLisandro Dalcin Input Parameter: 262521d9a4cSLisandro Dalcin + dm - the DM context 263a2b5a043SBarry Smith - ctype - the matrix type 264521d9a4cSLisandro Dalcin 265521d9a4cSLisandro Dalcin Options Database: 266521d9a4cSLisandro Dalcin . -dm_mat_type ctype 267521d9a4cSLisandro Dalcin 268521d9a4cSLisandro Dalcin Level: intermediate 269521d9a4cSLisandro Dalcin 270c0dedaeaSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType() 271521d9a4cSLisandro Dalcin @*/ 27219fd82e9SBarry Smith PetscErrorCode DMSetMatType(DM dm,MatType ctype) 273521d9a4cSLisandro Dalcin { 274521d9a4cSLisandro Dalcin PetscErrorCode ierr; 27588f0584fSBarry Smith 276521d9a4cSLisandro Dalcin PetscFunctionBegin; 277521d9a4cSLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 278521d9a4cSLisandro Dalcin ierr = PetscFree(dm->mattype);CHKERRQ(ierr); 27919fd82e9SBarry Smith ierr = PetscStrallocpy(ctype,(char**)&dm->mattype);CHKERRQ(ierr); 280521d9a4cSLisandro Dalcin PetscFunctionReturn(0); 281521d9a4cSLisandro Dalcin } 282521d9a4cSLisandro Dalcin 283c0dedaeaSBarry Smith /*@C 284c0dedaeaSBarry Smith DMGetMatType - Gets the type of matrix created with DMCreateMatrix() 285c0dedaeaSBarry Smith 286c0dedaeaSBarry Smith Logically Collective on DM 287c0dedaeaSBarry Smith 288c0dedaeaSBarry Smith Input Parameter: 289c0dedaeaSBarry Smith . dm - the DM context 290c0dedaeaSBarry Smith 291c0dedaeaSBarry Smith Output Parameter: 292c0dedaeaSBarry Smith . ctype - the matrix type 293c0dedaeaSBarry Smith 294c0dedaeaSBarry Smith Options Database: 295c0dedaeaSBarry Smith . -dm_mat_type ctype 296c0dedaeaSBarry Smith 297c0dedaeaSBarry Smith Level: intermediate 298c0dedaeaSBarry Smith 299c0dedaeaSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMSetMatType() 300c0dedaeaSBarry Smith @*/ 301c0dedaeaSBarry Smith PetscErrorCode DMGetMatType(DM dm,MatType *ctype) 302c0dedaeaSBarry Smith { 303c0dedaeaSBarry Smith PetscFunctionBegin; 304c0dedaeaSBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 305c0dedaeaSBarry Smith *ctype = dm->mattype; 306c0dedaeaSBarry Smith PetscFunctionReturn(0); 307c0dedaeaSBarry Smith } 308c0dedaeaSBarry Smith 309c688c046SMatthew G Knepley /*@ 31034f98d34SBarry Smith MatGetDM - Gets the DM defining the data layout of the matrix 311c688c046SMatthew G Knepley 312c688c046SMatthew G Knepley Not collective 313c688c046SMatthew G Knepley 314c688c046SMatthew G Knepley Input Parameter: 315c688c046SMatthew G Knepley . A - The Mat 316c688c046SMatthew G Knepley 317c688c046SMatthew G Knepley Output Parameter: 318c688c046SMatthew G Knepley . dm - The DM 319c688c046SMatthew G Knepley 320c688c046SMatthew G Knepley Level: intermediate 321c688c046SMatthew G Knepley 322c688c046SMatthew G Knepley .seealso: MatSetDM(), DMCreateMatrix(), DMSetMatType() 323c688c046SMatthew G Knepley @*/ 324c688c046SMatthew G Knepley PetscErrorCode MatGetDM(Mat A, DM *dm) 325c688c046SMatthew G Knepley { 326c688c046SMatthew G Knepley PetscErrorCode ierr; 327c688c046SMatthew G Knepley 328c688c046SMatthew G Knepley PetscFunctionBegin; 329c688c046SMatthew G Knepley PetscValidHeaderSpecific(A,MAT_CLASSID,1); 330c688c046SMatthew G Knepley PetscValidPointer(dm,2); 331c688c046SMatthew G Knepley ierr = PetscObjectQuery((PetscObject) A, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr); 332c688c046SMatthew G Knepley PetscFunctionReturn(0); 333c688c046SMatthew G Knepley } 334c688c046SMatthew G Knepley 335c688c046SMatthew G Knepley /*@ 336c688c046SMatthew G Knepley MatSetDM - Sets the DM defining the data layout of the matrix 337c688c046SMatthew G Knepley 338c688c046SMatthew G Knepley Not collective 339c688c046SMatthew G Knepley 340c688c046SMatthew G Knepley Input Parameters: 341c688c046SMatthew G Knepley + A - The Mat 342c688c046SMatthew G Knepley - dm - The DM 343c688c046SMatthew G Knepley 344c688c046SMatthew G Knepley Level: intermediate 345c688c046SMatthew G Knepley 346c688c046SMatthew G Knepley .seealso: MatGetDM(), DMCreateMatrix(), DMSetMatType() 347c688c046SMatthew G Knepley @*/ 348c688c046SMatthew G Knepley PetscErrorCode MatSetDM(Mat A, DM dm) 349c688c046SMatthew G Knepley { 350c688c046SMatthew G Knepley PetscErrorCode ierr; 351c688c046SMatthew G Knepley 352c688c046SMatthew G Knepley PetscFunctionBegin; 353c688c046SMatthew G Knepley PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3548865f1eaSKarl Rupp if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2); 355c688c046SMatthew G Knepley ierr = PetscObjectCompose((PetscObject) A, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 356c688c046SMatthew G Knepley PetscFunctionReturn(0); 357c688c046SMatthew G Knepley } 358c688c046SMatthew G Knepley 3599a42bb27SBarry Smith /*@C 3609a42bb27SBarry Smith DMSetOptionsPrefix - Sets the prefix used for searching for all 3616757b960SDave May DM options in the database. 3629a42bb27SBarry Smith 3638353ddbbSDave May Logically Collective on DM 3649a42bb27SBarry Smith 3659a42bb27SBarry Smith Input Parameter: 3668353ddbbSDave May + da - the DM context 3679a42bb27SBarry Smith - prefix - the prefix to prepend to all option names 3689a42bb27SBarry Smith 3699a42bb27SBarry Smith Notes: 3709a42bb27SBarry Smith A hyphen (-) must NOT be given at the beginning of the prefix name. 3719a42bb27SBarry Smith The first character of all runtime options is AUTOMATICALLY the hyphen. 3729a42bb27SBarry Smith 3739a42bb27SBarry Smith Level: advanced 3749a42bb27SBarry Smith 3758353ddbbSDave May .keywords: DM, set, options, prefix, database 3769a42bb27SBarry Smith 3779a42bb27SBarry Smith .seealso: DMSetFromOptions() 3789a42bb27SBarry Smith @*/ 3797087cfbeSBarry Smith PetscErrorCode DMSetOptionsPrefix(DM dm,const char prefix[]) 3809a42bb27SBarry Smith { 3819a42bb27SBarry Smith PetscErrorCode ierr; 3829a42bb27SBarry Smith 3839a42bb27SBarry Smith PetscFunctionBegin; 3849a42bb27SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3859a42bb27SBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 386691be533SLawrence Mitchell if (dm->sf) { 387691be533SLawrence Mitchell ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->sf,prefix);CHKERRQ(ierr); 388691be533SLawrence Mitchell } 389691be533SLawrence Mitchell if (dm->defaultSF) { 390691be533SLawrence Mitchell ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->defaultSF,prefix);CHKERRQ(ierr); 391691be533SLawrence Mitchell } 3929a42bb27SBarry Smith PetscFunctionReturn(0); 3939a42bb27SBarry Smith } 3949a42bb27SBarry Smith 39531697293SDave May /*@C 39631697293SDave May DMAppendOptionsPrefix - Appends to the prefix used for searching for all 39731697293SDave May DM options in the database. 39831697293SDave May 39931697293SDave May Logically Collective on DM 40031697293SDave May 40131697293SDave May Input Parameters: 40231697293SDave May + dm - the DM context 40331697293SDave May - prefix - the prefix string to prepend to all DM option requests 40431697293SDave May 40531697293SDave May Notes: 40631697293SDave May A hyphen (-) must NOT be given at the beginning of the prefix name. 40731697293SDave May The first character of all runtime options is AUTOMATICALLY the hyphen. 40831697293SDave May 40931697293SDave May Level: advanced 41031697293SDave May 41131697293SDave May .keywords: DM, append, options, prefix, database 41231697293SDave May 41331697293SDave May .seealso: DMSetOptionsPrefix(), DMGetOptionsPrefix() 41431697293SDave May @*/ 41531697293SDave May PetscErrorCode DMAppendOptionsPrefix(DM dm,const char prefix[]) 41631697293SDave May { 41731697293SDave May PetscErrorCode ierr; 41831697293SDave May 41931697293SDave May PetscFunctionBegin; 42031697293SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 42131697293SDave May ierr = PetscObjectAppendOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 42231697293SDave May PetscFunctionReturn(0); 42331697293SDave May } 42431697293SDave May 42531697293SDave May /*@C 42631697293SDave May DMGetOptionsPrefix - Gets the prefix used for searching for all 42731697293SDave May DM options in the database. 42831697293SDave May 42931697293SDave May Not Collective 43031697293SDave May 43131697293SDave May Input Parameters: 43231697293SDave May . dm - the DM context 43331697293SDave May 43431697293SDave May Output Parameters: 43531697293SDave May . prefix - pointer to the prefix string used is returned 43631697293SDave May 43731697293SDave May Notes: On the fortran side, the user should pass in a string 'prefix' of 43831697293SDave May sufficient length to hold the prefix. 43931697293SDave May 44031697293SDave May Level: advanced 44131697293SDave May 44231697293SDave May .keywords: DM, set, options, prefix, database 44331697293SDave May 44431697293SDave May .seealso: DMSetOptionsPrefix(), DMAppendOptionsPrefix() 44531697293SDave May @*/ 44631697293SDave May PetscErrorCode DMGetOptionsPrefix(DM dm,const char *prefix[]) 44731697293SDave May { 44831697293SDave May PetscErrorCode ierr; 44931697293SDave May 45031697293SDave May PetscFunctionBegin; 45131697293SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 45231697293SDave May ierr = PetscObjectGetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 45331697293SDave May PetscFunctionReturn(0); 45431697293SDave May } 45531697293SDave May 45688bdff64SToby Isaac static PetscErrorCode DMCountNonCyclicReferences(DM dm, PetscBool recurseCoarse, PetscBool recurseFine, PetscInt *ncrefct) 45788bdff64SToby Isaac { 45888bdff64SToby Isaac PetscInt i, refct = ((PetscObject) dm)->refct; 45988bdff64SToby Isaac DMNamedVecLink nlink; 46088bdff64SToby Isaac PetscErrorCode ierr; 46188bdff64SToby Isaac 46288bdff64SToby Isaac PetscFunctionBegin; 46388bdff64SToby Isaac /* count all the circular references of DM and its contained Vecs */ 46488bdff64SToby Isaac for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 46588bdff64SToby Isaac if (dm->localin[i]) refct--; 46688bdff64SToby Isaac if (dm->globalin[i]) refct--; 46788bdff64SToby Isaac } 46888bdff64SToby Isaac for (nlink=dm->namedglobal; nlink; nlink=nlink->next) refct--; 46988bdff64SToby Isaac for (nlink=dm->namedlocal; nlink; nlink=nlink->next) refct--; 47088bdff64SToby Isaac if (dm->x) { 47188bdff64SToby Isaac DM obj; 47288bdff64SToby Isaac ierr = VecGetDM(dm->x, &obj);CHKERRQ(ierr); 47388bdff64SToby Isaac if (obj == dm) refct--; 47488bdff64SToby Isaac } 47588bdff64SToby Isaac if (dm->coarseMesh && dm->coarseMesh->fineMesh == dm) { 47688bdff64SToby Isaac refct--; 47788bdff64SToby Isaac if (recurseCoarse) { 47888bdff64SToby Isaac PetscInt coarseCount; 47988bdff64SToby Isaac 48088bdff64SToby Isaac ierr = DMCountNonCyclicReferences(dm->coarseMesh, PETSC_TRUE, PETSC_FALSE,&coarseCount);CHKERRQ(ierr); 48188bdff64SToby Isaac refct += coarseCount; 48288bdff64SToby Isaac } 48388bdff64SToby Isaac } 48488bdff64SToby Isaac if (dm->fineMesh && dm->fineMesh->coarseMesh == dm) { 48588bdff64SToby Isaac refct--; 48688bdff64SToby Isaac if (recurseFine) { 48788bdff64SToby Isaac PetscInt fineCount; 48888bdff64SToby Isaac 48988bdff64SToby Isaac ierr = DMCountNonCyclicReferences(dm->fineMesh, PETSC_FALSE, PETSC_TRUE,&fineCount);CHKERRQ(ierr); 49088bdff64SToby Isaac refct += fineCount; 49188bdff64SToby Isaac } 49288bdff64SToby Isaac } 49388bdff64SToby Isaac *ncrefct = refct; 49488bdff64SToby Isaac PetscFunctionReturn(0); 49588bdff64SToby Isaac } 49688bdff64SToby Isaac 497354557abSToby Isaac PetscErrorCode DMDestroyLabelLinkList(DM dm) 498354557abSToby Isaac { 499354557abSToby Isaac PetscErrorCode ierr; 500354557abSToby Isaac 501354557abSToby Isaac PetscFunctionBegin; 502354557abSToby Isaac if (!--(dm->labels->refct)) { 503354557abSToby Isaac DMLabelLink next = dm->labels->next; 504354557abSToby Isaac 505354557abSToby Isaac /* destroy the labels */ 506354557abSToby Isaac while (next) { 507354557abSToby Isaac DMLabelLink tmp = next->next; 508354557abSToby Isaac 509354557abSToby Isaac ierr = DMLabelDestroy(&next->label);CHKERRQ(ierr); 510354557abSToby Isaac ierr = PetscFree(next);CHKERRQ(ierr); 511354557abSToby Isaac next = tmp; 512354557abSToby Isaac } 513354557abSToby Isaac ierr = PetscFree(dm->labels);CHKERRQ(ierr); 514354557abSToby Isaac } 515354557abSToby Isaac PetscFunctionReturn(0); 516354557abSToby Isaac } 517354557abSToby Isaac 51847c6ae99SBarry Smith /*@ 5198472ad0fSDave May DMDestroy - Destroys a vector packer or DM. 52047c6ae99SBarry Smith 52147c6ae99SBarry Smith Collective on DM 52247c6ae99SBarry Smith 52347c6ae99SBarry Smith Input Parameter: 52447c6ae99SBarry Smith . dm - the DM object to destroy 52547c6ae99SBarry Smith 52647c6ae99SBarry Smith Level: developer 52747c6ae99SBarry Smith 528e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 52947c6ae99SBarry Smith 53047c6ae99SBarry Smith @*/ 531fcfd50ebSBarry Smith PetscErrorCode DMDestroy(DM *dm) 53247c6ae99SBarry Smith { 53388bdff64SToby Isaac PetscInt i, cnt; 534dfe15315SJed Brown DMNamedVecLink nlink,nnext; 53547c6ae99SBarry Smith PetscErrorCode ierr; 53647c6ae99SBarry Smith 53747c6ae99SBarry Smith PetscFunctionBegin; 5386bf464f9SBarry Smith if (!*dm) PetscFunctionReturn(0); 5396bf464f9SBarry Smith PetscValidHeaderSpecific((*dm),DM_CLASSID,1); 54087e657c6SBarry Smith 54188bdff64SToby Isaac /* count all non-cyclic references in the doubly-linked list of coarse<->fine meshes */ 54288bdff64SToby Isaac ierr = DMCountNonCyclicReferences(*dm,PETSC_TRUE,PETSC_TRUE,&cnt);CHKERRQ(ierr); 54388bdff64SToby Isaac --((PetscObject)(*dm))->refct; 54488bdff64SToby Isaac if (--cnt > 0) {*dm = 0; PetscFunctionReturn(0);} 545732e2eb9SMatthew G Knepley /* 546732e2eb9SMatthew G Knepley Need this test because the dm references the vectors that 547732e2eb9SMatthew G Knepley reference the dm, so destroying the dm calls destroy on the 548732e2eb9SMatthew G Knepley vectors that cause another destroy on the dm 549732e2eb9SMatthew G Knepley */ 5506bf464f9SBarry Smith if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0); 5516bf464f9SBarry Smith ((PetscObject) (*dm))->refct = 0; 552732e2eb9SMatthew G Knepley for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 5536bf464f9SBarry Smith if ((*dm)->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Destroying a DM that has a local vector obtained with DMGetLocalVector()"); 5546bf464f9SBarry Smith ierr = VecDestroy(&(*dm)->localin[i]);CHKERRQ(ierr); 555732e2eb9SMatthew G Knepley } 556f490541aSPeter Brune nnext=(*dm)->namedglobal; 5570298fd71SBarry Smith (*dm)->namedglobal = NULL; 558f490541aSPeter Brune for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named vectors */ 5592348bcf4SPeter Brune nnext = nlink->next; 5602348bcf4SPeter Brune if (nlink->status != DMVEC_STATUS_IN) SETERRQ1(((PetscObject)*dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"DM still has Vec named '%s' checked out",nlink->name); 5612348bcf4SPeter Brune ierr = PetscFree(nlink->name);CHKERRQ(ierr); 5622348bcf4SPeter Brune ierr = VecDestroy(&nlink->X);CHKERRQ(ierr); 5632348bcf4SPeter Brune ierr = PetscFree(nlink);CHKERRQ(ierr); 5642348bcf4SPeter Brune } 565f490541aSPeter Brune nnext=(*dm)->namedlocal; 5660298fd71SBarry Smith (*dm)->namedlocal = NULL; 567f490541aSPeter Brune for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named local vectors */ 568f490541aSPeter Brune nnext = nlink->next; 569f490541aSPeter Brune if (nlink->status != DMVEC_STATUS_IN) SETERRQ1(((PetscObject)*dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"DM still has Vec named '%s' checked out",nlink->name); 570f490541aSPeter Brune ierr = PetscFree(nlink->name);CHKERRQ(ierr); 571f490541aSPeter Brune ierr = VecDestroy(&nlink->X);CHKERRQ(ierr); 572f490541aSPeter Brune ierr = PetscFree(nlink);CHKERRQ(ierr); 573f490541aSPeter Brune } 5742348bcf4SPeter Brune 575b17ce1afSJed Brown /* Destroy the list of hooks */ 576c833c3b5SJed Brown { 577c833c3b5SJed Brown DMCoarsenHookLink link,next; 578b17ce1afSJed Brown for (link=(*dm)->coarsenhook; link; link=next) { 579b17ce1afSJed Brown next = link->next; 580b17ce1afSJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 581b17ce1afSJed Brown } 5820298fd71SBarry Smith (*dm)->coarsenhook = NULL; 583c833c3b5SJed Brown } 584c833c3b5SJed Brown { 585c833c3b5SJed Brown DMRefineHookLink link,next; 586c833c3b5SJed Brown for (link=(*dm)->refinehook; link; link=next) { 587c833c3b5SJed Brown next = link->next; 588c833c3b5SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 589c833c3b5SJed Brown } 5900298fd71SBarry Smith (*dm)->refinehook = NULL; 591c833c3b5SJed Brown } 592be081cd6SPeter Brune { 593be081cd6SPeter Brune DMSubDomainHookLink link,next; 594be081cd6SPeter Brune for (link=(*dm)->subdomainhook; link; link=next) { 595be081cd6SPeter Brune next = link->next; 596be081cd6SPeter Brune ierr = PetscFree(link);CHKERRQ(ierr); 597be081cd6SPeter Brune } 5980298fd71SBarry Smith (*dm)->subdomainhook = NULL; 599be081cd6SPeter Brune } 600baf369e7SPeter Brune { 601baf369e7SPeter Brune DMGlobalToLocalHookLink link,next; 602baf369e7SPeter Brune for (link=(*dm)->gtolhook; link; link=next) { 603baf369e7SPeter Brune next = link->next; 604baf369e7SPeter Brune ierr = PetscFree(link);CHKERRQ(ierr); 605baf369e7SPeter Brune } 6060298fd71SBarry Smith (*dm)->gtolhook = NULL; 607baf369e7SPeter Brune } 608d4d07f1eSToby Isaac { 609d4d07f1eSToby Isaac DMLocalToGlobalHookLink link,next; 610d4d07f1eSToby Isaac for (link=(*dm)->ltoghook; link; link=next) { 611d4d07f1eSToby Isaac next = link->next; 612d4d07f1eSToby Isaac ierr = PetscFree(link);CHKERRQ(ierr); 613d4d07f1eSToby Isaac } 614d4d07f1eSToby Isaac (*dm)->ltoghook = NULL; 615d4d07f1eSToby Isaac } 616aa1993deSMatthew G Knepley /* Destroy the work arrays */ 617aa1993deSMatthew G Knepley { 618aa1993deSMatthew G Knepley DMWorkLink link,next; 619aa1993deSMatthew G Knepley if ((*dm)->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Work array still checked out"); 620aa1993deSMatthew G Knepley for (link=(*dm)->workin; link; link=next) { 621aa1993deSMatthew G Knepley next = link->next; 622aa1993deSMatthew G Knepley ierr = PetscFree(link->mem);CHKERRQ(ierr); 623aa1993deSMatthew G Knepley ierr = PetscFree(link);CHKERRQ(ierr); 624aa1993deSMatthew G Knepley } 6250298fd71SBarry Smith (*dm)->workin = NULL; 626aa1993deSMatthew G Knepley } 627c58f1c22SToby Isaac if (!--((*dm)->labels->refct)) { 628c58f1c22SToby Isaac DMLabelLink next = (*dm)->labels->next; 629c58f1c22SToby Isaac 630c58f1c22SToby Isaac /* destroy the labels */ 631c58f1c22SToby Isaac while (next) { 632c58f1c22SToby Isaac DMLabelLink tmp = next->next; 633c58f1c22SToby Isaac 634c58f1c22SToby Isaac ierr = DMLabelDestroy(&next->label);CHKERRQ(ierr); 635c58f1c22SToby Isaac ierr = PetscFree(next);CHKERRQ(ierr); 636c58f1c22SToby Isaac next = tmp; 637c58f1c22SToby Isaac } 638c58f1c22SToby Isaac ierr = PetscFree((*dm)->labels);CHKERRQ(ierr); 639c58f1c22SToby Isaac } 640e6f8dbb6SToby Isaac { 641e6f8dbb6SToby Isaac DMBoundary next = (*dm)->boundary; 642e6f8dbb6SToby Isaac while (next) { 643e6f8dbb6SToby Isaac DMBoundary b = next; 644e6f8dbb6SToby Isaac 645e6f8dbb6SToby Isaac next = b->next; 646e6f8dbb6SToby Isaac ierr = PetscFree(b);CHKERRQ(ierr); 647e6f8dbb6SToby Isaac } 648e6f8dbb6SToby Isaac } 649b17ce1afSJed Brown 65052536dc3SBarry Smith ierr = PetscObjectDestroy(&(*dm)->dmksp);CHKERRQ(ierr); 65152536dc3SBarry Smith ierr = PetscObjectDestroy(&(*dm)->dmsnes);CHKERRQ(ierr); 65252536dc3SBarry Smith ierr = PetscObjectDestroy(&(*dm)->dmts);CHKERRQ(ierr); 65352536dc3SBarry Smith 6541a266240SBarry Smith if ((*dm)->ctx && (*dm)->ctxdestroy) { 6551a266240SBarry Smith ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr); 6561a266240SBarry Smith } 65787e657c6SBarry Smith ierr = VecDestroy(&(*dm)->x);CHKERRQ(ierr); 65871cd77b2SBarry Smith ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr); 6594dcab191SBarry Smith ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr); 6606bf464f9SBarry Smith ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr); 6616bf464f9SBarry Smith ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr); 662073dac72SJed Brown ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr); 66388ed4aceSMatthew G Knepley 66488ed4aceSMatthew G Knepley ierr = PetscSectionDestroy(&(*dm)->defaultSection);CHKERRQ(ierr); 66588ed4aceSMatthew G Knepley ierr = PetscSectionDestroy(&(*dm)->defaultGlobalSection);CHKERRQ(ierr); 6668b1ab98fSJed Brown ierr = PetscLayoutDestroy(&(*dm)->map);CHKERRQ(ierr); 667fba222abSToby Isaac ierr = PetscSectionDestroy(&(*dm)->defaultConstraintSection);CHKERRQ(ierr); 668fba222abSToby Isaac ierr = MatDestroy(&(*dm)->defaultConstraintMat);CHKERRQ(ierr); 66988ed4aceSMatthew G Knepley ierr = PetscSFDestroy(&(*dm)->sf);CHKERRQ(ierr); 67088ed4aceSMatthew G Knepley ierr = PetscSFDestroy(&(*dm)->defaultSF);CHKERRQ(ierr); 6718e4ac7eaSMatthew G. Knepley ierr = PetscSFDestroy(&(*dm)->sfNatural);CHKERRQ(ierr); 672af122d2aSMatthew G Knepley 67388bdff64SToby Isaac if ((*dm)->coarseMesh && (*dm)->coarseMesh->fineMesh == *dm) { 67488bdff64SToby Isaac ierr = DMSetFineDM((*dm)->coarseMesh,NULL);CHKERRQ(ierr); 67588bdff64SToby Isaac } 676a8fb8f29SToby Isaac ierr = DMDestroy(&(*dm)->coarseMesh);CHKERRQ(ierr); 67788bdff64SToby Isaac if ((*dm)->fineMesh && (*dm)->fineMesh->coarseMesh == *dm) { 67888bdff64SToby Isaac ierr = DMSetCoarseDM((*dm)->fineMesh,NULL);CHKERRQ(ierr); 67988bdff64SToby Isaac } 68088bdff64SToby Isaac ierr = DMDestroy(&(*dm)->fineMesh);CHKERRQ(ierr); 6816636e97aSMatthew G Knepley ierr = DMDestroy(&(*dm)->coordinateDM);CHKERRQ(ierr); 6826636e97aSMatthew G Knepley ierr = VecDestroy(&(*dm)->coordinates);CHKERRQ(ierr); 6836636e97aSMatthew G Knepley ierr = VecDestroy(&(*dm)->coordinatesLocal);CHKERRQ(ierr); 6845dc8c3f7SMatthew G. Knepley ierr = PetscFree3((*dm)->L,(*dm)->maxCell,(*dm)->bdtype);CHKERRQ(ierr); 6856636e97aSMatthew G Knepley 6862764a2aaSMatthew G. Knepley ierr = PetscDSDestroy(&(*dm)->prob);CHKERRQ(ierr); 68714f150ffSMatthew G. Knepley ierr = DMDestroy(&(*dm)->dmBC);CHKERRQ(ierr); 688e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 689e04113cfSBarry Smith ierr = PetscObjectSAWsViewOff((PetscObject)*dm);CHKERRQ(ierr); 690732e2eb9SMatthew G Knepley 6916bf464f9SBarry Smith ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr); 692435a35e8SMatthew G Knepley /* We do not destroy (*dm)->data here so that we can reference count backend objects */ 693732e2eb9SMatthew G Knepley ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr); 69447c6ae99SBarry Smith PetscFunctionReturn(0); 69547c6ae99SBarry Smith } 69647c6ae99SBarry Smith 697d7bf68aeSBarry Smith /*@ 698d7bf68aeSBarry Smith DMSetUp - sets up the data structures inside a DM object 699d7bf68aeSBarry Smith 700d7bf68aeSBarry Smith Collective on DM 701d7bf68aeSBarry Smith 702d7bf68aeSBarry Smith Input Parameter: 703d7bf68aeSBarry Smith . dm - the DM object to setup 704d7bf68aeSBarry Smith 705d7bf68aeSBarry Smith Level: developer 706d7bf68aeSBarry Smith 707e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 708d7bf68aeSBarry Smith 709d7bf68aeSBarry Smith @*/ 7107087cfbeSBarry Smith PetscErrorCode DMSetUp(DM dm) 711d7bf68aeSBarry Smith { 712d7bf68aeSBarry Smith PetscErrorCode ierr; 713d7bf68aeSBarry Smith 714d7bf68aeSBarry Smith PetscFunctionBegin; 715171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7168387afaaSJed Brown if (dm->setupcalled) PetscFunctionReturn(0); 717d7bf68aeSBarry Smith if (dm->ops->setup) { 718d7bf68aeSBarry Smith ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr); 719d7bf68aeSBarry Smith } 7208387afaaSJed Brown dm->setupcalled = PETSC_TRUE; 721d7bf68aeSBarry Smith PetscFunctionReturn(0); 722d7bf68aeSBarry Smith } 723d7bf68aeSBarry Smith 724d7bf68aeSBarry Smith /*@ 725d7bf68aeSBarry Smith DMSetFromOptions - sets parameters in a DM from the options database 726d7bf68aeSBarry Smith 727d7bf68aeSBarry Smith Collective on DM 728d7bf68aeSBarry Smith 729d7bf68aeSBarry Smith Input Parameter: 730d7bf68aeSBarry Smith . dm - the DM object to set options for 731d7bf68aeSBarry Smith 732732e2eb9SMatthew G Knepley Options Database: 7334164ae61SDominic Meiser + -dm_preallocate_only - Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros 7344164ae61SDominic Meiser . -dm_vec_type <type> - type of vector to create inside DM 7354164ae61SDominic Meiser . -dm_mat_type <type> - type of matrix to create inside DM 7364164ae61SDominic Meiser - -dm_coloring_type - <global or ghosted> 737732e2eb9SMatthew G Knepley 738d7bf68aeSBarry Smith Level: developer 739d7bf68aeSBarry Smith 740e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 741d7bf68aeSBarry Smith 742d7bf68aeSBarry Smith @*/ 7437087cfbeSBarry Smith PetscErrorCode DMSetFromOptions(DM dm) 744d7bf68aeSBarry Smith { 7457781c08eSBarry Smith char typeName[256]; 746ca266f36SBarry Smith PetscBool flg; 747d7bf68aeSBarry Smith PetscErrorCode ierr; 748d7bf68aeSBarry Smith 749d7bf68aeSBarry Smith PetscFunctionBegin; 750171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 751f1fd5e65SToby Isaac if (dm->prob) { 752f1fd5e65SToby Isaac ierr = PetscDSSetFromOptions(dm->prob);CHKERRQ(ierr); 753f1fd5e65SToby Isaac } 754691be533SLawrence Mitchell if (dm->sf) { 755691be533SLawrence Mitchell ierr = PetscSFSetFromOptions(dm->sf);CHKERRQ(ierr); 756691be533SLawrence Mitchell } 757691be533SLawrence Mitchell if (dm->defaultSF) { 758691be533SLawrence Mitchell ierr = PetscSFSetFromOptions(dm->defaultSF);CHKERRQ(ierr); 759691be533SLawrence Mitchell } 7603194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr); 7610298fd71SBarry Smith ierr = PetscOptionsBool("-dm_preallocate_only","only preallocate matrix, but do not set column indices","DMSetMatrixPreallocateOnly",dm->prealloc_only,&dm->prealloc_only,NULL);CHKERRQ(ierr); 762a264d7a6SBarry Smith ierr = PetscOptionsFList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr); 763f9ba7244SBarry Smith if (flg) { 764f9ba7244SBarry Smith ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr); 765f9ba7244SBarry Smith } 766a264d7a6SBarry Smith ierr = PetscOptionsFList("-dm_mat_type","Matrix type used for created matrices","DMSetMatType",MatList,dm->mattype ? dm->mattype : typeName,typeName,sizeof(typeName),&flg);CHKERRQ(ierr); 767073dac72SJed Brown if (flg) { 768521d9a4cSLisandro Dalcin ierr = DMSetMatType(dm,typeName);CHKERRQ(ierr); 769073dac72SJed Brown } 7700298fd71SBarry Smith ierr = PetscOptionsEnum("-dm_is_coloring_type","Global or local coloring of Jacobian","ISColoringType",ISColoringTypes,(PetscEnum)dm->coloringtype,(PetscEnum*)&dm->coloringtype,NULL);CHKERRQ(ierr); 771f9ba7244SBarry Smith if (dm->ops->setfromoptions) { 772e55864a3SBarry Smith ierr = (*dm->ops->setfromoptions)(PetscOptionsObject,dm);CHKERRQ(ierr); 773f9ba7244SBarry Smith } 774f9ba7244SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 7750633abcbSJed Brown ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) dm);CHKERRQ(ierr); 77682fcb398SMatthew G Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 777d7bf68aeSBarry Smith PetscFunctionReturn(0); 778d7bf68aeSBarry Smith } 779d7bf68aeSBarry Smith 780fc9bc008SSatish Balay /*@C 781224748a4SBarry Smith DMView - Views a DM 78247c6ae99SBarry Smith 78347c6ae99SBarry Smith Collective on DM 78447c6ae99SBarry Smith 78547c6ae99SBarry Smith Input Parameter: 78647c6ae99SBarry Smith + dm - the DM object to view 78747c6ae99SBarry Smith - v - the viewer 78847c6ae99SBarry Smith 789224748a4SBarry Smith Level: beginner 79047c6ae99SBarry Smith 791e727c939SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 79247c6ae99SBarry Smith 79347c6ae99SBarry Smith @*/ 7947087cfbeSBarry Smith PetscErrorCode DMView(DM dm,PetscViewer v) 79547c6ae99SBarry Smith { 79647c6ae99SBarry Smith PetscErrorCode ierr; 79732c0f0efSBarry Smith PetscBool isbinary; 79847c6ae99SBarry Smith 79947c6ae99SBarry Smith PetscFunctionBegin; 800171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8013014e516SBarry Smith if (!v) { 802ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)dm),&v);CHKERRQ(ierr); 8033014e516SBarry Smith } 80498c3331eSBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)dm,v);CHKERRQ(ierr); 80532c0f0efSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 80632c0f0efSBarry Smith if (isbinary) { 80755849f57SBarry Smith PetscInt classid = DM_FILE_CLASSID; 80832c0f0efSBarry Smith char type[256]; 80932c0f0efSBarry Smith 81032c0f0efSBarry Smith ierr = PetscViewerBinaryWrite(v,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 81132c0f0efSBarry Smith ierr = PetscStrncpy(type,((PetscObject)dm)->type_name,256);CHKERRQ(ierr); 81232c0f0efSBarry Smith ierr = PetscViewerBinaryWrite(v,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 81332c0f0efSBarry Smith } 8140c010503SBarry Smith if (dm->ops->view) { 8150c010503SBarry Smith ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr); 81647c6ae99SBarry Smith } 81747c6ae99SBarry Smith PetscFunctionReturn(0); 81847c6ae99SBarry Smith } 81947c6ae99SBarry Smith 82047c6ae99SBarry Smith /*@ 8218472ad0fSDave May DMCreateGlobalVector - Creates a global vector from a DM object 82247c6ae99SBarry Smith 82347c6ae99SBarry Smith Collective on DM 82447c6ae99SBarry Smith 82547c6ae99SBarry Smith Input Parameter: 82647c6ae99SBarry Smith . dm - the DM object 82747c6ae99SBarry Smith 82847c6ae99SBarry Smith Output Parameter: 82947c6ae99SBarry Smith . vec - the global vector 83047c6ae99SBarry Smith 831073dac72SJed Brown Level: beginner 83247c6ae99SBarry Smith 833e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 83447c6ae99SBarry Smith 83547c6ae99SBarry Smith @*/ 8367087cfbeSBarry Smith PetscErrorCode DMCreateGlobalVector(DM dm,Vec *vec) 83747c6ae99SBarry Smith { 83847c6ae99SBarry Smith PetscErrorCode ierr; 83947c6ae99SBarry Smith 84047c6ae99SBarry Smith PetscFunctionBegin; 841171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 84247c6ae99SBarry Smith ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr); 84347c6ae99SBarry Smith PetscFunctionReturn(0); 84447c6ae99SBarry Smith } 84547c6ae99SBarry Smith 84647c6ae99SBarry Smith /*@ 8478472ad0fSDave May DMCreateLocalVector - Creates a local vector from a DM object 84847c6ae99SBarry Smith 84947c6ae99SBarry Smith Not Collective 85047c6ae99SBarry Smith 85147c6ae99SBarry Smith Input Parameter: 85247c6ae99SBarry Smith . dm - the DM object 85347c6ae99SBarry Smith 85447c6ae99SBarry Smith Output Parameter: 85547c6ae99SBarry Smith . vec - the local vector 85647c6ae99SBarry Smith 857073dac72SJed Brown Level: beginner 85847c6ae99SBarry Smith 859e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 86047c6ae99SBarry Smith 86147c6ae99SBarry Smith @*/ 8627087cfbeSBarry Smith PetscErrorCode DMCreateLocalVector(DM dm,Vec *vec) 86347c6ae99SBarry Smith { 86447c6ae99SBarry Smith PetscErrorCode ierr; 86547c6ae99SBarry Smith 86647c6ae99SBarry Smith PetscFunctionBegin; 867171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 86847c6ae99SBarry Smith ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr); 86947c6ae99SBarry Smith PetscFunctionReturn(0); 87047c6ae99SBarry Smith } 87147c6ae99SBarry Smith 8721411c6eeSJed Brown /*@ 8731411c6eeSJed Brown DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM. 8741411c6eeSJed Brown 8751411c6eeSJed Brown Collective on DM 8761411c6eeSJed Brown 8771411c6eeSJed Brown Input Parameter: 8781411c6eeSJed Brown . dm - the DM that provides the mapping 8791411c6eeSJed Brown 8801411c6eeSJed Brown Output Parameter: 8811411c6eeSJed Brown . ltog - the mapping 8821411c6eeSJed Brown 8831411c6eeSJed Brown Level: intermediate 8841411c6eeSJed Brown 8851411c6eeSJed Brown Notes: 8861411c6eeSJed Brown This mapping can then be used by VecSetLocalToGlobalMapping() or 8871411c6eeSJed Brown MatSetLocalToGlobalMapping(). 8881411c6eeSJed Brown 889fc31e74dSBarry Smith .seealso: DMCreateLocalVector() 8901411c6eeSJed Brown @*/ 8917087cfbeSBarry Smith PetscErrorCode DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog) 8921411c6eeSJed Brown { 893bff27382SMatthew G. Knepley PetscInt bs = -1, bsLocal, bsMin, bsMax; 8941411c6eeSJed Brown PetscErrorCode ierr; 8951411c6eeSJed Brown 8961411c6eeSJed Brown PetscFunctionBegin; 8971411c6eeSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8981411c6eeSJed Brown PetscValidPointer(ltog,2); 8991411c6eeSJed Brown if (!dm->ltogmap) { 90037d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 90137d0c07bSMatthew G Knepley 90237d0c07bSMatthew G Knepley ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 90337d0c07bSMatthew G Knepley if (section) { 904a974ec88SMatthew G. Knepley const PetscInt *cdofs; 90537d0c07bSMatthew G Knepley PetscInt *ltog; 90637d0c07bSMatthew G Knepley PetscInt pStart, pEnd, size, p, l; 90737d0c07bSMatthew G Knepley 90837d0c07bSMatthew G Knepley ierr = DMGetDefaultGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 90937d0c07bSMatthew G Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 91037d0c07bSMatthew G Knepley ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 911785e854fSJed Brown ierr = PetscMalloc1(size, <og);CHKERRQ(ierr); /* We want the local+overlap size */ 91237d0c07bSMatthew G Knepley for (p = pStart, l = 0; p < pEnd; ++p) { 913a974ec88SMatthew G. Knepley PetscInt bdof, cdof, dof, off, c, cind = 0; 91437d0c07bSMatthew G Knepley 91537d0c07bSMatthew G Knepley /* Should probably use constrained dofs */ 91637d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 917a974ec88SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr); 918a974ec88SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, p, &cdofs);CHKERRQ(ierr); 91937d0c07bSMatthew G Knepley ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr); 9201a7dc684SMatthew G. Knepley /* If you have dofs, and constraints, and they are unequal, we set the blocksize to 1 */ 9211a7dc684SMatthew G. Knepley bdof = cdof && (dof-cdof) ? 1 : dof; 9221a7dc684SMatthew G. Knepley if (dof) { 923b190aa46SMatthew G. Knepley if (bs < 0) {bs = bdof;} 924b190aa46SMatthew G. Knepley else if (bs != bdof) {bs = 1;} 9251a7dc684SMatthew G. Knepley } 92637d0c07bSMatthew G Knepley for (c = 0; c < dof; ++c, ++l) { 927a974ec88SMatthew G. Knepley if ((cind < cdof) && (c == cdofs[cind])) ltog[l] = off < 0 ? off-c : off+c; 928a974ec88SMatthew G. Knepley else ltog[l] = (off < 0 ? -(off+1) : off) + c; 92937d0c07bSMatthew G Knepley } 93037d0c07bSMatthew G Knepley } 931bff27382SMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 932bff27382SMatthew G. Knepley bsLocal = bs; 933bff27382SMatthew G. Knepley ierr = MPIU_Allreduce(&bsLocal, &bsMax, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 934bff27382SMatthew G. Knepley bsLocal = bs < 0 ? bsMax : bs; 935bff27382SMatthew G. Knepley ierr = MPIU_Allreduce(&bsLocal, &bsMin, 1, MPIU_INT, MPI_MIN, PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 936bff27382SMatthew G. Knepley if (bsMin != bsMax) {bs = 1;} 937bff27382SMatthew G. Knepley else {bs = bsMax;} 9387591dbb2SMatthew G. Knepley bs = bs < 0 ? 1 : bs; 9397591dbb2SMatthew G. Knepley /* Must reduce indices by blocksize */ 9407591dbb2SMatthew G. Knepley if (bs > 1) for (l = 0; l < size; ++l) ltog[l] /= bs; 9417591dbb2SMatthew G. Knepley ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, size, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr); 9423bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)dm, (PetscObject)dm->ltogmap);CHKERRQ(ierr); 94337d0c07bSMatthew G Knepley } else { 944184d77edSJed Brown if (!dm->ops->getlocaltoglobalmapping) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM can not create LocalToGlobalMapping"); 945184d77edSJed Brown ierr = (*dm->ops->getlocaltoglobalmapping)(dm);CHKERRQ(ierr); 9461411c6eeSJed Brown } 94737d0c07bSMatthew G Knepley } 9481411c6eeSJed Brown *ltog = dm->ltogmap; 9491411c6eeSJed Brown PetscFunctionReturn(0); 9501411c6eeSJed Brown } 9511411c6eeSJed Brown 9521411c6eeSJed Brown /*@ 9531411c6eeSJed Brown DMGetBlockSize - Gets the inherent block size associated with a DM 9541411c6eeSJed Brown 9551411c6eeSJed Brown Not Collective 9561411c6eeSJed Brown 9571411c6eeSJed Brown Input Parameter: 9581411c6eeSJed Brown . dm - the DM with block structure 9591411c6eeSJed Brown 9601411c6eeSJed Brown Output Parameter: 9611411c6eeSJed Brown . bs - the block size, 1 implies no exploitable block structure 9621411c6eeSJed Brown 9631411c6eeSJed Brown Level: intermediate 9641411c6eeSJed Brown 965fc31e74dSBarry Smith .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMapping() 9661411c6eeSJed Brown @*/ 9677087cfbeSBarry Smith PetscErrorCode DMGetBlockSize(DM dm,PetscInt *bs) 9681411c6eeSJed Brown { 9691411c6eeSJed Brown PetscFunctionBegin; 9701411c6eeSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 9711411c6eeSJed Brown PetscValidPointer(bs,2); 9721411c6eeSJed Brown if (dm->bs < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"DM does not have enough information to provide a block size yet"); 9731411c6eeSJed Brown *bs = dm->bs; 9741411c6eeSJed Brown PetscFunctionReturn(0); 9751411c6eeSJed Brown } 9761411c6eeSJed Brown 97747c6ae99SBarry Smith /*@ 9788472ad0fSDave May DMCreateInterpolation - Gets interpolation matrix between two DM objects 97947c6ae99SBarry Smith 98047c6ae99SBarry Smith Collective on DM 98147c6ae99SBarry Smith 98247c6ae99SBarry Smith Input Parameter: 98347c6ae99SBarry Smith + dm1 - the DM object 98447c6ae99SBarry Smith - dm2 - the second, finer DM object 98547c6ae99SBarry Smith 98647c6ae99SBarry Smith Output Parameter: 98747c6ae99SBarry Smith + mat - the interpolation 98847c6ae99SBarry Smith - vec - the scaling (optional) 98947c6ae99SBarry Smith 99047c6ae99SBarry Smith Level: developer 99147c6ae99SBarry Smith 99285afcc9aSBarry Smith 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 99385afcc9aSBarry Smith DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation. 994d52bd9f3SBarry Smith 9951f588964SMatthew G Knepley For DMDA objects you can use this interpolation (more precisely the interpolation from the DMGetCoordinateDM()) to interpolate the mesh coordinate vectors 996d52bd9f3SBarry Smith EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic. 99785afcc9aSBarry Smith 99885afcc9aSBarry Smith 9993ad4599aSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateRestriction() 100047c6ae99SBarry Smith 100147c6ae99SBarry Smith @*/ 1002e727c939SJed Brown PetscErrorCode DMCreateInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec) 100347c6ae99SBarry Smith { 100447c6ae99SBarry Smith PetscErrorCode ierr; 100547c6ae99SBarry Smith 100647c6ae99SBarry Smith PetscFunctionBegin; 1007171400e9SBarry Smith PetscValidHeaderSpecific(dm1,DM_CLASSID,1); 1008171400e9SBarry Smith PetscValidHeaderSpecific(dm2,DM_CLASSID,2); 1009cea54e9dSPatrick Farrell ierr = PetscLogEventBegin(DM_CreateInterpolation,dm1,dm2,0,0);CHKERRQ(ierr); 101025296bd5SBarry Smith ierr = (*dm1->ops->createinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr); 1011cea54e9dSPatrick Farrell ierr = PetscLogEventEnd(DM_CreateInterpolation,dm1,dm2,0,0);CHKERRQ(ierr); 101247c6ae99SBarry Smith PetscFunctionReturn(0); 101347c6ae99SBarry Smith } 101447c6ae99SBarry Smith 10153ad4599aSBarry Smith /*@ 10163ad4599aSBarry Smith DMCreateRestriction - Gets restriction matrix between two DM objects 10173ad4599aSBarry Smith 10183ad4599aSBarry Smith Collective on DM 10193ad4599aSBarry Smith 10203ad4599aSBarry Smith Input Parameter: 10213ad4599aSBarry Smith + dm1 - the DM object 10223ad4599aSBarry Smith - dm2 - the second, finer DM object 10233ad4599aSBarry Smith 10243ad4599aSBarry Smith Output Parameter: 10253ad4599aSBarry Smith . mat - the restriction 10263ad4599aSBarry Smith 10273ad4599aSBarry Smith 10283ad4599aSBarry Smith Level: developer 10293ad4599aSBarry Smith 10303ad4599aSBarry Smith 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 10313ad4599aSBarry Smith DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation. 10323ad4599aSBarry Smith 10333ad4599aSBarry Smith 10343ad4599aSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateInterpolation() 10353ad4599aSBarry Smith 10363ad4599aSBarry Smith @*/ 10373ad4599aSBarry Smith PetscErrorCode DMCreateRestriction(DM dm1,DM dm2,Mat *mat) 10383ad4599aSBarry Smith { 10393ad4599aSBarry Smith PetscErrorCode ierr; 10403ad4599aSBarry Smith 10413ad4599aSBarry Smith PetscFunctionBegin; 10423ad4599aSBarry Smith PetscValidHeaderSpecific(dm1,DM_CLASSID,1); 10433ad4599aSBarry Smith PetscValidHeaderSpecific(dm2,DM_CLASSID,2); 10443ad4599aSBarry Smith ierr = PetscLogEventBegin(DM_CreateRestriction,dm1,dm2,0,0);CHKERRQ(ierr); 10457294143fSBarry Smith if (!dm1->ops->createrestriction) SETERRQ(PetscObjectComm((PetscObject)dm1),PETSC_ERR_SUP,"DMCreateRestriction not implemented for this type"); 10463ad4599aSBarry Smith ierr = (*dm1->ops->createrestriction)(dm1,dm2,mat);CHKERRQ(ierr); 10473ad4599aSBarry Smith ierr = PetscLogEventEnd(DM_CreateRestriction,dm1,dm2,0,0);CHKERRQ(ierr); 10483ad4599aSBarry Smith PetscFunctionReturn(0); 10493ad4599aSBarry Smith } 10503ad4599aSBarry Smith 105147c6ae99SBarry Smith /*@ 10528472ad0fSDave May DMCreateInjection - Gets injection matrix between two DM objects 105347c6ae99SBarry Smith 105447c6ae99SBarry Smith Collective on DM 105547c6ae99SBarry Smith 105647c6ae99SBarry Smith Input Parameter: 105747c6ae99SBarry Smith + dm1 - the DM object 105847c6ae99SBarry Smith - dm2 - the second, finer DM object 105947c6ae99SBarry Smith 106047c6ae99SBarry Smith Output Parameter: 10616dbf9973SLawrence Mitchell . mat - the injection 106247c6ae99SBarry Smith 106347c6ae99SBarry Smith Level: developer 106447c6ae99SBarry Smith 106585afcc9aSBarry Smith 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 106685afcc9aSBarry Smith DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection. 106785afcc9aSBarry Smith 1068e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation() 106947c6ae99SBarry Smith 107047c6ae99SBarry Smith @*/ 10716dbf9973SLawrence Mitchell PetscErrorCode DMCreateInjection(DM dm1,DM dm2,Mat *mat) 107247c6ae99SBarry Smith { 107347c6ae99SBarry Smith PetscErrorCode ierr; 107447c6ae99SBarry Smith 107547c6ae99SBarry Smith PetscFunctionBegin; 1076171400e9SBarry Smith PetscValidHeaderSpecific(dm1,DM_CLASSID,1); 1077171400e9SBarry Smith PetscValidHeaderSpecific(dm2,DM_CLASSID,2); 10780c4c9125SBarry Smith if (!dm1->ops->getinjection) SETERRQ(PetscObjectComm((PetscObject)dm1),PETSC_ERR_SUP,"DMCreateInjection not implemented for this type"); 10796dbf9973SLawrence Mitchell ierr = (*dm1->ops->getinjection)(dm1,dm2,mat);CHKERRQ(ierr); 108047c6ae99SBarry Smith PetscFunctionReturn(0); 108147c6ae99SBarry Smith } 108247c6ae99SBarry Smith 1083b412c318SBarry Smith /*@ 1084b412c318SBarry Smith DMCreateColoring - Gets coloring for a DM 108547c6ae99SBarry Smith 108647c6ae99SBarry Smith Collective on DM 108747c6ae99SBarry Smith 108847c6ae99SBarry Smith Input Parameter: 108947c6ae99SBarry Smith + dm - the DM object 10905bdb020cSBarry Smith - ctype - IS_COLORING_LOCAL or IS_COLORING_GLOBAL 109147c6ae99SBarry Smith 109247c6ae99SBarry Smith Output Parameter: 109347c6ae99SBarry Smith . coloring - the coloring 109447c6ae99SBarry Smith 109547c6ae99SBarry Smith Level: developer 109647c6ae99SBarry Smith 1097b412c318SBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix(), DMSetMatType() 109847c6ae99SBarry Smith 1099aab9d709SJed Brown @*/ 1100b412c318SBarry Smith PetscErrorCode DMCreateColoring(DM dm,ISColoringType ctype,ISColoring *coloring) 110147c6ae99SBarry Smith { 110247c6ae99SBarry Smith PetscErrorCode ierr; 110347c6ae99SBarry Smith 110447c6ae99SBarry Smith PetscFunctionBegin; 1105171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1106ce94432eSBarry Smith if (!dm->ops->getcoloring) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No coloring for this type of DM yet"); 1107b412c318SBarry Smith ierr = (*dm->ops->getcoloring)(dm,ctype,coloring);CHKERRQ(ierr); 110847c6ae99SBarry Smith PetscFunctionReturn(0); 110947c6ae99SBarry Smith } 111047c6ae99SBarry Smith 1111b412c318SBarry Smith /*@ 11128472ad0fSDave May DMCreateMatrix - Gets empty Jacobian for a DM 111347c6ae99SBarry Smith 111447c6ae99SBarry Smith Collective on DM 111547c6ae99SBarry Smith 111647c6ae99SBarry Smith Input Parameter: 1117b412c318SBarry Smith . dm - the DM object 111847c6ae99SBarry Smith 111947c6ae99SBarry Smith Output Parameter: 112047c6ae99SBarry Smith . mat - the empty Jacobian 112147c6ae99SBarry Smith 1122073dac72SJed Brown Level: beginner 112347c6ae99SBarry Smith 112494013140SBarry Smith Notes: This properly preallocates the number of nonzeros in the sparse matrix so you 112594013140SBarry Smith do not need to do it yourself. 112694013140SBarry Smith 112794013140SBarry Smith By default it also sets the nonzero structure and puts in the zero entries. To prevent setting 11287889ec69SBarry Smith the nonzero pattern call DMSetMatrixPreallocateOnly() 112994013140SBarry Smith 113094013140SBarry Smith For structured grid problems, when you call MatView() on this matrix it is displayed using the global natural ordering, NOT in the ordering used 113194013140SBarry Smith internally by PETSc. 113294013140SBarry Smith 113394013140SBarry Smith For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires 1134aa219208SBarry Smith the indices for the global numbering for DMDAs which is complicated. 113594013140SBarry Smith 1136b412c318SBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMSetMatType() 113747c6ae99SBarry Smith 1138aab9d709SJed Brown @*/ 1139b412c318SBarry Smith PetscErrorCode DMCreateMatrix(DM dm,Mat *mat) 114047c6ae99SBarry Smith { 114147c6ae99SBarry Smith PetscErrorCode ierr; 114247c6ae99SBarry Smith 114347c6ae99SBarry Smith PetscFunctionBegin; 1144171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1145607a6623SBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 1146c7b7c8a4SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1147c7b7c8a4SJed Brown PetscValidPointer(mat,3); 1148b412c318SBarry Smith ierr = (*dm->ops->creatematrix)(dm,mat);CHKERRQ(ierr); 114947c6ae99SBarry Smith PetscFunctionReturn(0); 115047c6ae99SBarry Smith } 115147c6ae99SBarry Smith 1152732e2eb9SMatthew G Knepley /*@ 1153950540a4SJed Brown DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly 1154732e2eb9SMatthew G Knepley preallocated but the nonzero structure and zero values will not be set. 1155732e2eb9SMatthew G Knepley 11568472ad0fSDave May Logically Collective on DM 1157732e2eb9SMatthew G Knepley 1158732e2eb9SMatthew G Knepley Input Parameter: 1159732e2eb9SMatthew G Knepley + dm - the DM 1160732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation 1161732e2eb9SMatthew G Knepley 1162732e2eb9SMatthew G Knepley Level: developer 1163b06ff27eSHong Zhang .seealso DMCreateMatrix(), DMSetMatrixStructureOnly() 1164732e2eb9SMatthew G Knepley @*/ 1165732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only) 1166732e2eb9SMatthew G Knepley { 1167732e2eb9SMatthew G Knepley PetscFunctionBegin; 1168732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1169732e2eb9SMatthew G Knepley dm->prealloc_only = only; 1170732e2eb9SMatthew G Knepley PetscFunctionReturn(0); 1171732e2eb9SMatthew G Knepley } 1172732e2eb9SMatthew G Knepley 1173b06ff27eSHong Zhang /*@ 1174b06ff27eSHong Zhang DMSetMatrixStructureOnly - When DMCreateMatrix() is called, the matrix structure will be created 1175b06ff27eSHong Zhang but the array for values will not be allocated. 1176b06ff27eSHong Zhang 1177b06ff27eSHong Zhang Logically Collective on DM 1178b06ff27eSHong Zhang 1179b06ff27eSHong Zhang Input Parameter: 1180b06ff27eSHong Zhang + dm - the DM 1181b06ff27eSHong Zhang - only - PETSC_TRUE if only want matrix stucture 1182b06ff27eSHong Zhang 1183b06ff27eSHong Zhang Level: developer 1184b06ff27eSHong Zhang .seealso DMCreateMatrix(), DMSetMatrixPreallocateOnly() 1185b06ff27eSHong Zhang @*/ 1186b06ff27eSHong Zhang PetscErrorCode DMSetMatrixStructureOnly(DM dm, PetscBool only) 1187b06ff27eSHong Zhang { 1188b06ff27eSHong Zhang PetscFunctionBegin; 1189b06ff27eSHong Zhang PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1190b06ff27eSHong Zhang dm->structure_only = only; 1191b06ff27eSHong Zhang PetscFunctionReturn(0); 1192b06ff27eSHong Zhang } 1193b06ff27eSHong Zhang 1194a89ea682SMatthew G Knepley /*@C 1195aa1993deSMatthew G Knepley DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray() 1196a89ea682SMatthew G Knepley 1197a89ea682SMatthew G Knepley Not Collective 1198a89ea682SMatthew G Knepley 1199a89ea682SMatthew G Knepley Input Parameters: 1200a89ea682SMatthew G Knepley + dm - the DM object 1201aa1993deSMatthew G Knepley . count - The minium size 1202aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT) 1203a89ea682SMatthew G Knepley 1204a89ea682SMatthew G Knepley Output Parameter: 1205a89ea682SMatthew G Knepley . array - the work array 1206a89ea682SMatthew G Knepley 1207a89ea682SMatthew G Knepley Level: developer 1208a89ea682SMatthew G Knepley 1209a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate() 1210a89ea682SMatthew G Knepley @*/ 1211aa1993deSMatthew G Knepley PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem) 1212a89ea682SMatthew G Knepley { 1213a89ea682SMatthew G Knepley PetscErrorCode ierr; 1214aa1993deSMatthew G Knepley DMWorkLink link; 1215854ce69bSBarry Smith size_t dsize; 1216a89ea682SMatthew G Knepley 1217a89ea682SMatthew G Knepley PetscFunctionBegin; 1218a89ea682SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1219aa1993deSMatthew G Knepley PetscValidPointer(mem,4); 1220aa1993deSMatthew G Knepley if (dm->workin) { 1221aa1993deSMatthew G Knepley link = dm->workin; 1222aa1993deSMatthew G Knepley dm->workin = dm->workin->next; 1223aa1993deSMatthew G Knepley } else { 1224b00a9115SJed Brown ierr = PetscNewLog(dm,&link);CHKERRQ(ierr); 1225a89ea682SMatthew G Knepley } 1226854ce69bSBarry Smith ierr = PetscDataTypeGetSize(dtype,&dsize);CHKERRQ(ierr); 1227854ce69bSBarry Smith if (dsize*count > link->bytes) { 1228aa1993deSMatthew G Knepley ierr = PetscFree(link->mem);CHKERRQ(ierr); 1229854ce69bSBarry Smith ierr = PetscMalloc(dsize*count,&link->mem);CHKERRQ(ierr); 1230854ce69bSBarry Smith link->bytes = dsize*count; 1231aa1993deSMatthew G Knepley } 1232aa1993deSMatthew G Knepley link->next = dm->workout; 1233aa1993deSMatthew G Knepley dm->workout = link; 1234aa1993deSMatthew G Knepley *(void**)mem = link->mem; 1235a89ea682SMatthew G Knepley PetscFunctionReturn(0); 1236a89ea682SMatthew G Knepley } 1237a89ea682SMatthew G Knepley 1238aa1993deSMatthew G Knepley /*@C 1239aa1993deSMatthew G Knepley DMRestoreWorkArray - Restores a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray() 1240aa1993deSMatthew G Knepley 1241aa1993deSMatthew G Knepley Not Collective 1242aa1993deSMatthew G Knepley 1243aa1993deSMatthew G Knepley Input Parameters: 1244aa1993deSMatthew G Knepley + dm - the DM object 1245aa1993deSMatthew G Knepley . count - The minium size 1246aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT) 1247aa1993deSMatthew G Knepley 1248aa1993deSMatthew G Knepley Output Parameter: 1249aa1993deSMatthew G Knepley . array - the work array 1250aa1993deSMatthew G Knepley 1251aa1993deSMatthew G Knepley Level: developer 1252aa1993deSMatthew G Knepley 1253aa1993deSMatthew G Knepley .seealso DMDestroy(), DMCreate() 1254aa1993deSMatthew G Knepley @*/ 1255aa1993deSMatthew G Knepley PetscErrorCode DMRestoreWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem) 1256aa1993deSMatthew G Knepley { 1257aa1993deSMatthew G Knepley DMWorkLink *p,link; 1258aa1993deSMatthew G Knepley 1259aa1993deSMatthew G Knepley PetscFunctionBegin; 1260aa1993deSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1261aa1993deSMatthew G Knepley PetscValidPointer(mem,4); 1262aa1993deSMatthew G Knepley for (p=&dm->workout; (link=*p); p=&link->next) { 1263aa1993deSMatthew G Knepley if (link->mem == *(void**)mem) { 1264aa1993deSMatthew G Knepley *p = link->next; 1265aa1993deSMatthew G Knepley link->next = dm->workin; 1266aa1993deSMatthew G Knepley dm->workin = link; 12670298fd71SBarry Smith *(void**)mem = NULL; 1268aa1993deSMatthew G Knepley PetscFunctionReturn(0); 1269aa1993deSMatthew G Knepley } 1270aa1993deSMatthew G Knepley } 1271aa1993deSMatthew G Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out"); 1272aa1993deSMatthew G Knepley } 1273e7c4fc90SDmitry Karpeev 1274435a35e8SMatthew G Knepley PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace)) 1275435a35e8SMatthew G Knepley { 1276435a35e8SMatthew G Knepley PetscFunctionBegin; 1277435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 127882f516ccSBarry Smith if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field); 1279435a35e8SMatthew G Knepley dm->nullspaceConstructors[field] = nullsp; 1280435a35e8SMatthew G Knepley PetscFunctionReturn(0); 1281435a35e8SMatthew G Knepley } 1282435a35e8SMatthew G Knepley 12834f3b5142SJed Brown /*@C 12844d343eeaSMatthew G Knepley DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field 12854d343eeaSMatthew G Knepley 12864d343eeaSMatthew G Knepley Not collective 12874d343eeaSMatthew G Knepley 12884d343eeaSMatthew G Knepley Input Parameter: 12894d343eeaSMatthew G Knepley . dm - the DM object 12904d343eeaSMatthew G Knepley 12914d343eeaSMatthew G Knepley Output Parameters: 12920298fd71SBarry Smith + numFields - The number of fields (or NULL if not requested) 12930298fd71SBarry Smith . fieldNames - The name for each field (or NULL if not requested) 12940298fd71SBarry Smith - fields - The global indices for each field (or NULL if not requested) 12954d343eeaSMatthew G Knepley 12964d343eeaSMatthew G Knepley Level: intermediate 12974d343eeaSMatthew G Knepley 129821c9b008SJed Brown Notes: 129921c9b008SJed Brown The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 130021c9b008SJed Brown PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with 130121c9b008SJed Brown PetscFree(). 130221c9b008SJed Brown 13034d343eeaSMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 13044d343eeaSMatthew G Knepley @*/ 130537d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields) 13064d343eeaSMatthew G Knepley { 130737d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 13084d343eeaSMatthew G Knepley PetscErrorCode ierr; 13094d343eeaSMatthew G Knepley 13104d343eeaSMatthew G Knepley PetscFunctionBegin; 13114d343eeaSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 131269ca1f37SDmitry Karpeev if (numFields) { 131369ca1f37SDmitry Karpeev PetscValidPointer(numFields,2); 131469ca1f37SDmitry Karpeev *numFields = 0; 131569ca1f37SDmitry Karpeev } 131637d0c07bSMatthew G Knepley if (fieldNames) { 131737d0c07bSMatthew G Knepley PetscValidPointer(fieldNames,3); 13180298fd71SBarry Smith *fieldNames = NULL; 131969ca1f37SDmitry Karpeev } 132069ca1f37SDmitry Karpeev if (fields) { 132169ca1f37SDmitry Karpeev PetscValidPointer(fields,4); 13220298fd71SBarry Smith *fields = NULL; 132369ca1f37SDmitry Karpeev } 132437d0c07bSMatthew G Knepley ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 132537d0c07bSMatthew G Knepley if (section) { 132637d0c07bSMatthew G Knepley PetscInt *fieldSizes, **fieldIndices; 132737d0c07bSMatthew G Knepley PetscInt nF, f, pStart, pEnd, p; 132837d0c07bSMatthew G Knepley 132937d0c07bSMatthew G Knepley ierr = DMGetDefaultGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 133037d0c07bSMatthew G Knepley ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr); 1331dcca6d9dSJed Brown ierr = PetscMalloc2(nF,&fieldSizes,nF,&fieldIndices);CHKERRQ(ierr); 133237d0c07bSMatthew G Knepley ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 133337d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 133437d0c07bSMatthew G Knepley fieldSizes[f] = 0; 133537d0c07bSMatthew G Knepley } 133637d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 133737d0c07bSMatthew G Knepley PetscInt gdof; 133837d0c07bSMatthew G Knepley 133937d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 134037d0c07bSMatthew G Knepley if (gdof > 0) { 134137d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 134237d0c07bSMatthew G Knepley PetscInt fdof, fcdof; 134337d0c07bSMatthew G Knepley 134437d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 134537d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 134637d0c07bSMatthew G Knepley fieldSizes[f] += fdof-fcdof; 134737d0c07bSMatthew G Knepley } 134837d0c07bSMatthew G Knepley } 134937d0c07bSMatthew G Knepley } 135037d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 1351785e854fSJed Brown ierr = PetscMalloc1(fieldSizes[f], &fieldIndices[f]);CHKERRQ(ierr); 135237d0c07bSMatthew G Knepley fieldSizes[f] = 0; 135337d0c07bSMatthew G Knepley } 135437d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 135537d0c07bSMatthew G Knepley PetscInt gdof, goff; 135637d0c07bSMatthew G Knepley 135737d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 135837d0c07bSMatthew G Knepley if (gdof > 0) { 135937d0c07bSMatthew G Knepley ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr); 136037d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 136137d0c07bSMatthew G Knepley PetscInt fdof, fcdof, fc; 136237d0c07bSMatthew G Knepley 136337d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 136437d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 136537d0c07bSMatthew G Knepley for (fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) { 136637d0c07bSMatthew G Knepley fieldIndices[f][fieldSizes[f]] = goff++; 136737d0c07bSMatthew G Knepley } 136837d0c07bSMatthew G Knepley } 136937d0c07bSMatthew G Knepley } 137037d0c07bSMatthew G Knepley } 13718865f1eaSKarl Rupp if (numFields) *numFields = nF; 137237d0c07bSMatthew G Knepley if (fieldNames) { 1373785e854fSJed Brown ierr = PetscMalloc1(nF, fieldNames);CHKERRQ(ierr); 137437d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 137537d0c07bSMatthew G Knepley const char *fieldName; 137637d0c07bSMatthew G Knepley 137737d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr); 137837d0c07bSMatthew G Knepley ierr = PetscStrallocpy(fieldName, (char**) &(*fieldNames)[f]);CHKERRQ(ierr); 137937d0c07bSMatthew G Knepley } 138037d0c07bSMatthew G Knepley } 138137d0c07bSMatthew G Knepley if (fields) { 1382785e854fSJed Brown ierr = PetscMalloc1(nF, fields);CHKERRQ(ierr); 138337d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 138482f516ccSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr); 138537d0c07bSMatthew G Knepley } 138637d0c07bSMatthew G Knepley } 138737d0c07bSMatthew G Knepley ierr = PetscFree2(fieldSizes,fieldIndices);CHKERRQ(ierr); 13888865f1eaSKarl Rupp } else if (dm->ops->createfieldis) { 13898865f1eaSKarl Rupp ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr); 139069ca1f37SDmitry Karpeev } 13914d343eeaSMatthew G Knepley PetscFunctionReturn(0); 13924d343eeaSMatthew G Knepley } 13934d343eeaSMatthew G Knepley 139416621825SDmitry Karpeev 139516621825SDmitry Karpeev /*@C 139616621825SDmitry Karpeev DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems 139716621825SDmitry Karpeev corresponding to different fields: each IS contains the global indices of the dofs of the 139816621825SDmitry Karpeev corresponding field. The optional list of DMs define the DM for each subproblem. 1399e7c4fc90SDmitry Karpeev Generalizes DMCreateFieldIS(). 1400e7c4fc90SDmitry Karpeev 1401e7c4fc90SDmitry Karpeev Not collective 1402e7c4fc90SDmitry Karpeev 1403e7c4fc90SDmitry Karpeev Input Parameter: 1404e7c4fc90SDmitry Karpeev . dm - the DM object 1405e7c4fc90SDmitry Karpeev 1406e7c4fc90SDmitry Karpeev Output Parameters: 14070298fd71SBarry Smith + len - The number of subproblems in the field decomposition (or NULL if not requested) 14080298fd71SBarry Smith . namelist - The name for each field (or NULL if not requested) 14090298fd71SBarry Smith . islist - The global indices for each field (or NULL if not requested) 14100298fd71SBarry Smith - dmlist - The DMs for each field subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined) 1411e7c4fc90SDmitry Karpeev 1412e7c4fc90SDmitry Karpeev Level: intermediate 1413e7c4fc90SDmitry Karpeev 1414e7c4fc90SDmitry Karpeev Notes: 1415e7c4fc90SDmitry Karpeev The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 1416e7c4fc90SDmitry Karpeev PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(), 1417e7c4fc90SDmitry Karpeev and all of the arrays should be freed with PetscFree(). 1418e7c4fc90SDmitry Karpeev 1419e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 1420e7c4fc90SDmitry Karpeev @*/ 142116621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist) 1422e7c4fc90SDmitry Karpeev { 1423e7c4fc90SDmitry Karpeev PetscErrorCode ierr; 1424e7c4fc90SDmitry Karpeev 1425e7c4fc90SDmitry Karpeev PetscFunctionBegin; 1426e7c4fc90SDmitry Karpeev PetscValidHeaderSpecific(dm,DM_CLASSID,1); 14278865f1eaSKarl Rupp if (len) { 14288865f1eaSKarl Rupp PetscValidPointer(len,2); 14298865f1eaSKarl Rupp *len = 0; 14308865f1eaSKarl Rupp } 14318865f1eaSKarl Rupp if (namelist) { 14328865f1eaSKarl Rupp PetscValidPointer(namelist,3); 14338865f1eaSKarl Rupp *namelist = 0; 14348865f1eaSKarl Rupp } 14358865f1eaSKarl Rupp if (islist) { 14368865f1eaSKarl Rupp PetscValidPointer(islist,4); 14378865f1eaSKarl Rupp *islist = 0; 14388865f1eaSKarl Rupp } 14398865f1eaSKarl Rupp if (dmlist) { 14408865f1eaSKarl Rupp PetscValidPointer(dmlist,5); 14418865f1eaSKarl Rupp *dmlist = 0; 14428865f1eaSKarl Rupp } 1443f3f0edfdSDmitry Karpeev /* 1444f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 1445f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 1446f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 1447f3f0edfdSDmitry Karpeev */ 1448ce94432eSBarry Smith if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 144916621825SDmitry Karpeev if (!dm->ops->createfielddecomposition) { 1450435a35e8SMatthew G Knepley PetscSection section; 1451435a35e8SMatthew G Knepley PetscInt numFields, f; 1452435a35e8SMatthew G Knepley 1453435a35e8SMatthew G Knepley ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 1454435a35e8SMatthew G Knepley if (section) {ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr);} 1455435a35e8SMatthew G Knepley if (section && numFields && dm->ops->createsubdm) { 1456f25d98f1SMatthew G. Knepley if (len) *len = numFields; 145703dc3394SMatthew G. Knepley if (namelist) {ierr = PetscMalloc1(numFields,namelist);CHKERRQ(ierr);} 145803dc3394SMatthew G. Knepley if (islist) {ierr = PetscMalloc1(numFields,islist);CHKERRQ(ierr);} 145903dc3394SMatthew G. Knepley if (dmlist) {ierr = PetscMalloc1(numFields,dmlist);CHKERRQ(ierr);} 1460435a35e8SMatthew G Knepley for (f = 0; f < numFields; ++f) { 1461435a35e8SMatthew G Knepley const char *fieldName; 1462435a35e8SMatthew G Knepley 146303dc3394SMatthew G. Knepley ierr = DMCreateSubDM(dm, 1, &f, islist ? &(*islist)[f] : NULL, dmlist ? &(*dmlist)[f] : NULL);CHKERRQ(ierr); 146403dc3394SMatthew G. Knepley if (namelist) { 1465435a35e8SMatthew G Knepley ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr); 1466435a35e8SMatthew G Knepley ierr = PetscStrallocpy(fieldName, (char**) &(*namelist)[f]);CHKERRQ(ierr); 1467435a35e8SMatthew G Knepley } 146803dc3394SMatthew G. Knepley } 1469435a35e8SMatthew G Knepley } else { 147069ca1f37SDmitry Karpeev ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr); 1471e7c4fc90SDmitry Karpeev /* By default there are no DMs associated with subproblems. */ 14720298fd71SBarry Smith if (dmlist) *dmlist = NULL; 1473e7c4fc90SDmitry Karpeev } 14748865f1eaSKarl Rupp } else { 147516621825SDmitry Karpeev ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist);CHKERRQ(ierr); 147616621825SDmitry Karpeev } 147716621825SDmitry Karpeev PetscFunctionReturn(0); 147816621825SDmitry Karpeev } 147916621825SDmitry Karpeev 1480564cec59SMatthew G. Knepley /*@ 1481435a35e8SMatthew G Knepley DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in. 1482435a35e8SMatthew G Knepley The fields are defined by DMCreateFieldIS(). 1483435a35e8SMatthew G Knepley 1484435a35e8SMatthew G Knepley Not collective 1485435a35e8SMatthew G Knepley 1486435a35e8SMatthew G Knepley Input Parameters: 1487435a35e8SMatthew G Knepley + dm - the DM object 1488435a35e8SMatthew G Knepley . numFields - number of fields in this subproblem 14890298fd71SBarry Smith - len - The number of subproblems in the decomposition (or NULL if not requested) 1490435a35e8SMatthew G Knepley 1491435a35e8SMatthew G Knepley Output Parameters: 1492435a35e8SMatthew G Knepley . is - The global indices for the subproblem 1493435a35e8SMatthew G Knepley - dm - The DM for the subproblem 1494435a35e8SMatthew G Knepley 1495435a35e8SMatthew G Knepley Level: intermediate 1496435a35e8SMatthew G Knepley 1497435a35e8SMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 1498435a35e8SMatthew G Knepley @*/ 1499435a35e8SMatthew G Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm) 1500435a35e8SMatthew G Knepley { 1501435a35e8SMatthew G Knepley PetscErrorCode ierr; 1502435a35e8SMatthew G Knepley 1503435a35e8SMatthew G Knepley PetscFunctionBegin; 1504435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1505435a35e8SMatthew G Knepley PetscValidPointer(fields,3); 15068865f1eaSKarl Rupp if (is) PetscValidPointer(is,4); 15078865f1eaSKarl Rupp if (subdm) PetscValidPointer(subdm,5); 1508435a35e8SMatthew G Knepley if (dm->ops->createsubdm) { 1509435a35e8SMatthew G Knepley ierr = (*dm->ops->createsubdm)(dm, numFields, fields, is, subdm);CHKERRQ(ierr); 151082f516ccSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "This type has no DMCreateSubDM implementation defined"); 1511435a35e8SMatthew G Knepley PetscFunctionReturn(0); 1512435a35e8SMatthew G Knepley } 1513435a35e8SMatthew G Knepley 151416621825SDmitry Karpeev 151516621825SDmitry Karpeev /*@C 15168d4ac253SDmitry Karpeev DMCreateDomainDecomposition - Returns lists of IS objects defining a decomposition of a problem into subproblems 15178d4ac253SDmitry Karpeev corresponding to restrictions to pairs nested subdomains: each IS contains the global 15188d4ac253SDmitry Karpeev indices of the dofs of the corresponding subdomains. The inner subdomains conceptually 15198d4ac253SDmitry Karpeev define a nonoverlapping covering, while outer subdomains can overlap. 15208d4ac253SDmitry Karpeev The optional list of DMs define the DM for each subproblem. 152116621825SDmitry Karpeev 152216621825SDmitry Karpeev Not collective 152316621825SDmitry Karpeev 152416621825SDmitry Karpeev Input Parameter: 152516621825SDmitry Karpeev . dm - the DM object 152616621825SDmitry Karpeev 152716621825SDmitry Karpeev Output Parameters: 15280298fd71SBarry Smith + len - The number of subproblems in the domain decomposition (or NULL if not requested) 15290298fd71SBarry Smith . namelist - The name for each subdomain (or NULL if not requested) 15300298fd71SBarry Smith . innerislist - The global indices for each inner subdomain (or NULL, if not requested) 15310298fd71SBarry Smith . outerislist - The global indices for each outer subdomain (or NULL, if not requested) 15320298fd71SBarry Smith - dmlist - The DMs for each subdomain subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined) 153316621825SDmitry Karpeev 153416621825SDmitry Karpeev Level: intermediate 153516621825SDmitry Karpeev 153616621825SDmitry Karpeev Notes: 153716621825SDmitry Karpeev The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 153816621825SDmitry Karpeev PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(), 153916621825SDmitry Karpeev and all of the arrays should be freed with PetscFree(). 154016621825SDmitry Karpeev 15418d4ac253SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateDomainDecompositionDM(), DMCreateFieldDecomposition() 154216621825SDmitry Karpeev @*/ 15438d4ac253SDmitry Karpeev PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist) 154416621825SDmitry Karpeev { 154516621825SDmitry Karpeev PetscErrorCode ierr; 1546be081cd6SPeter Brune DMSubDomainHookLink link; 1547be081cd6SPeter Brune PetscInt i,l; 154816621825SDmitry Karpeev 154916621825SDmitry Karpeev PetscFunctionBegin; 155016621825SDmitry Karpeev PetscValidHeaderSpecific(dm,DM_CLASSID,1); 155114a18fd3SPeter Brune if (len) {PetscValidPointer(len,2); *len = 0;} 15520298fd71SBarry Smith if (namelist) {PetscValidPointer(namelist,3); *namelist = NULL;} 15530298fd71SBarry Smith if (innerislist) {PetscValidPointer(innerislist,4); *innerislist = NULL;} 15540298fd71SBarry Smith if (outerislist) {PetscValidPointer(outerislist,5); *outerislist = NULL;} 15550298fd71SBarry Smith if (dmlist) {PetscValidPointer(dmlist,6); *dmlist = NULL;} 1556f3f0edfdSDmitry Karpeev /* 1557f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 1558f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 1559f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 1560f3f0edfdSDmitry Karpeev */ 1561ce94432eSBarry Smith if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 156216621825SDmitry Karpeev if (dm->ops->createdomaindecomposition) { 1563be081cd6SPeter Brune ierr = (*dm->ops->createdomaindecomposition)(dm,&l,namelist,innerislist,outerislist,dmlist);CHKERRQ(ierr); 156414a18fd3SPeter Brune /* copy subdomain hooks and context over to the subdomain DMs */ 1565f891f5b9SPatrick Sanan if (dmlist && *dmlist) { 1566be081cd6SPeter Brune for (i = 0; i < l; i++) { 1567be081cd6SPeter Brune for (link=dm->subdomainhook; link; link=link->next) { 1568be081cd6SPeter Brune if (link->ddhook) {ierr = (*link->ddhook)(dm,(*dmlist)[i],link->ctx);CHKERRQ(ierr);} 1569be081cd6SPeter Brune } 1570648262bbSPatrick Sanan if (dm->ctx) (*dmlist)[i]->ctx = dm->ctx; 1571e7c4fc90SDmitry Karpeev } 157214a18fd3SPeter Brune } 157314a18fd3SPeter Brune if (len) *len = l; 157414a18fd3SPeter Brune } 1575e30e807fSPeter Brune PetscFunctionReturn(0); 1576e30e807fSPeter Brune } 1577e30e807fSPeter Brune 1578e30e807fSPeter Brune 1579e30e807fSPeter Brune /*@C 1580e30e807fSPeter Brune DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector 1581e30e807fSPeter Brune 1582e30e807fSPeter Brune Not collective 1583e30e807fSPeter Brune 1584e30e807fSPeter Brune Input Parameters: 1585e30e807fSPeter Brune + dm - the DM object 1586e30e807fSPeter Brune . n - the number of subdomain scatters 1587e30e807fSPeter Brune - subdms - the local subdomains 1588e30e807fSPeter Brune 1589e30e807fSPeter Brune Output Parameters: 1590e30e807fSPeter Brune + n - the number of scatters returned 1591e30e807fSPeter Brune . iscat - scatter from global vector to nonoverlapping global vector entries on subdomain 1592e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain 1593e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts) 1594e30e807fSPeter Brune 1595e30e807fSPeter Brune Notes: This is an alternative to the iis and ois arguments in DMCreateDomainDecomposition that allow for the solution 1596e30e807fSPeter Brune of general nonlinear problems with overlapping subdomain methods. While merely having index sets that enable subsets 1597e30e807fSPeter Brune of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of 1598e30e807fSPeter Brune solution and residual data. 1599e30e807fSPeter Brune 1600e30e807fSPeter Brune Level: developer 1601e30e807fSPeter Brune 1602e30e807fSPeter Brune .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 1603e30e807fSPeter Brune @*/ 1604e30e807fSPeter Brune PetscErrorCode DMCreateDomainDecompositionScatters(DM dm,PetscInt n,DM *subdms,VecScatter **iscat,VecScatter **oscat,VecScatter **gscat) 1605e30e807fSPeter Brune { 1606e30e807fSPeter Brune PetscErrorCode ierr; 1607e30e807fSPeter Brune 1608e30e807fSPeter Brune PetscFunctionBegin; 1609e30e807fSPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1610e30e807fSPeter Brune PetscValidPointer(subdms,3); 1611e30e807fSPeter Brune if (dm->ops->createddscatters) { 1612e30e807fSPeter Brune ierr = (*dm->ops->createddscatters)(dm,n,subdms,iscat,oscat,gscat);CHKERRQ(ierr); 16136668ed41SLisandro Dalcin } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "This type has no DMCreateDomainDecompositionScatter implementation defined"); 1614e7c4fc90SDmitry Karpeev PetscFunctionReturn(0); 1615e7c4fc90SDmitry Karpeev } 1616e7c4fc90SDmitry Karpeev 161747c6ae99SBarry Smith /*@ 161847c6ae99SBarry Smith DMRefine - Refines a DM object 161947c6ae99SBarry Smith 162047c6ae99SBarry Smith Collective on DM 162147c6ae99SBarry Smith 162247c6ae99SBarry Smith Input Parameter: 162347c6ae99SBarry Smith + dm - the DM object 162491d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL) 162547c6ae99SBarry Smith 162647c6ae99SBarry Smith Output Parameter: 16270298fd71SBarry Smith . dmf - the refined DM, or NULL 1628ae0a1c52SMatthew G Knepley 16290298fd71SBarry Smith Note: If no refinement was done, the return value is NULL 163047c6ae99SBarry Smith 163147c6ae99SBarry Smith Level: developer 163247c6ae99SBarry Smith 1633e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 163447c6ae99SBarry Smith @*/ 16357087cfbeSBarry Smith PetscErrorCode DMRefine(DM dm,MPI_Comm comm,DM *dmf) 163647c6ae99SBarry Smith { 163747c6ae99SBarry Smith PetscErrorCode ierr; 1638c833c3b5SJed Brown DMRefineHookLink link; 163947c6ae99SBarry Smith 164047c6ae99SBarry Smith PetscFunctionBegin; 1641732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 16421ac00216SMatthew G. Knepley ierr = PetscLogEventBegin(DM_Refine,dm,0,0,0);CHKERRQ(ierr); 1643fef3a512SBarry Smith if (!dm->ops->refine) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM cannot refine"); 164447c6ae99SBarry Smith ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr); 16454057135bSMatthew G Knepley if (*dmf) { 164643842a1eSJed Brown (*dmf)->ops->creatematrix = dm->ops->creatematrix; 16478865f1eaSKarl Rupp 16488cd211a4SJed Brown ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr); 16498865f1eaSKarl Rupp 1650644e2e5bSBarry Smith (*dmf)->ctx = dm->ctx; 16510598a293SJed Brown (*dmf)->leveldown = dm->leveldown; 1652656b349aSBarry Smith (*dmf)->levelup = dm->levelup + 1; 16538865f1eaSKarl Rupp 1654e4b4b23bSJed Brown ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr); 1655c833c3b5SJed Brown for (link=dm->refinehook; link; link=link->next) { 16568865f1eaSKarl Rupp if (link->refinehook) { 16578865f1eaSKarl Rupp ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr); 16588865f1eaSKarl Rupp } 1659c833c3b5SJed Brown } 1660c833c3b5SJed Brown } 16611ac00216SMatthew G. Knepley ierr = PetscLogEventEnd(DM_Refine,dm,0,0,0);CHKERRQ(ierr); 1662c833c3b5SJed Brown PetscFunctionReturn(0); 1663c833c3b5SJed Brown } 1664c833c3b5SJed Brown 1665bb9467b5SJed Brown /*@C 1666c833c3b5SJed Brown DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid 1667c833c3b5SJed Brown 1668c833c3b5SJed Brown Logically Collective 1669c833c3b5SJed Brown 1670c833c3b5SJed Brown Input Arguments: 1671c833c3b5SJed Brown + coarse - nonlinear solver context on which to run a hook when restricting to a coarser level 1672c833c3b5SJed Brown . refinehook - function to run when setting up a coarser level 1673c833c3b5SJed Brown . interphook - function to run to update data on finer levels (once per SNESSolve()) 16740298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 1675c833c3b5SJed Brown 1676c833c3b5SJed Brown Calling sequence of refinehook: 1677c833c3b5SJed Brown $ refinehook(DM coarse,DM fine,void *ctx); 1678c833c3b5SJed Brown 1679c833c3b5SJed Brown + coarse - coarse level DM 1680c833c3b5SJed Brown . fine - fine level DM to interpolate problem to 1681c833c3b5SJed Brown - ctx - optional user-defined function context 1682c833c3b5SJed Brown 1683c833c3b5SJed Brown Calling sequence for interphook: 1684c833c3b5SJed Brown $ interphook(DM coarse,Mat interp,DM fine,void *ctx) 1685c833c3b5SJed Brown 1686c833c3b5SJed Brown + coarse - coarse level DM 1687c833c3b5SJed Brown . interp - matrix interpolating a coarse-level solution to the finer grid 1688c833c3b5SJed Brown . fine - fine level DM to update 1689c833c3b5SJed Brown - ctx - optional user-defined function context 1690c833c3b5SJed Brown 1691c833c3b5SJed Brown Level: advanced 1692c833c3b5SJed Brown 1693c833c3b5SJed Brown Notes: 1694c833c3b5SJed Brown This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing 1695c833c3b5SJed Brown 1696c833c3b5SJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 1697c833c3b5SJed Brown 1698bb9467b5SJed Brown This function is currently not available from Fortran. 1699bb9467b5SJed Brown 1700c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 1701c833c3b5SJed Brown @*/ 1702c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx) 1703c833c3b5SJed Brown { 1704c833c3b5SJed Brown PetscErrorCode ierr; 1705c833c3b5SJed Brown DMRefineHookLink link,*p; 1706c833c3b5SJed Brown 1707c833c3b5SJed Brown PetscFunctionBegin; 1708c833c3b5SJed Brown PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 1709c833c3b5SJed Brown for (p=&coarse->refinehook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 171095dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 1711c833c3b5SJed Brown link->refinehook = refinehook; 1712c833c3b5SJed Brown link->interphook = interphook; 1713c833c3b5SJed Brown link->ctx = ctx; 17140298fd71SBarry Smith link->next = NULL; 1715c833c3b5SJed Brown *p = link; 1716c833c3b5SJed Brown PetscFunctionReturn(0); 1717c833c3b5SJed Brown } 1718c833c3b5SJed Brown 1719c833c3b5SJed Brown /*@ 1720c833c3b5SJed Brown DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd() 1721c833c3b5SJed Brown 1722c833c3b5SJed Brown Collective if any hooks are 1723c833c3b5SJed Brown 1724c833c3b5SJed Brown Input Arguments: 1725c833c3b5SJed Brown + coarse - coarser DM to use as a base 1726c833c3b5SJed Brown . restrct - interpolation matrix, apply using MatInterpolate() 1727c833c3b5SJed Brown - fine - finer DM to update 1728c833c3b5SJed Brown 1729c833c3b5SJed Brown Level: developer 1730c833c3b5SJed Brown 1731c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate() 1732c833c3b5SJed Brown @*/ 1733c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine) 1734c833c3b5SJed Brown { 1735c833c3b5SJed Brown PetscErrorCode ierr; 1736c833c3b5SJed Brown DMRefineHookLink link; 1737c833c3b5SJed Brown 1738c833c3b5SJed Brown PetscFunctionBegin; 1739c833c3b5SJed Brown for (link=fine->refinehook; link; link=link->next) { 17408865f1eaSKarl Rupp if (link->interphook) { 17418865f1eaSKarl Rupp ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr); 17428865f1eaSKarl Rupp } 17434057135bSMatthew G Knepley } 174447c6ae99SBarry Smith PetscFunctionReturn(0); 174547c6ae99SBarry Smith } 174647c6ae99SBarry Smith 1747eb3f98d2SBarry Smith /*@ 1748eb3f98d2SBarry Smith DMGetRefineLevel - Get's the number of refinements that have generated this DM. 1749eb3f98d2SBarry Smith 1750eb3f98d2SBarry Smith Not Collective 1751eb3f98d2SBarry Smith 1752eb3f98d2SBarry Smith Input Parameter: 1753eb3f98d2SBarry Smith . dm - the DM object 1754eb3f98d2SBarry Smith 1755eb3f98d2SBarry Smith Output Parameter: 1756eb3f98d2SBarry Smith . level - number of refinements 1757eb3f98d2SBarry Smith 1758eb3f98d2SBarry Smith Level: developer 1759eb3f98d2SBarry Smith 17606a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 1761eb3f98d2SBarry Smith 1762eb3f98d2SBarry Smith @*/ 1763eb3f98d2SBarry Smith PetscErrorCode DMGetRefineLevel(DM dm,PetscInt *level) 1764eb3f98d2SBarry Smith { 1765eb3f98d2SBarry Smith PetscFunctionBegin; 1766eb3f98d2SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1767eb3f98d2SBarry Smith *level = dm->levelup; 1768eb3f98d2SBarry Smith PetscFunctionReturn(0); 1769eb3f98d2SBarry Smith } 1770eb3f98d2SBarry Smith 1771fef3a512SBarry Smith /*@ 1772fef3a512SBarry Smith DMSetRefineLevel - Set's the number of refinements that have generated this DM. 1773fef3a512SBarry Smith 1774fef3a512SBarry Smith Not Collective 1775fef3a512SBarry Smith 1776fef3a512SBarry Smith Input Parameter: 1777fef3a512SBarry Smith + dm - the DM object 1778fef3a512SBarry Smith - level - number of refinements 1779fef3a512SBarry Smith 1780fef3a512SBarry Smith Level: advanced 1781fef3a512SBarry Smith 1782fef3a512SBarry Smith Notes: This value is used by PCMG to determine how many multigrid levels to use 1783fef3a512SBarry Smith 1784fef3a512SBarry Smith .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 1785fef3a512SBarry Smith 1786fef3a512SBarry Smith @*/ 1787fef3a512SBarry Smith PetscErrorCode DMSetRefineLevel(DM dm,PetscInt level) 1788fef3a512SBarry Smith { 1789fef3a512SBarry Smith PetscFunctionBegin; 1790fef3a512SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1791fef3a512SBarry Smith dm->levelup = level; 1792fef3a512SBarry Smith PetscFunctionReturn(0); 1793fef3a512SBarry Smith } 1794fef3a512SBarry Smith 1795bb9467b5SJed Brown /*@C 1796baf369e7SPeter Brune DMGlobalToLocalHookAdd - adds a callback to be run when global to local is called 1797baf369e7SPeter Brune 1798baf369e7SPeter Brune Logically Collective 1799baf369e7SPeter Brune 1800baf369e7SPeter Brune Input Arguments: 1801baf369e7SPeter Brune + dm - the DM 1802baf369e7SPeter Brune . beginhook - function to run at the beginning of DMGlobalToLocalBegin() 1803baf369e7SPeter Brune . endhook - function to run after DMGlobalToLocalEnd() has completed 18040298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 1805baf369e7SPeter Brune 1806baf369e7SPeter Brune Calling sequence for beginhook: 1807baf369e7SPeter Brune $ beginhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx) 1808baf369e7SPeter Brune 1809baf369e7SPeter Brune + dm - global DM 1810baf369e7SPeter Brune . g - global vector 1811baf369e7SPeter Brune . mode - mode 1812baf369e7SPeter Brune . l - local vector 1813baf369e7SPeter Brune - ctx - optional user-defined function context 1814baf369e7SPeter Brune 1815baf369e7SPeter Brune 1816baf369e7SPeter Brune Calling sequence for endhook: 1817ec4806b8SPeter Brune $ endhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx) 1818baf369e7SPeter Brune 1819baf369e7SPeter Brune + global - global DM 1820baf369e7SPeter Brune - ctx - optional user-defined function context 1821baf369e7SPeter Brune 1822baf369e7SPeter Brune Level: advanced 1823baf369e7SPeter Brune 1824baf369e7SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 1825baf369e7SPeter Brune @*/ 1826baf369e7SPeter Brune PetscErrorCode DMGlobalToLocalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx) 1827baf369e7SPeter Brune { 1828baf369e7SPeter Brune PetscErrorCode ierr; 1829baf369e7SPeter Brune DMGlobalToLocalHookLink link,*p; 1830baf369e7SPeter Brune 1831baf369e7SPeter Brune PetscFunctionBegin; 1832baf369e7SPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1833baf369e7SPeter Brune for (p=&dm->gtolhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 183495dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 1835baf369e7SPeter Brune link->beginhook = beginhook; 1836baf369e7SPeter Brune link->endhook = endhook; 1837baf369e7SPeter Brune link->ctx = ctx; 18380298fd71SBarry Smith link->next = NULL; 1839baf369e7SPeter Brune *p = link; 1840baf369e7SPeter Brune PetscFunctionReturn(0); 1841baf369e7SPeter Brune } 1842baf369e7SPeter Brune 18434c274da1SToby Isaac static PetscErrorCode DMGlobalToLocalHook_Constraints(DM dm, Vec g, InsertMode mode, Vec l, void *ctx) 18444c274da1SToby Isaac { 18454c274da1SToby Isaac Mat cMat; 18464c274da1SToby Isaac Vec cVec; 18474c274da1SToby Isaac PetscSection section, cSec; 18484c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 18494c274da1SToby Isaac PetscErrorCode ierr; 18504c274da1SToby Isaac 18514c274da1SToby Isaac PetscFunctionBegin; 18524c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18534c274da1SToby Isaac ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr); 18544c274da1SToby Isaac if (cMat && (mode == INSERT_VALUES || mode == INSERT_ALL_VALUES || mode == INSERT_BC_VALUES)) { 18555db9a05bSToby Isaac PetscInt nRows; 18565db9a05bSToby Isaac 18575db9a05bSToby Isaac ierr = MatGetSize(cMat,&nRows,NULL);CHKERRQ(ierr); 18585db9a05bSToby Isaac if (nRows <= 0) PetscFunctionReturn(0); 18594c274da1SToby Isaac ierr = DMGetDefaultSection(dm,§ion);CHKERRQ(ierr); 18607711e48fSToby Isaac ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr); 18614c274da1SToby Isaac ierr = MatMult(cMat,l,cVec);CHKERRQ(ierr); 18624c274da1SToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 18634c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 18644c274da1SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 18654c274da1SToby Isaac if (dof) { 18664c274da1SToby Isaac PetscScalar *vals; 18674c274da1SToby Isaac ierr = VecGetValuesSection(cVec,cSec,p,&vals);CHKERRQ(ierr); 18684c274da1SToby Isaac ierr = VecSetValuesSection(l,section,p,vals,INSERT_ALL_VALUES);CHKERRQ(ierr); 18694c274da1SToby Isaac } 18704c274da1SToby Isaac } 18714c274da1SToby Isaac ierr = VecDestroy(&cVec);CHKERRQ(ierr); 18724c274da1SToby Isaac } 18734c274da1SToby Isaac PetscFunctionReturn(0); 18744c274da1SToby Isaac } 18754c274da1SToby Isaac 187647c6ae99SBarry Smith /*@ 187747c6ae99SBarry Smith DMGlobalToLocalBegin - Begins updating local vectors from global vector 187847c6ae99SBarry Smith 187947c6ae99SBarry Smith Neighbor-wise Collective on DM 188047c6ae99SBarry Smith 188147c6ae99SBarry Smith Input Parameters: 188247c6ae99SBarry Smith + dm - the DM object 188347c6ae99SBarry Smith . g - the global vector 188447c6ae99SBarry Smith . mode - INSERT_VALUES or ADD_VALUES 188547c6ae99SBarry Smith - l - the local vector 188647c6ae99SBarry Smith 188747c6ae99SBarry Smith 188847c6ae99SBarry Smith Level: beginner 188947c6ae99SBarry Smith 1890e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 189147c6ae99SBarry Smith 189247c6ae99SBarry Smith @*/ 18937087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l) 189447c6ae99SBarry Smith { 18957128ae9fSMatthew G Knepley PetscSF sf; 189647c6ae99SBarry Smith PetscErrorCode ierr; 1897baf369e7SPeter Brune DMGlobalToLocalHookLink link; 189847c6ae99SBarry Smith 189947c6ae99SBarry Smith PetscFunctionBegin; 1900171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1901baf369e7SPeter Brune for (link=dm->gtolhook; link; link=link->next) { 19028865f1eaSKarl Rupp if (link->beginhook) { 19038865f1eaSKarl Rupp ierr = (*link->beginhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr); 19048865f1eaSKarl Rupp } 1905baf369e7SPeter Brune } 19067128ae9fSMatthew G Knepley ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr); 19077128ae9fSMatthew G Knepley if (sf) { 1908ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 1909ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 19107128ae9fSMatthew G Knepley 191182f516ccSBarry Smith if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 19127128ae9fSMatthew G Knepley ierr = VecGetArray(l, &lArray);CHKERRQ(ierr); 1913ae5cfb4aSMatthew G. Knepley ierr = VecGetArrayRead(g, &gArray);CHKERRQ(ierr); 19147128ae9fSMatthew G Knepley ierr = PetscSFBcastBegin(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr); 19157128ae9fSMatthew G Knepley ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr); 1916ae5cfb4aSMatthew G. Knepley ierr = VecRestoreArrayRead(g, &gArray);CHKERRQ(ierr); 19177128ae9fSMatthew G Knepley } else { 1918843c4018SMatthew G Knepley ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 19197128ae9fSMatthew G Knepley } 192047c6ae99SBarry Smith PetscFunctionReturn(0); 192147c6ae99SBarry Smith } 192247c6ae99SBarry Smith 192347c6ae99SBarry Smith /*@ 192447c6ae99SBarry Smith DMGlobalToLocalEnd - Ends updating local vectors from global vector 192547c6ae99SBarry Smith 192647c6ae99SBarry Smith Neighbor-wise Collective on DM 192747c6ae99SBarry Smith 192847c6ae99SBarry Smith Input Parameters: 192947c6ae99SBarry Smith + dm - the DM object 193047c6ae99SBarry Smith . g - the global vector 193147c6ae99SBarry Smith . mode - INSERT_VALUES or ADD_VALUES 193247c6ae99SBarry Smith - l - the local vector 193347c6ae99SBarry Smith 193447c6ae99SBarry Smith 193547c6ae99SBarry Smith Level: beginner 193647c6ae99SBarry Smith 1937e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 193847c6ae99SBarry Smith 193947c6ae99SBarry Smith @*/ 19407087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l) 194147c6ae99SBarry Smith { 19427128ae9fSMatthew G Knepley PetscSF sf; 194347c6ae99SBarry Smith PetscErrorCode ierr; 1944ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 1945ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 1946baf369e7SPeter Brune DMGlobalToLocalHookLink link; 194747c6ae99SBarry Smith 194847c6ae99SBarry Smith PetscFunctionBegin; 1949171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 19507128ae9fSMatthew G Knepley ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr); 19517128ae9fSMatthew G Knepley if (sf) { 195282f516ccSBarry Smith if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 19537128ae9fSMatthew G Knepley 19547128ae9fSMatthew G Knepley ierr = VecGetArray(l, &lArray);CHKERRQ(ierr); 1955ae5cfb4aSMatthew G. Knepley ierr = VecGetArrayRead(g, &gArray);CHKERRQ(ierr); 19567128ae9fSMatthew G Knepley ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr); 19577128ae9fSMatthew G Knepley ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr); 1958ae5cfb4aSMatthew G. Knepley ierr = VecRestoreArrayRead(g, &gArray);CHKERRQ(ierr); 19597128ae9fSMatthew G Knepley } else { 1960843c4018SMatthew G Knepley ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 19617128ae9fSMatthew G Knepley } 19624c274da1SToby Isaac ierr = DMGlobalToLocalHook_Constraints(dm,g,mode,l,NULL);CHKERRQ(ierr); 1963baf369e7SPeter Brune for (link=dm->gtolhook; link; link=link->next) { 1964baf369e7SPeter Brune if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);} 1965baf369e7SPeter Brune } 196647c6ae99SBarry Smith PetscFunctionReturn(0); 196747c6ae99SBarry Smith } 196847c6ae99SBarry Smith 1969d4d07f1eSToby Isaac /*@C 1970d4d07f1eSToby Isaac DMLocalToGlobalHookAdd - adds a callback to be run when a local to global is called 1971d4d07f1eSToby Isaac 1972d4d07f1eSToby Isaac Logically Collective 1973d4d07f1eSToby Isaac 1974d4d07f1eSToby Isaac Input Arguments: 1975d4d07f1eSToby Isaac + dm - the DM 1976d4d07f1eSToby Isaac . beginhook - function to run at the beginning of DMLocalToGlobalBegin() 1977d4d07f1eSToby Isaac . endhook - function to run after DMLocalToGlobalEnd() has completed 1978d4d07f1eSToby Isaac - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 1979d4d07f1eSToby Isaac 1980d4d07f1eSToby Isaac Calling sequence for beginhook: 1981d4d07f1eSToby Isaac $ beginhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx) 1982d4d07f1eSToby Isaac 1983d4d07f1eSToby Isaac + dm - global DM 1984d4d07f1eSToby Isaac . l - local vector 1985d4d07f1eSToby Isaac . mode - mode 1986d4d07f1eSToby Isaac . g - global vector 1987d4d07f1eSToby Isaac - ctx - optional user-defined function context 1988d4d07f1eSToby Isaac 1989d4d07f1eSToby Isaac 1990d4d07f1eSToby Isaac Calling sequence for endhook: 1991d4d07f1eSToby Isaac $ endhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx) 1992d4d07f1eSToby Isaac 1993d4d07f1eSToby Isaac + global - global DM 1994d4d07f1eSToby Isaac . l - local vector 1995d4d07f1eSToby Isaac . mode - mode 1996d4d07f1eSToby Isaac . g - global vector 1997d4d07f1eSToby Isaac - ctx - optional user-defined function context 1998d4d07f1eSToby Isaac 1999d4d07f1eSToby Isaac Level: advanced 2000d4d07f1eSToby Isaac 2001d4d07f1eSToby Isaac .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 2002d4d07f1eSToby Isaac @*/ 2003d4d07f1eSToby Isaac PetscErrorCode DMLocalToGlobalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx) 2004d4d07f1eSToby Isaac { 2005d4d07f1eSToby Isaac PetscErrorCode ierr; 2006d4d07f1eSToby Isaac DMLocalToGlobalHookLink link,*p; 2007d4d07f1eSToby Isaac 2008d4d07f1eSToby Isaac PetscFunctionBegin; 2009d4d07f1eSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2010d4d07f1eSToby Isaac for (p=&dm->ltoghook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 201195dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 2012d4d07f1eSToby Isaac link->beginhook = beginhook; 2013d4d07f1eSToby Isaac link->endhook = endhook; 2014d4d07f1eSToby Isaac link->ctx = ctx; 2015d4d07f1eSToby Isaac link->next = NULL; 2016d4d07f1eSToby Isaac *p = link; 2017d4d07f1eSToby Isaac PetscFunctionReturn(0); 2018d4d07f1eSToby Isaac } 2019d4d07f1eSToby Isaac 20204c274da1SToby Isaac static PetscErrorCode DMLocalToGlobalHook_Constraints(DM dm, Vec l, InsertMode mode, Vec g, void *ctx) 20214c274da1SToby Isaac { 20224c274da1SToby Isaac Mat cMat; 20234c274da1SToby Isaac Vec cVec; 20244c274da1SToby Isaac PetscSection section, cSec; 20254c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 20264c274da1SToby Isaac PetscErrorCode ierr; 20274c274da1SToby Isaac 20284c274da1SToby Isaac PetscFunctionBegin; 20294c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 20304c274da1SToby Isaac ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr); 20314c274da1SToby Isaac if (cMat && (mode == ADD_VALUES || mode == ADD_ALL_VALUES || mode == ADD_BC_VALUES)) { 20325db9a05bSToby Isaac PetscInt nRows; 20335db9a05bSToby Isaac 20345db9a05bSToby Isaac ierr = MatGetSize(cMat,&nRows,NULL);CHKERRQ(ierr); 20355db9a05bSToby Isaac if (nRows <= 0) PetscFunctionReturn(0); 20364c274da1SToby Isaac ierr = DMGetDefaultSection(dm,§ion);CHKERRQ(ierr); 20377711e48fSToby Isaac ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr); 20384c274da1SToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 20394c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 20404c274da1SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 20414c274da1SToby Isaac if (dof) { 20424c274da1SToby Isaac PetscInt d; 20434c274da1SToby Isaac PetscScalar *vals; 20444c274da1SToby Isaac ierr = VecGetValuesSection(l,section,p,&vals);CHKERRQ(ierr); 20454c274da1SToby Isaac ierr = VecSetValuesSection(cVec,cSec,p,vals,mode);CHKERRQ(ierr); 20464c274da1SToby Isaac /* for this to be the true transpose, we have to zero the values that 20474c274da1SToby Isaac * we just extracted */ 20484c274da1SToby Isaac for (d = 0; d < dof; d++) { 20494c274da1SToby Isaac vals[d] = 0.; 20504c274da1SToby Isaac } 20514c274da1SToby Isaac } 20524c274da1SToby Isaac } 20534c274da1SToby Isaac ierr = MatMultTransposeAdd(cMat,cVec,l,l);CHKERRQ(ierr); 20544c274da1SToby Isaac ierr = VecDestroy(&cVec);CHKERRQ(ierr); 20554c274da1SToby Isaac } 20564c274da1SToby Isaac PetscFunctionReturn(0); 20574c274da1SToby Isaac } 20584c274da1SToby Isaac 205947c6ae99SBarry Smith /*@ 20609a42bb27SBarry Smith DMLocalToGlobalBegin - updates global vectors from local vectors 20619a42bb27SBarry Smith 20629a42bb27SBarry Smith Neighbor-wise Collective on DM 20639a42bb27SBarry Smith 20649a42bb27SBarry Smith Input Parameters: 20659a42bb27SBarry Smith + dm - the DM object 2066f6813fd5SJed Brown . l - the local vector 20671eb28f2eSBarry Smith . 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 base point. 20681eb28f2eSBarry Smith - g - the global vector 20699a42bb27SBarry Smith 2070d96308ebSBarry Smith Notes: In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation. 207184330215SMatthew G. Knepley INSERT_VALUES is not supported for DMDA, in that case simply compute the values directly into a global vector instead of a local one. 20729a42bb27SBarry Smith 20739a42bb27SBarry Smith Level: beginner 20749a42bb27SBarry Smith 2075e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin() 20769a42bb27SBarry Smith 20779a42bb27SBarry Smith @*/ 20787087cfbeSBarry Smith PetscErrorCode DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g) 20799a42bb27SBarry Smith { 20807128ae9fSMatthew G Knepley PetscSF sf; 208184330215SMatthew G. Knepley PetscSection s, gs; 2082d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 2083ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 2084ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 208584330215SMatthew G. Knepley PetscBool isInsert; 208684330215SMatthew G. Knepley PetscErrorCode ierr; 20879a42bb27SBarry Smith 20889a42bb27SBarry Smith PetscFunctionBegin; 2089171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2090d4d07f1eSToby Isaac for (link=dm->ltoghook; link; link=link->next) { 2091d4d07f1eSToby Isaac if (link->beginhook) { 2092d4d07f1eSToby Isaac ierr = (*link->beginhook)(dm,l,mode,g,link->ctx);CHKERRQ(ierr); 2093d4d07f1eSToby Isaac } 2094d4d07f1eSToby Isaac } 20954c274da1SToby Isaac ierr = DMLocalToGlobalHook_Constraints(dm,l,mode,g,NULL);CHKERRQ(ierr); 20967128ae9fSMatthew G Knepley ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr); 209784330215SMatthew G. Knepley ierr = DMGetDefaultSection(dm, &s);CHKERRQ(ierr); 20987128ae9fSMatthew G Knepley switch (mode) { 20997128ae9fSMatthew G Knepley case INSERT_VALUES: 21007128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 2101304ab55fSMatthew G. Knepley case INSERT_BC_VALUES: 210284330215SMatthew G. Knepley isInsert = PETSC_TRUE; break; 21037128ae9fSMatthew G Knepley case ADD_VALUES: 21047128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 2105304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 210684330215SMatthew G. Knepley isInsert = PETSC_FALSE; break; 21077128ae9fSMatthew G Knepley default: 210882f516ccSBarry Smith SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 21097128ae9fSMatthew G Knepley } 211084330215SMatthew G. Knepley if (sf && !isInsert) { 2111ae5cfb4aSMatthew G. Knepley ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr); 21127128ae9fSMatthew G Knepley ierr = VecGetArray(g, &gArray);CHKERRQ(ierr); 2113a9b180a6SBarry Smith ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM);CHKERRQ(ierr); 2114ae5cfb4aSMatthew G. Knepley ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr); 211584330215SMatthew G. Knepley ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr); 211684330215SMatthew G. Knepley } else if (s && isInsert) { 211784330215SMatthew G. Knepley PetscInt gStart, pStart, pEnd, p; 211884330215SMatthew G. Knepley 211984330215SMatthew G. Knepley ierr = DMGetDefaultGlobalSection(dm, &gs);CHKERRQ(ierr); 212084330215SMatthew G. Knepley ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 212184330215SMatthew G. Knepley ierr = VecGetOwnershipRange(g, &gStart, NULL);CHKERRQ(ierr); 2122ae5cfb4aSMatthew G. Knepley ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr); 212384330215SMatthew G. Knepley ierr = VecGetArray(g, &gArray);CHKERRQ(ierr); 212484330215SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2125b3b16f48SMatthew G. Knepley PetscInt dof, gdof, cdof, gcdof, off, goff, d, e; 212684330215SMatthew G. Knepley 212784330215SMatthew G. Knepley ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 212803442857SMatthew G. Knepley ierr = PetscSectionGetDof(gs, p, &gdof);CHKERRQ(ierr); 212984330215SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 2130b3b16f48SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(gs, p, &gcdof);CHKERRQ(ierr); 213184330215SMatthew G. Knepley ierr = PetscSectionGetOffset(s, p, &off);CHKERRQ(ierr); 213284330215SMatthew G. Knepley ierr = PetscSectionGetOffset(gs, p, &goff);CHKERRQ(ierr); 2133b3b16f48SMatthew G. Knepley /* Ignore off-process data and points with no global data */ 213403442857SMatthew G. Knepley if (!gdof || goff < 0) continue; 2135b3b16f48SMatthew G. Knepley if (dof != gdof) SETERRQ5(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Inconsistent sizes, p: %d dof: %d gdof: %d cdof: %d gcdof: %d", p, dof, gdof, cdof, gcdof); 2136b3b16f48SMatthew G. Knepley /* If no constraints are enforced in the global vector */ 2137b3b16f48SMatthew G. Knepley if (!gcdof) { 213884330215SMatthew G. Knepley for (d = 0; d < dof; ++d) gArray[goff-gStart+d] = lArray[off+d]; 2139b3b16f48SMatthew G. Knepley /* If constraints are enforced in the global vector */ 2140b3b16f48SMatthew G. Knepley } else if (cdof == gcdof) { 214184330215SMatthew G. Knepley const PetscInt *cdofs; 214284330215SMatthew G. Knepley PetscInt cind = 0; 214384330215SMatthew G. Knepley 214484330215SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(s, p, &cdofs);CHKERRQ(ierr); 2145b3b16f48SMatthew G. Knepley for (d = 0, e = 0; d < dof; ++d) { 214684330215SMatthew G. Knepley if ((cind < cdof) && (d == cdofs[cind])) {++cind; continue;} 2147b3b16f48SMatthew G. Knepley gArray[goff-gStart+e++] = lArray[off+d]; 214884330215SMatthew G. Knepley } 2149b3b16f48SMatthew G. Knepley } else SETERRQ5(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Inconsistent sizes, p: %d dof: %d gdof: %d cdof: %d gcdof: %d", p, dof, gdof, cdof, gcdof); 215084330215SMatthew G. Knepley } 2151ae5cfb4aSMatthew G. Knepley ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr); 21527128ae9fSMatthew G Knepley ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr); 21537128ae9fSMatthew G Knepley } else { 2154843c4018SMatthew G Knepley ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr); 21557128ae9fSMatthew G Knepley } 21569a42bb27SBarry Smith PetscFunctionReturn(0); 21579a42bb27SBarry Smith } 21589a42bb27SBarry Smith 21599a42bb27SBarry Smith /*@ 21609a42bb27SBarry Smith DMLocalToGlobalEnd - updates global vectors from local vectors 216147c6ae99SBarry Smith 216247c6ae99SBarry Smith Neighbor-wise Collective on DM 216347c6ae99SBarry Smith 216447c6ae99SBarry Smith Input Parameters: 216547c6ae99SBarry Smith + dm - the DM object 2166f6813fd5SJed Brown . l - the local vector 216747c6ae99SBarry Smith . mode - INSERT_VALUES or ADD_VALUES 2168f6813fd5SJed Brown - g - the global vector 216947c6ae99SBarry Smith 217047c6ae99SBarry Smith 217147c6ae99SBarry Smith Level: beginner 217247c6ae99SBarry Smith 2173e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd() 217447c6ae99SBarry Smith 217547c6ae99SBarry Smith @*/ 21767087cfbeSBarry Smith PetscErrorCode DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g) 217747c6ae99SBarry Smith { 21787128ae9fSMatthew G Knepley PetscSF sf; 217984330215SMatthew G. Knepley PetscSection s; 2180d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 218184330215SMatthew G. Knepley PetscBool isInsert; 218284330215SMatthew G. Knepley PetscErrorCode ierr; 218347c6ae99SBarry Smith 218447c6ae99SBarry Smith PetscFunctionBegin; 2185171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 21867128ae9fSMatthew G Knepley ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr); 218784330215SMatthew G. Knepley ierr = DMGetDefaultSection(dm, &s);CHKERRQ(ierr); 21887128ae9fSMatthew G Knepley switch (mode) { 21897128ae9fSMatthew G Knepley case INSERT_VALUES: 21907128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 219184330215SMatthew G. Knepley isInsert = PETSC_TRUE; break; 21927128ae9fSMatthew G Knepley case ADD_VALUES: 21937128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 219484330215SMatthew G. Knepley isInsert = PETSC_FALSE; break; 21957128ae9fSMatthew G Knepley default: 219682f516ccSBarry Smith SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 21977128ae9fSMatthew G Knepley } 219884330215SMatthew G. Knepley if (sf && !isInsert) { 2199ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 2200ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 220184330215SMatthew G. Knepley 2202ae5cfb4aSMatthew G. Knepley ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr); 22037128ae9fSMatthew G Knepley ierr = VecGetArray(g, &gArray);CHKERRQ(ierr); 2204a9b180a6SBarry Smith ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM);CHKERRQ(ierr); 2205ae5cfb4aSMatthew G. Knepley ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr); 22067128ae9fSMatthew G Knepley ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr); 220784330215SMatthew G. Knepley } else if (s && isInsert) { 22087128ae9fSMatthew G Knepley } else { 2209843c4018SMatthew G Knepley ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr); 22107128ae9fSMatthew G Knepley } 2211d4d07f1eSToby Isaac for (link=dm->ltoghook; link; link=link->next) { 2212d4d07f1eSToby Isaac if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);} 2213d4d07f1eSToby Isaac } 221447c6ae99SBarry Smith PetscFunctionReturn(0); 221547c6ae99SBarry Smith } 221647c6ae99SBarry Smith 2217f089877aSRichard Tran Mills /*@ 2218bc0a1609SRichard Tran Mills DMLocalToLocalBegin - Maps from a local vector (including ghost points 2219bc0a1609SRichard Tran Mills that contain irrelevant values) to another local vector where the ghost 2220d78e899eSRichard Tran Mills points in the second are set correctly. Must be followed by DMLocalToLocalEnd(). 2221f089877aSRichard Tran Mills 2222bc0a1609SRichard Tran Mills Neighbor-wise Collective on DM and Vec 2223f089877aSRichard Tran Mills 2224f089877aSRichard Tran Mills Input Parameters: 2225f089877aSRichard Tran Mills + dm - the DM object 2226bc0a1609SRichard Tran Mills . g - the original local vector 2227bc0a1609SRichard Tran Mills - mode - one of INSERT_VALUES or ADD_VALUES 2228f089877aSRichard Tran Mills 2229bc0a1609SRichard Tran Mills Output Parameter: 2230bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 2231f089877aSRichard Tran Mills 2232f089877aSRichard Tran Mills Level: intermediate 2233f089877aSRichard Tran Mills 2234bc0a1609SRichard Tran Mills Notes: 2235bc0a1609SRichard Tran Mills The local vectors used here need not be the same as those 2236bc0a1609SRichard Tran Mills obtained from DMCreateLocalVector(), BUT they 2237bc0a1609SRichard Tran Mills must have the same parallel data layout; they could, for example, be 2238bc0a1609SRichard Tran Mills obtained with VecDuplicate() from the DM originating vectors. 2239bc0a1609SRichard Tran Mills 2240bc0a1609SRichard Tran Mills .keywords: DM, local-to-local, begin 2241bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalEnd(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 2242f089877aSRichard Tran Mills 2243f089877aSRichard Tran Mills @*/ 2244f089877aSRichard Tran Mills PetscErrorCode DMLocalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l) 2245f089877aSRichard Tran Mills { 2246f089877aSRichard Tran Mills PetscErrorCode ierr; 2247f089877aSRichard Tran Mills 2248f089877aSRichard Tran Mills PetscFunctionBegin; 2249f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2250f089877aSRichard Tran Mills ierr = (*dm->ops->localtolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 2251f089877aSRichard Tran Mills PetscFunctionReturn(0); 2252f089877aSRichard Tran Mills } 2253f089877aSRichard Tran Mills 2254f089877aSRichard Tran Mills /*@ 2255bc0a1609SRichard Tran Mills DMLocalToLocalEnd - Maps from a local vector (including ghost points 2256bc0a1609SRichard Tran Mills that contain irrelevant values) to another local vector where the ghost 2257d78e899eSRichard Tran Mills points in the second are set correctly. Must be preceded by DMLocalToLocalBegin(). 2258f089877aSRichard Tran Mills 2259bc0a1609SRichard Tran Mills Neighbor-wise Collective on DM and Vec 2260f089877aSRichard Tran Mills 2261f089877aSRichard Tran Mills Input Parameters: 2262bc0a1609SRichard Tran Mills + da - the DM object 2263bc0a1609SRichard Tran Mills . g - the original local vector 2264bc0a1609SRichard Tran Mills - mode - one of INSERT_VALUES or ADD_VALUES 2265f089877aSRichard Tran Mills 2266bc0a1609SRichard Tran Mills Output Parameter: 2267bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 2268f089877aSRichard Tran Mills 2269f089877aSRichard Tran Mills Level: intermediate 2270f089877aSRichard Tran Mills 2271bc0a1609SRichard Tran Mills Notes: 2272bc0a1609SRichard Tran Mills The local vectors used here need not be the same as those 2273bc0a1609SRichard Tran Mills obtained from DMCreateLocalVector(), BUT they 2274bc0a1609SRichard Tran Mills must have the same parallel data layout; they could, for example, be 2275bc0a1609SRichard Tran Mills obtained with VecDuplicate() from the DM originating vectors. 2276bc0a1609SRichard Tran Mills 2277bc0a1609SRichard Tran Mills .keywords: DM, local-to-local, end 2278bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalBegin(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 2279f089877aSRichard Tran Mills 2280f089877aSRichard Tran Mills @*/ 2281f089877aSRichard Tran Mills PetscErrorCode DMLocalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l) 2282f089877aSRichard Tran Mills { 2283f089877aSRichard Tran Mills PetscErrorCode ierr; 2284f089877aSRichard Tran Mills 2285f089877aSRichard Tran Mills PetscFunctionBegin; 2286f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2287f089877aSRichard Tran Mills ierr = (*dm->ops->localtolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 2288f089877aSRichard Tran Mills PetscFunctionReturn(0); 2289f089877aSRichard Tran Mills } 2290f089877aSRichard Tran Mills 2291f089877aSRichard Tran Mills 229247c6ae99SBarry Smith /*@ 229347c6ae99SBarry Smith DMCoarsen - Coarsens a DM object 229447c6ae99SBarry Smith 229547c6ae99SBarry Smith Collective on DM 229647c6ae99SBarry Smith 229747c6ae99SBarry Smith Input Parameter: 229847c6ae99SBarry Smith + dm - the DM object 229991d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL) 230047c6ae99SBarry Smith 230147c6ae99SBarry Smith Output Parameter: 230247c6ae99SBarry Smith . dmc - the coarsened DM 230347c6ae99SBarry Smith 230447c6ae99SBarry Smith Level: developer 230547c6ae99SBarry Smith 2306e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 230747c6ae99SBarry Smith 230847c6ae99SBarry Smith @*/ 23097087cfbeSBarry Smith PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc) 231047c6ae99SBarry Smith { 231147c6ae99SBarry Smith PetscErrorCode ierr; 2312b17ce1afSJed Brown DMCoarsenHookLink link; 231347c6ae99SBarry Smith 231447c6ae99SBarry Smith PetscFunctionBegin; 2315171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2316fef3a512SBarry Smith if (!dm->ops->coarsen) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM cannot coarsen"); 231747a35634SPatrick Farrell ierr = PetscLogEventBegin(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr); 231847c6ae99SBarry Smith ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr); 23198892b4c3SMatthew G. Knepley if (!(*dmc)) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "NULL coarse mesh produced"); 2320a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dm,*dmc);CHKERRQ(ierr); 232143842a1eSJed Brown (*dmc)->ops->creatematrix = dm->ops->creatematrix; 23228cd211a4SJed Brown ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr); 2323644e2e5bSBarry Smith (*dmc)->ctx = dm->ctx; 23240598a293SJed Brown (*dmc)->levelup = dm->levelup; 2325656b349aSBarry Smith (*dmc)->leveldown = dm->leveldown + 1; 2326e4b4b23bSJed Brown ierr = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr); 2327b17ce1afSJed Brown for (link=dm->coarsenhook; link; link=link->next) { 2328b17ce1afSJed Brown if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);} 2329b17ce1afSJed Brown } 233047a35634SPatrick Farrell ierr = PetscLogEventEnd(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr); 2331b17ce1afSJed Brown PetscFunctionReturn(0); 2332b17ce1afSJed Brown } 2333b17ce1afSJed Brown 2334bb9467b5SJed Brown /*@C 2335b17ce1afSJed Brown DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid 2336b17ce1afSJed Brown 2337b17ce1afSJed Brown Logically Collective 2338b17ce1afSJed Brown 2339b17ce1afSJed Brown Input Arguments: 2340b17ce1afSJed Brown + fine - nonlinear solver context on which to run a hook when restricting to a coarser level 2341b17ce1afSJed Brown . coarsenhook - function to run when setting up a coarser level 2342b17ce1afSJed Brown . restricthook - function to run to update data on coarser levels (once per SNESSolve()) 23430298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2344b17ce1afSJed Brown 2345b17ce1afSJed Brown Calling sequence of coarsenhook: 2346b17ce1afSJed Brown $ coarsenhook(DM fine,DM coarse,void *ctx); 2347b17ce1afSJed Brown 2348b17ce1afSJed Brown + fine - fine level DM 2349b17ce1afSJed Brown . coarse - coarse level DM to restrict problem to 2350b17ce1afSJed Brown - ctx - optional user-defined function context 2351b17ce1afSJed Brown 2352b17ce1afSJed Brown Calling sequence for restricthook: 2353c833c3b5SJed Brown $ restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx) 2354b17ce1afSJed Brown 2355b17ce1afSJed Brown + fine - fine level DM 2356b17ce1afSJed Brown . mrestrict - matrix restricting a fine-level solution to the coarse grid 2357c833c3b5SJed Brown . rscale - scaling vector for restriction 2358c833c3b5SJed Brown . inject - matrix restricting by injection 2359b17ce1afSJed Brown . coarse - coarse level DM to update 2360b17ce1afSJed Brown - ctx - optional user-defined function context 2361b17ce1afSJed Brown 2362b17ce1afSJed Brown Level: advanced 2363b17ce1afSJed Brown 2364b17ce1afSJed Brown Notes: 2365b17ce1afSJed Brown This function is only needed if auxiliary data needs to be set up on coarse grids. 2366b17ce1afSJed Brown 2367b17ce1afSJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 2368b17ce1afSJed Brown 2369b17ce1afSJed Brown In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 2370b17ce1afSJed Brown extract the finest level information from its context (instead of from the SNES). 2371b17ce1afSJed Brown 2372bb9467b5SJed Brown This function is currently not available from Fortran. 2373bb9467b5SJed Brown 2374c833c3b5SJed Brown .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 2375b17ce1afSJed Brown @*/ 2376b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx) 2377b17ce1afSJed Brown { 2378b17ce1afSJed Brown PetscErrorCode ierr; 2379b17ce1afSJed Brown DMCoarsenHookLink link,*p; 2380b17ce1afSJed Brown 2381b17ce1afSJed Brown PetscFunctionBegin; 2382b17ce1afSJed Brown PetscValidHeaderSpecific(fine,DM_CLASSID,1); 23836bfea28cSJed Brown for (p=&fine->coarsenhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 238495dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 2385b17ce1afSJed Brown link->coarsenhook = coarsenhook; 2386b17ce1afSJed Brown link->restricthook = restricthook; 2387b17ce1afSJed Brown link->ctx = ctx; 23880298fd71SBarry Smith link->next = NULL; 2389b17ce1afSJed Brown *p = link; 2390b17ce1afSJed Brown PetscFunctionReturn(0); 2391b17ce1afSJed Brown } 2392b17ce1afSJed Brown 2393b17ce1afSJed Brown /*@ 2394b17ce1afSJed Brown DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd() 2395b17ce1afSJed Brown 2396b17ce1afSJed Brown Collective if any hooks are 2397b17ce1afSJed Brown 2398b17ce1afSJed Brown Input Arguments: 2399b17ce1afSJed Brown + fine - finer DM to use as a base 2400b17ce1afSJed Brown . restrct - restriction matrix, apply using MatRestrict() 2401b17ce1afSJed Brown . inject - injection matrix, also use MatRestrict() 2402b17ce1afSJed Brown - coarse - coarer DM to update 2403b17ce1afSJed Brown 2404b17ce1afSJed Brown Level: developer 2405b17ce1afSJed Brown 2406b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict() 2407b17ce1afSJed Brown @*/ 2408b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse) 2409b17ce1afSJed Brown { 2410b17ce1afSJed Brown PetscErrorCode ierr; 2411b17ce1afSJed Brown DMCoarsenHookLink link; 2412b17ce1afSJed Brown 2413b17ce1afSJed Brown PetscFunctionBegin; 2414b17ce1afSJed Brown for (link=fine->coarsenhook; link; link=link->next) { 24158865f1eaSKarl Rupp if (link->restricthook) { 24168865f1eaSKarl Rupp ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr); 24178865f1eaSKarl Rupp } 2418b17ce1afSJed Brown } 241947c6ae99SBarry Smith PetscFunctionReturn(0); 242047c6ae99SBarry Smith } 242147c6ae99SBarry Smith 2422bb9467b5SJed Brown /*@C 2423be081cd6SPeter Brune DMSubDomainHookAdd - adds a callback to be run when restricting a problem to the coarse grid 24245dbd56e3SPeter Brune 24255dbd56e3SPeter Brune Logically Collective 24265dbd56e3SPeter Brune 24275dbd56e3SPeter Brune Input Arguments: 24285dbd56e3SPeter Brune + global - global DM 2429ec4806b8SPeter Brune . ddhook - function to run to pass data to the decomposition DM upon its creation 24305dbd56e3SPeter Brune . restricthook - function to run to update data on block solve (at the beginning of the block solve) 24310298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 24325dbd56e3SPeter Brune 2433ec4806b8SPeter Brune 2434ec4806b8SPeter Brune Calling sequence for ddhook: 2435ec4806b8SPeter Brune $ ddhook(DM global,DM block,void *ctx) 2436ec4806b8SPeter Brune 2437ec4806b8SPeter Brune + global - global DM 2438ec4806b8SPeter Brune . block - block DM 2439ec4806b8SPeter Brune - ctx - optional user-defined function context 2440ec4806b8SPeter Brune 24415dbd56e3SPeter Brune Calling sequence for restricthook: 2442ec4806b8SPeter Brune $ restricthook(DM global,VecScatter out,VecScatter in,DM block,void *ctx) 24435dbd56e3SPeter Brune 24445dbd56e3SPeter Brune + global - global DM 24455dbd56e3SPeter Brune . out - scatter to the outer (with ghost and overlap points) block vector 24465dbd56e3SPeter Brune . in - scatter to block vector values only owned locally 2447ec4806b8SPeter Brune . block - block DM 24485dbd56e3SPeter Brune - ctx - optional user-defined function context 24495dbd56e3SPeter Brune 24505dbd56e3SPeter Brune Level: advanced 24515dbd56e3SPeter Brune 24525dbd56e3SPeter Brune Notes: 2453ec4806b8SPeter Brune This function is only needed if auxiliary data needs to be set up on subdomain DMs. 24545dbd56e3SPeter Brune 24555dbd56e3SPeter Brune If this function is called multiple times, the hooks will be run in the order they are added. 24565dbd56e3SPeter Brune 24575dbd56e3SPeter Brune In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 2458ec4806b8SPeter Brune extract the global information from its context (instead of from the SNES). 24595dbd56e3SPeter Brune 2460bb9467b5SJed Brown This function is currently not available from Fortran. 2461bb9467b5SJed Brown 24625dbd56e3SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 24635dbd56e3SPeter Brune @*/ 2464be081cd6SPeter Brune PetscErrorCode DMSubDomainHookAdd(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx) 24655dbd56e3SPeter Brune { 24665dbd56e3SPeter Brune PetscErrorCode ierr; 2467be081cd6SPeter Brune DMSubDomainHookLink link,*p; 24685dbd56e3SPeter Brune 24695dbd56e3SPeter Brune PetscFunctionBegin; 24705dbd56e3SPeter Brune PetscValidHeaderSpecific(global,DM_CLASSID,1); 2471be081cd6SPeter Brune for (p=&global->subdomainhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 247295dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 24735dbd56e3SPeter Brune link->restricthook = restricthook; 2474be081cd6SPeter Brune link->ddhook = ddhook; 24755dbd56e3SPeter Brune link->ctx = ctx; 24760298fd71SBarry Smith link->next = NULL; 24775dbd56e3SPeter Brune *p = link; 24785dbd56e3SPeter Brune PetscFunctionReturn(0); 24795dbd56e3SPeter Brune } 24805dbd56e3SPeter Brune 24815dbd56e3SPeter Brune /*@ 2482be081cd6SPeter Brune DMSubDomainRestrict - restricts user-defined problem data to a block DM by running hooks registered by DMSubDomainHookAdd() 24835dbd56e3SPeter Brune 24845dbd56e3SPeter Brune Collective if any hooks are 24855dbd56e3SPeter Brune 24865dbd56e3SPeter Brune Input Arguments: 24875dbd56e3SPeter Brune + fine - finer DM to use as a base 2488be081cd6SPeter Brune . oscatter - scatter from domain global vector filling subdomain global vector with overlap 2489be081cd6SPeter Brune . gscatter - scatter from domain global vector filling subdomain local vector with ghosts 24905dbd56e3SPeter Brune - coarse - coarer DM to update 24915dbd56e3SPeter Brune 24925dbd56e3SPeter Brune Level: developer 24935dbd56e3SPeter Brune 24945dbd56e3SPeter Brune .seealso: DMCoarsenHookAdd(), MatRestrict() 24955dbd56e3SPeter Brune @*/ 2496be081cd6SPeter Brune PetscErrorCode DMSubDomainRestrict(DM global,VecScatter oscatter,VecScatter gscatter,DM subdm) 24975dbd56e3SPeter Brune { 24985dbd56e3SPeter Brune PetscErrorCode ierr; 2499be081cd6SPeter Brune DMSubDomainHookLink link; 25005dbd56e3SPeter Brune 25015dbd56e3SPeter Brune PetscFunctionBegin; 2502be081cd6SPeter Brune for (link=global->subdomainhook; link; link=link->next) { 25038865f1eaSKarl Rupp if (link->restricthook) { 25048865f1eaSKarl Rupp ierr = (*link->restricthook)(global,oscatter,gscatter,subdm,link->ctx);CHKERRQ(ierr); 25058865f1eaSKarl Rupp } 25065dbd56e3SPeter Brune } 25075dbd56e3SPeter Brune PetscFunctionReturn(0); 25085dbd56e3SPeter Brune } 25095dbd56e3SPeter Brune 25105fe1f584SPeter Brune /*@ 25116a7d9d85SPeter Brune DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM. 25125fe1f584SPeter Brune 25135fe1f584SPeter Brune Not Collective 25145fe1f584SPeter Brune 25155fe1f584SPeter Brune Input Parameter: 25165fe1f584SPeter Brune . dm - the DM object 25175fe1f584SPeter Brune 25185fe1f584SPeter Brune Output Parameter: 25196a7d9d85SPeter Brune . level - number of coarsenings 25205fe1f584SPeter Brune 25215fe1f584SPeter Brune Level: developer 25225fe1f584SPeter Brune 25236a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 25245fe1f584SPeter Brune 25255fe1f584SPeter Brune @*/ 25265fe1f584SPeter Brune PetscErrorCode DMGetCoarsenLevel(DM dm,PetscInt *level) 25275fe1f584SPeter Brune { 25285fe1f584SPeter Brune PetscFunctionBegin; 25295fe1f584SPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 25305fe1f584SPeter Brune *level = dm->leveldown; 25315fe1f584SPeter Brune PetscFunctionReturn(0); 25325fe1f584SPeter Brune } 25335fe1f584SPeter Brune 25345fe1f584SPeter Brune 25355fe1f584SPeter Brune 253647c6ae99SBarry Smith /*@C 253747c6ae99SBarry Smith DMRefineHierarchy - Refines a DM object, all levels at once 253847c6ae99SBarry Smith 253947c6ae99SBarry Smith Collective on DM 254047c6ae99SBarry Smith 254147c6ae99SBarry Smith Input Parameter: 254247c6ae99SBarry Smith + dm - the DM object 254347c6ae99SBarry Smith - nlevels - the number of levels of refinement 254447c6ae99SBarry Smith 254547c6ae99SBarry Smith Output Parameter: 254647c6ae99SBarry Smith . dmf - the refined DM hierarchy 254747c6ae99SBarry Smith 254847c6ae99SBarry Smith Level: developer 254947c6ae99SBarry Smith 2550e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 255147c6ae99SBarry Smith 255247c6ae99SBarry Smith @*/ 25537087cfbeSBarry Smith PetscErrorCode DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[]) 255447c6ae99SBarry Smith { 255547c6ae99SBarry Smith PetscErrorCode ierr; 255647c6ae99SBarry Smith 255747c6ae99SBarry Smith PetscFunctionBegin; 2558171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2559ce94432eSBarry Smith if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 256047c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 256147c6ae99SBarry Smith if (dm->ops->refinehierarchy) { 256247c6ae99SBarry Smith ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr); 256347c6ae99SBarry Smith } else if (dm->ops->refine) { 256447c6ae99SBarry Smith PetscInt i; 256547c6ae99SBarry Smith 2566ce94432eSBarry Smith ierr = DMRefine(dm,PetscObjectComm((PetscObject)dm),&dmf[0]);CHKERRQ(ierr); 256747c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 2568ce94432eSBarry Smith ierr = DMRefine(dmf[i-1],PetscObjectComm((PetscObject)dm),&dmf[i]);CHKERRQ(ierr); 256947c6ae99SBarry Smith } 2570ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No RefineHierarchy for this DM yet"); 257147c6ae99SBarry Smith PetscFunctionReturn(0); 257247c6ae99SBarry Smith } 257347c6ae99SBarry Smith 257447c6ae99SBarry Smith /*@C 257547c6ae99SBarry Smith DMCoarsenHierarchy - Coarsens a DM object, all levels at once 257647c6ae99SBarry Smith 257747c6ae99SBarry Smith Collective on DM 257847c6ae99SBarry Smith 257947c6ae99SBarry Smith Input Parameter: 258047c6ae99SBarry Smith + dm - the DM object 258147c6ae99SBarry Smith - nlevels - the number of levels of coarsening 258247c6ae99SBarry Smith 258347c6ae99SBarry Smith Output Parameter: 258447c6ae99SBarry Smith . dmc - the coarsened DM hierarchy 258547c6ae99SBarry Smith 258647c6ae99SBarry Smith Level: developer 258747c6ae99SBarry Smith 2588e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 258947c6ae99SBarry Smith 259047c6ae99SBarry Smith @*/ 25917087cfbeSBarry Smith PetscErrorCode DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[]) 259247c6ae99SBarry Smith { 259347c6ae99SBarry Smith PetscErrorCode ierr; 259447c6ae99SBarry Smith 259547c6ae99SBarry Smith PetscFunctionBegin; 2596171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2597ce94432eSBarry Smith if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 259847c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 259947c6ae99SBarry Smith PetscValidPointer(dmc,3); 260047c6ae99SBarry Smith if (dm->ops->coarsenhierarchy) { 260147c6ae99SBarry Smith ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr); 260247c6ae99SBarry Smith } else if (dm->ops->coarsen) { 260347c6ae99SBarry Smith PetscInt i; 260447c6ae99SBarry Smith 2605ce94432eSBarry Smith ierr = DMCoarsen(dm,PetscObjectComm((PetscObject)dm),&dmc[0]);CHKERRQ(ierr); 260647c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 2607ce94432eSBarry Smith ierr = DMCoarsen(dmc[i-1],PetscObjectComm((PetscObject)dm),&dmc[i]);CHKERRQ(ierr); 260847c6ae99SBarry Smith } 2609ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet"); 261047c6ae99SBarry Smith PetscFunctionReturn(0); 261147c6ae99SBarry Smith } 261247c6ae99SBarry Smith 261347c6ae99SBarry Smith /*@ 2614e727c939SJed Brown DMCreateAggregates - Gets the aggregates that map between 261547c6ae99SBarry Smith grids associated with two DMs. 261647c6ae99SBarry Smith 261747c6ae99SBarry Smith Collective on DM 261847c6ae99SBarry Smith 261947c6ae99SBarry Smith Input Parameters: 262047c6ae99SBarry Smith + dmc - the coarse grid DM 262147c6ae99SBarry Smith - dmf - the fine grid DM 262247c6ae99SBarry Smith 262347c6ae99SBarry Smith Output Parameters: 262447c6ae99SBarry Smith . rest - the restriction matrix (transpose of the projection matrix) 262547c6ae99SBarry Smith 262647c6ae99SBarry Smith Level: intermediate 262747c6ae99SBarry Smith 262847c6ae99SBarry Smith .keywords: interpolation, restriction, multigrid 262947c6ae99SBarry Smith 2630e727c939SJed Brown .seealso: DMRefine(), DMCreateInjection(), DMCreateInterpolation() 263147c6ae99SBarry Smith @*/ 2632e727c939SJed Brown PetscErrorCode DMCreateAggregates(DM dmc, DM dmf, Mat *rest) 263347c6ae99SBarry Smith { 263447c6ae99SBarry Smith PetscErrorCode ierr; 263547c6ae99SBarry Smith 263647c6ae99SBarry Smith PetscFunctionBegin; 2637171400e9SBarry Smith PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 2638171400e9SBarry Smith PetscValidHeaderSpecific(dmf,DM_CLASSID,2); 263947c6ae99SBarry Smith ierr = (*dmc->ops->getaggregates)(dmc, dmf, rest);CHKERRQ(ierr); 264047c6ae99SBarry Smith PetscFunctionReturn(0); 264147c6ae99SBarry Smith } 264247c6ae99SBarry Smith 26431a266240SBarry Smith /*@C 26441a266240SBarry Smith DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed 26451a266240SBarry Smith 26461a266240SBarry Smith Not Collective 26471a266240SBarry Smith 26481a266240SBarry Smith Input Parameters: 26491a266240SBarry Smith + dm - the DM object 26501a266240SBarry Smith - destroy - the destroy function 26511a266240SBarry Smith 26521a266240SBarry Smith Level: intermediate 26531a266240SBarry Smith 2654e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 26551a266240SBarry Smith 2656f07f9ceaSJed Brown @*/ 26571a266240SBarry Smith PetscErrorCode DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**)) 26581a266240SBarry Smith { 26591a266240SBarry Smith PetscFunctionBegin; 2660171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 26611a266240SBarry Smith dm->ctxdestroy = destroy; 26621a266240SBarry Smith PetscFunctionReturn(0); 26631a266240SBarry Smith } 26641a266240SBarry Smith 2665b07ff414SBarry Smith /*@ 26661b2093e4SBarry Smith DMSetApplicationContext - Set a user context into a DM object 266747c6ae99SBarry Smith 266847c6ae99SBarry Smith Not Collective 266947c6ae99SBarry Smith 267047c6ae99SBarry Smith Input Parameters: 267147c6ae99SBarry Smith + dm - the DM object 267247c6ae99SBarry Smith - ctx - the user context 267347c6ae99SBarry Smith 267447c6ae99SBarry Smith Level: intermediate 267547c6ae99SBarry Smith 2676e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 267747c6ae99SBarry Smith 267847c6ae99SBarry Smith @*/ 26791b2093e4SBarry Smith PetscErrorCode DMSetApplicationContext(DM dm,void *ctx) 268047c6ae99SBarry Smith { 268147c6ae99SBarry Smith PetscFunctionBegin; 2682171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 268347c6ae99SBarry Smith dm->ctx = ctx; 268447c6ae99SBarry Smith PetscFunctionReturn(0); 268547c6ae99SBarry Smith } 268647c6ae99SBarry Smith 268747c6ae99SBarry Smith /*@ 26881b2093e4SBarry Smith DMGetApplicationContext - Gets a user context from a DM object 268947c6ae99SBarry Smith 269047c6ae99SBarry Smith Not Collective 269147c6ae99SBarry Smith 269247c6ae99SBarry Smith Input Parameter: 269347c6ae99SBarry Smith . dm - the DM object 269447c6ae99SBarry Smith 269547c6ae99SBarry Smith Output Parameter: 269647c6ae99SBarry Smith . ctx - the user context 269747c6ae99SBarry Smith 269847c6ae99SBarry Smith Level: intermediate 269947c6ae99SBarry Smith 2700e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 270147c6ae99SBarry Smith 270247c6ae99SBarry Smith @*/ 27031b2093e4SBarry Smith PetscErrorCode DMGetApplicationContext(DM dm,void *ctx) 270447c6ae99SBarry Smith { 270547c6ae99SBarry Smith PetscFunctionBegin; 2706171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 27071b2093e4SBarry Smith *(void**)ctx = dm->ctx; 270847c6ae99SBarry Smith PetscFunctionReturn(0); 270947c6ae99SBarry Smith } 271047c6ae99SBarry Smith 271108da532bSDmitry Karpeev /*@C 2712df3898eeSBarry Smith DMSetVariableBounds - sets a function to compute the lower and upper bound vectors for SNESVI. 271308da532bSDmitry Karpeev 271408da532bSDmitry Karpeev Logically Collective on DM 271508da532bSDmitry Karpeev 271608da532bSDmitry Karpeev Input Parameter: 271708da532bSDmitry Karpeev + dm - the DM object 27180298fd71SBarry Smith - f - the function that computes variable bounds used by SNESVI (use NULL to cancel a previous function that was set) 271908da532bSDmitry Karpeev 272008da532bSDmitry Karpeev Level: intermediate 272108da532bSDmitry Karpeev 2722835c3ec7SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), 272308da532bSDmitry Karpeev DMSetJacobian() 272408da532bSDmitry Karpeev 272508da532bSDmitry Karpeev @*/ 272608da532bSDmitry Karpeev PetscErrorCode DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec)) 272708da532bSDmitry Karpeev { 272808da532bSDmitry Karpeev PetscFunctionBegin; 272908da532bSDmitry Karpeev dm->ops->computevariablebounds = f; 273008da532bSDmitry Karpeev PetscFunctionReturn(0); 273108da532bSDmitry Karpeev } 273208da532bSDmitry Karpeev 273308da532bSDmitry Karpeev /*@ 273408da532bSDmitry Karpeev DMHasVariableBounds - does the DM object have a variable bounds function? 273508da532bSDmitry Karpeev 273608da532bSDmitry Karpeev Not Collective 273708da532bSDmitry Karpeev 273808da532bSDmitry Karpeev Input Parameter: 273908da532bSDmitry Karpeev . dm - the DM object to destroy 274008da532bSDmitry Karpeev 274108da532bSDmitry Karpeev Output Parameter: 274208da532bSDmitry Karpeev . flg - PETSC_TRUE if the variable bounds function exists 274308da532bSDmitry Karpeev 274408da532bSDmitry Karpeev Level: developer 274508da532bSDmitry Karpeev 274674e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 274708da532bSDmitry Karpeev 274808da532bSDmitry Karpeev @*/ 274908da532bSDmitry Karpeev PetscErrorCode DMHasVariableBounds(DM dm,PetscBool *flg) 275008da532bSDmitry Karpeev { 275108da532bSDmitry Karpeev PetscFunctionBegin; 275208da532bSDmitry Karpeev *flg = (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE; 275308da532bSDmitry Karpeev PetscFunctionReturn(0); 275408da532bSDmitry Karpeev } 275508da532bSDmitry Karpeev 275608da532bSDmitry Karpeev /*@C 275708da532bSDmitry Karpeev DMComputeVariableBounds - compute variable bounds used by SNESVI. 275808da532bSDmitry Karpeev 275908da532bSDmitry Karpeev Logically Collective on DM 276008da532bSDmitry Karpeev 276108da532bSDmitry Karpeev Input Parameters: 2762907376e6SBarry Smith . dm - the DM object 276308da532bSDmitry Karpeev 276408da532bSDmitry Karpeev Output parameters: 276508da532bSDmitry Karpeev + xl - lower bound 276608da532bSDmitry Karpeev - xu - upper bound 276708da532bSDmitry Karpeev 2768907376e6SBarry Smith Level: advanced 2769907376e6SBarry Smith 2770907376e6SBarry Smith Notes: This is generally not called by users. It calls the function provided by the user with DMSetVariableBounds() 277108da532bSDmitry Karpeev 277274e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 277308da532bSDmitry Karpeev 277408da532bSDmitry Karpeev @*/ 277508da532bSDmitry Karpeev PetscErrorCode DMComputeVariableBounds(DM dm, Vec xl, Vec xu) 277608da532bSDmitry Karpeev { 277708da532bSDmitry Karpeev PetscErrorCode ierr; 27785fd66863SKarl Rupp 277908da532bSDmitry Karpeev PetscFunctionBegin; 278008da532bSDmitry Karpeev PetscValidHeaderSpecific(xl,VEC_CLASSID,2); 278108da532bSDmitry Karpeev PetscValidHeaderSpecific(xu,VEC_CLASSID,2); 278208da532bSDmitry Karpeev if (dm->ops->computevariablebounds) { 278308da532bSDmitry Karpeev ierr = (*dm->ops->computevariablebounds)(dm, xl,xu);CHKERRQ(ierr); 27848865f1eaSKarl Rupp } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "This DM is incapable of computing variable bounds."); 278508da532bSDmitry Karpeev PetscFunctionReturn(0); 278608da532bSDmitry Karpeev } 278708da532bSDmitry Karpeev 2788b0ae01b7SPeter Brune /*@ 2789b0ae01b7SPeter Brune DMHasColoring - does the DM object have a method of providing a coloring? 2790b0ae01b7SPeter Brune 2791b0ae01b7SPeter Brune Not Collective 2792b0ae01b7SPeter Brune 2793b0ae01b7SPeter Brune Input Parameter: 2794b0ae01b7SPeter Brune . dm - the DM object 2795b0ae01b7SPeter Brune 2796b0ae01b7SPeter Brune Output Parameter: 2797b0ae01b7SPeter Brune . flg - PETSC_TRUE if the DM has facilities for DMCreateColoring(). 2798b0ae01b7SPeter Brune 2799b0ae01b7SPeter Brune Level: developer 2800b0ae01b7SPeter Brune 2801b0ae01b7SPeter Brune .seealso DMHasFunction(), DMCreateColoring() 2802b0ae01b7SPeter Brune 2803b0ae01b7SPeter Brune @*/ 2804b0ae01b7SPeter Brune PetscErrorCode DMHasColoring(DM dm,PetscBool *flg) 2805b0ae01b7SPeter Brune { 2806b0ae01b7SPeter Brune PetscFunctionBegin; 2807b0ae01b7SPeter Brune *flg = (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE; 2808b0ae01b7SPeter Brune PetscFunctionReturn(0); 2809b0ae01b7SPeter Brune } 2810b0ae01b7SPeter Brune 28113ad4599aSBarry Smith /*@ 28123ad4599aSBarry Smith DMHasCreateRestriction - does the DM object have a method of providing a restriction? 28133ad4599aSBarry Smith 28143ad4599aSBarry Smith Not Collective 28153ad4599aSBarry Smith 28163ad4599aSBarry Smith Input Parameter: 28173ad4599aSBarry Smith . dm - the DM object 28183ad4599aSBarry Smith 28193ad4599aSBarry Smith Output Parameter: 28203ad4599aSBarry Smith . flg - PETSC_TRUE if the DM has facilities for DMCreateRestriction(). 28213ad4599aSBarry Smith 28223ad4599aSBarry Smith Level: developer 28233ad4599aSBarry Smith 28243ad4599aSBarry Smith .seealso DMHasFunction(), DMCreateRestriction() 28253ad4599aSBarry Smith 28263ad4599aSBarry Smith @*/ 28273ad4599aSBarry Smith PetscErrorCode DMHasCreateRestriction(DM dm,PetscBool *flg) 28283ad4599aSBarry Smith { 28293ad4599aSBarry Smith PetscFunctionBegin; 28303ad4599aSBarry Smith *flg = (dm->ops->createrestriction) ? PETSC_TRUE : PETSC_FALSE; 28313ad4599aSBarry Smith PetscFunctionReturn(0); 28323ad4599aSBarry Smith } 28333ad4599aSBarry Smith 2834748fac09SDmitry Karpeev /*@C 283508da532bSDmitry Karpeev DMSetVec - set the vector at which to compute residual, Jacobian and VI bounds, if the problem is nonlinear. 283608da532bSDmitry Karpeev 283708da532bSDmitry Karpeev Collective on DM 283808da532bSDmitry Karpeev 283908da532bSDmitry Karpeev Input Parameter: 284008da532bSDmitry Karpeev + dm - the DM object 28410298fd71SBarry Smith - x - location to compute residual and Jacobian, if NULL is passed to those routines; will be NULL for linear problems. 284208da532bSDmitry Karpeev 284308da532bSDmitry Karpeev Level: developer 284408da532bSDmitry Karpeev 284574e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 284608da532bSDmitry Karpeev 284708da532bSDmitry Karpeev @*/ 284808da532bSDmitry Karpeev PetscErrorCode DMSetVec(DM dm,Vec x) 284908da532bSDmitry Karpeev { 285008da532bSDmitry Karpeev PetscErrorCode ierr; 28515fd66863SKarl Rupp 285208da532bSDmitry Karpeev PetscFunctionBegin; 285308da532bSDmitry Karpeev if (x) { 285408da532bSDmitry Karpeev if (!dm->x) { 285508da532bSDmitry Karpeev ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr); 285608da532bSDmitry Karpeev } 285708da532bSDmitry Karpeev ierr = VecCopy(x,dm->x);CHKERRQ(ierr); 28588865f1eaSKarl Rupp } else if (dm->x) { 285908da532bSDmitry Karpeev ierr = VecDestroy(&dm->x);CHKERRQ(ierr); 286008da532bSDmitry Karpeev } 286108da532bSDmitry Karpeev PetscFunctionReturn(0); 286208da532bSDmitry Karpeev } 286308da532bSDmitry Karpeev 28640298fd71SBarry Smith PetscFunctionList DMList = NULL; 2865264ace61SBarry Smith PetscBool DMRegisterAllCalled = PETSC_FALSE; 2866264ace61SBarry Smith 2867264ace61SBarry Smith /*@C 2868264ace61SBarry Smith DMSetType - Builds a DM, for a particular DM implementation. 2869264ace61SBarry Smith 2870264ace61SBarry Smith Collective on DM 2871264ace61SBarry Smith 2872264ace61SBarry Smith Input Parameters: 2873264ace61SBarry Smith + dm - The DM object 2874264ace61SBarry Smith - method - The name of the DM type 2875264ace61SBarry Smith 2876264ace61SBarry Smith Options Database Key: 2877264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types 2878264ace61SBarry Smith 2879264ace61SBarry Smith Notes: 2880e1589f56SBarry Smith See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D). 2881264ace61SBarry Smith 2882264ace61SBarry Smith Level: intermediate 2883264ace61SBarry Smith 2884264ace61SBarry Smith .keywords: DM, set, type 2885264ace61SBarry Smith .seealso: DMGetType(), DMCreate() 2886264ace61SBarry Smith @*/ 288719fd82e9SBarry Smith PetscErrorCode DMSetType(DM dm, DMType method) 2888264ace61SBarry Smith { 2889264ace61SBarry Smith PetscErrorCode (*r)(DM); 2890264ace61SBarry Smith PetscBool match; 2891264ace61SBarry Smith PetscErrorCode ierr; 2892264ace61SBarry Smith 2893264ace61SBarry Smith PetscFunctionBegin; 2894264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID,1); 2895251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr); 2896264ace61SBarry Smith if (match) PetscFunctionReturn(0); 2897264ace61SBarry Smith 28980f51fdf8SToby Isaac ierr = DMRegisterAll();CHKERRQ(ierr); 28991c9cd337SJed Brown ierr = PetscFunctionListFind(DMList,method,&r);CHKERRQ(ierr); 2900ce94432eSBarry Smith if (!r) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method); 2901264ace61SBarry Smith 2902264ace61SBarry Smith if (dm->ops->destroy) { 2903264ace61SBarry Smith ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr); 29040298fd71SBarry Smith dm->ops->destroy = NULL; 2905264ace61SBarry Smith } 2906264ace61SBarry Smith ierr = (*r)(dm);CHKERRQ(ierr); 2907264ace61SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr); 2908264ace61SBarry Smith PetscFunctionReturn(0); 2909264ace61SBarry Smith } 2910264ace61SBarry Smith 2911264ace61SBarry Smith /*@C 2912264ace61SBarry Smith DMGetType - Gets the DM type name (as a string) from the DM. 2913264ace61SBarry Smith 2914264ace61SBarry Smith Not Collective 2915264ace61SBarry Smith 2916264ace61SBarry Smith Input Parameter: 2917264ace61SBarry Smith . dm - The DM 2918264ace61SBarry Smith 2919264ace61SBarry Smith Output Parameter: 2920264ace61SBarry Smith . type - The DM type name 2921264ace61SBarry Smith 2922264ace61SBarry Smith Level: intermediate 2923264ace61SBarry Smith 2924264ace61SBarry Smith .keywords: DM, get, type, name 2925264ace61SBarry Smith .seealso: DMSetType(), DMCreate() 2926264ace61SBarry Smith @*/ 292719fd82e9SBarry Smith PetscErrorCode DMGetType(DM dm, DMType *type) 2928264ace61SBarry Smith { 2929264ace61SBarry Smith PetscErrorCode ierr; 2930264ace61SBarry Smith 2931264ace61SBarry Smith PetscFunctionBegin; 2932264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID,1); 2933c959eef4SJed Brown PetscValidPointer(type,2); 2934607a6623SBarry Smith ierr = DMRegisterAll();CHKERRQ(ierr); 2935264ace61SBarry Smith *type = ((PetscObject)dm)->type_name; 2936264ace61SBarry Smith PetscFunctionReturn(0); 2937264ace61SBarry Smith } 2938264ace61SBarry Smith 293967a56275SMatthew G Knepley /*@C 294067a56275SMatthew G Knepley DMConvert - Converts a DM to another DM, either of the same or different type. 294167a56275SMatthew G Knepley 294267a56275SMatthew G Knepley Collective on DM 294367a56275SMatthew G Knepley 294467a56275SMatthew G Knepley Input Parameters: 294567a56275SMatthew G Knepley + dm - the DM 294667a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type) 294767a56275SMatthew G Knepley 294867a56275SMatthew G Knepley Output Parameter: 294967a56275SMatthew G Knepley . M - pointer to new DM 295067a56275SMatthew G Knepley 295167a56275SMatthew G Knepley Notes: 295267a56275SMatthew G Knepley Cannot be used to convert a sequential DM to parallel or parallel to sequential, 295367a56275SMatthew G Knepley the MPI communicator of the generated DM is always the same as the communicator 295467a56275SMatthew G Knepley of the input DM. 295567a56275SMatthew G Knepley 295667a56275SMatthew G Knepley Level: intermediate 295767a56275SMatthew G Knepley 295867a56275SMatthew G Knepley .seealso: DMCreate() 295967a56275SMatthew G Knepley @*/ 296019fd82e9SBarry Smith PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M) 296167a56275SMatthew G Knepley { 296267a56275SMatthew G Knepley DM B; 296367a56275SMatthew G Knepley char convname[256]; 2964c067b6caSMatthew G. Knepley PetscBool sametype/*, issame */; 296567a56275SMatthew G Knepley PetscErrorCode ierr; 296667a56275SMatthew G Knepley 296767a56275SMatthew G Knepley PetscFunctionBegin; 296867a56275SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 296967a56275SMatthew G Knepley PetscValidType(dm,1); 297067a56275SMatthew G Knepley PetscValidPointer(M,3); 2971251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr); 2972c067b6caSMatthew G. Knepley /* ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr); */ 2973c067b6caSMatthew G. Knepley if (sametype) { 2974c067b6caSMatthew G. Knepley *M = dm; 2975c067b6caSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr); 2976c067b6caSMatthew G. Knepley PetscFunctionReturn(0); 2977c067b6caSMatthew G. Knepley } else { 29780298fd71SBarry Smith PetscErrorCode (*conv)(DM, DMType, DM*) = NULL; 297967a56275SMatthew G Knepley 298067a56275SMatthew G Knepley /* 298167a56275SMatthew G Knepley Order of precedence: 298267a56275SMatthew G Knepley 1) See if a specialized converter is known to the current DM. 298367a56275SMatthew G Knepley 2) See if a specialized converter is known to the desired DM class. 298467a56275SMatthew G Knepley 3) See if a good general converter is registered for the desired class 298567a56275SMatthew G Knepley 4) See if a good general converter is known for the current matrix. 298667a56275SMatthew G Knepley 5) Use a really basic converter. 298767a56275SMatthew G Knepley */ 298867a56275SMatthew G Knepley 298967a56275SMatthew G Knepley /* 1) See if a specialized converter is known to the current DM and the desired class */ 299067a56275SMatthew G Knepley ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr); 299167a56275SMatthew G Knepley ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr); 299267a56275SMatthew G Knepley ierr = PetscStrcat(convname,"_");CHKERRQ(ierr); 299367a56275SMatthew G Knepley ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr); 299467a56275SMatthew G Knepley ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr); 29950005d66cSJed Brown ierr = PetscObjectQueryFunction((PetscObject)dm,convname,&conv);CHKERRQ(ierr); 299667a56275SMatthew G Knepley if (conv) goto foundconv; 299767a56275SMatthew G Knepley 299867a56275SMatthew G Knepley /* 2) See if a specialized converter is known to the desired DM class. */ 299982f516ccSBarry Smith ierr = DMCreate(PetscObjectComm((PetscObject)dm), &B);CHKERRQ(ierr); 300067a56275SMatthew G Knepley ierr = DMSetType(B, newtype);CHKERRQ(ierr); 300167a56275SMatthew G Knepley ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr); 300267a56275SMatthew G Knepley ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr); 300367a56275SMatthew G Knepley ierr = PetscStrcat(convname,"_");CHKERRQ(ierr); 300467a56275SMatthew G Knepley ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr); 300567a56275SMatthew G Knepley ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr); 30060005d66cSJed Brown ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 300767a56275SMatthew G Knepley if (conv) { 3008fcfd50ebSBarry Smith ierr = DMDestroy(&B);CHKERRQ(ierr); 300967a56275SMatthew G Knepley goto foundconv; 301067a56275SMatthew G Knepley } 301167a56275SMatthew G Knepley 301267a56275SMatthew G Knepley #if 0 301367a56275SMatthew G Knepley /* 3) See if a good general converter is registered for the desired class */ 301467a56275SMatthew G Knepley conv = B->ops->convertfrom; 3015fcfd50ebSBarry Smith ierr = DMDestroy(&B);CHKERRQ(ierr); 301667a56275SMatthew G Knepley if (conv) goto foundconv; 301767a56275SMatthew G Knepley 301867a56275SMatthew G Knepley /* 4) See if a good general converter is known for the current matrix */ 301967a56275SMatthew G Knepley if (dm->ops->convert) { 302067a56275SMatthew G Knepley conv = dm->ops->convert; 302167a56275SMatthew G Knepley } 302267a56275SMatthew G Knepley if (conv) goto foundconv; 302367a56275SMatthew G Knepley #endif 302467a56275SMatthew G Knepley 302567a56275SMatthew G Knepley /* 5) Use a really basic converter. */ 302682f516ccSBarry Smith SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype); 302767a56275SMatthew G Knepley 302867a56275SMatthew G Knepley foundconv: 302967a56275SMatthew G Knepley ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr); 303067a56275SMatthew G Knepley ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr); 303112fa691eSMatthew G. Knepley /* Things that are independent of DM type: We should consult DMClone() here */ 303212fa691eSMatthew G. Knepley if (dm->maxCell) { 303312fa691eSMatthew G. Knepley const PetscReal *maxCell, *L; 303412fa691eSMatthew G. Knepley const DMBoundaryType *bd; 303512fa691eSMatthew G. Knepley ierr = DMGetPeriodicity(dm, &maxCell, &L, &bd);CHKERRQ(ierr); 303612fa691eSMatthew G. Knepley ierr = DMSetPeriodicity(*M, maxCell, L, bd);CHKERRQ(ierr); 303712fa691eSMatthew G. Knepley } 303867a56275SMatthew G Knepley ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr); 303967a56275SMatthew G Knepley } 304067a56275SMatthew G Knepley ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr); 304167a56275SMatthew G Knepley PetscFunctionReturn(0); 304267a56275SMatthew G Knepley } 3043264ace61SBarry Smith 3044264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/ 3045264ace61SBarry Smith 3046264ace61SBarry Smith /*@C 30471c84c290SBarry Smith DMRegister - Adds a new DM component implementation 30481c84c290SBarry Smith 30491c84c290SBarry Smith Not Collective 30501c84c290SBarry Smith 30511c84c290SBarry Smith Input Parameters: 30521c84c290SBarry Smith + name - The name of a new user-defined creation routine 30531c84c290SBarry Smith - create_func - The creation routine itself 30541c84c290SBarry Smith 30551c84c290SBarry Smith Notes: 30561c84c290SBarry Smith DMRegister() may be called multiple times to add several user-defined DMs 30571c84c290SBarry Smith 30581c84c290SBarry Smith 30591c84c290SBarry Smith Sample usage: 30601c84c290SBarry Smith .vb 3061bdf89e91SBarry Smith DMRegister("my_da", MyDMCreate); 30621c84c290SBarry Smith .ve 30631c84c290SBarry Smith 30641c84c290SBarry Smith Then, your DM type can be chosen with the procedural interface via 30651c84c290SBarry Smith .vb 30661c84c290SBarry Smith DMCreate(MPI_Comm, DM *); 30671c84c290SBarry Smith DMSetType(DM,"my_da"); 30681c84c290SBarry Smith .ve 30691c84c290SBarry Smith or at runtime via the option 30701c84c290SBarry Smith .vb 30711c84c290SBarry Smith -da_type my_da 30721c84c290SBarry Smith .ve 3073264ace61SBarry Smith 3074264ace61SBarry Smith Level: advanced 30751c84c290SBarry Smith 30761c84c290SBarry Smith .keywords: DM, register 3077bdf89e91SBarry Smith .seealso: DMRegisterAll(), DMRegisterDestroy() 30781c84c290SBarry Smith 3079264ace61SBarry Smith @*/ 3080bdf89e91SBarry Smith PetscErrorCode DMRegister(const char sname[],PetscErrorCode (*function)(DM)) 3081264ace61SBarry Smith { 3082264ace61SBarry Smith PetscErrorCode ierr; 3083264ace61SBarry Smith 3084264ace61SBarry Smith PetscFunctionBegin; 3085a240a19fSJed Brown ierr = PetscFunctionListAdd(&DMList,sname,function);CHKERRQ(ierr); 3086264ace61SBarry Smith PetscFunctionReturn(0); 3087264ace61SBarry Smith } 3088264ace61SBarry Smith 3089b859378eSBarry Smith /*@C 309055849f57SBarry Smith DMLoad - Loads a DM that has been stored in binary with DMView(). 3091b859378eSBarry Smith 3092b859378eSBarry Smith Collective on PetscViewer 3093b859378eSBarry Smith 3094b859378eSBarry Smith Input Parameters: 3095b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or 3096b859378eSBarry Smith some related function before a call to DMLoad(). 3097b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or 3098b859378eSBarry Smith HDF5 file viewer, obtained from PetscViewerHDF5Open() 3099b859378eSBarry Smith 3100b859378eSBarry Smith Level: intermediate 3101b859378eSBarry Smith 3102b859378eSBarry Smith Notes: 310355849f57SBarry Smith The type is determined by the data in the file, any type set into the DM before this call is ignored. 3104b859378eSBarry Smith 3105b859378eSBarry Smith Notes for advanced users: 3106b859378eSBarry Smith Most users should not need to know the details of the binary storage 3107b859378eSBarry Smith format, since DMLoad() and DMView() completely hide these details. 3108b859378eSBarry Smith But for anyone who's interested, the standard binary matrix storage 3109b859378eSBarry Smith format is 3110b859378eSBarry Smith .vb 3111b859378eSBarry Smith has not yet been determined 3112b859378eSBarry Smith .ve 3113b859378eSBarry Smith 3114b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad() 3115b859378eSBarry Smith @*/ 3116b859378eSBarry Smith PetscErrorCode DMLoad(DM newdm, PetscViewer viewer) 3117b859378eSBarry Smith { 31189331c7a4SMatthew G. Knepley PetscBool isbinary, ishdf5; 3119b859378eSBarry Smith PetscErrorCode ierr; 3120b859378eSBarry Smith 3121b859378eSBarry Smith PetscFunctionBegin; 3122b859378eSBarry Smith PetscValidHeaderSpecific(newdm,DM_CLASSID,1); 3123b859378eSBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 312432c0f0efSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 31259331c7a4SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 31269331c7a4SMatthew G. Knepley if (isbinary) { 31279331c7a4SMatthew G. Knepley PetscInt classid; 31289331c7a4SMatthew G. Knepley char type[256]; 3129b859378eSBarry Smith 3130060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr); 31319200755eSBarry Smith if (classid != DM_FILE_CLASSID) SETERRQ1(PetscObjectComm((PetscObject)newdm),PETSC_ERR_ARG_WRONG,"Not DM next in file, classid found %d",(int)classid); 3132060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr); 313332c0f0efSBarry Smith ierr = DMSetType(newdm, type);CHKERRQ(ierr); 31349331c7a4SMatthew G. Knepley if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);} 31359331c7a4SMatthew G. Knepley } else if (ishdf5) { 31369331c7a4SMatthew G. Knepley if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);} 31379331c7a4SMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()"); 3138b859378eSBarry Smith PetscFunctionReturn(0); 3139b859378eSBarry Smith } 3140b859378eSBarry Smith 31417da65231SMatthew G Knepley /******************************** FEM Support **********************************/ 31427da65231SMatthew G Knepley 3143a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) 3144a6dfd86eSKarl Rupp { 31451d47ebbbSSatish Balay PetscInt f; 31461b30c384SMatthew G Knepley PetscErrorCode ierr; 31471b30c384SMatthew G Knepley 31487da65231SMatthew G Knepley PetscFunctionBegin; 314974778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr); 31501d47ebbbSSatish Balay for (f = 0; f < len; ++f) { 315157622a8eSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, " | %g |\n", (double)PetscRealPart(x[f]));CHKERRQ(ierr); 31527da65231SMatthew G Knepley } 31537da65231SMatthew G Knepley PetscFunctionReturn(0); 31547da65231SMatthew G Knepley } 31557da65231SMatthew G Knepley 3156a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) 3157a6dfd86eSKarl Rupp { 31581b30c384SMatthew G Knepley PetscInt f, g; 31597da65231SMatthew G Knepley PetscErrorCode ierr; 31607da65231SMatthew G Knepley 31617da65231SMatthew G Knepley PetscFunctionBegin; 316274778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr); 31631d47ebbbSSatish Balay for (f = 0; f < rows; ++f) { 316474778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, " |");CHKERRQ(ierr); 31651d47ebbbSSatish Balay for (g = 0; g < cols; ++g) { 3166e3556bceSMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5g", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr); 31677da65231SMatthew G Knepley } 316874778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr); 31697da65231SMatthew G Knepley } 31707da65231SMatthew G Knepley PetscFunctionReturn(0); 31717da65231SMatthew G Knepley } 3172e7c4fc90SDmitry Karpeev 31736113b454SMatthew G. Knepley PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X) 3174e759306cSMatthew G. Knepley { 31750c5b8624SToby Isaac PetscInt localSize, bs; 31760c5b8624SToby Isaac PetscMPIInt size; 31770c5b8624SToby Isaac Vec x, xglob; 31780c5b8624SToby Isaac const PetscScalar *xarray; 3179e759306cSMatthew G. Knepley PetscErrorCode ierr; 3180e759306cSMatthew G. Knepley 3181e759306cSMatthew G. Knepley PetscFunctionBegin; 31829852e123SBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm),&size);CHKERRQ(ierr); 3183e759306cSMatthew G. Knepley ierr = VecDuplicate(X, &x);CHKERRQ(ierr); 3184e759306cSMatthew G. Knepley ierr = VecCopy(X, x);CHKERRQ(ierr); 31856113b454SMatthew G. Knepley ierr = VecChop(x, tol);CHKERRQ(ierr); 31860c5b8624SToby Isaac ierr = PetscPrintf(PetscObjectComm((PetscObject) dm),"%s:\n",name);CHKERRQ(ierr); 31870c5b8624SToby Isaac if (size > 1) { 31880c5b8624SToby Isaac ierr = VecGetLocalSize(x,&localSize);CHKERRQ(ierr); 31890c5b8624SToby Isaac ierr = VecGetArrayRead(x,&xarray);CHKERRQ(ierr); 31900c5b8624SToby Isaac ierr = VecGetBlockSize(x,&bs);CHKERRQ(ierr); 31910c5b8624SToby Isaac ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject) dm),bs,localSize,PETSC_DETERMINE,xarray,&xglob);CHKERRQ(ierr); 31920c5b8624SToby Isaac } else { 31930c5b8624SToby Isaac xglob = x; 31940c5b8624SToby Isaac } 31950c5b8624SToby Isaac ierr = VecView(xglob,PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject) dm)));CHKERRQ(ierr); 31960c5b8624SToby Isaac if (size > 1) { 31970c5b8624SToby Isaac ierr = VecDestroy(&xglob);CHKERRQ(ierr); 31980c5b8624SToby Isaac ierr = VecRestoreArrayRead(x,&xarray);CHKERRQ(ierr); 31990c5b8624SToby Isaac } 3200e759306cSMatthew G. Knepley ierr = VecDestroy(&x);CHKERRQ(ierr); 3201e759306cSMatthew G. Knepley PetscFunctionReturn(0); 3202e759306cSMatthew G. Knepley } 3203e759306cSMatthew G. Knepley 320488ed4aceSMatthew G Knepley /*@ 320588ed4aceSMatthew G Knepley DMGetDefaultSection - Get the PetscSection encoding the local data layout for the DM. 320688ed4aceSMatthew G Knepley 320788ed4aceSMatthew G Knepley Input Parameter: 320888ed4aceSMatthew G Knepley . dm - The DM 320988ed4aceSMatthew G Knepley 321088ed4aceSMatthew G Knepley Output Parameter: 321188ed4aceSMatthew G Knepley . section - The PetscSection 321288ed4aceSMatthew G Knepley 321388ed4aceSMatthew G Knepley Level: intermediate 321488ed4aceSMatthew G Knepley 321588ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSection. 321688ed4aceSMatthew G Knepley 321788ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection() 321888ed4aceSMatthew G Knepley @*/ 32190adebc6cSBarry Smith PetscErrorCode DMGetDefaultSection(DM dm, PetscSection *section) 32200adebc6cSBarry Smith { 3221fd59a867SMatthew G. Knepley PetscErrorCode ierr; 3222fd59a867SMatthew G. Knepley 322388ed4aceSMatthew G Knepley PetscFunctionBegin; 322488ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 322588ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 32262f0f8703SMatthew G. Knepley if (!dm->defaultSection && dm->ops->createdefaultsection) { 32272f0f8703SMatthew G. Knepley ierr = (*dm->ops->createdefaultsection)(dm);CHKERRQ(ierr); 3228ae71db08SMatthew G. Knepley if (dm->defaultSection) {ierr = PetscObjectViewFromOptions((PetscObject) dm->defaultSection, NULL, "-dm_petscsection_view");CHKERRQ(ierr);} 32292f0f8703SMatthew G. Knepley } 323088ed4aceSMatthew G Knepley *section = dm->defaultSection; 323188ed4aceSMatthew G Knepley PetscFunctionReturn(0); 323288ed4aceSMatthew G Knepley } 323388ed4aceSMatthew G Knepley 323488ed4aceSMatthew G Knepley /*@ 323588ed4aceSMatthew G Knepley DMSetDefaultSection - Set the PetscSection encoding the local data layout for the DM. 323688ed4aceSMatthew G Knepley 323788ed4aceSMatthew G Knepley Input Parameters: 323888ed4aceSMatthew G Knepley + dm - The DM 323988ed4aceSMatthew G Knepley - section - The PetscSection 324088ed4aceSMatthew G Knepley 324188ed4aceSMatthew G Knepley Level: intermediate 324288ed4aceSMatthew G Knepley 324388ed4aceSMatthew G Knepley Note: Any existing Section will be destroyed 324488ed4aceSMatthew G Knepley 324588ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection() 324688ed4aceSMatthew G Knepley @*/ 32470adebc6cSBarry Smith PetscErrorCode DMSetDefaultSection(DM dm, PetscSection section) 32480adebc6cSBarry Smith { 3249c473ab19SMatthew G. Knepley PetscInt numFields = 0; 3250af122d2aSMatthew G Knepley PetscInt f; 325188ed4aceSMatthew G Knepley PetscErrorCode ierr; 325288ed4aceSMatthew G Knepley 325388ed4aceSMatthew G Knepley PetscFunctionBegin; 325488ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3255c473ab19SMatthew G. Knepley if (section) { 32561d799100SJed Brown PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 32571d799100SJed Brown ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 3258c473ab19SMatthew G. Knepley } 325988ed4aceSMatthew G Knepley ierr = PetscSectionDestroy(&dm->defaultSection);CHKERRQ(ierr); 326088ed4aceSMatthew G Knepley dm->defaultSection = section; 3261c473ab19SMatthew G. Knepley if (section) {ierr = PetscSectionGetNumFields(dm->defaultSection, &numFields);CHKERRQ(ierr);} 3262af122d2aSMatthew G Knepley if (numFields) { 3263af122d2aSMatthew G Knepley ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr); 3264af122d2aSMatthew G Knepley for (f = 0; f < numFields; ++f) { 32650f21e855SMatthew G. Knepley PetscObject disc; 3266af122d2aSMatthew G Knepley const char *name; 3267af122d2aSMatthew G Knepley 3268af122d2aSMatthew G Knepley ierr = PetscSectionGetFieldName(dm->defaultSection, f, &name);CHKERRQ(ierr); 32690f21e855SMatthew G. Knepley ierr = DMGetField(dm, f, &disc);CHKERRQ(ierr); 32700f21e855SMatthew G. Knepley ierr = PetscObjectSetName(disc, name);CHKERRQ(ierr); 3271af122d2aSMatthew G Knepley } 3272af122d2aSMatthew G Knepley } 32731d799100SJed Brown /* The global section will be rebuilt in the next call to DMGetDefaultGlobalSection(). */ 32741d799100SJed Brown ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr); 327588ed4aceSMatthew G Knepley PetscFunctionReturn(0); 327688ed4aceSMatthew G Knepley } 327788ed4aceSMatthew G Knepley 32789435951eSToby Isaac /*@ 32799435951eSToby Isaac DMGetDefaultConstraints - Get the PetscSection and Mat the specify the local constraint interpolation. See DMSetDefaultConstraints() for a description of the purpose of constraint interpolation. 32809435951eSToby Isaac 3281e228b242SToby Isaac not collective 3282e228b242SToby Isaac 32839435951eSToby Isaac Input Parameter: 32849435951eSToby Isaac . dm - The DM 32859435951eSToby Isaac 32869435951eSToby Isaac Output Parameter: 32879435951eSToby Isaac + section - The PetscSection describing the range of the constraint matrix: relates rows of the constraint matrix to dofs of the default section. Returns NULL if there are no local constraints. 32889435951eSToby Isaac - mat - The Mat that interpolates local constraints: its width should be the layout size of the default section. Returns NULL if there are no local constraints. 32899435951eSToby Isaac 32909435951eSToby Isaac Level: advanced 32919435951eSToby Isaac 32929435951eSToby Isaac Note: This gets borrowed references, so the user should not destroy the PetscSection or the Mat. 32939435951eSToby Isaac 32949435951eSToby Isaac .seealso: DMSetDefaultConstraints() 32959435951eSToby Isaac @*/ 32969435951eSToby Isaac PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat) 32979435951eSToby Isaac { 32989435951eSToby Isaac PetscErrorCode ierr; 32999435951eSToby Isaac 33009435951eSToby Isaac PetscFunctionBegin; 33019435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 33029435951eSToby Isaac if (!dm->defaultConstraintSection && !dm->defaultConstraintMat && dm->ops->createdefaultconstraints) {ierr = (*dm->ops->createdefaultconstraints)(dm);CHKERRQ(ierr);} 330345a75d81SToby Isaac if (section) {*section = dm->defaultConstraintSection;} 330445a75d81SToby Isaac if (mat) {*mat = dm->defaultConstraintMat;} 33059435951eSToby Isaac PetscFunctionReturn(0); 33069435951eSToby Isaac } 33079435951eSToby Isaac 33089435951eSToby Isaac /*@ 33099435951eSToby Isaac DMSetDefaultConstraints - Set the PetscSection and Mat the specify the local constraint interpolation. 33109435951eSToby Isaac 33119435951eSToby Isaac If a constraint matrix is specified, then it is applied during DMGlobalToLocalEnd() when mode is INSERT_VALUES, INSERT_BC_VALUES, or INSERT_ALL_VALUES. Without a constraint matrix, the local vector l returned by DMGlobalToLocalEnd() contains values that have been scattered from a global vector without modification; with a constraint matrix A, l is modified by computing c = A * l, l[s[i]] = c[i], where the scatter s is defined by the PetscSection returned by DMGetDefaultConstraintMatrix(). 33129435951eSToby Isaac 33139435951eSToby Isaac If a constraint matrix is specified, then its adjoint is applied during DMLocalToGlobalBegin() when mode is ADD_VALUES, ADD_BC_VALUES, or ADD_ALL_VALUES. Without a constraint matrix, the local vector l is accumulated into a global vector without modification; with a constraint matrix A, l is first modified by computing c[i] = l[s[i]], l[s[i]] = 0, l = l + A'*c, which is the adjoint of the operation described above. 33149435951eSToby Isaac 3315e228b242SToby Isaac collective on dm 3316e228b242SToby Isaac 33179435951eSToby Isaac Input Parameters: 33189435951eSToby Isaac + dm - The DM 3319e228b242SToby Isaac + section - The PetscSection describing the range of the constraint matrix: relates rows of the constraint matrix to dofs of the default section. Must have a local communicator (PETSC_COMM_SELF or derivative). 3320e228b242SToby Isaac - mat - The Mat that interpolates local constraints: its width should be the layout size of the default section: NULL indicates no constraints. Must have a local communicator (PETSC_COMM_SELF or derivative). 33219435951eSToby Isaac 33229435951eSToby Isaac Level: advanced 33239435951eSToby Isaac 33249435951eSToby Isaac Note: This increments the references of the PetscSection and the Mat, so they user can destroy them 33259435951eSToby Isaac 33269435951eSToby Isaac .seealso: DMGetDefaultConstraints() 33279435951eSToby Isaac @*/ 33289435951eSToby Isaac PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat) 33299435951eSToby Isaac { 3330e228b242SToby Isaac PetscMPIInt result; 33319435951eSToby Isaac PetscErrorCode ierr; 33329435951eSToby Isaac 33339435951eSToby Isaac PetscFunctionBegin; 33349435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3335e228b242SToby Isaac if (section) { 3336e228b242SToby Isaac PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 3337e228b242SToby Isaac ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)section),&result);CHKERRQ(ierr); 3338f60917d2SBarry Smith if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint section must have local communicator"); 3339e228b242SToby Isaac } 3340e228b242SToby Isaac if (mat) { 3341e228b242SToby Isaac PetscValidHeaderSpecific(mat,MAT_CLASSID,3); 3342e228b242SToby Isaac ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)mat),&result);CHKERRQ(ierr); 3343f60917d2SBarry Smith if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint matrix must have local communicator"); 3344e228b242SToby Isaac } 33459435951eSToby Isaac ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 33469435951eSToby Isaac ierr = PetscSectionDestroy(&dm->defaultConstraintSection);CHKERRQ(ierr); 33479435951eSToby Isaac dm->defaultConstraintSection = section; 33489435951eSToby Isaac ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 33499435951eSToby Isaac ierr = MatDestroy(&dm->defaultConstraintMat);CHKERRQ(ierr); 33509435951eSToby Isaac dm->defaultConstraintMat = mat; 33519435951eSToby Isaac PetscFunctionReturn(0); 33529435951eSToby Isaac } 33539435951eSToby Isaac 3354f741bcd2SMatthew G. Knepley #ifdef PETSC_USE_DEBUG 3355507e4973SMatthew G. Knepley /* 3356507e4973SMatthew G. Knepley DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections. 3357507e4973SMatthew G. Knepley 3358507e4973SMatthew G. Knepley Input Parameters: 3359507e4973SMatthew G. Knepley + dm - The DM 3360507e4973SMatthew G. Knepley . localSection - PetscSection describing the local data layout 3361507e4973SMatthew G. Knepley - globalSection - PetscSection describing the global data layout 3362507e4973SMatthew G. Knepley 3363507e4973SMatthew G. Knepley Level: intermediate 3364507e4973SMatthew G. Knepley 3365507e4973SMatthew G. Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF() 3366507e4973SMatthew G. Knepley */ 3367f741bcd2SMatthew G. Knepley static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection) 3368507e4973SMatthew G. Knepley { 3369507e4973SMatthew G. Knepley MPI_Comm comm; 3370507e4973SMatthew G. Knepley PetscLayout layout; 3371507e4973SMatthew G. Knepley const PetscInt *ranges; 3372507e4973SMatthew G. Knepley PetscInt pStart, pEnd, p, nroots; 3373507e4973SMatthew G. Knepley PetscMPIInt size, rank; 3374507e4973SMatthew G. Knepley PetscBool valid = PETSC_TRUE, gvalid; 3375507e4973SMatthew G. Knepley PetscErrorCode ierr; 3376507e4973SMatthew G. Knepley 3377507e4973SMatthew G. Knepley PetscFunctionBegin; 3378507e4973SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 3379507e4973SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3380507e4973SMatthew G. Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 3381507e4973SMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 3382507e4973SMatthew G. Knepley ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr); 3383507e4973SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr); 3384507e4973SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr); 3385507e4973SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr); 3386507e4973SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr); 3387507e4973SMatthew G. Knepley ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr); 3388507e4973SMatthew G. Knepley ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr); 3389507e4973SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3390f741bcd2SMatthew G. Knepley PetscInt dof, cdof, off, gdof, gcdof, goff, gsize, d; 3391507e4973SMatthew G. Knepley 3392507e4973SMatthew G. Knepley ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr); 3393507e4973SMatthew G. Knepley ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr); 3394507e4973SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr); 3395507e4973SMatthew G. Knepley ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr); 3396507e4973SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr); 3397507e4973SMatthew G. Knepley ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr); 3398507e4973SMatthew G. Knepley if (!gdof) continue; /* Censored point */ 3399507e4973SMatthew G. Knepley if ((gdof < 0 ? -(gdof+1) : gdof) != dof) {ierr = PetscSynchronizedPrintf(comm, "[%d]Global dof %d for point %d not equal to local dof %d\n", rank, gdof, p, dof);CHKERRQ(ierr); valid = PETSC_FALSE;} 3400507e4973SMatthew G. Knepley if (gcdof && (gcdof != cdof)) {ierr = PetscSynchronizedPrintf(comm, "[%d]Global constraints %d for point %d not equal to local constraints %d\n", rank, gcdof, p, cdof);CHKERRQ(ierr); valid = PETSC_FALSE;} 3401507e4973SMatthew G. Knepley if (gdof < 0) { 3402507e4973SMatthew G. Knepley gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof; 3403507e4973SMatthew G. Knepley for (d = 0; d < gsize; ++d) { 3404507e4973SMatthew G. Knepley PetscInt offset = -(goff+1) + d, r; 3405507e4973SMatthew G. Knepley 3406507e4973SMatthew G. Knepley ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr); 3407507e4973SMatthew G. Knepley if (r < 0) r = -(r+2); 3408507e4973SMatthew G. Knepley if ((r < 0) || (r >= size)) {ierr = PetscSynchronizedPrintf(comm, "[%d]Point %d mapped to invalid process %d (%d, %d)\n", rank, p, r, gdof, goff);CHKERRQ(ierr); valid = PETSC_FALSE;break;} 3409507e4973SMatthew G. Knepley } 3410507e4973SMatthew G. Knepley } 3411507e4973SMatthew G. Knepley } 3412507e4973SMatthew G. Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 3413507e4973SMatthew G. Knepley ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr); 3414b2566f29SBarry Smith ierr = MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRQ(ierr); 3415507e4973SMatthew G. Knepley if (!gvalid) { 3416507e4973SMatthew G. Knepley ierr = DMView(dm, NULL);CHKERRQ(ierr); 3417507e4973SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections"); 3418507e4973SMatthew G. Knepley } 3419507e4973SMatthew G. Knepley PetscFunctionReturn(0); 3420507e4973SMatthew G. Knepley } 3421f741bcd2SMatthew G. Knepley #endif 3422507e4973SMatthew G. Knepley 342388ed4aceSMatthew G Knepley /*@ 342488ed4aceSMatthew G Knepley DMGetDefaultGlobalSection - Get the PetscSection encoding the global data layout for the DM. 342588ed4aceSMatthew G Knepley 34268b1ab98fSJed Brown Collective on DM 34278b1ab98fSJed Brown 342888ed4aceSMatthew G Knepley Input Parameter: 342988ed4aceSMatthew G Knepley . dm - The DM 343088ed4aceSMatthew G Knepley 343188ed4aceSMatthew G Knepley Output Parameter: 343288ed4aceSMatthew G Knepley . section - The PetscSection 343388ed4aceSMatthew G Knepley 343488ed4aceSMatthew G Knepley Level: intermediate 343588ed4aceSMatthew G Knepley 343688ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSection. 343788ed4aceSMatthew G Knepley 343888ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultSection() 343988ed4aceSMatthew G Knepley @*/ 34400adebc6cSBarry Smith PetscErrorCode DMGetDefaultGlobalSection(DM dm, PetscSection *section) 34410adebc6cSBarry Smith { 344288ed4aceSMatthew G Knepley PetscErrorCode ierr; 344388ed4aceSMatthew G Knepley 344488ed4aceSMatthew G Knepley PetscFunctionBegin; 344588ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 344688ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 344788ed4aceSMatthew G Knepley if (!dm->defaultGlobalSection) { 3448fd59a867SMatthew G. Knepley PetscSection s; 3449fd59a867SMatthew G. Knepley 3450fd59a867SMatthew G. Knepley ierr = DMGetDefaultSection(dm, &s);CHKERRQ(ierr); 3451fd59a867SMatthew G. Knepley if (!s) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a default PetscSection in order to create a global PetscSection"); 3452fd59a867SMatthew G. Knepley if (!dm->sf) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a default PetscSF in order to create a global PetscSection"); 345315b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(s, dm->sf, PETSC_FALSE, PETSC_FALSE, &dm->defaultGlobalSection);CHKERRQ(ierr); 3454cf06b437SMatthew G. Knepley ierr = PetscLayoutDestroy(&dm->map);CHKERRQ(ierr); 3455ce94432eSBarry Smith ierr = PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->defaultGlobalSection, &dm->map);CHKERRQ(ierr); 3456685405a1SBarry Smith ierr = PetscSectionViewFromOptions(dm->defaultGlobalSection, NULL, "-global_section_view");CHKERRQ(ierr); 345788ed4aceSMatthew G Knepley } 345888ed4aceSMatthew G Knepley *section = dm->defaultGlobalSection; 345988ed4aceSMatthew G Knepley PetscFunctionReturn(0); 346088ed4aceSMatthew G Knepley } 346188ed4aceSMatthew G Knepley 3462b21d0597SMatthew G Knepley /*@ 3463b21d0597SMatthew G Knepley DMSetDefaultGlobalSection - Set the PetscSection encoding the global data layout for the DM. 3464b21d0597SMatthew G Knepley 3465b21d0597SMatthew G Knepley Input Parameters: 3466b21d0597SMatthew G Knepley + dm - The DM 34675080bbdbSMatthew G Knepley - section - The PetscSection, or NULL 3468b21d0597SMatthew G Knepley 3469b21d0597SMatthew G Knepley Level: intermediate 3470b21d0597SMatthew G Knepley 3471b21d0597SMatthew G Knepley Note: Any existing Section will be destroyed 3472b21d0597SMatthew G Knepley 3473b21d0597SMatthew G Knepley .seealso: DMGetDefaultGlobalSection(), DMSetDefaultSection() 3474b21d0597SMatthew G Knepley @*/ 34750adebc6cSBarry Smith PetscErrorCode DMSetDefaultGlobalSection(DM dm, PetscSection section) 34760adebc6cSBarry Smith { 3477b21d0597SMatthew G Knepley PetscErrorCode ierr; 3478b21d0597SMatthew G Knepley 3479b21d0597SMatthew G Knepley PetscFunctionBegin; 3480b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 34815080bbdbSMatthew G Knepley if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 34821d799100SJed Brown ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 3483b21d0597SMatthew G Knepley ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr); 3484b21d0597SMatthew G Knepley dm->defaultGlobalSection = section; 3485507e4973SMatthew G. Knepley #ifdef PETSC_USE_DEBUG 3486f741bcd2SMatthew G. Knepley if (section) {ierr = DMDefaultSectionCheckConsistency_Internal(dm, dm->defaultSection, section);CHKERRQ(ierr);} 3487507e4973SMatthew G. Knepley #endif 3488b21d0597SMatthew G Knepley PetscFunctionReturn(0); 3489b21d0597SMatthew G Knepley } 3490b21d0597SMatthew G Knepley 349188ed4aceSMatthew G Knepley /*@ 349288ed4aceSMatthew G Knepley DMGetDefaultSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set, 349388ed4aceSMatthew G Knepley it is created from the default PetscSection layouts in the DM. 349488ed4aceSMatthew G Knepley 349588ed4aceSMatthew G Knepley Input Parameter: 349688ed4aceSMatthew G Knepley . dm - The DM 349788ed4aceSMatthew G Knepley 349888ed4aceSMatthew G Knepley Output Parameter: 349988ed4aceSMatthew G Knepley . sf - The PetscSF 350088ed4aceSMatthew G Knepley 350188ed4aceSMatthew G Knepley Level: intermediate 350288ed4aceSMatthew G Knepley 350388ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSF. 350488ed4aceSMatthew G Knepley 350588ed4aceSMatthew G Knepley .seealso: DMSetDefaultSF(), DMCreateDefaultSF() 350688ed4aceSMatthew G Knepley @*/ 35070adebc6cSBarry Smith PetscErrorCode DMGetDefaultSF(DM dm, PetscSF *sf) 35080adebc6cSBarry Smith { 350988ed4aceSMatthew G Knepley PetscInt nroots; 351088ed4aceSMatthew G Knepley PetscErrorCode ierr; 351188ed4aceSMatthew G Knepley 351288ed4aceSMatthew G Knepley PetscFunctionBegin; 351388ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 351488ed4aceSMatthew G Knepley PetscValidPointer(sf, 2); 35150298fd71SBarry Smith ierr = PetscSFGetGraph(dm->defaultSF, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 351688ed4aceSMatthew G Knepley if (nroots < 0) { 351788ed4aceSMatthew G Knepley PetscSection section, gSection; 351888ed4aceSMatthew G Knepley 351988ed4aceSMatthew G Knepley ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 352031ea6d37SMatthew G Knepley if (section) { 352188ed4aceSMatthew G Knepley ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr); 352288ed4aceSMatthew G Knepley ierr = DMCreateDefaultSF(dm, section, gSection);CHKERRQ(ierr); 352331ea6d37SMatthew G Knepley } else { 35240298fd71SBarry Smith *sf = NULL; 352531ea6d37SMatthew G Knepley PetscFunctionReturn(0); 352631ea6d37SMatthew G Knepley } 352788ed4aceSMatthew G Knepley } 352888ed4aceSMatthew G Knepley *sf = dm->defaultSF; 352988ed4aceSMatthew G Knepley PetscFunctionReturn(0); 353088ed4aceSMatthew G Knepley } 353188ed4aceSMatthew G Knepley 353288ed4aceSMatthew G Knepley /*@ 353388ed4aceSMatthew G Knepley DMSetDefaultSF - Set the PetscSF encoding the parallel dof overlap for the DM 353488ed4aceSMatthew G Knepley 353588ed4aceSMatthew G Knepley Input Parameters: 353688ed4aceSMatthew G Knepley + dm - The DM 353788ed4aceSMatthew G Knepley - sf - The PetscSF 353888ed4aceSMatthew G Knepley 353988ed4aceSMatthew G Knepley Level: intermediate 354088ed4aceSMatthew G Knepley 354188ed4aceSMatthew G Knepley Note: Any previous SF is destroyed 354288ed4aceSMatthew G Knepley 354388ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMCreateDefaultSF() 354488ed4aceSMatthew G Knepley @*/ 35450adebc6cSBarry Smith PetscErrorCode DMSetDefaultSF(DM dm, PetscSF sf) 35460adebc6cSBarry Smith { 354788ed4aceSMatthew G Knepley PetscErrorCode ierr; 354888ed4aceSMatthew G Knepley 354988ed4aceSMatthew G Knepley PetscFunctionBegin; 355088ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 355188ed4aceSMatthew G Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 355288ed4aceSMatthew G Knepley ierr = PetscSFDestroy(&dm->defaultSF);CHKERRQ(ierr); 355388ed4aceSMatthew G Knepley dm->defaultSF = sf; 355488ed4aceSMatthew G Knepley PetscFunctionReturn(0); 355588ed4aceSMatthew G Knepley } 355688ed4aceSMatthew G Knepley 355788ed4aceSMatthew G Knepley /*@C 355888ed4aceSMatthew G Knepley DMCreateDefaultSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections 355988ed4aceSMatthew G Knepley describing the data layout. 356088ed4aceSMatthew G Knepley 356188ed4aceSMatthew G Knepley Input Parameters: 356288ed4aceSMatthew G Knepley + dm - The DM 356388ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout 356488ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout 356588ed4aceSMatthew G Knepley 356688ed4aceSMatthew G Knepley Level: intermediate 356788ed4aceSMatthew G Knepley 356888ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF() 356988ed4aceSMatthew G Knepley @*/ 357088ed4aceSMatthew G Knepley PetscErrorCode DMCreateDefaultSF(DM dm, PetscSection localSection, PetscSection globalSection) 357188ed4aceSMatthew G Knepley { 357282f516ccSBarry Smith MPI_Comm comm; 357388ed4aceSMatthew G Knepley PetscLayout layout; 357488ed4aceSMatthew G Knepley const PetscInt *ranges; 357588ed4aceSMatthew G Knepley PetscInt *local; 357688ed4aceSMatthew G Knepley PetscSFNode *remote; 3577ecd73843SMatthew G. Knepley PetscInt pStart, pEnd, p, nroots, nleaves = 0, l; 357888ed4aceSMatthew G Knepley PetscMPIInt size, rank; 357988ed4aceSMatthew G Knepley PetscErrorCode ierr; 358088ed4aceSMatthew G Knepley 358188ed4aceSMatthew G Knepley PetscFunctionBegin; 358282f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 358388ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 358488ed4aceSMatthew G Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 358588ed4aceSMatthew G Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 358688ed4aceSMatthew G Knepley ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr); 358788ed4aceSMatthew G Knepley ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr); 358888ed4aceSMatthew G Knepley ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr); 358988ed4aceSMatthew G Knepley ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr); 359088ed4aceSMatthew G Knepley ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr); 359188ed4aceSMatthew G Knepley ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr); 359288ed4aceSMatthew G Knepley ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr); 3593ecd73843SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 35946636e97aSMatthew G Knepley PetscInt gdof, gcdof; 359588ed4aceSMatthew G Knepley 35966636e97aSMatthew G Knepley ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr); 35976636e97aSMatthew G Knepley ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr); 3598235fbf56SMatthew G. Knepley if (gcdof > (gdof < 0 ? -(gdof+1) : gdof)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point %d has %d constraints > %d dof", p, gcdof, (gdof < 0 ? -(gdof+1) : gdof)); 35996636e97aSMatthew G Knepley nleaves += gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof; 360088ed4aceSMatthew G Knepley } 3601785e854fSJed Brown ierr = PetscMalloc1(nleaves, &local);CHKERRQ(ierr); 3602785e854fSJed Brown ierr = PetscMalloc1(nleaves, &remote);CHKERRQ(ierr); 360388ed4aceSMatthew G Knepley for (p = pStart, l = 0; p < pEnd; ++p) { 36041f588964SMatthew G Knepley const PetscInt *cind; 36056636e97aSMatthew G Knepley PetscInt dof, cdof, off, gdof, gcdof, goff, gsize, d, c; 360688ed4aceSMatthew G Knepley 360788ed4aceSMatthew G Knepley ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr); 360888ed4aceSMatthew G Knepley ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr); 360988ed4aceSMatthew G Knepley ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr); 361088ed4aceSMatthew G Knepley ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr); 361188ed4aceSMatthew G Knepley ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr); 36126636e97aSMatthew G Knepley ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr); 361388ed4aceSMatthew G Knepley ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr); 36146636e97aSMatthew G Knepley if (!gdof) continue; /* Censored point */ 36156636e97aSMatthew G Knepley gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof; 36166636e97aSMatthew G Knepley if (gsize != dof-cdof) { 3617057b4bcdSMatthew G Knepley if (gsize != dof) SETERRQ4(comm, PETSC_ERR_ARG_WRONG, "Global dof %d for point %d is neither the constrained size %d, nor the unconstrained %d", gsize, p, dof-cdof, dof); 36186636e97aSMatthew G Knepley cdof = 0; /* Ignore constraints */ 36196636e97aSMatthew G Knepley } 362088ed4aceSMatthew G Knepley for (d = 0, c = 0; d < dof; ++d) { 362188ed4aceSMatthew G Knepley if ((c < cdof) && (cind[c] == d)) {++c; continue;} 362288ed4aceSMatthew G Knepley local[l+d-c] = off+d; 362388ed4aceSMatthew G Knepley } 362488ed4aceSMatthew G Knepley if (gdof < 0) { 36256636e97aSMatthew G Knepley for (d = 0; d < gsize; ++d, ++l) { 362688ed4aceSMatthew G Knepley PetscInt offset = -(goff+1) + d, r; 362788ed4aceSMatthew G Knepley 362805376888SMatthew G. Knepley ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr); 362931d3f06eSJed Brown if (r < 0) r = -(r+2); 363005376888SMatthew G. Knepley if ((r < 0) || (r >= size)) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point %d mapped to invalid process %d (%d, %d)", p, r, gdof, goff); 363188ed4aceSMatthew G Knepley remote[l].rank = r; 363288ed4aceSMatthew G Knepley remote[l].index = offset - ranges[r]; 363388ed4aceSMatthew G Knepley } 363488ed4aceSMatthew G Knepley } else { 36356636e97aSMatthew G Knepley for (d = 0; d < gsize; ++d, ++l) { 363688ed4aceSMatthew G Knepley remote[l].rank = rank; 363788ed4aceSMatthew G Knepley remote[l].index = goff+d - ranges[rank]; 363888ed4aceSMatthew G Knepley } 363988ed4aceSMatthew G Knepley } 364088ed4aceSMatthew G Knepley } 36416636e97aSMatthew G Knepley if (l != nleaves) SETERRQ2(comm, PETSC_ERR_PLIB, "Iteration error, l %d != nleaves %d", l, nleaves); 364288ed4aceSMatthew G Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 364388ed4aceSMatthew G Knepley ierr = PetscSFSetGraph(dm->defaultSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr); 364488ed4aceSMatthew G Knepley PetscFunctionReturn(0); 364588ed4aceSMatthew G Knepley } 3646af122d2aSMatthew G Knepley 3647b21d0597SMatthew G Knepley /*@ 3648b21d0597SMatthew G Knepley DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM. 3649b21d0597SMatthew G Knepley 3650b21d0597SMatthew G Knepley Input Parameter: 3651b21d0597SMatthew G Knepley . dm - The DM 3652b21d0597SMatthew G Knepley 3653b21d0597SMatthew G Knepley Output Parameter: 3654b21d0597SMatthew G Knepley . sf - The PetscSF 3655b21d0597SMatthew G Knepley 3656b21d0597SMatthew G Knepley Level: intermediate 3657b21d0597SMatthew G Knepley 3658b21d0597SMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSF. 3659b21d0597SMatthew G Knepley 3660057b4bcdSMatthew G Knepley .seealso: DMSetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF() 3661b21d0597SMatthew G Knepley @*/ 36620adebc6cSBarry Smith PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) 36630adebc6cSBarry Smith { 3664b21d0597SMatthew G Knepley PetscFunctionBegin; 3665b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3666b21d0597SMatthew G Knepley PetscValidPointer(sf, 2); 3667b21d0597SMatthew G Knepley *sf = dm->sf; 3668b21d0597SMatthew G Knepley PetscFunctionReturn(0); 3669b21d0597SMatthew G Knepley } 3670b21d0597SMatthew G Knepley 3671057b4bcdSMatthew G Knepley /*@ 3672057b4bcdSMatthew G Knepley DMSetPointSF - Set the PetscSF encoding the parallel section point overlap for the DM. 3673057b4bcdSMatthew G Knepley 3674057b4bcdSMatthew G Knepley Input Parameters: 3675057b4bcdSMatthew G Knepley + dm - The DM 3676057b4bcdSMatthew G Knepley - sf - The PetscSF 3677057b4bcdSMatthew G Knepley 3678057b4bcdSMatthew G Knepley Level: intermediate 3679057b4bcdSMatthew G Knepley 3680057b4bcdSMatthew G Knepley .seealso: DMGetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF() 3681057b4bcdSMatthew G Knepley @*/ 36820adebc6cSBarry Smith PetscErrorCode DMSetPointSF(DM dm, PetscSF sf) 36830adebc6cSBarry Smith { 3684057b4bcdSMatthew G Knepley PetscErrorCode ierr; 3685057b4bcdSMatthew G Knepley 3686057b4bcdSMatthew G Knepley PetscFunctionBegin; 3687057b4bcdSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3688057b4bcdSMatthew G Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 1); 3689057b4bcdSMatthew G Knepley ierr = PetscSFDestroy(&dm->sf);CHKERRQ(ierr); 3690057b4bcdSMatthew G Knepley ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr); 3691057b4bcdSMatthew G Knepley dm->sf = sf; 3692057b4bcdSMatthew G Knepley PetscFunctionReturn(0); 3693057b4bcdSMatthew G Knepley } 3694057b4bcdSMatthew G Knepley 36952764a2aaSMatthew G. Knepley /*@ 36962764a2aaSMatthew G. Knepley DMGetDS - Get the PetscDS 36972764a2aaSMatthew G. Knepley 36982764a2aaSMatthew G. Knepley Input Parameter: 36992764a2aaSMatthew G. Knepley . dm - The DM 37002764a2aaSMatthew G. Knepley 37012764a2aaSMatthew G. Knepley Output Parameter: 37022764a2aaSMatthew G. Knepley . prob - The PetscDS 37032764a2aaSMatthew G. Knepley 37042764a2aaSMatthew G. Knepley Level: developer 37052764a2aaSMatthew G. Knepley 37062764a2aaSMatthew G. Knepley .seealso: DMSetDS() 37072764a2aaSMatthew G. Knepley @*/ 37082764a2aaSMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *prob) 3709af122d2aSMatthew G Knepley { 3710af122d2aSMatthew G Knepley PetscFunctionBegin; 3711af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37120f21e855SMatthew G. Knepley PetscValidPointer(prob, 2); 37130f21e855SMatthew G. Knepley *prob = dm->prob; 37140f21e855SMatthew G. Knepley PetscFunctionReturn(0); 37150f21e855SMatthew G. Knepley } 37160f21e855SMatthew G. Knepley 37172764a2aaSMatthew G. Knepley /*@ 37182764a2aaSMatthew G. Knepley DMSetDS - Set the PetscDS 37192764a2aaSMatthew G. Knepley 37202764a2aaSMatthew G. Knepley Input Parameters: 37212764a2aaSMatthew G. Knepley + dm - The DM 37222764a2aaSMatthew G. Knepley - prob - The PetscDS 37232764a2aaSMatthew G. Knepley 37242764a2aaSMatthew G. Knepley Level: developer 37252764a2aaSMatthew G. Knepley 37262764a2aaSMatthew G. Knepley .seealso: DMGetDS() 37272764a2aaSMatthew G. Knepley @*/ 37282764a2aaSMatthew G. Knepley PetscErrorCode DMSetDS(DM dm, PetscDS prob) 37290f21e855SMatthew G. Knepley { 37300f21e855SMatthew G. Knepley PetscErrorCode ierr; 37310f21e855SMatthew G. Knepley 37320f21e855SMatthew G. Knepley PetscFunctionBegin; 37330f21e855SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37342764a2aaSMatthew G. Knepley PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 2); 373537316535SToby Isaac ierr = PetscObjectReference((PetscObject) prob);CHKERRQ(ierr); 37362764a2aaSMatthew G. Knepley ierr = PetscDSDestroy(&dm->prob);CHKERRQ(ierr); 37370f21e855SMatthew G. Knepley dm->prob = prob; 37380f21e855SMatthew G. Knepley PetscFunctionReturn(0); 37390f21e855SMatthew G. Knepley } 37400f21e855SMatthew G. Knepley 37410f21e855SMatthew G. Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields) 37420f21e855SMatthew G. Knepley { 37430f21e855SMatthew G. Knepley PetscErrorCode ierr; 37440f21e855SMatthew G. Knepley 37450f21e855SMatthew G. Knepley PetscFunctionBegin; 37460f21e855SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37472764a2aaSMatthew G. Knepley ierr = PetscDSGetNumFields(dm->prob, numFields);CHKERRQ(ierr); 3748af122d2aSMatthew G Knepley PetscFunctionReturn(0); 3749af122d2aSMatthew G Knepley } 3750af122d2aSMatthew G Knepley 3751af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields) 3752af122d2aSMatthew G Knepley { 37530f21e855SMatthew G. Knepley PetscInt Nf, f; 3754af122d2aSMatthew G Knepley PetscErrorCode ierr; 3755af122d2aSMatthew G Knepley 3756af122d2aSMatthew G Knepley PetscFunctionBegin; 3757af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37582764a2aaSMatthew G. Knepley ierr = PetscDSGetNumFields(dm->prob, &Nf);CHKERRQ(ierr); 37590f21e855SMatthew G. Knepley for (f = Nf; f < numFields; ++f) { 37600f21e855SMatthew G. Knepley PetscContainer obj; 37610f21e855SMatthew G. Knepley 37620f21e855SMatthew G. Knepley ierr = PetscContainerCreate(PetscObjectComm((PetscObject) dm), &obj);CHKERRQ(ierr); 37632764a2aaSMatthew G. Knepley ierr = PetscDSSetDiscretization(dm->prob, f, (PetscObject) obj);CHKERRQ(ierr); 37640f21e855SMatthew G. Knepley ierr = PetscContainerDestroy(&obj);CHKERRQ(ierr); 3765af122d2aSMatthew G Knepley } 3766af122d2aSMatthew G Knepley PetscFunctionReturn(0); 3767af122d2aSMatthew G Knepley } 3768af122d2aSMatthew G Knepley 3769c1929be8SMatthew G. Knepley /*@ 3770c1929be8SMatthew G. Knepley DMGetField - Return the discretization object for a given DM field 3771c1929be8SMatthew G. Knepley 3772c1929be8SMatthew G. Knepley Not collective 3773c1929be8SMatthew G. Knepley 3774c1929be8SMatthew G. Knepley Input Parameters: 3775c1929be8SMatthew G. Knepley + dm - The DM 3776c1929be8SMatthew G. Knepley - f - The field number 3777c1929be8SMatthew G. Knepley 3778c1929be8SMatthew G. Knepley Output Parameter: 3779c1929be8SMatthew G. Knepley . field - The discretization object 3780c1929be8SMatthew G. Knepley 3781c1929be8SMatthew G. Knepley Level: developer 3782c1929be8SMatthew G. Knepley 3783c1929be8SMatthew G. Knepley .seealso: DMSetField() 3784c1929be8SMatthew G. Knepley @*/ 3785af122d2aSMatthew G Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, PetscObject *field) 3786af122d2aSMatthew G Knepley { 37870f21e855SMatthew G. Knepley PetscErrorCode ierr; 37880f21e855SMatthew G. Knepley 3789af122d2aSMatthew G Knepley PetscFunctionBegin; 3790af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37912764a2aaSMatthew G. Knepley ierr = PetscDSGetDiscretization(dm->prob, f, field);CHKERRQ(ierr); 3792decb47aaSMatthew G. Knepley PetscFunctionReturn(0); 3793decb47aaSMatthew G. Knepley } 3794decb47aaSMatthew G. Knepley 3795c1929be8SMatthew G. Knepley /*@ 3796c1929be8SMatthew G. Knepley DMSetField - Set the discretization object for a given DM field 3797c1929be8SMatthew G. Knepley 3798c1929be8SMatthew G. Knepley Logically collective on DM 3799c1929be8SMatthew G. Knepley 3800c1929be8SMatthew G. Knepley Input Parameters: 3801c1929be8SMatthew G. Knepley + dm - The DM 3802c1929be8SMatthew G. Knepley . f - The field number 3803c1929be8SMatthew G. Knepley - field - The discretization object 3804c1929be8SMatthew G. Knepley 3805c1929be8SMatthew G. Knepley Level: developer 3806c1929be8SMatthew G. Knepley 3807c1929be8SMatthew G. Knepley .seealso: DMGetField() 3808c1929be8SMatthew G. Knepley @*/ 3809decb47aaSMatthew G. Knepley PetscErrorCode DMSetField(DM dm, PetscInt f, PetscObject field) 3810decb47aaSMatthew G. Knepley { 3811decb47aaSMatthew G. Knepley PetscErrorCode ierr; 3812decb47aaSMatthew G. Knepley 3813decb47aaSMatthew G. Knepley PetscFunctionBegin; 3814decb47aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 38152764a2aaSMatthew G. Knepley ierr = PetscDSSetDiscretization(dm->prob, f, field);CHKERRQ(ierr); 3816af122d2aSMatthew G Knepley PetscFunctionReturn(0); 3817af122d2aSMatthew G Knepley } 38186636e97aSMatthew G Knepley 3819b64e0483SPeter Brune PetscErrorCode DMRestrictHook_Coordinates(DM dm,DM dmc,void *ctx) 3820b64e0483SPeter Brune { 3821b64e0483SPeter Brune DM dm_coord,dmc_coord; 3822b64e0483SPeter Brune PetscErrorCode ierr; 3823b64e0483SPeter Brune Vec coords,ccoords; 38246dbf9973SLawrence Mitchell Mat inject; 3825b64e0483SPeter Brune PetscFunctionBegin; 3826b64e0483SPeter Brune ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr); 3827b64e0483SPeter Brune ierr = DMGetCoordinateDM(dmc,&dmc_coord);CHKERRQ(ierr); 3828b64e0483SPeter Brune ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr); 3829b64e0483SPeter Brune ierr = DMGetCoordinates(dmc,&ccoords);CHKERRQ(ierr); 3830b64e0483SPeter Brune if (coords && !ccoords) { 3831b64e0483SPeter Brune ierr = DMCreateGlobalVector(dmc_coord,&ccoords);CHKERRQ(ierr); 38326668ed41SLisandro Dalcin ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr); 38336dbf9973SLawrence Mitchell ierr = DMCreateInjection(dmc_coord,dm_coord,&inject);CHKERRQ(ierr); 38342adcf181SLawrence Mitchell ierr = MatRestrict(inject,coords,ccoords);CHKERRQ(ierr); 38356dbf9973SLawrence Mitchell ierr = MatDestroy(&inject);CHKERRQ(ierr); 3836b64e0483SPeter Brune ierr = DMSetCoordinates(dmc,ccoords);CHKERRQ(ierr); 3837b64e0483SPeter Brune ierr = VecDestroy(&ccoords);CHKERRQ(ierr); 3838b64e0483SPeter Brune } 3839b64e0483SPeter Brune PetscFunctionReturn(0); 3840b64e0483SPeter Brune } 3841b64e0483SPeter Brune 384203dadc2fSPeter Brune static PetscErrorCode DMSubDomainHook_Coordinates(DM dm,DM subdm,void *ctx) 384303dadc2fSPeter Brune { 384403dadc2fSPeter Brune DM dm_coord,subdm_coord; 384503dadc2fSPeter Brune PetscErrorCode ierr; 384603dadc2fSPeter Brune Vec coords,ccoords,clcoords; 384703dadc2fSPeter Brune VecScatter *scat_i,*scat_g; 384803dadc2fSPeter Brune PetscFunctionBegin; 384903dadc2fSPeter Brune ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr); 385003dadc2fSPeter Brune ierr = DMGetCoordinateDM(subdm,&subdm_coord);CHKERRQ(ierr); 385103dadc2fSPeter Brune ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr); 385203dadc2fSPeter Brune ierr = DMGetCoordinates(subdm,&ccoords);CHKERRQ(ierr); 385303dadc2fSPeter Brune if (coords && !ccoords) { 385403dadc2fSPeter Brune ierr = DMCreateGlobalVector(subdm_coord,&ccoords);CHKERRQ(ierr); 38556668ed41SLisandro Dalcin ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr); 385603dadc2fSPeter Brune ierr = DMCreateLocalVector(subdm_coord,&clcoords);CHKERRQ(ierr); 385724640c55SToby Isaac ierr = PetscObjectSetName((PetscObject)clcoords,"coordinates");CHKERRQ(ierr); 385803dadc2fSPeter Brune ierr = DMCreateDomainDecompositionScatters(dm_coord,1,&subdm_coord,NULL,&scat_i,&scat_g);CHKERRQ(ierr); 385903dadc2fSPeter Brune ierr = VecScatterBegin(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 386003dadc2fSPeter Brune ierr = VecScatterBegin(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 386103dadc2fSPeter Brune ierr = VecScatterEnd(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 386203dadc2fSPeter Brune ierr = VecScatterEnd(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 386303dadc2fSPeter Brune ierr = DMSetCoordinates(subdm,ccoords);CHKERRQ(ierr); 386403dadc2fSPeter Brune ierr = DMSetCoordinatesLocal(subdm,clcoords);CHKERRQ(ierr); 386503dadc2fSPeter Brune ierr = VecScatterDestroy(&scat_i[0]);CHKERRQ(ierr); 386603dadc2fSPeter Brune ierr = VecScatterDestroy(&scat_g[0]);CHKERRQ(ierr); 386703dadc2fSPeter Brune ierr = VecDestroy(&ccoords);CHKERRQ(ierr); 386803dadc2fSPeter Brune ierr = VecDestroy(&clcoords);CHKERRQ(ierr); 386903dadc2fSPeter Brune ierr = PetscFree(scat_i);CHKERRQ(ierr); 387003dadc2fSPeter Brune ierr = PetscFree(scat_g);CHKERRQ(ierr); 387103dadc2fSPeter Brune } 387203dadc2fSPeter Brune PetscFunctionReturn(0); 387303dadc2fSPeter Brune } 387403dadc2fSPeter Brune 3875c73cfb54SMatthew G. Knepley /*@ 3876c73cfb54SMatthew G. Knepley DMGetDimension - Return the topological dimension of the DM 3877c73cfb54SMatthew G. Knepley 3878c73cfb54SMatthew G. Knepley Not collective 3879c73cfb54SMatthew G. Knepley 3880c73cfb54SMatthew G. Knepley Input Parameter: 3881c73cfb54SMatthew G. Knepley . dm - The DM 3882c73cfb54SMatthew G. Knepley 3883c73cfb54SMatthew G. Knepley Output Parameter: 3884c73cfb54SMatthew G. Knepley . dim - The topological dimension 3885c73cfb54SMatthew G. Knepley 3886c73cfb54SMatthew G. Knepley Level: beginner 3887c73cfb54SMatthew G. Knepley 3888c73cfb54SMatthew G. Knepley .seealso: DMSetDimension(), DMCreate() 3889c73cfb54SMatthew G. Knepley @*/ 3890c73cfb54SMatthew G. Knepley PetscErrorCode DMGetDimension(DM dm, PetscInt *dim) 3891c73cfb54SMatthew G. Knepley { 3892c73cfb54SMatthew G. Knepley PetscFunctionBegin; 3893c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3894c73cfb54SMatthew G. Knepley PetscValidPointer(dim, 2); 3895c73cfb54SMatthew G. Knepley *dim = dm->dim; 3896c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 3897c73cfb54SMatthew G. Knepley } 3898c73cfb54SMatthew G. Knepley 3899c73cfb54SMatthew G. Knepley /*@ 3900c73cfb54SMatthew G. Knepley DMSetDimension - Set the topological dimension of the DM 3901c73cfb54SMatthew G. Knepley 3902c73cfb54SMatthew G. Knepley Collective on dm 3903c73cfb54SMatthew G. Knepley 3904c73cfb54SMatthew G. Knepley Input Parameters: 3905c73cfb54SMatthew G. Knepley + dm - The DM 3906c73cfb54SMatthew G. Knepley - dim - The topological dimension 3907c73cfb54SMatthew G. Knepley 3908c73cfb54SMatthew G. Knepley Level: beginner 3909c73cfb54SMatthew G. Knepley 3910c73cfb54SMatthew G. Knepley .seealso: DMGetDimension(), DMCreate() 3911c73cfb54SMatthew G. Knepley @*/ 3912c73cfb54SMatthew G. Knepley PetscErrorCode DMSetDimension(DM dm, PetscInt dim) 3913c73cfb54SMatthew G. Knepley { 3914c73cfb54SMatthew G. Knepley PetscFunctionBegin; 3915c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3916c73cfb54SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 3917c73cfb54SMatthew G. Knepley dm->dim = dim; 3918c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 3919c73cfb54SMatthew G. Knepley } 3920c73cfb54SMatthew G. Knepley 3921793f3fe5SMatthew G. Knepley /*@ 3922793f3fe5SMatthew G. Knepley DMGetDimPoints - Get the half-open interval for all points of a given dimension 3923793f3fe5SMatthew G. Knepley 3924793f3fe5SMatthew G. Knepley Collective on DM 3925793f3fe5SMatthew G. Knepley 3926793f3fe5SMatthew G. Knepley Input Parameters: 3927793f3fe5SMatthew G. Knepley + dm - the DM 3928793f3fe5SMatthew G. Knepley - dim - the dimension 3929793f3fe5SMatthew G. Knepley 3930793f3fe5SMatthew G. Knepley Output Parameters: 3931793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension 3932793f3fe5SMatthew G. Knepley . pEnd - The first point following points of the given dimension 3933793f3fe5SMatthew G. Knepley 3934793f3fe5SMatthew G. Knepley Note: 3935793f3fe5SMatthew G. Knepley The points are vertices in the Hasse diagram encoding the topology. This is explained in 3936793f3fe5SMatthew G. Knepley http://arxiv.org/abs/0908.4427. If not points exist of this dimension in the storage scheme, 3937793f3fe5SMatthew G. Knepley then the interval is empty. 3938793f3fe5SMatthew G. Knepley 3939793f3fe5SMatthew G. Knepley Level: intermediate 3940793f3fe5SMatthew G. Knepley 3941793f3fe5SMatthew G. Knepley .keywords: point, Hasse Diagram, dimension 3942793f3fe5SMatthew G. Knepley .seealso: DMPLEX, DMPlexGetDepthStratum(), DMPlexGetHeightStratum() 3943793f3fe5SMatthew G. Knepley @*/ 3944793f3fe5SMatthew G. Knepley PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 3945793f3fe5SMatthew G. Knepley { 3946793f3fe5SMatthew G. Knepley PetscInt d; 3947793f3fe5SMatthew G. Knepley PetscErrorCode ierr; 3948793f3fe5SMatthew G. Knepley 3949793f3fe5SMatthew G. Knepley PetscFunctionBegin; 3950793f3fe5SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3951793f3fe5SMatthew G. Knepley ierr = DMGetDimension(dm, &d);CHKERRQ(ierr); 3952793f3fe5SMatthew G. Knepley if ((dim < 0) || (dim > d)) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %d 1", dim, d); 3953793f3fe5SMatthew G. Knepley ierr = (*dm->ops->getdimpoints)(dm, dim, pStart, pEnd);CHKERRQ(ierr); 3954793f3fe5SMatthew G. Knepley PetscFunctionReturn(0); 3955793f3fe5SMatthew G. Knepley } 3956793f3fe5SMatthew G. Knepley 39576636e97aSMatthew G Knepley /*@ 39586636e97aSMatthew G Knepley DMSetCoordinates - Sets into the DM a global vector that holds the coordinates 39596636e97aSMatthew G Knepley 39606636e97aSMatthew G Knepley Collective on DM 39616636e97aSMatthew G Knepley 39626636e97aSMatthew G Knepley Input Parameters: 39636636e97aSMatthew G Knepley + dm - the DM 39646636e97aSMatthew G Knepley - c - coordinate vector 39656636e97aSMatthew G Knepley 39666636e97aSMatthew G Knepley Note: 39676636e97aSMatthew G Knepley The coordinates do include those for ghost points, which are in the local vector 39686636e97aSMatthew G Knepley 39696636e97aSMatthew G Knepley Level: intermediate 39706636e97aSMatthew G Knepley 39716636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates 39726636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLoca(), DMGetCoordinateDM() 39736636e97aSMatthew G Knepley @*/ 39746636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c) 39756636e97aSMatthew G Knepley { 39766636e97aSMatthew G Knepley PetscErrorCode ierr; 39776636e97aSMatthew G Knepley 39786636e97aSMatthew G Knepley PetscFunctionBegin; 39796636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 39806636e97aSMatthew G Knepley PetscValidHeaderSpecific(c,VEC_CLASSID,2); 39816636e97aSMatthew G Knepley ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr); 39826636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr); 39836636e97aSMatthew G Knepley dm->coordinates = c; 39846636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr); 3985b64e0483SPeter Brune ierr = DMCoarsenHookAdd(dm,DMRestrictHook_Coordinates,NULL,NULL);CHKERRQ(ierr); 398603dadc2fSPeter Brune ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_Coordinates,NULL,NULL);CHKERRQ(ierr); 39876636e97aSMatthew G Knepley PetscFunctionReturn(0); 39886636e97aSMatthew G Knepley } 39896636e97aSMatthew G Knepley 39906636e97aSMatthew G Knepley /*@ 39916636e97aSMatthew G Knepley DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates 39926636e97aSMatthew G Knepley 39936636e97aSMatthew G Knepley Collective on DM 39946636e97aSMatthew G Knepley 39956636e97aSMatthew G Knepley Input Parameters: 39966636e97aSMatthew G Knepley + dm - the DM 39976636e97aSMatthew G Knepley - c - coordinate vector 39986636e97aSMatthew G Knepley 39996636e97aSMatthew G Knepley Note: 40006636e97aSMatthew G Knepley The coordinates of ghost points can be set using DMSetCoordinates() 40016636e97aSMatthew G Knepley followed by DMGetCoordinatesLocal(). This is intended to enable the 40026636e97aSMatthew G Knepley setting of ghost coordinates outside of the domain. 40036636e97aSMatthew G Knepley 40046636e97aSMatthew G Knepley Level: intermediate 40056636e97aSMatthew G Knepley 40066636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates 40076636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM() 40086636e97aSMatthew G Knepley @*/ 40096636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c) 40106636e97aSMatthew G Knepley { 40116636e97aSMatthew G Knepley PetscErrorCode ierr; 40126636e97aSMatthew G Knepley 40136636e97aSMatthew G Knepley PetscFunctionBegin; 40146636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 40156636e97aSMatthew G Knepley PetscValidHeaderSpecific(c,VEC_CLASSID,2); 40166636e97aSMatthew G Knepley ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr); 40176636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr); 40188865f1eaSKarl Rupp 40196636e97aSMatthew G Knepley dm->coordinatesLocal = c; 40208865f1eaSKarl Rupp 40216636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr); 40226636e97aSMatthew G Knepley PetscFunctionReturn(0); 40236636e97aSMatthew G Knepley } 40246636e97aSMatthew G Knepley 40256636e97aSMatthew G Knepley /*@ 40266636e97aSMatthew G Knepley DMGetCoordinates - Gets a global vector with the coordinates associated with the DM. 40276636e97aSMatthew G Knepley 40286636e97aSMatthew G Knepley Not Collective 40296636e97aSMatthew G Knepley 40306636e97aSMatthew G Knepley Input Parameter: 40316636e97aSMatthew G Knepley . dm - the DM 40326636e97aSMatthew G Knepley 40336636e97aSMatthew G Knepley Output Parameter: 40346636e97aSMatthew G Knepley . c - global coordinate vector 40356636e97aSMatthew G Knepley 40366636e97aSMatthew G Knepley Note: 40376636e97aSMatthew G Knepley This is a borrowed reference, so the user should NOT destroy this vector 40386636e97aSMatthew G Knepley 40396636e97aSMatthew G Knepley Each process has only the local coordinates (does NOT have the ghost coordinates). 40406636e97aSMatthew G Knepley 40416636e97aSMatthew G Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 40426636e97aSMatthew G Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 40436636e97aSMatthew G Knepley 40446636e97aSMatthew G Knepley Level: intermediate 40456636e97aSMatthew G Knepley 40466636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates 40476636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM() 40486636e97aSMatthew G Knepley @*/ 40496636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c) 40506636e97aSMatthew G Knepley { 40516636e97aSMatthew G Knepley PetscErrorCode ierr; 40526636e97aSMatthew G Knepley 40536636e97aSMatthew G Knepley PetscFunctionBegin; 40546636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 40556636e97aSMatthew G Knepley PetscValidPointer(c,2); 40561f588964SMatthew G Knepley if (!dm->coordinates && dm->coordinatesLocal) { 40570298fd71SBarry Smith DM cdm = NULL; 40586636e97aSMatthew G Knepley 40596636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 40606636e97aSMatthew G Knepley ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr); 40616636e97aSMatthew G Knepley ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr); 40626636e97aSMatthew G Knepley ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr); 40636636e97aSMatthew G Knepley ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr); 40646636e97aSMatthew G Knepley } 40656636e97aSMatthew G Knepley *c = dm->coordinates; 40666636e97aSMatthew G Knepley PetscFunctionReturn(0); 40676636e97aSMatthew G Knepley } 40686636e97aSMatthew G Knepley 40696636e97aSMatthew G Knepley /*@ 40706636e97aSMatthew G Knepley DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM. 40716636e97aSMatthew G Knepley 40726636e97aSMatthew G Knepley Collective on DM 40736636e97aSMatthew G Knepley 40746636e97aSMatthew G Knepley Input Parameter: 40756636e97aSMatthew G Knepley . dm - the DM 40766636e97aSMatthew G Knepley 40776636e97aSMatthew G Knepley Output Parameter: 40786636e97aSMatthew G Knepley . c - coordinate vector 40796636e97aSMatthew G Knepley 40806636e97aSMatthew G Knepley Note: 40816636e97aSMatthew G Knepley This is a borrowed reference, so the user should NOT destroy this vector 40826636e97aSMatthew G Knepley 40836636e97aSMatthew G Knepley Each process has the local and ghost coordinates 40846636e97aSMatthew G Knepley 40856636e97aSMatthew G Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 40866636e97aSMatthew G Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 40876636e97aSMatthew G Knepley 40886636e97aSMatthew G Knepley Level: intermediate 40896636e97aSMatthew G Knepley 40906636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates 40916636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM() 40926636e97aSMatthew G Knepley @*/ 40936636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c) 40946636e97aSMatthew G Knepley { 40956636e97aSMatthew G Knepley PetscErrorCode ierr; 40966636e97aSMatthew G Knepley 40976636e97aSMatthew G Knepley PetscFunctionBegin; 40986636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 40996636e97aSMatthew G Knepley PetscValidPointer(c,2); 41001f588964SMatthew G Knepley if (!dm->coordinatesLocal && dm->coordinates) { 41010298fd71SBarry Smith DM cdm = NULL; 41026636e97aSMatthew G Knepley 41036636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 41046636e97aSMatthew G Knepley ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr); 41056636e97aSMatthew G Knepley ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr); 41066636e97aSMatthew G Knepley ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr); 41076636e97aSMatthew G Knepley ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr); 41086636e97aSMatthew G Knepley } 41096636e97aSMatthew G Knepley *c = dm->coordinatesLocal; 41106636e97aSMatthew G Knepley PetscFunctionReturn(0); 41116636e97aSMatthew G Knepley } 41126636e97aSMatthew G Knepley 41136636e97aSMatthew G Knepley /*@ 41141cfe2091SMatthew G. Knepley DMGetCoordinateDM - Gets the DM that prescribes coordinate layout and scatters between global and local coordinates 41156636e97aSMatthew G Knepley 41166636e97aSMatthew G Knepley Collective on DM 41176636e97aSMatthew G Knepley 41186636e97aSMatthew G Knepley Input Parameter: 41196636e97aSMatthew G Knepley . dm - the DM 41206636e97aSMatthew G Knepley 41216636e97aSMatthew G Knepley Output Parameter: 41226636e97aSMatthew G Knepley . cdm - coordinate DM 41236636e97aSMatthew G Knepley 41246636e97aSMatthew G Knepley Level: intermediate 41256636e97aSMatthew G Knepley 41266636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates 41271cfe2091SMatthew G. Knepley .seealso: DMSetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal() 41286636e97aSMatthew G Knepley @*/ 41296636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm) 41306636e97aSMatthew G Knepley { 41316636e97aSMatthew G Knepley PetscErrorCode ierr; 41326636e97aSMatthew G Knepley 41336636e97aSMatthew G Knepley PetscFunctionBegin; 41346636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 41356636e97aSMatthew G Knepley PetscValidPointer(cdm,2); 41366636e97aSMatthew G Knepley if (!dm->coordinateDM) { 413782f516ccSBarry Smith if (!dm->ops->createcoordinatedm) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unable to create coordinates for this DM"); 41386636e97aSMatthew G Knepley ierr = (*dm->ops->createcoordinatedm)(dm, &dm->coordinateDM);CHKERRQ(ierr); 41396636e97aSMatthew G Knepley } 41406636e97aSMatthew G Knepley *cdm = dm->coordinateDM; 41416636e97aSMatthew G Knepley PetscFunctionReturn(0); 41426636e97aSMatthew G Knepley } 4143e87bb0d3SMatthew G Knepley 41441cfe2091SMatthew G. Knepley /*@ 41451cfe2091SMatthew G. Knepley DMSetCoordinateDM - Sets the DM that prescribes coordinate layout and scatters between global and local coordinates 41461cfe2091SMatthew G. Knepley 41471cfe2091SMatthew G. Knepley Logically Collective on DM 41481cfe2091SMatthew G. Knepley 41491cfe2091SMatthew G. Knepley Input Parameters: 41501cfe2091SMatthew G. Knepley + dm - the DM 41511cfe2091SMatthew G. Knepley - cdm - coordinate DM 41521cfe2091SMatthew G. Knepley 41531cfe2091SMatthew G. Knepley Level: intermediate 41541cfe2091SMatthew G. Knepley 41551cfe2091SMatthew G. Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates 41561cfe2091SMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal() 41571cfe2091SMatthew G. Knepley @*/ 41581cfe2091SMatthew G. Knepley PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm) 41591cfe2091SMatthew G. Knepley { 41601cfe2091SMatthew G. Knepley PetscErrorCode ierr; 41611cfe2091SMatthew G. Knepley 41621cfe2091SMatthew G. Knepley PetscFunctionBegin; 41631cfe2091SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 41641cfe2091SMatthew G. Knepley PetscValidHeaderSpecific(cdm,DM_CLASSID,2); 4165f26b38b9SToby Isaac ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr); 41661cfe2091SMatthew G. Knepley ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr); 41671cfe2091SMatthew G. Knepley dm->coordinateDM = cdm; 41681cfe2091SMatthew G. Knepley PetscFunctionReturn(0); 41691cfe2091SMatthew G. Knepley } 41701cfe2091SMatthew G. Knepley 417146e270d4SMatthew G. Knepley /*@ 417246e270d4SMatthew G. Knepley DMGetCoordinateDim - Retrieve the dimension of embedding space for coordinate values. 417346e270d4SMatthew G. Knepley 417446e270d4SMatthew G. Knepley Not Collective 417546e270d4SMatthew G. Knepley 417646e270d4SMatthew G. Knepley Input Parameter: 417746e270d4SMatthew G. Knepley . dm - The DM object 417846e270d4SMatthew G. Knepley 417946e270d4SMatthew G. Knepley Output Parameter: 418046e270d4SMatthew G. Knepley . dim - The embedding dimension 418146e270d4SMatthew G. Knepley 418246e270d4SMatthew G. Knepley Level: intermediate 418346e270d4SMatthew G. Knepley 418446e270d4SMatthew G. Knepley .keywords: mesh, coordinates 418546e270d4SMatthew G. Knepley .seealso: DMSetCoordinateDim(), DMGetCoordinateSection(), DMGetCoordinateDM(), DMGetDefaultSection(), DMSetDefaultSection() 418646e270d4SMatthew G. Knepley @*/ 418746e270d4SMatthew G. Knepley PetscErrorCode DMGetCoordinateDim(DM dm, PetscInt *dim) 418846e270d4SMatthew G. Knepley { 418946e270d4SMatthew G. Knepley PetscFunctionBegin; 419046e270d4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 419146e270d4SMatthew G. Knepley PetscValidPointer(dim, 2); 41929a9a41abSToby Isaac if (dm->dimEmbed == PETSC_DEFAULT) { 41939a9a41abSToby Isaac dm->dimEmbed = dm->dim; 41949a9a41abSToby Isaac } 419546e270d4SMatthew G. Knepley *dim = dm->dimEmbed; 419646e270d4SMatthew G. Knepley PetscFunctionReturn(0); 419746e270d4SMatthew G. Knepley } 419846e270d4SMatthew G. Knepley 419946e270d4SMatthew G. Knepley /*@ 420046e270d4SMatthew G. Knepley DMSetCoordinateDim - Set the dimension of the embedding space for coordinate values. 420146e270d4SMatthew G. Knepley 420246e270d4SMatthew G. Knepley Not Collective 420346e270d4SMatthew G. Knepley 420446e270d4SMatthew G. Knepley Input Parameters: 420546e270d4SMatthew G. Knepley + dm - The DM object 420646e270d4SMatthew G. Knepley - dim - The embedding dimension 420746e270d4SMatthew G. Knepley 420846e270d4SMatthew G. Knepley Level: intermediate 420946e270d4SMatthew G. Knepley 421046e270d4SMatthew G. Knepley .keywords: mesh, coordinates 421146e270d4SMatthew G. Knepley .seealso: DMGetCoordinateDim(), DMSetCoordinateSection(), DMGetCoordinateSection(), DMGetDefaultSection(), DMSetDefaultSection() 421246e270d4SMatthew G. Knepley @*/ 421346e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateDim(DM dm, PetscInt dim) 421446e270d4SMatthew G. Knepley { 421546e270d4SMatthew G. Knepley PetscFunctionBegin; 421646e270d4SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 421746e270d4SMatthew G. Knepley dm->dimEmbed = dim; 421846e270d4SMatthew G. Knepley PetscFunctionReturn(0); 421946e270d4SMatthew G. Knepley } 422046e270d4SMatthew G. Knepley 4221e8abe2deSMatthew G. Knepley /*@ 4222e8abe2deSMatthew G. Knepley DMGetCoordinateSection - Retrieve the layout of coordinate values over the mesh. 4223e8abe2deSMatthew G. Knepley 4224e8abe2deSMatthew G. Knepley Not Collective 4225e8abe2deSMatthew G. Knepley 4226e8abe2deSMatthew G. Knepley Input Parameter: 4227e8abe2deSMatthew G. Knepley . dm - The DM object 4228e8abe2deSMatthew G. Knepley 4229e8abe2deSMatthew G. Knepley Output Parameter: 4230e8abe2deSMatthew G. Knepley . section - The PetscSection object 4231e8abe2deSMatthew G. Knepley 4232e8abe2deSMatthew G. Knepley Level: intermediate 4233e8abe2deSMatthew G. Knepley 4234e8abe2deSMatthew G. Knepley .keywords: mesh, coordinates 4235e8abe2deSMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMGetDefaultSection(), DMSetDefaultSection() 4236e8abe2deSMatthew G. Knepley @*/ 4237e8abe2deSMatthew G. Knepley PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section) 4238e8abe2deSMatthew G. Knepley { 4239e8abe2deSMatthew G. Knepley DM cdm; 4240e8abe2deSMatthew G. Knepley PetscErrorCode ierr; 4241e8abe2deSMatthew G. Knepley 4242e8abe2deSMatthew G. Knepley PetscFunctionBegin; 4243e8abe2deSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4244e8abe2deSMatthew G. Knepley PetscValidPointer(section, 2); 4245e8abe2deSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 4246e8abe2deSMatthew G. Knepley ierr = DMGetDefaultSection(cdm, section);CHKERRQ(ierr); 4247e8abe2deSMatthew G. Knepley PetscFunctionReturn(0); 4248e8abe2deSMatthew G. Knepley } 4249e8abe2deSMatthew G. Knepley 4250e8abe2deSMatthew G. Knepley /*@ 4251e8abe2deSMatthew G. Knepley DMSetCoordinateSection - Set the layout of coordinate values over the mesh. 4252e8abe2deSMatthew G. Knepley 4253e8abe2deSMatthew G. Knepley Not Collective 4254e8abe2deSMatthew G. Knepley 4255e8abe2deSMatthew G. Knepley Input Parameters: 4256e8abe2deSMatthew G. Knepley + dm - The DM object 425746e270d4SMatthew G. Knepley . dim - The embedding dimension, or PETSC_DETERMINE 4258e8abe2deSMatthew G. Knepley - section - The PetscSection object 4259e8abe2deSMatthew G. Knepley 4260e8abe2deSMatthew G. Knepley Level: intermediate 4261e8abe2deSMatthew G. Knepley 4262e8abe2deSMatthew G. Knepley .keywords: mesh, coordinates 4263e8abe2deSMatthew G. Knepley .seealso: DMGetCoordinateSection(), DMGetDefaultSection(), DMSetDefaultSection() 4264e8abe2deSMatthew G. Knepley @*/ 426546e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateSection(DM dm, PetscInt dim, PetscSection section) 4266e8abe2deSMatthew G. Knepley { 4267e8abe2deSMatthew G. Knepley DM cdm; 4268e8abe2deSMatthew G. Knepley PetscErrorCode ierr; 4269e8abe2deSMatthew G. Knepley 4270e8abe2deSMatthew G. Knepley PetscFunctionBegin; 4271e8abe2deSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 427246e270d4SMatthew G. Knepley PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,3); 4273e8abe2deSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 4274e8abe2deSMatthew G. Knepley ierr = DMSetDefaultSection(cdm, section);CHKERRQ(ierr); 427546e270d4SMatthew G. Knepley if (dim == PETSC_DETERMINE) { 42764c1069a6SMatthew G. Knepley PetscInt d = PETSC_DEFAULT; 427746e270d4SMatthew G. Knepley PetscInt pStart, pEnd, vStart, vEnd, v, dd; 427846e270d4SMatthew G. Knepley 427946e270d4SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 428046e270d4SMatthew G. Knepley ierr = DMGetDimPoints(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 428146e270d4SMatthew G. Knepley pStart = PetscMax(vStart, pStart); 428246e270d4SMatthew G. Knepley pEnd = PetscMin(vEnd, pEnd); 428346e270d4SMatthew G. Knepley for (v = pStart; v < pEnd; ++v) { 428446e270d4SMatthew G. Knepley ierr = PetscSectionGetDof(section, v, &dd);CHKERRQ(ierr); 428546e270d4SMatthew G. Knepley if (dd) {d = dd; break;} 428646e270d4SMatthew G. Knepley } 42876be882deSMatthew G. Knepley if (d < 0) d = PETSC_DEFAULT; 428846e270d4SMatthew G. Knepley ierr = DMSetCoordinateDim(dm, d);CHKERRQ(ierr); 428946e270d4SMatthew G. Knepley } 4290e8abe2deSMatthew G. Knepley PetscFunctionReturn(0); 4291e8abe2deSMatthew G. Knepley } 4292e8abe2deSMatthew G. Knepley 42935dc8c3f7SMatthew G. Knepley /*@C 42945dc8c3f7SMatthew G. Knepley DMSetPeriodicity - Set the description of mesh periodicity 42955dc8c3f7SMatthew G. Knepley 42965dc8c3f7SMatthew G. Knepley Input Parameters: 42975dc8c3f7SMatthew G. Knepley + dm - The DM object 42985dc8c3f7SMatthew G. Knepley . maxCell - Over distances greater than this, we can assume a point has crossed over to another sheet, when trying to localize cell coordinates 42995dc8c3f7SMatthew G. Knepley . L - If we assume the mesh is a torus, this is the length of each coordinate 43005dc8c3f7SMatthew G. Knepley - bd - This describes the type of periodicity in each topological dimension 43015dc8c3f7SMatthew G. Knepley 43025dc8c3f7SMatthew G. Knepley Level: developer 43035dc8c3f7SMatthew G. Knepley 43045dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity() 43055dc8c3f7SMatthew G. Knepley @*/ 43065dc8c3f7SMatthew G. Knepley PetscErrorCode DMGetPeriodicity(DM dm, const PetscReal **maxCell, const PetscReal **L, const DMBoundaryType **bd) 4307c6b900c6SMatthew G. Knepley { 4308c6b900c6SMatthew G. Knepley PetscFunctionBegin; 4309c6b900c6SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4310c6b900c6SMatthew G. Knepley if (L) *L = dm->L; 4311c6b900c6SMatthew G. Knepley if (maxCell) *maxCell = dm->maxCell; 43125dc8c3f7SMatthew G. Knepley if (bd) *bd = dm->bdtype; 4313c6b900c6SMatthew G. Knepley PetscFunctionReturn(0); 4314c6b900c6SMatthew G. Knepley } 4315c6b900c6SMatthew G. Knepley 43165dc8c3f7SMatthew G. Knepley /*@C 43175dc8c3f7SMatthew G. Knepley DMSetPeriodicity - Set the description of mesh periodicity 43185dc8c3f7SMatthew G. Knepley 43195dc8c3f7SMatthew G. Knepley Input Parameters: 43205dc8c3f7SMatthew G. Knepley + dm - The DM object 43215dc8c3f7SMatthew G. Knepley . maxCell - Over distances greater than this, we can assume a point has crossed over to another sheet, when trying to localize cell coordinates 43225dc8c3f7SMatthew G. Knepley . L - If we assume the mesh is a torus, this is the length of each coordinate 43235dc8c3f7SMatthew G. Knepley - bd - This describes the type of periodicity in each topological dimension 43245dc8c3f7SMatthew G. Knepley 43255dc8c3f7SMatthew G. Knepley Level: developer 43265dc8c3f7SMatthew G. Knepley 43275dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity() 43285dc8c3f7SMatthew G. Knepley @*/ 43295dc8c3f7SMatthew G. Knepley PetscErrorCode DMSetPeriodicity(DM dm, const PetscReal maxCell[], const PetscReal L[], const DMBoundaryType bd[]) 4330c6b900c6SMatthew G. Knepley { 4331c6b900c6SMatthew G. Knepley PetscInt dim, d; 4332c6b900c6SMatthew G. Knepley PetscErrorCode ierr; 4333c6b900c6SMatthew G. Knepley 4334c6b900c6SMatthew G. Knepley PetscFunctionBegin; 4335c6b900c6SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 43365dc8c3f7SMatthew G. Knepley PetscValidPointer(L,3);PetscValidPointer(maxCell,2);PetscValidPointer(bd,4); 43375dc8c3f7SMatthew G. Knepley ierr = PetscFree3(dm->L,dm->maxCell,dm->bdtype);CHKERRQ(ierr); 43385dc8c3f7SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 43395dc8c3f7SMatthew G. Knepley ierr = PetscMalloc3(dim,&dm->L,dim,&dm->maxCell,dim,&dm->bdtype);CHKERRQ(ierr); 43405dc8c3f7SMatthew G. Knepley for (d = 0; d < dim; ++d) {dm->L[d] = L[d]; dm->maxCell[d] = maxCell[d]; dm->bdtype[d] = bd[d];} 4341c6b900c6SMatthew G. Knepley PetscFunctionReturn(0); 4342c6b900c6SMatthew G. Knepley } 4343c6b900c6SMatthew G. Knepley 43442e17dfb7SMatthew G. Knepley /*@ 43452e17dfb7SMatthew G. Knepley DMLocalizeCoordinate - If a mesh is periodic (a torus with lengths L_i, some of which can be infinite), project the coordinate onto [0, L_i) in each dimension. 43462e17dfb7SMatthew G. Knepley 43472e17dfb7SMatthew G. Knepley Input Parameters: 43482e17dfb7SMatthew G. Knepley + dm - The DM 434965da65dcSMatthew G. Knepley . in - The input coordinate point (dim numbers) 435065da65dcSMatthew G. Knepley - endpoint - Include the endpoint L_i 43512e17dfb7SMatthew G. Knepley 43522e17dfb7SMatthew G. Knepley Output Parameter: 43532e17dfb7SMatthew G. Knepley . out - The localized coordinate point 43542e17dfb7SMatthew G. Knepley 43552e17dfb7SMatthew G. Knepley Level: developer 43562e17dfb7SMatthew G. Knepley 43572e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate() 43582e17dfb7SMatthew G. Knepley @*/ 435965da65dcSMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate(DM dm, const PetscScalar in[], PetscBool endpoint, PetscScalar out[]) 43602e17dfb7SMatthew G. Knepley { 43612e17dfb7SMatthew G. Knepley PetscInt dim, d; 43622e17dfb7SMatthew G. Knepley PetscErrorCode ierr; 43632e17dfb7SMatthew G. Knepley 43642e17dfb7SMatthew G. Knepley PetscFunctionBegin; 43652e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 43662e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 43672e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 43682e17dfb7SMatthew G. Knepley } else { 436965da65dcSMatthew G. Knepley if (endpoint) { 437065da65dcSMatthew G. Knepley for (d = 0; d < dim; ++d) { 4371da3333bfSMatthew G. Knepley if ((PetscAbsReal(PetscRealPart(in[d])/dm->L[d] - PetscFloorReal(PetscRealPart(in[d])/dm->L[d])) < PETSC_SMALL) && (PetscRealPart(in[d])/dm->L[d] > PETSC_SMALL)) { 4372da3333bfSMatthew G. Knepley out[d] = in[d] - dm->L[d]*(PetscFloorReal(PetscRealPart(in[d])/dm->L[d]) - 1); 437365da65dcSMatthew G. Knepley } else { 4374da3333bfSMatthew G. Knepley out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]); 437565da65dcSMatthew G. Knepley } 437665da65dcSMatthew G. Knepley } 437765da65dcSMatthew G. Knepley } else { 43782e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 43791118d4bcSLisandro Dalcin out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]); 43802e17dfb7SMatthew G. Knepley } 43812e17dfb7SMatthew G. Knepley } 438265da65dcSMatthew G. Knepley } 43832e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 43842e17dfb7SMatthew G. Knepley } 43852e17dfb7SMatthew G. Knepley 43862e17dfb7SMatthew G. Knepley /* 43872e17dfb7SMatthew G. Knepley DMLocalizeCoordinate_Internal - If a mesh is periodic, and the input point is far from the anchor, pick the coordinate sheet of the torus which moves it closer. 43882e17dfb7SMatthew G. Knepley 43892e17dfb7SMatthew G. Knepley Input Parameters: 43902e17dfb7SMatthew G. Knepley + dm - The DM 43912e17dfb7SMatthew G. Knepley . dim - The spatial dimension 43922e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it 43932e17dfb7SMatthew G. Knepley - in - The input coordinate point (dim numbers) 43942e17dfb7SMatthew G. Knepley 43952e17dfb7SMatthew G. Knepley Output Parameter: 43962e17dfb7SMatthew G. Knepley . out - The localized coordinate point 43972e17dfb7SMatthew G. Knepley 43982e17dfb7SMatthew G. Knepley Level: developer 43992e17dfb7SMatthew G. Knepley 44002e17dfb7SMatthew G. Knepley Note: This is meant to get a set of coordinates close to each other, as in a cell. The anchor is usually the one of the vertices on a containing cell 44012e17dfb7SMatthew G. Knepley 44022e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate() 44032e17dfb7SMatthew G. Knepley */ 44042e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[]) 44052e17dfb7SMatthew G. Knepley { 44062e17dfb7SMatthew G. Knepley PetscInt d; 44072e17dfb7SMatthew G. Knepley 44082e17dfb7SMatthew G. Knepley PetscFunctionBegin; 44092e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 44102e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 44112e17dfb7SMatthew G. Knepley } else { 44122e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 4413908eca10SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) { 44142e17dfb7SMatthew G. Knepley out[d] = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d]; 44152e17dfb7SMatthew G. Knepley } else { 44162e17dfb7SMatthew G. Knepley out[d] = in[d]; 44172e17dfb7SMatthew G. Knepley } 44182e17dfb7SMatthew G. Knepley } 44192e17dfb7SMatthew G. Knepley } 44202e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 44212e17dfb7SMatthew G. Knepley } 44222e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinateReal_Internal(DM dm, PetscInt dim, const PetscReal anchor[], const PetscReal in[], PetscReal out[]) 44232e17dfb7SMatthew G. Knepley { 44242e17dfb7SMatthew G. Knepley PetscInt d; 44252e17dfb7SMatthew G. Knepley 44262e17dfb7SMatthew G. Knepley PetscFunctionBegin; 44272e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 44282e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 44292e17dfb7SMatthew G. Knepley } else { 44302e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 4431908eca10SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsReal(anchor[d] - in[d]) > dm->maxCell[d])) { 44322e17dfb7SMatthew G. Knepley out[d] = anchor[d] > in[d] ? dm->L[d] + in[d] : in[d] - dm->L[d]; 44332e17dfb7SMatthew G. Knepley } else { 44342e17dfb7SMatthew G. Knepley out[d] = in[d]; 44352e17dfb7SMatthew G. Knepley } 44362e17dfb7SMatthew G. Knepley } 44372e17dfb7SMatthew G. Knepley } 44382e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 44392e17dfb7SMatthew G. Knepley } 44402e17dfb7SMatthew G. Knepley 44412e17dfb7SMatthew G. Knepley /* 44422e17dfb7SMatthew G. Knepley DMLocalizeAddCoordinate_Internal - If a mesh is periodic, and the input point is far from the anchor, pick the coordinate sheet of the torus which moves it closer. 44432e17dfb7SMatthew G. Knepley 44442e17dfb7SMatthew G. Knepley Input Parameters: 44452e17dfb7SMatthew G. Knepley + dm - The DM 44462e17dfb7SMatthew G. Knepley . dim - The spatial dimension 44472e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it 44482e17dfb7SMatthew G. Knepley . in - The input coordinate delta (dim numbers) 44492e17dfb7SMatthew G. Knepley - out - The input coordinate point (dim numbers) 44502e17dfb7SMatthew G. Knepley 44512e17dfb7SMatthew G. Knepley Output Parameter: 44522e17dfb7SMatthew G. Knepley . out - The localized coordinate in + out 44532e17dfb7SMatthew G. Knepley 44542e17dfb7SMatthew G. Knepley Level: developer 44552e17dfb7SMatthew G. Knepley 44562e17dfb7SMatthew G. Knepley Note: This is meant to get a set of coordinates close to each other, as in a cell. The anchor is usually the one of the vertices on a containing cell 44572e17dfb7SMatthew G. Knepley 44582e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeCoordinate() 44592e17dfb7SMatthew G. Knepley */ 44602e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeAddCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[]) 44612e17dfb7SMatthew G. Knepley { 44622e17dfb7SMatthew G. Knepley PetscInt d; 44632e17dfb7SMatthew G. Knepley 44642e17dfb7SMatthew G. Knepley PetscFunctionBegin; 44652e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 44662e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] += in[d]; 44672e17dfb7SMatthew G. Knepley } else { 44682e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 4469908eca10SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) { 44702e17dfb7SMatthew G. Knepley out[d] += PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d]; 44712e17dfb7SMatthew G. Knepley } else { 44722e17dfb7SMatthew G. Knepley out[d] += in[d]; 44732e17dfb7SMatthew G. Knepley } 44742e17dfb7SMatthew G. Knepley } 44752e17dfb7SMatthew G. Knepley } 44762e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 44772e17dfb7SMatthew G. Knepley } 44782e17dfb7SMatthew G. Knepley 447936447a5eSToby Isaac /*@ 448036447a5eSToby Isaac DMGetCoordinatesLocalized - Check if the DM coordinates have been localized for cells 448136447a5eSToby Isaac 448236447a5eSToby Isaac Input Parameter: 448336447a5eSToby Isaac . dm - The DM 448436447a5eSToby Isaac 448536447a5eSToby Isaac Output Parameter: 448636447a5eSToby Isaac areLocalized - True if localized 448736447a5eSToby Isaac 448836447a5eSToby Isaac Level: developer 448936447a5eSToby Isaac 449036447a5eSToby Isaac .seealso: DMLocalizeCoordinates() 449136447a5eSToby Isaac @*/ 449236447a5eSToby Isaac PetscErrorCode DMGetCoordinatesLocalized(DM dm,PetscBool *areLocalized) 449336447a5eSToby Isaac { 449436447a5eSToby Isaac DM cdm; 449536447a5eSToby Isaac PetscSection coordSection; 449636447a5eSToby Isaac PetscInt cStart, cEnd, c, sStart, sEnd, dof; 449736447a5eSToby Isaac PetscBool alreadyLocalized, alreadyLocalizedGlobal; 449836447a5eSToby Isaac PetscErrorCode ierr; 449936447a5eSToby Isaac 450036447a5eSToby Isaac PetscFunctionBegin; 450136447a5eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 45028b09590cSToby Isaac if (!dm->maxCell) { 45038b09590cSToby Isaac *areLocalized = PETSC_FALSE; 45048b09590cSToby Isaac PetscFunctionReturn(0); 45058b09590cSToby Isaac } 450636447a5eSToby Isaac /* We need some generic way of refering to cells/vertices */ 450736447a5eSToby Isaac ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 450836447a5eSToby Isaac { 450936447a5eSToby Isaac PetscBool isplex; 451036447a5eSToby Isaac 451136447a5eSToby Isaac ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isplex);CHKERRQ(ierr); 451236447a5eSToby Isaac if (isplex) { 451336447a5eSToby Isaac ierr = DMPlexGetHeightStratum(cdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 451436447a5eSToby Isaac } else SETERRQ(PetscObjectComm((PetscObject) cdm), PETSC_ERR_ARG_WRONG, "Coordinate localization requires a DMPLEX coordinate DM"); 451536447a5eSToby Isaac } 451636447a5eSToby Isaac ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 451736447a5eSToby Isaac ierr = PetscSectionGetChart(coordSection,&sStart,&sEnd);CHKERRQ(ierr); 45185a42012cSToby Isaac alreadyLocalized = alreadyLocalizedGlobal = PETSC_FALSE; 451936447a5eSToby Isaac for (c = cStart; c < cEnd; ++c) { 452036447a5eSToby Isaac if (c < sStart || c >= sEnd) { 452136447a5eSToby Isaac alreadyLocalized = PETSC_FALSE; 452236447a5eSToby Isaac break; 452336447a5eSToby Isaac } 452436447a5eSToby Isaac ierr = PetscSectionGetDof(coordSection, c, &dof);CHKERRQ(ierr); 45255a42012cSToby Isaac if (dof) { 45265a42012cSToby Isaac alreadyLocalized = PETSC_TRUE; 452736447a5eSToby Isaac break; 452836447a5eSToby Isaac } 452936447a5eSToby Isaac } 45305a42012cSToby Isaac ierr = MPI_Allreduce(&alreadyLocalized,&alreadyLocalizedGlobal,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 453136447a5eSToby Isaac *areLocalized = alreadyLocalizedGlobal; 453236447a5eSToby Isaac PetscFunctionReturn(0); 453336447a5eSToby Isaac } 453436447a5eSToby Isaac 453536447a5eSToby Isaac 45362e17dfb7SMatthew G. Knepley /*@ 45372e17dfb7SMatthew G. Knepley DMLocalizeCoordinates - If a mesh is periodic, create local coordinates for each cell 45382e17dfb7SMatthew G. Knepley 45392e17dfb7SMatthew G. Knepley Input Parameter: 45402e17dfb7SMatthew G. Knepley . dm - The DM 45412e17dfb7SMatthew G. Knepley 45422e17dfb7SMatthew G. Knepley Level: developer 45432e17dfb7SMatthew G. Knepley 45442e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinate(), DMLocalizeAddCoordinate() 45452e17dfb7SMatthew G. Knepley @*/ 45462e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinates(DM dm) 45472e17dfb7SMatthew G. Knepley { 45482e17dfb7SMatthew G. Knepley DM cdm; 45492e17dfb7SMatthew G. Knepley PetscSection coordSection, cSection; 45502e17dfb7SMatthew G. Knepley Vec coordinates, cVec; 45513e922f36SToby Isaac PetscScalar *coords, *coords2, *anchor, *localized; 45523e922f36SToby Isaac PetscInt Nc, vStart, vEnd, v, sStart, sEnd, newStart = PETSC_MAX_INT, newEnd = PETSC_MIN_INT, dof, d, off, off2, bs, coordSize; 4553e0ae35bbSToby Isaac PetscBool alreadyLocalized, alreadyLocalizedGlobal; 45543e922f36SToby Isaac PetscInt maxHeight = 0, h; 45553e922f36SToby Isaac PetscInt *pStart = NULL, *pEnd = NULL; 45562e17dfb7SMatthew G. Knepley PetscErrorCode ierr; 45572e17dfb7SMatthew G. Knepley 45582e17dfb7SMatthew G. Knepley PetscFunctionBegin; 45592e17dfb7SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 45602e17dfb7SMatthew G. Knepley if (!dm->maxCell) PetscFunctionReturn(0); 45612e17dfb7SMatthew G. Knepley /* We need some generic way of refering to cells/vertices */ 45622e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 45632e17dfb7SMatthew G. Knepley { 45642e17dfb7SMatthew G. Knepley PetscBool isplex; 45652e17dfb7SMatthew G. Knepley 45662e17dfb7SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isplex);CHKERRQ(ierr); 45672e17dfb7SMatthew G. Knepley if (isplex) { 45682e17dfb7SMatthew G. Knepley ierr = DMPlexGetDepthStratum(cdm, 0, &vStart, &vEnd);CHKERRQ(ierr); 45693e922f36SToby Isaac ierr = DMPlexGetMaxProjectionHeight(cdm,&maxHeight);CHKERRQ(ierr); 45703e922f36SToby Isaac ierr = DMGetWorkArray(dm,2*(maxHeight + 1),PETSC_INT,&pStart);CHKERRQ(ierr); 45713e922f36SToby Isaac pEnd = &pStart[maxHeight + 1]; 45723e922f36SToby Isaac newStart = vStart; 45733e922f36SToby Isaac newEnd = vEnd; 45743e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 45753e922f36SToby Isaac ierr = DMPlexGetHeightStratum(cdm, h, &pStart[h], &pEnd[h]);CHKERRQ(ierr); 45763e922f36SToby Isaac newStart = PetscMin(newStart,pStart[h]); 45773e922f36SToby Isaac newEnd = PetscMax(newEnd,pEnd[h]); 45783e922f36SToby Isaac } 45792e17dfb7SMatthew G. Knepley } else SETERRQ(PetscObjectComm((PetscObject) cdm), PETSC_ERR_ARG_WRONG, "Coordinate localization requires a DMPLEX coordinate DM"); 45802e17dfb7SMatthew G. Knepley } 45812e17dfb7SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 45822e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 45833e922f36SToby Isaac ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 4584e0ae35bbSToby Isaac ierr = PetscSectionGetChart(coordSection,&sStart,&sEnd);CHKERRQ(ierr); 45853e922f36SToby Isaac 45862e17dfb7SMatthew G. Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &cSection);CHKERRQ(ierr); 45872e17dfb7SMatthew G. Knepley ierr = PetscSectionSetNumFields(cSection, 1);CHKERRQ(ierr); 45882e17dfb7SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(coordSection, 0, &Nc);CHKERRQ(ierr); 45892e17dfb7SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(cSection, 0, Nc);CHKERRQ(ierr); 45903e922f36SToby Isaac ierr = PetscSectionSetChart(cSection, newStart, newEnd);CHKERRQ(ierr); 45913e922f36SToby Isaac 45923e922f36SToby Isaac ierr = DMGetWorkArray(dm, 2 * bs, PETSC_SCALAR, &anchor);CHKERRQ(ierr); 45933e922f36SToby Isaac localized = &anchor[bs]; 45943e922f36SToby Isaac alreadyLocalized = alreadyLocalizedGlobal = PETSC_TRUE; 45953e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 45963e922f36SToby Isaac PetscInt cStart = pStart[h], cEnd = pEnd[h], c; 45973e922f36SToby Isaac 45983e922f36SToby Isaac for (c = cStart; c < cEnd; ++c) { 45993e922f36SToby Isaac PetscScalar *cellCoords = NULL; 46003e922f36SToby Isaac PetscInt b; 46013e922f36SToby Isaac 46023e922f36SToby Isaac if (c < sStart || c >= sEnd) alreadyLocalized = PETSC_FALSE; 46033e922f36SToby Isaac ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 46043e922f36SToby Isaac for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b]; 46053e922f36SToby Isaac for (d = 0; d < dof/bs; ++d) { 46063e922f36SToby Isaac ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], localized);CHKERRQ(ierr); 46073e922f36SToby Isaac for (b = 0; b < bs; b++) { 46083e922f36SToby Isaac if (cellCoords[d*bs + b] != localized[b]) break; 46093e922f36SToby Isaac } 46103e922f36SToby Isaac if (b < bs) break; 46113e922f36SToby Isaac } 46123e922f36SToby Isaac if (d < dof/bs) { 46133e922f36SToby Isaac if (c >= sStart && c < sEnd) { 46143e922f36SToby Isaac PetscInt cdof; 46153e922f36SToby Isaac 46163e922f36SToby Isaac ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 46173e922f36SToby Isaac if (cdof != dof) alreadyLocalized = PETSC_FALSE; 46183e922f36SToby Isaac } 46193e922f36SToby Isaac ierr = PetscSectionSetDof(cSection, c, dof);CHKERRQ(ierr); 46203e922f36SToby Isaac ierr = PetscSectionSetFieldDof(cSection, c, 0, dof);CHKERRQ(ierr); 46213e922f36SToby Isaac } 46223e922f36SToby Isaac ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 46233e922f36SToby Isaac } 46243e922f36SToby Isaac } 46253e922f36SToby Isaac ierr = MPI_Allreduce(&alreadyLocalized,&alreadyLocalizedGlobal,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 46263e922f36SToby Isaac if (alreadyLocalizedGlobal) { 46273e922f36SToby Isaac ierr = DMRestoreWorkArray(dm, 2 * bs, PETSC_SCALAR, &anchor);CHKERRQ(ierr); 46283e922f36SToby Isaac ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr); 46293e922f36SToby Isaac ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),PETSC_INT,&pStart);CHKERRQ(ierr); 46303e922f36SToby Isaac PetscFunctionReturn(0); 46313e922f36SToby Isaac } 46322e17dfb7SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 46332e17dfb7SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 46342e17dfb7SMatthew G. Knepley ierr = PetscSectionSetDof(cSection, v, dof);CHKERRQ(ierr); 46352e17dfb7SMatthew G. Knepley ierr = PetscSectionSetFieldDof(cSection, v, 0, dof);CHKERRQ(ierr); 46362e17dfb7SMatthew G. Knepley } 46372e17dfb7SMatthew G. Knepley ierr = PetscSectionSetUp(cSection);CHKERRQ(ierr); 46382e17dfb7SMatthew G. Knepley ierr = PetscSectionGetStorageSize(cSection, &coordSize);CHKERRQ(ierr); 4639c2be7e5eSLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &cVec);CHKERRQ(ierr); 46402e17dfb7SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject)cVec,"coordinates");CHKERRQ(ierr); 46412e17dfb7SMatthew G. Knepley ierr = VecSetBlockSize(cVec, bs);CHKERRQ(ierr); 46422e17dfb7SMatthew G. Knepley ierr = VecSetSizes(cVec, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 46432e17dfb7SMatthew G. Knepley ierr = VecSetType(cVec, VECSTANDARD);CHKERRQ(ierr); 4644c2be7e5eSLisandro Dalcin ierr = VecGetArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr); 46452e17dfb7SMatthew G. Knepley ierr = VecGetArray(cVec, &coords2);CHKERRQ(ierr); 46462e17dfb7SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 46472e17dfb7SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 46482e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 46492e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(cSection, v, &off2);CHKERRQ(ierr); 46502e17dfb7SMatthew G. Knepley for (d = 0; d < dof; ++d) coords2[off2+d] = coords[off+d]; 46512e17dfb7SMatthew G. Knepley } 46523e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 46533e922f36SToby Isaac PetscInt cStart = pStart[h], cEnd = pEnd[h], c; 46543e922f36SToby Isaac 46552e17dfb7SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 46562e17dfb7SMatthew G. Knepley PetscScalar *cellCoords = NULL; 46573e922f36SToby Isaac PetscInt b, cdof; 46582e17dfb7SMatthew G. Knepley 46593e922f36SToby Isaac ierr = PetscSectionGetDof(cSection,c,&cdof);CHKERRQ(ierr); 46603e922f36SToby Isaac if (!cdof) continue; 46612e17dfb7SMatthew G. Knepley ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 46622e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(cSection, c, &off2);CHKERRQ(ierr); 46632e17dfb7SMatthew G. Knepley for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b]; 46642e17dfb7SMatthew G. Knepley for (d = 0; d < dof/bs; ++d) {ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], &coords2[off2+d*bs]);CHKERRQ(ierr);} 46652e17dfb7SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 46662e17dfb7SMatthew G. Knepley } 46673e922f36SToby Isaac } 46683e922f36SToby Isaac ierr = DMRestoreWorkArray(dm, 2 * bs, PETSC_SCALAR, &anchor);CHKERRQ(ierr); 46693e922f36SToby Isaac ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),PETSC_INT,&pStart);CHKERRQ(ierr); 4670c2be7e5eSLisandro Dalcin ierr = VecRestoreArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr); 46712e17dfb7SMatthew G. Knepley ierr = VecRestoreArray(cVec, &coords2);CHKERRQ(ierr); 46722e17dfb7SMatthew G. Knepley ierr = DMSetCoordinateSection(dm, PETSC_DETERMINE, cSection);CHKERRQ(ierr); 46732e17dfb7SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, cVec);CHKERRQ(ierr); 46742e17dfb7SMatthew G. Knepley ierr = VecDestroy(&cVec);CHKERRQ(ierr); 46752e17dfb7SMatthew G. Knepley ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr); 46762e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 46772e17dfb7SMatthew G. Knepley } 46782e17dfb7SMatthew G. Knepley 4679e87bb0d3SMatthew G Knepley /*@ 46803a93e3b7SToby Isaac DMLocatePoints - Locate the points in v in the mesh and return a PetscSF of the containing cells 4681e87bb0d3SMatthew G Knepley 46823a93e3b7SToby Isaac Collective on Vec v (see explanation below) 4683e87bb0d3SMatthew G Knepley 4684e87bb0d3SMatthew G Knepley Input Parameters: 4685e87bb0d3SMatthew G Knepley + dm - The DM 46863a93e3b7SToby Isaac . v - The Vec of points 468762a38674SMatthew G. Knepley . ltype - The type of point location, e.g. DM_POINTLOCATION_NONE or DM_POINTLOCATION_NEAREST 46883a93e3b7SToby Isaac - cells - Points to either NULL, or a PetscSF with guesses for which cells contain each point. 4689e87bb0d3SMatthew G Knepley 469061e3bb9bSMatthew G Knepley Output Parameter: 469162a38674SMatthew G. Knepley + v - The Vec of points, which now contains the nearest mesh points to the given points if DM_POINTLOCATION_NEAREST is used 469262a38674SMatthew G. Knepley - cells - The PetscSF containing the ranks and local indices of the containing points. 46933a93e3b7SToby Isaac 4694e87bb0d3SMatthew G Knepley 4695e87bb0d3SMatthew G Knepley Level: developer 469661e3bb9bSMatthew G Knepley 469762a38674SMatthew G. Knepley Notes: 46983a93e3b7SToby Isaac To do a search of the local cells of the mesh, v should have PETSC_COMM_SELF as its communicator. 469962a38674SMatthew G. Knepley To do a search of all the cells in the distributed mesh, v should have the same communicator as dm. 47003a93e3b7SToby Isaac 47013a93e3b7SToby Isaac If *cellSF is NULL on input, a PetscSF will be created. 470262a38674SMatthew G. Knepley If *cellSF is not NULL on input, it should point to an existing PetscSF, whose graph will be used as initial guesses. 47033a93e3b7SToby Isaac 47043a93e3b7SToby Isaac An array that maps each point to its containing cell can be obtained with 47053a93e3b7SToby Isaac 470662a38674SMatthew G. Knepley $ const PetscSFNode *cells; 470762a38674SMatthew G. Knepley $ PetscInt nFound; 470862a38674SMatthew G. Knepley $ const PetscSFNode *found; 470962a38674SMatthew G. Knepley $ 471062a38674SMatthew G. Knepley $ PetscSFGetGraph(cells,NULL,&nFound,&found,&cells); 47113a93e3b7SToby Isaac 47123a93e3b7SToby Isaac Where cells[i].rank is the rank of the cell containing point found[i] (or i if found == NULL), and cells[i].index is 47133a93e3b7SToby Isaac the index of the cell in its rank's local numbering. 47143a93e3b7SToby Isaac 471561e3bb9bSMatthew G Knepley .keywords: point location, mesh 471662a38674SMatthew G. Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMPointLocationType 471761e3bb9bSMatthew G Knepley @*/ 471862a38674SMatthew G. Knepley PetscErrorCode DMLocatePoints(DM dm, Vec v, DMPointLocationType ltype, PetscSF *cellSF) 4719e87bb0d3SMatthew G Knepley { 4720735aa83eSMatthew G Knepley PetscErrorCode ierr; 4721735aa83eSMatthew G Knepley 4722e87bb0d3SMatthew G Knepley PetscFunctionBegin; 4723e87bb0d3SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4724e87bb0d3SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4725e0fc9d1bSMatthew G. Knepley PetscValidPointer(cellSF,4); 47263a93e3b7SToby Isaac if (*cellSF) { 47273a93e3b7SToby Isaac PetscMPIInt result; 47283a93e3b7SToby Isaac 4729e0fc9d1bSMatthew G. Knepley PetscValidHeaderSpecific(*cellSF,PETSCSF_CLASSID,4); 47303a93e3b7SToby Isaac ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)v),PetscObjectComm((PetscObject)cellSF),&result);CHKERRQ(ierr); 47313a93e3b7SToby Isaac if (result != MPI_IDENT && result != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"cellSF must have a communicator congruent to v's"); 4732e0fc9d1bSMatthew G. Knepley } else { 47333a93e3b7SToby Isaac ierr = PetscSFCreate(PetscObjectComm((PetscObject)v),cellSF);CHKERRQ(ierr); 47343a93e3b7SToby Isaac } 473547a35634SPatrick Farrell ierr = PetscLogEventBegin(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr); 4736735aa83eSMatthew G Knepley if (dm->ops->locatepoints) { 473762a38674SMatthew G. Knepley ierr = (*dm->ops->locatepoints)(dm,v,ltype,*cellSF);CHKERRQ(ierr); 473882f516ccSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Point location not available for this DM"); 473947a35634SPatrick Farrell ierr = PetscLogEventEnd(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr); 4740e87bb0d3SMatthew G Knepley PetscFunctionReturn(0); 4741e87bb0d3SMatthew G Knepley } 474214f150ffSMatthew G. Knepley 4743f4d763aaSMatthew G. Knepley /*@ 4744f4d763aaSMatthew G. Knepley DMGetOutputDM - Retrieve the DM associated with the layout for output 4745f4d763aaSMatthew G. Knepley 4746f4d763aaSMatthew G. Knepley Input Parameter: 4747f4d763aaSMatthew G. Knepley . dm - The original DM 4748f4d763aaSMatthew G. Knepley 4749f4d763aaSMatthew G. Knepley Output Parameter: 4750f4d763aaSMatthew G. Knepley . odm - The DM which provides the layout for output 4751f4d763aaSMatthew G. Knepley 4752f4d763aaSMatthew G. Knepley Level: intermediate 4753f4d763aaSMatthew G. Knepley 4754f4d763aaSMatthew G. Knepley .seealso: VecView(), DMGetDefaultGlobalSection() 4755f4d763aaSMatthew G. Knepley @*/ 475614f150ffSMatthew G. Knepley PetscErrorCode DMGetOutputDM(DM dm, DM *odm) 475714f150ffSMatthew G. Knepley { 4758c26acbdeSMatthew G. Knepley PetscSection section; 47592d4e4a49SMatthew G. Knepley PetscBool hasConstraints, ghasConstraints; 476014f150ffSMatthew G. Knepley PetscErrorCode ierr; 476114f150ffSMatthew G. Knepley 476214f150ffSMatthew G. Knepley PetscFunctionBegin; 476314f150ffSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 476414f150ffSMatthew G. Knepley PetscValidPointer(odm,2); 4765c26acbdeSMatthew G. Knepley ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 4766c26acbdeSMatthew G. Knepley ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr); 4767127fe6b9SMatthew G. Knepley ierr = MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 47682d4e4a49SMatthew G. Knepley if (!ghasConstraints) { 4769c26acbdeSMatthew G. Knepley *odm = dm; 4770c26acbdeSMatthew G. Knepley PetscFunctionReturn(0); 4771c26acbdeSMatthew G. Knepley } 477214f150ffSMatthew G. Knepley if (!dm->dmBC) { 47730305aff6SMatthew G. Knepley PetscDS ds; 4774c26acbdeSMatthew G. Knepley PetscSection newSection, gsection; 477514f150ffSMatthew G. Knepley PetscSF sf; 477614f150ffSMatthew G. Knepley 477714f150ffSMatthew G. Knepley ierr = DMClone(dm, &dm->dmBC);CHKERRQ(ierr); 47780305aff6SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 47790305aff6SMatthew G. Knepley ierr = DMSetDS(dm->dmBC, ds);CHKERRQ(ierr); 478014f150ffSMatthew G. Knepley ierr = PetscSectionClone(section, &newSection);CHKERRQ(ierr); 478114f150ffSMatthew G. Knepley ierr = DMSetDefaultSection(dm->dmBC, newSection);CHKERRQ(ierr); 478214f150ffSMatthew G. Knepley ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr); 478314f150ffSMatthew G. Knepley ierr = DMGetPointSF(dm->dmBC, &sf);CHKERRQ(ierr); 478415b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr); 478514f150ffSMatthew G. Knepley ierr = DMSetDefaultGlobalSection(dm->dmBC, gsection);CHKERRQ(ierr); 478614f150ffSMatthew G. Knepley ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr); 478714f150ffSMatthew G. Knepley } 478814f150ffSMatthew G. Knepley *odm = dm->dmBC; 478914f150ffSMatthew G. Knepley PetscFunctionReturn(0); 479014f150ffSMatthew G. Knepley } 4791f4d763aaSMatthew G. Knepley 4792f4d763aaSMatthew G. Knepley /*@ 4793cdb7a50dSMatthew G. Knepley DMGetOutputSequenceNumber - Retrieve the sequence number/value for output 4794f4d763aaSMatthew G. Knepley 4795f4d763aaSMatthew G. Knepley Input Parameter: 4796f4d763aaSMatthew G. Knepley . dm - The original DM 4797f4d763aaSMatthew G. Knepley 4798cdb7a50dSMatthew G. Knepley Output Parameters: 4799cdb7a50dSMatthew G. Knepley + num - The output sequence number 4800cdb7a50dSMatthew G. Knepley - val - The output sequence value 4801f4d763aaSMatthew G. Knepley 4802f4d763aaSMatthew G. Knepley Level: intermediate 4803f4d763aaSMatthew G. Knepley 4804f4d763aaSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 4805f4d763aaSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 4806f4d763aaSMatthew G. Knepley 4807f4d763aaSMatthew G. Knepley .seealso: VecView() 4808f4d763aaSMatthew G. Knepley @*/ 4809cdb7a50dSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val) 4810f4d763aaSMatthew G. Knepley { 4811f4d763aaSMatthew G. Knepley PetscFunctionBegin; 4812f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4813cdb7a50dSMatthew G. Knepley if (num) {PetscValidPointer(num,2); *num = dm->outputSequenceNum;} 4814cdb7a50dSMatthew G. Knepley if (val) {PetscValidPointer(val,3);*val = dm->outputSequenceVal;} 4815f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 4816f4d763aaSMatthew G. Knepley } 4817f4d763aaSMatthew G. Knepley 4818f4d763aaSMatthew G. Knepley /*@ 4819cdb7a50dSMatthew G. Knepley DMSetOutputSequenceNumber - Set the sequence number/value for output 4820f4d763aaSMatthew G. Knepley 4821f4d763aaSMatthew G. Knepley Input Parameters: 4822f4d763aaSMatthew G. Knepley + dm - The original DM 4823cdb7a50dSMatthew G. Knepley . num - The output sequence number 4824cdb7a50dSMatthew G. Knepley - val - The output sequence value 4825f4d763aaSMatthew G. Knepley 4826f4d763aaSMatthew G. Knepley Level: intermediate 4827f4d763aaSMatthew G. Knepley 4828f4d763aaSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 4829f4d763aaSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 4830f4d763aaSMatthew G. Knepley 4831f4d763aaSMatthew G. Knepley .seealso: VecView() 4832f4d763aaSMatthew G. Knepley @*/ 4833cdb7a50dSMatthew G. Knepley PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val) 4834f4d763aaSMatthew G. Knepley { 4835f4d763aaSMatthew G. Knepley PetscFunctionBegin; 4836f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4837f4d763aaSMatthew G. Knepley dm->outputSequenceNum = num; 4838cdb7a50dSMatthew G. Knepley dm->outputSequenceVal = val; 4839cdb7a50dSMatthew G. Knepley PetscFunctionReturn(0); 4840cdb7a50dSMatthew G. Knepley } 4841cdb7a50dSMatthew G. Knepley 4842cdb7a50dSMatthew G. Knepley /*@C 4843cdb7a50dSMatthew G. Knepley DMOutputSequenceLoad - Retrieve the sequence value from a Viewer 4844cdb7a50dSMatthew G. Knepley 4845cdb7a50dSMatthew G. Knepley Input Parameters: 4846cdb7a50dSMatthew G. Knepley + dm - The original DM 4847cdb7a50dSMatthew G. Knepley . name - The sequence name 4848cdb7a50dSMatthew G. Knepley - num - The output sequence number 4849cdb7a50dSMatthew G. Knepley 4850cdb7a50dSMatthew G. Knepley Output Parameter: 4851cdb7a50dSMatthew G. Knepley . val - The output sequence value 4852cdb7a50dSMatthew G. Knepley 4853cdb7a50dSMatthew G. Knepley Level: intermediate 4854cdb7a50dSMatthew G. Knepley 4855cdb7a50dSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 4856cdb7a50dSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 4857cdb7a50dSMatthew G. Knepley 4858cdb7a50dSMatthew G. Knepley .seealso: DMGetOutputSequenceNumber(), DMSetOutputSequenceNumber(), VecView() 4859cdb7a50dSMatthew G. Knepley @*/ 4860cdb7a50dSMatthew G. Knepley PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val) 4861cdb7a50dSMatthew G. Knepley { 4862cdb7a50dSMatthew G. Knepley PetscBool ishdf5; 4863cdb7a50dSMatthew G. Knepley PetscErrorCode ierr; 4864cdb7a50dSMatthew G. Knepley 4865cdb7a50dSMatthew G. Knepley PetscFunctionBegin; 4866cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4867cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 4868cdb7a50dSMatthew G. Knepley PetscValidPointer(val,4); 4869cdb7a50dSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 4870cdb7a50dSMatthew G. Knepley if (ishdf5) { 4871cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 4872cdb7a50dSMatthew G. Knepley PetscScalar value; 4873cdb7a50dSMatthew G. Knepley 487439d25373SMatthew G. Knepley ierr = DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer);CHKERRQ(ierr); 48754aeb217fSMatthew G. Knepley *val = PetscRealPart(value); 4876cdb7a50dSMatthew G. Knepley #endif 4877cdb7a50dSMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()"); 4878f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 4879f4d763aaSMatthew G. Knepley } 48808e4ac7eaSMatthew G. Knepley 48818e4ac7eaSMatthew G. Knepley /*@ 48828e4ac7eaSMatthew G. Knepley DMGetUseNatural - Get the flag for creating a mapping to the natural order on distribution 48838e4ac7eaSMatthew G. Knepley 48848e4ac7eaSMatthew G. Knepley Not collective 48858e4ac7eaSMatthew G. Knepley 48868e4ac7eaSMatthew G. Knepley Input Parameter: 48878e4ac7eaSMatthew G. Knepley . dm - The DM 48888e4ac7eaSMatthew G. Knepley 48898e4ac7eaSMatthew G. Knepley Output Parameter: 48908e4ac7eaSMatthew G. Knepley . useNatural - The flag to build the mapping to a natural order during distribution 48918e4ac7eaSMatthew G. Knepley 48928e4ac7eaSMatthew G. Knepley Level: beginner 48938e4ac7eaSMatthew G. Knepley 48948e4ac7eaSMatthew G. Knepley .seealso: DMSetUseNatural(), DMCreate() 48958e4ac7eaSMatthew G. Knepley @*/ 48968e4ac7eaSMatthew G. Knepley PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural) 48978e4ac7eaSMatthew G. Knepley { 48988e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 48998e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 49008e4ac7eaSMatthew G. Knepley PetscValidPointer(useNatural, 2); 49018e4ac7eaSMatthew G. Knepley *useNatural = dm->useNatural; 49028e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 49038e4ac7eaSMatthew G. Knepley } 49048e4ac7eaSMatthew G. Knepley 49058e4ac7eaSMatthew G. Knepley /*@ 49068e4ac7eaSMatthew G. Knepley DMSetUseNatural - Set the flag for creating a mapping to the natural order on distribution 49078e4ac7eaSMatthew G. Knepley 49088e4ac7eaSMatthew G. Knepley Collective on dm 49098e4ac7eaSMatthew G. Knepley 49108e4ac7eaSMatthew G. Knepley Input Parameters: 49118e4ac7eaSMatthew G. Knepley + dm - The DM 49128e4ac7eaSMatthew G. Knepley - useNatural - The flag to build the mapping to a natural order during distribution 49138e4ac7eaSMatthew G. Knepley 49148e4ac7eaSMatthew G. Knepley Level: beginner 49158e4ac7eaSMatthew G. Knepley 49168e4ac7eaSMatthew G. Knepley .seealso: DMGetUseNatural(), DMCreate() 49178e4ac7eaSMatthew G. Knepley @*/ 49188e4ac7eaSMatthew G. Knepley PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural) 49198e4ac7eaSMatthew G. Knepley { 49208e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 49218e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 49228e4ac7eaSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, useNatural, 2); 49238e4ac7eaSMatthew G. Knepley dm->useNatural = useNatural; 49248e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 49258e4ac7eaSMatthew G. Knepley } 4926c58f1c22SToby Isaac 4927c58f1c22SToby Isaac 4928c58f1c22SToby Isaac /*@C 4929c58f1c22SToby Isaac DMCreateLabel - Create a label of the given name if it does not already exist 4930c58f1c22SToby Isaac 4931c58f1c22SToby Isaac Not Collective 4932c58f1c22SToby Isaac 4933c58f1c22SToby Isaac Input Parameters: 4934c58f1c22SToby Isaac + dm - The DM object 4935c58f1c22SToby Isaac - name - The label name 4936c58f1c22SToby Isaac 4937c58f1c22SToby Isaac Level: intermediate 4938c58f1c22SToby Isaac 4939c58f1c22SToby Isaac .keywords: mesh 4940c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 4941c58f1c22SToby Isaac @*/ 4942c58f1c22SToby Isaac PetscErrorCode DMCreateLabel(DM dm, const char name[]) 4943c58f1c22SToby Isaac { 4944c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 4945c58f1c22SToby Isaac PetscBool flg = PETSC_FALSE; 4946c58f1c22SToby Isaac PetscErrorCode ierr; 4947c58f1c22SToby Isaac 4948c58f1c22SToby Isaac PetscFunctionBegin; 4949c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4950c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 4951c58f1c22SToby Isaac while (next) { 4952c58f1c22SToby Isaac ierr = PetscStrcmp(name, next->label->name, &flg);CHKERRQ(ierr); 4953c58f1c22SToby Isaac if (flg) break; 4954c58f1c22SToby Isaac next = next->next; 4955c58f1c22SToby Isaac } 4956c58f1c22SToby Isaac if (!flg) { 4957c58f1c22SToby Isaac DMLabelLink tmpLabel; 4958c58f1c22SToby Isaac 4959c58f1c22SToby Isaac ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr); 4960c58f1c22SToby Isaac ierr = DMLabelCreate(name, &tmpLabel->label);CHKERRQ(ierr); 4961c58f1c22SToby Isaac tmpLabel->output = PETSC_TRUE; 4962c58f1c22SToby Isaac tmpLabel->next = dm->labels->next; 4963c58f1c22SToby Isaac dm->labels->next = tmpLabel; 4964c58f1c22SToby Isaac } 4965c58f1c22SToby Isaac PetscFunctionReturn(0); 4966c58f1c22SToby Isaac } 4967c58f1c22SToby Isaac 4968c58f1c22SToby Isaac /*@C 4969c58f1c22SToby Isaac DMGetLabelValue - Get the value in a Sieve Label for the given point, with 0 as the default 4970c58f1c22SToby Isaac 4971c58f1c22SToby Isaac Not Collective 4972c58f1c22SToby Isaac 4973c58f1c22SToby Isaac Input Parameters: 4974c58f1c22SToby Isaac + dm - The DM object 4975c58f1c22SToby Isaac . name - The label name 4976c58f1c22SToby Isaac - point - The mesh point 4977c58f1c22SToby Isaac 4978c58f1c22SToby Isaac Output Parameter: 4979c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label 4980c58f1c22SToby Isaac 4981c58f1c22SToby Isaac Level: beginner 4982c58f1c22SToby Isaac 4983c58f1c22SToby Isaac .keywords: mesh 4984c58f1c22SToby Isaac .seealso: DMLabelGetValue(), DMSetLabelValue(), DMGetStratumIS() 4985c58f1c22SToby Isaac @*/ 4986c58f1c22SToby Isaac PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value) 4987c58f1c22SToby Isaac { 4988c58f1c22SToby Isaac DMLabel label; 4989c58f1c22SToby Isaac PetscErrorCode ierr; 4990c58f1c22SToby Isaac 4991c58f1c22SToby Isaac PetscFunctionBegin; 4992c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4993c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 4994c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 4995c58f1c22SToby Isaac if (!label) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name);CHKERRQ(ierr); 4996c58f1c22SToby Isaac ierr = DMLabelGetValue(label, point, value);CHKERRQ(ierr); 4997c58f1c22SToby Isaac PetscFunctionReturn(0); 4998c58f1c22SToby Isaac } 4999c58f1c22SToby Isaac 5000c58f1c22SToby Isaac /*@C 5001c58f1c22SToby Isaac DMSetLabelValue - Add a point to a Sieve Label with given value 5002c58f1c22SToby Isaac 5003c58f1c22SToby Isaac Not Collective 5004c58f1c22SToby Isaac 5005c58f1c22SToby Isaac Input Parameters: 5006c58f1c22SToby Isaac + dm - The DM object 5007c58f1c22SToby Isaac . name - The label name 5008c58f1c22SToby Isaac . point - The mesh point 5009c58f1c22SToby Isaac - value - The label value for this point 5010c58f1c22SToby Isaac 5011c58f1c22SToby Isaac Output Parameter: 5012c58f1c22SToby Isaac 5013c58f1c22SToby Isaac Level: beginner 5014c58f1c22SToby Isaac 5015c58f1c22SToby Isaac .keywords: mesh 5016c58f1c22SToby Isaac .seealso: DMLabelSetValue(), DMGetStratumIS(), DMClearLabelValue() 5017c58f1c22SToby Isaac @*/ 5018c58f1c22SToby Isaac PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 5019c58f1c22SToby Isaac { 5020c58f1c22SToby Isaac DMLabel label; 5021c58f1c22SToby Isaac PetscErrorCode ierr; 5022c58f1c22SToby Isaac 5023c58f1c22SToby Isaac PetscFunctionBegin; 5024c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5025c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5026c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 5027c58f1c22SToby Isaac if (!label) { 5028c58f1c22SToby Isaac ierr = DMCreateLabel(dm, name);CHKERRQ(ierr); 5029c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 5030c58f1c22SToby Isaac } 5031c58f1c22SToby Isaac ierr = DMLabelSetValue(label, point, value);CHKERRQ(ierr); 5032c58f1c22SToby Isaac PetscFunctionReturn(0); 5033c58f1c22SToby Isaac } 5034c58f1c22SToby Isaac 5035c58f1c22SToby Isaac /*@C 5036c58f1c22SToby Isaac DMClearLabelValue - Remove a point from a Sieve Label with given value 5037c58f1c22SToby Isaac 5038c58f1c22SToby Isaac Not Collective 5039c58f1c22SToby Isaac 5040c58f1c22SToby Isaac Input Parameters: 5041c58f1c22SToby Isaac + dm - The DM object 5042c58f1c22SToby Isaac . name - The label name 5043c58f1c22SToby Isaac . point - The mesh point 5044c58f1c22SToby Isaac - value - The label value for this point 5045c58f1c22SToby Isaac 5046c58f1c22SToby Isaac Output Parameter: 5047c58f1c22SToby Isaac 5048c58f1c22SToby Isaac Level: beginner 5049c58f1c22SToby Isaac 5050c58f1c22SToby Isaac .keywords: mesh 5051c58f1c22SToby Isaac .seealso: DMLabelClearValue(), DMSetLabelValue(), DMGetStratumIS() 5052c58f1c22SToby Isaac @*/ 5053c58f1c22SToby Isaac PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 5054c58f1c22SToby Isaac { 5055c58f1c22SToby Isaac DMLabel label; 5056c58f1c22SToby Isaac PetscErrorCode ierr; 5057c58f1c22SToby Isaac 5058c58f1c22SToby Isaac PetscFunctionBegin; 5059c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5060c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5061c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 5062c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 5063c58f1c22SToby Isaac ierr = DMLabelClearValue(label, point, value);CHKERRQ(ierr); 5064c58f1c22SToby Isaac PetscFunctionReturn(0); 5065c58f1c22SToby Isaac } 5066c58f1c22SToby Isaac 5067c58f1c22SToby Isaac /*@C 5068c58f1c22SToby Isaac DMGetLabelSize - Get the number of different integer ids in a Label 5069c58f1c22SToby Isaac 5070c58f1c22SToby Isaac Not Collective 5071c58f1c22SToby Isaac 5072c58f1c22SToby Isaac Input Parameters: 5073c58f1c22SToby Isaac + dm - The DM object 5074c58f1c22SToby Isaac - name - The label name 5075c58f1c22SToby Isaac 5076c58f1c22SToby Isaac Output Parameter: 5077c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist 5078c58f1c22SToby Isaac 5079c58f1c22SToby Isaac Level: beginner 5080c58f1c22SToby Isaac 5081c58f1c22SToby Isaac .keywords: mesh 5082c58f1c22SToby Isaac .seealso: DMLabeGetNumValues(), DMSetLabelValue() 5083c58f1c22SToby Isaac @*/ 5084c58f1c22SToby Isaac PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size) 5085c58f1c22SToby Isaac { 5086c58f1c22SToby Isaac DMLabel label; 5087c58f1c22SToby Isaac PetscErrorCode ierr; 5088c58f1c22SToby Isaac 5089c58f1c22SToby Isaac PetscFunctionBegin; 5090c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5091c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5092c58f1c22SToby Isaac PetscValidPointer(size, 3); 5093c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 5094c58f1c22SToby Isaac *size = 0; 5095c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 5096c58f1c22SToby Isaac ierr = DMLabelGetNumValues(label, size);CHKERRQ(ierr); 5097c58f1c22SToby Isaac PetscFunctionReturn(0); 5098c58f1c22SToby Isaac } 5099c58f1c22SToby Isaac 5100c58f1c22SToby Isaac /*@C 5101c58f1c22SToby Isaac DMGetLabelIdIS - Get the integer ids in a label 5102c58f1c22SToby Isaac 5103c58f1c22SToby Isaac Not Collective 5104c58f1c22SToby Isaac 5105c58f1c22SToby Isaac Input Parameters: 5106c58f1c22SToby Isaac + mesh - The DM object 5107c58f1c22SToby Isaac - name - The label name 5108c58f1c22SToby Isaac 5109c58f1c22SToby Isaac Output Parameter: 5110c58f1c22SToby Isaac . ids - The integer ids, or NULL if the label does not exist 5111c58f1c22SToby Isaac 5112c58f1c22SToby Isaac Level: beginner 5113c58f1c22SToby Isaac 5114c58f1c22SToby Isaac .keywords: mesh 5115c58f1c22SToby Isaac .seealso: DMLabelGetValueIS(), DMGetLabelSize() 5116c58f1c22SToby Isaac @*/ 5117c58f1c22SToby Isaac PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids) 5118c58f1c22SToby Isaac { 5119c58f1c22SToby Isaac DMLabel label; 5120c58f1c22SToby Isaac PetscErrorCode ierr; 5121c58f1c22SToby Isaac 5122c58f1c22SToby Isaac PetscFunctionBegin; 5123c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5124c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5125c58f1c22SToby Isaac PetscValidPointer(ids, 3); 5126c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 5127c58f1c22SToby Isaac *ids = NULL; 5128c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 5129c58f1c22SToby Isaac ierr = DMLabelGetValueIS(label, ids);CHKERRQ(ierr); 5130c58f1c22SToby Isaac PetscFunctionReturn(0); 5131c58f1c22SToby Isaac } 5132c58f1c22SToby Isaac 5133c58f1c22SToby Isaac /*@C 5134c58f1c22SToby Isaac DMGetStratumSize - Get the number of points in a label stratum 5135c58f1c22SToby Isaac 5136c58f1c22SToby Isaac Not Collective 5137c58f1c22SToby Isaac 5138c58f1c22SToby Isaac Input Parameters: 5139c58f1c22SToby Isaac + dm - The DM object 5140c58f1c22SToby Isaac . name - The label name 5141c58f1c22SToby Isaac - value - The stratum value 5142c58f1c22SToby Isaac 5143c58f1c22SToby Isaac Output Parameter: 5144c58f1c22SToby Isaac . size - The stratum size 5145c58f1c22SToby Isaac 5146c58f1c22SToby Isaac Level: beginner 5147c58f1c22SToby Isaac 5148c58f1c22SToby Isaac .keywords: mesh 5149c58f1c22SToby Isaac .seealso: DMLabelGetStratumSize(), DMGetLabelSize(), DMGetLabelIds() 5150c58f1c22SToby Isaac @*/ 5151c58f1c22SToby Isaac PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size) 5152c58f1c22SToby Isaac { 5153c58f1c22SToby Isaac DMLabel label; 5154c58f1c22SToby Isaac PetscErrorCode ierr; 5155c58f1c22SToby Isaac 5156c58f1c22SToby Isaac PetscFunctionBegin; 5157c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5158c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5159c58f1c22SToby Isaac PetscValidPointer(size, 4); 5160c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 5161c58f1c22SToby Isaac *size = 0; 5162c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 5163c58f1c22SToby Isaac ierr = DMLabelGetStratumSize(label, value, size);CHKERRQ(ierr); 5164c58f1c22SToby Isaac PetscFunctionReturn(0); 5165c58f1c22SToby Isaac } 5166c58f1c22SToby Isaac 5167c58f1c22SToby Isaac /*@C 5168c58f1c22SToby Isaac DMGetStratumIS - Get the points in a label stratum 5169c58f1c22SToby Isaac 5170c58f1c22SToby Isaac Not Collective 5171c58f1c22SToby Isaac 5172c58f1c22SToby Isaac Input Parameters: 5173c58f1c22SToby Isaac + dm - The DM object 5174c58f1c22SToby Isaac . name - The label name 5175c58f1c22SToby Isaac - value - The stratum value 5176c58f1c22SToby Isaac 5177c58f1c22SToby Isaac Output Parameter: 5178c58f1c22SToby Isaac . points - The stratum points, or NULL if the label does not exist or does not have that value 5179c58f1c22SToby Isaac 5180c58f1c22SToby Isaac Level: beginner 5181c58f1c22SToby Isaac 5182c58f1c22SToby Isaac .keywords: mesh 5183c58f1c22SToby Isaac .seealso: DMLabelGetStratumIS(), DMGetStratumSize() 5184c58f1c22SToby Isaac @*/ 5185c58f1c22SToby Isaac PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points) 5186c58f1c22SToby Isaac { 5187c58f1c22SToby Isaac DMLabel label; 5188c58f1c22SToby Isaac PetscErrorCode ierr; 5189c58f1c22SToby Isaac 5190c58f1c22SToby Isaac PetscFunctionBegin; 5191c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5192c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5193c58f1c22SToby Isaac PetscValidPointer(points, 4); 5194c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 5195c58f1c22SToby Isaac *points = NULL; 5196c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 5197c58f1c22SToby Isaac ierr = DMLabelGetStratumIS(label, value, points);CHKERRQ(ierr); 5198c58f1c22SToby Isaac PetscFunctionReturn(0); 5199c58f1c22SToby Isaac } 5200c58f1c22SToby Isaac 52014de306b1SToby Isaac /*@C 52024de306b1SToby Isaac DMGetStratumIS - Set the points in a label stratum 52034de306b1SToby Isaac 52044de306b1SToby Isaac Not Collective 52054de306b1SToby Isaac 52064de306b1SToby Isaac Input Parameters: 52074de306b1SToby Isaac + dm - The DM object 52084de306b1SToby Isaac . name - The label name 52094de306b1SToby Isaac . value - The stratum value 52104de306b1SToby Isaac - points - The stratum points 52114de306b1SToby Isaac 52124de306b1SToby Isaac Level: beginner 52134de306b1SToby Isaac 52144de306b1SToby Isaac .keywords: mesh 52154de306b1SToby Isaac .seealso: DMLabelSetStratumIS(), DMGetStratumSize() 52164de306b1SToby Isaac @*/ 52174de306b1SToby Isaac PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points) 52184de306b1SToby Isaac { 52194de306b1SToby Isaac DMLabel label; 52204de306b1SToby Isaac PetscErrorCode ierr; 52214de306b1SToby Isaac 52224de306b1SToby Isaac PetscFunctionBegin; 52234de306b1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 52244de306b1SToby Isaac PetscValidCharPointer(name, 2); 52254de306b1SToby Isaac PetscValidPointer(points, 4); 52264de306b1SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 52274de306b1SToby Isaac if (!label) PetscFunctionReturn(0); 52284de306b1SToby Isaac ierr = DMLabelSetStratumIS(label, value, points);CHKERRQ(ierr); 52294de306b1SToby Isaac PetscFunctionReturn(0); 52304de306b1SToby Isaac } 52314de306b1SToby Isaac 5232c58f1c22SToby Isaac /*@C 5233c58f1c22SToby Isaac DMClearLabelStratum - Remove all points from a stratum from a Sieve Label 5234c58f1c22SToby Isaac 5235c58f1c22SToby Isaac Not Collective 5236c58f1c22SToby Isaac 5237c58f1c22SToby Isaac Input Parameters: 5238c58f1c22SToby Isaac + dm - The DM object 5239c58f1c22SToby Isaac . name - The label name 5240c58f1c22SToby Isaac - value - The label value for this point 5241c58f1c22SToby Isaac 5242c58f1c22SToby Isaac Output Parameter: 5243c58f1c22SToby Isaac 5244c58f1c22SToby Isaac Level: beginner 5245c58f1c22SToby Isaac 5246c58f1c22SToby Isaac .keywords: mesh 5247c58f1c22SToby Isaac .seealso: DMLabelClearStratum(), DMSetLabelValue(), DMGetStratumIS(), DMClearLabelValue() 5248c58f1c22SToby Isaac @*/ 5249c58f1c22SToby Isaac PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value) 5250c58f1c22SToby Isaac { 5251c58f1c22SToby Isaac DMLabel label; 5252c58f1c22SToby Isaac PetscErrorCode ierr; 5253c58f1c22SToby Isaac 5254c58f1c22SToby Isaac PetscFunctionBegin; 5255c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5256c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5257c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 5258c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 5259c58f1c22SToby Isaac ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr); 5260c58f1c22SToby Isaac PetscFunctionReturn(0); 5261c58f1c22SToby Isaac } 5262c58f1c22SToby Isaac 5263c58f1c22SToby Isaac /*@ 5264c58f1c22SToby Isaac DMGetNumLabels - Return the number of labels defined by the mesh 5265c58f1c22SToby Isaac 5266c58f1c22SToby Isaac Not Collective 5267c58f1c22SToby Isaac 5268c58f1c22SToby Isaac Input Parameter: 5269c58f1c22SToby Isaac . dm - The DM object 5270c58f1c22SToby Isaac 5271c58f1c22SToby Isaac Output Parameter: 5272c58f1c22SToby Isaac . numLabels - the number of Labels 5273c58f1c22SToby Isaac 5274c58f1c22SToby Isaac Level: intermediate 5275c58f1c22SToby Isaac 5276c58f1c22SToby Isaac .keywords: mesh 5277c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5278c58f1c22SToby Isaac @*/ 5279c58f1c22SToby Isaac PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels) 5280c58f1c22SToby Isaac { 5281c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5282c58f1c22SToby Isaac PetscInt n = 0; 5283c58f1c22SToby Isaac 5284c58f1c22SToby Isaac PetscFunctionBegin; 5285c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5286c58f1c22SToby Isaac PetscValidPointer(numLabels, 2); 5287c58f1c22SToby Isaac while (next) {++n; next = next->next;} 5288c58f1c22SToby Isaac *numLabels = n; 5289c58f1c22SToby Isaac PetscFunctionReturn(0); 5290c58f1c22SToby Isaac } 5291c58f1c22SToby Isaac 5292c58f1c22SToby Isaac /*@C 5293c58f1c22SToby Isaac DMGetLabelName - Return the name of nth label 5294c58f1c22SToby Isaac 5295c58f1c22SToby Isaac Not Collective 5296c58f1c22SToby Isaac 5297c58f1c22SToby Isaac Input Parameters: 5298c58f1c22SToby Isaac + dm - The DM object 5299c58f1c22SToby Isaac - n - the label number 5300c58f1c22SToby Isaac 5301c58f1c22SToby Isaac Output Parameter: 5302c58f1c22SToby Isaac . name - the label name 5303c58f1c22SToby Isaac 5304c58f1c22SToby Isaac Level: intermediate 5305c58f1c22SToby Isaac 5306c58f1c22SToby Isaac .keywords: mesh 5307c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5308c58f1c22SToby Isaac @*/ 5309c58f1c22SToby Isaac PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name) 5310c58f1c22SToby Isaac { 5311c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5312c58f1c22SToby Isaac PetscInt l = 0; 5313c58f1c22SToby Isaac 5314c58f1c22SToby Isaac PetscFunctionBegin; 5315c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5316c58f1c22SToby Isaac PetscValidPointer(name, 3); 5317c58f1c22SToby Isaac while (next) { 5318c58f1c22SToby Isaac if (l == n) { 5319c58f1c22SToby Isaac *name = next->label->name; 5320c58f1c22SToby Isaac PetscFunctionReturn(0); 5321c58f1c22SToby Isaac } 5322c58f1c22SToby Isaac ++l; 5323c58f1c22SToby Isaac next = next->next; 5324c58f1c22SToby Isaac } 5325c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n); 5326c58f1c22SToby Isaac } 5327c58f1c22SToby Isaac 5328c58f1c22SToby Isaac /*@C 5329c58f1c22SToby Isaac DMHasLabel - Determine whether the mesh has a label of a given name 5330c58f1c22SToby Isaac 5331c58f1c22SToby Isaac Not Collective 5332c58f1c22SToby Isaac 5333c58f1c22SToby Isaac Input Parameters: 5334c58f1c22SToby Isaac + dm - The DM object 5335c58f1c22SToby Isaac - name - The label name 5336c58f1c22SToby Isaac 5337c58f1c22SToby Isaac Output Parameter: 5338c58f1c22SToby Isaac . hasLabel - PETSC_TRUE if the label is present 5339c58f1c22SToby Isaac 5340c58f1c22SToby Isaac Level: intermediate 5341c58f1c22SToby Isaac 5342c58f1c22SToby Isaac .keywords: mesh 5343c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5344c58f1c22SToby Isaac @*/ 5345c58f1c22SToby Isaac PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel) 5346c58f1c22SToby Isaac { 5347c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5348c58f1c22SToby Isaac PetscErrorCode ierr; 5349c58f1c22SToby Isaac 5350c58f1c22SToby Isaac PetscFunctionBegin; 5351c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5352c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5353c58f1c22SToby Isaac PetscValidPointer(hasLabel, 3); 5354c58f1c22SToby Isaac *hasLabel = PETSC_FALSE; 5355c58f1c22SToby Isaac while (next) { 5356c58f1c22SToby Isaac ierr = PetscStrcmp(name, next->label->name, hasLabel);CHKERRQ(ierr); 5357c58f1c22SToby Isaac if (*hasLabel) break; 5358c58f1c22SToby Isaac next = next->next; 5359c58f1c22SToby Isaac } 5360c58f1c22SToby Isaac PetscFunctionReturn(0); 5361c58f1c22SToby Isaac } 5362c58f1c22SToby Isaac 5363c58f1c22SToby Isaac /*@C 5364c58f1c22SToby Isaac DMGetLabel - Return the label of a given name, or NULL 5365c58f1c22SToby Isaac 5366c58f1c22SToby Isaac Not Collective 5367c58f1c22SToby Isaac 5368c58f1c22SToby Isaac Input Parameters: 5369c58f1c22SToby Isaac + dm - The DM object 5370c58f1c22SToby Isaac - name - The label name 5371c58f1c22SToby Isaac 5372c58f1c22SToby Isaac Output Parameter: 5373c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent 5374c58f1c22SToby Isaac 5375c58f1c22SToby Isaac Level: intermediate 5376c58f1c22SToby Isaac 5377c58f1c22SToby Isaac .keywords: mesh 5378c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5379c58f1c22SToby Isaac @*/ 5380c58f1c22SToby Isaac PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label) 5381c58f1c22SToby Isaac { 5382c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5383c58f1c22SToby Isaac PetscBool hasLabel; 5384c58f1c22SToby Isaac PetscErrorCode ierr; 5385c58f1c22SToby Isaac 5386c58f1c22SToby Isaac PetscFunctionBegin; 5387c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5388c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5389c58f1c22SToby Isaac PetscValidPointer(label, 3); 5390c58f1c22SToby Isaac *label = NULL; 5391c58f1c22SToby Isaac while (next) { 5392c58f1c22SToby Isaac ierr = PetscStrcmp(name, next->label->name, &hasLabel);CHKERRQ(ierr); 5393c58f1c22SToby Isaac if (hasLabel) { 5394c58f1c22SToby Isaac *label = next->label; 5395c58f1c22SToby Isaac break; 5396c58f1c22SToby Isaac } 5397c58f1c22SToby Isaac next = next->next; 5398c58f1c22SToby Isaac } 5399c58f1c22SToby Isaac PetscFunctionReturn(0); 5400c58f1c22SToby Isaac } 5401c58f1c22SToby Isaac 5402c58f1c22SToby Isaac /*@C 5403c58f1c22SToby Isaac DMGetLabelByNum - Return the nth label 5404c58f1c22SToby Isaac 5405c58f1c22SToby Isaac Not Collective 5406c58f1c22SToby Isaac 5407c58f1c22SToby Isaac Input Parameters: 5408c58f1c22SToby Isaac + dm - The DM object 5409c58f1c22SToby Isaac - n - the label number 5410c58f1c22SToby Isaac 5411c58f1c22SToby Isaac Output Parameter: 5412c58f1c22SToby Isaac . label - the label 5413c58f1c22SToby Isaac 5414c58f1c22SToby Isaac Level: intermediate 5415c58f1c22SToby Isaac 5416c58f1c22SToby Isaac .keywords: mesh 5417c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5418c58f1c22SToby Isaac @*/ 5419c58f1c22SToby Isaac PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label) 5420c58f1c22SToby Isaac { 5421c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5422c58f1c22SToby Isaac PetscInt l = 0; 5423c58f1c22SToby Isaac 5424c58f1c22SToby Isaac PetscFunctionBegin; 5425c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5426c58f1c22SToby Isaac PetscValidPointer(label, 3); 5427c58f1c22SToby Isaac while (next) { 5428c58f1c22SToby Isaac if (l == n) { 5429c58f1c22SToby Isaac *label = next->label; 5430c58f1c22SToby Isaac PetscFunctionReturn(0); 5431c58f1c22SToby Isaac } 5432c58f1c22SToby Isaac ++l; 5433c58f1c22SToby Isaac next = next->next; 5434c58f1c22SToby Isaac } 5435c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n); 5436c58f1c22SToby Isaac } 5437c58f1c22SToby Isaac 5438c58f1c22SToby Isaac /*@C 5439c58f1c22SToby Isaac DMAddLabel - Add the label to this mesh 5440c58f1c22SToby Isaac 5441c58f1c22SToby Isaac Not Collective 5442c58f1c22SToby Isaac 5443c58f1c22SToby Isaac Input Parameters: 5444c58f1c22SToby Isaac + dm - The DM object 5445c58f1c22SToby Isaac - label - The DMLabel 5446c58f1c22SToby Isaac 5447c58f1c22SToby Isaac Level: developer 5448c58f1c22SToby Isaac 5449c58f1c22SToby Isaac .keywords: mesh 5450c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5451c58f1c22SToby Isaac @*/ 5452c58f1c22SToby Isaac PetscErrorCode DMAddLabel(DM dm, DMLabel label) 5453c58f1c22SToby Isaac { 5454c58f1c22SToby Isaac DMLabelLink tmpLabel; 5455c58f1c22SToby Isaac PetscBool hasLabel; 5456c58f1c22SToby Isaac PetscErrorCode ierr; 5457c58f1c22SToby Isaac 5458c58f1c22SToby Isaac PetscFunctionBegin; 5459c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5460c58f1c22SToby Isaac ierr = DMHasLabel(dm, label->name, &hasLabel);CHKERRQ(ierr); 5461c58f1c22SToby Isaac if (hasLabel) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", label->name); 5462c58f1c22SToby Isaac ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr); 5463c58f1c22SToby Isaac tmpLabel->label = label; 5464c58f1c22SToby Isaac tmpLabel->output = PETSC_TRUE; 5465c58f1c22SToby Isaac tmpLabel->next = dm->labels->next; 5466c58f1c22SToby Isaac dm->labels->next = tmpLabel; 5467c58f1c22SToby Isaac PetscFunctionReturn(0); 5468c58f1c22SToby Isaac } 5469c58f1c22SToby Isaac 5470c58f1c22SToby Isaac /*@C 5471c58f1c22SToby Isaac DMRemoveLabel - Remove the label from this mesh 5472c58f1c22SToby Isaac 5473c58f1c22SToby Isaac Not Collective 5474c58f1c22SToby Isaac 5475c58f1c22SToby Isaac Input Parameters: 5476c58f1c22SToby Isaac + dm - The DM object 5477c58f1c22SToby Isaac - name - The label name 5478c58f1c22SToby Isaac 5479c58f1c22SToby Isaac Output Parameter: 5480c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent 5481c58f1c22SToby Isaac 5482c58f1c22SToby Isaac Level: developer 5483c58f1c22SToby Isaac 5484c58f1c22SToby Isaac .keywords: mesh 5485c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5486c58f1c22SToby Isaac @*/ 5487c58f1c22SToby Isaac PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label) 5488c58f1c22SToby Isaac { 5489c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5490c58f1c22SToby Isaac DMLabelLink last = NULL; 5491c58f1c22SToby Isaac PetscBool hasLabel; 5492c58f1c22SToby Isaac PetscErrorCode ierr; 5493c58f1c22SToby Isaac 5494c58f1c22SToby Isaac PetscFunctionBegin; 5495c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5496c58f1c22SToby Isaac ierr = DMHasLabel(dm, name, &hasLabel);CHKERRQ(ierr); 5497c58f1c22SToby Isaac *label = NULL; 5498c58f1c22SToby Isaac if (!hasLabel) PetscFunctionReturn(0); 5499c58f1c22SToby Isaac while (next) { 5500c58f1c22SToby Isaac ierr = PetscStrcmp(name, next->label->name, &hasLabel);CHKERRQ(ierr); 5501c58f1c22SToby Isaac if (hasLabel) { 5502c58f1c22SToby Isaac if (last) last->next = next->next; 5503c58f1c22SToby Isaac else dm->labels->next = next->next; 5504c58f1c22SToby Isaac next->next = NULL; 5505c58f1c22SToby Isaac *label = next->label; 5506c58f1c22SToby Isaac ierr = PetscStrcmp(name, "depth", &hasLabel);CHKERRQ(ierr); 5507c58f1c22SToby Isaac if (hasLabel) { 5508c58f1c22SToby Isaac dm->depthLabel = NULL; 5509c58f1c22SToby Isaac } 5510c58f1c22SToby Isaac ierr = PetscFree(next);CHKERRQ(ierr); 5511c58f1c22SToby Isaac break; 5512c58f1c22SToby Isaac } 5513c58f1c22SToby Isaac last = next; 5514c58f1c22SToby Isaac next = next->next; 5515c58f1c22SToby Isaac } 5516c58f1c22SToby Isaac PetscFunctionReturn(0); 5517c58f1c22SToby Isaac } 5518c58f1c22SToby Isaac 5519c58f1c22SToby Isaac /*@C 5520c58f1c22SToby Isaac DMGetLabelOutput - Get the output flag for a given label 5521c58f1c22SToby Isaac 5522c58f1c22SToby Isaac Not Collective 5523c58f1c22SToby Isaac 5524c58f1c22SToby Isaac Input Parameters: 5525c58f1c22SToby Isaac + dm - The DM object 5526c58f1c22SToby Isaac - name - The label name 5527c58f1c22SToby Isaac 5528c58f1c22SToby Isaac Output Parameter: 5529c58f1c22SToby Isaac . output - The flag for output 5530c58f1c22SToby Isaac 5531c58f1c22SToby Isaac Level: developer 5532c58f1c22SToby Isaac 5533c58f1c22SToby Isaac .keywords: mesh 5534c58f1c22SToby Isaac .seealso: DMSetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5535c58f1c22SToby Isaac @*/ 5536c58f1c22SToby Isaac PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output) 5537c58f1c22SToby Isaac { 5538c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5539c58f1c22SToby Isaac PetscErrorCode ierr; 5540c58f1c22SToby Isaac 5541c58f1c22SToby Isaac PetscFunctionBegin; 5542c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5543c58f1c22SToby Isaac PetscValidPointer(name, 2); 5544c58f1c22SToby Isaac PetscValidPointer(output, 3); 5545c58f1c22SToby Isaac while (next) { 5546c58f1c22SToby Isaac PetscBool flg; 5547c58f1c22SToby Isaac 5548c58f1c22SToby Isaac ierr = PetscStrcmp(name, next->label->name, &flg);CHKERRQ(ierr); 5549c58f1c22SToby Isaac if (flg) {*output = next->output; PetscFunctionReturn(0);} 5550c58f1c22SToby Isaac next = next->next; 5551c58f1c22SToby Isaac } 5552c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 5553c58f1c22SToby Isaac } 5554c58f1c22SToby Isaac 5555c58f1c22SToby Isaac /*@C 5556c58f1c22SToby Isaac DMSetLabelOutput - Set the output flag for a given label 5557c58f1c22SToby Isaac 5558c58f1c22SToby Isaac Not Collective 5559c58f1c22SToby Isaac 5560c58f1c22SToby Isaac Input Parameters: 5561c58f1c22SToby Isaac + dm - The DM object 5562c58f1c22SToby Isaac . name - The label name 5563c58f1c22SToby Isaac - output - The flag for output 5564c58f1c22SToby Isaac 5565c58f1c22SToby Isaac Level: developer 5566c58f1c22SToby Isaac 5567c58f1c22SToby Isaac .keywords: mesh 5568c58f1c22SToby Isaac .seealso: DMGetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5569c58f1c22SToby Isaac @*/ 5570c58f1c22SToby Isaac PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output) 5571c58f1c22SToby Isaac { 5572c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5573c58f1c22SToby Isaac PetscErrorCode ierr; 5574c58f1c22SToby Isaac 5575c58f1c22SToby Isaac PetscFunctionBegin; 5576c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5577c58f1c22SToby Isaac PetscValidPointer(name, 2); 5578c58f1c22SToby Isaac while (next) { 5579c58f1c22SToby Isaac PetscBool flg; 5580c58f1c22SToby Isaac 5581c58f1c22SToby Isaac ierr = PetscStrcmp(name, next->label->name, &flg);CHKERRQ(ierr); 5582c58f1c22SToby Isaac if (flg) {next->output = output; PetscFunctionReturn(0);} 5583c58f1c22SToby Isaac next = next->next; 5584c58f1c22SToby Isaac } 5585c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 5586c58f1c22SToby Isaac } 5587c58f1c22SToby Isaac 5588c58f1c22SToby Isaac 5589c58f1c22SToby Isaac /*@ 5590c58f1c22SToby Isaac DMCopyLabels - Copy labels from one mesh to another with a superset of the points 5591c58f1c22SToby Isaac 5592c58f1c22SToby Isaac Collective on DM 5593c58f1c22SToby Isaac 5594c58f1c22SToby Isaac Input Parameter: 55952e17dfb7SMatthew G. Knepley . dmA - The DM object with initial labels 5596c58f1c22SToby Isaac 5597c58f1c22SToby Isaac Output Parameter: 55982e17dfb7SMatthew G. Knepley . dmB - The DM object with copied labels 5599c58f1c22SToby Isaac 5600c58f1c22SToby Isaac Level: intermediate 5601c58f1c22SToby Isaac 5602c58f1c22SToby Isaac Note: This is typically used when interpolating or otherwise adding to a mesh 5603c58f1c22SToby Isaac 5604c58f1c22SToby Isaac .keywords: mesh 5605c58f1c22SToby Isaac .seealso: DMCopyCoordinates(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMGetCoordinateSection() 5606c58f1c22SToby Isaac @*/ 5607c58f1c22SToby Isaac PetscErrorCode DMCopyLabels(DM dmA, DM dmB) 5608c58f1c22SToby Isaac { 5609c58f1c22SToby Isaac PetscInt numLabels, l; 5610c58f1c22SToby Isaac PetscErrorCode ierr; 5611c58f1c22SToby Isaac 5612c58f1c22SToby Isaac PetscFunctionBegin; 5613c58f1c22SToby Isaac if (dmA == dmB) PetscFunctionReturn(0); 5614c58f1c22SToby Isaac ierr = DMGetNumLabels(dmA, &numLabels);CHKERRQ(ierr); 5615c58f1c22SToby Isaac for (l = 0; l < numLabels; ++l) { 5616c58f1c22SToby Isaac DMLabel label, labelNew; 5617c58f1c22SToby Isaac const char *name; 5618c58f1c22SToby Isaac PetscBool flg; 5619c58f1c22SToby Isaac 5620c58f1c22SToby Isaac ierr = DMGetLabelName(dmA, l, &name);CHKERRQ(ierr); 5621c58f1c22SToby Isaac ierr = PetscStrcmp(name, "depth", &flg);CHKERRQ(ierr); 5622c58f1c22SToby Isaac if (flg) continue; 5623c58f1c22SToby Isaac ierr = DMGetLabel(dmA, name, &label);CHKERRQ(ierr); 5624c58f1c22SToby Isaac ierr = DMLabelDuplicate(label, &labelNew);CHKERRQ(ierr); 5625c58f1c22SToby Isaac ierr = DMAddLabel(dmB, labelNew);CHKERRQ(ierr); 5626c58f1c22SToby Isaac } 5627c58f1c22SToby Isaac PetscFunctionReturn(0); 5628c58f1c22SToby Isaac } 5629a8fb8f29SToby Isaac 5630a8fb8f29SToby Isaac /*@ 5631a8fb8f29SToby Isaac DMGetCoarseDM - Get the coarse mesh from which this was obtained by refinement 5632a8fb8f29SToby Isaac 5633a8fb8f29SToby Isaac Input Parameter: 5634a8fb8f29SToby Isaac . dm - The DM object 5635a8fb8f29SToby Isaac 5636a8fb8f29SToby Isaac Output Parameter: 5637a8fb8f29SToby Isaac . cdm - The coarse DM 5638a8fb8f29SToby Isaac 5639a8fb8f29SToby Isaac Level: intermediate 5640a8fb8f29SToby Isaac 5641a8fb8f29SToby Isaac .seealso: DMSetCoarseDM() 5642a8fb8f29SToby Isaac @*/ 5643a8fb8f29SToby Isaac PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm) 5644a8fb8f29SToby Isaac { 5645a8fb8f29SToby Isaac PetscFunctionBegin; 5646a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5647a8fb8f29SToby Isaac PetscValidPointer(cdm, 2); 5648a8fb8f29SToby Isaac *cdm = dm->coarseMesh; 5649a8fb8f29SToby Isaac PetscFunctionReturn(0); 5650a8fb8f29SToby Isaac } 5651a8fb8f29SToby Isaac 5652a8fb8f29SToby Isaac /*@ 5653a8fb8f29SToby Isaac DMSetCoarseDM - Set the coarse mesh from which this was obtained by refinement 5654a8fb8f29SToby Isaac 5655a8fb8f29SToby Isaac Input Parameters: 5656a8fb8f29SToby Isaac + dm - The DM object 5657a8fb8f29SToby Isaac - cdm - The coarse DM 5658a8fb8f29SToby Isaac 5659a8fb8f29SToby Isaac Level: intermediate 5660a8fb8f29SToby Isaac 5661a8fb8f29SToby Isaac .seealso: DMGetCoarseDM() 5662a8fb8f29SToby Isaac @*/ 5663a8fb8f29SToby Isaac PetscErrorCode DMSetCoarseDM(DM dm, DM cdm) 5664a8fb8f29SToby Isaac { 5665a8fb8f29SToby Isaac PetscErrorCode ierr; 5666a8fb8f29SToby Isaac 5667a8fb8f29SToby Isaac PetscFunctionBegin; 5668a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5669a8fb8f29SToby Isaac if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 5670a8fb8f29SToby Isaac ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr); 5671a8fb8f29SToby Isaac ierr = DMDestroy(&dm->coarseMesh);CHKERRQ(ierr); 5672a8fb8f29SToby Isaac dm->coarseMesh = cdm; 5673a8fb8f29SToby Isaac PetscFunctionReturn(0); 5674a8fb8f29SToby Isaac } 5675a8fb8f29SToby Isaac 567688bdff64SToby Isaac /*@ 567788bdff64SToby Isaac DMGetFineDM - Get the fine mesh from which this was obtained by refinement 567888bdff64SToby Isaac 567988bdff64SToby Isaac Input Parameter: 568088bdff64SToby Isaac . dm - The DM object 568188bdff64SToby Isaac 568288bdff64SToby Isaac Output Parameter: 568388bdff64SToby Isaac . fdm - The fine DM 568488bdff64SToby Isaac 568588bdff64SToby Isaac Level: intermediate 568688bdff64SToby Isaac 568788bdff64SToby Isaac .seealso: DMSetFineDM() 568888bdff64SToby Isaac @*/ 568988bdff64SToby Isaac PetscErrorCode DMGetFineDM(DM dm, DM *fdm) 569088bdff64SToby Isaac { 569188bdff64SToby Isaac PetscFunctionBegin; 569288bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 569388bdff64SToby Isaac PetscValidPointer(fdm, 2); 569488bdff64SToby Isaac *fdm = dm->fineMesh; 569588bdff64SToby Isaac PetscFunctionReturn(0); 569688bdff64SToby Isaac } 569788bdff64SToby Isaac 569888bdff64SToby Isaac /*@ 569988bdff64SToby Isaac DMSetFineDM - Set the fine mesh from which this was obtained by refinement 570088bdff64SToby Isaac 570188bdff64SToby Isaac Input Parameters: 570288bdff64SToby Isaac + dm - The DM object 570388bdff64SToby Isaac - fdm - The fine DM 570488bdff64SToby Isaac 570588bdff64SToby Isaac Level: intermediate 570688bdff64SToby Isaac 570788bdff64SToby Isaac .seealso: DMGetFineDM() 570888bdff64SToby Isaac @*/ 570988bdff64SToby Isaac PetscErrorCode DMSetFineDM(DM dm, DM fdm) 571088bdff64SToby Isaac { 571188bdff64SToby Isaac PetscErrorCode ierr; 571288bdff64SToby Isaac 571388bdff64SToby Isaac PetscFunctionBegin; 571488bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 571588bdff64SToby Isaac if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2); 571688bdff64SToby Isaac ierr = PetscObjectReference((PetscObject)fdm);CHKERRQ(ierr); 571788bdff64SToby Isaac ierr = DMDestroy(&dm->fineMesh);CHKERRQ(ierr); 571888bdff64SToby Isaac dm->fineMesh = fdm; 571988bdff64SToby Isaac PetscFunctionReturn(0); 572088bdff64SToby Isaac } 572188bdff64SToby Isaac 5722a6ba4734SToby Isaac /*=== DMBoundary code ===*/ 5723a6ba4734SToby Isaac 5724a6ba4734SToby Isaac PetscErrorCode DMCopyBoundary(DM dm, DM dmNew) 5725a6ba4734SToby Isaac { 5726a6ba4734SToby Isaac PetscErrorCode ierr; 5727a6ba4734SToby Isaac 5728a6ba4734SToby Isaac PetscFunctionBegin; 5729e6f8dbb6SToby Isaac ierr = PetscDSCopyBoundary(dm->prob,dmNew->prob);CHKERRQ(ierr); 5730a6ba4734SToby Isaac PetscFunctionReturn(0); 5731a6ba4734SToby Isaac } 5732a6ba4734SToby Isaac 5733a6ba4734SToby Isaac /*@C 5734a6ba4734SToby Isaac DMAddBoundary - Add a boundary condition to the model 5735a6ba4734SToby Isaac 5736a6ba4734SToby Isaac Input Parameters: 57374c258f51SMatthew G. Knepley + dm - The DM, with a PetscDS that matches the problem being constrained 5738f971fd6bSMatthew G. Knepley . type - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann) 5739a6ba4734SToby Isaac . name - The BC name 5740a6ba4734SToby Isaac . labelname - The label defining constrained points 5741a6ba4734SToby Isaac . field - The field to constrain 5742a6ba4734SToby Isaac . numcomps - The number of constrained field components 5743a6ba4734SToby Isaac . comps - An array of constrained component numbers 5744a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 5745a6ba4734SToby Isaac . numids - The number of DMLabel ids for constrained points 5746a6ba4734SToby Isaac . ids - An array of ids for constrained points 5747a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 5748a6ba4734SToby Isaac 5749a6ba4734SToby Isaac Options Database Keys: 5750a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 5751a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 5752a6ba4734SToby Isaac 5753a6ba4734SToby Isaac Level: developer 5754a6ba4734SToby Isaac 5755a6ba4734SToby Isaac .seealso: DMGetBoundary() 5756a6ba4734SToby Isaac @*/ 5757a30ec4eaSSatish Balay PetscErrorCode DMAddBoundary(DM dm, DMBoundaryConditionType type, const char name[], const char labelname[], PetscInt field, PetscInt numcomps, const PetscInt *comps, void (*bcFunc)(void), PetscInt numids, const PetscInt *ids, void *ctx) 5758a6ba4734SToby Isaac { 5759a6ba4734SToby Isaac PetscErrorCode ierr; 5760a6ba4734SToby Isaac 5761a6ba4734SToby Isaac PetscFunctionBegin; 5762a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5763f971fd6bSMatthew G. Knepley ierr = PetscDSAddBoundary(dm->prob,type,name,labelname,field,numcomps,comps,bcFunc,numids,ids,ctx);CHKERRQ(ierr); 5764a6ba4734SToby Isaac PetscFunctionReturn(0); 5765a6ba4734SToby Isaac } 5766a6ba4734SToby Isaac 5767a6ba4734SToby Isaac /*@ 5768a6ba4734SToby Isaac DMGetNumBoundary - Get the number of registered BC 5769a6ba4734SToby Isaac 5770a6ba4734SToby Isaac Input Parameters: 5771a6ba4734SToby Isaac . dm - The mesh object 5772a6ba4734SToby Isaac 5773a6ba4734SToby Isaac Output Parameters: 5774a6ba4734SToby Isaac . numBd - The number of BC 5775a6ba4734SToby Isaac 5776a6ba4734SToby Isaac Level: intermediate 5777a6ba4734SToby Isaac 5778a6ba4734SToby Isaac .seealso: DMAddBoundary(), DMGetBoundary() 5779a6ba4734SToby Isaac @*/ 5780a6ba4734SToby Isaac PetscErrorCode DMGetNumBoundary(DM dm, PetscInt *numBd) 5781a6ba4734SToby Isaac { 578258ebd649SToby Isaac PetscErrorCode ierr; 5783a6ba4734SToby Isaac 5784a6ba4734SToby Isaac PetscFunctionBegin; 5785a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 578658ebd649SToby Isaac ierr = PetscDSGetNumBoundary(dm->prob,numBd);CHKERRQ(ierr); 5787a6ba4734SToby Isaac PetscFunctionReturn(0); 5788a6ba4734SToby Isaac } 5789a6ba4734SToby Isaac 5790a6ba4734SToby Isaac /*@C 5791a6ba4734SToby Isaac DMGetBoundary - Add a boundary condition to the model 5792a6ba4734SToby Isaac 5793a6ba4734SToby Isaac Input Parameters: 5794a6ba4734SToby Isaac + dm - The mesh object 5795a6ba4734SToby Isaac - bd - The BC number 5796a6ba4734SToby Isaac 5797a6ba4734SToby Isaac Output Parameters: 5798f971fd6bSMatthew G. Knepley + type - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann) 5799a6ba4734SToby Isaac . name - The BC name 5800a6ba4734SToby Isaac . labelname - The label defining constrained points 5801a6ba4734SToby Isaac . field - The field to constrain 5802a6ba4734SToby Isaac . numcomps - The number of constrained field components 5803a6ba4734SToby Isaac . comps - An array of constrained component numbers 5804a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 5805a6ba4734SToby Isaac . numids - The number of DMLabel ids for constrained points 5806a6ba4734SToby Isaac . ids - An array of ids for constrained points 5807a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 5808a6ba4734SToby Isaac 5809a6ba4734SToby Isaac Options Database Keys: 5810a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 5811a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 5812a6ba4734SToby Isaac 5813a6ba4734SToby Isaac Level: developer 5814a6ba4734SToby Isaac 5815a6ba4734SToby Isaac .seealso: DMAddBoundary() 5816a6ba4734SToby Isaac @*/ 5817a30ec4eaSSatish Balay PetscErrorCode DMGetBoundary(DM dm, PetscInt bd, DMBoundaryConditionType *type, const char **name, const char **labelname, PetscInt *field, PetscInt *numcomps, const PetscInt **comps, void (**func)(void), PetscInt *numids, const PetscInt **ids, void **ctx) 5818a6ba4734SToby Isaac { 581958ebd649SToby Isaac PetscErrorCode ierr; 5820a6ba4734SToby Isaac 5821a6ba4734SToby Isaac PetscFunctionBegin; 5822a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5823f971fd6bSMatthew G. Knepley ierr = PetscDSGetBoundary(dm->prob,bd,type,name,labelname,field,numcomps,comps,func,numids,ids,ctx);CHKERRQ(ierr); 5824a6ba4734SToby Isaac PetscFunctionReturn(0); 5825a6ba4734SToby Isaac } 5826a6ba4734SToby Isaac 5827e6f8dbb6SToby Isaac static PetscErrorCode DMPopulateBoundary(DM dm) 5828e6f8dbb6SToby Isaac { 5829dff059c6SToby Isaac DMBoundary *lastnext; 5830e6f8dbb6SToby Isaac DSBoundary dsbound; 5831e6f8dbb6SToby Isaac PetscErrorCode ierr; 5832e6f8dbb6SToby Isaac 5833e6f8dbb6SToby Isaac PetscFunctionBegin; 5834e6f8dbb6SToby Isaac dsbound = dm->prob->boundary; 583547a1f5adSToby Isaac if (dm->boundary) { 583647a1f5adSToby Isaac DMBoundary next = dm->boundary; 583747a1f5adSToby Isaac 583847a1f5adSToby Isaac /* quick check to see if the PetscDS has changed */ 583947a1f5adSToby Isaac if (next->dsboundary == dsbound) PetscFunctionReturn(0); 584047a1f5adSToby Isaac /* the PetscDS has changed: tear down and rebuild */ 584147a1f5adSToby Isaac while (next) { 584247a1f5adSToby Isaac DMBoundary b = next; 584347a1f5adSToby Isaac 584447a1f5adSToby Isaac next = b->next; 584547a1f5adSToby Isaac ierr = PetscFree(b);CHKERRQ(ierr); 5846a6ba4734SToby Isaac } 584747a1f5adSToby Isaac dm->boundary = NULL; 5848a6ba4734SToby Isaac } 584947a1f5adSToby Isaac 5850dff059c6SToby Isaac lastnext = &(dm->boundary); 5851e6f8dbb6SToby Isaac while (dsbound) { 5852e6f8dbb6SToby Isaac DMBoundary dmbound; 5853e6f8dbb6SToby Isaac 5854e6f8dbb6SToby Isaac ierr = PetscNew(&dmbound);CHKERRQ(ierr); 5855e6f8dbb6SToby Isaac dmbound->dsboundary = dsbound; 5856e6f8dbb6SToby Isaac ierr = DMGetLabel(dm, dsbound->labelname, &(dmbound->label));CHKERRQ(ierr); 5857e6f8dbb6SToby Isaac if (!dmbound->label) PetscInfo2(dm, "DSBoundary %s wants label %s, which is not in this dm.\n",dsbound->name,dsbound->labelname);CHKERRQ(ierr); 585847a1f5adSToby Isaac /* push on the back instead of the front so that it is in the same order as in the PetscDS */ 5859dff059c6SToby Isaac *lastnext = dmbound; 5860dff059c6SToby Isaac lastnext = &(dmbound->next); 5861dff059c6SToby Isaac dsbound = dsbound->next; 5862a6ba4734SToby Isaac } 5863a6ba4734SToby Isaac PetscFunctionReturn(0); 5864a6ba4734SToby Isaac } 5865a6ba4734SToby Isaac 5866a6ba4734SToby Isaac PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd) 5867a6ba4734SToby Isaac { 5868b95f2879SToby Isaac DMBoundary b; 5869a6ba4734SToby Isaac PetscErrorCode ierr; 5870a6ba4734SToby Isaac 5871a6ba4734SToby Isaac PetscFunctionBegin; 5872a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5873a6ba4734SToby Isaac PetscValidPointer(isBd, 3); 5874a6ba4734SToby Isaac *isBd = PETSC_FALSE; 5875e6f8dbb6SToby Isaac ierr = DMPopulateBoundary(dm);CHKERRQ(ierr); 5876b95f2879SToby Isaac b = dm->boundary; 5877a6ba4734SToby Isaac while (b && !(*isBd)) { 5878e6f8dbb6SToby Isaac DMLabel label = b->label; 5879e6f8dbb6SToby Isaac DSBoundary dsb = b->dsboundary; 58803424c85cSToby Isaac 58813424c85cSToby Isaac if (label) { 5882a6ba4734SToby Isaac PetscInt i; 5883a6ba4734SToby Isaac 5884e6f8dbb6SToby Isaac for (i = 0; i < dsb->numids && !(*isBd); ++i) { 5885e6f8dbb6SToby Isaac ierr = DMLabelStratumHasPoint(label, dsb->ids[i], point, isBd);CHKERRQ(ierr); 5886a6ba4734SToby Isaac } 5887a6ba4734SToby Isaac } 5888a6ba4734SToby Isaac b = b->next; 5889a6ba4734SToby Isaac } 5890a6ba4734SToby Isaac PetscFunctionReturn(0); 5891a6ba4734SToby Isaac } 58924d6f44ffSToby Isaac 58934d6f44ffSToby Isaac /*@C 58944d6f44ffSToby Isaac DMProjectFunction - This projects the given function into the function space provided. 58954d6f44ffSToby Isaac 58964d6f44ffSToby Isaac Input Parameters: 58974d6f44ffSToby Isaac + dm - The DM 58980709b2feSToby Isaac . time - The time 58994d6f44ffSToby Isaac . funcs - The coordinate functions to evaluate, one per field 59004d6f44ffSToby Isaac . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 59014d6f44ffSToby Isaac - mode - The insertion mode for values 59024d6f44ffSToby Isaac 59034d6f44ffSToby Isaac Output Parameter: 59044d6f44ffSToby Isaac . X - vector 59054d6f44ffSToby Isaac 59064d6f44ffSToby Isaac Calling sequence of func: 59070709b2feSToby Isaac $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 59084d6f44ffSToby Isaac 59094d6f44ffSToby Isaac + dim - The spatial dimension 59104d6f44ffSToby Isaac . x - The coordinates 59114d6f44ffSToby Isaac . Nf - The number of fields 59124d6f44ffSToby Isaac . u - The output field values 59134d6f44ffSToby Isaac - ctx - optional user-defined function context 59144d6f44ffSToby Isaac 59154d6f44ffSToby Isaac Level: developer 59164d6f44ffSToby Isaac 59172716604bSToby Isaac .seealso: DMComputeL2Diff() 59184d6f44ffSToby Isaac @*/ 59190709b2feSToby Isaac PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X) 59204d6f44ffSToby Isaac { 59214d6f44ffSToby Isaac Vec localX; 59224d6f44ffSToby Isaac PetscErrorCode ierr; 59234d6f44ffSToby Isaac 59244d6f44ffSToby Isaac PetscFunctionBegin; 59254d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 59264d6f44ffSToby Isaac ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr); 59270709b2feSToby Isaac ierr = DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr); 59284d6f44ffSToby Isaac ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr); 59294d6f44ffSToby Isaac ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr); 59304d6f44ffSToby Isaac ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr); 59314d6f44ffSToby Isaac PetscFunctionReturn(0); 59324d6f44ffSToby Isaac } 59334d6f44ffSToby Isaac 59340709b2feSToby Isaac PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 59354d6f44ffSToby Isaac { 59364d6f44ffSToby Isaac PetscErrorCode ierr; 59374d6f44ffSToby Isaac 59384d6f44ffSToby Isaac PetscFunctionBegin; 59394d6f44ffSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 59404d6f44ffSToby Isaac PetscValidHeaderSpecific(localX,VEC_CLASSID,5); 59414d6f44ffSToby Isaac if (!dm->ops->projectfunctionlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implemnt DMProjectFunctionLocal",((PetscObject)dm)->type_name); 59420709b2feSToby Isaac ierr = (dm->ops->projectfunctionlocal) (dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr); 59434d6f44ffSToby Isaac PetscFunctionReturn(0); 59444d6f44ffSToby Isaac } 59454d6f44ffSToby Isaac 59460709b2feSToby Isaac PetscErrorCode DMProjectFunctionLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 59474d6f44ffSToby Isaac { 59484d6f44ffSToby Isaac PetscErrorCode ierr; 59494d6f44ffSToby Isaac 59504d6f44ffSToby Isaac PetscFunctionBegin; 59514d6f44ffSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 59524d6f44ffSToby Isaac PetscValidHeaderSpecific(localX,VEC_CLASSID,5); 59534d6f44ffSToby Isaac if (!dm->ops->projectfunctionlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implemnt DMProjectFunctionLabelLocal",((PetscObject)dm)->type_name); 59540709b2feSToby Isaac ierr = (dm->ops->projectfunctionlabellocal) (dm, time, label, numIds, ids, funcs, ctxs, mode, localX);CHKERRQ(ierr); 59554d6f44ffSToby Isaac PetscFunctionReturn(0); 59564d6f44ffSToby Isaac } 59572716604bSToby Isaac 59588c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal(DM dm, PetscReal time, Vec localU, 59598c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 59608c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 59618c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 5962191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 59638c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 59648c6c5593SMatthew G. Knepley { 59658c6c5593SMatthew G. Knepley PetscErrorCode ierr; 59668c6c5593SMatthew G. Knepley 59678c6c5593SMatthew G. Knepley PetscFunctionBegin; 59688c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 59698c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,3); 59708c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,6); 59718c6c5593SMatthew G. Knepley if (!dm->ops->projectfieldlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implemnt DMProjectFieldLocal",((PetscObject)dm)->type_name); 59728c6c5593SMatthew G. Knepley ierr = (dm->ops->projectfieldlocal) (dm, time, localU, funcs, mode, localX);CHKERRQ(ierr); 59738c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 59748c6c5593SMatthew G. Knepley } 59758c6c5593SMatthew G. Knepley 59768c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], Vec localU, 59778c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 59788c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 59798c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 5980191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 59818c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 59828c6c5593SMatthew G. Knepley { 59838c6c5593SMatthew G. Knepley PetscErrorCode ierr; 59848c6c5593SMatthew G. Knepley 59858c6c5593SMatthew G. Knepley PetscFunctionBegin; 59868c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 59878c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,6); 59888c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,9); 59898c6c5593SMatthew G. Knepley if (!dm->ops->projectfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implemnt DMProjectFieldLocal",((PetscObject)dm)->type_name); 59908c6c5593SMatthew G. Knepley ierr = (dm->ops->projectfieldlabellocal)(dm, time, label, numIds, ids, localU, funcs, mode, localX);CHKERRQ(ierr); 59918c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 59928c6c5593SMatthew G. Knepley } 59938c6c5593SMatthew G. Knepley 59942716604bSToby Isaac /*@C 59952716604bSToby Isaac DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h. 59962716604bSToby Isaac 59972716604bSToby Isaac Input Parameters: 59982716604bSToby Isaac + dm - The DM 59990709b2feSToby Isaac . time - The time 60002716604bSToby Isaac . funcs - The functions to evaluate for each field component 60012716604bSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 60022716604bSToby Isaac - X - The coefficient vector u_h 60032716604bSToby Isaac 60042716604bSToby Isaac Output Parameter: 60052716604bSToby Isaac . diff - The diff ||u - u_h||_2 60062716604bSToby Isaac 60072716604bSToby Isaac Level: developer 60082716604bSToby Isaac 60091189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff() 60102716604bSToby Isaac @*/ 60110709b2feSToby Isaac PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff) 60122716604bSToby Isaac { 60132716604bSToby Isaac PetscErrorCode ierr; 60142716604bSToby Isaac 60152716604bSToby Isaac PetscFunctionBegin; 60162716604bSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6017b698f381SToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 60182716604bSToby Isaac if (!dm->ops->computel2diff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implemnt DMComputeL2Diff",((PetscObject)dm)->type_name); 60190709b2feSToby Isaac ierr = (dm->ops->computel2diff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr); 60202716604bSToby Isaac PetscFunctionReturn(0); 60212716604bSToby Isaac } 6022b698f381SToby Isaac 6023b698f381SToby Isaac /*@C 6024b698f381SToby Isaac DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h. 6025b698f381SToby Isaac 6026b698f381SToby Isaac Input Parameters: 6027b698f381SToby Isaac + dm - The DM 6028b698f381SToby Isaac , time - The time 6029b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component 6030b698f381SToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 6031b698f381SToby Isaac . X - The coefficient vector u_h 6032b698f381SToby Isaac - n - The vector to project along 6033b698f381SToby Isaac 6034b698f381SToby Isaac Output Parameter: 6035b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2 6036b698f381SToby Isaac 6037b698f381SToby Isaac Level: developer 6038b698f381SToby Isaac 6039b698f381SToby Isaac .seealso: DMProjectFunction(), DMComputeL2Diff() 6040b698f381SToby Isaac @*/ 6041b698f381SToby Isaac PetscErrorCode DMComputeL2GradientDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, const PetscReal n[], PetscReal *diff) 6042b698f381SToby Isaac { 6043b698f381SToby Isaac PetscErrorCode ierr; 6044b698f381SToby Isaac 6045b698f381SToby Isaac PetscFunctionBegin; 6046b698f381SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6047b698f381SToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 6048b698f381SToby Isaac if (!dm->ops->computel2gradientdiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2GradientDiff",((PetscObject)dm)->type_name); 6049b698f381SToby Isaac ierr = (dm->ops->computel2gradientdiff)(dm,time,funcs,ctxs,X,n,diff);CHKERRQ(ierr); 6050b698f381SToby Isaac PetscFunctionReturn(0); 6051b698f381SToby Isaac } 6052b698f381SToby Isaac 60532a16baeaSToby Isaac /*@C 60542a16baeaSToby Isaac DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components. 60552a16baeaSToby Isaac 60562a16baeaSToby Isaac Input Parameters: 60572a16baeaSToby Isaac + dm - The DM 60582a16baeaSToby Isaac . time - The time 60592a16baeaSToby Isaac . funcs - The functions to evaluate for each field component 60602a16baeaSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 60612a16baeaSToby Isaac - X - The coefficient vector u_h 60622a16baeaSToby Isaac 60632a16baeaSToby Isaac Output Parameter: 60642a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2 60652a16baeaSToby Isaac 60662a16baeaSToby Isaac Level: developer 60672a16baeaSToby Isaac 60681189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff() 60692a16baeaSToby Isaac @*/ 60701189c1efSToby Isaac PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[]) 60712a16baeaSToby Isaac { 60722a16baeaSToby Isaac PetscErrorCode ierr; 60732a16baeaSToby Isaac 60742a16baeaSToby Isaac PetscFunctionBegin; 60752a16baeaSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 60762a16baeaSToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 60772a16baeaSToby Isaac if (!dm->ops->computel2fielddiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implemnt DMComputeL2FieldDiff",((PetscObject)dm)->type_name); 60782a16baeaSToby Isaac ierr = (dm->ops->computel2fielddiff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr); 60792a16baeaSToby Isaac PetscFunctionReturn(0); 60802a16baeaSToby Isaac } 60812a16baeaSToby Isaac 6082df0b854cSToby Isaac /*@C 6083df0b854cSToby Isaac DMAdaptLabel - Adapt a dm based on a label with values interpreted as coarsening and refining flags. Specific implementations of DM maybe have 6084cd3c525cSToby Isaac specialized flags, but all implementations should accept flag values DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN. 6085df0b854cSToby Isaac 6086df0b854cSToby Isaac Collective on dm 6087df0b854cSToby Isaac 6088df0b854cSToby Isaac Input parameters: 6089df0b854cSToby Isaac + dm - the pre-adaptation DM object 6090a1b0c543SToby Isaac - label - label with the flags 6091df0b854cSToby Isaac 6092df0b854cSToby Isaac Output parameters: 6093*0d1cd5e0SMatthew G. Knepley . dmAdapt - the adapted DM object: may be NULL if an adapted DM could not be produced. 6094df0b854cSToby Isaac 6095df0b854cSToby Isaac Level: intermediate 6096*0d1cd5e0SMatthew G. Knepley 6097*0d1cd5e0SMatthew G. Knepley .seealso: DMAdaptMetric(), DMCoarsen(), DMRefine() 6098df0b854cSToby Isaac @*/ 6099*0d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptLabel(DM dm, DMLabel label, DM *dmAdapt) 6100df0b854cSToby Isaac { 6101df0b854cSToby Isaac PetscErrorCode ierr; 6102df0b854cSToby Isaac 6103df0b854cSToby Isaac PetscFunctionBegin; 6104df0b854cSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6105a1b0c543SToby Isaac PetscValidPointer(label,2); 6106*0d1cd5e0SMatthew G. Knepley PetscValidPointer(dmAdapt,3); 6107*0d1cd5e0SMatthew G. Knepley *dmAdapt = NULL; 6108*0d1cd5e0SMatthew G. Knepley if (!dm->ops->adaptlabel) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implemnt DMAdaptLabel",((PetscObject)dm)->type_name); 6109*0d1cd5e0SMatthew G. Knepley ierr = (dm->ops->adaptlabel)(dm, label, dmAdapt);CHKERRQ(ierr); 6110*0d1cd5e0SMatthew G. Knepley PetscFunctionReturn(0); 6111*0d1cd5e0SMatthew G. Knepley } 6112*0d1cd5e0SMatthew G. Knepley 6113*0d1cd5e0SMatthew G. Knepley /*@C 6114*0d1cd5e0SMatthew G. Knepley DMAdaptMetric - Generates a mesh adapted to the specified metric field using the pragmatic library. 6115*0d1cd5e0SMatthew G. Knepley 6116*0d1cd5e0SMatthew G. Knepley Input Parameters: 6117*0d1cd5e0SMatthew G. Knepley + dm - The DM object 6118*0d1cd5e0SMatthew G. Knepley . metric - The metric to which the mesh is adapted, defined vertex-wise. 6119*0d1cd5e0SMatthew G. Knepley - bdLabel - Label for boundary tags, which will be preserved in the output mesh. bdLabel should be NULL if there is no such label, and should be different from "boundary". 6120*0d1cd5e0SMatthew G. Knepley 6121*0d1cd5e0SMatthew G. Knepley Output Parameter: 6122*0d1cd5e0SMatthew G. Knepley . dmAdapt - Pointer to the DM object containing the adapted mesh 6123*0d1cd5e0SMatthew G. Knepley 6124*0d1cd5e0SMatthew G. Knepley Note: The label in the adapted mesh will be registered under the name of the input DMLabel object 6125*0d1cd5e0SMatthew G. Knepley 6126*0d1cd5e0SMatthew G. Knepley Level: advanced 6127*0d1cd5e0SMatthew G. Knepley 6128*0d1cd5e0SMatthew G. Knepley .seealso: DMAdaptLabel(), DMCoarsen(), DMRefine() 6129*0d1cd5e0SMatthew G. Knepley @*/ 6130*0d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptMetric(DM dm, Vec metric, DMLabel bdLabel, DM *dmAdapt) 6131*0d1cd5e0SMatthew G. Knepley { 6132*0d1cd5e0SMatthew G. Knepley PetscErrorCode ierr; 6133*0d1cd5e0SMatthew G. Knepley 6134*0d1cd5e0SMatthew G. Knepley PetscFunctionBegin; 6135*0d1cd5e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6136*0d1cd5e0SMatthew G. Knepley PetscValidHeaderSpecific(metric, VEC_CLASSID, 2); 6137*0d1cd5e0SMatthew G. Knepley if (bdLabel) PetscValidPointer(bdLabel, 3); 6138*0d1cd5e0SMatthew G. Knepley PetscValidPointer(dmAdapt, 4); 6139*0d1cd5e0SMatthew G. Knepley if (!dm->ops->adaptlabel) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implemnt DMAdaptLabel",((PetscObject)dm)->type_name); 6140*0d1cd5e0SMatthew G. Knepley ierr = (dm->ops->adaptmetric)(dm, metric, bdLabel, dmAdapt);CHKERRQ(ierr); 6141df0b854cSToby Isaac PetscFunctionReturn(0); 6142df0b854cSToby Isaac } 6143c4088d22SMatthew G. Knepley 6144502a2867SDave May /*@C 6145502a2867SDave May DMGetNeighbors - Gets an array containing the MPI rank of all the processes neighbors 6146502a2867SDave May 6147502a2867SDave May Not Collective 6148502a2867SDave May 6149502a2867SDave May Input Parameter: 6150502a2867SDave May . dm - The DM 6151502a2867SDave May 6152502a2867SDave May Output Parameter: 6153502a2867SDave May . nranks - the number of neighbours 6154502a2867SDave May . ranks - the neighbors ranks 6155502a2867SDave May 6156502a2867SDave May Notes: 6157502a2867SDave May Do not free the array, it is freed when the DM is destroyed. 6158502a2867SDave May 6159502a2867SDave May Level: beginner 6160502a2867SDave May 6161dee935c1SDave May .seealso: DMDAGetNeighbors(), PetscSFGetRanks() 6162502a2867SDave May @*/ 6163502a2867SDave May PetscErrorCode DMGetNeighbors(DM dm,PetscInt *nranks,const PetscMPIInt *ranks[]) 6164502a2867SDave May { 6165502a2867SDave May PetscErrorCode ierr; 6166502a2867SDave May 6167502a2867SDave May PetscFunctionBegin; 6168502a2867SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6169502a2867SDave May if (!dm->ops->getneighbors) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implemnt DMGetNeighbors",((PetscObject)dm)->type_name); 6170502a2867SDave May ierr = (dm->ops->getneighbors)(dm,nranks,ranks);CHKERRQ(ierr); 6171502a2867SDave May PetscFunctionReturn(0); 6172502a2867SDave May } 6173502a2867SDave May 6174531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */ 6175531c7667SBarry Smith 6176531c7667SBarry Smith /* 6177531c7667SBarry Smith Converts the input vector to a ghosted vector and then calls the standard coloring code. 6178531c7667SBarry Smith This has be a different function because it requires DM which is not defined in the Mat library 6179531c7667SBarry Smith */ 6180531c7667SBarry Smith PetscErrorCode MatFDColoringApply_AIJDM(Mat J,MatFDColoring coloring,Vec x1,void *sctx) 6181531c7667SBarry Smith { 6182531c7667SBarry Smith PetscErrorCode ierr; 6183531c7667SBarry Smith 6184531c7667SBarry Smith PetscFunctionBegin; 6185531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 6186531c7667SBarry Smith Vec x1local; 6187531c7667SBarry Smith DM dm; 6188531c7667SBarry Smith ierr = MatGetDM(J,&dm);CHKERRQ(ierr); 6189531c7667SBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_INCOMP,"IS_COLORING_LOCAL requires a DM"); 6190531c7667SBarry Smith ierr = DMGetLocalVector(dm,&x1local);CHKERRQ(ierr); 6191531c7667SBarry Smith ierr = DMGlobalToLocalBegin(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr); 6192531c7667SBarry Smith ierr = DMGlobalToLocalEnd(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr); 6193531c7667SBarry Smith x1 = x1local; 6194531c7667SBarry Smith } 6195531c7667SBarry Smith ierr = MatFDColoringApply_AIJ(J,coloring,x1,sctx);CHKERRQ(ierr); 6196531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 6197531c7667SBarry Smith DM dm; 6198531c7667SBarry Smith ierr = MatGetDM(J,&dm);CHKERRQ(ierr); 6199531c7667SBarry Smith ierr = DMRestoreLocalVector(dm,&x1);CHKERRQ(ierr); 6200531c7667SBarry Smith } 6201531c7667SBarry Smith PetscFunctionReturn(0); 6202531c7667SBarry Smith } 6203531c7667SBarry Smith 6204531c7667SBarry Smith /*@ 6205531c7667SBarry Smith MatFDColoringUseDM - allows a MatFDColoring object to use the DM associated with the matrix to use a IS_COLORING_LOCAL coloring 6206531c7667SBarry Smith 6207531c7667SBarry Smith Input Parameter: 6208531c7667SBarry Smith . coloring - the MatFDColoring object 6209531c7667SBarry Smith 6210531c7667SBarry Smith Developer Notes: this routine exists because the PETSc Mat library does not know about the DM objects 6211531c7667SBarry Smith 62121b266c99SBarry Smith Level: advanced 62131b266c99SBarry Smith 6214531c7667SBarry Smith .seealso: MatFDColoring, MatFDColoringCreate(), ISColoringType 6215531c7667SBarry Smith @*/ 6216531c7667SBarry Smith PetscErrorCode MatFDColoringUseDM(Mat coloring,MatFDColoring fdcoloring) 6217531c7667SBarry Smith { 6218531c7667SBarry Smith PetscFunctionBegin; 6219531c7667SBarry Smith coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM; 6220531c7667SBarry Smith PetscFunctionReturn(0); 6221531c7667SBarry Smith } 6222