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> 5f19dbd58SToby Isaac #include <petscdmfield.h> 60c312b8eSJed Brown #include <petscsf.h> 72764a2aaSMatthew G. Knepley #include <petscds.h> 847c6ae99SBarry Smith 9732e2eb9SMatthew G Knepley PetscClassId DM_CLASSID; 101ac00216SMatthew G. Knepley PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal, DM_LocalToLocal, DM_LocatePoints, DM_Coarsen, DM_Refine, DM_CreateInterpolation, DM_CreateRestriction; 1167a56275SMatthew G Knepley 12e249ee26SToby Isaac const char *const DMBoundaryTypes[] = {"NONE","GHOSTED","MIRROR","PERIODIC","TWIST","DMBoundaryType","DM_BOUNDARY_",0}; 13bff4a2f0SMatthew G. Knepley 144a7a4c06SLawrence Mitchell static PetscErrorCode DMHasCreateInjection_Default(DM dm, PetscBool *flg) 154a7a4c06SLawrence Mitchell { 164a7a4c06SLawrence Mitchell PetscFunctionBegin; 174a7a4c06SLawrence Mitchell PetscValidHeaderSpecific(dm,DM_CLASSID,1); 184a7a4c06SLawrence Mitchell PetscValidPointer(flg,2); 194a7a4c06SLawrence Mitchell *flg = PETSC_FALSE; 204a7a4c06SLawrence Mitchell PetscFunctionReturn(0); 214a7a4c06SLawrence Mitchell } 224a7a4c06SLawrence Mitchell 23a4121054SBarry Smith /*@ 24de043629SMatthew G Knepley DMCreate - Creates an empty DM object. The type can then be set with DMSetType(). 25a4121054SBarry Smith 26a4121054SBarry Smith If you never call DMSetType() it will generate an 27a4121054SBarry Smith error when you try to use the vector. 28a4121054SBarry Smith 29a4121054SBarry Smith Collective on MPI_Comm 30a4121054SBarry Smith 31a4121054SBarry Smith Input Parameter: 32a4121054SBarry Smith . comm - The communicator for the DM object 33a4121054SBarry Smith 34a4121054SBarry Smith Output Parameter: 35a4121054SBarry Smith . dm - The DM object 36a4121054SBarry Smith 37a4121054SBarry Smith Level: beginner 38a4121054SBarry Smith 398472ad0fSDave May .seealso: DMSetType(), DMDA, DMSLICED, DMCOMPOSITE, DMPLEX, DMMOAB, DMNETWORK 40a4121054SBarry Smith @*/ 417087cfbeSBarry Smith PetscErrorCode DMCreate(MPI_Comm comm,DM *dm) 42a4121054SBarry Smith { 43a4121054SBarry Smith DM v; 44a4121054SBarry Smith PetscErrorCode ierr; 45a4121054SBarry Smith 46a4121054SBarry Smith PetscFunctionBegin; 471411c6eeSJed Brown PetscValidPointer(dm,2); 480298fd71SBarry Smith *dm = NULL; 498b984314SMatthew G. Knepley ierr = PetscSysInitializePackage();CHKERRQ(ierr); 50607a6623SBarry Smith ierr = VecInitializePackage();CHKERRQ(ierr); 51607a6623SBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 52607a6623SBarry Smith ierr = DMInitializePackage();CHKERRQ(ierr); 53a4121054SBarry Smith 5473107ff1SLisandro Dalcin ierr = PetscHeaderCreate(v, DM_CLASSID, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView);CHKERRQ(ierr); 55e7c4fc90SDmitry Karpeev 560298fd71SBarry Smith v->ltogmap = NULL; 571411c6eeSJed Brown v->bs = 1; 58171400e9SBarry Smith v->coloringtype = IS_COLORING_GLOBAL; 5988ed4aceSMatthew G Knepley ierr = PetscSFCreate(comm, &v->sf);CHKERRQ(ierr); 6088ed4aceSMatthew G Knepley ierr = PetscSFCreate(comm, &v->defaultSF);CHKERRQ(ierr); 61c58f1c22SToby Isaac v->labels = NULL; 62c58f1c22SToby Isaac v->depthLabel = NULL; 630298fd71SBarry Smith v->defaultSection = NULL; 640298fd71SBarry Smith v->defaultGlobalSection = NULL; 65fba222abSToby Isaac v->defaultConstraintSection = NULL; 66fba222abSToby Isaac v->defaultConstraintMat = NULL; 67c6b900c6SMatthew G. Knepley v->L = NULL; 68c6b900c6SMatthew G. Knepley v->maxCell = NULL; 695dc8c3f7SMatthew G. Knepley v->bdtype = NULL; 709a9a41abSToby Isaac v->dimEmbed = PETSC_DEFAULT; 7196173672SStefano Zampini v->dim = PETSC_DETERMINE; 72435a35e8SMatthew G Knepley { 73435a35e8SMatthew G Knepley PetscInt i; 74435a35e8SMatthew G Knepley for (i = 0; i < 10; ++i) { 750298fd71SBarry Smith v->nullspaceConstructors[i] = NULL; 76435a35e8SMatthew G Knepley } 77435a35e8SMatthew G Knepley } 782764a2aaSMatthew G. Knepley ierr = PetscDSCreate(comm, &v->prob);CHKERRQ(ierr); 7914f150ffSMatthew G. Knepley v->dmBC = NULL; 80a8fb8f29SToby Isaac v->coarseMesh = NULL; 81f4d763aaSMatthew G. Knepley v->outputSequenceNum = -1; 82cdb7a50dSMatthew G. Knepley v->outputSequenceVal = 0.0; 83c0dedaeaSBarry Smith ierr = DMSetVecType(v,VECSTANDARD);CHKERRQ(ierr); 84b412c318SBarry Smith ierr = DMSetMatType(v,MATAIJ);CHKERRQ(ierr); 85bcc5ffd9SToby Isaac ierr = PetscNew(&(v->labels));CHKERRQ(ierr); 86c58f1c22SToby Isaac v->labels->refct = 1; 874a7a4c06SLawrence Mitchell 884a7a4c06SLawrence Mitchell v->ops->hascreateinjection = DMHasCreateInjection_Default; 894a7a4c06SLawrence Mitchell 901411c6eeSJed Brown *dm = v; 91a4121054SBarry Smith PetscFunctionReturn(0); 92a4121054SBarry Smith } 93a4121054SBarry Smith 9438221697SMatthew G. Knepley /*@ 9538221697SMatthew G. Knepley DMClone - Creates a DM object with the same topology as the original. 9638221697SMatthew G. Knepley 9738221697SMatthew G. Knepley Collective on MPI_Comm 9838221697SMatthew G. Knepley 9938221697SMatthew G. Knepley Input Parameter: 10038221697SMatthew G. Knepley . dm - The original DM object 10138221697SMatthew G. Knepley 10238221697SMatthew G. Knepley Output Parameter: 10338221697SMatthew G. Knepley . newdm - The new DM object 10438221697SMatthew G. Knepley 10538221697SMatthew G. Knepley Level: beginner 10638221697SMatthew G. Knepley 10738221697SMatthew G. Knepley .keywords: DM, topology, create 10838221697SMatthew G. Knepley @*/ 10938221697SMatthew G. Knepley PetscErrorCode DMClone(DM dm, DM *newdm) 11038221697SMatthew G. Knepley { 11138221697SMatthew G. Knepley PetscSF sf; 11238221697SMatthew G. Knepley Vec coords; 11338221697SMatthew G. Knepley void *ctx; 114a3219837SMatthew G. Knepley PetscInt dim, cdim; 11538221697SMatthew G. Knepley PetscErrorCode ierr; 11638221697SMatthew G. Knepley 11738221697SMatthew G. Knepley PetscFunctionBegin; 11838221697SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 11938221697SMatthew G. Knepley PetscValidPointer(newdm,2); 12038221697SMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject) dm), newdm);CHKERRQ(ierr); 121c58f1c22SToby Isaac ierr = PetscFree((*newdm)->labels);CHKERRQ(ierr); 122c58f1c22SToby Isaac dm->labels->refct++; 123c58f1c22SToby Isaac (*newdm)->labels = dm->labels; 124c58f1c22SToby Isaac (*newdm)->depthLabel = dm->depthLabel; 1251de53e9aSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1261de53e9aSMatthew G. Knepley ierr = DMSetDimension(*newdm, dim);CHKERRQ(ierr); 12738221697SMatthew G. Knepley if (dm->ops->clone) { 12838221697SMatthew G. Knepley ierr = (*dm->ops->clone)(dm, newdm);CHKERRQ(ierr); 12938221697SMatthew G. Knepley } 1303f22bcbcSToby Isaac (*newdm)->setupcalled = dm->setupcalled; 13138221697SMatthew G. Knepley ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 13238221697SMatthew G. Knepley ierr = DMSetPointSF(*newdm, sf);CHKERRQ(ierr); 13338221697SMatthew G. Knepley ierr = DMGetApplicationContext(dm, &ctx);CHKERRQ(ierr); 13438221697SMatthew G. Knepley ierr = DMSetApplicationContext(*newdm, ctx);CHKERRQ(ierr); 135be4c1c3eSMatthew G. Knepley if (dm->coordinateDM) { 136be4c1c3eSMatthew G. Knepley DM ncdm; 137be4c1c3eSMatthew G. Knepley PetscSection cs; 1385a0206caSToby Isaac PetscInt pEnd = -1, pEndMax = -1; 139be4c1c3eSMatthew G. Knepley 140e87a4003SBarry Smith ierr = DMGetSection(dm->coordinateDM, &cs);CHKERRQ(ierr); 141be4c1c3eSMatthew G. Knepley if (cs) {ierr = PetscSectionGetChart(cs, NULL, &pEnd);CHKERRQ(ierr);} 1425a0206caSToby Isaac ierr = MPI_Allreduce(&pEnd,&pEndMax,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 1435a0206caSToby Isaac if (pEndMax >= 0) { 144be4c1c3eSMatthew G. Knepley ierr = DMClone(dm->coordinateDM, &ncdm);CHKERRQ(ierr); 145e87a4003SBarry Smith ierr = DMSetSection(ncdm, cs);CHKERRQ(ierr); 146a61e840bSMatthew G. Knepley ierr = DMSetCoordinateDM(*newdm, ncdm);CHKERRQ(ierr); 147be4c1c3eSMatthew G. Knepley ierr = DMDestroy(&ncdm);CHKERRQ(ierr); 148be4c1c3eSMatthew G. Knepley } 149be4c1c3eSMatthew G. Knepley } 150a3219837SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 151a3219837SMatthew G. Knepley ierr = DMSetCoordinateDim(*newdm, cdim);CHKERRQ(ierr); 15238221697SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coords);CHKERRQ(ierr); 15338221697SMatthew G. Knepley if (coords) { 15438221697SMatthew G. Knepley ierr = DMSetCoordinatesLocal(*newdm, coords);CHKERRQ(ierr); 15538221697SMatthew G. Knepley } else { 15638221697SMatthew G. Knepley ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr); 15738221697SMatthew G. Knepley if (coords) {ierr = DMSetCoordinates(*newdm, coords);CHKERRQ(ierr);} 15838221697SMatthew G. Knepley } 15990b157c4SStefano Zampini { 16090b157c4SStefano Zampini PetscBool isper; 161c6b900c6SMatthew G. Knepley const PetscReal *maxCell, *L; 1625dc8c3f7SMatthew G. Knepley const DMBoundaryType *bd; 16390b157c4SStefano Zampini ierr = DMGetPeriodicity(dm, &isper, &maxCell, &L, &bd);CHKERRQ(ierr); 16490b157c4SStefano Zampini ierr = DMSetPeriodicity(*newdm, isper, maxCell, L, bd);CHKERRQ(ierr); 165c6b900c6SMatthew G. Knepley } 16638221697SMatthew G. Knepley PetscFunctionReturn(0); 16738221697SMatthew G. Knepley } 16838221697SMatthew G. Knepley 1699a42bb27SBarry Smith /*@C 170564755cdSBarry Smith DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector() 1719a42bb27SBarry Smith 1728472ad0fSDave May Logically Collective on DM 1739a42bb27SBarry Smith 1749a42bb27SBarry Smith Input Parameter: 1759a42bb27SBarry Smith + da - initial distributed array 176e9e886b6SKarl Rupp . ctype - the vector type, currently either VECSTANDARD, VECCUDA, or VECVIENNACL 1779a42bb27SBarry Smith 1789a42bb27SBarry Smith Options Database: 179dd85299cSBarry Smith . -dm_vec_type ctype 1809a42bb27SBarry Smith 1819a42bb27SBarry Smith Level: intermediate 1829a42bb27SBarry Smith 1838472ad0fSDave May .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType, DMGetVecType() 1849a42bb27SBarry Smith @*/ 18519fd82e9SBarry Smith PetscErrorCode DMSetVecType(DM da,VecType ctype) 1869a42bb27SBarry Smith { 1879a42bb27SBarry Smith PetscErrorCode ierr; 1889a42bb27SBarry Smith 1899a42bb27SBarry Smith PetscFunctionBegin; 1909a42bb27SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 1919a42bb27SBarry Smith ierr = PetscFree(da->vectype);CHKERRQ(ierr); 19219fd82e9SBarry Smith ierr = PetscStrallocpy(ctype,(char**)&da->vectype);CHKERRQ(ierr); 1939a42bb27SBarry Smith PetscFunctionReturn(0); 1949a42bb27SBarry Smith } 1959a42bb27SBarry Smith 196c0dedaeaSBarry Smith /*@C 197c0dedaeaSBarry Smith DMGetVecType - Gets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector() 198c0dedaeaSBarry Smith 1998472ad0fSDave May Logically Collective on DM 200c0dedaeaSBarry Smith 201c0dedaeaSBarry Smith Input Parameter: 202c0dedaeaSBarry Smith . da - initial distributed array 203c0dedaeaSBarry Smith 204c0dedaeaSBarry Smith Output Parameter: 205c0dedaeaSBarry Smith . ctype - the vector type 206c0dedaeaSBarry Smith 207c0dedaeaSBarry Smith Level: intermediate 208c0dedaeaSBarry Smith 2098472ad0fSDave May .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType 210c0dedaeaSBarry Smith @*/ 211c0dedaeaSBarry Smith PetscErrorCode DMGetVecType(DM da,VecType *ctype) 212c0dedaeaSBarry Smith { 213c0dedaeaSBarry Smith PetscFunctionBegin; 214c0dedaeaSBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 215c0dedaeaSBarry Smith *ctype = da->vectype; 216c0dedaeaSBarry Smith PetscFunctionReturn(0); 217c0dedaeaSBarry Smith } 218c0dedaeaSBarry Smith 2195f1ad066SMatthew G Knepley /*@ 22034f98d34SBarry Smith VecGetDM - Gets the DM defining the data layout of the vector 2215f1ad066SMatthew G Knepley 2225f1ad066SMatthew G Knepley Not collective 2235f1ad066SMatthew G Knepley 2245f1ad066SMatthew G Knepley Input Parameter: 2255f1ad066SMatthew G Knepley . v - The Vec 2265f1ad066SMatthew G Knepley 2275f1ad066SMatthew G Knepley Output Parameter: 2285f1ad066SMatthew G Knepley . dm - The DM 2295f1ad066SMatthew G Knepley 2305f1ad066SMatthew G Knepley Level: intermediate 2315f1ad066SMatthew G Knepley 2325f1ad066SMatthew G Knepley .seealso: VecSetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType() 2335f1ad066SMatthew G Knepley @*/ 2345f1ad066SMatthew G Knepley PetscErrorCode VecGetDM(Vec v, DM *dm) 2355f1ad066SMatthew G Knepley { 2365f1ad066SMatthew G Knepley PetscErrorCode ierr; 2375f1ad066SMatthew G Knepley 2385f1ad066SMatthew G Knepley PetscFunctionBegin; 2395f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,1); 2405f1ad066SMatthew G Knepley PetscValidPointer(dm,2); 2415f1ad066SMatthew G Knepley ierr = PetscObjectQuery((PetscObject) v, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr); 2425f1ad066SMatthew G Knepley PetscFunctionReturn(0); 2435f1ad066SMatthew G Knepley } 2445f1ad066SMatthew G Knepley 2455f1ad066SMatthew G Knepley /*@ 246d9805387SMatthew G. Knepley VecSetDM - Sets the DM defining the data layout of the vector. 2475f1ad066SMatthew G Knepley 2485f1ad066SMatthew G Knepley Not collective 2495f1ad066SMatthew G Knepley 2505f1ad066SMatthew G Knepley Input Parameters: 2515f1ad066SMatthew G Knepley + v - The Vec 2525f1ad066SMatthew G Knepley - dm - The DM 2535f1ad066SMatthew G Knepley 254d9805387SMatthew 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. 255d9805387SMatthew G. Knepley 2565f1ad066SMatthew G Knepley Level: intermediate 2575f1ad066SMatthew G Knepley 2585f1ad066SMatthew G Knepley .seealso: VecGetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType() 2595f1ad066SMatthew G Knepley @*/ 2605f1ad066SMatthew G Knepley PetscErrorCode VecSetDM(Vec v, DM dm) 2615f1ad066SMatthew G Knepley { 2625f1ad066SMatthew G Knepley PetscErrorCode ierr; 2635f1ad066SMatthew G Knepley 2645f1ad066SMatthew G Knepley PetscFunctionBegin; 2655f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,1); 266d7f50e27SLisandro Dalcin if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2); 2675f1ad066SMatthew G Knepley ierr = PetscObjectCompose((PetscObject) v, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 2685f1ad066SMatthew G Knepley PetscFunctionReturn(0); 2695f1ad066SMatthew G Knepley } 2705f1ad066SMatthew G Knepley 271521d9a4cSLisandro Dalcin /*@C 2728f1509bcSBarry Smith DMSetISColoringType - Sets the type of coloring, global or local, that is created by the DM 2738f1509bcSBarry Smith 2748f1509bcSBarry Smith Logically Collective on DM 2758f1509bcSBarry Smith 2768f1509bcSBarry Smith Input Parameters: 2778f1509bcSBarry Smith + dm - the DM context 2788f1509bcSBarry Smith - ctype - the matrix type 2798f1509bcSBarry Smith 2808f1509bcSBarry Smith Options Database: 2818f1509bcSBarry Smith . -dm_is_coloring_type - global or local 2828f1509bcSBarry Smith 2838f1509bcSBarry Smith Level: intermediate 2848f1509bcSBarry Smith 2858f1509bcSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(), 2868f1509bcSBarry Smith DMGetISColoringType() 2878f1509bcSBarry Smith @*/ 2888f1509bcSBarry Smith PetscErrorCode DMSetISColoringType(DM dm,ISColoringType ctype) 2898f1509bcSBarry Smith { 2908f1509bcSBarry Smith PetscFunctionBegin; 2918f1509bcSBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2928f1509bcSBarry Smith dm->coloringtype = ctype; 2938f1509bcSBarry Smith PetscFunctionReturn(0); 2948f1509bcSBarry Smith } 2958f1509bcSBarry Smith 2968f1509bcSBarry Smith /*@C 2978f1509bcSBarry Smith DMGetISColoringType - Gets the type of coloring, global or local, that is created by the DM 298521d9a4cSLisandro Dalcin 299521d9a4cSLisandro Dalcin Logically Collective on DM 300521d9a4cSLisandro Dalcin 301521d9a4cSLisandro Dalcin Input Parameter: 3028f1509bcSBarry Smith . dm - the DM context 3038f1509bcSBarry Smith 3048f1509bcSBarry Smith Output Parameter: 3058f1509bcSBarry Smith . ctype - the matrix type 3068f1509bcSBarry Smith 3078f1509bcSBarry Smith Options Database: 3088f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3098f1509bcSBarry Smith 3108f1509bcSBarry Smith Level: intermediate 3118f1509bcSBarry Smith 3128f1509bcSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(), 3138f1509bcSBarry Smith DMGetISColoringType() 3148f1509bcSBarry Smith @*/ 3158f1509bcSBarry Smith PetscErrorCode DMGetISColoringType(DM dm,ISColoringType *ctype) 3168f1509bcSBarry Smith { 3178f1509bcSBarry Smith PetscFunctionBegin; 3188f1509bcSBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3198f1509bcSBarry Smith *ctype = dm->coloringtype; 3208f1509bcSBarry Smith PetscFunctionReturn(0); 3218f1509bcSBarry Smith } 3228f1509bcSBarry Smith 3238f1509bcSBarry Smith /*@C 3248f1509bcSBarry Smith DMSetMatType - Sets the type of matrix created with DMCreateMatrix() 3258f1509bcSBarry Smith 3268f1509bcSBarry Smith Logically Collective on DM 3278f1509bcSBarry Smith 3288f1509bcSBarry Smith Input Parameters: 329521d9a4cSLisandro Dalcin + dm - the DM context 330a2b5a043SBarry Smith - ctype - the matrix type 331521d9a4cSLisandro Dalcin 332521d9a4cSLisandro Dalcin Options Database: 333521d9a4cSLisandro Dalcin . -dm_mat_type ctype 334521d9a4cSLisandro Dalcin 335521d9a4cSLisandro Dalcin Level: intermediate 336521d9a4cSLisandro Dalcin 337c0dedaeaSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType() 338521d9a4cSLisandro Dalcin @*/ 33919fd82e9SBarry Smith PetscErrorCode DMSetMatType(DM dm,MatType ctype) 340521d9a4cSLisandro Dalcin { 341521d9a4cSLisandro Dalcin PetscErrorCode ierr; 34288f0584fSBarry Smith 343521d9a4cSLisandro Dalcin PetscFunctionBegin; 344521d9a4cSLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 345521d9a4cSLisandro Dalcin ierr = PetscFree(dm->mattype);CHKERRQ(ierr); 34619fd82e9SBarry Smith ierr = PetscStrallocpy(ctype,(char**)&dm->mattype);CHKERRQ(ierr); 347521d9a4cSLisandro Dalcin PetscFunctionReturn(0); 348521d9a4cSLisandro Dalcin } 349521d9a4cSLisandro Dalcin 350c0dedaeaSBarry Smith /*@C 351c0dedaeaSBarry Smith DMGetMatType - Gets the type of matrix created with DMCreateMatrix() 352c0dedaeaSBarry Smith 353c0dedaeaSBarry Smith Logically Collective on DM 354c0dedaeaSBarry Smith 355c0dedaeaSBarry Smith Input Parameter: 356c0dedaeaSBarry Smith . dm - the DM context 357c0dedaeaSBarry Smith 358c0dedaeaSBarry Smith Output Parameter: 359c0dedaeaSBarry Smith . ctype - the matrix type 360c0dedaeaSBarry Smith 361c0dedaeaSBarry Smith Options Database: 362c0dedaeaSBarry Smith . -dm_mat_type ctype 363c0dedaeaSBarry Smith 364c0dedaeaSBarry Smith Level: intermediate 365c0dedaeaSBarry Smith 366c0dedaeaSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMSetMatType() 367c0dedaeaSBarry Smith @*/ 368c0dedaeaSBarry Smith PetscErrorCode DMGetMatType(DM dm,MatType *ctype) 369c0dedaeaSBarry Smith { 370c0dedaeaSBarry Smith PetscFunctionBegin; 371c0dedaeaSBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 372c0dedaeaSBarry Smith *ctype = dm->mattype; 373c0dedaeaSBarry Smith PetscFunctionReturn(0); 374c0dedaeaSBarry Smith } 375c0dedaeaSBarry Smith 376c688c046SMatthew G Knepley /*@ 37734f98d34SBarry Smith MatGetDM - Gets the DM defining the data layout of the matrix 378c688c046SMatthew G Knepley 379c688c046SMatthew G Knepley Not collective 380c688c046SMatthew G Knepley 381c688c046SMatthew G Knepley Input Parameter: 382c688c046SMatthew G Knepley . A - The Mat 383c688c046SMatthew G Knepley 384c688c046SMatthew G Knepley Output Parameter: 385c688c046SMatthew G Knepley . dm - The DM 386c688c046SMatthew G Knepley 387c688c046SMatthew G Knepley Level: intermediate 388c688c046SMatthew G Knepley 3898f1509bcSBarry Smith Developer Note: Since the Mat class doesn't know about the DM class the DM object is associated with 3908f1509bcSBarry Smith the Mat through a PetscObjectCompose() operation 3918f1509bcSBarry Smith 392c688c046SMatthew G Knepley .seealso: MatSetDM(), DMCreateMatrix(), DMSetMatType() 393c688c046SMatthew G Knepley @*/ 394c688c046SMatthew G Knepley PetscErrorCode MatGetDM(Mat A, DM *dm) 395c688c046SMatthew G Knepley { 396c688c046SMatthew G Knepley PetscErrorCode ierr; 397c688c046SMatthew G Knepley 398c688c046SMatthew G Knepley PetscFunctionBegin; 399c688c046SMatthew G Knepley PetscValidHeaderSpecific(A,MAT_CLASSID,1); 400c688c046SMatthew G Knepley PetscValidPointer(dm,2); 401c688c046SMatthew G Knepley ierr = PetscObjectQuery((PetscObject) A, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr); 402c688c046SMatthew G Knepley PetscFunctionReturn(0); 403c688c046SMatthew G Knepley } 404c688c046SMatthew G Knepley 405c688c046SMatthew G Knepley /*@ 406c688c046SMatthew G Knepley MatSetDM - Sets the DM defining the data layout of the matrix 407c688c046SMatthew G Knepley 408c688c046SMatthew G Knepley Not collective 409c688c046SMatthew G Knepley 410c688c046SMatthew G Knepley Input Parameters: 411c688c046SMatthew G Knepley + A - The Mat 412c688c046SMatthew G Knepley - dm - The DM 413c688c046SMatthew G Knepley 414c688c046SMatthew G Knepley Level: intermediate 415c688c046SMatthew G Knepley 4168f1509bcSBarry Smith Developer Note: Since the Mat class doesn't know about the DM class the DM object is associated with 4178f1509bcSBarry Smith the Mat through a PetscObjectCompose() operation 4188f1509bcSBarry Smith 4198f1509bcSBarry Smith 420c688c046SMatthew G Knepley .seealso: MatGetDM(), DMCreateMatrix(), DMSetMatType() 421c688c046SMatthew G Knepley @*/ 422c688c046SMatthew G Knepley PetscErrorCode MatSetDM(Mat A, DM dm) 423c688c046SMatthew G Knepley { 424c688c046SMatthew G Knepley PetscErrorCode ierr; 425c688c046SMatthew G Knepley 426c688c046SMatthew G Knepley PetscFunctionBegin; 427c688c046SMatthew G Knepley PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4288865f1eaSKarl Rupp if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2); 429c688c046SMatthew G Knepley ierr = PetscObjectCompose((PetscObject) A, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 430c688c046SMatthew G Knepley PetscFunctionReturn(0); 431c688c046SMatthew G Knepley } 432c688c046SMatthew G Knepley 4339a42bb27SBarry Smith /*@C 4349a42bb27SBarry Smith DMSetOptionsPrefix - Sets the prefix used for searching for all 4356757b960SDave May DM options in the database. 4369a42bb27SBarry Smith 4378353ddbbSDave May Logically Collective on DM 4389a42bb27SBarry Smith 4399a42bb27SBarry Smith Input Parameter: 4408353ddbbSDave May + da - the DM context 4419a42bb27SBarry Smith - prefix - the prefix to prepend to all option names 4429a42bb27SBarry Smith 4439a42bb27SBarry Smith Notes: 4449a42bb27SBarry Smith A hyphen (-) must NOT be given at the beginning of the prefix name. 4459a42bb27SBarry Smith The first character of all runtime options is AUTOMATICALLY the hyphen. 4469a42bb27SBarry Smith 4479a42bb27SBarry Smith Level: advanced 4489a42bb27SBarry Smith 4498353ddbbSDave May .keywords: DM, set, options, prefix, database 4509a42bb27SBarry Smith 4519a42bb27SBarry Smith .seealso: DMSetFromOptions() 4529a42bb27SBarry Smith @*/ 4537087cfbeSBarry Smith PetscErrorCode DMSetOptionsPrefix(DM dm,const char prefix[]) 4549a42bb27SBarry Smith { 4559a42bb27SBarry Smith PetscErrorCode ierr; 4569a42bb27SBarry Smith 4579a42bb27SBarry Smith PetscFunctionBegin; 4589a42bb27SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4599a42bb27SBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 460691be533SLawrence Mitchell if (dm->sf) { 461691be533SLawrence Mitchell ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->sf,prefix);CHKERRQ(ierr); 462691be533SLawrence Mitchell } 463691be533SLawrence Mitchell if (dm->defaultSF) { 464691be533SLawrence Mitchell ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->defaultSF,prefix);CHKERRQ(ierr); 465691be533SLawrence Mitchell } 4669a42bb27SBarry Smith PetscFunctionReturn(0); 4679a42bb27SBarry Smith } 4689a42bb27SBarry Smith 46931697293SDave May /*@C 47031697293SDave May DMAppendOptionsPrefix - Appends to the prefix used for searching for all 47131697293SDave May DM options in the database. 47231697293SDave May 47331697293SDave May Logically Collective on DM 47431697293SDave May 47531697293SDave May Input Parameters: 47631697293SDave May + dm - the DM context 47731697293SDave May - prefix - the prefix string to prepend to all DM option requests 47831697293SDave May 47931697293SDave May Notes: 48031697293SDave May A hyphen (-) must NOT be given at the beginning of the prefix name. 48131697293SDave May The first character of all runtime options is AUTOMATICALLY the hyphen. 48231697293SDave May 48331697293SDave May Level: advanced 48431697293SDave May 48531697293SDave May .keywords: DM, append, options, prefix, database 48631697293SDave May 48731697293SDave May .seealso: DMSetOptionsPrefix(), DMGetOptionsPrefix() 48831697293SDave May @*/ 48931697293SDave May PetscErrorCode DMAppendOptionsPrefix(DM dm,const char prefix[]) 49031697293SDave May { 49131697293SDave May PetscErrorCode ierr; 49231697293SDave May 49331697293SDave May PetscFunctionBegin; 49431697293SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 49531697293SDave May ierr = PetscObjectAppendOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 49631697293SDave May PetscFunctionReturn(0); 49731697293SDave May } 49831697293SDave May 49931697293SDave May /*@C 50031697293SDave May DMGetOptionsPrefix - Gets the prefix used for searching for all 50131697293SDave May DM options in the database. 50231697293SDave May 50331697293SDave May Not Collective 50431697293SDave May 50531697293SDave May Input Parameters: 50631697293SDave May . dm - the DM context 50731697293SDave May 50831697293SDave May Output Parameters: 50931697293SDave May . prefix - pointer to the prefix string used is returned 51031697293SDave May 51195452b02SPatrick Sanan Notes: 51295452b02SPatrick Sanan On the fortran side, the user should pass in a string 'prefix' of 51331697293SDave May sufficient length to hold the prefix. 51431697293SDave May 51531697293SDave May Level: advanced 51631697293SDave May 51731697293SDave May .keywords: DM, set, options, prefix, database 51831697293SDave May 51931697293SDave May .seealso: DMSetOptionsPrefix(), DMAppendOptionsPrefix() 52031697293SDave May @*/ 52131697293SDave May PetscErrorCode DMGetOptionsPrefix(DM dm,const char *prefix[]) 52231697293SDave May { 52331697293SDave May PetscErrorCode ierr; 52431697293SDave May 52531697293SDave May PetscFunctionBegin; 52631697293SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 52731697293SDave May ierr = PetscObjectGetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 52831697293SDave May PetscFunctionReturn(0); 52931697293SDave May } 53031697293SDave May 53188bdff64SToby Isaac static PetscErrorCode DMCountNonCyclicReferences(DM dm, PetscBool recurseCoarse, PetscBool recurseFine, PetscInt *ncrefct) 53288bdff64SToby Isaac { 53388bdff64SToby Isaac PetscInt i, refct = ((PetscObject) dm)->refct; 53488bdff64SToby Isaac DMNamedVecLink nlink; 53588bdff64SToby Isaac PetscErrorCode ierr; 53688bdff64SToby Isaac 53788bdff64SToby Isaac PetscFunctionBegin; 538aab5bcd8SJed Brown *ncrefct = 0; 53988bdff64SToby Isaac /* count all the circular references of DM and its contained Vecs */ 54088bdff64SToby Isaac for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 54188bdff64SToby Isaac if (dm->localin[i]) refct--; 54288bdff64SToby Isaac if (dm->globalin[i]) refct--; 54388bdff64SToby Isaac } 54488bdff64SToby Isaac for (nlink=dm->namedglobal; nlink; nlink=nlink->next) refct--; 54588bdff64SToby Isaac for (nlink=dm->namedlocal; nlink; nlink=nlink->next) refct--; 54688bdff64SToby Isaac if (dm->x) { 54788bdff64SToby Isaac DM obj; 54888bdff64SToby Isaac ierr = VecGetDM(dm->x, &obj);CHKERRQ(ierr); 54988bdff64SToby Isaac if (obj == dm) refct--; 55088bdff64SToby Isaac } 55188bdff64SToby Isaac if (dm->coarseMesh && dm->coarseMesh->fineMesh == dm) { 55288bdff64SToby Isaac refct--; 55388bdff64SToby Isaac if (recurseCoarse) { 55488bdff64SToby Isaac PetscInt coarseCount; 55588bdff64SToby Isaac 55688bdff64SToby Isaac ierr = DMCountNonCyclicReferences(dm->coarseMesh, PETSC_TRUE, PETSC_FALSE,&coarseCount);CHKERRQ(ierr); 55788bdff64SToby Isaac refct += coarseCount; 55888bdff64SToby Isaac } 55988bdff64SToby Isaac } 56088bdff64SToby Isaac if (dm->fineMesh && dm->fineMesh->coarseMesh == dm) { 56188bdff64SToby Isaac refct--; 56288bdff64SToby Isaac if (recurseFine) { 56388bdff64SToby Isaac PetscInt fineCount; 56488bdff64SToby Isaac 56588bdff64SToby Isaac ierr = DMCountNonCyclicReferences(dm->fineMesh, PETSC_FALSE, PETSC_TRUE,&fineCount);CHKERRQ(ierr); 56688bdff64SToby Isaac refct += fineCount; 56788bdff64SToby Isaac } 56888bdff64SToby Isaac } 56988bdff64SToby Isaac *ncrefct = refct; 57088bdff64SToby Isaac PetscFunctionReturn(0); 57188bdff64SToby Isaac } 57288bdff64SToby Isaac 573354557abSToby Isaac PetscErrorCode DMDestroyLabelLinkList(DM dm) 574354557abSToby Isaac { 575354557abSToby Isaac PetscErrorCode ierr; 576354557abSToby Isaac 577354557abSToby Isaac PetscFunctionBegin; 578354557abSToby Isaac if (!--(dm->labels->refct)) { 579354557abSToby Isaac DMLabelLink next = dm->labels->next; 580354557abSToby Isaac 581354557abSToby Isaac /* destroy the labels */ 582354557abSToby Isaac while (next) { 583354557abSToby Isaac DMLabelLink tmp = next->next; 584354557abSToby Isaac 585354557abSToby Isaac ierr = DMLabelDestroy(&next->label);CHKERRQ(ierr); 586354557abSToby Isaac ierr = PetscFree(next);CHKERRQ(ierr); 587354557abSToby Isaac next = tmp; 588354557abSToby Isaac } 589354557abSToby Isaac ierr = PetscFree(dm->labels);CHKERRQ(ierr); 590354557abSToby Isaac } 591354557abSToby Isaac PetscFunctionReturn(0); 592354557abSToby Isaac } 593354557abSToby Isaac 59447c6ae99SBarry Smith /*@ 5958472ad0fSDave May DMDestroy - Destroys a vector packer or DM. 59647c6ae99SBarry Smith 59747c6ae99SBarry Smith Collective on DM 59847c6ae99SBarry Smith 59947c6ae99SBarry Smith Input Parameter: 60047c6ae99SBarry Smith . dm - the DM object to destroy 60147c6ae99SBarry Smith 60247c6ae99SBarry Smith Level: developer 60347c6ae99SBarry Smith 604e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 60547c6ae99SBarry Smith 60647c6ae99SBarry Smith @*/ 607fcfd50ebSBarry Smith PetscErrorCode DMDestroy(DM *dm) 60847c6ae99SBarry Smith { 60988bdff64SToby Isaac PetscInt i, cnt; 610dfe15315SJed Brown DMNamedVecLink nlink,nnext; 61147c6ae99SBarry Smith PetscErrorCode ierr; 61247c6ae99SBarry Smith 61347c6ae99SBarry Smith PetscFunctionBegin; 6146bf464f9SBarry Smith if (!*dm) PetscFunctionReturn(0); 6156bf464f9SBarry Smith PetscValidHeaderSpecific((*dm),DM_CLASSID,1); 61687e657c6SBarry Smith 61788bdff64SToby Isaac /* count all non-cyclic references in the doubly-linked list of coarse<->fine meshes */ 61888bdff64SToby Isaac ierr = DMCountNonCyclicReferences(*dm,PETSC_TRUE,PETSC_TRUE,&cnt);CHKERRQ(ierr); 61988bdff64SToby Isaac --((PetscObject)(*dm))->refct; 62088bdff64SToby Isaac if (--cnt > 0) {*dm = 0; PetscFunctionReturn(0);} 621732e2eb9SMatthew G Knepley /* 622732e2eb9SMatthew G Knepley Need this test because the dm references the vectors that 623732e2eb9SMatthew G Knepley reference the dm, so destroying the dm calls destroy on the 624732e2eb9SMatthew G Knepley vectors that cause another destroy on the dm 625732e2eb9SMatthew G Knepley */ 6266bf464f9SBarry Smith if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0); 6276bf464f9SBarry Smith ((PetscObject) (*dm))->refct = 0; 628732e2eb9SMatthew G Knepley for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 6296bf464f9SBarry Smith if ((*dm)->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Destroying a DM that has a local vector obtained with DMGetLocalVector()"); 6306bf464f9SBarry Smith ierr = VecDestroy(&(*dm)->localin[i]);CHKERRQ(ierr); 631732e2eb9SMatthew G Knepley } 632f490541aSPeter Brune nnext=(*dm)->namedglobal; 6330298fd71SBarry Smith (*dm)->namedglobal = NULL; 634f490541aSPeter Brune for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named vectors */ 6352348bcf4SPeter Brune nnext = nlink->next; 6362348bcf4SPeter 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); 6372348bcf4SPeter Brune ierr = PetscFree(nlink->name);CHKERRQ(ierr); 6382348bcf4SPeter Brune ierr = VecDestroy(&nlink->X);CHKERRQ(ierr); 6392348bcf4SPeter Brune ierr = PetscFree(nlink);CHKERRQ(ierr); 6402348bcf4SPeter Brune } 641f490541aSPeter Brune nnext=(*dm)->namedlocal; 6420298fd71SBarry Smith (*dm)->namedlocal = NULL; 643f490541aSPeter Brune for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named local vectors */ 644f490541aSPeter Brune nnext = nlink->next; 645f490541aSPeter 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); 646f490541aSPeter Brune ierr = PetscFree(nlink->name);CHKERRQ(ierr); 647f490541aSPeter Brune ierr = VecDestroy(&nlink->X);CHKERRQ(ierr); 648f490541aSPeter Brune ierr = PetscFree(nlink);CHKERRQ(ierr); 649f490541aSPeter Brune } 6502348bcf4SPeter Brune 651b17ce1afSJed Brown /* Destroy the list of hooks */ 652c833c3b5SJed Brown { 653c833c3b5SJed Brown DMCoarsenHookLink link,next; 654b17ce1afSJed Brown for (link=(*dm)->coarsenhook; link; link=next) { 655b17ce1afSJed Brown next = link->next; 656b17ce1afSJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 657b17ce1afSJed Brown } 6580298fd71SBarry Smith (*dm)->coarsenhook = NULL; 659c833c3b5SJed Brown } 660c833c3b5SJed Brown { 661c833c3b5SJed Brown DMRefineHookLink link,next; 662c833c3b5SJed Brown for (link=(*dm)->refinehook; link; link=next) { 663c833c3b5SJed Brown next = link->next; 664c833c3b5SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 665c833c3b5SJed Brown } 6660298fd71SBarry Smith (*dm)->refinehook = NULL; 667c833c3b5SJed Brown } 668be081cd6SPeter Brune { 669be081cd6SPeter Brune DMSubDomainHookLink link,next; 670be081cd6SPeter Brune for (link=(*dm)->subdomainhook; link; link=next) { 671be081cd6SPeter Brune next = link->next; 672be081cd6SPeter Brune ierr = PetscFree(link);CHKERRQ(ierr); 673be081cd6SPeter Brune } 6740298fd71SBarry Smith (*dm)->subdomainhook = NULL; 675be081cd6SPeter Brune } 676baf369e7SPeter Brune { 677baf369e7SPeter Brune DMGlobalToLocalHookLink link,next; 678baf369e7SPeter Brune for (link=(*dm)->gtolhook; link; link=next) { 679baf369e7SPeter Brune next = link->next; 680baf369e7SPeter Brune ierr = PetscFree(link);CHKERRQ(ierr); 681baf369e7SPeter Brune } 6820298fd71SBarry Smith (*dm)->gtolhook = NULL; 683baf369e7SPeter Brune } 684d4d07f1eSToby Isaac { 685d4d07f1eSToby Isaac DMLocalToGlobalHookLink link,next; 686d4d07f1eSToby Isaac for (link=(*dm)->ltoghook; link; link=next) { 687d4d07f1eSToby Isaac next = link->next; 688d4d07f1eSToby Isaac ierr = PetscFree(link);CHKERRQ(ierr); 689d4d07f1eSToby Isaac } 690d4d07f1eSToby Isaac (*dm)->ltoghook = NULL; 691d4d07f1eSToby Isaac } 692aa1993deSMatthew G Knepley /* Destroy the work arrays */ 693aa1993deSMatthew G Knepley { 694aa1993deSMatthew G Knepley DMWorkLink link,next; 695aa1993deSMatthew G Knepley if ((*dm)->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Work array still checked out"); 696aa1993deSMatthew G Knepley for (link=(*dm)->workin; link; link=next) { 697aa1993deSMatthew G Knepley next = link->next; 698aa1993deSMatthew G Knepley ierr = PetscFree(link->mem);CHKERRQ(ierr); 699aa1993deSMatthew G Knepley ierr = PetscFree(link);CHKERRQ(ierr); 700aa1993deSMatthew G Knepley } 7010298fd71SBarry Smith (*dm)->workin = NULL; 702aa1993deSMatthew G Knepley } 703c58f1c22SToby Isaac if (!--((*dm)->labels->refct)) { 704c58f1c22SToby Isaac DMLabelLink next = (*dm)->labels->next; 705c58f1c22SToby Isaac 706c58f1c22SToby Isaac /* destroy the labels */ 707c58f1c22SToby Isaac while (next) { 708c58f1c22SToby Isaac DMLabelLink tmp = next->next; 709c58f1c22SToby Isaac 710c58f1c22SToby Isaac ierr = DMLabelDestroy(&next->label);CHKERRQ(ierr); 711c58f1c22SToby Isaac ierr = PetscFree(next);CHKERRQ(ierr); 712c58f1c22SToby Isaac next = tmp; 713c58f1c22SToby Isaac } 714c58f1c22SToby Isaac ierr = PetscFree((*dm)->labels);CHKERRQ(ierr); 715c58f1c22SToby Isaac } 716e6f8dbb6SToby Isaac { 717e6f8dbb6SToby Isaac DMBoundary next = (*dm)->boundary; 718e6f8dbb6SToby Isaac while (next) { 719e6f8dbb6SToby Isaac DMBoundary b = next; 720e6f8dbb6SToby Isaac 721e6f8dbb6SToby Isaac next = b->next; 722e6f8dbb6SToby Isaac ierr = PetscFree(b);CHKERRQ(ierr); 723e6f8dbb6SToby Isaac } 724e6f8dbb6SToby Isaac } 725b17ce1afSJed Brown 72652536dc3SBarry Smith ierr = PetscObjectDestroy(&(*dm)->dmksp);CHKERRQ(ierr); 72752536dc3SBarry Smith ierr = PetscObjectDestroy(&(*dm)->dmsnes);CHKERRQ(ierr); 72852536dc3SBarry Smith ierr = PetscObjectDestroy(&(*dm)->dmts);CHKERRQ(ierr); 72952536dc3SBarry Smith 7301a266240SBarry Smith if ((*dm)->ctx && (*dm)->ctxdestroy) { 7311a266240SBarry Smith ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr); 7321a266240SBarry Smith } 73387e657c6SBarry Smith ierr = VecDestroy(&(*dm)->x);CHKERRQ(ierr); 73471cd77b2SBarry Smith ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr); 7354dcab191SBarry Smith ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr); 7366bf464f9SBarry Smith ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr); 7376bf464f9SBarry Smith ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr); 738073dac72SJed Brown ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr); 73988ed4aceSMatthew G Knepley 74088ed4aceSMatthew G Knepley ierr = PetscSectionDestroy(&(*dm)->defaultSection);CHKERRQ(ierr); 74188ed4aceSMatthew G Knepley ierr = PetscSectionDestroy(&(*dm)->defaultGlobalSection);CHKERRQ(ierr); 7428b1ab98fSJed Brown ierr = PetscLayoutDestroy(&(*dm)->map);CHKERRQ(ierr); 743fba222abSToby Isaac ierr = PetscSectionDestroy(&(*dm)->defaultConstraintSection);CHKERRQ(ierr); 744fba222abSToby Isaac ierr = MatDestroy(&(*dm)->defaultConstraintMat);CHKERRQ(ierr); 74588ed4aceSMatthew G Knepley ierr = PetscSFDestroy(&(*dm)->sf);CHKERRQ(ierr); 74688ed4aceSMatthew G Knepley ierr = PetscSFDestroy(&(*dm)->defaultSF);CHKERRQ(ierr); 747736995cdSBlaise Bourdin if ((*dm)->useNatural) { 748736995cdSBlaise Bourdin if ((*dm)->sfNatural) { 7498e4ac7eaSMatthew G. Knepley ierr = PetscSFDestroy(&(*dm)->sfNatural);CHKERRQ(ierr); 750736995cdSBlaise Bourdin } 751736995cdSBlaise Bourdin ierr = PetscObjectDereference((PetscObject) (*dm)->sfMigration);CHKERRQ(ierr); 752736995cdSBlaise Bourdin } 75388bdff64SToby Isaac if ((*dm)->coarseMesh && (*dm)->coarseMesh->fineMesh == *dm) { 75488bdff64SToby Isaac ierr = DMSetFineDM((*dm)->coarseMesh,NULL);CHKERRQ(ierr); 75588bdff64SToby Isaac } 756a8fb8f29SToby Isaac ierr = DMDestroy(&(*dm)->coarseMesh);CHKERRQ(ierr); 75788bdff64SToby Isaac if ((*dm)->fineMesh && (*dm)->fineMesh->coarseMesh == *dm) { 75888bdff64SToby Isaac ierr = DMSetCoarseDM((*dm)->fineMesh,NULL);CHKERRQ(ierr); 75988bdff64SToby Isaac } 76088bdff64SToby Isaac ierr = DMDestroy(&(*dm)->fineMesh);CHKERRQ(ierr); 761f19dbd58SToby Isaac ierr = DMFieldDestroy(&(*dm)->coordinateField);CHKERRQ(ierr); 7626636e97aSMatthew G Knepley ierr = DMDestroy(&(*dm)->coordinateDM);CHKERRQ(ierr); 7636636e97aSMatthew G Knepley ierr = VecDestroy(&(*dm)->coordinates);CHKERRQ(ierr); 7646636e97aSMatthew G Knepley ierr = VecDestroy(&(*dm)->coordinatesLocal);CHKERRQ(ierr); 7655dc8c3f7SMatthew G. Knepley ierr = PetscFree3((*dm)->L,(*dm)->maxCell,(*dm)->bdtype);CHKERRQ(ierr); 7666636e97aSMatthew G Knepley 7672764a2aaSMatthew G. Knepley ierr = PetscDSDestroy(&(*dm)->prob);CHKERRQ(ierr); 76814f150ffSMatthew G. Knepley ierr = DMDestroy(&(*dm)->dmBC);CHKERRQ(ierr); 769e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 770e04113cfSBarry Smith ierr = PetscObjectSAWsViewOff((PetscObject)*dm);CHKERRQ(ierr); 771732e2eb9SMatthew G Knepley 772ed3c66a1SDave May if ((*dm)->ops->destroy) { 7736bf464f9SBarry Smith ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr); 774ed3c66a1SDave May } 775435a35e8SMatthew G Knepley /* We do not destroy (*dm)->data here so that we can reference count backend objects */ 776732e2eb9SMatthew G Knepley ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr); 77747c6ae99SBarry Smith PetscFunctionReturn(0); 77847c6ae99SBarry Smith } 77947c6ae99SBarry Smith 780d7bf68aeSBarry Smith /*@ 781d7bf68aeSBarry Smith DMSetUp - sets up the data structures inside a DM object 782d7bf68aeSBarry Smith 783d7bf68aeSBarry Smith Collective on DM 784d7bf68aeSBarry Smith 785d7bf68aeSBarry Smith Input Parameter: 786d7bf68aeSBarry Smith . dm - the DM object to setup 787d7bf68aeSBarry Smith 788d7bf68aeSBarry Smith Level: developer 789d7bf68aeSBarry Smith 790e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 791d7bf68aeSBarry Smith 792d7bf68aeSBarry Smith @*/ 7937087cfbeSBarry Smith PetscErrorCode DMSetUp(DM dm) 794d7bf68aeSBarry Smith { 795d7bf68aeSBarry Smith PetscErrorCode ierr; 796d7bf68aeSBarry Smith 797d7bf68aeSBarry Smith PetscFunctionBegin; 798171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7998387afaaSJed Brown if (dm->setupcalled) PetscFunctionReturn(0); 800d7bf68aeSBarry Smith if (dm->ops->setup) { 801d7bf68aeSBarry Smith ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr); 802d7bf68aeSBarry Smith } 8038387afaaSJed Brown dm->setupcalled = PETSC_TRUE; 804d7bf68aeSBarry Smith PetscFunctionReturn(0); 805d7bf68aeSBarry Smith } 806d7bf68aeSBarry Smith 807d7bf68aeSBarry Smith /*@ 808d7bf68aeSBarry Smith DMSetFromOptions - sets parameters in a DM from the options database 809d7bf68aeSBarry Smith 810d7bf68aeSBarry Smith Collective on DM 811d7bf68aeSBarry Smith 812d7bf68aeSBarry Smith Input Parameter: 813d7bf68aeSBarry Smith . dm - the DM object to set options for 814d7bf68aeSBarry Smith 815732e2eb9SMatthew G Knepley Options Database: 8164164ae61SDominic Meiser + -dm_preallocate_only - Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros 8174164ae61SDominic Meiser . -dm_vec_type <type> - type of vector to create inside DM 8184164ae61SDominic Meiser . -dm_mat_type <type> - type of matrix to create inside DM 8198f1509bcSBarry Smith - -dm_is_coloring_type - <global or local> 820732e2eb9SMatthew G Knepley 821d7bf68aeSBarry Smith Level: developer 822d7bf68aeSBarry Smith 823e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 824d7bf68aeSBarry Smith 825d7bf68aeSBarry Smith @*/ 8267087cfbeSBarry Smith PetscErrorCode DMSetFromOptions(DM dm) 827d7bf68aeSBarry Smith { 8287781c08eSBarry Smith char typeName[256]; 829ca266f36SBarry Smith PetscBool flg; 830d7bf68aeSBarry Smith PetscErrorCode ierr; 831d7bf68aeSBarry Smith 832d7bf68aeSBarry Smith PetscFunctionBegin; 833171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 834f1fd5e65SToby Isaac if (dm->prob) { 835f1fd5e65SToby Isaac ierr = PetscDSSetFromOptions(dm->prob);CHKERRQ(ierr); 836f1fd5e65SToby Isaac } 837691be533SLawrence Mitchell if (dm->sf) { 838691be533SLawrence Mitchell ierr = PetscSFSetFromOptions(dm->sf);CHKERRQ(ierr); 839691be533SLawrence Mitchell } 840691be533SLawrence Mitchell if (dm->defaultSF) { 841691be533SLawrence Mitchell ierr = PetscSFSetFromOptions(dm->defaultSF);CHKERRQ(ierr); 842691be533SLawrence Mitchell } 8433194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr); 8440298fd71SBarry 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); 845a264d7a6SBarry Smith ierr = PetscOptionsFList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr); 846f9ba7244SBarry Smith if (flg) { 847f9ba7244SBarry Smith ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr); 848f9ba7244SBarry Smith } 849a264d7a6SBarry 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); 850073dac72SJed Brown if (flg) { 851521d9a4cSLisandro Dalcin ierr = DMSetMatType(dm,typeName);CHKERRQ(ierr); 852073dac72SJed Brown } 8538f1509bcSBarry Smith ierr = PetscOptionsEnum("-dm_is_coloring_type","Global or local coloring of Jacobian","DMSetISColoringType",ISColoringTypes,(PetscEnum)dm->coloringtype,(PetscEnum*)&dm->coloringtype,NULL);CHKERRQ(ierr); 854f9ba7244SBarry Smith if (dm->ops->setfromoptions) { 855e55864a3SBarry Smith ierr = (*dm->ops->setfromoptions)(PetscOptionsObject,dm);CHKERRQ(ierr); 856f9ba7244SBarry Smith } 857f9ba7244SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 8580633abcbSJed Brown ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) dm);CHKERRQ(ierr); 85982fcb398SMatthew G Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 860d7bf68aeSBarry Smith PetscFunctionReturn(0); 861d7bf68aeSBarry Smith } 862d7bf68aeSBarry Smith 863fc9bc008SSatish Balay /*@C 864224748a4SBarry Smith DMView - Views a DM 86547c6ae99SBarry Smith 86647c6ae99SBarry Smith Collective on DM 86747c6ae99SBarry Smith 86847c6ae99SBarry Smith Input Parameter: 86947c6ae99SBarry Smith + dm - the DM object to view 87047c6ae99SBarry Smith - v - the viewer 87147c6ae99SBarry Smith 872224748a4SBarry Smith Level: beginner 87347c6ae99SBarry Smith 874e727c939SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 87547c6ae99SBarry Smith 87647c6ae99SBarry Smith @*/ 8777087cfbeSBarry Smith PetscErrorCode DMView(DM dm,PetscViewer v) 87847c6ae99SBarry Smith { 87947c6ae99SBarry Smith PetscErrorCode ierr; 88032c0f0efSBarry Smith PetscBool isbinary; 88176a8abe0SBarry Smith PetscMPIInt size; 88276a8abe0SBarry Smith PetscViewerFormat format; 88347c6ae99SBarry Smith 88447c6ae99SBarry Smith PetscFunctionBegin; 885171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8863014e516SBarry Smith if (!v) { 887ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)dm),&v);CHKERRQ(ierr); 8883014e516SBarry Smith } 88976a8abe0SBarry Smith ierr = PetscViewerGetFormat(v,&format);CHKERRQ(ierr); 89076a8abe0SBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&size);CHKERRQ(ierr); 89176a8abe0SBarry Smith if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 89298c3331eSBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)dm,v);CHKERRQ(ierr); 89332c0f0efSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 89432c0f0efSBarry Smith if (isbinary) { 89555849f57SBarry Smith PetscInt classid = DM_FILE_CLASSID; 89632c0f0efSBarry Smith char type[256]; 89732c0f0efSBarry Smith 89832c0f0efSBarry Smith ierr = PetscViewerBinaryWrite(v,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 89932c0f0efSBarry Smith ierr = PetscStrncpy(type,((PetscObject)dm)->type_name,256);CHKERRQ(ierr); 90032c0f0efSBarry Smith ierr = PetscViewerBinaryWrite(v,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 90132c0f0efSBarry Smith } 9020c010503SBarry Smith if (dm->ops->view) { 9030c010503SBarry Smith ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr); 90447c6ae99SBarry Smith } 90547c6ae99SBarry Smith PetscFunctionReturn(0); 90647c6ae99SBarry Smith } 90747c6ae99SBarry Smith 90847c6ae99SBarry Smith /*@ 9098472ad0fSDave May DMCreateGlobalVector - Creates a global vector from a DM object 91047c6ae99SBarry Smith 91147c6ae99SBarry Smith Collective on DM 91247c6ae99SBarry Smith 91347c6ae99SBarry Smith Input Parameter: 91447c6ae99SBarry Smith . dm - the DM object 91547c6ae99SBarry Smith 91647c6ae99SBarry Smith Output Parameter: 91747c6ae99SBarry Smith . vec - the global vector 91847c6ae99SBarry Smith 919073dac72SJed Brown Level: beginner 92047c6ae99SBarry Smith 921e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 92247c6ae99SBarry Smith 92347c6ae99SBarry Smith @*/ 9247087cfbeSBarry Smith PetscErrorCode DMCreateGlobalVector(DM dm,Vec *vec) 92547c6ae99SBarry Smith { 92647c6ae99SBarry Smith PetscErrorCode ierr; 92747c6ae99SBarry Smith 92847c6ae99SBarry Smith PetscFunctionBegin; 929171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 93047c6ae99SBarry Smith ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr); 93147c6ae99SBarry Smith PetscFunctionReturn(0); 93247c6ae99SBarry Smith } 93347c6ae99SBarry Smith 93447c6ae99SBarry Smith /*@ 9358472ad0fSDave May DMCreateLocalVector - Creates a local vector from a DM object 93647c6ae99SBarry Smith 93747c6ae99SBarry Smith Not Collective 93847c6ae99SBarry Smith 93947c6ae99SBarry Smith Input Parameter: 94047c6ae99SBarry Smith . dm - the DM object 94147c6ae99SBarry Smith 94247c6ae99SBarry Smith Output Parameter: 94347c6ae99SBarry Smith . vec - the local vector 94447c6ae99SBarry Smith 945073dac72SJed Brown Level: beginner 94647c6ae99SBarry Smith 947e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 94847c6ae99SBarry Smith 94947c6ae99SBarry Smith @*/ 9507087cfbeSBarry Smith PetscErrorCode DMCreateLocalVector(DM dm,Vec *vec) 95147c6ae99SBarry Smith { 95247c6ae99SBarry Smith PetscErrorCode ierr; 95347c6ae99SBarry Smith 95447c6ae99SBarry Smith PetscFunctionBegin; 955171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 95647c6ae99SBarry Smith ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr); 95747c6ae99SBarry Smith PetscFunctionReturn(0); 95847c6ae99SBarry Smith } 95947c6ae99SBarry Smith 9601411c6eeSJed Brown /*@ 9611411c6eeSJed Brown DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM. 9621411c6eeSJed Brown 9631411c6eeSJed Brown Collective on DM 9641411c6eeSJed Brown 9651411c6eeSJed Brown Input Parameter: 9661411c6eeSJed Brown . dm - the DM that provides the mapping 9671411c6eeSJed Brown 9681411c6eeSJed Brown Output Parameter: 9691411c6eeSJed Brown . ltog - the mapping 9701411c6eeSJed Brown 9711411c6eeSJed Brown Level: intermediate 9721411c6eeSJed Brown 9731411c6eeSJed Brown Notes: 9741411c6eeSJed Brown This mapping can then be used by VecSetLocalToGlobalMapping() or 9751411c6eeSJed Brown MatSetLocalToGlobalMapping(). 9761411c6eeSJed Brown 977fc31e74dSBarry Smith .seealso: DMCreateLocalVector() 9781411c6eeSJed Brown @*/ 9797087cfbeSBarry Smith PetscErrorCode DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog) 9801411c6eeSJed Brown { 9810be3e97aSMatthew G. Knepley PetscInt bs = -1, bsLocal[2], bsMinMax[2]; 9821411c6eeSJed Brown PetscErrorCode ierr; 9831411c6eeSJed Brown 9841411c6eeSJed Brown PetscFunctionBegin; 9851411c6eeSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 9861411c6eeSJed Brown PetscValidPointer(ltog,2); 9871411c6eeSJed Brown if (!dm->ltogmap) { 98837d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 98937d0c07bSMatthew G Knepley 990e87a4003SBarry Smith ierr = DMGetSection(dm, §ion);CHKERRQ(ierr); 99137d0c07bSMatthew G Knepley if (section) { 992a974ec88SMatthew G. Knepley const PetscInt *cdofs; 99337d0c07bSMatthew G Knepley PetscInt *ltog; 994ccf3bd66SMatthew G. Knepley PetscInt pStart, pEnd, n, p, k, l; 99537d0c07bSMatthew G Knepley 996e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 99737d0c07bSMatthew G Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 998ccf3bd66SMatthew G. Knepley ierr = PetscSectionGetStorageSize(section, &n);CHKERRQ(ierr); 999ccf3bd66SMatthew G. Knepley ierr = PetscMalloc1(n, <og);CHKERRQ(ierr); /* We want the local+overlap size */ 100037d0c07bSMatthew G Knepley for (p = pStart, l = 0; p < pEnd; ++p) { 1001a974ec88SMatthew G. Knepley PetscInt bdof, cdof, dof, off, c, cind = 0; 100237d0c07bSMatthew G Knepley 100337d0c07bSMatthew G Knepley /* Should probably use constrained dofs */ 100437d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 1005a974ec88SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr); 1006a974ec88SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, p, &cdofs);CHKERRQ(ierr); 100737d0c07bSMatthew G Knepley ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr); 10081a7dc684SMatthew G. Knepley /* If you have dofs, and constraints, and they are unequal, we set the blocksize to 1 */ 10091a7dc684SMatthew G. Knepley bdof = cdof && (dof-cdof) ? 1 : dof; 10101a7dc684SMatthew G. Knepley if (dof) { 1011b190aa46SMatthew G. Knepley if (bs < 0) {bs = bdof;} 1012b190aa46SMatthew G. Knepley else if (bs != bdof) {bs = 1;} 10131a7dc684SMatthew G. Knepley } 101437d0c07bSMatthew G Knepley for (c = 0; c < dof; ++c, ++l) { 1015a974ec88SMatthew G. Knepley if ((cind < cdof) && (c == cdofs[cind])) ltog[l] = off < 0 ? off-c : off+c; 1016a974ec88SMatthew G. Knepley else ltog[l] = (off < 0 ? -(off+1) : off) + c; 101737d0c07bSMatthew G Knepley } 101837d0c07bSMatthew G Knepley } 1019bff27382SMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 10200be3e97aSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 10210be3e97aSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 10220be3e97aSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 10230be3e97aSMatthew G. Knepley else {bs = bsMinMax[0];} 10247591dbb2SMatthew G. Knepley bs = bs < 0 ? 1 : bs; 10257591dbb2SMatthew G. Knepley /* Must reduce indices by blocksize */ 1026ccf3bd66SMatthew G. Knepley if (bs > 1) { 1027ccf3bd66SMatthew G. Knepley for (l = 0, k = 0; l < n; l += bs, ++k) ltog[k] = ltog[l]/bs; 1028ccf3bd66SMatthew G. Knepley n /= bs; 1029ccf3bd66SMatthew G. Knepley } 1030ccf3bd66SMatthew G. Knepley ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, n, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr); 10313bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)dm, (PetscObject)dm->ltogmap);CHKERRQ(ierr); 103237d0c07bSMatthew G Knepley } else { 1033184d77edSJed Brown if (!dm->ops->getlocaltoglobalmapping) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM can not create LocalToGlobalMapping"); 1034184d77edSJed Brown ierr = (*dm->ops->getlocaltoglobalmapping)(dm);CHKERRQ(ierr); 10351411c6eeSJed Brown } 103637d0c07bSMatthew G Knepley } 10371411c6eeSJed Brown *ltog = dm->ltogmap; 10381411c6eeSJed Brown PetscFunctionReturn(0); 10391411c6eeSJed Brown } 10401411c6eeSJed Brown 10411411c6eeSJed Brown /*@ 10421411c6eeSJed Brown DMGetBlockSize - Gets the inherent block size associated with a DM 10431411c6eeSJed Brown 10441411c6eeSJed Brown Not Collective 10451411c6eeSJed Brown 10461411c6eeSJed Brown Input Parameter: 10471411c6eeSJed Brown . dm - the DM with block structure 10481411c6eeSJed Brown 10491411c6eeSJed Brown Output Parameter: 10501411c6eeSJed Brown . bs - the block size, 1 implies no exploitable block structure 10511411c6eeSJed Brown 10521411c6eeSJed Brown Level: intermediate 10531411c6eeSJed Brown 1054fc31e74dSBarry Smith .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMapping() 10551411c6eeSJed Brown @*/ 10567087cfbeSBarry Smith PetscErrorCode DMGetBlockSize(DM dm,PetscInt *bs) 10571411c6eeSJed Brown { 10581411c6eeSJed Brown PetscFunctionBegin; 10591411c6eeSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 10601411c6eeSJed Brown PetscValidPointer(bs,2); 10611411c6eeSJed 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"); 10621411c6eeSJed Brown *bs = dm->bs; 10631411c6eeSJed Brown PetscFunctionReturn(0); 10641411c6eeSJed Brown } 10651411c6eeSJed Brown 106647c6ae99SBarry Smith /*@ 10678472ad0fSDave May DMCreateInterpolation - Gets interpolation matrix between two DM objects 106847c6ae99SBarry Smith 106947c6ae99SBarry Smith Collective on DM 107047c6ae99SBarry Smith 107147c6ae99SBarry Smith Input Parameter: 107247c6ae99SBarry Smith + dm1 - the DM object 107347c6ae99SBarry Smith - dm2 - the second, finer DM object 107447c6ae99SBarry Smith 107547c6ae99SBarry Smith Output Parameter: 107647c6ae99SBarry Smith + mat - the interpolation 107747c6ae99SBarry Smith - vec - the scaling (optional) 107847c6ae99SBarry Smith 107947c6ae99SBarry Smith Level: developer 108047c6ae99SBarry Smith 108195452b02SPatrick Sanan Notes: 108295452b02SPatrick Sanan For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by 108385afcc9aSBarry Smith DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation. 1084d52bd9f3SBarry Smith 10851f588964SMatthew G Knepley For DMDA objects you can use this interpolation (more precisely the interpolation from the DMGetCoordinateDM()) to interpolate the mesh coordinate vectors 1086d52bd9f3SBarry Smith EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic. 108785afcc9aSBarry Smith 108885afcc9aSBarry Smith 10893ad4599aSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateRestriction() 109047c6ae99SBarry Smith 109147c6ae99SBarry Smith @*/ 1092e727c939SJed Brown PetscErrorCode DMCreateInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec) 109347c6ae99SBarry Smith { 109447c6ae99SBarry Smith PetscErrorCode ierr; 109547c6ae99SBarry Smith 109647c6ae99SBarry Smith PetscFunctionBegin; 1097171400e9SBarry Smith PetscValidHeaderSpecific(dm1,DM_CLASSID,1); 1098171400e9SBarry Smith PetscValidHeaderSpecific(dm2,DM_CLASSID,2); 1099cea54e9dSPatrick Farrell ierr = PetscLogEventBegin(DM_CreateInterpolation,dm1,dm2,0,0);CHKERRQ(ierr); 110025296bd5SBarry Smith ierr = (*dm1->ops->createinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr); 1101cea54e9dSPatrick Farrell ierr = PetscLogEventEnd(DM_CreateInterpolation,dm1,dm2,0,0);CHKERRQ(ierr); 110247c6ae99SBarry Smith PetscFunctionReturn(0); 110347c6ae99SBarry Smith } 110447c6ae99SBarry Smith 11053ad4599aSBarry Smith /*@ 11063ad4599aSBarry Smith DMCreateRestriction - Gets restriction matrix between two DM objects 11073ad4599aSBarry Smith 11083ad4599aSBarry Smith Collective on DM 11093ad4599aSBarry Smith 11103ad4599aSBarry Smith Input Parameter: 11113ad4599aSBarry Smith + dm1 - the DM object 11123ad4599aSBarry Smith - dm2 - the second, finer DM object 11133ad4599aSBarry Smith 11143ad4599aSBarry Smith Output Parameter: 11153ad4599aSBarry Smith . mat - the restriction 11163ad4599aSBarry Smith 11173ad4599aSBarry Smith 11183ad4599aSBarry Smith Level: developer 11193ad4599aSBarry Smith 112095452b02SPatrick Sanan Notes: 112195452b02SPatrick Sanan For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by 11223ad4599aSBarry Smith DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation. 11233ad4599aSBarry Smith 11243ad4599aSBarry Smith 11253ad4599aSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateInterpolation() 11263ad4599aSBarry Smith 11273ad4599aSBarry Smith @*/ 11283ad4599aSBarry Smith PetscErrorCode DMCreateRestriction(DM dm1,DM dm2,Mat *mat) 11293ad4599aSBarry Smith { 11303ad4599aSBarry Smith PetscErrorCode ierr; 11313ad4599aSBarry Smith 11323ad4599aSBarry Smith PetscFunctionBegin; 11333ad4599aSBarry Smith PetscValidHeaderSpecific(dm1,DM_CLASSID,1); 11343ad4599aSBarry Smith PetscValidHeaderSpecific(dm2,DM_CLASSID,2); 11353ad4599aSBarry Smith ierr = PetscLogEventBegin(DM_CreateRestriction,dm1,dm2,0,0);CHKERRQ(ierr); 11367294143fSBarry Smith if (!dm1->ops->createrestriction) SETERRQ(PetscObjectComm((PetscObject)dm1),PETSC_ERR_SUP,"DMCreateRestriction not implemented for this type"); 11373ad4599aSBarry Smith ierr = (*dm1->ops->createrestriction)(dm1,dm2,mat);CHKERRQ(ierr); 11383ad4599aSBarry Smith ierr = PetscLogEventEnd(DM_CreateRestriction,dm1,dm2,0,0);CHKERRQ(ierr); 11393ad4599aSBarry Smith PetscFunctionReturn(0); 11403ad4599aSBarry Smith } 11413ad4599aSBarry Smith 114247c6ae99SBarry Smith /*@ 11438472ad0fSDave May DMCreateInjection - Gets injection matrix between two DM objects 114447c6ae99SBarry Smith 114547c6ae99SBarry Smith Collective on DM 114647c6ae99SBarry Smith 114747c6ae99SBarry Smith Input Parameter: 114847c6ae99SBarry Smith + dm1 - the DM object 114947c6ae99SBarry Smith - dm2 - the second, finer DM object 115047c6ae99SBarry Smith 115147c6ae99SBarry Smith Output Parameter: 11526dbf9973SLawrence Mitchell . mat - the injection 115347c6ae99SBarry Smith 115447c6ae99SBarry Smith Level: developer 115547c6ae99SBarry Smith 115695452b02SPatrick Sanan Notes: 115795452b02SPatrick Sanan For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by 115885afcc9aSBarry Smith DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection. 115985afcc9aSBarry Smith 1160e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation() 116147c6ae99SBarry Smith 116247c6ae99SBarry Smith @*/ 11636dbf9973SLawrence Mitchell PetscErrorCode DMCreateInjection(DM dm1,DM dm2,Mat *mat) 116447c6ae99SBarry Smith { 116547c6ae99SBarry Smith PetscErrorCode ierr; 116647c6ae99SBarry Smith 116747c6ae99SBarry Smith PetscFunctionBegin; 1168171400e9SBarry Smith PetscValidHeaderSpecific(dm1,DM_CLASSID,1); 1169171400e9SBarry Smith PetscValidHeaderSpecific(dm2,DM_CLASSID,2); 11700c4c9125SBarry Smith if (!dm1->ops->getinjection) SETERRQ(PetscObjectComm((PetscObject)dm1),PETSC_ERR_SUP,"DMCreateInjection not implemented for this type"); 11716dbf9973SLawrence Mitchell ierr = (*dm1->ops->getinjection)(dm1,dm2,mat);CHKERRQ(ierr); 117247c6ae99SBarry Smith PetscFunctionReturn(0); 117347c6ae99SBarry Smith } 117447c6ae99SBarry Smith 1175b412c318SBarry Smith /*@ 1176bd041c0cSMatthew G. Knepley DMCreateMassMatrix - Gets mass matrix between two DM objects, M_ij = \int \phi_i \psi_j 1177bd041c0cSMatthew G. Knepley 1178bd041c0cSMatthew G. Knepley Collective on DM 1179bd041c0cSMatthew G. Knepley 1180bd041c0cSMatthew G. Knepley Input Parameter: 1181bd041c0cSMatthew G. Knepley + dm1 - the DM object 1182bd041c0cSMatthew G. Knepley - dm2 - the second, finer DM object 1183bd041c0cSMatthew G. Knepley 1184bd041c0cSMatthew G. Knepley Output Parameter: 1185bd041c0cSMatthew G. Knepley . mat - the interpolation 1186bd041c0cSMatthew G. Knepley 1187bd041c0cSMatthew G. Knepley Level: developer 1188bd041c0cSMatthew G. Knepley 1189bd041c0cSMatthew G. Knepley .seealso DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateRestriction(), DMCreateInterpolation(), DMCreateInjection() 1190bd041c0cSMatthew G. Knepley @*/ 1191bd041c0cSMatthew G. Knepley PetscErrorCode DMCreateMassMatrix(DM dm1, DM dm2, Mat *mat) 1192bd041c0cSMatthew G. Knepley { 1193bd041c0cSMatthew G. Knepley PetscErrorCode ierr; 1194bd041c0cSMatthew G. Knepley 1195bd041c0cSMatthew G. Knepley PetscFunctionBegin; 1196bd041c0cSMatthew G. Knepley PetscValidHeaderSpecific(dm1, DM_CLASSID, 1); 1197bd041c0cSMatthew G. Knepley PetscValidHeaderSpecific(dm2, DM_CLASSID, 2); 1198bd041c0cSMatthew G. Knepley ierr = (*dm1->ops->createmassmatrix)(dm1, dm2, mat);CHKERRQ(ierr); 1199bd041c0cSMatthew G. Knepley PetscFunctionReturn(0); 1200bd041c0cSMatthew G. Knepley } 1201bd041c0cSMatthew G. Knepley 1202bd041c0cSMatthew G. Knepley /*@ 1203b412c318SBarry Smith DMCreateColoring - Gets coloring for a DM 120447c6ae99SBarry Smith 120547c6ae99SBarry Smith Collective on DM 120647c6ae99SBarry Smith 120747c6ae99SBarry Smith Input Parameter: 120847c6ae99SBarry Smith + dm - the DM object 12095bdb020cSBarry Smith - ctype - IS_COLORING_LOCAL or IS_COLORING_GLOBAL 121047c6ae99SBarry Smith 121147c6ae99SBarry Smith Output Parameter: 121247c6ae99SBarry Smith . coloring - the coloring 121347c6ae99SBarry Smith 121447c6ae99SBarry Smith Level: developer 121547c6ae99SBarry Smith 1216b412c318SBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix(), DMSetMatType() 121747c6ae99SBarry Smith 1218aab9d709SJed Brown @*/ 1219b412c318SBarry Smith PetscErrorCode DMCreateColoring(DM dm,ISColoringType ctype,ISColoring *coloring) 122047c6ae99SBarry Smith { 122147c6ae99SBarry Smith PetscErrorCode ierr; 122247c6ae99SBarry Smith 122347c6ae99SBarry Smith PetscFunctionBegin; 1224171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1225ce94432eSBarry Smith if (!dm->ops->getcoloring) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No coloring for this type of DM yet"); 1226b412c318SBarry Smith ierr = (*dm->ops->getcoloring)(dm,ctype,coloring);CHKERRQ(ierr); 122747c6ae99SBarry Smith PetscFunctionReturn(0); 122847c6ae99SBarry Smith } 122947c6ae99SBarry Smith 1230b412c318SBarry Smith /*@ 12318472ad0fSDave May DMCreateMatrix - Gets empty Jacobian for a DM 123247c6ae99SBarry Smith 123347c6ae99SBarry Smith Collective on DM 123447c6ae99SBarry Smith 123547c6ae99SBarry Smith Input Parameter: 1236b412c318SBarry Smith . dm - the DM object 123747c6ae99SBarry Smith 123847c6ae99SBarry Smith Output Parameter: 123947c6ae99SBarry Smith . mat - the empty Jacobian 124047c6ae99SBarry Smith 1241073dac72SJed Brown Level: beginner 124247c6ae99SBarry Smith 124395452b02SPatrick Sanan Notes: 124495452b02SPatrick Sanan This properly preallocates the number of nonzeros in the sparse matrix so you 124594013140SBarry Smith do not need to do it yourself. 124694013140SBarry Smith 124794013140SBarry Smith By default it also sets the nonzero structure and puts in the zero entries. To prevent setting 12487889ec69SBarry Smith the nonzero pattern call DMSetMatrixPreallocateOnly() 124994013140SBarry Smith 125094013140SBarry 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 125194013140SBarry Smith internally by PETSc. 125294013140SBarry Smith 125394013140SBarry Smith For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires 1254aa219208SBarry Smith the indices for the global numbering for DMDAs which is complicated. 125594013140SBarry Smith 1256b412c318SBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMSetMatType() 125747c6ae99SBarry Smith 1258aab9d709SJed Brown @*/ 1259b412c318SBarry Smith PetscErrorCode DMCreateMatrix(DM dm,Mat *mat) 126047c6ae99SBarry Smith { 126147c6ae99SBarry Smith PetscErrorCode ierr; 126247c6ae99SBarry Smith 126347c6ae99SBarry Smith PetscFunctionBegin; 1264171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1265607a6623SBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 1266c7b7c8a4SJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1267c7b7c8a4SJed Brown PetscValidPointer(mat,3); 1268b412c318SBarry Smith ierr = (*dm->ops->creatematrix)(dm,mat);CHKERRQ(ierr); 126947c6ae99SBarry Smith PetscFunctionReturn(0); 127047c6ae99SBarry Smith } 127147c6ae99SBarry Smith 1272732e2eb9SMatthew G Knepley /*@ 1273950540a4SJed Brown DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly 1274732e2eb9SMatthew G Knepley preallocated but the nonzero structure and zero values will not be set. 1275732e2eb9SMatthew G Knepley 12768472ad0fSDave May Logically Collective on DM 1277732e2eb9SMatthew G Knepley 1278732e2eb9SMatthew G Knepley Input Parameter: 1279732e2eb9SMatthew G Knepley + dm - the DM 1280732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation 1281732e2eb9SMatthew G Knepley 1282732e2eb9SMatthew G Knepley Level: developer 1283b06ff27eSHong Zhang .seealso DMCreateMatrix(), DMSetMatrixStructureOnly() 1284732e2eb9SMatthew G Knepley @*/ 1285732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only) 1286732e2eb9SMatthew G Knepley { 1287732e2eb9SMatthew G Knepley PetscFunctionBegin; 1288732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1289732e2eb9SMatthew G Knepley dm->prealloc_only = only; 1290732e2eb9SMatthew G Knepley PetscFunctionReturn(0); 1291732e2eb9SMatthew G Knepley } 1292732e2eb9SMatthew G Knepley 1293b06ff27eSHong Zhang /*@ 1294b06ff27eSHong Zhang DMSetMatrixStructureOnly - When DMCreateMatrix() is called, the matrix structure will be created 1295b06ff27eSHong Zhang but the array for values will not be allocated. 1296b06ff27eSHong Zhang 1297b06ff27eSHong Zhang Logically Collective on DM 1298b06ff27eSHong Zhang 1299b06ff27eSHong Zhang Input Parameter: 1300b06ff27eSHong Zhang + dm - the DM 1301b06ff27eSHong Zhang - only - PETSC_TRUE if only want matrix stucture 1302b06ff27eSHong Zhang 1303b06ff27eSHong Zhang Level: developer 1304b06ff27eSHong Zhang .seealso DMCreateMatrix(), DMSetMatrixPreallocateOnly() 1305b06ff27eSHong Zhang @*/ 1306b06ff27eSHong Zhang PetscErrorCode DMSetMatrixStructureOnly(DM dm, PetscBool only) 1307b06ff27eSHong Zhang { 1308b06ff27eSHong Zhang PetscFunctionBegin; 1309b06ff27eSHong Zhang PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1310b06ff27eSHong Zhang dm->structure_only = only; 1311b06ff27eSHong Zhang PetscFunctionReturn(0); 1312b06ff27eSHong Zhang } 1313b06ff27eSHong Zhang 1314a89ea682SMatthew G Knepley /*@C 1315aa1993deSMatthew G Knepley DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray() 1316a89ea682SMatthew G Knepley 1317a89ea682SMatthew G Knepley Not Collective 1318a89ea682SMatthew G Knepley 1319a89ea682SMatthew G Knepley Input Parameters: 1320a89ea682SMatthew G Knepley + dm - the DM object 1321aa1993deSMatthew G Knepley . count - The minium size 132269291d52SBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, MPIU_INT) 1323a89ea682SMatthew G Knepley 1324a89ea682SMatthew G Knepley Output Parameter: 1325a89ea682SMatthew G Knepley . array - the work array 1326a89ea682SMatthew G Knepley 1327a89ea682SMatthew G Knepley Level: developer 1328a89ea682SMatthew G Knepley 1329a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate() 1330a89ea682SMatthew G Knepley @*/ 133169291d52SBarry Smith PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,MPI_Datatype dtype,void *mem) 1332a89ea682SMatthew G Knepley { 1333a89ea682SMatthew G Knepley PetscErrorCode ierr; 1334aa1993deSMatthew G Knepley DMWorkLink link; 133569291d52SBarry Smith PetscMPIInt dsize; 1336a89ea682SMatthew G Knepley 1337a89ea682SMatthew G Knepley PetscFunctionBegin; 1338a89ea682SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1339aa1993deSMatthew G Knepley PetscValidPointer(mem,4); 1340aa1993deSMatthew G Knepley if (dm->workin) { 1341aa1993deSMatthew G Knepley link = dm->workin; 1342aa1993deSMatthew G Knepley dm->workin = dm->workin->next; 1343aa1993deSMatthew G Knepley } else { 1344b00a9115SJed Brown ierr = PetscNewLog(dm,&link);CHKERRQ(ierr); 1345a89ea682SMatthew G Knepley } 134669291d52SBarry Smith ierr = MPI_Type_size(dtype,&dsize);CHKERRQ(ierr); 13475056fcd2SBarry Smith if (((size_t)dsize*count) > link->bytes) { 1348aa1993deSMatthew G Knepley ierr = PetscFree(link->mem);CHKERRQ(ierr); 1349854ce69bSBarry Smith ierr = PetscMalloc(dsize*count,&link->mem);CHKERRQ(ierr); 1350854ce69bSBarry Smith link->bytes = dsize*count; 1351aa1993deSMatthew G Knepley } 1352aa1993deSMatthew G Knepley link->next = dm->workout; 1353aa1993deSMatthew G Knepley dm->workout = link; 1354aa1993deSMatthew G Knepley *(void**)mem = link->mem; 1355a89ea682SMatthew G Knepley PetscFunctionReturn(0); 1356a89ea682SMatthew G Knepley } 1357a89ea682SMatthew G Knepley 1358aa1993deSMatthew G Knepley /*@C 1359aa1993deSMatthew G Knepley DMRestoreWorkArray - Restores a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray() 1360aa1993deSMatthew G Knepley 1361aa1993deSMatthew G Knepley Not Collective 1362aa1993deSMatthew G Knepley 1363aa1993deSMatthew G Knepley Input Parameters: 1364aa1993deSMatthew G Knepley + dm - the DM object 1365aa1993deSMatthew G Knepley . count - The minium size 136669291d52SBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, MPIU_INT 1367aa1993deSMatthew G Knepley 1368aa1993deSMatthew G Knepley Output Parameter: 1369aa1993deSMatthew G Knepley . array - the work array 1370aa1993deSMatthew G Knepley 1371aa1993deSMatthew G Knepley Level: developer 1372aa1993deSMatthew G Knepley 137395452b02SPatrick Sanan Developer Notes: 137495452b02SPatrick Sanan count and dtype are ignored, they are only needed for DMGetWorkArray() 1375aa1993deSMatthew G Knepley .seealso DMDestroy(), DMCreate() 1376aa1993deSMatthew G Knepley @*/ 137769291d52SBarry Smith PetscErrorCode DMRestoreWorkArray(DM dm,PetscInt count,MPI_Datatype dtype,void *mem) 1378aa1993deSMatthew G Knepley { 1379aa1993deSMatthew G Knepley DMWorkLink *p,link; 1380aa1993deSMatthew G Knepley 1381aa1993deSMatthew G Knepley PetscFunctionBegin; 1382aa1993deSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1383aa1993deSMatthew G Knepley PetscValidPointer(mem,4); 1384aa1993deSMatthew G Knepley for (p=&dm->workout; (link=*p); p=&link->next) { 1385aa1993deSMatthew G Knepley if (link->mem == *(void**)mem) { 1386aa1993deSMatthew G Knepley *p = link->next; 1387aa1993deSMatthew G Knepley link->next = dm->workin; 1388aa1993deSMatthew G Knepley dm->workin = link; 13890298fd71SBarry Smith *(void**)mem = NULL; 1390aa1993deSMatthew G Knepley PetscFunctionReturn(0); 1391aa1993deSMatthew G Knepley } 1392aa1993deSMatthew G Knepley } 1393aa1993deSMatthew G Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out"); 1394aa1993deSMatthew G Knepley } 1395e7c4fc90SDmitry Karpeev 1396435a35e8SMatthew G Knepley PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace)) 1397435a35e8SMatthew G Knepley { 1398435a35e8SMatthew G Knepley PetscFunctionBegin; 1399435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 140082f516ccSBarry Smith if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field); 1401435a35e8SMatthew G Knepley dm->nullspaceConstructors[field] = nullsp; 1402435a35e8SMatthew G Knepley PetscFunctionReturn(0); 1403435a35e8SMatthew G Knepley } 1404435a35e8SMatthew G Knepley 14050a50eb56SMatthew G. Knepley PetscErrorCode DMGetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace)) 14060a50eb56SMatthew G. Knepley { 14070a50eb56SMatthew G. Knepley PetscFunctionBegin; 14080a50eb56SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 14090a50eb56SMatthew G. Knepley if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field); 14100a50eb56SMatthew G. Knepley *nullsp = dm->nullspaceConstructors[field]; 14110a50eb56SMatthew G. Knepley PetscFunctionReturn(0); 14120a50eb56SMatthew G. Knepley } 14130a50eb56SMatthew G. Knepley 14144f3b5142SJed Brown /*@C 14154d343eeaSMatthew G Knepley DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field 14164d343eeaSMatthew G Knepley 14174d343eeaSMatthew G Knepley Not collective 14184d343eeaSMatthew G Knepley 14194d343eeaSMatthew G Knepley Input Parameter: 14204d343eeaSMatthew G Knepley . dm - the DM object 14214d343eeaSMatthew G Knepley 14224d343eeaSMatthew G Knepley Output Parameters: 14230298fd71SBarry Smith + numFields - The number of fields (or NULL if not requested) 14240298fd71SBarry Smith . fieldNames - The name for each field (or NULL if not requested) 14250298fd71SBarry Smith - fields - The global indices for each field (or NULL if not requested) 14264d343eeaSMatthew G Knepley 14274d343eeaSMatthew G Knepley Level: intermediate 14284d343eeaSMatthew G Knepley 142921c9b008SJed Brown Notes: 143021c9b008SJed Brown The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 143121c9b008SJed Brown PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with 143221c9b008SJed Brown PetscFree(). 143321c9b008SJed Brown 14344d343eeaSMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 14354d343eeaSMatthew G Knepley @*/ 143637d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields) 14374d343eeaSMatthew G Knepley { 143837d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 14394d343eeaSMatthew G Knepley PetscErrorCode ierr; 14404d343eeaSMatthew G Knepley 14414d343eeaSMatthew G Knepley PetscFunctionBegin; 14424d343eeaSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 144369ca1f37SDmitry Karpeev if (numFields) { 144469ca1f37SDmitry Karpeev PetscValidPointer(numFields,2); 144569ca1f37SDmitry Karpeev *numFields = 0; 144669ca1f37SDmitry Karpeev } 144737d0c07bSMatthew G Knepley if (fieldNames) { 144837d0c07bSMatthew G Knepley PetscValidPointer(fieldNames,3); 14490298fd71SBarry Smith *fieldNames = NULL; 145069ca1f37SDmitry Karpeev } 145169ca1f37SDmitry Karpeev if (fields) { 145269ca1f37SDmitry Karpeev PetscValidPointer(fields,4); 14530298fd71SBarry Smith *fields = NULL; 145469ca1f37SDmitry Karpeev } 1455e87a4003SBarry Smith ierr = DMGetSection(dm, §ion);CHKERRQ(ierr); 145637d0c07bSMatthew G Knepley if (section) { 145737d0c07bSMatthew G Knepley PetscInt *fieldSizes, **fieldIndices; 145837d0c07bSMatthew G Knepley PetscInt nF, f, pStart, pEnd, p; 145937d0c07bSMatthew G Knepley 1460e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 146137d0c07bSMatthew G Knepley ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr); 1462dcca6d9dSJed Brown ierr = PetscMalloc2(nF,&fieldSizes,nF,&fieldIndices);CHKERRQ(ierr); 146337d0c07bSMatthew G Knepley ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 146437d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 146537d0c07bSMatthew G Knepley fieldSizes[f] = 0; 146637d0c07bSMatthew G Knepley } 146737d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 146837d0c07bSMatthew G Knepley PetscInt gdof; 146937d0c07bSMatthew G Knepley 147037d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 147137d0c07bSMatthew G Knepley if (gdof > 0) { 147237d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 147337d0c07bSMatthew G Knepley PetscInt fdof, fcdof; 147437d0c07bSMatthew G Knepley 147537d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 147637d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 147737d0c07bSMatthew G Knepley fieldSizes[f] += fdof-fcdof; 147837d0c07bSMatthew G Knepley } 147937d0c07bSMatthew G Knepley } 148037d0c07bSMatthew G Knepley } 148137d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 1482785e854fSJed Brown ierr = PetscMalloc1(fieldSizes[f], &fieldIndices[f]);CHKERRQ(ierr); 148337d0c07bSMatthew G Knepley fieldSizes[f] = 0; 148437d0c07bSMatthew G Knepley } 148537d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 148637d0c07bSMatthew G Knepley PetscInt gdof, goff; 148737d0c07bSMatthew G Knepley 148837d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 148937d0c07bSMatthew G Knepley if (gdof > 0) { 149037d0c07bSMatthew G Knepley ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr); 149137d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 149237d0c07bSMatthew G Knepley PetscInt fdof, fcdof, fc; 149337d0c07bSMatthew G Knepley 149437d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 149537d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 149637d0c07bSMatthew G Knepley for (fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) { 149737d0c07bSMatthew G Knepley fieldIndices[f][fieldSizes[f]] = goff++; 149837d0c07bSMatthew G Knepley } 149937d0c07bSMatthew G Knepley } 150037d0c07bSMatthew G Knepley } 150137d0c07bSMatthew G Knepley } 15028865f1eaSKarl Rupp if (numFields) *numFields = nF; 150337d0c07bSMatthew G Knepley if (fieldNames) { 1504785e854fSJed Brown ierr = PetscMalloc1(nF, fieldNames);CHKERRQ(ierr); 150537d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 150637d0c07bSMatthew G Knepley const char *fieldName; 150737d0c07bSMatthew G Knepley 150837d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr); 150937d0c07bSMatthew G Knepley ierr = PetscStrallocpy(fieldName, (char**) &(*fieldNames)[f]);CHKERRQ(ierr); 151037d0c07bSMatthew G Knepley } 151137d0c07bSMatthew G Knepley } 151237d0c07bSMatthew G Knepley if (fields) { 1513785e854fSJed Brown ierr = PetscMalloc1(nF, fields);CHKERRQ(ierr); 151437d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 151582f516ccSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr); 151637d0c07bSMatthew G Knepley } 151737d0c07bSMatthew G Knepley } 151837d0c07bSMatthew G Knepley ierr = PetscFree2(fieldSizes,fieldIndices);CHKERRQ(ierr); 15198865f1eaSKarl Rupp } else if (dm->ops->createfieldis) { 15208865f1eaSKarl Rupp ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr); 152169ca1f37SDmitry Karpeev } 15224d343eeaSMatthew G Knepley PetscFunctionReturn(0); 15234d343eeaSMatthew G Knepley } 15244d343eeaSMatthew G Knepley 152516621825SDmitry Karpeev 152616621825SDmitry Karpeev /*@C 152716621825SDmitry Karpeev DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems 152816621825SDmitry Karpeev corresponding to different fields: each IS contains the global indices of the dofs of the 152916621825SDmitry Karpeev corresponding field. The optional list of DMs define the DM for each subproblem. 1530e7c4fc90SDmitry Karpeev Generalizes DMCreateFieldIS(). 1531e7c4fc90SDmitry Karpeev 1532e7c4fc90SDmitry Karpeev Not collective 1533e7c4fc90SDmitry Karpeev 1534e7c4fc90SDmitry Karpeev Input Parameter: 1535e7c4fc90SDmitry Karpeev . dm - the DM object 1536e7c4fc90SDmitry Karpeev 1537e7c4fc90SDmitry Karpeev Output Parameters: 15380298fd71SBarry Smith + len - The number of subproblems in the field decomposition (or NULL if not requested) 15390298fd71SBarry Smith . namelist - The name for each field (or NULL if not requested) 15400298fd71SBarry Smith . islist - The global indices for each field (or NULL if not requested) 15410298fd71SBarry Smith - dmlist - The DMs for each field subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined) 1542e7c4fc90SDmitry Karpeev 1543e7c4fc90SDmitry Karpeev Level: intermediate 1544e7c4fc90SDmitry Karpeev 1545e7c4fc90SDmitry Karpeev Notes: 1546e7c4fc90SDmitry Karpeev The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 1547e7c4fc90SDmitry Karpeev PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(), 1548e7c4fc90SDmitry Karpeev and all of the arrays should be freed with PetscFree(). 1549e7c4fc90SDmitry Karpeev 1550e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 1551e7c4fc90SDmitry Karpeev @*/ 155216621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist) 1553e7c4fc90SDmitry Karpeev { 1554e7c4fc90SDmitry Karpeev PetscErrorCode ierr; 1555e7c4fc90SDmitry Karpeev 1556e7c4fc90SDmitry Karpeev PetscFunctionBegin; 1557e7c4fc90SDmitry Karpeev PetscValidHeaderSpecific(dm,DM_CLASSID,1); 15588865f1eaSKarl Rupp if (len) { 15598865f1eaSKarl Rupp PetscValidPointer(len,2); 15608865f1eaSKarl Rupp *len = 0; 15618865f1eaSKarl Rupp } 15628865f1eaSKarl Rupp if (namelist) { 15638865f1eaSKarl Rupp PetscValidPointer(namelist,3); 15648865f1eaSKarl Rupp *namelist = 0; 15658865f1eaSKarl Rupp } 15668865f1eaSKarl Rupp if (islist) { 15678865f1eaSKarl Rupp PetscValidPointer(islist,4); 15688865f1eaSKarl Rupp *islist = 0; 15698865f1eaSKarl Rupp } 15708865f1eaSKarl Rupp if (dmlist) { 15718865f1eaSKarl Rupp PetscValidPointer(dmlist,5); 15728865f1eaSKarl Rupp *dmlist = 0; 15738865f1eaSKarl Rupp } 1574f3f0edfdSDmitry Karpeev /* 1575f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 1576f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 1577f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 1578f3f0edfdSDmitry Karpeev */ 1579ce94432eSBarry Smith if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 158016621825SDmitry Karpeev if (!dm->ops->createfielddecomposition) { 1581435a35e8SMatthew G Knepley PetscSection section; 1582435a35e8SMatthew G Knepley PetscInt numFields, f; 1583435a35e8SMatthew G Knepley 1584e87a4003SBarry Smith ierr = DMGetSection(dm, §ion);CHKERRQ(ierr); 1585435a35e8SMatthew G Knepley if (section) {ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr);} 1586435a35e8SMatthew G Knepley if (section && numFields && dm->ops->createsubdm) { 1587f25d98f1SMatthew G. Knepley if (len) *len = numFields; 158803dc3394SMatthew G. Knepley if (namelist) {ierr = PetscMalloc1(numFields,namelist);CHKERRQ(ierr);} 158903dc3394SMatthew G. Knepley if (islist) {ierr = PetscMalloc1(numFields,islist);CHKERRQ(ierr);} 159003dc3394SMatthew G. Knepley if (dmlist) {ierr = PetscMalloc1(numFields,dmlist);CHKERRQ(ierr);} 1591435a35e8SMatthew G Knepley for (f = 0; f < numFields; ++f) { 1592435a35e8SMatthew G Knepley const char *fieldName; 1593435a35e8SMatthew G Knepley 159403dc3394SMatthew G. Knepley ierr = DMCreateSubDM(dm, 1, &f, islist ? &(*islist)[f] : NULL, dmlist ? &(*dmlist)[f] : NULL);CHKERRQ(ierr); 159503dc3394SMatthew G. Knepley if (namelist) { 1596435a35e8SMatthew G Knepley ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr); 1597435a35e8SMatthew G Knepley ierr = PetscStrallocpy(fieldName, (char**) &(*namelist)[f]);CHKERRQ(ierr); 1598435a35e8SMatthew G Knepley } 159903dc3394SMatthew G. Knepley } 1600435a35e8SMatthew G Knepley } else { 160169ca1f37SDmitry Karpeev ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr); 1602e7c4fc90SDmitry Karpeev /* By default there are no DMs associated with subproblems. */ 16030298fd71SBarry Smith if (dmlist) *dmlist = NULL; 1604e7c4fc90SDmitry Karpeev } 16058865f1eaSKarl Rupp } else { 160616621825SDmitry Karpeev ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist);CHKERRQ(ierr); 160716621825SDmitry Karpeev } 160816621825SDmitry Karpeev PetscFunctionReturn(0); 160916621825SDmitry Karpeev } 161016621825SDmitry Karpeev 1611564cec59SMatthew G. Knepley /*@ 1612435a35e8SMatthew G Knepley DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in. 1613435a35e8SMatthew G Knepley The fields are defined by DMCreateFieldIS(). 1614435a35e8SMatthew G Knepley 1615435a35e8SMatthew G Knepley Not collective 1616435a35e8SMatthew G Knepley 1617435a35e8SMatthew G Knepley Input Parameters: 16182adcc780SMatthew G. Knepley + dm - The DM object 16192adcc780SMatthew G. Knepley . numFields - The number of fields in this subproblem 16202adcc780SMatthew G. Knepley - fields - The field numbers of the selected fields 1621435a35e8SMatthew G Knepley 1622435a35e8SMatthew G Knepley Output Parameters: 16232adcc780SMatthew G. Knepley + is - The global indices for the subproblem 16242adcc780SMatthew G. Knepley - subdm - The DM for the subproblem 1625435a35e8SMatthew G Knepley 1626435a35e8SMatthew G Knepley Level: intermediate 1627435a35e8SMatthew G Knepley 1628435a35e8SMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 1629435a35e8SMatthew G Knepley @*/ 163037bc7515SMatthew G. Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 1631435a35e8SMatthew G Knepley { 1632435a35e8SMatthew G Knepley PetscErrorCode ierr; 1633435a35e8SMatthew G Knepley 1634435a35e8SMatthew G Knepley PetscFunctionBegin; 1635435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1636435a35e8SMatthew G Knepley PetscValidPointer(fields,3); 16378865f1eaSKarl Rupp if (is) PetscValidPointer(is,4); 16388865f1eaSKarl Rupp if (subdm) PetscValidPointer(subdm,5); 1639435a35e8SMatthew G Knepley if (dm->ops->createsubdm) { 1640435a35e8SMatthew G Knepley ierr = (*dm->ops->createsubdm)(dm, numFields, fields, is, subdm);CHKERRQ(ierr); 164182f516ccSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "This type has no DMCreateSubDM implementation defined"); 1642435a35e8SMatthew G Knepley PetscFunctionReturn(0); 1643435a35e8SMatthew G Knepley } 1644435a35e8SMatthew G Knepley 16452adcc780SMatthew G. Knepley /*@C 16462adcc780SMatthew G. Knepley DMCreateSuperDM - Returns an arrays of ISes and DM encapsulating a superproblem defined by the DMs passed in. 16472adcc780SMatthew G. Knepley 16482adcc780SMatthew G. Knepley Not collective 16492adcc780SMatthew G. Knepley 16502adcc780SMatthew G. Knepley Input Parameter: 16512adcc780SMatthew G. Knepley + dms - The DM objects 16522adcc780SMatthew G. Knepley - len - The number of DMs 16532adcc780SMatthew G. Knepley 16542adcc780SMatthew G. Knepley Output Parameters: 1655a42bd24dSMatthew G. Knepley + is - The global indices for the subproblem, or NULL 16562adcc780SMatthew G. Knepley - superdm - The DM for the superproblem 16572adcc780SMatthew G. Knepley 16582adcc780SMatthew G. Knepley Level: intermediate 16592adcc780SMatthew G. Knepley 16602adcc780SMatthew G. Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 16612adcc780SMatthew G. Knepley @*/ 16622adcc780SMatthew G. Knepley PetscErrorCode DMCreateSuperDM(DM dms[], PetscInt len, IS **is, DM *superdm) 16632adcc780SMatthew G. Knepley { 16642adcc780SMatthew G. Knepley PetscInt i; 16652adcc780SMatthew G. Knepley PetscErrorCode ierr; 16662adcc780SMatthew G. Knepley 16672adcc780SMatthew G. Knepley PetscFunctionBegin; 16682adcc780SMatthew G. Knepley PetscValidPointer(dms,1); 16692adcc780SMatthew G. Knepley for (i = 0; i < len; ++i) {PetscValidHeaderSpecific(dms[i],DM_CLASSID,1);} 16702adcc780SMatthew G. Knepley if (is) PetscValidPointer(is,3); 1671a42bd24dSMatthew G. Knepley PetscValidPointer(superdm,4); 16722adcc780SMatthew G. Knepley if (len < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of DMs must be nonnegative: %D", len); 16732adcc780SMatthew G. Knepley if (len) { 1674a42bd24dSMatthew G. Knepley if (dms[0]->ops->createsuperdm) {ierr = (*dms[0]->ops->createsuperdm)(dms, len, is, superdm);CHKERRQ(ierr);} 1675a42bd24dSMatthew G. Knepley else SETERRQ(PetscObjectComm((PetscObject) dms[0]), PETSC_ERR_SUP, "This type has no DMCreateSuperDM implementation defined"); 16762adcc780SMatthew G. Knepley } 16772adcc780SMatthew G. Knepley PetscFunctionReturn(0); 16782adcc780SMatthew G. Knepley } 16792adcc780SMatthew G. Knepley 168016621825SDmitry Karpeev 168116621825SDmitry Karpeev /*@C 16828d4ac253SDmitry Karpeev DMCreateDomainDecomposition - Returns lists of IS objects defining a decomposition of a problem into subproblems 16838d4ac253SDmitry Karpeev corresponding to restrictions to pairs nested subdomains: each IS contains the global 16848d4ac253SDmitry Karpeev indices of the dofs of the corresponding subdomains. The inner subdomains conceptually 16858d4ac253SDmitry Karpeev define a nonoverlapping covering, while outer subdomains can overlap. 16868d4ac253SDmitry Karpeev The optional list of DMs define the DM for each subproblem. 168716621825SDmitry Karpeev 168816621825SDmitry Karpeev Not collective 168916621825SDmitry Karpeev 169016621825SDmitry Karpeev Input Parameter: 169116621825SDmitry Karpeev . dm - the DM object 169216621825SDmitry Karpeev 169316621825SDmitry Karpeev Output Parameters: 16940298fd71SBarry Smith + len - The number of subproblems in the domain decomposition (or NULL if not requested) 16950298fd71SBarry Smith . namelist - The name for each subdomain (or NULL if not requested) 16960298fd71SBarry Smith . innerislist - The global indices for each inner subdomain (or NULL, if not requested) 16970298fd71SBarry Smith . outerislist - The global indices for each outer subdomain (or NULL, if not requested) 16980298fd71SBarry Smith - dmlist - The DMs for each subdomain subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined) 169916621825SDmitry Karpeev 170016621825SDmitry Karpeev Level: intermediate 170116621825SDmitry Karpeev 170216621825SDmitry Karpeev Notes: 170316621825SDmitry Karpeev The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 170416621825SDmitry Karpeev PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(), 170516621825SDmitry Karpeev and all of the arrays should be freed with PetscFree(). 170616621825SDmitry Karpeev 17078d4ac253SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateDomainDecompositionDM(), DMCreateFieldDecomposition() 170816621825SDmitry Karpeev @*/ 17098d4ac253SDmitry Karpeev PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist) 171016621825SDmitry Karpeev { 171116621825SDmitry Karpeev PetscErrorCode ierr; 1712be081cd6SPeter Brune DMSubDomainHookLink link; 1713be081cd6SPeter Brune PetscInt i,l; 171416621825SDmitry Karpeev 171516621825SDmitry Karpeev PetscFunctionBegin; 171616621825SDmitry Karpeev PetscValidHeaderSpecific(dm,DM_CLASSID,1); 171714a18fd3SPeter Brune if (len) {PetscValidPointer(len,2); *len = 0;} 17180298fd71SBarry Smith if (namelist) {PetscValidPointer(namelist,3); *namelist = NULL;} 17190298fd71SBarry Smith if (innerislist) {PetscValidPointer(innerislist,4); *innerislist = NULL;} 17200298fd71SBarry Smith if (outerislist) {PetscValidPointer(outerislist,5); *outerislist = NULL;} 17210298fd71SBarry Smith if (dmlist) {PetscValidPointer(dmlist,6); *dmlist = NULL;} 1722f3f0edfdSDmitry Karpeev /* 1723f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 1724f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 1725f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 1726f3f0edfdSDmitry Karpeev */ 1727ce94432eSBarry Smith if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 172816621825SDmitry Karpeev if (dm->ops->createdomaindecomposition) { 1729be081cd6SPeter Brune ierr = (*dm->ops->createdomaindecomposition)(dm,&l,namelist,innerislist,outerislist,dmlist);CHKERRQ(ierr); 173014a18fd3SPeter Brune /* copy subdomain hooks and context over to the subdomain DMs */ 1731f891f5b9SPatrick Sanan if (dmlist && *dmlist) { 1732be081cd6SPeter Brune for (i = 0; i < l; i++) { 1733be081cd6SPeter Brune for (link=dm->subdomainhook; link; link=link->next) { 1734be081cd6SPeter Brune if (link->ddhook) {ierr = (*link->ddhook)(dm,(*dmlist)[i],link->ctx);CHKERRQ(ierr);} 1735be081cd6SPeter Brune } 1736648262bbSPatrick Sanan if (dm->ctx) (*dmlist)[i]->ctx = dm->ctx; 1737e7c4fc90SDmitry Karpeev } 173814a18fd3SPeter Brune } 173914a18fd3SPeter Brune if (len) *len = l; 174014a18fd3SPeter Brune } 1741e30e807fSPeter Brune PetscFunctionReturn(0); 1742e30e807fSPeter Brune } 1743e30e807fSPeter Brune 1744e30e807fSPeter Brune 1745e30e807fSPeter Brune /*@C 1746e30e807fSPeter Brune DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector 1747e30e807fSPeter Brune 1748e30e807fSPeter Brune Not collective 1749e30e807fSPeter Brune 1750e30e807fSPeter Brune Input Parameters: 1751e30e807fSPeter Brune + dm - the DM object 1752e30e807fSPeter Brune . n - the number of subdomain scatters 1753e30e807fSPeter Brune - subdms - the local subdomains 1754e30e807fSPeter Brune 1755e30e807fSPeter Brune Output Parameters: 1756e30e807fSPeter Brune + n - the number of scatters returned 1757e30e807fSPeter Brune . iscat - scatter from global vector to nonoverlapping global vector entries on subdomain 1758e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain 1759e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts) 1760e30e807fSPeter Brune 176195452b02SPatrick Sanan Notes: 176295452b02SPatrick Sanan This is an alternative to the iis and ois arguments in DMCreateDomainDecomposition that allow for the solution 1763e30e807fSPeter Brune of general nonlinear problems with overlapping subdomain methods. While merely having index sets that enable subsets 1764e30e807fSPeter Brune of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of 1765e30e807fSPeter Brune solution and residual data. 1766e30e807fSPeter Brune 1767e30e807fSPeter Brune Level: developer 1768e30e807fSPeter Brune 1769e30e807fSPeter Brune .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 1770e30e807fSPeter Brune @*/ 1771e30e807fSPeter Brune PetscErrorCode DMCreateDomainDecompositionScatters(DM dm,PetscInt n,DM *subdms,VecScatter **iscat,VecScatter **oscat,VecScatter **gscat) 1772e30e807fSPeter Brune { 1773e30e807fSPeter Brune PetscErrorCode ierr; 1774e30e807fSPeter Brune 1775e30e807fSPeter Brune PetscFunctionBegin; 1776e30e807fSPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1777e30e807fSPeter Brune PetscValidPointer(subdms,3); 1778e30e807fSPeter Brune if (dm->ops->createddscatters) { 1779e30e807fSPeter Brune ierr = (*dm->ops->createddscatters)(dm,n,subdms,iscat,oscat,gscat);CHKERRQ(ierr); 17806668ed41SLisandro Dalcin } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "This type has no DMCreateDomainDecompositionScatter implementation defined"); 1781e7c4fc90SDmitry Karpeev PetscFunctionReturn(0); 1782e7c4fc90SDmitry Karpeev } 1783e7c4fc90SDmitry Karpeev 178447c6ae99SBarry Smith /*@ 178547c6ae99SBarry Smith DMRefine - Refines a DM object 178647c6ae99SBarry Smith 178747c6ae99SBarry Smith Collective on DM 178847c6ae99SBarry Smith 178947c6ae99SBarry Smith Input Parameter: 179047c6ae99SBarry Smith + dm - the DM object 179191d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL) 179247c6ae99SBarry Smith 179347c6ae99SBarry Smith Output Parameter: 17940298fd71SBarry Smith . dmf - the refined DM, or NULL 1795ae0a1c52SMatthew G Knepley 17960298fd71SBarry Smith Note: If no refinement was done, the return value is NULL 179747c6ae99SBarry Smith 179847c6ae99SBarry Smith Level: developer 179947c6ae99SBarry Smith 1800e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 180147c6ae99SBarry Smith @*/ 18027087cfbeSBarry Smith PetscErrorCode DMRefine(DM dm,MPI_Comm comm,DM *dmf) 180347c6ae99SBarry Smith { 180447c6ae99SBarry Smith PetscErrorCode ierr; 1805c833c3b5SJed Brown DMRefineHookLink link; 180647c6ae99SBarry Smith 180747c6ae99SBarry Smith PetscFunctionBegin; 1808732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 18091ac00216SMatthew G. Knepley ierr = PetscLogEventBegin(DM_Refine,dm,0,0,0);CHKERRQ(ierr); 1810fef3a512SBarry Smith if (!dm->ops->refine) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM cannot refine"); 181147c6ae99SBarry Smith ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr); 18124057135bSMatthew G Knepley if (*dmf) { 181343842a1eSJed Brown (*dmf)->ops->creatematrix = dm->ops->creatematrix; 18148865f1eaSKarl Rupp 18158cd211a4SJed Brown ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr); 18168865f1eaSKarl Rupp 1817644e2e5bSBarry Smith (*dmf)->ctx = dm->ctx; 18180598a293SJed Brown (*dmf)->leveldown = dm->leveldown; 1819656b349aSBarry Smith (*dmf)->levelup = dm->levelup + 1; 18208865f1eaSKarl Rupp 1821e4b4b23bSJed Brown ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr); 1822c833c3b5SJed Brown for (link=dm->refinehook; link; link=link->next) { 18238865f1eaSKarl Rupp if (link->refinehook) { 18248865f1eaSKarl Rupp ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr); 18258865f1eaSKarl Rupp } 1826c833c3b5SJed Brown } 1827c833c3b5SJed Brown } 18281ac00216SMatthew G. Knepley ierr = PetscLogEventEnd(DM_Refine,dm,0,0,0);CHKERRQ(ierr); 1829c833c3b5SJed Brown PetscFunctionReturn(0); 1830c833c3b5SJed Brown } 1831c833c3b5SJed Brown 1832bb9467b5SJed Brown /*@C 1833c833c3b5SJed Brown DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid 1834c833c3b5SJed Brown 1835c833c3b5SJed Brown Logically Collective 1836c833c3b5SJed Brown 1837c833c3b5SJed Brown Input Arguments: 1838c833c3b5SJed Brown + coarse - nonlinear solver context on which to run a hook when restricting to a coarser level 1839c833c3b5SJed Brown . refinehook - function to run when setting up a coarser level 1840c833c3b5SJed Brown . interphook - function to run to update data on finer levels (once per SNESSolve()) 18410298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 1842c833c3b5SJed Brown 1843c833c3b5SJed Brown Calling sequence of refinehook: 1844c833c3b5SJed Brown $ refinehook(DM coarse,DM fine,void *ctx); 1845c833c3b5SJed Brown 1846c833c3b5SJed Brown + coarse - coarse level DM 1847c833c3b5SJed Brown . fine - fine level DM to interpolate problem to 1848c833c3b5SJed Brown - ctx - optional user-defined function context 1849c833c3b5SJed Brown 1850c833c3b5SJed Brown Calling sequence for interphook: 1851c833c3b5SJed Brown $ interphook(DM coarse,Mat interp,DM fine,void *ctx) 1852c833c3b5SJed Brown 1853c833c3b5SJed Brown + coarse - coarse level DM 1854c833c3b5SJed Brown . interp - matrix interpolating a coarse-level solution to the finer grid 1855c833c3b5SJed Brown . fine - fine level DM to update 1856c833c3b5SJed Brown - ctx - optional user-defined function context 1857c833c3b5SJed Brown 1858c833c3b5SJed Brown Level: advanced 1859c833c3b5SJed Brown 1860c833c3b5SJed Brown Notes: 1861c833c3b5SJed Brown This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing 1862c833c3b5SJed Brown 1863c833c3b5SJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 1864c833c3b5SJed Brown 1865bb9467b5SJed Brown This function is currently not available from Fortran. 1866bb9467b5SJed Brown 1867c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 1868c833c3b5SJed Brown @*/ 1869c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx) 1870c833c3b5SJed Brown { 1871c833c3b5SJed Brown PetscErrorCode ierr; 1872c833c3b5SJed Brown DMRefineHookLink link,*p; 1873c833c3b5SJed Brown 1874c833c3b5SJed Brown PetscFunctionBegin; 1875c833c3b5SJed Brown PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 18763d8e3701SJed Brown for (p=&coarse->refinehook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */ 18773d8e3701SJed Brown if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) PetscFunctionReturn(0); 18783d8e3701SJed Brown } 187995dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 1880c833c3b5SJed Brown link->refinehook = refinehook; 1881c833c3b5SJed Brown link->interphook = interphook; 1882c833c3b5SJed Brown link->ctx = ctx; 18830298fd71SBarry Smith link->next = NULL; 1884c833c3b5SJed Brown *p = link; 1885c833c3b5SJed Brown PetscFunctionReturn(0); 1886c833c3b5SJed Brown } 1887c833c3b5SJed Brown 18883d8e3701SJed Brown /*@C 18893d8e3701SJed Brown DMRefineHookRemove - remove a callback from the list of hooks to be run when interpolating a nonlinear problem to a finer grid 18903d8e3701SJed Brown 18913d8e3701SJed Brown Logically Collective 18923d8e3701SJed Brown 18933d8e3701SJed Brown Input Arguments: 18943d8e3701SJed Brown + coarse - nonlinear solver context on which to run a hook when restricting to a coarser level 18953d8e3701SJed Brown . refinehook - function to run when setting up a coarser level 18963d8e3701SJed Brown . interphook - function to run to update data on finer levels (once per SNESSolve()) 18973d8e3701SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 18983d8e3701SJed Brown 18993d8e3701SJed Brown Level: advanced 19003d8e3701SJed Brown 19013d8e3701SJed Brown Notes: 19023d8e3701SJed Brown This function does nothing if the hook is not in the list. 19033d8e3701SJed Brown 19043d8e3701SJed Brown This function is currently not available from Fortran. 19053d8e3701SJed Brown 19063d8e3701SJed Brown .seealso: DMCoarsenHookRemove(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 19073d8e3701SJed Brown @*/ 19083d8e3701SJed Brown PetscErrorCode DMRefineHookRemove(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx) 19093d8e3701SJed Brown { 19103d8e3701SJed Brown PetscErrorCode ierr; 19113d8e3701SJed Brown DMRefineHookLink link,*p; 19123d8e3701SJed Brown 19133d8e3701SJed Brown PetscFunctionBegin; 19143d8e3701SJed Brown PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 19153d8e3701SJed Brown for (p=&coarse->refinehook; *p; p=&(*p)->next) { /* Search the list of current hooks */ 19163d8e3701SJed Brown if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) { 19173d8e3701SJed Brown link = *p; 19183d8e3701SJed Brown *p = link->next; 19193d8e3701SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 19203d8e3701SJed Brown break; 19213d8e3701SJed Brown } 19223d8e3701SJed Brown } 19233d8e3701SJed Brown PetscFunctionReturn(0); 19243d8e3701SJed Brown } 19253d8e3701SJed Brown 1926c833c3b5SJed Brown /*@ 1927c833c3b5SJed Brown DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd() 1928c833c3b5SJed Brown 1929c833c3b5SJed Brown Collective if any hooks are 1930c833c3b5SJed Brown 1931c833c3b5SJed Brown Input Arguments: 1932c833c3b5SJed Brown + coarse - coarser DM to use as a base 1933e91eccc2SStefano Zampini . interp - interpolation matrix, apply using MatInterpolate() 1934c833c3b5SJed Brown - fine - finer DM to update 1935c833c3b5SJed Brown 1936c833c3b5SJed Brown Level: developer 1937c833c3b5SJed Brown 1938c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate() 1939c833c3b5SJed Brown @*/ 1940c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine) 1941c833c3b5SJed Brown { 1942c833c3b5SJed Brown PetscErrorCode ierr; 1943c833c3b5SJed Brown DMRefineHookLink link; 1944c833c3b5SJed Brown 1945c833c3b5SJed Brown PetscFunctionBegin; 1946c833c3b5SJed Brown for (link=fine->refinehook; link; link=link->next) { 19478865f1eaSKarl Rupp if (link->interphook) { 19488865f1eaSKarl Rupp ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr); 19498865f1eaSKarl Rupp } 19504057135bSMatthew G Knepley } 195147c6ae99SBarry Smith PetscFunctionReturn(0); 195247c6ae99SBarry Smith } 195347c6ae99SBarry Smith 1954eb3f98d2SBarry Smith /*@ 1955eb3f98d2SBarry Smith DMGetRefineLevel - Get's the number of refinements that have generated this DM. 1956eb3f98d2SBarry Smith 1957eb3f98d2SBarry Smith Not Collective 1958eb3f98d2SBarry Smith 1959eb3f98d2SBarry Smith Input Parameter: 1960eb3f98d2SBarry Smith . dm - the DM object 1961eb3f98d2SBarry Smith 1962eb3f98d2SBarry Smith Output Parameter: 1963eb3f98d2SBarry Smith . level - number of refinements 1964eb3f98d2SBarry Smith 1965eb3f98d2SBarry Smith Level: developer 1966eb3f98d2SBarry Smith 19676a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 1968eb3f98d2SBarry Smith 1969eb3f98d2SBarry Smith @*/ 1970eb3f98d2SBarry Smith PetscErrorCode DMGetRefineLevel(DM dm,PetscInt *level) 1971eb3f98d2SBarry Smith { 1972eb3f98d2SBarry Smith PetscFunctionBegin; 1973eb3f98d2SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1974eb3f98d2SBarry Smith *level = dm->levelup; 1975eb3f98d2SBarry Smith PetscFunctionReturn(0); 1976eb3f98d2SBarry Smith } 1977eb3f98d2SBarry Smith 1978fef3a512SBarry Smith /*@ 1979fef3a512SBarry Smith DMSetRefineLevel - Set's the number of refinements that have generated this DM. 1980fef3a512SBarry Smith 1981fef3a512SBarry Smith Not Collective 1982fef3a512SBarry Smith 1983fef3a512SBarry Smith Input Parameter: 1984fef3a512SBarry Smith + dm - the DM object 1985fef3a512SBarry Smith - level - number of refinements 1986fef3a512SBarry Smith 1987fef3a512SBarry Smith Level: advanced 1988fef3a512SBarry Smith 198995452b02SPatrick Sanan Notes: 199095452b02SPatrick Sanan This value is used by PCMG to determine how many multigrid levels to use 1991fef3a512SBarry Smith 1992fef3a512SBarry Smith .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 1993fef3a512SBarry Smith 1994fef3a512SBarry Smith @*/ 1995fef3a512SBarry Smith PetscErrorCode DMSetRefineLevel(DM dm,PetscInt level) 1996fef3a512SBarry Smith { 1997fef3a512SBarry Smith PetscFunctionBegin; 1998fef3a512SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1999fef3a512SBarry Smith dm->levelup = level; 2000fef3a512SBarry Smith PetscFunctionReturn(0); 2001fef3a512SBarry Smith } 2002fef3a512SBarry Smith 2003bb9467b5SJed Brown /*@C 2004baf369e7SPeter Brune DMGlobalToLocalHookAdd - adds a callback to be run when global to local is called 2005baf369e7SPeter Brune 2006baf369e7SPeter Brune Logically Collective 2007baf369e7SPeter Brune 2008baf369e7SPeter Brune Input Arguments: 2009baf369e7SPeter Brune + dm - the DM 2010baf369e7SPeter Brune . beginhook - function to run at the beginning of DMGlobalToLocalBegin() 2011baf369e7SPeter Brune . endhook - function to run after DMGlobalToLocalEnd() has completed 20120298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2013baf369e7SPeter Brune 2014baf369e7SPeter Brune Calling sequence for beginhook: 2015baf369e7SPeter Brune $ beginhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx) 2016baf369e7SPeter Brune 2017baf369e7SPeter Brune + dm - global DM 2018baf369e7SPeter Brune . g - global vector 2019baf369e7SPeter Brune . mode - mode 2020baf369e7SPeter Brune . l - local vector 2021baf369e7SPeter Brune - ctx - optional user-defined function context 2022baf369e7SPeter Brune 2023baf369e7SPeter Brune 2024baf369e7SPeter Brune Calling sequence for endhook: 2025ec4806b8SPeter Brune $ endhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx) 2026baf369e7SPeter Brune 2027baf369e7SPeter Brune + global - global DM 2028baf369e7SPeter Brune - ctx - optional user-defined function context 2029baf369e7SPeter Brune 2030baf369e7SPeter Brune Level: advanced 2031baf369e7SPeter Brune 2032baf369e7SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 2033baf369e7SPeter Brune @*/ 2034baf369e7SPeter Brune PetscErrorCode DMGlobalToLocalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx) 2035baf369e7SPeter Brune { 2036baf369e7SPeter Brune PetscErrorCode ierr; 2037baf369e7SPeter Brune DMGlobalToLocalHookLink link,*p; 2038baf369e7SPeter Brune 2039baf369e7SPeter Brune PetscFunctionBegin; 2040baf369e7SPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2041baf369e7SPeter Brune for (p=&dm->gtolhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 204295dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 2043baf369e7SPeter Brune link->beginhook = beginhook; 2044baf369e7SPeter Brune link->endhook = endhook; 2045baf369e7SPeter Brune link->ctx = ctx; 20460298fd71SBarry Smith link->next = NULL; 2047baf369e7SPeter Brune *p = link; 2048baf369e7SPeter Brune PetscFunctionReturn(0); 2049baf369e7SPeter Brune } 2050baf369e7SPeter Brune 20514c274da1SToby Isaac static PetscErrorCode DMGlobalToLocalHook_Constraints(DM dm, Vec g, InsertMode mode, Vec l, void *ctx) 20524c274da1SToby Isaac { 20534c274da1SToby Isaac Mat cMat; 20544c274da1SToby Isaac Vec cVec; 20554c274da1SToby Isaac PetscSection section, cSec; 20564c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 20574c274da1SToby Isaac PetscErrorCode ierr; 20584c274da1SToby Isaac 20594c274da1SToby Isaac PetscFunctionBegin; 20604c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 20614c274da1SToby Isaac ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr); 20624c274da1SToby Isaac if (cMat && (mode == INSERT_VALUES || mode == INSERT_ALL_VALUES || mode == INSERT_BC_VALUES)) { 20635db9a05bSToby Isaac PetscInt nRows; 20645db9a05bSToby Isaac 20655db9a05bSToby Isaac ierr = MatGetSize(cMat,&nRows,NULL);CHKERRQ(ierr); 20665db9a05bSToby Isaac if (nRows <= 0) PetscFunctionReturn(0); 2067e87a4003SBarry Smith ierr = DMGetSection(dm,§ion);CHKERRQ(ierr); 20687711e48fSToby Isaac ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr); 20694c274da1SToby Isaac ierr = MatMult(cMat,l,cVec);CHKERRQ(ierr); 20704c274da1SToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 20714c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 20724c274da1SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 20734c274da1SToby Isaac if (dof) { 20744c274da1SToby Isaac PetscScalar *vals; 20754c274da1SToby Isaac ierr = VecGetValuesSection(cVec,cSec,p,&vals);CHKERRQ(ierr); 20764c274da1SToby Isaac ierr = VecSetValuesSection(l,section,p,vals,INSERT_ALL_VALUES);CHKERRQ(ierr); 20774c274da1SToby Isaac } 20784c274da1SToby Isaac } 20794c274da1SToby Isaac ierr = VecDestroy(&cVec);CHKERRQ(ierr); 20804c274da1SToby Isaac } 20814c274da1SToby Isaac PetscFunctionReturn(0); 20824c274da1SToby Isaac } 20834c274da1SToby Isaac 208447c6ae99SBarry Smith /*@ 208547c6ae99SBarry Smith DMGlobalToLocalBegin - Begins updating local vectors from global vector 208647c6ae99SBarry Smith 208747c6ae99SBarry Smith Neighbor-wise Collective on DM 208847c6ae99SBarry Smith 208947c6ae99SBarry Smith Input Parameters: 209047c6ae99SBarry Smith + dm - the DM object 209147c6ae99SBarry Smith . g - the global vector 209247c6ae99SBarry Smith . mode - INSERT_VALUES or ADD_VALUES 209347c6ae99SBarry Smith - l - the local vector 209447c6ae99SBarry Smith 209547c6ae99SBarry Smith 209647c6ae99SBarry Smith Level: beginner 209747c6ae99SBarry Smith 2098e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 209947c6ae99SBarry Smith 210047c6ae99SBarry Smith @*/ 21017087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l) 210247c6ae99SBarry Smith { 21037128ae9fSMatthew G Knepley PetscSF sf; 210447c6ae99SBarry Smith PetscErrorCode ierr; 2105baf369e7SPeter Brune DMGlobalToLocalHookLink link; 210647c6ae99SBarry Smith 210747c6ae99SBarry Smith PetscFunctionBegin; 2108171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2109baf369e7SPeter Brune for (link=dm->gtolhook; link; link=link->next) { 21108865f1eaSKarl Rupp if (link->beginhook) { 21118865f1eaSKarl Rupp ierr = (*link->beginhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr); 21128865f1eaSKarl Rupp } 2113baf369e7SPeter Brune } 21147128ae9fSMatthew G Knepley ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr); 21157128ae9fSMatthew G Knepley if (sf) { 2116ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2117ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 21187128ae9fSMatthew G Knepley 211982f516ccSBarry Smith if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 21207128ae9fSMatthew G Knepley ierr = VecGetArray(l, &lArray);CHKERRQ(ierr); 2121ae5cfb4aSMatthew G. Knepley ierr = VecGetArrayRead(g, &gArray);CHKERRQ(ierr); 21227128ae9fSMatthew G Knepley ierr = PetscSFBcastBegin(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr); 21237128ae9fSMatthew G Knepley ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr); 2124ae5cfb4aSMatthew G. Knepley ierr = VecRestoreArrayRead(g, &gArray);CHKERRQ(ierr); 21257128ae9fSMatthew G Knepley } else { 2126843c4018SMatthew G Knepley ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 21277128ae9fSMatthew G Knepley } 212847c6ae99SBarry Smith PetscFunctionReturn(0); 212947c6ae99SBarry Smith } 213047c6ae99SBarry Smith 213147c6ae99SBarry Smith /*@ 213247c6ae99SBarry Smith DMGlobalToLocalEnd - Ends updating local vectors from global vector 213347c6ae99SBarry Smith 213447c6ae99SBarry Smith Neighbor-wise Collective on DM 213547c6ae99SBarry Smith 213647c6ae99SBarry Smith Input Parameters: 213747c6ae99SBarry Smith + dm - the DM object 213847c6ae99SBarry Smith . g - the global vector 213947c6ae99SBarry Smith . mode - INSERT_VALUES or ADD_VALUES 214047c6ae99SBarry Smith - l - the local vector 214147c6ae99SBarry Smith 214247c6ae99SBarry Smith 214347c6ae99SBarry Smith Level: beginner 214447c6ae99SBarry Smith 2145e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 214647c6ae99SBarry Smith 214747c6ae99SBarry Smith @*/ 21487087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l) 214947c6ae99SBarry Smith { 21507128ae9fSMatthew G Knepley PetscSF sf; 215147c6ae99SBarry Smith PetscErrorCode ierr; 2152ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2153ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2154baf369e7SPeter Brune DMGlobalToLocalHookLink link; 215547c6ae99SBarry Smith 215647c6ae99SBarry Smith PetscFunctionBegin; 2157171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 21587128ae9fSMatthew G Knepley ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr); 21597128ae9fSMatthew G Knepley if (sf) { 216082f516ccSBarry Smith if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 21617128ae9fSMatthew G Knepley 21627128ae9fSMatthew G Knepley ierr = VecGetArray(l, &lArray);CHKERRQ(ierr); 2163ae5cfb4aSMatthew G. Knepley ierr = VecGetArrayRead(g, &gArray);CHKERRQ(ierr); 21647128ae9fSMatthew G Knepley ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr); 21657128ae9fSMatthew G Knepley ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr); 2166ae5cfb4aSMatthew G. Knepley ierr = VecRestoreArrayRead(g, &gArray);CHKERRQ(ierr); 21677128ae9fSMatthew G Knepley } else { 2168843c4018SMatthew G Knepley ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 21697128ae9fSMatthew G Knepley } 21704c274da1SToby Isaac ierr = DMGlobalToLocalHook_Constraints(dm,g,mode,l,NULL);CHKERRQ(ierr); 2171baf369e7SPeter Brune for (link=dm->gtolhook; link; link=link->next) { 2172baf369e7SPeter Brune if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);} 2173baf369e7SPeter Brune } 217447c6ae99SBarry Smith PetscFunctionReturn(0); 217547c6ae99SBarry Smith } 217647c6ae99SBarry Smith 2177d4d07f1eSToby Isaac /*@C 2178d4d07f1eSToby Isaac DMLocalToGlobalHookAdd - adds a callback to be run when a local to global is called 2179d4d07f1eSToby Isaac 2180d4d07f1eSToby Isaac Logically Collective 2181d4d07f1eSToby Isaac 2182d4d07f1eSToby Isaac Input Arguments: 2183d4d07f1eSToby Isaac + dm - the DM 2184d4d07f1eSToby Isaac . beginhook - function to run at the beginning of DMLocalToGlobalBegin() 2185d4d07f1eSToby Isaac . endhook - function to run after DMLocalToGlobalEnd() has completed 2186d4d07f1eSToby Isaac - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2187d4d07f1eSToby Isaac 2188d4d07f1eSToby Isaac Calling sequence for beginhook: 2189d4d07f1eSToby Isaac $ beginhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx) 2190d4d07f1eSToby Isaac 2191d4d07f1eSToby Isaac + dm - global DM 2192d4d07f1eSToby Isaac . l - local vector 2193d4d07f1eSToby Isaac . mode - mode 2194d4d07f1eSToby Isaac . g - global vector 2195d4d07f1eSToby Isaac - ctx - optional user-defined function context 2196d4d07f1eSToby Isaac 2197d4d07f1eSToby Isaac 2198d4d07f1eSToby Isaac Calling sequence for endhook: 2199d4d07f1eSToby Isaac $ endhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx) 2200d4d07f1eSToby Isaac 2201d4d07f1eSToby Isaac + global - global DM 2202d4d07f1eSToby Isaac . l - local vector 2203d4d07f1eSToby Isaac . mode - mode 2204d4d07f1eSToby Isaac . g - global vector 2205d4d07f1eSToby Isaac - ctx - optional user-defined function context 2206d4d07f1eSToby Isaac 2207d4d07f1eSToby Isaac Level: advanced 2208d4d07f1eSToby Isaac 2209d4d07f1eSToby Isaac .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 2210d4d07f1eSToby Isaac @*/ 2211d4d07f1eSToby Isaac PetscErrorCode DMLocalToGlobalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx) 2212d4d07f1eSToby Isaac { 2213d4d07f1eSToby Isaac PetscErrorCode ierr; 2214d4d07f1eSToby Isaac DMLocalToGlobalHookLink link,*p; 2215d4d07f1eSToby Isaac 2216d4d07f1eSToby Isaac PetscFunctionBegin; 2217d4d07f1eSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2218d4d07f1eSToby Isaac for (p=&dm->ltoghook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 221995dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 2220d4d07f1eSToby Isaac link->beginhook = beginhook; 2221d4d07f1eSToby Isaac link->endhook = endhook; 2222d4d07f1eSToby Isaac link->ctx = ctx; 2223d4d07f1eSToby Isaac link->next = NULL; 2224d4d07f1eSToby Isaac *p = link; 2225d4d07f1eSToby Isaac PetscFunctionReturn(0); 2226d4d07f1eSToby Isaac } 2227d4d07f1eSToby Isaac 22284c274da1SToby Isaac static PetscErrorCode DMLocalToGlobalHook_Constraints(DM dm, Vec l, InsertMode mode, Vec g, void *ctx) 22294c274da1SToby Isaac { 22304c274da1SToby Isaac Mat cMat; 22314c274da1SToby Isaac Vec cVec; 22324c274da1SToby Isaac PetscSection section, cSec; 22334c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 22344c274da1SToby Isaac PetscErrorCode ierr; 22354c274da1SToby Isaac 22364c274da1SToby Isaac PetscFunctionBegin; 22374c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 22384c274da1SToby Isaac ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr); 22394c274da1SToby Isaac if (cMat && (mode == ADD_VALUES || mode == ADD_ALL_VALUES || mode == ADD_BC_VALUES)) { 22405db9a05bSToby Isaac PetscInt nRows; 22415db9a05bSToby Isaac 22425db9a05bSToby Isaac ierr = MatGetSize(cMat,&nRows,NULL);CHKERRQ(ierr); 22435db9a05bSToby Isaac if (nRows <= 0) PetscFunctionReturn(0); 2244e87a4003SBarry Smith ierr = DMGetSection(dm,§ion);CHKERRQ(ierr); 22457711e48fSToby Isaac ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr); 22464c274da1SToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 22474c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 22484c274da1SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 22494c274da1SToby Isaac if (dof) { 22504c274da1SToby Isaac PetscInt d; 22514c274da1SToby Isaac PetscScalar *vals; 22524c274da1SToby Isaac ierr = VecGetValuesSection(l,section,p,&vals);CHKERRQ(ierr); 22534c274da1SToby Isaac ierr = VecSetValuesSection(cVec,cSec,p,vals,mode);CHKERRQ(ierr); 22544c274da1SToby Isaac /* for this to be the true transpose, we have to zero the values that 22554c274da1SToby Isaac * we just extracted */ 22564c274da1SToby Isaac for (d = 0; d < dof; d++) { 22574c274da1SToby Isaac vals[d] = 0.; 22584c274da1SToby Isaac } 22594c274da1SToby Isaac } 22604c274da1SToby Isaac } 22614c274da1SToby Isaac ierr = MatMultTransposeAdd(cMat,cVec,l,l);CHKERRQ(ierr); 22624c274da1SToby Isaac ierr = VecDestroy(&cVec);CHKERRQ(ierr); 22634c274da1SToby Isaac } 22644c274da1SToby Isaac PetscFunctionReturn(0); 22654c274da1SToby Isaac } 22664c274da1SToby Isaac 226747c6ae99SBarry Smith /*@ 22689a42bb27SBarry Smith DMLocalToGlobalBegin - updates global vectors from local vectors 22699a42bb27SBarry Smith 22709a42bb27SBarry Smith Neighbor-wise Collective on DM 22719a42bb27SBarry Smith 22729a42bb27SBarry Smith Input Parameters: 22739a42bb27SBarry Smith + dm - the DM object 2274f6813fd5SJed Brown . l - the local vector 22751eb28f2eSBarry 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. 22761eb28f2eSBarry Smith - g - the global vector 22779a42bb27SBarry Smith 227895452b02SPatrick Sanan Notes: 227995452b02SPatrick Sanan In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation. 228084330215SMatthew 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. 22819a42bb27SBarry Smith 22829a42bb27SBarry Smith Level: beginner 22839a42bb27SBarry Smith 2284e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin() 22859a42bb27SBarry Smith 22869a42bb27SBarry Smith @*/ 22877087cfbeSBarry Smith PetscErrorCode DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g) 22889a42bb27SBarry Smith { 22897128ae9fSMatthew G Knepley PetscSF sf; 229084330215SMatthew G. Knepley PetscSection s, gs; 2291d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 2292ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 2293ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 229484330215SMatthew G. Knepley PetscBool isInsert; 229584330215SMatthew G. Knepley PetscErrorCode ierr; 22969a42bb27SBarry Smith 22979a42bb27SBarry Smith PetscFunctionBegin; 2298171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2299d4d07f1eSToby Isaac for (link=dm->ltoghook; link; link=link->next) { 2300d4d07f1eSToby Isaac if (link->beginhook) { 2301d4d07f1eSToby Isaac ierr = (*link->beginhook)(dm,l,mode,g,link->ctx);CHKERRQ(ierr); 2302d4d07f1eSToby Isaac } 2303d4d07f1eSToby Isaac } 23044c274da1SToby Isaac ierr = DMLocalToGlobalHook_Constraints(dm,l,mode,g,NULL);CHKERRQ(ierr); 23057128ae9fSMatthew G Knepley ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr); 2306e87a4003SBarry Smith ierr = DMGetSection(dm, &s);CHKERRQ(ierr); 23077128ae9fSMatthew G Knepley switch (mode) { 23087128ae9fSMatthew G Knepley case INSERT_VALUES: 23097128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 2310304ab55fSMatthew G. Knepley case INSERT_BC_VALUES: 231184330215SMatthew G. Knepley isInsert = PETSC_TRUE; break; 23127128ae9fSMatthew G Knepley case ADD_VALUES: 23137128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 2314304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 231584330215SMatthew G. Knepley isInsert = PETSC_FALSE; break; 23167128ae9fSMatthew G Knepley default: 231782f516ccSBarry Smith SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 23187128ae9fSMatthew G Knepley } 231984330215SMatthew G. Knepley if (sf && !isInsert) { 2320ae5cfb4aSMatthew G. Knepley ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr); 23217128ae9fSMatthew G Knepley ierr = VecGetArray(g, &gArray);CHKERRQ(ierr); 2322a9b180a6SBarry Smith ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM);CHKERRQ(ierr); 2323ae5cfb4aSMatthew G. Knepley ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr); 232484330215SMatthew G. Knepley ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr); 232584330215SMatthew G. Knepley } else if (s && isInsert) { 232684330215SMatthew G. Knepley PetscInt gStart, pStart, pEnd, p; 232784330215SMatthew G. Knepley 2328e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, &gs);CHKERRQ(ierr); 232984330215SMatthew G. Knepley ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 233084330215SMatthew G. Knepley ierr = VecGetOwnershipRange(g, &gStart, NULL);CHKERRQ(ierr); 2331ae5cfb4aSMatthew G. Knepley ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr); 233284330215SMatthew G. Knepley ierr = VecGetArray(g, &gArray);CHKERRQ(ierr); 233384330215SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2334b3b16f48SMatthew G. Knepley PetscInt dof, gdof, cdof, gcdof, off, goff, d, e; 233584330215SMatthew G. Knepley 233684330215SMatthew G. Knepley ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 233703442857SMatthew G. Knepley ierr = PetscSectionGetDof(gs, p, &gdof);CHKERRQ(ierr); 233884330215SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 2339b3b16f48SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(gs, p, &gcdof);CHKERRQ(ierr); 234084330215SMatthew G. Knepley ierr = PetscSectionGetOffset(s, p, &off);CHKERRQ(ierr); 234184330215SMatthew G. Knepley ierr = PetscSectionGetOffset(gs, p, &goff);CHKERRQ(ierr); 2342b3b16f48SMatthew G. Knepley /* Ignore off-process data and points with no global data */ 234303442857SMatthew G. Knepley if (!gdof || goff < 0) continue; 2344b3b16f48SMatthew 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); 2345b3b16f48SMatthew G. Knepley /* If no constraints are enforced in the global vector */ 2346b3b16f48SMatthew G. Knepley if (!gcdof) { 234784330215SMatthew G. Knepley for (d = 0; d < dof; ++d) gArray[goff-gStart+d] = lArray[off+d]; 2348b3b16f48SMatthew G. Knepley /* If constraints are enforced in the global vector */ 2349b3b16f48SMatthew G. Knepley } else if (cdof == gcdof) { 235084330215SMatthew G. Knepley const PetscInt *cdofs; 235184330215SMatthew G. Knepley PetscInt cind = 0; 235284330215SMatthew G. Knepley 235384330215SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(s, p, &cdofs);CHKERRQ(ierr); 2354b3b16f48SMatthew G. Knepley for (d = 0, e = 0; d < dof; ++d) { 235584330215SMatthew G. Knepley if ((cind < cdof) && (d == cdofs[cind])) {++cind; continue;} 2356b3b16f48SMatthew G. Knepley gArray[goff-gStart+e++] = lArray[off+d]; 235784330215SMatthew G. Knepley } 2358b3b16f48SMatthew 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); 235984330215SMatthew G. Knepley } 2360ae5cfb4aSMatthew G. Knepley ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr); 23617128ae9fSMatthew G Knepley ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr); 23627128ae9fSMatthew G Knepley } else { 2363843c4018SMatthew G Knepley ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr); 23647128ae9fSMatthew G Knepley } 23659a42bb27SBarry Smith PetscFunctionReturn(0); 23669a42bb27SBarry Smith } 23679a42bb27SBarry Smith 23689a42bb27SBarry Smith /*@ 23699a42bb27SBarry Smith DMLocalToGlobalEnd - updates global vectors from local vectors 237047c6ae99SBarry Smith 237147c6ae99SBarry Smith Neighbor-wise Collective on DM 237247c6ae99SBarry Smith 237347c6ae99SBarry Smith Input Parameters: 237447c6ae99SBarry Smith + dm - the DM object 2375f6813fd5SJed Brown . l - the local vector 237647c6ae99SBarry Smith . mode - INSERT_VALUES or ADD_VALUES 2377f6813fd5SJed Brown - g - the global vector 237847c6ae99SBarry Smith 237947c6ae99SBarry Smith 238047c6ae99SBarry Smith Level: beginner 238147c6ae99SBarry Smith 2382e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd() 238347c6ae99SBarry Smith 238447c6ae99SBarry Smith @*/ 23857087cfbeSBarry Smith PetscErrorCode DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g) 238647c6ae99SBarry Smith { 23877128ae9fSMatthew G Knepley PetscSF sf; 238884330215SMatthew G. Knepley PetscSection s; 2389d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 239084330215SMatthew G. Knepley PetscBool isInsert; 239184330215SMatthew G. Knepley PetscErrorCode ierr; 239247c6ae99SBarry Smith 239347c6ae99SBarry Smith PetscFunctionBegin; 2394171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 23957128ae9fSMatthew G Knepley ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr); 2396e87a4003SBarry Smith ierr = DMGetSection(dm, &s);CHKERRQ(ierr); 23977128ae9fSMatthew G Knepley switch (mode) { 23987128ae9fSMatthew G Knepley case INSERT_VALUES: 23997128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 240084330215SMatthew G. Knepley isInsert = PETSC_TRUE; break; 24017128ae9fSMatthew G Knepley case ADD_VALUES: 24027128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 240384330215SMatthew G. Knepley isInsert = PETSC_FALSE; break; 24047128ae9fSMatthew G Knepley default: 240582f516ccSBarry Smith SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 24067128ae9fSMatthew G Knepley } 240784330215SMatthew G. Knepley if (sf && !isInsert) { 2408ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 2409ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 241084330215SMatthew G. Knepley 2411ae5cfb4aSMatthew G. Knepley ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr); 24127128ae9fSMatthew G Knepley ierr = VecGetArray(g, &gArray);CHKERRQ(ierr); 2413a9b180a6SBarry Smith ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM);CHKERRQ(ierr); 2414ae5cfb4aSMatthew G. Knepley ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr); 24157128ae9fSMatthew G Knepley ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr); 241684330215SMatthew G. Knepley } else if (s && isInsert) { 24177128ae9fSMatthew G Knepley } else { 2418843c4018SMatthew G Knepley ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr); 24197128ae9fSMatthew G Knepley } 2420d4d07f1eSToby Isaac for (link=dm->ltoghook; link; link=link->next) { 2421d4d07f1eSToby Isaac if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);} 2422d4d07f1eSToby Isaac } 242347c6ae99SBarry Smith PetscFunctionReturn(0); 242447c6ae99SBarry Smith } 242547c6ae99SBarry Smith 2426f089877aSRichard Tran Mills /*@ 2427bc0a1609SRichard Tran Mills DMLocalToLocalBegin - Maps from a local vector (including ghost points 2428bc0a1609SRichard Tran Mills that contain irrelevant values) to another local vector where the ghost 2429d78e899eSRichard Tran Mills points in the second are set correctly. Must be followed by DMLocalToLocalEnd(). 2430f089877aSRichard Tran Mills 2431bc0a1609SRichard Tran Mills Neighbor-wise Collective on DM and Vec 2432f089877aSRichard Tran Mills 2433f089877aSRichard Tran Mills Input Parameters: 2434f089877aSRichard Tran Mills + dm - the DM object 2435bc0a1609SRichard Tran Mills . g - the original local vector 2436bc0a1609SRichard Tran Mills - mode - one of INSERT_VALUES or ADD_VALUES 2437f089877aSRichard Tran Mills 2438bc0a1609SRichard Tran Mills Output Parameter: 2439bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 2440f089877aSRichard Tran Mills 2441f089877aSRichard Tran Mills Level: intermediate 2442f089877aSRichard Tran Mills 2443bc0a1609SRichard Tran Mills Notes: 2444bc0a1609SRichard Tran Mills The local vectors used here need not be the same as those 2445bc0a1609SRichard Tran Mills obtained from DMCreateLocalVector(), BUT they 2446bc0a1609SRichard Tran Mills must have the same parallel data layout; they could, for example, be 2447bc0a1609SRichard Tran Mills obtained with VecDuplicate() from the DM originating vectors. 2448bc0a1609SRichard Tran Mills 2449bc0a1609SRichard Tran Mills .keywords: DM, local-to-local, begin 2450bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalEnd(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 2451f089877aSRichard Tran Mills 2452f089877aSRichard Tran Mills @*/ 2453f089877aSRichard Tran Mills PetscErrorCode DMLocalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l) 2454f089877aSRichard Tran Mills { 2455f089877aSRichard Tran Mills PetscErrorCode ierr; 2456f089877aSRichard Tran Mills 2457f089877aSRichard Tran Mills PetscFunctionBegin; 2458f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2459bb358533SPatrick Sanan if (!dm->ops->localtolocalbegin) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM does not support local to local maps"); 2460f089877aSRichard Tran Mills ierr = (*dm->ops->localtolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 2461f089877aSRichard Tran Mills PetscFunctionReturn(0); 2462f089877aSRichard Tran Mills } 2463f089877aSRichard Tran Mills 2464f089877aSRichard Tran Mills /*@ 2465bc0a1609SRichard Tran Mills DMLocalToLocalEnd - Maps from a local vector (including ghost points 2466bc0a1609SRichard Tran Mills that contain irrelevant values) to another local vector where the ghost 2467d78e899eSRichard Tran Mills points in the second are set correctly. Must be preceded by DMLocalToLocalBegin(). 2468f089877aSRichard Tran Mills 2469bc0a1609SRichard Tran Mills Neighbor-wise Collective on DM and Vec 2470f089877aSRichard Tran Mills 2471f089877aSRichard Tran Mills Input Parameters: 2472bc0a1609SRichard Tran Mills + da - the DM object 2473bc0a1609SRichard Tran Mills . g - the original local vector 2474bc0a1609SRichard Tran Mills - mode - one of INSERT_VALUES or ADD_VALUES 2475f089877aSRichard Tran Mills 2476bc0a1609SRichard Tran Mills Output Parameter: 2477bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 2478f089877aSRichard Tran Mills 2479f089877aSRichard Tran Mills Level: intermediate 2480f089877aSRichard Tran Mills 2481bc0a1609SRichard Tran Mills Notes: 2482bc0a1609SRichard Tran Mills The local vectors used here need not be the same as those 2483bc0a1609SRichard Tran Mills obtained from DMCreateLocalVector(), BUT they 2484bc0a1609SRichard Tran Mills must have the same parallel data layout; they could, for example, be 2485bc0a1609SRichard Tran Mills obtained with VecDuplicate() from the DM originating vectors. 2486bc0a1609SRichard Tran Mills 2487bc0a1609SRichard Tran Mills .keywords: DM, local-to-local, end 2488bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalBegin(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 2489f089877aSRichard Tran Mills 2490f089877aSRichard Tran Mills @*/ 2491f089877aSRichard Tran Mills PetscErrorCode DMLocalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l) 2492f089877aSRichard Tran Mills { 2493f089877aSRichard Tran Mills PetscErrorCode ierr; 2494f089877aSRichard Tran Mills 2495f089877aSRichard Tran Mills PetscFunctionBegin; 2496f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2497bb358533SPatrick Sanan if (!dm->ops->localtolocalend) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM does not support local to local maps"); 2498f089877aSRichard Tran Mills ierr = (*dm->ops->localtolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 2499f089877aSRichard Tran Mills PetscFunctionReturn(0); 2500f089877aSRichard Tran Mills } 2501f089877aSRichard Tran Mills 2502f089877aSRichard Tran Mills 250347c6ae99SBarry Smith /*@ 250447c6ae99SBarry Smith DMCoarsen - Coarsens a DM object 250547c6ae99SBarry Smith 250647c6ae99SBarry Smith Collective on DM 250747c6ae99SBarry Smith 250847c6ae99SBarry Smith Input Parameter: 250947c6ae99SBarry Smith + dm - the DM object 251091d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL) 251147c6ae99SBarry Smith 251247c6ae99SBarry Smith Output Parameter: 251347c6ae99SBarry Smith . dmc - the coarsened DM 251447c6ae99SBarry Smith 251547c6ae99SBarry Smith Level: developer 251647c6ae99SBarry Smith 2517e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 251847c6ae99SBarry Smith 251947c6ae99SBarry Smith @*/ 25207087cfbeSBarry Smith PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc) 252147c6ae99SBarry Smith { 252247c6ae99SBarry Smith PetscErrorCode ierr; 2523b17ce1afSJed Brown DMCoarsenHookLink link; 252447c6ae99SBarry Smith 252547c6ae99SBarry Smith PetscFunctionBegin; 2526171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2527fef3a512SBarry Smith if (!dm->ops->coarsen) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM cannot coarsen"); 252847a35634SPatrick Farrell ierr = PetscLogEventBegin(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr); 252947c6ae99SBarry Smith ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr); 25308892b4c3SMatthew G. Knepley if (!(*dmc)) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "NULL coarse mesh produced"); 2531a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dm,*dmc);CHKERRQ(ierr); 253243842a1eSJed Brown (*dmc)->ops->creatematrix = dm->ops->creatematrix; 25338cd211a4SJed Brown ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr); 2534644e2e5bSBarry Smith (*dmc)->ctx = dm->ctx; 25350598a293SJed Brown (*dmc)->levelup = dm->levelup; 2536656b349aSBarry Smith (*dmc)->leveldown = dm->leveldown + 1; 2537e4b4b23bSJed Brown ierr = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr); 2538b17ce1afSJed Brown for (link=dm->coarsenhook; link; link=link->next) { 2539b17ce1afSJed Brown if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);} 2540b17ce1afSJed Brown } 254147a35634SPatrick Farrell ierr = PetscLogEventEnd(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr); 2542b17ce1afSJed Brown PetscFunctionReturn(0); 2543b17ce1afSJed Brown } 2544b17ce1afSJed Brown 2545bb9467b5SJed Brown /*@C 2546b17ce1afSJed Brown DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid 2547b17ce1afSJed Brown 2548b17ce1afSJed Brown Logically Collective 2549b17ce1afSJed Brown 2550b17ce1afSJed Brown Input Arguments: 2551b17ce1afSJed Brown + fine - nonlinear solver context on which to run a hook when restricting to a coarser level 2552b17ce1afSJed Brown . coarsenhook - function to run when setting up a coarser level 2553b17ce1afSJed Brown . restricthook - function to run to update data on coarser levels (once per SNESSolve()) 25540298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2555b17ce1afSJed Brown 2556b17ce1afSJed Brown Calling sequence of coarsenhook: 2557b17ce1afSJed Brown $ coarsenhook(DM fine,DM coarse,void *ctx); 2558b17ce1afSJed Brown 2559b17ce1afSJed Brown + fine - fine level DM 2560b17ce1afSJed Brown . coarse - coarse level DM to restrict problem to 2561b17ce1afSJed Brown - ctx - optional user-defined function context 2562b17ce1afSJed Brown 2563b17ce1afSJed Brown Calling sequence for restricthook: 2564c833c3b5SJed Brown $ restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx) 2565b17ce1afSJed Brown 2566b17ce1afSJed Brown + fine - fine level DM 2567b17ce1afSJed Brown . mrestrict - matrix restricting a fine-level solution to the coarse grid 2568c833c3b5SJed Brown . rscale - scaling vector for restriction 2569c833c3b5SJed Brown . inject - matrix restricting by injection 2570b17ce1afSJed Brown . coarse - coarse level DM to update 2571b17ce1afSJed Brown - ctx - optional user-defined function context 2572b17ce1afSJed Brown 2573b17ce1afSJed Brown Level: advanced 2574b17ce1afSJed Brown 2575b17ce1afSJed Brown Notes: 2576b17ce1afSJed Brown This function is only needed if auxiliary data needs to be set up on coarse grids. 2577b17ce1afSJed Brown 2578b17ce1afSJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 2579b17ce1afSJed Brown 2580b17ce1afSJed Brown In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 2581b17ce1afSJed Brown extract the finest level information from its context (instead of from the SNES). 2582b17ce1afSJed Brown 2583bb9467b5SJed Brown This function is currently not available from Fortran. 2584bb9467b5SJed Brown 2585dc822a44SJed Brown .seealso: DMCoarsenHookRemove(), DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 2586b17ce1afSJed Brown @*/ 2587b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx) 2588b17ce1afSJed Brown { 2589b17ce1afSJed Brown PetscErrorCode ierr; 2590b17ce1afSJed Brown DMCoarsenHookLink link,*p; 2591b17ce1afSJed Brown 2592b17ce1afSJed Brown PetscFunctionBegin; 2593b17ce1afSJed Brown PetscValidHeaderSpecific(fine,DM_CLASSID,1); 25941e3d8eccSJed Brown for (p=&fine->coarsenhook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */ 25951e3d8eccSJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0); 25961e3d8eccSJed Brown } 259795dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 2598b17ce1afSJed Brown link->coarsenhook = coarsenhook; 2599b17ce1afSJed Brown link->restricthook = restricthook; 2600b17ce1afSJed Brown link->ctx = ctx; 26010298fd71SBarry Smith link->next = NULL; 2602b17ce1afSJed Brown *p = link; 2603b17ce1afSJed Brown PetscFunctionReturn(0); 2604b17ce1afSJed Brown } 2605b17ce1afSJed Brown 2606dc822a44SJed Brown /*@C 2607dc822a44SJed Brown DMCoarsenHookRemove - remove a callback from the list of hooks to be run when restricting a nonlinear problem to the coarse grid 2608dc822a44SJed Brown 2609dc822a44SJed Brown Logically Collective 2610dc822a44SJed Brown 2611dc822a44SJed Brown Input Arguments: 2612dc822a44SJed Brown + fine - nonlinear solver context on which to run a hook when restricting to a coarser level 2613dc822a44SJed Brown . coarsenhook - function to run when setting up a coarser level 2614dc822a44SJed Brown . restricthook - function to run to update data on coarser levels (once per SNESSolve()) 2615dc822a44SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2616dc822a44SJed Brown 2617dc822a44SJed Brown Level: advanced 2618dc822a44SJed Brown 2619dc822a44SJed Brown Notes: 2620dc822a44SJed Brown This function does nothing if the hook is not in the list. 2621dc822a44SJed Brown 2622dc822a44SJed Brown This function is currently not available from Fortran. 2623dc822a44SJed Brown 2624dc822a44SJed Brown .seealso: DMCoarsenHookAdd(), DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 2625dc822a44SJed Brown @*/ 2626dc822a44SJed Brown PetscErrorCode DMCoarsenHookRemove(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx) 2627dc822a44SJed Brown { 2628dc822a44SJed Brown PetscErrorCode ierr; 2629dc822a44SJed Brown DMCoarsenHookLink link,*p; 2630dc822a44SJed Brown 2631dc822a44SJed Brown PetscFunctionBegin; 2632dc822a44SJed Brown PetscValidHeaderSpecific(fine,DM_CLASSID,1); 2633dc822a44SJed Brown for (p=&fine->coarsenhook; *p; p=&(*p)->next) { /* Search the list of current hooks */ 2634dc822a44SJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 2635dc822a44SJed Brown link = *p; 2636dc822a44SJed Brown *p = link->next; 2637dc822a44SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 2638dc822a44SJed Brown break; 2639dc822a44SJed Brown } 2640dc822a44SJed Brown } 2641dc822a44SJed Brown PetscFunctionReturn(0); 2642dc822a44SJed Brown } 2643dc822a44SJed Brown 2644dc822a44SJed Brown 2645b17ce1afSJed Brown /*@ 2646b17ce1afSJed Brown DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd() 2647b17ce1afSJed Brown 2648b17ce1afSJed Brown Collective if any hooks are 2649b17ce1afSJed Brown 2650b17ce1afSJed Brown Input Arguments: 2651b17ce1afSJed Brown + fine - finer DM to use as a base 2652b17ce1afSJed Brown . restrct - restriction matrix, apply using MatRestrict() 2653e91eccc2SStefano Zampini . rscale - scaling vector for restriction 2654b17ce1afSJed Brown . inject - injection matrix, also use MatRestrict() 2655e91eccc2SStefano Zampini - coarse - coarser DM to update 2656b17ce1afSJed Brown 2657b17ce1afSJed Brown Level: developer 2658b17ce1afSJed Brown 2659b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict() 2660b17ce1afSJed Brown @*/ 2661b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse) 2662b17ce1afSJed Brown { 2663b17ce1afSJed Brown PetscErrorCode ierr; 2664b17ce1afSJed Brown DMCoarsenHookLink link; 2665b17ce1afSJed Brown 2666b17ce1afSJed Brown PetscFunctionBegin; 2667b17ce1afSJed Brown for (link=fine->coarsenhook; link; link=link->next) { 26688865f1eaSKarl Rupp if (link->restricthook) { 26698865f1eaSKarl Rupp ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr); 26708865f1eaSKarl Rupp } 2671b17ce1afSJed Brown } 267247c6ae99SBarry Smith PetscFunctionReturn(0); 267347c6ae99SBarry Smith } 267447c6ae99SBarry Smith 2675bb9467b5SJed Brown /*@C 2676be081cd6SPeter Brune DMSubDomainHookAdd - adds a callback to be run when restricting a problem to the coarse grid 26775dbd56e3SPeter Brune 26785dbd56e3SPeter Brune Logically Collective 26795dbd56e3SPeter Brune 26805dbd56e3SPeter Brune Input Arguments: 26815dbd56e3SPeter Brune + global - global DM 2682ec4806b8SPeter Brune . ddhook - function to run to pass data to the decomposition DM upon its creation 26835dbd56e3SPeter Brune . restricthook - function to run to update data on block solve (at the beginning of the block solve) 26840298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 26855dbd56e3SPeter Brune 2686ec4806b8SPeter Brune 2687ec4806b8SPeter Brune Calling sequence for ddhook: 2688ec4806b8SPeter Brune $ ddhook(DM global,DM block,void *ctx) 2689ec4806b8SPeter Brune 2690ec4806b8SPeter Brune + global - global DM 2691ec4806b8SPeter Brune . block - block DM 2692ec4806b8SPeter Brune - ctx - optional user-defined function context 2693ec4806b8SPeter Brune 26945dbd56e3SPeter Brune Calling sequence for restricthook: 2695ec4806b8SPeter Brune $ restricthook(DM global,VecScatter out,VecScatter in,DM block,void *ctx) 26965dbd56e3SPeter Brune 26975dbd56e3SPeter Brune + global - global DM 26985dbd56e3SPeter Brune . out - scatter to the outer (with ghost and overlap points) block vector 26995dbd56e3SPeter Brune . in - scatter to block vector values only owned locally 2700ec4806b8SPeter Brune . block - block DM 27015dbd56e3SPeter Brune - ctx - optional user-defined function context 27025dbd56e3SPeter Brune 27035dbd56e3SPeter Brune Level: advanced 27045dbd56e3SPeter Brune 27055dbd56e3SPeter Brune Notes: 2706ec4806b8SPeter Brune This function is only needed if auxiliary data needs to be set up on subdomain DMs. 27075dbd56e3SPeter Brune 27085dbd56e3SPeter Brune If this function is called multiple times, the hooks will be run in the order they are added. 27095dbd56e3SPeter Brune 27105dbd56e3SPeter Brune In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 2711ec4806b8SPeter Brune extract the global information from its context (instead of from the SNES). 27125dbd56e3SPeter Brune 2713bb9467b5SJed Brown This function is currently not available from Fortran. 2714bb9467b5SJed Brown 27155dbd56e3SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 27165dbd56e3SPeter Brune @*/ 2717be081cd6SPeter Brune PetscErrorCode DMSubDomainHookAdd(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx) 27185dbd56e3SPeter Brune { 27195dbd56e3SPeter Brune PetscErrorCode ierr; 2720be081cd6SPeter Brune DMSubDomainHookLink link,*p; 27215dbd56e3SPeter Brune 27225dbd56e3SPeter Brune PetscFunctionBegin; 27235dbd56e3SPeter Brune PetscValidHeaderSpecific(global,DM_CLASSID,1); 2724b3a6b972SJed Brown for (p=&global->subdomainhook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */ 2725b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0); 2726b3a6b972SJed Brown } 272795dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 27285dbd56e3SPeter Brune link->restricthook = restricthook; 2729be081cd6SPeter Brune link->ddhook = ddhook; 27305dbd56e3SPeter Brune link->ctx = ctx; 27310298fd71SBarry Smith link->next = NULL; 27325dbd56e3SPeter Brune *p = link; 27335dbd56e3SPeter Brune PetscFunctionReturn(0); 27345dbd56e3SPeter Brune } 27355dbd56e3SPeter Brune 2736b3a6b972SJed Brown /*@C 2737b3a6b972SJed Brown DMSubDomainHookRemove - remove a callback from the list to be run when restricting a problem to the coarse grid 2738b3a6b972SJed Brown 2739b3a6b972SJed Brown Logically Collective 2740b3a6b972SJed Brown 2741b3a6b972SJed Brown Input Arguments: 2742b3a6b972SJed Brown + global - global DM 2743b3a6b972SJed Brown . ddhook - function to run to pass data to the decomposition DM upon its creation 2744b3a6b972SJed Brown . restricthook - function to run to update data on block solve (at the beginning of the block solve) 2745b3a6b972SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2746b3a6b972SJed Brown 2747b3a6b972SJed Brown Level: advanced 2748b3a6b972SJed Brown 2749b3a6b972SJed Brown Notes: 2750b3a6b972SJed Brown 2751b3a6b972SJed Brown This function is currently not available from Fortran. 2752b3a6b972SJed Brown 2753b3a6b972SJed Brown .seealso: DMSubDomainHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 2754b3a6b972SJed Brown @*/ 2755b3a6b972SJed Brown PetscErrorCode DMSubDomainHookRemove(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx) 2756b3a6b972SJed Brown { 2757b3a6b972SJed Brown PetscErrorCode ierr; 2758b3a6b972SJed Brown DMSubDomainHookLink link,*p; 2759b3a6b972SJed Brown 2760b3a6b972SJed Brown PetscFunctionBegin; 2761b3a6b972SJed Brown PetscValidHeaderSpecific(global,DM_CLASSID,1); 2762b3a6b972SJed Brown for (p=&global->subdomainhook; *p; p=&(*p)->next) { /* Search the list of current hooks */ 2763b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 2764b3a6b972SJed Brown link = *p; 2765b3a6b972SJed Brown *p = link->next; 2766b3a6b972SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 2767b3a6b972SJed Brown break; 2768b3a6b972SJed Brown } 2769b3a6b972SJed Brown } 2770b3a6b972SJed Brown PetscFunctionReturn(0); 2771b3a6b972SJed Brown } 2772b3a6b972SJed Brown 27735dbd56e3SPeter Brune /*@ 2774be081cd6SPeter Brune DMSubDomainRestrict - restricts user-defined problem data to a block DM by running hooks registered by DMSubDomainHookAdd() 27755dbd56e3SPeter Brune 27765dbd56e3SPeter Brune Collective if any hooks are 27775dbd56e3SPeter Brune 27785dbd56e3SPeter Brune Input Arguments: 27795dbd56e3SPeter Brune + fine - finer DM to use as a base 2780be081cd6SPeter Brune . oscatter - scatter from domain global vector filling subdomain global vector with overlap 2781be081cd6SPeter Brune . gscatter - scatter from domain global vector filling subdomain local vector with ghosts 27825dbd56e3SPeter Brune - coarse - coarer DM to update 27835dbd56e3SPeter Brune 27845dbd56e3SPeter Brune Level: developer 27855dbd56e3SPeter Brune 27865dbd56e3SPeter Brune .seealso: DMCoarsenHookAdd(), MatRestrict() 27875dbd56e3SPeter Brune @*/ 2788be081cd6SPeter Brune PetscErrorCode DMSubDomainRestrict(DM global,VecScatter oscatter,VecScatter gscatter,DM subdm) 27895dbd56e3SPeter Brune { 27905dbd56e3SPeter Brune PetscErrorCode ierr; 2791be081cd6SPeter Brune DMSubDomainHookLink link; 27925dbd56e3SPeter Brune 27935dbd56e3SPeter Brune PetscFunctionBegin; 2794be081cd6SPeter Brune for (link=global->subdomainhook; link; link=link->next) { 27958865f1eaSKarl Rupp if (link->restricthook) { 27968865f1eaSKarl Rupp ierr = (*link->restricthook)(global,oscatter,gscatter,subdm,link->ctx);CHKERRQ(ierr); 27978865f1eaSKarl Rupp } 27985dbd56e3SPeter Brune } 27995dbd56e3SPeter Brune PetscFunctionReturn(0); 28005dbd56e3SPeter Brune } 28015dbd56e3SPeter Brune 28025fe1f584SPeter Brune /*@ 28036a7d9d85SPeter Brune DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM. 28045fe1f584SPeter Brune 28055fe1f584SPeter Brune Not Collective 28065fe1f584SPeter Brune 28075fe1f584SPeter Brune Input Parameter: 28085fe1f584SPeter Brune . dm - the DM object 28095fe1f584SPeter Brune 28105fe1f584SPeter Brune Output Parameter: 28116a7d9d85SPeter Brune . level - number of coarsenings 28125fe1f584SPeter Brune 28135fe1f584SPeter Brune Level: developer 28145fe1f584SPeter Brune 28156a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 28165fe1f584SPeter Brune 28175fe1f584SPeter Brune @*/ 28185fe1f584SPeter Brune PetscErrorCode DMGetCoarsenLevel(DM dm,PetscInt *level) 28195fe1f584SPeter Brune { 28205fe1f584SPeter Brune PetscFunctionBegin; 28215fe1f584SPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 28225fe1f584SPeter Brune *level = dm->leveldown; 28235fe1f584SPeter Brune PetscFunctionReturn(0); 28245fe1f584SPeter Brune } 28255fe1f584SPeter Brune 2826*9a64c4a8SMatthew G. Knepley /*@ 2827*9a64c4a8SMatthew G. Knepley DMSetCoarsenLevel - Sets the number of coarsenings that have generated this DM. 2828*9a64c4a8SMatthew G. Knepley 2829*9a64c4a8SMatthew G. Knepley Not Collective 2830*9a64c4a8SMatthew G. Knepley 2831*9a64c4a8SMatthew G. Knepley Input Parameters: 2832*9a64c4a8SMatthew G. Knepley + dm - the DM object 2833*9a64c4a8SMatthew G. Knepley - level - number of coarsenings 2834*9a64c4a8SMatthew G. Knepley 2835*9a64c4a8SMatthew G. Knepley Level: developer 2836*9a64c4a8SMatthew G. Knepley 2837*9a64c4a8SMatthew G. Knepley .seealso DMCoarsen(), DMGetCoarsenLevel(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 2838*9a64c4a8SMatthew G. Knepley @*/ 2839*9a64c4a8SMatthew G. Knepley PetscErrorCode DMSetCoarsenLevel(DM dm,PetscInt level) 2840*9a64c4a8SMatthew G. Knepley { 2841*9a64c4a8SMatthew G. Knepley PetscFunctionBegin; 2842*9a64c4a8SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2843*9a64c4a8SMatthew G. Knepley dm->leveldown = level; 2844*9a64c4a8SMatthew G. Knepley PetscFunctionReturn(0); 2845*9a64c4a8SMatthew G. Knepley } 2846*9a64c4a8SMatthew G. Knepley 28475fe1f584SPeter Brune 28485fe1f584SPeter Brune 284947c6ae99SBarry Smith /*@C 285047c6ae99SBarry Smith DMRefineHierarchy - Refines a DM object, all levels at once 285147c6ae99SBarry Smith 285247c6ae99SBarry Smith Collective on DM 285347c6ae99SBarry Smith 285447c6ae99SBarry Smith Input Parameter: 285547c6ae99SBarry Smith + dm - the DM object 285647c6ae99SBarry Smith - nlevels - the number of levels of refinement 285747c6ae99SBarry Smith 285847c6ae99SBarry Smith Output Parameter: 285947c6ae99SBarry Smith . dmf - the refined DM hierarchy 286047c6ae99SBarry Smith 286147c6ae99SBarry Smith Level: developer 286247c6ae99SBarry Smith 2863e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 286447c6ae99SBarry Smith 286547c6ae99SBarry Smith @*/ 28667087cfbeSBarry Smith PetscErrorCode DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[]) 286747c6ae99SBarry Smith { 286847c6ae99SBarry Smith PetscErrorCode ierr; 286947c6ae99SBarry Smith 287047c6ae99SBarry Smith PetscFunctionBegin; 2871171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2872ce94432eSBarry Smith if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 287347c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 287447c6ae99SBarry Smith if (dm->ops->refinehierarchy) { 287547c6ae99SBarry Smith ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr); 287647c6ae99SBarry Smith } else if (dm->ops->refine) { 287747c6ae99SBarry Smith PetscInt i; 287847c6ae99SBarry Smith 2879ce94432eSBarry Smith ierr = DMRefine(dm,PetscObjectComm((PetscObject)dm),&dmf[0]);CHKERRQ(ierr); 288047c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 2881ce94432eSBarry Smith ierr = DMRefine(dmf[i-1],PetscObjectComm((PetscObject)dm),&dmf[i]);CHKERRQ(ierr); 288247c6ae99SBarry Smith } 2883ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No RefineHierarchy for this DM yet"); 288447c6ae99SBarry Smith PetscFunctionReturn(0); 288547c6ae99SBarry Smith } 288647c6ae99SBarry Smith 288747c6ae99SBarry Smith /*@C 288847c6ae99SBarry Smith DMCoarsenHierarchy - Coarsens a DM object, all levels at once 288947c6ae99SBarry Smith 289047c6ae99SBarry Smith Collective on DM 289147c6ae99SBarry Smith 289247c6ae99SBarry Smith Input Parameter: 289347c6ae99SBarry Smith + dm - the DM object 289447c6ae99SBarry Smith - nlevels - the number of levels of coarsening 289547c6ae99SBarry Smith 289647c6ae99SBarry Smith Output Parameter: 289747c6ae99SBarry Smith . dmc - the coarsened DM hierarchy 289847c6ae99SBarry Smith 289947c6ae99SBarry Smith Level: developer 290047c6ae99SBarry Smith 2901e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 290247c6ae99SBarry Smith 290347c6ae99SBarry Smith @*/ 29047087cfbeSBarry Smith PetscErrorCode DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[]) 290547c6ae99SBarry Smith { 290647c6ae99SBarry Smith PetscErrorCode ierr; 290747c6ae99SBarry Smith 290847c6ae99SBarry Smith PetscFunctionBegin; 2909171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2910ce94432eSBarry Smith if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 291147c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 291247c6ae99SBarry Smith PetscValidPointer(dmc,3); 291347c6ae99SBarry Smith if (dm->ops->coarsenhierarchy) { 291447c6ae99SBarry Smith ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr); 291547c6ae99SBarry Smith } else if (dm->ops->coarsen) { 291647c6ae99SBarry Smith PetscInt i; 291747c6ae99SBarry Smith 2918ce94432eSBarry Smith ierr = DMCoarsen(dm,PetscObjectComm((PetscObject)dm),&dmc[0]);CHKERRQ(ierr); 291947c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 2920ce94432eSBarry Smith ierr = DMCoarsen(dmc[i-1],PetscObjectComm((PetscObject)dm),&dmc[i]);CHKERRQ(ierr); 292147c6ae99SBarry Smith } 2922ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet"); 292347c6ae99SBarry Smith PetscFunctionReturn(0); 292447c6ae99SBarry Smith } 292547c6ae99SBarry Smith 292647c6ae99SBarry Smith /*@ 2927e727c939SJed Brown DMCreateAggregates - Gets the aggregates that map between 292847c6ae99SBarry Smith grids associated with two DMs. 292947c6ae99SBarry Smith 293047c6ae99SBarry Smith Collective on DM 293147c6ae99SBarry Smith 293247c6ae99SBarry Smith Input Parameters: 293347c6ae99SBarry Smith + dmc - the coarse grid DM 293447c6ae99SBarry Smith - dmf - the fine grid DM 293547c6ae99SBarry Smith 293647c6ae99SBarry Smith Output Parameters: 293747c6ae99SBarry Smith . rest - the restriction matrix (transpose of the projection matrix) 293847c6ae99SBarry Smith 293947c6ae99SBarry Smith Level: intermediate 294047c6ae99SBarry Smith 294147c6ae99SBarry Smith .keywords: interpolation, restriction, multigrid 294247c6ae99SBarry Smith 2943e727c939SJed Brown .seealso: DMRefine(), DMCreateInjection(), DMCreateInterpolation() 294447c6ae99SBarry Smith @*/ 2945e727c939SJed Brown PetscErrorCode DMCreateAggregates(DM dmc, DM dmf, Mat *rest) 294647c6ae99SBarry Smith { 294747c6ae99SBarry Smith PetscErrorCode ierr; 294847c6ae99SBarry Smith 294947c6ae99SBarry Smith PetscFunctionBegin; 2950171400e9SBarry Smith PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 2951171400e9SBarry Smith PetscValidHeaderSpecific(dmf,DM_CLASSID,2); 295247c6ae99SBarry Smith ierr = (*dmc->ops->getaggregates)(dmc, dmf, rest);CHKERRQ(ierr); 295347c6ae99SBarry Smith PetscFunctionReturn(0); 295447c6ae99SBarry Smith } 295547c6ae99SBarry Smith 29561a266240SBarry Smith /*@C 29571a266240SBarry Smith DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed 29581a266240SBarry Smith 29591a266240SBarry Smith Not Collective 29601a266240SBarry Smith 29611a266240SBarry Smith Input Parameters: 29621a266240SBarry Smith + dm - the DM object 29631a266240SBarry Smith - destroy - the destroy function 29641a266240SBarry Smith 29651a266240SBarry Smith Level: intermediate 29661a266240SBarry Smith 2967e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 29681a266240SBarry Smith 2969f07f9ceaSJed Brown @*/ 29701a266240SBarry Smith PetscErrorCode DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**)) 29711a266240SBarry Smith { 29721a266240SBarry Smith PetscFunctionBegin; 2973171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 29741a266240SBarry Smith dm->ctxdestroy = destroy; 29751a266240SBarry Smith PetscFunctionReturn(0); 29761a266240SBarry Smith } 29771a266240SBarry Smith 2978b07ff414SBarry Smith /*@ 29791b2093e4SBarry Smith DMSetApplicationContext - Set a user context into a DM object 298047c6ae99SBarry Smith 298147c6ae99SBarry Smith Not Collective 298247c6ae99SBarry Smith 298347c6ae99SBarry Smith Input Parameters: 298447c6ae99SBarry Smith + dm - the DM object 298547c6ae99SBarry Smith - ctx - the user context 298647c6ae99SBarry Smith 298747c6ae99SBarry Smith Level: intermediate 298847c6ae99SBarry Smith 2989e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 299047c6ae99SBarry Smith 299147c6ae99SBarry Smith @*/ 29921b2093e4SBarry Smith PetscErrorCode DMSetApplicationContext(DM dm,void *ctx) 299347c6ae99SBarry Smith { 299447c6ae99SBarry Smith PetscFunctionBegin; 2995171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 299647c6ae99SBarry Smith dm->ctx = ctx; 299747c6ae99SBarry Smith PetscFunctionReturn(0); 299847c6ae99SBarry Smith } 299947c6ae99SBarry Smith 300047c6ae99SBarry Smith /*@ 30011b2093e4SBarry Smith DMGetApplicationContext - Gets a user context from a DM object 300247c6ae99SBarry Smith 300347c6ae99SBarry Smith Not Collective 300447c6ae99SBarry Smith 300547c6ae99SBarry Smith Input Parameter: 300647c6ae99SBarry Smith . dm - the DM object 300747c6ae99SBarry Smith 300847c6ae99SBarry Smith Output Parameter: 300947c6ae99SBarry Smith . ctx - the user context 301047c6ae99SBarry Smith 301147c6ae99SBarry Smith Level: intermediate 301247c6ae99SBarry Smith 3013e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 301447c6ae99SBarry Smith 301547c6ae99SBarry Smith @*/ 30161b2093e4SBarry Smith PetscErrorCode DMGetApplicationContext(DM dm,void *ctx) 301747c6ae99SBarry Smith { 301847c6ae99SBarry Smith PetscFunctionBegin; 3019171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 30201b2093e4SBarry Smith *(void**)ctx = dm->ctx; 302147c6ae99SBarry Smith PetscFunctionReturn(0); 302247c6ae99SBarry Smith } 302347c6ae99SBarry Smith 302408da532bSDmitry Karpeev /*@C 3025df3898eeSBarry Smith DMSetVariableBounds - sets a function to compute the lower and upper bound vectors for SNESVI. 302608da532bSDmitry Karpeev 302708da532bSDmitry Karpeev Logically Collective on DM 302808da532bSDmitry Karpeev 302908da532bSDmitry Karpeev Input Parameter: 303008da532bSDmitry Karpeev + dm - the DM object 30310298fd71SBarry Smith - f - the function that computes variable bounds used by SNESVI (use NULL to cancel a previous function that was set) 303208da532bSDmitry Karpeev 303308da532bSDmitry Karpeev Level: intermediate 303408da532bSDmitry Karpeev 3035835c3ec7SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), 303608da532bSDmitry Karpeev DMSetJacobian() 303708da532bSDmitry Karpeev 303808da532bSDmitry Karpeev @*/ 303908da532bSDmitry Karpeev PetscErrorCode DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec)) 304008da532bSDmitry Karpeev { 304108da532bSDmitry Karpeev PetscFunctionBegin; 304208da532bSDmitry Karpeev dm->ops->computevariablebounds = f; 304308da532bSDmitry Karpeev PetscFunctionReturn(0); 304408da532bSDmitry Karpeev } 304508da532bSDmitry Karpeev 304608da532bSDmitry Karpeev /*@ 304708da532bSDmitry Karpeev DMHasVariableBounds - does the DM object have a variable bounds function? 304808da532bSDmitry Karpeev 304908da532bSDmitry Karpeev Not Collective 305008da532bSDmitry Karpeev 305108da532bSDmitry Karpeev Input Parameter: 305208da532bSDmitry Karpeev . dm - the DM object to destroy 305308da532bSDmitry Karpeev 305408da532bSDmitry Karpeev Output Parameter: 305508da532bSDmitry Karpeev . flg - PETSC_TRUE if the variable bounds function exists 305608da532bSDmitry Karpeev 305708da532bSDmitry Karpeev Level: developer 305808da532bSDmitry Karpeev 305974e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 306008da532bSDmitry Karpeev 306108da532bSDmitry Karpeev @*/ 306208da532bSDmitry Karpeev PetscErrorCode DMHasVariableBounds(DM dm,PetscBool *flg) 306308da532bSDmitry Karpeev { 306408da532bSDmitry Karpeev PetscFunctionBegin; 306508da532bSDmitry Karpeev *flg = (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE; 306608da532bSDmitry Karpeev PetscFunctionReturn(0); 306708da532bSDmitry Karpeev } 306808da532bSDmitry Karpeev 306908da532bSDmitry Karpeev /*@C 307008da532bSDmitry Karpeev DMComputeVariableBounds - compute variable bounds used by SNESVI. 307108da532bSDmitry Karpeev 307208da532bSDmitry Karpeev Logically Collective on DM 307308da532bSDmitry Karpeev 307408da532bSDmitry Karpeev Input Parameters: 3075907376e6SBarry Smith . dm - the DM object 307608da532bSDmitry Karpeev 307708da532bSDmitry Karpeev Output parameters: 307808da532bSDmitry Karpeev + xl - lower bound 307908da532bSDmitry Karpeev - xu - upper bound 308008da532bSDmitry Karpeev 3081907376e6SBarry Smith Level: advanced 3082907376e6SBarry Smith 308395452b02SPatrick Sanan Notes: 308495452b02SPatrick Sanan This is generally not called by users. It calls the function provided by the user with DMSetVariableBounds() 308508da532bSDmitry Karpeev 308674e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 308708da532bSDmitry Karpeev 308808da532bSDmitry Karpeev @*/ 308908da532bSDmitry Karpeev PetscErrorCode DMComputeVariableBounds(DM dm, Vec xl, Vec xu) 309008da532bSDmitry Karpeev { 309108da532bSDmitry Karpeev PetscErrorCode ierr; 30925fd66863SKarl Rupp 309308da532bSDmitry Karpeev PetscFunctionBegin; 309408da532bSDmitry Karpeev PetscValidHeaderSpecific(xl,VEC_CLASSID,2); 309508da532bSDmitry Karpeev PetscValidHeaderSpecific(xu,VEC_CLASSID,2); 309608da532bSDmitry Karpeev if (dm->ops->computevariablebounds) { 309708da532bSDmitry Karpeev ierr = (*dm->ops->computevariablebounds)(dm, xl,xu);CHKERRQ(ierr); 30988865f1eaSKarl Rupp } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "This DM is incapable of computing variable bounds."); 309908da532bSDmitry Karpeev PetscFunctionReturn(0); 310008da532bSDmitry Karpeev } 310108da532bSDmitry Karpeev 3102b0ae01b7SPeter Brune /*@ 3103b0ae01b7SPeter Brune DMHasColoring - does the DM object have a method of providing a coloring? 3104b0ae01b7SPeter Brune 3105b0ae01b7SPeter Brune Not Collective 3106b0ae01b7SPeter Brune 3107b0ae01b7SPeter Brune Input Parameter: 3108b0ae01b7SPeter Brune . dm - the DM object 3109b0ae01b7SPeter Brune 3110b0ae01b7SPeter Brune Output Parameter: 3111b0ae01b7SPeter Brune . flg - PETSC_TRUE if the DM has facilities for DMCreateColoring(). 3112b0ae01b7SPeter Brune 3113b0ae01b7SPeter Brune Level: developer 3114b0ae01b7SPeter Brune 3115b0ae01b7SPeter Brune .seealso DMHasFunction(), DMCreateColoring() 3116b0ae01b7SPeter Brune 3117b0ae01b7SPeter Brune @*/ 3118b0ae01b7SPeter Brune PetscErrorCode DMHasColoring(DM dm,PetscBool *flg) 3119b0ae01b7SPeter Brune { 3120b0ae01b7SPeter Brune PetscFunctionBegin; 3121b0ae01b7SPeter Brune *flg = (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE; 3122b0ae01b7SPeter Brune PetscFunctionReturn(0); 3123b0ae01b7SPeter Brune } 3124b0ae01b7SPeter Brune 31253ad4599aSBarry Smith /*@ 31263ad4599aSBarry Smith DMHasCreateRestriction - does the DM object have a method of providing a restriction? 31273ad4599aSBarry Smith 31283ad4599aSBarry Smith Not Collective 31293ad4599aSBarry Smith 31303ad4599aSBarry Smith Input Parameter: 31313ad4599aSBarry Smith . dm - the DM object 31323ad4599aSBarry Smith 31333ad4599aSBarry Smith Output Parameter: 31343ad4599aSBarry Smith . flg - PETSC_TRUE if the DM has facilities for DMCreateRestriction(). 31353ad4599aSBarry Smith 31363ad4599aSBarry Smith Level: developer 31373ad4599aSBarry Smith 31383ad4599aSBarry Smith .seealso DMHasFunction(), DMCreateRestriction() 31393ad4599aSBarry Smith 31403ad4599aSBarry Smith @*/ 31413ad4599aSBarry Smith PetscErrorCode DMHasCreateRestriction(DM dm,PetscBool *flg) 31423ad4599aSBarry Smith { 31433ad4599aSBarry Smith PetscFunctionBegin; 31443ad4599aSBarry Smith *flg = (dm->ops->createrestriction) ? PETSC_TRUE : PETSC_FALSE; 31453ad4599aSBarry Smith PetscFunctionReturn(0); 31463ad4599aSBarry Smith } 31473ad4599aSBarry Smith 3148a7058e45SLawrence Mitchell 3149a7058e45SLawrence Mitchell /*@ 3150a7058e45SLawrence Mitchell DMHasCreateInjection - does the DM object have a method of providing an injection? 3151a7058e45SLawrence Mitchell 3152a7058e45SLawrence Mitchell Not Collective 3153a7058e45SLawrence Mitchell 3154a7058e45SLawrence Mitchell Input Parameter: 3155a7058e45SLawrence Mitchell . dm - the DM object 3156a7058e45SLawrence Mitchell 3157a7058e45SLawrence Mitchell Output Parameter: 3158a7058e45SLawrence Mitchell . flg - PETSC_TRUE if the DM has facilities for DMCreateInjection(). 3159a7058e45SLawrence Mitchell 3160a7058e45SLawrence Mitchell Level: developer 3161a7058e45SLawrence Mitchell 3162a7058e45SLawrence Mitchell .seealso DMHasFunction(), DMCreateInjection() 3163a7058e45SLawrence Mitchell 3164a7058e45SLawrence Mitchell @*/ 3165a7058e45SLawrence Mitchell PetscErrorCode DMHasCreateInjection(DM dm,PetscBool *flg) 3166a7058e45SLawrence Mitchell { 31674a7a4c06SLawrence Mitchell PetscErrorCode ierr; 3168a7058e45SLawrence Mitchell PetscFunctionBegin; 31694a7a4c06SLawrence Mitchell if (!dm->ops->hascreateinjection) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DMHasCreateInjection not implemented for this type"); 31704a7a4c06SLawrence Mitchell ierr = (*dm->ops->hascreateinjection)(dm,flg);CHKERRQ(ierr); 3171a7058e45SLawrence Mitchell PetscFunctionReturn(0); 3172a7058e45SLawrence Mitchell } 3173a7058e45SLawrence Mitchell 3174748fac09SDmitry Karpeev /*@C 317508da532bSDmitry Karpeev DMSetVec - set the vector at which to compute residual, Jacobian and VI bounds, if the problem is nonlinear. 317608da532bSDmitry Karpeev 317708da532bSDmitry Karpeev Collective on DM 317808da532bSDmitry Karpeev 317908da532bSDmitry Karpeev Input Parameter: 318008da532bSDmitry Karpeev + dm - the DM object 31810298fd71SBarry Smith - x - location to compute residual and Jacobian, if NULL is passed to those routines; will be NULL for linear problems. 318208da532bSDmitry Karpeev 318308da532bSDmitry Karpeev Level: developer 318408da532bSDmitry Karpeev 318574e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 318608da532bSDmitry Karpeev 318708da532bSDmitry Karpeev @*/ 318808da532bSDmitry Karpeev PetscErrorCode DMSetVec(DM dm,Vec x) 318908da532bSDmitry Karpeev { 319008da532bSDmitry Karpeev PetscErrorCode ierr; 31915fd66863SKarl Rupp 319208da532bSDmitry Karpeev PetscFunctionBegin; 319308da532bSDmitry Karpeev if (x) { 319408da532bSDmitry Karpeev if (!dm->x) { 319508da532bSDmitry Karpeev ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr); 319608da532bSDmitry Karpeev } 319708da532bSDmitry Karpeev ierr = VecCopy(x,dm->x);CHKERRQ(ierr); 31988865f1eaSKarl Rupp } else if (dm->x) { 319908da532bSDmitry Karpeev ierr = VecDestroy(&dm->x);CHKERRQ(ierr); 320008da532bSDmitry Karpeev } 320108da532bSDmitry Karpeev PetscFunctionReturn(0); 320208da532bSDmitry Karpeev } 320308da532bSDmitry Karpeev 32040298fd71SBarry Smith PetscFunctionList DMList = NULL; 3205264ace61SBarry Smith PetscBool DMRegisterAllCalled = PETSC_FALSE; 3206264ace61SBarry Smith 3207264ace61SBarry Smith /*@C 3208264ace61SBarry Smith DMSetType - Builds a DM, for a particular DM implementation. 3209264ace61SBarry Smith 3210264ace61SBarry Smith Collective on DM 3211264ace61SBarry Smith 3212264ace61SBarry Smith Input Parameters: 3213264ace61SBarry Smith + dm - The DM object 3214264ace61SBarry Smith - method - The name of the DM type 3215264ace61SBarry Smith 3216264ace61SBarry Smith Options Database Key: 3217264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types 3218264ace61SBarry Smith 3219264ace61SBarry Smith Notes: 3220e1589f56SBarry Smith See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D). 3221264ace61SBarry Smith 3222264ace61SBarry Smith Level: intermediate 3223264ace61SBarry Smith 3224264ace61SBarry Smith .keywords: DM, set, type 3225264ace61SBarry Smith .seealso: DMGetType(), DMCreate() 3226264ace61SBarry Smith @*/ 322719fd82e9SBarry Smith PetscErrorCode DMSetType(DM dm, DMType method) 3228264ace61SBarry Smith { 3229264ace61SBarry Smith PetscErrorCode (*r)(DM); 3230264ace61SBarry Smith PetscBool match; 3231264ace61SBarry Smith PetscErrorCode ierr; 3232264ace61SBarry Smith 3233264ace61SBarry Smith PetscFunctionBegin; 3234264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID,1); 3235251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr); 3236264ace61SBarry Smith if (match) PetscFunctionReturn(0); 3237264ace61SBarry Smith 32380f51fdf8SToby Isaac ierr = DMRegisterAll();CHKERRQ(ierr); 32391c9cd337SJed Brown ierr = PetscFunctionListFind(DMList,method,&r);CHKERRQ(ierr); 3240ce94432eSBarry Smith if (!r) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method); 3241264ace61SBarry Smith 3242264ace61SBarry Smith if (dm->ops->destroy) { 3243264ace61SBarry Smith ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr); 32440298fd71SBarry Smith dm->ops->destroy = NULL; 3245264ace61SBarry Smith } 3246264ace61SBarry Smith ierr = (*r)(dm);CHKERRQ(ierr); 3247264ace61SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr); 3248264ace61SBarry Smith PetscFunctionReturn(0); 3249264ace61SBarry Smith } 3250264ace61SBarry Smith 3251264ace61SBarry Smith /*@C 3252264ace61SBarry Smith DMGetType - Gets the DM type name (as a string) from the DM. 3253264ace61SBarry Smith 3254264ace61SBarry Smith Not Collective 3255264ace61SBarry Smith 3256264ace61SBarry Smith Input Parameter: 3257264ace61SBarry Smith . dm - The DM 3258264ace61SBarry Smith 3259264ace61SBarry Smith Output Parameter: 3260264ace61SBarry Smith . type - The DM type name 3261264ace61SBarry Smith 3262264ace61SBarry Smith Level: intermediate 3263264ace61SBarry Smith 3264264ace61SBarry Smith .keywords: DM, get, type, name 3265264ace61SBarry Smith .seealso: DMSetType(), DMCreate() 3266264ace61SBarry Smith @*/ 326719fd82e9SBarry Smith PetscErrorCode DMGetType(DM dm, DMType *type) 3268264ace61SBarry Smith { 3269264ace61SBarry Smith PetscErrorCode ierr; 3270264ace61SBarry Smith 3271264ace61SBarry Smith PetscFunctionBegin; 3272264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID,1); 3273c959eef4SJed Brown PetscValidPointer(type,2); 3274607a6623SBarry Smith ierr = DMRegisterAll();CHKERRQ(ierr); 3275264ace61SBarry Smith *type = ((PetscObject)dm)->type_name; 3276264ace61SBarry Smith PetscFunctionReturn(0); 3277264ace61SBarry Smith } 3278264ace61SBarry Smith 327967a56275SMatthew G Knepley /*@C 328067a56275SMatthew G Knepley DMConvert - Converts a DM to another DM, either of the same or different type. 328167a56275SMatthew G Knepley 328267a56275SMatthew G Knepley Collective on DM 328367a56275SMatthew G Knepley 328467a56275SMatthew G Knepley Input Parameters: 328567a56275SMatthew G Knepley + dm - the DM 328667a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type) 328767a56275SMatthew G Knepley 328867a56275SMatthew G Knepley Output Parameter: 328967a56275SMatthew G Knepley . M - pointer to new DM 329067a56275SMatthew G Knepley 329167a56275SMatthew G Knepley Notes: 329267a56275SMatthew G Knepley Cannot be used to convert a sequential DM to parallel or parallel to sequential, 329367a56275SMatthew G Knepley the MPI communicator of the generated DM is always the same as the communicator 329467a56275SMatthew G Knepley of the input DM. 329567a56275SMatthew G Knepley 329667a56275SMatthew G Knepley Level: intermediate 329767a56275SMatthew G Knepley 329867a56275SMatthew G Knepley .seealso: DMCreate() 329967a56275SMatthew G Knepley @*/ 330019fd82e9SBarry Smith PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M) 330167a56275SMatthew G Knepley { 330267a56275SMatthew G Knepley DM B; 330367a56275SMatthew G Knepley char convname[256]; 3304c067b6caSMatthew G. Knepley PetscBool sametype/*, issame */; 330567a56275SMatthew G Knepley PetscErrorCode ierr; 330667a56275SMatthew G Knepley 330767a56275SMatthew G Knepley PetscFunctionBegin; 330867a56275SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 330967a56275SMatthew G Knepley PetscValidType(dm,1); 331067a56275SMatthew G Knepley PetscValidPointer(M,3); 3311251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr); 3312c067b6caSMatthew G. Knepley /* ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr); */ 3313c067b6caSMatthew G. Knepley if (sametype) { 3314c067b6caSMatthew G. Knepley *M = dm; 3315c067b6caSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr); 3316c067b6caSMatthew G. Knepley PetscFunctionReturn(0); 3317c067b6caSMatthew G. Knepley } else { 33180298fd71SBarry Smith PetscErrorCode (*conv)(DM, DMType, DM*) = NULL; 331967a56275SMatthew G Knepley 332067a56275SMatthew G Knepley /* 332167a56275SMatthew G Knepley Order of precedence: 332267a56275SMatthew G Knepley 1) See if a specialized converter is known to the current DM. 332367a56275SMatthew G Knepley 2) See if a specialized converter is known to the desired DM class. 332467a56275SMatthew G Knepley 3) See if a good general converter is registered for the desired class 332567a56275SMatthew G Knepley 4) See if a good general converter is known for the current matrix. 332667a56275SMatthew G Knepley 5) Use a really basic converter. 332767a56275SMatthew G Knepley */ 332867a56275SMatthew G Knepley 332967a56275SMatthew G Knepley /* 1) See if a specialized converter is known to the current DM and the desired class */ 3330a126751eSBarry Smith ierr = PetscStrncpy(convname,"DMConvert_",sizeof(convname));CHKERRQ(ierr); 3331a126751eSBarry Smith ierr = PetscStrlcat(convname,((PetscObject) dm)->type_name,sizeof(convname));CHKERRQ(ierr); 3332a126751eSBarry Smith ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 3333a126751eSBarry Smith ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 3334a126751eSBarry Smith ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 33350005d66cSJed Brown ierr = PetscObjectQueryFunction((PetscObject)dm,convname,&conv);CHKERRQ(ierr); 333667a56275SMatthew G Knepley if (conv) goto foundconv; 333767a56275SMatthew G Knepley 333867a56275SMatthew G Knepley /* 2) See if a specialized converter is known to the desired DM class. */ 333982f516ccSBarry Smith ierr = DMCreate(PetscObjectComm((PetscObject)dm), &B);CHKERRQ(ierr); 334067a56275SMatthew G Knepley ierr = DMSetType(B, newtype);CHKERRQ(ierr); 3341a126751eSBarry Smith ierr = PetscStrncpy(convname,"DMConvert_",sizeof(convname));CHKERRQ(ierr); 3342a126751eSBarry Smith ierr = PetscStrlcat(convname,((PetscObject) dm)->type_name,sizeof(convname));CHKERRQ(ierr); 3343a126751eSBarry Smith ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 3344a126751eSBarry Smith ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 3345a126751eSBarry Smith ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 33460005d66cSJed Brown ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 334767a56275SMatthew G Knepley if (conv) { 3348fcfd50ebSBarry Smith ierr = DMDestroy(&B);CHKERRQ(ierr); 334967a56275SMatthew G Knepley goto foundconv; 335067a56275SMatthew G Knepley } 335167a56275SMatthew G Knepley 335267a56275SMatthew G Knepley #if 0 335367a56275SMatthew G Knepley /* 3) See if a good general converter is registered for the desired class */ 335467a56275SMatthew G Knepley conv = B->ops->convertfrom; 3355fcfd50ebSBarry Smith ierr = DMDestroy(&B);CHKERRQ(ierr); 335667a56275SMatthew G Knepley if (conv) goto foundconv; 335767a56275SMatthew G Knepley 335867a56275SMatthew G Knepley /* 4) See if a good general converter is known for the current matrix */ 335967a56275SMatthew G Knepley if (dm->ops->convert) { 336067a56275SMatthew G Knepley conv = dm->ops->convert; 336167a56275SMatthew G Knepley } 336267a56275SMatthew G Knepley if (conv) goto foundconv; 336367a56275SMatthew G Knepley #endif 336467a56275SMatthew G Knepley 336567a56275SMatthew G Knepley /* 5) Use a really basic converter. */ 336682f516ccSBarry Smith SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype); 336767a56275SMatthew G Knepley 336867a56275SMatthew G Knepley foundconv: 336967a56275SMatthew G Knepley ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr); 337067a56275SMatthew G Knepley ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr); 337112fa691eSMatthew G. Knepley /* Things that are independent of DM type: We should consult DMClone() here */ 337290b157c4SStefano Zampini { 337390b157c4SStefano Zampini PetscBool isper; 337412fa691eSMatthew G. Knepley const PetscReal *maxCell, *L; 337512fa691eSMatthew G. Knepley const DMBoundaryType *bd; 337690b157c4SStefano Zampini ierr = DMGetPeriodicity(dm, &isper, &maxCell, &L, &bd);CHKERRQ(ierr); 337790b157c4SStefano Zampini ierr = DMSetPeriodicity(*M, isper, maxCell, L, bd);CHKERRQ(ierr); 337812fa691eSMatthew G. Knepley } 337967a56275SMatthew G Knepley ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr); 338067a56275SMatthew G Knepley } 338167a56275SMatthew G Knepley ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr); 338267a56275SMatthew G Knepley PetscFunctionReturn(0); 338367a56275SMatthew G Knepley } 3384264ace61SBarry Smith 3385264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/ 3386264ace61SBarry Smith 3387264ace61SBarry Smith /*@C 33881c84c290SBarry Smith DMRegister - Adds a new DM component implementation 33891c84c290SBarry Smith 33901c84c290SBarry Smith Not Collective 33911c84c290SBarry Smith 33921c84c290SBarry Smith Input Parameters: 33931c84c290SBarry Smith + name - The name of a new user-defined creation routine 33941c84c290SBarry Smith - create_func - The creation routine itself 33951c84c290SBarry Smith 33961c84c290SBarry Smith Notes: 33971c84c290SBarry Smith DMRegister() may be called multiple times to add several user-defined DMs 33981c84c290SBarry Smith 33991c84c290SBarry Smith 34001c84c290SBarry Smith Sample usage: 34011c84c290SBarry Smith .vb 3402bdf89e91SBarry Smith DMRegister("my_da", MyDMCreate); 34031c84c290SBarry Smith .ve 34041c84c290SBarry Smith 34051c84c290SBarry Smith Then, your DM type can be chosen with the procedural interface via 34061c84c290SBarry Smith .vb 34071c84c290SBarry Smith DMCreate(MPI_Comm, DM *); 34081c84c290SBarry Smith DMSetType(DM,"my_da"); 34091c84c290SBarry Smith .ve 34101c84c290SBarry Smith or at runtime via the option 34111c84c290SBarry Smith .vb 34121c84c290SBarry Smith -da_type my_da 34131c84c290SBarry Smith .ve 3414264ace61SBarry Smith 3415264ace61SBarry Smith Level: advanced 34161c84c290SBarry Smith 34171c84c290SBarry Smith .keywords: DM, register 3418bdf89e91SBarry Smith .seealso: DMRegisterAll(), DMRegisterDestroy() 34191c84c290SBarry Smith 3420264ace61SBarry Smith @*/ 3421bdf89e91SBarry Smith PetscErrorCode DMRegister(const char sname[],PetscErrorCode (*function)(DM)) 3422264ace61SBarry Smith { 3423264ace61SBarry Smith PetscErrorCode ierr; 3424264ace61SBarry Smith 3425264ace61SBarry Smith PetscFunctionBegin; 3426a240a19fSJed Brown ierr = PetscFunctionListAdd(&DMList,sname,function);CHKERRQ(ierr); 3427264ace61SBarry Smith PetscFunctionReturn(0); 3428264ace61SBarry Smith } 3429264ace61SBarry Smith 3430b859378eSBarry Smith /*@C 343155849f57SBarry Smith DMLoad - Loads a DM that has been stored in binary with DMView(). 3432b859378eSBarry Smith 3433b859378eSBarry Smith Collective on PetscViewer 3434b859378eSBarry Smith 3435b859378eSBarry Smith Input Parameters: 3436b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or 3437b859378eSBarry Smith some related function before a call to DMLoad(). 3438b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or 3439b859378eSBarry Smith HDF5 file viewer, obtained from PetscViewerHDF5Open() 3440b859378eSBarry Smith 3441b859378eSBarry Smith Level: intermediate 3442b859378eSBarry Smith 3443b859378eSBarry Smith Notes: 344455849f57SBarry Smith The type is determined by the data in the file, any type set into the DM before this call is ignored. 3445b859378eSBarry Smith 3446b859378eSBarry Smith Notes for advanced users: 3447b859378eSBarry Smith Most users should not need to know the details of the binary storage 3448b859378eSBarry Smith format, since DMLoad() and DMView() completely hide these details. 3449b859378eSBarry Smith But for anyone who's interested, the standard binary matrix storage 3450b859378eSBarry Smith format is 3451b859378eSBarry Smith .vb 3452b859378eSBarry Smith has not yet been determined 3453b859378eSBarry Smith .ve 3454b859378eSBarry Smith 3455b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad() 3456b859378eSBarry Smith @*/ 3457b859378eSBarry Smith PetscErrorCode DMLoad(DM newdm, PetscViewer viewer) 3458b859378eSBarry Smith { 34599331c7a4SMatthew G. Knepley PetscBool isbinary, ishdf5; 3460b859378eSBarry Smith PetscErrorCode ierr; 3461b859378eSBarry Smith 3462b859378eSBarry Smith PetscFunctionBegin; 3463b859378eSBarry Smith PetscValidHeaderSpecific(newdm,DM_CLASSID,1); 3464b859378eSBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 346532c0f0efSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 34669331c7a4SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 34679331c7a4SMatthew G. Knepley if (isbinary) { 34689331c7a4SMatthew G. Knepley PetscInt classid; 34699331c7a4SMatthew G. Knepley char type[256]; 3470b859378eSBarry Smith 3471060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr); 34729200755eSBarry Smith if (classid != DM_FILE_CLASSID) SETERRQ1(PetscObjectComm((PetscObject)newdm),PETSC_ERR_ARG_WRONG,"Not DM next in file, classid found %d",(int)classid); 3473060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr); 347432c0f0efSBarry Smith ierr = DMSetType(newdm, type);CHKERRQ(ierr); 34759331c7a4SMatthew G. Knepley if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);} 34769331c7a4SMatthew G. Knepley } else if (ishdf5) { 34779331c7a4SMatthew G. Knepley if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);} 34789331c7a4SMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()"); 3479b859378eSBarry Smith PetscFunctionReturn(0); 3480b859378eSBarry Smith } 3481b859378eSBarry Smith 34827da65231SMatthew G Knepley /******************************** FEM Support **********************************/ 34837da65231SMatthew G Knepley 3484a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) 3485a6dfd86eSKarl Rupp { 34861d47ebbbSSatish Balay PetscInt f; 34871b30c384SMatthew G Knepley PetscErrorCode ierr; 34881b30c384SMatthew G Knepley 34897da65231SMatthew G Knepley PetscFunctionBegin; 349074778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr); 34911d47ebbbSSatish Balay for (f = 0; f < len; ++f) { 349257622a8eSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, " | %g |\n", (double)PetscRealPart(x[f]));CHKERRQ(ierr); 34937da65231SMatthew G Knepley } 34947da65231SMatthew G Knepley PetscFunctionReturn(0); 34957da65231SMatthew G Knepley } 34967da65231SMatthew G Knepley 3497a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) 3498a6dfd86eSKarl Rupp { 34991b30c384SMatthew G Knepley PetscInt f, g; 35007da65231SMatthew G Knepley PetscErrorCode ierr; 35017da65231SMatthew G Knepley 35027da65231SMatthew G Knepley PetscFunctionBegin; 350374778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr); 35041d47ebbbSSatish Balay for (f = 0; f < rows; ++f) { 350574778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, " |");CHKERRQ(ierr); 35061d47ebbbSSatish Balay for (g = 0; g < cols; ++g) { 3507e3556bceSMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5g", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr); 35087da65231SMatthew G Knepley } 350974778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr); 35107da65231SMatthew G Knepley } 35117da65231SMatthew G Knepley PetscFunctionReturn(0); 35127da65231SMatthew G Knepley } 3513e7c4fc90SDmitry Karpeev 35146113b454SMatthew G. Knepley PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X) 3515e759306cSMatthew G. Knepley { 35160c5b8624SToby Isaac PetscInt localSize, bs; 35170c5b8624SToby Isaac PetscMPIInt size; 35180c5b8624SToby Isaac Vec x, xglob; 35190c5b8624SToby Isaac const PetscScalar *xarray; 3520e759306cSMatthew G. Knepley PetscErrorCode ierr; 3521e759306cSMatthew G. Knepley 3522e759306cSMatthew G. Knepley PetscFunctionBegin; 35239852e123SBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm),&size);CHKERRQ(ierr); 3524e759306cSMatthew G. Knepley ierr = VecDuplicate(X, &x);CHKERRQ(ierr); 3525e759306cSMatthew G. Knepley ierr = VecCopy(X, x);CHKERRQ(ierr); 35266113b454SMatthew G. Knepley ierr = VecChop(x, tol);CHKERRQ(ierr); 35270c5b8624SToby Isaac ierr = PetscPrintf(PetscObjectComm((PetscObject) dm),"%s:\n",name);CHKERRQ(ierr); 35280c5b8624SToby Isaac if (size > 1) { 35290c5b8624SToby Isaac ierr = VecGetLocalSize(x,&localSize);CHKERRQ(ierr); 35300c5b8624SToby Isaac ierr = VecGetArrayRead(x,&xarray);CHKERRQ(ierr); 35310c5b8624SToby Isaac ierr = VecGetBlockSize(x,&bs);CHKERRQ(ierr); 35320c5b8624SToby Isaac ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject) dm),bs,localSize,PETSC_DETERMINE,xarray,&xglob);CHKERRQ(ierr); 35330c5b8624SToby Isaac } else { 35340c5b8624SToby Isaac xglob = x; 35350c5b8624SToby Isaac } 35360c5b8624SToby Isaac ierr = VecView(xglob,PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject) dm)));CHKERRQ(ierr); 35370c5b8624SToby Isaac if (size > 1) { 35380c5b8624SToby Isaac ierr = VecDestroy(&xglob);CHKERRQ(ierr); 35390c5b8624SToby Isaac ierr = VecRestoreArrayRead(x,&xarray);CHKERRQ(ierr); 35400c5b8624SToby Isaac } 3541e759306cSMatthew G. Knepley ierr = VecDestroy(&x);CHKERRQ(ierr); 3542e759306cSMatthew G. Knepley PetscFunctionReturn(0); 3543e759306cSMatthew G. Knepley } 3544e759306cSMatthew G. Knepley 354588ed4aceSMatthew G Knepley /*@ 3546e87a4003SBarry Smith DMGetSection - Get the PetscSection encoding the local data layout for the DM. 354788ed4aceSMatthew G Knepley 354888ed4aceSMatthew G Knepley Input Parameter: 354988ed4aceSMatthew G Knepley . dm - The DM 355088ed4aceSMatthew G Knepley 355188ed4aceSMatthew G Knepley Output Parameter: 355288ed4aceSMatthew G Knepley . section - The PetscSection 355388ed4aceSMatthew G Knepley 3554e5893cccSMatthew G. Knepley Options Database Keys: 3555e5893cccSMatthew G. Knepley . -dm_petscsection_view - View the Section created by the DM 3556e5893cccSMatthew G. Knepley 355788ed4aceSMatthew G Knepley Level: intermediate 355888ed4aceSMatthew G Knepley 355988ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSection. 356088ed4aceSMatthew G Knepley 3561e87a4003SBarry Smith .seealso: DMSetSection(), DMGetGlobalSection() 356288ed4aceSMatthew G Knepley @*/ 3563e87a4003SBarry Smith PetscErrorCode DMGetSection(DM dm, PetscSection *section) 35640adebc6cSBarry Smith { 3565fd59a867SMatthew G. Knepley PetscErrorCode ierr; 3566fd59a867SMatthew G. Knepley 356788ed4aceSMatthew G Knepley PetscFunctionBegin; 356888ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 356988ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 35702f0f8703SMatthew G. Knepley if (!dm->defaultSection && dm->ops->createdefaultsection) { 35712f0f8703SMatthew G. Knepley ierr = (*dm->ops->createdefaultsection)(dm);CHKERRQ(ierr); 3572ae71db08SMatthew G. Knepley if (dm->defaultSection) {ierr = PetscObjectViewFromOptions((PetscObject) dm->defaultSection, NULL, "-dm_petscsection_view");CHKERRQ(ierr);} 35732f0f8703SMatthew G. Knepley } 357488ed4aceSMatthew G Knepley *section = dm->defaultSection; 357588ed4aceSMatthew G Knepley PetscFunctionReturn(0); 357688ed4aceSMatthew G Knepley } 357788ed4aceSMatthew G Knepley 357888ed4aceSMatthew G Knepley /*@ 3579e87a4003SBarry Smith DMSetSection - Set the PetscSection encoding the local data layout for the DM. 358088ed4aceSMatthew G Knepley 358188ed4aceSMatthew G Knepley Input Parameters: 358288ed4aceSMatthew G Knepley + dm - The DM 358388ed4aceSMatthew G Knepley - section - The PetscSection 358488ed4aceSMatthew G Knepley 358588ed4aceSMatthew G Knepley Level: intermediate 358688ed4aceSMatthew G Knepley 358788ed4aceSMatthew G Knepley Note: Any existing Section will be destroyed 358888ed4aceSMatthew G Knepley 3589e87a4003SBarry Smith .seealso: DMSetSection(), DMGetGlobalSection() 359088ed4aceSMatthew G Knepley @*/ 3591e87a4003SBarry Smith PetscErrorCode DMSetSection(DM dm, PetscSection section) 35920adebc6cSBarry Smith { 3593c473ab19SMatthew G. Knepley PetscInt numFields = 0; 3594af122d2aSMatthew G Knepley PetscInt f; 359588ed4aceSMatthew G Knepley PetscErrorCode ierr; 359688ed4aceSMatthew G Knepley 359788ed4aceSMatthew G Knepley PetscFunctionBegin; 359888ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3599c473ab19SMatthew G. Knepley if (section) { 36001d799100SJed Brown PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 36011d799100SJed Brown ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 3602c473ab19SMatthew G. Knepley } 360388ed4aceSMatthew G Knepley ierr = PetscSectionDestroy(&dm->defaultSection);CHKERRQ(ierr); 360488ed4aceSMatthew G Knepley dm->defaultSection = section; 3605c473ab19SMatthew G. Knepley if (section) {ierr = PetscSectionGetNumFields(dm->defaultSection, &numFields);CHKERRQ(ierr);} 3606af122d2aSMatthew G Knepley if (numFields) { 3607af122d2aSMatthew G Knepley ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr); 3608af122d2aSMatthew G Knepley for (f = 0; f < numFields; ++f) { 36090f21e855SMatthew G. Knepley PetscObject disc; 3610af122d2aSMatthew G Knepley const char *name; 3611af122d2aSMatthew G Knepley 3612af122d2aSMatthew G Knepley ierr = PetscSectionGetFieldName(dm->defaultSection, f, &name);CHKERRQ(ierr); 36130f21e855SMatthew G. Knepley ierr = DMGetField(dm, f, &disc);CHKERRQ(ierr); 36140f21e855SMatthew G. Knepley ierr = PetscObjectSetName(disc, name);CHKERRQ(ierr); 3615af122d2aSMatthew G Knepley } 3616af122d2aSMatthew G Knepley } 3617e87a4003SBarry Smith /* The global section will be rebuilt in the next call to DMGetGlobalSection(). */ 36181d799100SJed Brown ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr); 361988ed4aceSMatthew G Knepley PetscFunctionReturn(0); 362088ed4aceSMatthew G Knepley } 362188ed4aceSMatthew G Knepley 36229435951eSToby Isaac /*@ 36239435951eSToby Isaac DMGetDefaultConstraints - Get the PetscSection and Mat the specify the local constraint interpolation. See DMSetDefaultConstraints() for a description of the purpose of constraint interpolation. 36249435951eSToby Isaac 3625e228b242SToby Isaac not collective 3626e228b242SToby Isaac 36279435951eSToby Isaac Input Parameter: 36289435951eSToby Isaac . dm - The DM 36299435951eSToby Isaac 36309435951eSToby Isaac Output Parameter: 36319435951eSToby 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. 36329435951eSToby 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. 36339435951eSToby Isaac 36349435951eSToby Isaac Level: advanced 36359435951eSToby Isaac 36369435951eSToby Isaac Note: This gets borrowed references, so the user should not destroy the PetscSection or the Mat. 36379435951eSToby Isaac 36389435951eSToby Isaac .seealso: DMSetDefaultConstraints() 36399435951eSToby Isaac @*/ 36409435951eSToby Isaac PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat) 36419435951eSToby Isaac { 36429435951eSToby Isaac PetscErrorCode ierr; 36439435951eSToby Isaac 36449435951eSToby Isaac PetscFunctionBegin; 36459435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36469435951eSToby Isaac if (!dm->defaultConstraintSection && !dm->defaultConstraintMat && dm->ops->createdefaultconstraints) {ierr = (*dm->ops->createdefaultconstraints)(dm);CHKERRQ(ierr);} 364745a75d81SToby Isaac if (section) {*section = dm->defaultConstraintSection;} 364845a75d81SToby Isaac if (mat) {*mat = dm->defaultConstraintMat;} 36499435951eSToby Isaac PetscFunctionReturn(0); 36509435951eSToby Isaac } 36519435951eSToby Isaac 36529435951eSToby Isaac /*@ 36539435951eSToby Isaac DMSetDefaultConstraints - Set the PetscSection and Mat the specify the local constraint interpolation. 36549435951eSToby Isaac 36559435951eSToby 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(). 36569435951eSToby Isaac 36579435951eSToby 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. 36589435951eSToby Isaac 3659e228b242SToby Isaac collective on dm 3660e228b242SToby Isaac 36619435951eSToby Isaac Input Parameters: 36629435951eSToby Isaac + dm - The DM 3663e228b242SToby 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). 3664e228b242SToby 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). 36659435951eSToby Isaac 36669435951eSToby Isaac Level: advanced 36679435951eSToby Isaac 36689435951eSToby Isaac Note: This increments the references of the PetscSection and the Mat, so they user can destroy them 36699435951eSToby Isaac 36709435951eSToby Isaac .seealso: DMGetDefaultConstraints() 36719435951eSToby Isaac @*/ 36729435951eSToby Isaac PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat) 36739435951eSToby Isaac { 3674e228b242SToby Isaac PetscMPIInt result; 36759435951eSToby Isaac PetscErrorCode ierr; 36769435951eSToby Isaac 36779435951eSToby Isaac PetscFunctionBegin; 36789435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3679e228b242SToby Isaac if (section) { 3680e228b242SToby Isaac PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 3681e228b242SToby Isaac ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)section),&result);CHKERRQ(ierr); 3682f60917d2SBarry Smith if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint section must have local communicator"); 3683e228b242SToby Isaac } 3684e228b242SToby Isaac if (mat) { 3685e228b242SToby Isaac PetscValidHeaderSpecific(mat,MAT_CLASSID,3); 3686e228b242SToby Isaac ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)mat),&result);CHKERRQ(ierr); 3687f60917d2SBarry Smith if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint matrix must have local communicator"); 3688e228b242SToby Isaac } 36899435951eSToby Isaac ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 36909435951eSToby Isaac ierr = PetscSectionDestroy(&dm->defaultConstraintSection);CHKERRQ(ierr); 36919435951eSToby Isaac dm->defaultConstraintSection = section; 36929435951eSToby Isaac ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 36939435951eSToby Isaac ierr = MatDestroy(&dm->defaultConstraintMat);CHKERRQ(ierr); 36949435951eSToby Isaac dm->defaultConstraintMat = mat; 36959435951eSToby Isaac PetscFunctionReturn(0); 36969435951eSToby Isaac } 36979435951eSToby Isaac 3698497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 3699507e4973SMatthew G. Knepley /* 3700507e4973SMatthew G. Knepley DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections. 3701507e4973SMatthew G. Knepley 3702507e4973SMatthew G. Knepley Input Parameters: 3703507e4973SMatthew G. Knepley + dm - The DM 3704507e4973SMatthew G. Knepley . localSection - PetscSection describing the local data layout 3705507e4973SMatthew G. Knepley - globalSection - PetscSection describing the global data layout 3706507e4973SMatthew G. Knepley 3707507e4973SMatthew G. Knepley Level: intermediate 3708507e4973SMatthew G. Knepley 3709507e4973SMatthew G. Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF() 3710507e4973SMatthew G. Knepley */ 3711f741bcd2SMatthew G. Knepley static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection) 3712507e4973SMatthew G. Knepley { 3713507e4973SMatthew G. Knepley MPI_Comm comm; 3714507e4973SMatthew G. Knepley PetscLayout layout; 3715507e4973SMatthew G. Knepley const PetscInt *ranges; 3716507e4973SMatthew G. Knepley PetscInt pStart, pEnd, p, nroots; 3717507e4973SMatthew G. Knepley PetscMPIInt size, rank; 3718507e4973SMatthew G. Knepley PetscBool valid = PETSC_TRUE, gvalid; 3719507e4973SMatthew G. Knepley PetscErrorCode ierr; 3720507e4973SMatthew G. Knepley 3721507e4973SMatthew G. Knepley PetscFunctionBegin; 3722507e4973SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 3723507e4973SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3724507e4973SMatthew G. Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 3725507e4973SMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 3726507e4973SMatthew G. Knepley ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr); 3727507e4973SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr); 3728507e4973SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr); 3729507e4973SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr); 3730507e4973SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr); 3731507e4973SMatthew G. Knepley ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr); 3732507e4973SMatthew G. Knepley ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr); 3733507e4973SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3734f741bcd2SMatthew G. Knepley PetscInt dof, cdof, off, gdof, gcdof, goff, gsize, d; 3735507e4973SMatthew G. Knepley 3736507e4973SMatthew G. Knepley ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr); 3737507e4973SMatthew G. Knepley ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr); 3738507e4973SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr); 3739507e4973SMatthew G. Knepley ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr); 3740507e4973SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr); 3741507e4973SMatthew G. Knepley ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr); 3742507e4973SMatthew G. Knepley if (!gdof) continue; /* Censored point */ 3743507e4973SMatthew 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;} 3744507e4973SMatthew 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;} 3745507e4973SMatthew G. Knepley if (gdof < 0) { 3746507e4973SMatthew G. Knepley gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof; 3747507e4973SMatthew G. Knepley for (d = 0; d < gsize; ++d) { 3748507e4973SMatthew G. Knepley PetscInt offset = -(goff+1) + d, r; 3749507e4973SMatthew G. Knepley 3750507e4973SMatthew G. Knepley ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr); 3751507e4973SMatthew G. Knepley if (r < 0) r = -(r+2); 3752507e4973SMatthew 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;} 3753507e4973SMatthew G. Knepley } 3754507e4973SMatthew G. Knepley } 3755507e4973SMatthew G. Knepley } 3756507e4973SMatthew G. Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 3757507e4973SMatthew G. Knepley ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr); 3758b2566f29SBarry Smith ierr = MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRQ(ierr); 3759507e4973SMatthew G. Knepley if (!gvalid) { 3760507e4973SMatthew G. Knepley ierr = DMView(dm, NULL);CHKERRQ(ierr); 3761507e4973SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections"); 3762507e4973SMatthew G. Knepley } 3763507e4973SMatthew G. Knepley PetscFunctionReturn(0); 3764507e4973SMatthew G. Knepley } 3765f741bcd2SMatthew G. Knepley #endif 3766507e4973SMatthew G. Knepley 376788ed4aceSMatthew G Knepley /*@ 3768e87a4003SBarry Smith DMGetGlobalSection - Get the PetscSection encoding the global data layout for the DM. 376988ed4aceSMatthew G Knepley 37708b1ab98fSJed Brown Collective on DM 37718b1ab98fSJed Brown 377288ed4aceSMatthew G Knepley Input Parameter: 377388ed4aceSMatthew G Knepley . dm - The DM 377488ed4aceSMatthew G Knepley 377588ed4aceSMatthew G Knepley Output Parameter: 377688ed4aceSMatthew G Knepley . section - The PetscSection 377788ed4aceSMatthew G Knepley 377888ed4aceSMatthew G Knepley Level: intermediate 377988ed4aceSMatthew G Knepley 378088ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSection. 378188ed4aceSMatthew G Knepley 3782e87a4003SBarry Smith .seealso: DMSetSection(), DMGetSection() 378388ed4aceSMatthew G Knepley @*/ 3784e87a4003SBarry Smith PetscErrorCode DMGetGlobalSection(DM dm, PetscSection *section) 37850adebc6cSBarry Smith { 378688ed4aceSMatthew G Knepley PetscErrorCode ierr; 378788ed4aceSMatthew G Knepley 378888ed4aceSMatthew G Knepley PetscFunctionBegin; 378988ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 379088ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 379188ed4aceSMatthew G Knepley if (!dm->defaultGlobalSection) { 3792fd59a867SMatthew G. Knepley PetscSection s; 3793fd59a867SMatthew G. Knepley 3794e87a4003SBarry Smith ierr = DMGetSection(dm, &s);CHKERRQ(ierr); 3795fd59a867SMatthew 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"); 3796fd59a867SMatthew 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"); 379715b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(s, dm->sf, PETSC_FALSE, PETSC_FALSE, &dm->defaultGlobalSection);CHKERRQ(ierr); 3798cf06b437SMatthew G. Knepley ierr = PetscLayoutDestroy(&dm->map);CHKERRQ(ierr); 3799ce94432eSBarry Smith ierr = PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->defaultGlobalSection, &dm->map);CHKERRQ(ierr); 3800685405a1SBarry Smith ierr = PetscSectionViewFromOptions(dm->defaultGlobalSection, NULL, "-global_section_view");CHKERRQ(ierr); 380188ed4aceSMatthew G Knepley } 380288ed4aceSMatthew G Knepley *section = dm->defaultGlobalSection; 380388ed4aceSMatthew G Knepley PetscFunctionReturn(0); 380488ed4aceSMatthew G Knepley } 380588ed4aceSMatthew G Knepley 3806b21d0597SMatthew G Knepley /*@ 3807e87a4003SBarry Smith DMSetGlobalSection - Set the PetscSection encoding the global data layout for the DM. 3808b21d0597SMatthew G Knepley 3809b21d0597SMatthew G Knepley Input Parameters: 3810b21d0597SMatthew G Knepley + dm - The DM 38115080bbdbSMatthew G Knepley - section - The PetscSection, or NULL 3812b21d0597SMatthew G Knepley 3813b21d0597SMatthew G Knepley Level: intermediate 3814b21d0597SMatthew G Knepley 3815b21d0597SMatthew G Knepley Note: Any existing Section will be destroyed 3816b21d0597SMatthew G Knepley 3817e87a4003SBarry Smith .seealso: DMGetGlobalSection(), DMSetSection() 3818b21d0597SMatthew G Knepley @*/ 3819e87a4003SBarry Smith PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section) 38200adebc6cSBarry Smith { 3821b21d0597SMatthew G Knepley PetscErrorCode ierr; 3822b21d0597SMatthew G Knepley 3823b21d0597SMatthew G Knepley PetscFunctionBegin; 3824b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 38255080bbdbSMatthew G Knepley if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 38261d799100SJed Brown ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 3827b21d0597SMatthew G Knepley ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr); 3828b21d0597SMatthew G Knepley dm->defaultGlobalSection = section; 3829497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 3830f741bcd2SMatthew G. Knepley if (section) {ierr = DMDefaultSectionCheckConsistency_Internal(dm, dm->defaultSection, section);CHKERRQ(ierr);} 3831507e4973SMatthew G. Knepley #endif 3832b21d0597SMatthew G Knepley PetscFunctionReturn(0); 3833b21d0597SMatthew G Knepley } 3834b21d0597SMatthew G Knepley 383588ed4aceSMatthew G Knepley /*@ 383688ed4aceSMatthew G Knepley DMGetDefaultSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set, 383788ed4aceSMatthew G Knepley it is created from the default PetscSection layouts in the DM. 383888ed4aceSMatthew G Knepley 383988ed4aceSMatthew G Knepley Input Parameter: 384088ed4aceSMatthew G Knepley . dm - The DM 384188ed4aceSMatthew G Knepley 384288ed4aceSMatthew G Knepley Output Parameter: 384388ed4aceSMatthew G Knepley . sf - The PetscSF 384488ed4aceSMatthew G Knepley 384588ed4aceSMatthew G Knepley Level: intermediate 384688ed4aceSMatthew G Knepley 384788ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSF. 384888ed4aceSMatthew G Knepley 384988ed4aceSMatthew G Knepley .seealso: DMSetDefaultSF(), DMCreateDefaultSF() 385088ed4aceSMatthew G Knepley @*/ 38510adebc6cSBarry Smith PetscErrorCode DMGetDefaultSF(DM dm, PetscSF *sf) 38520adebc6cSBarry Smith { 385388ed4aceSMatthew G Knepley PetscInt nroots; 385488ed4aceSMatthew G Knepley PetscErrorCode ierr; 385588ed4aceSMatthew G Knepley 385688ed4aceSMatthew G Knepley PetscFunctionBegin; 385788ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 385888ed4aceSMatthew G Knepley PetscValidPointer(sf, 2); 38590298fd71SBarry Smith ierr = PetscSFGetGraph(dm->defaultSF, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 386088ed4aceSMatthew G Knepley if (nroots < 0) { 386188ed4aceSMatthew G Knepley PetscSection section, gSection; 386288ed4aceSMatthew G Knepley 3863e87a4003SBarry Smith ierr = DMGetSection(dm, §ion);CHKERRQ(ierr); 386431ea6d37SMatthew G Knepley if (section) { 3865e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, &gSection);CHKERRQ(ierr); 386688ed4aceSMatthew G Knepley ierr = DMCreateDefaultSF(dm, section, gSection);CHKERRQ(ierr); 386731ea6d37SMatthew G Knepley } else { 38680298fd71SBarry Smith *sf = NULL; 386931ea6d37SMatthew G Knepley PetscFunctionReturn(0); 387031ea6d37SMatthew G Knepley } 387188ed4aceSMatthew G Knepley } 387288ed4aceSMatthew G Knepley *sf = dm->defaultSF; 387388ed4aceSMatthew G Knepley PetscFunctionReturn(0); 387488ed4aceSMatthew G Knepley } 387588ed4aceSMatthew G Knepley 387688ed4aceSMatthew G Knepley /*@ 387788ed4aceSMatthew G Knepley DMSetDefaultSF - Set the PetscSF encoding the parallel dof overlap for the DM 387888ed4aceSMatthew G Knepley 387988ed4aceSMatthew G Knepley Input Parameters: 388088ed4aceSMatthew G Knepley + dm - The DM 388188ed4aceSMatthew G Knepley - sf - The PetscSF 388288ed4aceSMatthew G Knepley 388388ed4aceSMatthew G Knepley Level: intermediate 388488ed4aceSMatthew G Knepley 388588ed4aceSMatthew G Knepley Note: Any previous SF is destroyed 388688ed4aceSMatthew G Knepley 388788ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMCreateDefaultSF() 388888ed4aceSMatthew G Knepley @*/ 38890adebc6cSBarry Smith PetscErrorCode DMSetDefaultSF(DM dm, PetscSF sf) 38900adebc6cSBarry Smith { 389188ed4aceSMatthew G Knepley PetscErrorCode ierr; 389288ed4aceSMatthew G Knepley 389388ed4aceSMatthew G Knepley PetscFunctionBegin; 389488ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 389588ed4aceSMatthew G Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 389688ed4aceSMatthew G Knepley ierr = PetscSFDestroy(&dm->defaultSF);CHKERRQ(ierr); 389788ed4aceSMatthew G Knepley dm->defaultSF = sf; 389888ed4aceSMatthew G Knepley PetscFunctionReturn(0); 389988ed4aceSMatthew G Knepley } 390088ed4aceSMatthew G Knepley 390188ed4aceSMatthew G Knepley /*@C 390288ed4aceSMatthew G Knepley DMCreateDefaultSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections 390388ed4aceSMatthew G Knepley describing the data layout. 390488ed4aceSMatthew G Knepley 390588ed4aceSMatthew G Knepley Input Parameters: 390688ed4aceSMatthew G Knepley + dm - The DM 390788ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout 390888ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout 390988ed4aceSMatthew G Knepley 391088ed4aceSMatthew G Knepley Level: intermediate 391188ed4aceSMatthew G Knepley 391288ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF() 391388ed4aceSMatthew G Knepley @*/ 391488ed4aceSMatthew G Knepley PetscErrorCode DMCreateDefaultSF(DM dm, PetscSection localSection, PetscSection globalSection) 391588ed4aceSMatthew G Knepley { 391682f516ccSBarry Smith MPI_Comm comm; 391788ed4aceSMatthew G Knepley PetscLayout layout; 391888ed4aceSMatthew G Knepley const PetscInt *ranges; 391988ed4aceSMatthew G Knepley PetscInt *local; 392088ed4aceSMatthew G Knepley PetscSFNode *remote; 3921ecd73843SMatthew G. Knepley PetscInt pStart, pEnd, p, nroots, nleaves = 0, l; 392288ed4aceSMatthew G Knepley PetscMPIInt size, rank; 392388ed4aceSMatthew G Knepley PetscErrorCode ierr; 392488ed4aceSMatthew G Knepley 392588ed4aceSMatthew G Knepley PetscFunctionBegin; 392682f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 392788ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 392888ed4aceSMatthew G Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 392988ed4aceSMatthew G Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 393088ed4aceSMatthew G Knepley ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr); 393188ed4aceSMatthew G Knepley ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr); 393288ed4aceSMatthew G Knepley ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr); 393388ed4aceSMatthew G Knepley ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr); 393488ed4aceSMatthew G Knepley ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr); 393588ed4aceSMatthew G Knepley ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr); 393688ed4aceSMatthew G Knepley ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr); 3937ecd73843SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 39386636e97aSMatthew G Knepley PetscInt gdof, gcdof; 393988ed4aceSMatthew G Knepley 39406636e97aSMatthew G Knepley ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr); 39416636e97aSMatthew G Knepley ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr); 3942235fbf56SMatthew 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)); 39436636e97aSMatthew G Knepley nleaves += gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof; 394488ed4aceSMatthew G Knepley } 3945785e854fSJed Brown ierr = PetscMalloc1(nleaves, &local);CHKERRQ(ierr); 3946785e854fSJed Brown ierr = PetscMalloc1(nleaves, &remote);CHKERRQ(ierr); 394788ed4aceSMatthew G Knepley for (p = pStart, l = 0; p < pEnd; ++p) { 39481f588964SMatthew G Knepley const PetscInt *cind; 39496636e97aSMatthew G Knepley PetscInt dof, cdof, off, gdof, gcdof, goff, gsize, d, c; 395088ed4aceSMatthew G Knepley 395188ed4aceSMatthew G Knepley ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr); 395288ed4aceSMatthew G Knepley ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr); 395388ed4aceSMatthew G Knepley ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr); 395488ed4aceSMatthew G Knepley ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr); 395588ed4aceSMatthew G Knepley ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr); 39566636e97aSMatthew G Knepley ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr); 395788ed4aceSMatthew G Knepley ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr); 39586636e97aSMatthew G Knepley if (!gdof) continue; /* Censored point */ 39596636e97aSMatthew G Knepley gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof; 39606636e97aSMatthew G Knepley if (gsize != dof-cdof) { 3961057b4bcdSMatthew 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); 39626636e97aSMatthew G Knepley cdof = 0; /* Ignore constraints */ 39636636e97aSMatthew G Knepley } 396488ed4aceSMatthew G Knepley for (d = 0, c = 0; d < dof; ++d) { 396588ed4aceSMatthew G Knepley if ((c < cdof) && (cind[c] == d)) {++c; continue;} 396688ed4aceSMatthew G Knepley local[l+d-c] = off+d; 396788ed4aceSMatthew G Knepley } 396888ed4aceSMatthew G Knepley if (gdof < 0) { 39696636e97aSMatthew G Knepley for (d = 0; d < gsize; ++d, ++l) { 397088ed4aceSMatthew G Knepley PetscInt offset = -(goff+1) + d, r; 397188ed4aceSMatthew G Knepley 397205376888SMatthew G. Knepley ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr); 397331d3f06eSJed Brown if (r < 0) r = -(r+2); 397405376888SMatthew 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); 397588ed4aceSMatthew G Knepley remote[l].rank = r; 397688ed4aceSMatthew G Knepley remote[l].index = offset - ranges[r]; 397788ed4aceSMatthew G Knepley } 397888ed4aceSMatthew G Knepley } else { 39796636e97aSMatthew G Knepley for (d = 0; d < gsize; ++d, ++l) { 398088ed4aceSMatthew G Knepley remote[l].rank = rank; 398188ed4aceSMatthew G Knepley remote[l].index = goff+d - ranges[rank]; 398288ed4aceSMatthew G Knepley } 398388ed4aceSMatthew G Knepley } 398488ed4aceSMatthew G Knepley } 39856636e97aSMatthew G Knepley if (l != nleaves) SETERRQ2(comm, PETSC_ERR_PLIB, "Iteration error, l %d != nleaves %d", l, nleaves); 398688ed4aceSMatthew G Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 398788ed4aceSMatthew G Knepley ierr = PetscSFSetGraph(dm->defaultSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr); 398888ed4aceSMatthew G Knepley PetscFunctionReturn(0); 398988ed4aceSMatthew G Knepley } 3990af122d2aSMatthew G Knepley 3991b21d0597SMatthew G Knepley /*@ 3992b21d0597SMatthew G Knepley DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM. 3993b21d0597SMatthew G Knepley 3994b21d0597SMatthew G Knepley Input Parameter: 3995b21d0597SMatthew G Knepley . dm - The DM 3996b21d0597SMatthew G Knepley 3997b21d0597SMatthew G Knepley Output Parameter: 3998b21d0597SMatthew G Knepley . sf - The PetscSF 3999b21d0597SMatthew G Knepley 4000b21d0597SMatthew G Knepley Level: intermediate 4001b21d0597SMatthew G Knepley 4002b21d0597SMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSF. 4003b21d0597SMatthew G Knepley 4004057b4bcdSMatthew G Knepley .seealso: DMSetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF() 4005b21d0597SMatthew G Knepley @*/ 40060adebc6cSBarry Smith PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) 40070adebc6cSBarry Smith { 4008b21d0597SMatthew G Knepley PetscFunctionBegin; 4009b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4010b21d0597SMatthew G Knepley PetscValidPointer(sf, 2); 4011b21d0597SMatthew G Knepley *sf = dm->sf; 4012b21d0597SMatthew G Knepley PetscFunctionReturn(0); 4013b21d0597SMatthew G Knepley } 4014b21d0597SMatthew G Knepley 4015057b4bcdSMatthew G Knepley /*@ 4016057b4bcdSMatthew G Knepley DMSetPointSF - Set the PetscSF encoding the parallel section point overlap for the DM. 4017057b4bcdSMatthew G Knepley 4018057b4bcdSMatthew G Knepley Input Parameters: 4019057b4bcdSMatthew G Knepley + dm - The DM 4020057b4bcdSMatthew G Knepley - sf - The PetscSF 4021057b4bcdSMatthew G Knepley 4022057b4bcdSMatthew G Knepley Level: intermediate 4023057b4bcdSMatthew G Knepley 4024057b4bcdSMatthew G Knepley .seealso: DMGetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF() 4025057b4bcdSMatthew G Knepley @*/ 40260adebc6cSBarry Smith PetscErrorCode DMSetPointSF(DM dm, PetscSF sf) 40270adebc6cSBarry Smith { 4028057b4bcdSMatthew G Knepley PetscErrorCode ierr; 4029057b4bcdSMatthew G Knepley 4030057b4bcdSMatthew G Knepley PetscFunctionBegin; 4031057b4bcdSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4032057b4bcdSMatthew G Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 1); 4033057b4bcdSMatthew G Knepley ierr = PetscSFDestroy(&dm->sf);CHKERRQ(ierr); 4034057b4bcdSMatthew G Knepley ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr); 4035057b4bcdSMatthew G Knepley dm->sf = sf; 4036057b4bcdSMatthew G Knepley PetscFunctionReturn(0); 4037057b4bcdSMatthew G Knepley } 4038057b4bcdSMatthew G Knepley 40392764a2aaSMatthew G. Knepley /*@ 40402764a2aaSMatthew G. Knepley DMGetDS - Get the PetscDS 40412764a2aaSMatthew G. Knepley 40422764a2aaSMatthew G. Knepley Input Parameter: 40432764a2aaSMatthew G. Knepley . dm - The DM 40442764a2aaSMatthew G. Knepley 40452764a2aaSMatthew G. Knepley Output Parameter: 40462764a2aaSMatthew G. Knepley . prob - The PetscDS 40472764a2aaSMatthew G. Knepley 40482764a2aaSMatthew G. Knepley Level: developer 40492764a2aaSMatthew G. Knepley 40502764a2aaSMatthew G. Knepley .seealso: DMSetDS() 40512764a2aaSMatthew G. Knepley @*/ 40522764a2aaSMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *prob) 4053af122d2aSMatthew G Knepley { 4054af122d2aSMatthew G Knepley PetscFunctionBegin; 4055af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 40560f21e855SMatthew G. Knepley PetscValidPointer(prob, 2); 40570f21e855SMatthew G. Knepley *prob = dm->prob; 40580f21e855SMatthew G. Knepley PetscFunctionReturn(0); 40590f21e855SMatthew G. Knepley } 40600f21e855SMatthew G. Knepley 40612764a2aaSMatthew G. Knepley /*@ 40622764a2aaSMatthew G. Knepley DMSetDS - Set the PetscDS 40632764a2aaSMatthew G. Knepley 40642764a2aaSMatthew G. Knepley Input Parameters: 40652764a2aaSMatthew G. Knepley + dm - The DM 40662764a2aaSMatthew G. Knepley - prob - The PetscDS 40672764a2aaSMatthew G. Knepley 40682764a2aaSMatthew G. Knepley Level: developer 40692764a2aaSMatthew G. Knepley 40702764a2aaSMatthew G. Knepley .seealso: DMGetDS() 40712764a2aaSMatthew G. Knepley @*/ 40722764a2aaSMatthew G. Knepley PetscErrorCode DMSetDS(DM dm, PetscDS prob) 40730f21e855SMatthew G. Knepley { 4074f17e8794SMatthew G. Knepley PetscInt dimEmbed; 40750f21e855SMatthew G. Knepley PetscErrorCode ierr; 40760f21e855SMatthew G. Knepley 40770f21e855SMatthew G. Knepley PetscFunctionBegin; 40780f21e855SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 40792764a2aaSMatthew G. Knepley PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 2); 408037316535SToby Isaac ierr = PetscObjectReference((PetscObject) prob);CHKERRQ(ierr); 40812764a2aaSMatthew G. Knepley ierr = PetscDSDestroy(&dm->prob);CHKERRQ(ierr); 40820f21e855SMatthew G. Knepley dm->prob = prob; 4083f17e8794SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr); 4084f17e8794SMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(prob, dimEmbed);CHKERRQ(ierr); 40850f21e855SMatthew G. Knepley PetscFunctionReturn(0); 40860f21e855SMatthew G. Knepley } 40870f21e855SMatthew G. Knepley 40880f21e855SMatthew G. Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields) 40890f21e855SMatthew G. Knepley { 40900f21e855SMatthew G. Knepley PetscErrorCode ierr; 40910f21e855SMatthew G. Knepley 40920f21e855SMatthew G. Knepley PetscFunctionBegin; 40930f21e855SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 40942764a2aaSMatthew G. Knepley ierr = PetscDSGetNumFields(dm->prob, numFields);CHKERRQ(ierr); 4095af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4096af122d2aSMatthew G Knepley } 4097af122d2aSMatthew G Knepley 4098af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields) 4099af122d2aSMatthew G Knepley { 41000f21e855SMatthew G. Knepley PetscInt Nf, f; 4101af122d2aSMatthew G Knepley PetscErrorCode ierr; 4102af122d2aSMatthew G Knepley 4103af122d2aSMatthew G Knepley PetscFunctionBegin; 4104af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 41052764a2aaSMatthew G. Knepley ierr = PetscDSGetNumFields(dm->prob, &Nf);CHKERRQ(ierr); 41060f21e855SMatthew G. Knepley for (f = Nf; f < numFields; ++f) { 41070f21e855SMatthew G. Knepley PetscContainer obj; 41080f21e855SMatthew G. Knepley 41090f21e855SMatthew G. Knepley ierr = PetscContainerCreate(PetscObjectComm((PetscObject) dm), &obj);CHKERRQ(ierr); 41102764a2aaSMatthew G. Knepley ierr = PetscDSSetDiscretization(dm->prob, f, (PetscObject) obj);CHKERRQ(ierr); 41110f21e855SMatthew G. Knepley ierr = PetscContainerDestroy(&obj);CHKERRQ(ierr); 4112af122d2aSMatthew G Knepley } 4113af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4114af122d2aSMatthew G Knepley } 4115af122d2aSMatthew G Knepley 4116c1929be8SMatthew G. Knepley /*@ 4117c1929be8SMatthew G. Knepley DMGetField - Return the discretization object for a given DM field 4118c1929be8SMatthew G. Knepley 4119c1929be8SMatthew G. Knepley Not collective 4120c1929be8SMatthew G. Knepley 4121c1929be8SMatthew G. Knepley Input Parameters: 4122c1929be8SMatthew G. Knepley + dm - The DM 4123c1929be8SMatthew G. Knepley - f - The field number 4124c1929be8SMatthew G. Knepley 4125c1929be8SMatthew G. Knepley Output Parameter: 4126c1929be8SMatthew G. Knepley . field - The discretization object 4127c1929be8SMatthew G. Knepley 4128c1929be8SMatthew G. Knepley Level: developer 4129c1929be8SMatthew G. Knepley 4130c1929be8SMatthew G. Knepley .seealso: DMSetField() 4131c1929be8SMatthew G. Knepley @*/ 4132af122d2aSMatthew G Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, PetscObject *field) 4133af122d2aSMatthew G Knepley { 41340f21e855SMatthew G. Knepley PetscErrorCode ierr; 41350f21e855SMatthew G. Knepley 4136af122d2aSMatthew G Knepley PetscFunctionBegin; 4137af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 41382764a2aaSMatthew G. Knepley ierr = PetscDSGetDiscretization(dm->prob, f, field);CHKERRQ(ierr); 4139decb47aaSMatthew G. Knepley PetscFunctionReturn(0); 4140decb47aaSMatthew G. Knepley } 4141decb47aaSMatthew G. Knepley 4142c1929be8SMatthew G. Knepley /*@ 4143c1929be8SMatthew G. Knepley DMSetField - Set the discretization object for a given DM field 4144c1929be8SMatthew G. Knepley 4145c1929be8SMatthew G. Knepley Logically collective on DM 4146c1929be8SMatthew G. Knepley 4147c1929be8SMatthew G. Knepley Input Parameters: 4148c1929be8SMatthew G. Knepley + dm - The DM 4149c1929be8SMatthew G. Knepley . f - The field number 4150c1929be8SMatthew G. Knepley - field - The discretization object 4151c1929be8SMatthew G. Knepley 4152c1929be8SMatthew G. Knepley Level: developer 4153c1929be8SMatthew G. Knepley 4154c1929be8SMatthew G. Knepley .seealso: DMGetField() 4155c1929be8SMatthew G. Knepley @*/ 4156decb47aaSMatthew G. Knepley PetscErrorCode DMSetField(DM dm, PetscInt f, PetscObject field) 4157decb47aaSMatthew G. Knepley { 4158decb47aaSMatthew G. Knepley PetscErrorCode ierr; 4159decb47aaSMatthew G. Knepley 4160decb47aaSMatthew G. Knepley PetscFunctionBegin; 4161decb47aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 41622764a2aaSMatthew G. Knepley ierr = PetscDSSetDiscretization(dm->prob, f, field);CHKERRQ(ierr); 4163af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4164af122d2aSMatthew G Knepley } 41656636e97aSMatthew G Knepley 4166b64e0483SPeter Brune PetscErrorCode DMRestrictHook_Coordinates(DM dm,DM dmc,void *ctx) 4167b64e0483SPeter Brune { 4168b64e0483SPeter Brune DM dm_coord,dmc_coord; 4169b64e0483SPeter Brune PetscErrorCode ierr; 4170b64e0483SPeter Brune Vec coords,ccoords; 41716dbf9973SLawrence Mitchell Mat inject; 4172b64e0483SPeter Brune PetscFunctionBegin; 4173b64e0483SPeter Brune ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr); 4174b64e0483SPeter Brune ierr = DMGetCoordinateDM(dmc,&dmc_coord);CHKERRQ(ierr); 4175b64e0483SPeter Brune ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr); 4176b64e0483SPeter Brune ierr = DMGetCoordinates(dmc,&ccoords);CHKERRQ(ierr); 4177b64e0483SPeter Brune if (coords && !ccoords) { 4178b64e0483SPeter Brune ierr = DMCreateGlobalVector(dmc_coord,&ccoords);CHKERRQ(ierr); 41796668ed41SLisandro Dalcin ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr); 41806dbf9973SLawrence Mitchell ierr = DMCreateInjection(dmc_coord,dm_coord,&inject);CHKERRQ(ierr); 41812adcf181SLawrence Mitchell ierr = MatRestrict(inject,coords,ccoords);CHKERRQ(ierr); 41826dbf9973SLawrence Mitchell ierr = MatDestroy(&inject);CHKERRQ(ierr); 4183b64e0483SPeter Brune ierr = DMSetCoordinates(dmc,ccoords);CHKERRQ(ierr); 4184b64e0483SPeter Brune ierr = VecDestroy(&ccoords);CHKERRQ(ierr); 4185b64e0483SPeter Brune } 4186b64e0483SPeter Brune PetscFunctionReturn(0); 4187b64e0483SPeter Brune } 4188b64e0483SPeter Brune 418903dadc2fSPeter Brune static PetscErrorCode DMSubDomainHook_Coordinates(DM dm,DM subdm,void *ctx) 419003dadc2fSPeter Brune { 419103dadc2fSPeter Brune DM dm_coord,subdm_coord; 419203dadc2fSPeter Brune PetscErrorCode ierr; 419303dadc2fSPeter Brune Vec coords,ccoords,clcoords; 419403dadc2fSPeter Brune VecScatter *scat_i,*scat_g; 419503dadc2fSPeter Brune PetscFunctionBegin; 419603dadc2fSPeter Brune ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr); 419703dadc2fSPeter Brune ierr = DMGetCoordinateDM(subdm,&subdm_coord);CHKERRQ(ierr); 419803dadc2fSPeter Brune ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr); 419903dadc2fSPeter Brune ierr = DMGetCoordinates(subdm,&ccoords);CHKERRQ(ierr); 420003dadc2fSPeter Brune if (coords && !ccoords) { 420103dadc2fSPeter Brune ierr = DMCreateGlobalVector(subdm_coord,&ccoords);CHKERRQ(ierr); 42026668ed41SLisandro Dalcin ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr); 420303dadc2fSPeter Brune ierr = DMCreateLocalVector(subdm_coord,&clcoords);CHKERRQ(ierr); 420424640c55SToby Isaac ierr = PetscObjectSetName((PetscObject)clcoords,"coordinates");CHKERRQ(ierr); 420503dadc2fSPeter Brune ierr = DMCreateDomainDecompositionScatters(dm_coord,1,&subdm_coord,NULL,&scat_i,&scat_g);CHKERRQ(ierr); 420603dadc2fSPeter Brune ierr = VecScatterBegin(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 420703dadc2fSPeter Brune ierr = VecScatterBegin(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 420803dadc2fSPeter Brune ierr = VecScatterEnd(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 420903dadc2fSPeter Brune ierr = VecScatterEnd(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 421003dadc2fSPeter Brune ierr = DMSetCoordinates(subdm,ccoords);CHKERRQ(ierr); 421103dadc2fSPeter Brune ierr = DMSetCoordinatesLocal(subdm,clcoords);CHKERRQ(ierr); 421203dadc2fSPeter Brune ierr = VecScatterDestroy(&scat_i[0]);CHKERRQ(ierr); 421303dadc2fSPeter Brune ierr = VecScatterDestroy(&scat_g[0]);CHKERRQ(ierr); 421403dadc2fSPeter Brune ierr = VecDestroy(&ccoords);CHKERRQ(ierr); 421503dadc2fSPeter Brune ierr = VecDestroy(&clcoords);CHKERRQ(ierr); 421603dadc2fSPeter Brune ierr = PetscFree(scat_i);CHKERRQ(ierr); 421703dadc2fSPeter Brune ierr = PetscFree(scat_g);CHKERRQ(ierr); 421803dadc2fSPeter Brune } 421903dadc2fSPeter Brune PetscFunctionReturn(0); 422003dadc2fSPeter Brune } 422103dadc2fSPeter Brune 4222c73cfb54SMatthew G. Knepley /*@ 4223c73cfb54SMatthew G. Knepley DMGetDimension - Return the topological dimension of the DM 4224c73cfb54SMatthew G. Knepley 4225c73cfb54SMatthew G. Knepley Not collective 4226c73cfb54SMatthew G. Knepley 4227c73cfb54SMatthew G. Knepley Input Parameter: 4228c73cfb54SMatthew G. Knepley . dm - The DM 4229c73cfb54SMatthew G. Knepley 4230c73cfb54SMatthew G. Knepley Output Parameter: 4231c73cfb54SMatthew G. Knepley . dim - The topological dimension 4232c73cfb54SMatthew G. Knepley 4233c73cfb54SMatthew G. Knepley Level: beginner 4234c73cfb54SMatthew G. Knepley 4235c73cfb54SMatthew G. Knepley .seealso: DMSetDimension(), DMCreate() 4236c73cfb54SMatthew G. Knepley @*/ 4237c73cfb54SMatthew G. Knepley PetscErrorCode DMGetDimension(DM dm, PetscInt *dim) 4238c73cfb54SMatthew G. Knepley { 4239c73cfb54SMatthew G. Knepley PetscFunctionBegin; 4240c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4241c73cfb54SMatthew G. Knepley PetscValidPointer(dim, 2); 4242c73cfb54SMatthew G. Knepley *dim = dm->dim; 4243c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 4244c73cfb54SMatthew G. Knepley } 4245c73cfb54SMatthew G. Knepley 4246c73cfb54SMatthew G. Knepley /*@ 4247c73cfb54SMatthew G. Knepley DMSetDimension - Set the topological dimension of the DM 4248c73cfb54SMatthew G. Knepley 4249c73cfb54SMatthew G. Knepley Collective on dm 4250c73cfb54SMatthew G. Knepley 4251c73cfb54SMatthew G. Knepley Input Parameters: 4252c73cfb54SMatthew G. Knepley + dm - The DM 4253c73cfb54SMatthew G. Knepley - dim - The topological dimension 4254c73cfb54SMatthew G. Knepley 4255c73cfb54SMatthew G. Knepley Level: beginner 4256c73cfb54SMatthew G. Knepley 4257c73cfb54SMatthew G. Knepley .seealso: DMGetDimension(), DMCreate() 4258c73cfb54SMatthew G. Knepley @*/ 4259c73cfb54SMatthew G. Knepley PetscErrorCode DMSetDimension(DM dm, PetscInt dim) 4260c73cfb54SMatthew G. Knepley { 4261f17e8794SMatthew G. Knepley PetscErrorCode ierr; 4262f17e8794SMatthew G. Knepley 4263c73cfb54SMatthew G. Knepley PetscFunctionBegin; 4264c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4265c73cfb54SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 4266c73cfb54SMatthew G. Knepley dm->dim = dim; 4267f17e8794SMatthew G. Knepley if (dm->prob->dimEmbed < 0) {ierr = PetscDSSetCoordinateDimension(dm->prob, dm->dim);CHKERRQ(ierr);} 4268c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 4269c73cfb54SMatthew G. Knepley } 4270c73cfb54SMatthew G. Knepley 4271793f3fe5SMatthew G. Knepley /*@ 4272793f3fe5SMatthew G. Knepley DMGetDimPoints - Get the half-open interval for all points of a given dimension 4273793f3fe5SMatthew G. Knepley 4274793f3fe5SMatthew G. Knepley Collective on DM 4275793f3fe5SMatthew G. Knepley 4276793f3fe5SMatthew G. Knepley Input Parameters: 4277793f3fe5SMatthew G. Knepley + dm - the DM 4278793f3fe5SMatthew G. Knepley - dim - the dimension 4279793f3fe5SMatthew G. Knepley 4280793f3fe5SMatthew G. Knepley Output Parameters: 4281793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension 4282793f3fe5SMatthew G. Knepley . pEnd - The first point following points of the given dimension 4283793f3fe5SMatthew G. Knepley 4284793f3fe5SMatthew G. Knepley Note: 4285793f3fe5SMatthew G. Knepley The points are vertices in the Hasse diagram encoding the topology. This is explained in 4286793f3fe5SMatthew G. Knepley http://arxiv.org/abs/0908.4427. If not points exist of this dimension in the storage scheme, 4287793f3fe5SMatthew G. Knepley then the interval is empty. 4288793f3fe5SMatthew G. Knepley 4289793f3fe5SMatthew G. Knepley Level: intermediate 4290793f3fe5SMatthew G. Knepley 4291793f3fe5SMatthew G. Knepley .keywords: point, Hasse Diagram, dimension 4292793f3fe5SMatthew G. Knepley .seealso: DMPLEX, DMPlexGetDepthStratum(), DMPlexGetHeightStratum() 4293793f3fe5SMatthew G. Knepley @*/ 4294793f3fe5SMatthew G. Knepley PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 4295793f3fe5SMatthew G. Knepley { 4296793f3fe5SMatthew G. Knepley PetscInt d; 4297793f3fe5SMatthew G. Knepley PetscErrorCode ierr; 4298793f3fe5SMatthew G. Knepley 4299793f3fe5SMatthew G. Knepley PetscFunctionBegin; 4300793f3fe5SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4301793f3fe5SMatthew G. Knepley ierr = DMGetDimension(dm, &d);CHKERRQ(ierr); 4302793f3fe5SMatthew G. Knepley if ((dim < 0) || (dim > d)) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %d 1", dim, d); 4303793f3fe5SMatthew G. Knepley ierr = (*dm->ops->getdimpoints)(dm, dim, pStart, pEnd);CHKERRQ(ierr); 4304793f3fe5SMatthew G. Knepley PetscFunctionReturn(0); 4305793f3fe5SMatthew G. Knepley } 4306793f3fe5SMatthew G. Knepley 43076636e97aSMatthew G Knepley /*@ 43086636e97aSMatthew G Knepley DMSetCoordinates - Sets into the DM a global vector that holds the coordinates 43096636e97aSMatthew G Knepley 43106636e97aSMatthew G Knepley Collective on DM 43116636e97aSMatthew G Knepley 43126636e97aSMatthew G Knepley Input Parameters: 43136636e97aSMatthew G Knepley + dm - the DM 43146636e97aSMatthew G Knepley - c - coordinate vector 43156636e97aSMatthew G Knepley 43162dd40e9bSPatrick Sanan Notes: 43172dd40e9bSPatrick Sanan The coordinates do include those for ghost points, which are in the local vector. 43182dd40e9bSPatrick Sanan 43192dd40e9bSPatrick Sanan The vector c should be destroyed by the caller. 43206636e97aSMatthew G Knepley 43216636e97aSMatthew G Knepley Level: intermediate 43226636e97aSMatthew G Knepley 43236636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates 43242dd40e9bSPatrick Sanan .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM() 43256636e97aSMatthew G Knepley @*/ 43266636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c) 43276636e97aSMatthew G Knepley { 43286636e97aSMatthew G Knepley PetscErrorCode ierr; 43296636e97aSMatthew G Knepley 43306636e97aSMatthew G Knepley PetscFunctionBegin; 43316636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 43326636e97aSMatthew G Knepley PetscValidHeaderSpecific(c,VEC_CLASSID,2); 43336636e97aSMatthew G Knepley ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr); 43346636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr); 43356636e97aSMatthew G Knepley dm->coordinates = c; 43366636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr); 4337b64e0483SPeter Brune ierr = DMCoarsenHookAdd(dm,DMRestrictHook_Coordinates,NULL,NULL);CHKERRQ(ierr); 433803dadc2fSPeter Brune ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_Coordinates,NULL,NULL);CHKERRQ(ierr); 43396636e97aSMatthew G Knepley PetscFunctionReturn(0); 43406636e97aSMatthew G Knepley } 43416636e97aSMatthew G Knepley 43426636e97aSMatthew G Knepley /*@ 43436636e97aSMatthew G Knepley DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates 43446636e97aSMatthew G Knepley 43456636e97aSMatthew G Knepley Collective on DM 43466636e97aSMatthew G Knepley 43476636e97aSMatthew G Knepley Input Parameters: 43486636e97aSMatthew G Knepley + dm - the DM 43496636e97aSMatthew G Knepley - c - coordinate vector 43506636e97aSMatthew G Knepley 43512dd40e9bSPatrick Sanan Notes: 43526636e97aSMatthew G Knepley The coordinates of ghost points can be set using DMSetCoordinates() 43536636e97aSMatthew G Knepley followed by DMGetCoordinatesLocal(). This is intended to enable the 43546636e97aSMatthew G Knepley setting of ghost coordinates outside of the domain. 43556636e97aSMatthew G Knepley 43562dd40e9bSPatrick Sanan The vector c should be destroyed by the caller. 43572dd40e9bSPatrick Sanan 43586636e97aSMatthew G Knepley Level: intermediate 43596636e97aSMatthew G Knepley 43606636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates 43616636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM() 43626636e97aSMatthew G Knepley @*/ 43636636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c) 43646636e97aSMatthew G Knepley { 43656636e97aSMatthew G Knepley PetscErrorCode ierr; 43666636e97aSMatthew G Knepley 43676636e97aSMatthew G Knepley PetscFunctionBegin; 43686636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 43696636e97aSMatthew G Knepley PetscValidHeaderSpecific(c,VEC_CLASSID,2); 43706636e97aSMatthew G Knepley ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr); 43716636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr); 43728865f1eaSKarl Rupp 43736636e97aSMatthew G Knepley dm->coordinatesLocal = c; 43748865f1eaSKarl Rupp 43756636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr); 43766636e97aSMatthew G Knepley PetscFunctionReturn(0); 43776636e97aSMatthew G Knepley } 43786636e97aSMatthew G Knepley 43796636e97aSMatthew G Knepley /*@ 43806636e97aSMatthew G Knepley DMGetCoordinates - Gets a global vector with the coordinates associated with the DM. 43816636e97aSMatthew G Knepley 43826636e97aSMatthew G Knepley Not Collective 43836636e97aSMatthew G Knepley 43846636e97aSMatthew G Knepley Input Parameter: 43856636e97aSMatthew G Knepley . dm - the DM 43866636e97aSMatthew G Knepley 43876636e97aSMatthew G Knepley Output Parameter: 43886636e97aSMatthew G Knepley . c - global coordinate vector 43896636e97aSMatthew G Knepley 43906636e97aSMatthew G Knepley Note: 43916636e97aSMatthew G Knepley This is a borrowed reference, so the user should NOT destroy this vector 43926636e97aSMatthew G Knepley 43936636e97aSMatthew G Knepley Each process has only the local coordinates (does NOT have the ghost coordinates). 43946636e97aSMatthew G Knepley 43956636e97aSMatthew G Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 43966636e97aSMatthew G Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 43976636e97aSMatthew G Knepley 43986636e97aSMatthew G Knepley Level: intermediate 43996636e97aSMatthew G Knepley 44006636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates 44016636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM() 44026636e97aSMatthew G Knepley @*/ 44036636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c) 44046636e97aSMatthew G Knepley { 44056636e97aSMatthew G Knepley PetscErrorCode ierr; 44066636e97aSMatthew G Knepley 44076636e97aSMatthew G Knepley PetscFunctionBegin; 44086636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 44096636e97aSMatthew G Knepley PetscValidPointer(c,2); 44101f588964SMatthew G Knepley if (!dm->coordinates && dm->coordinatesLocal) { 44110298fd71SBarry Smith DM cdm = NULL; 44126636e97aSMatthew G Knepley 44136636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 44146636e97aSMatthew G Knepley ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr); 44156636e97aSMatthew G Knepley ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr); 44166636e97aSMatthew G Knepley ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr); 44176636e97aSMatthew G Knepley ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr); 44186636e97aSMatthew G Knepley } 44196636e97aSMatthew G Knepley *c = dm->coordinates; 44206636e97aSMatthew G Knepley PetscFunctionReturn(0); 44216636e97aSMatthew G Knepley } 44226636e97aSMatthew G Knepley 44236636e97aSMatthew G Knepley /*@ 44246636e97aSMatthew G Knepley DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM. 44256636e97aSMatthew G Knepley 44266636e97aSMatthew G Knepley Collective on DM 44276636e97aSMatthew G Knepley 44286636e97aSMatthew G Knepley Input Parameter: 44296636e97aSMatthew G Knepley . dm - the DM 44306636e97aSMatthew G Knepley 44316636e97aSMatthew G Knepley Output Parameter: 44326636e97aSMatthew G Knepley . c - coordinate vector 44336636e97aSMatthew G Knepley 44346636e97aSMatthew G Knepley Note: 44356636e97aSMatthew G Knepley This is a borrowed reference, so the user should NOT destroy this vector 44366636e97aSMatthew G Knepley 44376636e97aSMatthew G Knepley Each process has the local and ghost coordinates 44386636e97aSMatthew G Knepley 44396636e97aSMatthew G Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 44406636e97aSMatthew G Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 44416636e97aSMatthew G Knepley 44426636e97aSMatthew G Knepley Level: intermediate 44436636e97aSMatthew G Knepley 44446636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates 44456636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM() 44466636e97aSMatthew G Knepley @*/ 44476636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c) 44486636e97aSMatthew G Knepley { 44496636e97aSMatthew G Knepley PetscErrorCode ierr; 44506636e97aSMatthew G Knepley 44516636e97aSMatthew G Knepley PetscFunctionBegin; 44526636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 44536636e97aSMatthew G Knepley PetscValidPointer(c,2); 44541f588964SMatthew G Knepley if (!dm->coordinatesLocal && dm->coordinates) { 44550298fd71SBarry Smith DM cdm = NULL; 44566636e97aSMatthew G Knepley 44576636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 44586636e97aSMatthew G Knepley ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr); 44596636e97aSMatthew G Knepley ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr); 44606636e97aSMatthew G Knepley ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr); 44616636e97aSMatthew G Knepley ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr); 44626636e97aSMatthew G Knepley } 44636636e97aSMatthew G Knepley *c = dm->coordinatesLocal; 44646636e97aSMatthew G Knepley PetscFunctionReturn(0); 44656636e97aSMatthew G Knepley } 44666636e97aSMatthew G Knepley 4467f19dbd58SToby Isaac PetscErrorCode DMGetCoordinateField(DM dm, DMField *field) 4468f19dbd58SToby Isaac { 4469f19dbd58SToby Isaac PetscErrorCode ierr; 4470f19dbd58SToby Isaac 4471f19dbd58SToby Isaac PetscFunctionBegin; 4472f19dbd58SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4473f19dbd58SToby Isaac PetscValidPointer(field,2); 4474f19dbd58SToby Isaac if (!dm->coordinateField) { 4475f19dbd58SToby Isaac if (dm->ops->createcoordinatefield) { 4476f19dbd58SToby Isaac ierr = (*dm->ops->createcoordinatefield)(dm,&dm->coordinateField);CHKERRQ(ierr); 4477f19dbd58SToby Isaac } 4478f19dbd58SToby Isaac } 4479f19dbd58SToby Isaac *field = dm->coordinateField; 4480f19dbd58SToby Isaac PetscFunctionReturn(0); 4481f19dbd58SToby Isaac } 4482f19dbd58SToby Isaac 4483f19dbd58SToby Isaac PetscErrorCode DMSetCoordinateField(DM dm, DMField field) 4484f19dbd58SToby Isaac { 4485f19dbd58SToby Isaac PetscErrorCode ierr; 4486f19dbd58SToby Isaac 4487f19dbd58SToby Isaac PetscFunctionBegin; 4488f19dbd58SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4489f19dbd58SToby Isaac if (field) PetscValidHeaderSpecific(field,DMFIELD_CLASSID,2); 4490c4e6da2cSBarry Smith ierr = PetscObjectReference((PetscObject)field);CHKERRQ(ierr); 4491f19dbd58SToby Isaac ierr = DMFieldDestroy(&dm->coordinateField);CHKERRQ(ierr); 4492f19dbd58SToby Isaac dm->coordinateField = field; 4493f19dbd58SToby Isaac PetscFunctionReturn(0); 4494f19dbd58SToby Isaac } 4495f19dbd58SToby Isaac 44966636e97aSMatthew G Knepley /*@ 44971cfe2091SMatthew G. Knepley DMGetCoordinateDM - Gets the DM that prescribes coordinate layout and scatters between global and local coordinates 44986636e97aSMatthew G Knepley 44996636e97aSMatthew G Knepley Collective on DM 45006636e97aSMatthew G Knepley 45016636e97aSMatthew G Knepley Input Parameter: 45026636e97aSMatthew G Knepley . dm - the DM 45036636e97aSMatthew G Knepley 45046636e97aSMatthew G Knepley Output Parameter: 45056636e97aSMatthew G Knepley . cdm - coordinate DM 45066636e97aSMatthew G Knepley 45076636e97aSMatthew G Knepley Level: intermediate 45086636e97aSMatthew G Knepley 45096636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates 45101cfe2091SMatthew G. Knepley .seealso: DMSetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal() 45116636e97aSMatthew G Knepley @*/ 45126636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm) 45136636e97aSMatthew G Knepley { 45146636e97aSMatthew G Knepley PetscErrorCode ierr; 45156636e97aSMatthew G Knepley 45166636e97aSMatthew G Knepley PetscFunctionBegin; 45176636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 45186636e97aSMatthew G Knepley PetscValidPointer(cdm,2); 45196636e97aSMatthew G Knepley if (!dm->coordinateDM) { 452082f516ccSBarry Smith if (!dm->ops->createcoordinatedm) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unable to create coordinates for this DM"); 45216636e97aSMatthew G Knepley ierr = (*dm->ops->createcoordinatedm)(dm, &dm->coordinateDM);CHKERRQ(ierr); 45226636e97aSMatthew G Knepley } 45236636e97aSMatthew G Knepley *cdm = dm->coordinateDM; 45246636e97aSMatthew G Knepley PetscFunctionReturn(0); 45256636e97aSMatthew G Knepley } 4526e87bb0d3SMatthew G Knepley 45271cfe2091SMatthew G. Knepley /*@ 45281cfe2091SMatthew G. Knepley DMSetCoordinateDM - Sets the DM that prescribes coordinate layout and scatters between global and local coordinates 45291cfe2091SMatthew G. Knepley 45301cfe2091SMatthew G. Knepley Logically Collective on DM 45311cfe2091SMatthew G. Knepley 45321cfe2091SMatthew G. Knepley Input Parameters: 45331cfe2091SMatthew G. Knepley + dm - the DM 45341cfe2091SMatthew G. Knepley - cdm - coordinate DM 45351cfe2091SMatthew G. Knepley 45361cfe2091SMatthew G. Knepley Level: intermediate 45371cfe2091SMatthew G. Knepley 45381cfe2091SMatthew G. Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates 45391cfe2091SMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal() 45401cfe2091SMatthew G. Knepley @*/ 45411cfe2091SMatthew G. Knepley PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm) 45421cfe2091SMatthew G. Knepley { 45431cfe2091SMatthew G. Knepley PetscErrorCode ierr; 45441cfe2091SMatthew G. Knepley 45451cfe2091SMatthew G. Knepley PetscFunctionBegin; 45461cfe2091SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 45471cfe2091SMatthew G. Knepley PetscValidHeaderSpecific(cdm,DM_CLASSID,2); 4548f26b38b9SToby Isaac ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr); 45491cfe2091SMatthew G. Knepley ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr); 45501cfe2091SMatthew G. Knepley dm->coordinateDM = cdm; 45511cfe2091SMatthew G. Knepley PetscFunctionReturn(0); 45521cfe2091SMatthew G. Knepley } 45531cfe2091SMatthew G. Knepley 455446e270d4SMatthew G. Knepley /*@ 455546e270d4SMatthew G. Knepley DMGetCoordinateDim - Retrieve the dimension of embedding space for coordinate values. 455646e270d4SMatthew G. Knepley 455746e270d4SMatthew G. Knepley Not Collective 455846e270d4SMatthew G. Knepley 455946e270d4SMatthew G. Knepley Input Parameter: 456046e270d4SMatthew G. Knepley . dm - The DM object 456146e270d4SMatthew G. Knepley 456246e270d4SMatthew G. Knepley Output Parameter: 456346e270d4SMatthew G. Knepley . dim - The embedding dimension 456446e270d4SMatthew G. Knepley 456546e270d4SMatthew G. Knepley Level: intermediate 456646e270d4SMatthew G. Knepley 456746e270d4SMatthew G. Knepley .keywords: mesh, coordinates 4568e87a4003SBarry Smith .seealso: DMSetCoordinateDim(), DMGetCoordinateSection(), DMGetCoordinateDM(), DMGetSection(), DMSetSection() 456946e270d4SMatthew G. Knepley @*/ 457046e270d4SMatthew G. Knepley PetscErrorCode DMGetCoordinateDim(DM dm, PetscInt *dim) 457146e270d4SMatthew G. Knepley { 457246e270d4SMatthew G. Knepley PetscFunctionBegin; 457346e270d4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 457446e270d4SMatthew G. Knepley PetscValidPointer(dim, 2); 45759a9a41abSToby Isaac if (dm->dimEmbed == PETSC_DEFAULT) { 45769a9a41abSToby Isaac dm->dimEmbed = dm->dim; 45779a9a41abSToby Isaac } 457846e270d4SMatthew G. Knepley *dim = dm->dimEmbed; 457946e270d4SMatthew G. Knepley PetscFunctionReturn(0); 458046e270d4SMatthew G. Knepley } 458146e270d4SMatthew G. Knepley 458246e270d4SMatthew G. Knepley /*@ 458346e270d4SMatthew G. Knepley DMSetCoordinateDim - Set the dimension of the embedding space for coordinate values. 458446e270d4SMatthew G. Knepley 458546e270d4SMatthew G. Knepley Not Collective 458646e270d4SMatthew G. Knepley 458746e270d4SMatthew G. Knepley Input Parameters: 458846e270d4SMatthew G. Knepley + dm - The DM object 458946e270d4SMatthew G. Knepley - dim - The embedding dimension 459046e270d4SMatthew G. Knepley 459146e270d4SMatthew G. Knepley Level: intermediate 459246e270d4SMatthew G. Knepley 459346e270d4SMatthew G. Knepley .keywords: mesh, coordinates 4594e87a4003SBarry Smith .seealso: DMGetCoordinateDim(), DMSetCoordinateSection(), DMGetCoordinateSection(), DMGetSection(), DMSetSection() 459546e270d4SMatthew G. Knepley @*/ 459646e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateDim(DM dm, PetscInt dim) 459746e270d4SMatthew G. Knepley { 4598f17e8794SMatthew G. Knepley PetscErrorCode ierr; 4599f17e8794SMatthew G. Knepley 460046e270d4SMatthew G. Knepley PetscFunctionBegin; 460146e270d4SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 460246e270d4SMatthew G. Knepley dm->dimEmbed = dim; 4603f17e8794SMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(dm->prob, dm->dimEmbed);CHKERRQ(ierr); 460446e270d4SMatthew G. Knepley PetscFunctionReturn(0); 460546e270d4SMatthew G. Knepley } 460646e270d4SMatthew G. Knepley 4607e8abe2deSMatthew G. Knepley /*@ 4608e8abe2deSMatthew G. Knepley DMGetCoordinateSection - Retrieve the layout of coordinate values over the mesh. 4609e8abe2deSMatthew G. Knepley 4610e8abe2deSMatthew G. Knepley Not Collective 4611e8abe2deSMatthew G. Knepley 4612e8abe2deSMatthew G. Knepley Input Parameter: 4613e8abe2deSMatthew G. Knepley . dm - The DM object 4614e8abe2deSMatthew G. Knepley 4615e8abe2deSMatthew G. Knepley Output Parameter: 4616e8abe2deSMatthew G. Knepley . section - The PetscSection object 4617e8abe2deSMatthew G. Knepley 4618e8abe2deSMatthew G. Knepley Level: intermediate 4619e8abe2deSMatthew G. Knepley 4620e8abe2deSMatthew G. Knepley .keywords: mesh, coordinates 4621e87a4003SBarry Smith .seealso: DMGetCoordinateDM(), DMGetSection(), DMSetSection() 4622e8abe2deSMatthew G. Knepley @*/ 4623e8abe2deSMatthew G. Knepley PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section) 4624e8abe2deSMatthew G. Knepley { 4625e8abe2deSMatthew G. Knepley DM cdm; 4626e8abe2deSMatthew G. Knepley PetscErrorCode ierr; 4627e8abe2deSMatthew G. Knepley 4628e8abe2deSMatthew G. Knepley PetscFunctionBegin; 4629e8abe2deSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4630e8abe2deSMatthew G. Knepley PetscValidPointer(section, 2); 4631e8abe2deSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 4632e87a4003SBarry Smith ierr = DMGetSection(cdm, section);CHKERRQ(ierr); 4633e8abe2deSMatthew G. Knepley PetscFunctionReturn(0); 4634e8abe2deSMatthew G. Knepley } 4635e8abe2deSMatthew G. Knepley 4636e8abe2deSMatthew G. Knepley /*@ 4637e8abe2deSMatthew G. Knepley DMSetCoordinateSection - Set the layout of coordinate values over the mesh. 4638e8abe2deSMatthew G. Knepley 4639e8abe2deSMatthew G. Knepley Not Collective 4640e8abe2deSMatthew G. Knepley 4641e8abe2deSMatthew G. Knepley Input Parameters: 4642e8abe2deSMatthew G. Knepley + dm - The DM object 464346e270d4SMatthew G. Knepley . dim - The embedding dimension, or PETSC_DETERMINE 4644e8abe2deSMatthew G. Knepley - section - The PetscSection object 4645e8abe2deSMatthew G. Knepley 4646e8abe2deSMatthew G. Knepley Level: intermediate 4647e8abe2deSMatthew G. Knepley 4648e8abe2deSMatthew G. Knepley .keywords: mesh, coordinates 4649e87a4003SBarry Smith .seealso: DMGetCoordinateSection(), DMGetSection(), DMSetSection() 4650e8abe2deSMatthew G. Knepley @*/ 465146e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateSection(DM dm, PetscInt dim, PetscSection section) 4652e8abe2deSMatthew G. Knepley { 4653e8abe2deSMatthew G. Knepley DM cdm; 4654e8abe2deSMatthew G. Knepley PetscErrorCode ierr; 4655e8abe2deSMatthew G. Knepley 4656e8abe2deSMatthew G. Knepley PetscFunctionBegin; 4657e8abe2deSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 465846e270d4SMatthew G. Knepley PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,3); 4659e8abe2deSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 4660e87a4003SBarry Smith ierr = DMSetSection(cdm, section);CHKERRQ(ierr); 466146e270d4SMatthew G. Knepley if (dim == PETSC_DETERMINE) { 46624c1069a6SMatthew G. Knepley PetscInt d = PETSC_DEFAULT; 466346e270d4SMatthew G. Knepley PetscInt pStart, pEnd, vStart, vEnd, v, dd; 466446e270d4SMatthew G. Knepley 466546e270d4SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 466646e270d4SMatthew G. Knepley ierr = DMGetDimPoints(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 466746e270d4SMatthew G. Knepley pStart = PetscMax(vStart, pStart); 466846e270d4SMatthew G. Knepley pEnd = PetscMin(vEnd, pEnd); 466946e270d4SMatthew G. Knepley for (v = pStart; v < pEnd; ++v) { 467046e270d4SMatthew G. Knepley ierr = PetscSectionGetDof(section, v, &dd);CHKERRQ(ierr); 467146e270d4SMatthew G. Knepley if (dd) {d = dd; break;} 467246e270d4SMatthew G. Knepley } 46736be882deSMatthew G. Knepley if (d < 0) d = PETSC_DEFAULT; 467446e270d4SMatthew G. Knepley ierr = DMSetCoordinateDim(dm, d);CHKERRQ(ierr); 467546e270d4SMatthew G. Knepley } 4676e8abe2deSMatthew G. Knepley PetscFunctionReturn(0); 4677e8abe2deSMatthew G. Knepley } 4678e8abe2deSMatthew G. Knepley 46795dc8c3f7SMatthew G. Knepley /*@C 468090b157c4SStefano Zampini DMGetPeriodicity - Get the description of mesh periodicity 46815dc8c3f7SMatthew G. Knepley 46825dc8c3f7SMatthew G. Knepley Input Parameters: 468390b157c4SStefano Zampini . dm - The DM object 468490b157c4SStefano Zampini 468590b157c4SStefano Zampini Output Parameters: 468690b157c4SStefano Zampini + per - Whether the DM is periodic or not 46875dc8c3f7SMatthew 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 46885dc8c3f7SMatthew G. Knepley . L - If we assume the mesh is a torus, this is the length of each coordinate 46895dc8c3f7SMatthew G. Knepley - bd - This describes the type of periodicity in each topological dimension 46905dc8c3f7SMatthew G. Knepley 46915dc8c3f7SMatthew G. Knepley Level: developer 46925dc8c3f7SMatthew G. Knepley 46935dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity() 46945dc8c3f7SMatthew G. Knepley @*/ 469590b157c4SStefano Zampini PetscErrorCode DMGetPeriodicity(DM dm, PetscBool *per, const PetscReal **maxCell, const PetscReal **L, const DMBoundaryType **bd) 4696c6b900c6SMatthew G. Knepley { 4697c6b900c6SMatthew G. Knepley PetscFunctionBegin; 4698c6b900c6SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 469990b157c4SStefano Zampini if (per) *per = dm->periodic; 4700c6b900c6SMatthew G. Knepley if (L) *L = dm->L; 4701c6b900c6SMatthew G. Knepley if (maxCell) *maxCell = dm->maxCell; 47025dc8c3f7SMatthew G. Knepley if (bd) *bd = dm->bdtype; 4703c6b900c6SMatthew G. Knepley PetscFunctionReturn(0); 4704c6b900c6SMatthew G. Knepley } 4705c6b900c6SMatthew G. Knepley 47065dc8c3f7SMatthew G. Knepley /*@C 47075dc8c3f7SMatthew G. Knepley DMSetPeriodicity - Set the description of mesh periodicity 47085dc8c3f7SMatthew G. Knepley 47095dc8c3f7SMatthew G. Knepley Input Parameters: 47105dc8c3f7SMatthew G. Knepley + dm - The DM object 471190b157c4SStefano Zampini . per - Whether the DM is periodic or not. If maxCell is not provided, coordinates need to be localized 47125dc8c3f7SMatthew 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 47135dc8c3f7SMatthew G. Knepley . L - If we assume the mesh is a torus, this is the length of each coordinate 47145dc8c3f7SMatthew G. Knepley - bd - This describes the type of periodicity in each topological dimension 47155dc8c3f7SMatthew G. Knepley 47165dc8c3f7SMatthew G. Knepley Level: developer 47175dc8c3f7SMatthew G. Knepley 47185dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity() 47195dc8c3f7SMatthew G. Knepley @*/ 472090b157c4SStefano Zampini PetscErrorCode DMSetPeriodicity(DM dm, PetscBool per, const PetscReal maxCell[], const PetscReal L[], const DMBoundaryType bd[]) 4721c6b900c6SMatthew G. Knepley { 4722c6b900c6SMatthew G. Knepley PetscInt dim, d; 4723c6b900c6SMatthew G. Knepley PetscErrorCode ierr; 4724c6b900c6SMatthew G. Knepley 4725c6b900c6SMatthew G. Knepley PetscFunctionBegin; 4726c6b900c6SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 472790b157c4SStefano Zampini PetscValidLogicalCollectiveBool(dm,per,2); 472890b157c4SStefano Zampini if (maxCell) { 472990b157c4SStefano Zampini PetscValidPointer(maxCell,3); 473090b157c4SStefano Zampini PetscValidPointer(L,4); 473190b157c4SStefano Zampini PetscValidPointer(bd,5); 473290b157c4SStefano Zampini } 47335dc8c3f7SMatthew G. Knepley ierr = PetscFree3(dm->L,dm->maxCell,dm->bdtype);CHKERRQ(ierr); 47345dc8c3f7SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 473590b157c4SStefano Zampini if (maxCell) { 47365dc8c3f7SMatthew G. Knepley ierr = PetscMalloc3(dim,&dm->L,dim,&dm->maxCell,dim,&dm->bdtype);CHKERRQ(ierr); 47375dc8c3f7SMatthew G. Knepley for (d = 0; d < dim; ++d) {dm->L[d] = L[d]; dm->maxCell[d] = maxCell[d]; dm->bdtype[d] = bd[d];} 473890b157c4SStefano Zampini dm->periodic = PETSC_TRUE; 473990b157c4SStefano Zampini } else { 474090b157c4SStefano Zampini dm->periodic = per; 474190b157c4SStefano Zampini } 4742c6b900c6SMatthew G. Knepley PetscFunctionReturn(0); 4743c6b900c6SMatthew G. Knepley } 4744c6b900c6SMatthew G. Knepley 47452e17dfb7SMatthew G. Knepley /*@ 47462e17dfb7SMatthew 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. 47472e17dfb7SMatthew G. Knepley 47482e17dfb7SMatthew G. Knepley Input Parameters: 47492e17dfb7SMatthew G. Knepley + dm - The DM 475065da65dcSMatthew G. Knepley . in - The input coordinate point (dim numbers) 475165da65dcSMatthew G. Knepley - endpoint - Include the endpoint L_i 47522e17dfb7SMatthew G. Knepley 47532e17dfb7SMatthew G. Knepley Output Parameter: 47542e17dfb7SMatthew G. Knepley . out - The localized coordinate point 47552e17dfb7SMatthew G. Knepley 47562e17dfb7SMatthew G. Knepley Level: developer 47572e17dfb7SMatthew G. Knepley 47582e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate() 47592e17dfb7SMatthew G. Knepley @*/ 476065da65dcSMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate(DM dm, const PetscScalar in[], PetscBool endpoint, PetscScalar out[]) 47612e17dfb7SMatthew G. Knepley { 47622e17dfb7SMatthew G. Knepley PetscInt dim, d; 47632e17dfb7SMatthew G. Knepley PetscErrorCode ierr; 47642e17dfb7SMatthew G. Knepley 47652e17dfb7SMatthew G. Knepley PetscFunctionBegin; 47662e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 47672e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 47682e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 47692e17dfb7SMatthew G. Knepley } else { 477065da65dcSMatthew G. Knepley if (endpoint) { 477165da65dcSMatthew G. Knepley for (d = 0; d < dim; ++d) { 4772da3333bfSMatthew 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)) { 4773da3333bfSMatthew G. Knepley out[d] = in[d] - dm->L[d]*(PetscFloorReal(PetscRealPart(in[d])/dm->L[d]) - 1); 477465da65dcSMatthew G. Knepley } else { 4775da3333bfSMatthew G. Knepley out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]); 477665da65dcSMatthew G. Knepley } 477765da65dcSMatthew G. Knepley } 477865da65dcSMatthew G. Knepley } else { 47792e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 47801118d4bcSLisandro Dalcin out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]); 47812e17dfb7SMatthew G. Knepley } 47822e17dfb7SMatthew G. Knepley } 478365da65dcSMatthew G. Knepley } 47842e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 47852e17dfb7SMatthew G. Knepley } 47862e17dfb7SMatthew G. Knepley 47872e17dfb7SMatthew G. Knepley /* 47882e17dfb7SMatthew 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. 47892e17dfb7SMatthew G. Knepley 47902e17dfb7SMatthew G. Knepley Input Parameters: 47912e17dfb7SMatthew G. Knepley + dm - The DM 47922e17dfb7SMatthew G. Knepley . dim - The spatial dimension 47932e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it 47942e17dfb7SMatthew G. Knepley - in - The input coordinate point (dim numbers) 47952e17dfb7SMatthew G. Knepley 47962e17dfb7SMatthew G. Knepley Output Parameter: 47972e17dfb7SMatthew G. Knepley . out - The localized coordinate point 47982e17dfb7SMatthew G. Knepley 47992e17dfb7SMatthew G. Knepley Level: developer 48002e17dfb7SMatthew G. Knepley 48012e17dfb7SMatthew 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 48022e17dfb7SMatthew G. Knepley 48032e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate() 48042e17dfb7SMatthew G. Knepley */ 48052e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[]) 48062e17dfb7SMatthew G. Knepley { 48072e17dfb7SMatthew G. Knepley PetscInt d; 48082e17dfb7SMatthew G. Knepley 48092e17dfb7SMatthew G. Knepley PetscFunctionBegin; 48102e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 48112e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 48122e17dfb7SMatthew G. Knepley } else { 48132e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 4814908eca10SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) { 48152e17dfb7SMatthew G. Knepley out[d] = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d]; 48162e17dfb7SMatthew G. Knepley } else { 48172e17dfb7SMatthew G. Knepley out[d] = in[d]; 48182e17dfb7SMatthew G. Knepley } 48192e17dfb7SMatthew G. Knepley } 48202e17dfb7SMatthew G. Knepley } 48212e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 48222e17dfb7SMatthew G. Knepley } 48232e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinateReal_Internal(DM dm, PetscInt dim, const PetscReal anchor[], const PetscReal in[], PetscReal out[]) 48242e17dfb7SMatthew G. Knepley { 48252e17dfb7SMatthew G. Knepley PetscInt d; 48262e17dfb7SMatthew G. Knepley 48272e17dfb7SMatthew G. Knepley PetscFunctionBegin; 48282e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 48292e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 48302e17dfb7SMatthew G. Knepley } else { 48312e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 4832908eca10SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsReal(anchor[d] - in[d]) > dm->maxCell[d])) { 48332e17dfb7SMatthew G. Knepley out[d] = anchor[d] > in[d] ? dm->L[d] + in[d] : in[d] - dm->L[d]; 48342e17dfb7SMatthew G. Knepley } else { 48352e17dfb7SMatthew G. Knepley out[d] = in[d]; 48362e17dfb7SMatthew G. Knepley } 48372e17dfb7SMatthew G. Knepley } 48382e17dfb7SMatthew G. Knepley } 48392e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 48402e17dfb7SMatthew G. Knepley } 48412e17dfb7SMatthew G. Knepley 48422e17dfb7SMatthew G. Knepley /* 48432e17dfb7SMatthew 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. 48442e17dfb7SMatthew G. Knepley 48452e17dfb7SMatthew G. Knepley Input Parameters: 48462e17dfb7SMatthew G. Knepley + dm - The DM 48472e17dfb7SMatthew G. Knepley . dim - The spatial dimension 48482e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it 48492e17dfb7SMatthew G. Knepley . in - The input coordinate delta (dim numbers) 48502e17dfb7SMatthew G. Knepley - out - The input coordinate point (dim numbers) 48512e17dfb7SMatthew G. Knepley 48522e17dfb7SMatthew G. Knepley Output Parameter: 48532e17dfb7SMatthew G. Knepley . out - The localized coordinate in + out 48542e17dfb7SMatthew G. Knepley 48552e17dfb7SMatthew G. Knepley Level: developer 48562e17dfb7SMatthew G. Knepley 48572e17dfb7SMatthew 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 48582e17dfb7SMatthew G. Knepley 48592e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeCoordinate() 48602e17dfb7SMatthew G. Knepley */ 48612e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeAddCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[]) 48622e17dfb7SMatthew G. Knepley { 48632e17dfb7SMatthew G. Knepley PetscInt d; 48642e17dfb7SMatthew G. Knepley 48652e17dfb7SMatthew G. Knepley PetscFunctionBegin; 48662e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 48672e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] += in[d]; 48682e17dfb7SMatthew G. Knepley } else { 48692e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 4870908eca10SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) { 48712e17dfb7SMatthew G. Knepley out[d] += PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d]; 48722e17dfb7SMatthew G. Knepley } else { 48732e17dfb7SMatthew G. Knepley out[d] += in[d]; 48742e17dfb7SMatthew G. Knepley } 48752e17dfb7SMatthew G. Knepley } 48762e17dfb7SMatthew G. Knepley } 48772e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 48782e17dfb7SMatthew G. Knepley } 48792e17dfb7SMatthew G. Knepley 488036447a5eSToby Isaac /*@ 488136447a5eSToby Isaac DMGetCoordinatesLocalized - Check if the DM coordinates have been localized for cells 488236447a5eSToby Isaac 488336447a5eSToby Isaac Input Parameter: 488436447a5eSToby Isaac . dm - The DM 488536447a5eSToby Isaac 488636447a5eSToby Isaac Output Parameter: 488736447a5eSToby Isaac areLocalized - True if localized 488836447a5eSToby Isaac 488936447a5eSToby Isaac Level: developer 489036447a5eSToby Isaac 489136447a5eSToby Isaac .seealso: DMLocalizeCoordinates() 489236447a5eSToby Isaac @*/ 489336447a5eSToby Isaac PetscErrorCode DMGetCoordinatesLocalized(DM dm,PetscBool *areLocalized) 489436447a5eSToby Isaac { 489536447a5eSToby Isaac DM cdm; 489636447a5eSToby Isaac PetscSection coordSection; 489746a3a80fSLisandro Dalcin PetscInt cStart, cEnd, sStart, sEnd, c, dof; 489846a3a80fSLisandro Dalcin PetscBool isPlex, alreadyLocalized; 489936447a5eSToby Isaac PetscErrorCode ierr; 490036447a5eSToby Isaac 490136447a5eSToby Isaac PetscFunctionBegin; 490236447a5eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 490346a3a80fSLisandro Dalcin PetscValidPointer(areLocalized, 2); 490446a3a80fSLisandro Dalcin 49058b09590cSToby Isaac *areLocalized = PETSC_FALSE; 490646a3a80fSLisandro Dalcin if (!dm->periodic) PetscFunctionReturn(0); /* This is a hideous optimization hack! */ 490746a3a80fSLisandro Dalcin 490836447a5eSToby Isaac /* We need some generic way of refering to cells/vertices */ 490936447a5eSToby Isaac ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 491036447a5eSToby Isaac ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 491146a3a80fSLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isPlex);CHKERRQ(ierr); 491246a3a80fSLisandro Dalcin if (!isPlex) SETERRQ(PetscObjectComm((PetscObject) cdm), PETSC_ERR_ARG_WRONG, "Coordinate localization requires a DMPLEX coordinate DM"); 491346a3a80fSLisandro Dalcin 491446a3a80fSLisandro Dalcin ierr = DMPlexGetHeightStratum(cdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 491536447a5eSToby Isaac ierr = PetscSectionGetChart(coordSection, &sStart, &sEnd);CHKERRQ(ierr); 491636447a5eSToby Isaac alreadyLocalized = PETSC_FALSE; 491746a3a80fSLisandro Dalcin for (c = cStart; c < cEnd; ++c) { 491846a3a80fSLisandro Dalcin if (c < sStart || c >= sEnd) continue; 491936447a5eSToby Isaac ierr = PetscSectionGetDof(coordSection, c, &dof);CHKERRQ(ierr); 492046a3a80fSLisandro Dalcin if (dof) { alreadyLocalized = PETSC_TRUE; break; } 492136447a5eSToby Isaac } 492246a3a80fSLisandro Dalcin ierr = MPIU_Allreduce(&alreadyLocalized,areLocalized,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 492336447a5eSToby Isaac PetscFunctionReturn(0); 492436447a5eSToby Isaac } 492536447a5eSToby Isaac 492636447a5eSToby Isaac 49272e17dfb7SMatthew G. Knepley /*@ 4928492b8470SStefano Zampini DMLocalizeCoordinates - If a mesh is periodic, create local coordinates for cells having periodic faces 49292e17dfb7SMatthew G. Knepley 49302e17dfb7SMatthew G. Knepley Input Parameter: 49312e17dfb7SMatthew G. Knepley . dm - The DM 49322e17dfb7SMatthew G. Knepley 49332e17dfb7SMatthew G. Knepley Level: developer 49342e17dfb7SMatthew G. Knepley 49352e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinate(), DMLocalizeAddCoordinate() 49362e17dfb7SMatthew G. Knepley @*/ 49372e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinates(DM dm) 49382e17dfb7SMatthew G. Knepley { 49392e17dfb7SMatthew G. Knepley DM cdm; 49402e17dfb7SMatthew G. Knepley PetscSection coordSection, cSection; 49412e17dfb7SMatthew G. Knepley Vec coordinates, cVec; 49423e922f36SToby Isaac PetscScalar *coords, *coords2, *anchor, *localized; 49433e922f36SToby Isaac PetscInt Nc, vStart, vEnd, v, sStart, sEnd, newStart = PETSC_MAX_INT, newEnd = PETSC_MIN_INT, dof, d, off, off2, bs, coordSize; 4944e0ae35bbSToby Isaac PetscBool alreadyLocalized, alreadyLocalizedGlobal; 49453e922f36SToby Isaac PetscInt maxHeight = 0, h; 49463e922f36SToby Isaac PetscInt *pStart = NULL, *pEnd = NULL; 49472e17dfb7SMatthew G. Knepley PetscErrorCode ierr; 49482e17dfb7SMatthew G. Knepley 49492e17dfb7SMatthew G. Knepley PetscFunctionBegin; 49502e17dfb7SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 495192c9c85fSStefano Zampini if (!dm->periodic) PetscFunctionReturn(0); 4952f7cbd40bSStefano Zampini ierr = DMGetCoordinatesLocalized(dm, &alreadyLocalized);CHKERRQ(ierr); 4953f7cbd40bSStefano Zampini if (alreadyLocalized) PetscFunctionReturn(0); 4954f7cbd40bSStefano Zampini 49552e17dfb7SMatthew G. Knepley /* We need some generic way of refering to cells/vertices */ 49562e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 49572e17dfb7SMatthew G. Knepley { 49582e17dfb7SMatthew G. Knepley PetscBool isplex; 49592e17dfb7SMatthew G. Knepley 49602e17dfb7SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isplex);CHKERRQ(ierr); 49612e17dfb7SMatthew G. Knepley if (isplex) { 49622e17dfb7SMatthew G. Knepley ierr = DMPlexGetDepthStratum(cdm, 0, &vStart, &vEnd);CHKERRQ(ierr); 49633e922f36SToby Isaac ierr = DMPlexGetMaxProjectionHeight(cdm,&maxHeight);CHKERRQ(ierr); 496469291d52SBarry Smith ierr = DMGetWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 49653e922f36SToby Isaac pEnd = &pStart[maxHeight + 1]; 49663e922f36SToby Isaac newStart = vStart; 49673e922f36SToby Isaac newEnd = vEnd; 49683e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 49693e922f36SToby Isaac ierr = DMPlexGetHeightStratum(cdm, h, &pStart[h], &pEnd[h]);CHKERRQ(ierr); 49703e922f36SToby Isaac newStart = PetscMin(newStart,pStart[h]); 49713e922f36SToby Isaac newEnd = PetscMax(newEnd,pEnd[h]); 49723e922f36SToby Isaac } 49732e17dfb7SMatthew G. Knepley } else SETERRQ(PetscObjectComm((PetscObject) cdm), PETSC_ERR_ARG_WRONG, "Coordinate localization requires a DMPLEX coordinate DM"); 49742e17dfb7SMatthew G. Knepley } 49752e17dfb7SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 497643eeeb2dSStefano Zampini if (!coordinates) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Missing local coordinates vector"); 49772e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 49783e922f36SToby Isaac ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 4979e0ae35bbSToby Isaac ierr = PetscSectionGetChart(coordSection,&sStart,&sEnd);CHKERRQ(ierr); 49803e922f36SToby Isaac 49812e17dfb7SMatthew G. Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &cSection);CHKERRQ(ierr); 49822e17dfb7SMatthew G. Knepley ierr = PetscSectionSetNumFields(cSection, 1);CHKERRQ(ierr); 49832e17dfb7SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(coordSection, 0, &Nc);CHKERRQ(ierr); 49842e17dfb7SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(cSection, 0, Nc);CHKERRQ(ierr); 49853e922f36SToby Isaac ierr = PetscSectionSetChart(cSection, newStart, newEnd);CHKERRQ(ierr); 49863e922f36SToby Isaac 498769291d52SBarry Smith ierr = DMGetWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 49883e922f36SToby Isaac localized = &anchor[bs]; 49893e922f36SToby Isaac alreadyLocalized = alreadyLocalizedGlobal = PETSC_TRUE; 49903e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 49913e922f36SToby Isaac PetscInt cStart = pStart[h], cEnd = pEnd[h], c; 49923e922f36SToby Isaac 49933e922f36SToby Isaac for (c = cStart; c < cEnd; ++c) { 49943e922f36SToby Isaac PetscScalar *cellCoords = NULL; 49953e922f36SToby Isaac PetscInt b; 49963e922f36SToby Isaac 49973e922f36SToby Isaac if (c < sStart || c >= sEnd) alreadyLocalized = PETSC_FALSE; 49983e922f36SToby Isaac ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 49993e922f36SToby Isaac for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b]; 50003e922f36SToby Isaac for (d = 0; d < dof/bs; ++d) { 50013e922f36SToby Isaac ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], localized);CHKERRQ(ierr); 50023e922f36SToby Isaac for (b = 0; b < bs; b++) { 50033e922f36SToby Isaac if (cellCoords[d*bs + b] != localized[b]) break; 50043e922f36SToby Isaac } 50053e922f36SToby Isaac if (b < bs) break; 50063e922f36SToby Isaac } 50073e922f36SToby Isaac if (d < dof/bs) { 50083e922f36SToby Isaac if (c >= sStart && c < sEnd) { 50093e922f36SToby Isaac PetscInt cdof; 50103e922f36SToby Isaac 50113e922f36SToby Isaac ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 50123e922f36SToby Isaac if (cdof != dof) alreadyLocalized = PETSC_FALSE; 50133e922f36SToby Isaac } 50143e922f36SToby Isaac ierr = PetscSectionSetDof(cSection, c, dof);CHKERRQ(ierr); 50153e922f36SToby Isaac ierr = PetscSectionSetFieldDof(cSection, c, 0, dof);CHKERRQ(ierr); 50163e922f36SToby Isaac } 50173e922f36SToby Isaac ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 50183e922f36SToby Isaac } 50193e922f36SToby Isaac } 50203e922f36SToby Isaac ierr = MPI_Allreduce(&alreadyLocalized,&alreadyLocalizedGlobal,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 50213e922f36SToby Isaac if (alreadyLocalizedGlobal) { 502269291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 50233e922f36SToby Isaac ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr); 502469291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 50253e922f36SToby Isaac PetscFunctionReturn(0); 50263e922f36SToby Isaac } 50272e17dfb7SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 50282e17dfb7SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 50292e17dfb7SMatthew G. Knepley ierr = PetscSectionSetDof(cSection, v, dof);CHKERRQ(ierr); 50302e17dfb7SMatthew G. Knepley ierr = PetscSectionSetFieldDof(cSection, v, 0, dof);CHKERRQ(ierr); 50312e17dfb7SMatthew G. Knepley } 50322e17dfb7SMatthew G. Knepley ierr = PetscSectionSetUp(cSection);CHKERRQ(ierr); 50332e17dfb7SMatthew G. Knepley ierr = PetscSectionGetStorageSize(cSection, &coordSize);CHKERRQ(ierr); 5034c2be7e5eSLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &cVec);CHKERRQ(ierr); 50352e17dfb7SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject)cVec,"coordinates");CHKERRQ(ierr); 50362e17dfb7SMatthew G. Knepley ierr = VecSetBlockSize(cVec, bs);CHKERRQ(ierr); 50372e17dfb7SMatthew G. Knepley ierr = VecSetSizes(cVec, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 50382e17dfb7SMatthew G. Knepley ierr = VecSetType(cVec, VECSTANDARD);CHKERRQ(ierr); 5039c2be7e5eSLisandro Dalcin ierr = VecGetArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr); 50402e17dfb7SMatthew G. Knepley ierr = VecGetArray(cVec, &coords2);CHKERRQ(ierr); 50412e17dfb7SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 50422e17dfb7SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 50432e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 50442e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(cSection, v, &off2);CHKERRQ(ierr); 50452e17dfb7SMatthew G. Knepley for (d = 0; d < dof; ++d) coords2[off2+d] = coords[off+d]; 50462e17dfb7SMatthew G. Knepley } 50473e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 50483e922f36SToby Isaac PetscInt cStart = pStart[h], cEnd = pEnd[h], c; 50493e922f36SToby Isaac 50502e17dfb7SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 50512e17dfb7SMatthew G. Knepley PetscScalar *cellCoords = NULL; 50523e922f36SToby Isaac PetscInt b, cdof; 50532e17dfb7SMatthew G. Knepley 50543e922f36SToby Isaac ierr = PetscSectionGetDof(cSection,c,&cdof);CHKERRQ(ierr); 50553e922f36SToby Isaac if (!cdof) continue; 50562e17dfb7SMatthew G. Knepley ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 50572e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(cSection, c, &off2);CHKERRQ(ierr); 50582e17dfb7SMatthew G. Knepley for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b]; 50592e17dfb7SMatthew G. Knepley for (d = 0; d < dof/bs; ++d) {ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], &coords2[off2+d*bs]);CHKERRQ(ierr);} 50602e17dfb7SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 50612e17dfb7SMatthew G. Knepley } 50623e922f36SToby Isaac } 506369291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 506469291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 5065c2be7e5eSLisandro Dalcin ierr = VecRestoreArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr); 50662e17dfb7SMatthew G. Knepley ierr = VecRestoreArray(cVec, &coords2);CHKERRQ(ierr); 50672e17dfb7SMatthew G. Knepley ierr = DMSetCoordinateSection(dm, PETSC_DETERMINE, cSection);CHKERRQ(ierr); 50682e17dfb7SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, cVec);CHKERRQ(ierr); 50692e17dfb7SMatthew G. Knepley ierr = VecDestroy(&cVec);CHKERRQ(ierr); 50702e17dfb7SMatthew G. Knepley ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr); 50712e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 50722e17dfb7SMatthew G. Knepley } 50732e17dfb7SMatthew G. Knepley 5074e87bb0d3SMatthew G Knepley /*@ 50753a93e3b7SToby Isaac DMLocatePoints - Locate the points in v in the mesh and return a PetscSF of the containing cells 5076e87bb0d3SMatthew G Knepley 50773a93e3b7SToby Isaac Collective on Vec v (see explanation below) 5078e87bb0d3SMatthew G Knepley 5079e87bb0d3SMatthew G Knepley Input Parameters: 5080e87bb0d3SMatthew G Knepley + dm - The DM 50813a93e3b7SToby Isaac . v - The Vec of points 508262a38674SMatthew G. Knepley . ltype - The type of point location, e.g. DM_POINTLOCATION_NONE or DM_POINTLOCATION_NEAREST 50833a93e3b7SToby Isaac - cells - Points to either NULL, or a PetscSF with guesses for which cells contain each point. 5084e87bb0d3SMatthew G Knepley 508561e3bb9bSMatthew G Knepley Output Parameter: 508662a38674SMatthew G. Knepley + v - The Vec of points, which now contains the nearest mesh points to the given points if DM_POINTLOCATION_NEAREST is used 508762a38674SMatthew G. Knepley - cells - The PetscSF containing the ranks and local indices of the containing points. 50883a93e3b7SToby Isaac 5089e87bb0d3SMatthew G Knepley 5090e87bb0d3SMatthew G Knepley Level: developer 509161e3bb9bSMatthew G Knepley 509262a38674SMatthew G. Knepley Notes: 50933a93e3b7SToby Isaac To do a search of the local cells of the mesh, v should have PETSC_COMM_SELF as its communicator. 509462a38674SMatthew G. Knepley To do a search of all the cells in the distributed mesh, v should have the same communicator as dm. 50953a93e3b7SToby Isaac 50963a93e3b7SToby Isaac If *cellSF is NULL on input, a PetscSF will be created. 509762a38674SMatthew G. Knepley If *cellSF is not NULL on input, it should point to an existing PetscSF, whose graph will be used as initial guesses. 50983a93e3b7SToby Isaac 50993a93e3b7SToby Isaac An array that maps each point to its containing cell can be obtained with 51003a93e3b7SToby Isaac 510162a38674SMatthew G. Knepley $ const PetscSFNode *cells; 510262a38674SMatthew G. Knepley $ PetscInt nFound; 5103a6216909SToby Isaac $ const PetscInt *found; 510462a38674SMatthew G. Knepley $ 5105a6216909SToby Isaac $ PetscSFGetGraph(cellSF,NULL,&nFound,&found,&cells); 51063a93e3b7SToby Isaac 51073a93e3b7SToby 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 51083a93e3b7SToby Isaac the index of the cell in its rank's local numbering. 51093a93e3b7SToby Isaac 511061e3bb9bSMatthew G Knepley .keywords: point location, mesh 511162a38674SMatthew G. Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMPointLocationType 511261e3bb9bSMatthew G Knepley @*/ 511362a38674SMatthew G. Knepley PetscErrorCode DMLocatePoints(DM dm, Vec v, DMPointLocationType ltype, PetscSF *cellSF) 5114e87bb0d3SMatthew G Knepley { 5115735aa83eSMatthew G Knepley PetscErrorCode ierr; 5116735aa83eSMatthew G Knepley 5117e87bb0d3SMatthew G Knepley PetscFunctionBegin; 5118e87bb0d3SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 5119e87bb0d3SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5120e0fc9d1bSMatthew G. Knepley PetscValidPointer(cellSF,4); 51213a93e3b7SToby Isaac if (*cellSF) { 51223a93e3b7SToby Isaac PetscMPIInt result; 51233a93e3b7SToby Isaac 5124e0fc9d1bSMatthew G. Knepley PetscValidHeaderSpecific(*cellSF,PETSCSF_CLASSID,4); 5125a4f09dd6SDave May ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)v),PetscObjectComm((PetscObject)*cellSF),&result);CHKERRQ(ierr); 51263a93e3b7SToby 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"); 5127e0fc9d1bSMatthew G. Knepley } else { 51283a93e3b7SToby Isaac ierr = PetscSFCreate(PetscObjectComm((PetscObject)v),cellSF);CHKERRQ(ierr); 51293a93e3b7SToby Isaac } 513047a35634SPatrick Farrell ierr = PetscLogEventBegin(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr); 5131735aa83eSMatthew G Knepley if (dm->ops->locatepoints) { 513262a38674SMatthew G. Knepley ierr = (*dm->ops->locatepoints)(dm,v,ltype,*cellSF);CHKERRQ(ierr); 513382f516ccSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Point location not available for this DM"); 513447a35634SPatrick Farrell ierr = PetscLogEventEnd(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr); 5135e87bb0d3SMatthew G Knepley PetscFunctionReturn(0); 5136e87bb0d3SMatthew G Knepley } 513714f150ffSMatthew G. Knepley 5138f4d763aaSMatthew G. Knepley /*@ 5139f4d763aaSMatthew G. Knepley DMGetOutputDM - Retrieve the DM associated with the layout for output 5140f4d763aaSMatthew G. Knepley 5141f4d763aaSMatthew G. Knepley Input Parameter: 5142f4d763aaSMatthew G. Knepley . dm - The original DM 5143f4d763aaSMatthew G. Knepley 5144f4d763aaSMatthew G. Knepley Output Parameter: 5145f4d763aaSMatthew G. Knepley . odm - The DM which provides the layout for output 5146f4d763aaSMatthew G. Knepley 5147f4d763aaSMatthew G. Knepley Level: intermediate 5148f4d763aaSMatthew G. Knepley 5149e87a4003SBarry Smith .seealso: VecView(), DMGetGlobalSection() 5150f4d763aaSMatthew G. Knepley @*/ 515114f150ffSMatthew G. Knepley PetscErrorCode DMGetOutputDM(DM dm, DM *odm) 515214f150ffSMatthew G. Knepley { 5153c26acbdeSMatthew G. Knepley PetscSection section; 51542d4e4a49SMatthew G. Knepley PetscBool hasConstraints, ghasConstraints; 515514f150ffSMatthew G. Knepley PetscErrorCode ierr; 515614f150ffSMatthew G. Knepley 515714f150ffSMatthew G. Knepley PetscFunctionBegin; 515814f150ffSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 515914f150ffSMatthew G. Knepley PetscValidPointer(odm,2); 5160e87a4003SBarry Smith ierr = DMGetSection(dm, §ion);CHKERRQ(ierr); 5161c26acbdeSMatthew G. Knepley ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr); 5162127fe6b9SMatthew G. Knepley ierr = MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 51632d4e4a49SMatthew G. Knepley if (!ghasConstraints) { 5164c26acbdeSMatthew G. Knepley *odm = dm; 5165c26acbdeSMatthew G. Knepley PetscFunctionReturn(0); 5166c26acbdeSMatthew G. Knepley } 516714f150ffSMatthew G. Knepley if (!dm->dmBC) { 51680305aff6SMatthew G. Knepley PetscDS ds; 5169c26acbdeSMatthew G. Knepley PetscSection newSection, gsection; 517014f150ffSMatthew G. Knepley PetscSF sf; 517114f150ffSMatthew G. Knepley 517214f150ffSMatthew G. Knepley ierr = DMClone(dm, &dm->dmBC);CHKERRQ(ierr); 51730305aff6SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 51740305aff6SMatthew G. Knepley ierr = DMSetDS(dm->dmBC, ds);CHKERRQ(ierr); 517514f150ffSMatthew G. Knepley ierr = PetscSectionClone(section, &newSection);CHKERRQ(ierr); 5176e87a4003SBarry Smith ierr = DMSetSection(dm->dmBC, newSection);CHKERRQ(ierr); 517714f150ffSMatthew G. Knepley ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr); 517814f150ffSMatthew G. Knepley ierr = DMGetPointSF(dm->dmBC, &sf);CHKERRQ(ierr); 517915b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr); 5180e87a4003SBarry Smith ierr = DMSetGlobalSection(dm->dmBC, gsection);CHKERRQ(ierr); 518114f150ffSMatthew G. Knepley ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr); 518214f150ffSMatthew G. Knepley } 518314f150ffSMatthew G. Knepley *odm = dm->dmBC; 518414f150ffSMatthew G. Knepley PetscFunctionReturn(0); 518514f150ffSMatthew G. Knepley } 5186f4d763aaSMatthew G. Knepley 5187f4d763aaSMatthew G. Knepley /*@ 5188cdb7a50dSMatthew G. Knepley DMGetOutputSequenceNumber - Retrieve the sequence number/value for output 5189f4d763aaSMatthew G. Knepley 5190f4d763aaSMatthew G. Knepley Input Parameter: 5191f4d763aaSMatthew G. Knepley . dm - The original DM 5192f4d763aaSMatthew G. Knepley 5193cdb7a50dSMatthew G. Knepley Output Parameters: 5194cdb7a50dSMatthew G. Knepley + num - The output sequence number 5195cdb7a50dSMatthew G. Knepley - val - The output sequence value 5196f4d763aaSMatthew G. Knepley 5197f4d763aaSMatthew G. Knepley Level: intermediate 5198f4d763aaSMatthew G. Knepley 5199f4d763aaSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 5200f4d763aaSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 5201f4d763aaSMatthew G. Knepley 5202f4d763aaSMatthew G. Knepley .seealso: VecView() 5203f4d763aaSMatthew G. Knepley @*/ 5204cdb7a50dSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val) 5205f4d763aaSMatthew G. Knepley { 5206f4d763aaSMatthew G. Knepley PetscFunctionBegin; 5207f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 5208cdb7a50dSMatthew G. Knepley if (num) {PetscValidPointer(num,2); *num = dm->outputSequenceNum;} 5209cdb7a50dSMatthew G. Knepley if (val) {PetscValidPointer(val,3);*val = dm->outputSequenceVal;} 5210f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 5211f4d763aaSMatthew G. Knepley } 5212f4d763aaSMatthew G. Knepley 5213f4d763aaSMatthew G. Knepley /*@ 5214cdb7a50dSMatthew G. Knepley DMSetOutputSequenceNumber - Set the sequence number/value for output 5215f4d763aaSMatthew G. Knepley 5216f4d763aaSMatthew G. Knepley Input Parameters: 5217f4d763aaSMatthew G. Knepley + dm - The original DM 5218cdb7a50dSMatthew G. Knepley . num - The output sequence number 5219cdb7a50dSMatthew G. Knepley - val - The output sequence value 5220f4d763aaSMatthew G. Knepley 5221f4d763aaSMatthew G. Knepley Level: intermediate 5222f4d763aaSMatthew G. Knepley 5223f4d763aaSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 5224f4d763aaSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 5225f4d763aaSMatthew G. Knepley 5226f4d763aaSMatthew G. Knepley .seealso: VecView() 5227f4d763aaSMatthew G. Knepley @*/ 5228cdb7a50dSMatthew G. Knepley PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val) 5229f4d763aaSMatthew G. Knepley { 5230f4d763aaSMatthew G. Knepley PetscFunctionBegin; 5231f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 5232f4d763aaSMatthew G. Knepley dm->outputSequenceNum = num; 5233cdb7a50dSMatthew G. Knepley dm->outputSequenceVal = val; 5234cdb7a50dSMatthew G. Knepley PetscFunctionReturn(0); 5235cdb7a50dSMatthew G. Knepley } 5236cdb7a50dSMatthew G. Knepley 5237cdb7a50dSMatthew G. Knepley /*@C 5238cdb7a50dSMatthew G. Knepley DMOutputSequenceLoad - Retrieve the sequence value from a Viewer 5239cdb7a50dSMatthew G. Knepley 5240cdb7a50dSMatthew G. Knepley Input Parameters: 5241cdb7a50dSMatthew G. Knepley + dm - The original DM 5242cdb7a50dSMatthew G. Knepley . name - The sequence name 5243cdb7a50dSMatthew G. Knepley - num - The output sequence number 5244cdb7a50dSMatthew G. Knepley 5245cdb7a50dSMatthew G. Knepley Output Parameter: 5246cdb7a50dSMatthew G. Knepley . val - The output sequence value 5247cdb7a50dSMatthew G. Knepley 5248cdb7a50dSMatthew G. Knepley Level: intermediate 5249cdb7a50dSMatthew G. Knepley 5250cdb7a50dSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 5251cdb7a50dSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 5252cdb7a50dSMatthew G. Knepley 5253cdb7a50dSMatthew G. Knepley .seealso: DMGetOutputSequenceNumber(), DMSetOutputSequenceNumber(), VecView() 5254cdb7a50dSMatthew G. Knepley @*/ 5255cdb7a50dSMatthew G. Knepley PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val) 5256cdb7a50dSMatthew G. Knepley { 5257cdb7a50dSMatthew G. Knepley PetscBool ishdf5; 5258cdb7a50dSMatthew G. Knepley PetscErrorCode ierr; 5259cdb7a50dSMatthew G. Knepley 5260cdb7a50dSMatthew G. Knepley PetscFunctionBegin; 5261cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 5262cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 5263cdb7a50dSMatthew G. Knepley PetscValidPointer(val,4); 5264cdb7a50dSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 5265cdb7a50dSMatthew G. Knepley if (ishdf5) { 5266cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 5267cdb7a50dSMatthew G. Knepley PetscScalar value; 5268cdb7a50dSMatthew G. Knepley 526939d25373SMatthew G. Knepley ierr = DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer);CHKERRQ(ierr); 52704aeb217fSMatthew G. Knepley *val = PetscRealPart(value); 5271cdb7a50dSMatthew G. Knepley #endif 5272cdb7a50dSMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()"); 5273f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 5274f4d763aaSMatthew G. Knepley } 52758e4ac7eaSMatthew G. Knepley 52768e4ac7eaSMatthew G. Knepley /*@ 52778e4ac7eaSMatthew G. Knepley DMGetUseNatural - Get the flag for creating a mapping to the natural order on distribution 52788e4ac7eaSMatthew G. Knepley 52798e4ac7eaSMatthew G. Knepley Not collective 52808e4ac7eaSMatthew G. Knepley 52818e4ac7eaSMatthew G. Knepley Input Parameter: 52828e4ac7eaSMatthew G. Knepley . dm - The DM 52838e4ac7eaSMatthew G. Knepley 52848e4ac7eaSMatthew G. Knepley Output Parameter: 52858e4ac7eaSMatthew G. Knepley . useNatural - The flag to build the mapping to a natural order during distribution 52868e4ac7eaSMatthew G. Knepley 52878e4ac7eaSMatthew G. Knepley Level: beginner 52888e4ac7eaSMatthew G. Knepley 52898e4ac7eaSMatthew G. Knepley .seealso: DMSetUseNatural(), DMCreate() 52908e4ac7eaSMatthew G. Knepley @*/ 52918e4ac7eaSMatthew G. Knepley PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural) 52928e4ac7eaSMatthew G. Knepley { 52938e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 52948e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 52958e4ac7eaSMatthew G. Knepley PetscValidPointer(useNatural, 2); 52968e4ac7eaSMatthew G. Knepley *useNatural = dm->useNatural; 52978e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 52988e4ac7eaSMatthew G. Knepley } 52998e4ac7eaSMatthew G. Knepley 53008e4ac7eaSMatthew G. Knepley /*@ 53018e4ac7eaSMatthew G. Knepley DMSetUseNatural - Set the flag for creating a mapping to the natural order on distribution 53028e4ac7eaSMatthew G. Knepley 53038e4ac7eaSMatthew G. Knepley Collective on dm 53048e4ac7eaSMatthew G. Knepley 53058e4ac7eaSMatthew G. Knepley Input Parameters: 53068e4ac7eaSMatthew G. Knepley + dm - The DM 53078e4ac7eaSMatthew G. Knepley - useNatural - The flag to build the mapping to a natural order during distribution 53088e4ac7eaSMatthew G. Knepley 53098e4ac7eaSMatthew G. Knepley Level: beginner 53108e4ac7eaSMatthew G. Knepley 53118e4ac7eaSMatthew G. Knepley .seealso: DMGetUseNatural(), DMCreate() 53128e4ac7eaSMatthew G. Knepley @*/ 53138e4ac7eaSMatthew G. Knepley PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural) 53148e4ac7eaSMatthew G. Knepley { 53158e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 53168e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 53178833efb5SBlaise Bourdin PetscValidLogicalCollectiveBool(dm, useNatural, 2); 53188e4ac7eaSMatthew G. Knepley dm->useNatural = useNatural; 53198e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 53208e4ac7eaSMatthew G. Knepley } 5321c58f1c22SToby Isaac 5322c58f1c22SToby Isaac 5323c58f1c22SToby Isaac /*@C 5324c58f1c22SToby Isaac DMCreateLabel - Create a label of the given name if it does not already exist 5325c58f1c22SToby Isaac 5326c58f1c22SToby Isaac Not Collective 5327c58f1c22SToby Isaac 5328c58f1c22SToby Isaac Input Parameters: 5329c58f1c22SToby Isaac + dm - The DM object 5330c58f1c22SToby Isaac - name - The label name 5331c58f1c22SToby Isaac 5332c58f1c22SToby Isaac Level: intermediate 5333c58f1c22SToby Isaac 5334c58f1c22SToby Isaac .keywords: mesh 5335c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5336c58f1c22SToby Isaac @*/ 5337c58f1c22SToby Isaac PetscErrorCode DMCreateLabel(DM dm, const char name[]) 5338c58f1c22SToby Isaac { 5339c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5340c58f1c22SToby Isaac PetscBool flg = PETSC_FALSE; 5341c58f1c22SToby Isaac PetscErrorCode ierr; 5342c58f1c22SToby Isaac 5343c58f1c22SToby Isaac PetscFunctionBegin; 5344c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5345c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5346c58f1c22SToby Isaac while (next) { 5347c58f1c22SToby Isaac ierr = PetscStrcmp(name, next->label->name, &flg);CHKERRQ(ierr); 5348c58f1c22SToby Isaac if (flg) break; 5349c58f1c22SToby Isaac next = next->next; 5350c58f1c22SToby Isaac } 5351c58f1c22SToby Isaac if (!flg) { 5352c58f1c22SToby Isaac DMLabelLink tmpLabel; 5353c58f1c22SToby Isaac 5354c58f1c22SToby Isaac ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr); 5355c58f1c22SToby Isaac ierr = DMLabelCreate(name, &tmpLabel->label);CHKERRQ(ierr); 5356c58f1c22SToby Isaac tmpLabel->output = PETSC_TRUE; 5357c58f1c22SToby Isaac tmpLabel->next = dm->labels->next; 5358c58f1c22SToby Isaac dm->labels->next = tmpLabel; 5359c58f1c22SToby Isaac } 5360c58f1c22SToby Isaac PetscFunctionReturn(0); 5361c58f1c22SToby Isaac } 5362c58f1c22SToby Isaac 5363c58f1c22SToby Isaac /*@C 5364c58f1c22SToby Isaac DMGetLabelValue - Get the value in a Sieve Label for the given point, with 0 as the default 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 - point - The mesh point 5372c58f1c22SToby Isaac 5373c58f1c22SToby Isaac Output Parameter: 5374c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label 5375c58f1c22SToby Isaac 5376c58f1c22SToby Isaac Level: beginner 5377c58f1c22SToby Isaac 5378c58f1c22SToby Isaac .keywords: mesh 5379c58f1c22SToby Isaac .seealso: DMLabelGetValue(), DMSetLabelValue(), DMGetStratumIS() 5380c58f1c22SToby Isaac @*/ 5381c58f1c22SToby Isaac PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value) 5382c58f1c22SToby Isaac { 5383c58f1c22SToby Isaac DMLabel label; 5384c58f1c22SToby Isaac PetscErrorCode ierr; 5385c58f1c22SToby Isaac 5386c58f1c22SToby Isaac PetscFunctionBegin; 5387c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5388c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5389c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 539013903a91SSatish Balay if (!label) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name); 5391c58f1c22SToby Isaac ierr = DMLabelGetValue(label, point, value);CHKERRQ(ierr); 5392c58f1c22SToby Isaac PetscFunctionReturn(0); 5393c58f1c22SToby Isaac } 5394c58f1c22SToby Isaac 5395c58f1c22SToby Isaac /*@C 5396c58f1c22SToby Isaac DMSetLabelValue - Add a point to a Sieve Label with given value 5397c58f1c22SToby Isaac 5398c58f1c22SToby Isaac Not Collective 5399c58f1c22SToby Isaac 5400c58f1c22SToby Isaac Input Parameters: 5401c58f1c22SToby Isaac + dm - The DM object 5402c58f1c22SToby Isaac . name - The label name 5403c58f1c22SToby Isaac . point - The mesh point 5404c58f1c22SToby Isaac - value - The label value for this point 5405c58f1c22SToby Isaac 5406c58f1c22SToby Isaac Output Parameter: 5407c58f1c22SToby Isaac 5408c58f1c22SToby Isaac Level: beginner 5409c58f1c22SToby Isaac 5410c58f1c22SToby Isaac .keywords: mesh 5411c58f1c22SToby Isaac .seealso: DMLabelSetValue(), DMGetStratumIS(), DMClearLabelValue() 5412c58f1c22SToby Isaac @*/ 5413c58f1c22SToby Isaac PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 5414c58f1c22SToby Isaac { 5415c58f1c22SToby Isaac DMLabel label; 5416c58f1c22SToby Isaac PetscErrorCode ierr; 5417c58f1c22SToby Isaac 5418c58f1c22SToby Isaac PetscFunctionBegin; 5419c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5420c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5421c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 5422c58f1c22SToby Isaac if (!label) { 5423c58f1c22SToby Isaac ierr = DMCreateLabel(dm, name);CHKERRQ(ierr); 5424c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 5425c58f1c22SToby Isaac } 5426c58f1c22SToby Isaac ierr = DMLabelSetValue(label, point, value);CHKERRQ(ierr); 5427c58f1c22SToby Isaac PetscFunctionReturn(0); 5428c58f1c22SToby Isaac } 5429c58f1c22SToby Isaac 5430c58f1c22SToby Isaac /*@C 5431c58f1c22SToby Isaac DMClearLabelValue - Remove a point from a Sieve Label with given value 5432c58f1c22SToby Isaac 5433c58f1c22SToby Isaac Not Collective 5434c58f1c22SToby Isaac 5435c58f1c22SToby Isaac Input Parameters: 5436c58f1c22SToby Isaac + dm - The DM object 5437c58f1c22SToby Isaac . name - The label name 5438c58f1c22SToby Isaac . point - The mesh point 5439c58f1c22SToby Isaac - value - The label value for this point 5440c58f1c22SToby Isaac 5441c58f1c22SToby Isaac Output Parameter: 5442c58f1c22SToby Isaac 5443c58f1c22SToby Isaac Level: beginner 5444c58f1c22SToby Isaac 5445c58f1c22SToby Isaac .keywords: mesh 5446c58f1c22SToby Isaac .seealso: DMLabelClearValue(), DMSetLabelValue(), DMGetStratumIS() 5447c58f1c22SToby Isaac @*/ 5448c58f1c22SToby Isaac PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 5449c58f1c22SToby Isaac { 5450c58f1c22SToby Isaac DMLabel label; 5451c58f1c22SToby Isaac PetscErrorCode ierr; 5452c58f1c22SToby Isaac 5453c58f1c22SToby Isaac PetscFunctionBegin; 5454c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5455c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5456c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 5457c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 5458c58f1c22SToby Isaac ierr = DMLabelClearValue(label, point, value);CHKERRQ(ierr); 5459c58f1c22SToby Isaac PetscFunctionReturn(0); 5460c58f1c22SToby Isaac } 5461c58f1c22SToby Isaac 5462c58f1c22SToby Isaac /*@C 5463c58f1c22SToby Isaac DMGetLabelSize - Get the number of different integer ids in a Label 5464c58f1c22SToby Isaac 5465c58f1c22SToby Isaac Not Collective 5466c58f1c22SToby Isaac 5467c58f1c22SToby Isaac Input Parameters: 5468c58f1c22SToby Isaac + dm - The DM object 5469c58f1c22SToby Isaac - name - The label name 5470c58f1c22SToby Isaac 5471c58f1c22SToby Isaac Output Parameter: 5472c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist 5473c58f1c22SToby Isaac 5474c58f1c22SToby Isaac Level: beginner 5475c58f1c22SToby Isaac 5476c58f1c22SToby Isaac .keywords: mesh 5477c58f1c22SToby Isaac .seealso: DMLabeGetNumValues(), DMSetLabelValue() 5478c58f1c22SToby Isaac @*/ 5479c58f1c22SToby Isaac PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size) 5480c58f1c22SToby Isaac { 5481c58f1c22SToby Isaac DMLabel label; 5482c58f1c22SToby Isaac PetscErrorCode ierr; 5483c58f1c22SToby Isaac 5484c58f1c22SToby Isaac PetscFunctionBegin; 5485c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5486c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5487c58f1c22SToby Isaac PetscValidPointer(size, 3); 5488c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 5489c58f1c22SToby Isaac *size = 0; 5490c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 5491c58f1c22SToby Isaac ierr = DMLabelGetNumValues(label, size);CHKERRQ(ierr); 5492c58f1c22SToby Isaac PetscFunctionReturn(0); 5493c58f1c22SToby Isaac } 5494c58f1c22SToby Isaac 5495c58f1c22SToby Isaac /*@C 5496c58f1c22SToby Isaac DMGetLabelIdIS - Get the integer ids in a label 5497c58f1c22SToby Isaac 5498c58f1c22SToby Isaac Not Collective 5499c58f1c22SToby Isaac 5500c58f1c22SToby Isaac Input Parameters: 5501c58f1c22SToby Isaac + mesh - The DM object 5502c58f1c22SToby Isaac - name - The label name 5503c58f1c22SToby Isaac 5504c58f1c22SToby Isaac Output Parameter: 5505c58f1c22SToby Isaac . ids - The integer ids, or NULL if the label does not exist 5506c58f1c22SToby Isaac 5507c58f1c22SToby Isaac Level: beginner 5508c58f1c22SToby Isaac 5509c58f1c22SToby Isaac .keywords: mesh 5510c58f1c22SToby Isaac .seealso: DMLabelGetValueIS(), DMGetLabelSize() 5511c58f1c22SToby Isaac @*/ 5512c58f1c22SToby Isaac PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids) 5513c58f1c22SToby Isaac { 5514c58f1c22SToby Isaac DMLabel label; 5515c58f1c22SToby Isaac PetscErrorCode ierr; 5516c58f1c22SToby Isaac 5517c58f1c22SToby Isaac PetscFunctionBegin; 5518c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5519c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5520c58f1c22SToby Isaac PetscValidPointer(ids, 3); 5521c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 5522c58f1c22SToby Isaac *ids = NULL; 5523dab2e251SBlaise Bourdin if (label) { 5524c58f1c22SToby Isaac ierr = DMLabelGetValueIS(label, ids);CHKERRQ(ierr); 5525dab2e251SBlaise Bourdin } else { 5526dab2e251SBlaise Bourdin /* returning an empty IS */ 5527dab2e251SBlaise Bourdin ierr = ISCreateGeneral(PETSC_COMM_SELF,0,NULL,PETSC_USE_POINTER,ids);CHKERRQ(ierr); 5528dab2e251SBlaise Bourdin } 5529c58f1c22SToby Isaac PetscFunctionReturn(0); 5530c58f1c22SToby Isaac } 5531c58f1c22SToby Isaac 5532c58f1c22SToby Isaac /*@C 5533c58f1c22SToby Isaac DMGetStratumSize - Get the number of points in a label stratum 5534c58f1c22SToby Isaac 5535c58f1c22SToby Isaac Not Collective 5536c58f1c22SToby Isaac 5537c58f1c22SToby Isaac Input Parameters: 5538c58f1c22SToby Isaac + dm - The DM object 5539c58f1c22SToby Isaac . name - The label name 5540c58f1c22SToby Isaac - value - The stratum value 5541c58f1c22SToby Isaac 5542c58f1c22SToby Isaac Output Parameter: 5543c58f1c22SToby Isaac . size - The stratum size 5544c58f1c22SToby Isaac 5545c58f1c22SToby Isaac Level: beginner 5546c58f1c22SToby Isaac 5547c58f1c22SToby Isaac .keywords: mesh 5548c58f1c22SToby Isaac .seealso: DMLabelGetStratumSize(), DMGetLabelSize(), DMGetLabelIds() 5549c58f1c22SToby Isaac @*/ 5550c58f1c22SToby Isaac PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size) 5551c58f1c22SToby Isaac { 5552c58f1c22SToby Isaac DMLabel label; 5553c58f1c22SToby Isaac PetscErrorCode ierr; 5554c58f1c22SToby Isaac 5555c58f1c22SToby Isaac PetscFunctionBegin; 5556c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5557c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5558c58f1c22SToby Isaac PetscValidPointer(size, 4); 5559c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 5560c58f1c22SToby Isaac *size = 0; 5561c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 5562c58f1c22SToby Isaac ierr = DMLabelGetStratumSize(label, value, size);CHKERRQ(ierr); 5563c58f1c22SToby Isaac PetscFunctionReturn(0); 5564c58f1c22SToby Isaac } 5565c58f1c22SToby Isaac 5566c58f1c22SToby Isaac /*@C 5567c58f1c22SToby Isaac DMGetStratumIS - Get the points in a label stratum 5568c58f1c22SToby Isaac 5569c58f1c22SToby Isaac Not Collective 5570c58f1c22SToby Isaac 5571c58f1c22SToby Isaac Input Parameters: 5572c58f1c22SToby Isaac + dm - The DM object 5573c58f1c22SToby Isaac . name - The label name 5574c58f1c22SToby Isaac - value - The stratum value 5575c58f1c22SToby Isaac 5576c58f1c22SToby Isaac Output Parameter: 5577c58f1c22SToby Isaac . points - The stratum points, or NULL if the label does not exist or does not have that value 5578c58f1c22SToby Isaac 5579c58f1c22SToby Isaac Level: beginner 5580c58f1c22SToby Isaac 5581c58f1c22SToby Isaac .keywords: mesh 5582c58f1c22SToby Isaac .seealso: DMLabelGetStratumIS(), DMGetStratumSize() 5583c58f1c22SToby Isaac @*/ 5584c58f1c22SToby Isaac PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points) 5585c58f1c22SToby Isaac { 5586c58f1c22SToby Isaac DMLabel label; 5587c58f1c22SToby Isaac PetscErrorCode ierr; 5588c58f1c22SToby Isaac 5589c58f1c22SToby Isaac PetscFunctionBegin; 5590c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5591c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5592c58f1c22SToby Isaac PetscValidPointer(points, 4); 5593c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 5594c58f1c22SToby Isaac *points = NULL; 5595c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 5596c58f1c22SToby Isaac ierr = DMLabelGetStratumIS(label, value, points);CHKERRQ(ierr); 5597c58f1c22SToby Isaac PetscFunctionReturn(0); 5598c58f1c22SToby Isaac } 5599c58f1c22SToby Isaac 56004de306b1SToby Isaac /*@C 56019044fa66SMatthew G. Knepley DMSetStratumIS - Set the points in a label stratum 56024de306b1SToby Isaac 56034de306b1SToby Isaac Not Collective 56044de306b1SToby Isaac 56054de306b1SToby Isaac Input Parameters: 56064de306b1SToby Isaac + dm - The DM object 56074de306b1SToby Isaac . name - The label name 56084de306b1SToby Isaac . value - The stratum value 56094de306b1SToby Isaac - points - The stratum points 56104de306b1SToby Isaac 56114de306b1SToby Isaac Level: beginner 56124de306b1SToby Isaac 56134de306b1SToby Isaac .keywords: mesh 56144de306b1SToby Isaac .seealso: DMLabelSetStratumIS(), DMGetStratumSize() 56154de306b1SToby Isaac @*/ 56164de306b1SToby Isaac PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points) 56174de306b1SToby Isaac { 56184de306b1SToby Isaac DMLabel label; 56194de306b1SToby Isaac PetscErrorCode ierr; 56204de306b1SToby Isaac 56214de306b1SToby Isaac PetscFunctionBegin; 56224de306b1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 56234de306b1SToby Isaac PetscValidCharPointer(name, 2); 56244de306b1SToby Isaac PetscValidPointer(points, 4); 56254de306b1SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 56264de306b1SToby Isaac if (!label) PetscFunctionReturn(0); 56274de306b1SToby Isaac ierr = DMLabelSetStratumIS(label, value, points);CHKERRQ(ierr); 56284de306b1SToby Isaac PetscFunctionReturn(0); 56294de306b1SToby Isaac } 56304de306b1SToby Isaac 5631c58f1c22SToby Isaac /*@C 5632c58f1c22SToby Isaac DMClearLabelStratum - Remove all points from a stratum from a Sieve Label 5633c58f1c22SToby Isaac 5634c58f1c22SToby Isaac Not Collective 5635c58f1c22SToby Isaac 5636c58f1c22SToby Isaac Input Parameters: 5637c58f1c22SToby Isaac + dm - The DM object 5638c58f1c22SToby Isaac . name - The label name 5639c58f1c22SToby Isaac - value - The label value for this point 5640c58f1c22SToby Isaac 5641c58f1c22SToby Isaac Output Parameter: 5642c58f1c22SToby Isaac 5643c58f1c22SToby Isaac Level: beginner 5644c58f1c22SToby Isaac 5645c58f1c22SToby Isaac .keywords: mesh 5646c58f1c22SToby Isaac .seealso: DMLabelClearStratum(), DMSetLabelValue(), DMGetStratumIS(), DMClearLabelValue() 5647c58f1c22SToby Isaac @*/ 5648c58f1c22SToby Isaac PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value) 5649c58f1c22SToby Isaac { 5650c58f1c22SToby Isaac DMLabel label; 5651c58f1c22SToby Isaac PetscErrorCode ierr; 5652c58f1c22SToby Isaac 5653c58f1c22SToby Isaac PetscFunctionBegin; 5654c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5655c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5656c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 5657c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 5658c58f1c22SToby Isaac ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr); 5659c58f1c22SToby Isaac PetscFunctionReturn(0); 5660c58f1c22SToby Isaac } 5661c58f1c22SToby Isaac 5662c58f1c22SToby Isaac /*@ 5663c58f1c22SToby Isaac DMGetNumLabels - Return the number of labels defined by the mesh 5664c58f1c22SToby Isaac 5665c58f1c22SToby Isaac Not Collective 5666c58f1c22SToby Isaac 5667c58f1c22SToby Isaac Input Parameter: 5668c58f1c22SToby Isaac . dm - The DM object 5669c58f1c22SToby Isaac 5670c58f1c22SToby Isaac Output Parameter: 5671c58f1c22SToby Isaac . numLabels - the number of Labels 5672c58f1c22SToby Isaac 5673c58f1c22SToby Isaac Level: intermediate 5674c58f1c22SToby Isaac 5675c58f1c22SToby Isaac .keywords: mesh 5676c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5677c58f1c22SToby Isaac @*/ 5678c58f1c22SToby Isaac PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels) 5679c58f1c22SToby Isaac { 5680c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5681c58f1c22SToby Isaac PetscInt n = 0; 5682c58f1c22SToby Isaac 5683c58f1c22SToby Isaac PetscFunctionBegin; 5684c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5685c58f1c22SToby Isaac PetscValidPointer(numLabels, 2); 5686c58f1c22SToby Isaac while (next) {++n; next = next->next;} 5687c58f1c22SToby Isaac *numLabels = n; 5688c58f1c22SToby Isaac PetscFunctionReturn(0); 5689c58f1c22SToby Isaac } 5690c58f1c22SToby Isaac 5691c58f1c22SToby Isaac /*@C 5692c58f1c22SToby Isaac DMGetLabelName - Return the name of nth label 5693c58f1c22SToby Isaac 5694c58f1c22SToby Isaac Not Collective 5695c58f1c22SToby Isaac 5696c58f1c22SToby Isaac Input Parameters: 5697c58f1c22SToby Isaac + dm - The DM object 5698c58f1c22SToby Isaac - n - the label number 5699c58f1c22SToby Isaac 5700c58f1c22SToby Isaac Output Parameter: 5701c58f1c22SToby Isaac . name - the label name 5702c58f1c22SToby Isaac 5703c58f1c22SToby Isaac Level: intermediate 5704c58f1c22SToby Isaac 5705c58f1c22SToby Isaac .keywords: mesh 5706c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5707c58f1c22SToby Isaac @*/ 5708c58f1c22SToby Isaac PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name) 5709c58f1c22SToby Isaac { 5710c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5711c58f1c22SToby Isaac PetscInt l = 0; 5712c58f1c22SToby Isaac 5713c58f1c22SToby Isaac PetscFunctionBegin; 5714c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5715c58f1c22SToby Isaac PetscValidPointer(name, 3); 5716c58f1c22SToby Isaac while (next) { 5717c58f1c22SToby Isaac if (l == n) { 5718c58f1c22SToby Isaac *name = next->label->name; 5719c58f1c22SToby Isaac PetscFunctionReturn(0); 5720c58f1c22SToby Isaac } 5721c58f1c22SToby Isaac ++l; 5722c58f1c22SToby Isaac next = next->next; 5723c58f1c22SToby Isaac } 5724c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n); 5725c58f1c22SToby Isaac } 5726c58f1c22SToby Isaac 5727c58f1c22SToby Isaac /*@C 5728c58f1c22SToby Isaac DMHasLabel - Determine whether the mesh has a label of a given name 5729c58f1c22SToby Isaac 5730c58f1c22SToby Isaac Not Collective 5731c58f1c22SToby Isaac 5732c58f1c22SToby Isaac Input Parameters: 5733c58f1c22SToby Isaac + dm - The DM object 5734c58f1c22SToby Isaac - name - The label name 5735c58f1c22SToby Isaac 5736c58f1c22SToby Isaac Output Parameter: 5737c58f1c22SToby Isaac . hasLabel - PETSC_TRUE if the label is present 5738c58f1c22SToby Isaac 5739c58f1c22SToby Isaac Level: intermediate 5740c58f1c22SToby Isaac 5741c58f1c22SToby Isaac .keywords: mesh 5742c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5743c58f1c22SToby Isaac @*/ 5744c58f1c22SToby Isaac PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel) 5745c58f1c22SToby Isaac { 5746c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5747c58f1c22SToby Isaac PetscErrorCode ierr; 5748c58f1c22SToby Isaac 5749c58f1c22SToby Isaac PetscFunctionBegin; 5750c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5751c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5752c58f1c22SToby Isaac PetscValidPointer(hasLabel, 3); 5753c58f1c22SToby Isaac *hasLabel = PETSC_FALSE; 5754c58f1c22SToby Isaac while (next) { 5755c58f1c22SToby Isaac ierr = PetscStrcmp(name, next->label->name, hasLabel);CHKERRQ(ierr); 5756c58f1c22SToby Isaac if (*hasLabel) break; 5757c58f1c22SToby Isaac next = next->next; 5758c58f1c22SToby Isaac } 5759c58f1c22SToby Isaac PetscFunctionReturn(0); 5760c58f1c22SToby Isaac } 5761c58f1c22SToby Isaac 5762c58f1c22SToby Isaac /*@C 5763c58f1c22SToby Isaac DMGetLabel - Return the label of a given name, or NULL 5764c58f1c22SToby Isaac 5765c58f1c22SToby Isaac Not Collective 5766c58f1c22SToby Isaac 5767c58f1c22SToby Isaac Input Parameters: 5768c58f1c22SToby Isaac + dm - The DM object 5769c58f1c22SToby Isaac - name - The label name 5770c58f1c22SToby Isaac 5771c58f1c22SToby Isaac Output Parameter: 5772c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent 5773c58f1c22SToby Isaac 5774c58f1c22SToby Isaac Level: intermediate 5775c58f1c22SToby Isaac 5776c58f1c22SToby Isaac .keywords: mesh 5777c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5778c58f1c22SToby Isaac @*/ 5779c58f1c22SToby Isaac PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label) 5780c58f1c22SToby Isaac { 5781c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5782c58f1c22SToby Isaac PetscBool hasLabel; 5783c58f1c22SToby Isaac PetscErrorCode ierr; 5784c58f1c22SToby Isaac 5785c58f1c22SToby Isaac PetscFunctionBegin; 5786c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5787c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 5788c58f1c22SToby Isaac PetscValidPointer(label, 3); 5789c58f1c22SToby Isaac *label = NULL; 5790c58f1c22SToby Isaac while (next) { 5791c58f1c22SToby Isaac ierr = PetscStrcmp(name, next->label->name, &hasLabel);CHKERRQ(ierr); 5792c58f1c22SToby Isaac if (hasLabel) { 5793c58f1c22SToby Isaac *label = next->label; 5794c58f1c22SToby Isaac break; 5795c58f1c22SToby Isaac } 5796c58f1c22SToby Isaac next = next->next; 5797c58f1c22SToby Isaac } 5798c58f1c22SToby Isaac PetscFunctionReturn(0); 5799c58f1c22SToby Isaac } 5800c58f1c22SToby Isaac 5801c58f1c22SToby Isaac /*@C 5802c58f1c22SToby Isaac DMGetLabelByNum - Return the nth label 5803c58f1c22SToby Isaac 5804c58f1c22SToby Isaac Not Collective 5805c58f1c22SToby Isaac 5806c58f1c22SToby Isaac Input Parameters: 5807c58f1c22SToby Isaac + dm - The DM object 5808c58f1c22SToby Isaac - n - the label number 5809c58f1c22SToby Isaac 5810c58f1c22SToby Isaac Output Parameter: 5811c58f1c22SToby Isaac . label - the label 5812c58f1c22SToby Isaac 5813c58f1c22SToby Isaac Level: intermediate 5814c58f1c22SToby Isaac 5815c58f1c22SToby Isaac .keywords: mesh 5816c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5817c58f1c22SToby Isaac @*/ 5818c58f1c22SToby Isaac PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label) 5819c58f1c22SToby Isaac { 5820c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5821c58f1c22SToby Isaac PetscInt l = 0; 5822c58f1c22SToby Isaac 5823c58f1c22SToby Isaac PetscFunctionBegin; 5824c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5825c58f1c22SToby Isaac PetscValidPointer(label, 3); 5826c58f1c22SToby Isaac while (next) { 5827c58f1c22SToby Isaac if (l == n) { 5828c58f1c22SToby Isaac *label = next->label; 5829c58f1c22SToby Isaac PetscFunctionReturn(0); 5830c58f1c22SToby Isaac } 5831c58f1c22SToby Isaac ++l; 5832c58f1c22SToby Isaac next = next->next; 5833c58f1c22SToby Isaac } 5834c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n); 5835c58f1c22SToby Isaac } 5836c58f1c22SToby Isaac 5837c58f1c22SToby Isaac /*@C 5838c58f1c22SToby Isaac DMAddLabel - Add the label to this mesh 5839c58f1c22SToby Isaac 5840c58f1c22SToby Isaac Not Collective 5841c58f1c22SToby Isaac 5842c58f1c22SToby Isaac Input Parameters: 5843c58f1c22SToby Isaac + dm - The DM object 5844c58f1c22SToby Isaac - label - The DMLabel 5845c58f1c22SToby Isaac 5846c58f1c22SToby Isaac Level: developer 5847c58f1c22SToby Isaac 5848c58f1c22SToby Isaac .keywords: mesh 5849c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5850c58f1c22SToby Isaac @*/ 5851c58f1c22SToby Isaac PetscErrorCode DMAddLabel(DM dm, DMLabel label) 5852c58f1c22SToby Isaac { 5853c58f1c22SToby Isaac DMLabelLink tmpLabel; 5854c58f1c22SToby Isaac PetscBool hasLabel; 5855c58f1c22SToby Isaac PetscErrorCode ierr; 5856c58f1c22SToby Isaac 5857c58f1c22SToby Isaac PetscFunctionBegin; 5858c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5859c58f1c22SToby Isaac ierr = DMHasLabel(dm, label->name, &hasLabel);CHKERRQ(ierr); 5860c58f1c22SToby Isaac if (hasLabel) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", label->name); 5861c58f1c22SToby Isaac ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr); 5862c58f1c22SToby Isaac tmpLabel->label = label; 5863c58f1c22SToby Isaac tmpLabel->output = PETSC_TRUE; 5864c58f1c22SToby Isaac tmpLabel->next = dm->labels->next; 5865c58f1c22SToby Isaac dm->labels->next = tmpLabel; 5866c58f1c22SToby Isaac PetscFunctionReturn(0); 5867c58f1c22SToby Isaac } 5868c58f1c22SToby Isaac 5869c58f1c22SToby Isaac /*@C 5870c58f1c22SToby Isaac DMRemoveLabel - Remove the label from this mesh 5871c58f1c22SToby Isaac 5872c58f1c22SToby Isaac Not Collective 5873c58f1c22SToby Isaac 5874c58f1c22SToby Isaac Input Parameters: 5875c58f1c22SToby Isaac + dm - The DM object 5876c58f1c22SToby Isaac - name - The label name 5877c58f1c22SToby Isaac 5878c58f1c22SToby Isaac Output Parameter: 5879c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent 5880c58f1c22SToby Isaac 5881c58f1c22SToby Isaac Level: developer 5882c58f1c22SToby Isaac 5883c58f1c22SToby Isaac .keywords: mesh 5884c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5885c58f1c22SToby Isaac @*/ 5886c58f1c22SToby Isaac PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label) 5887c58f1c22SToby Isaac { 5888c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5889c58f1c22SToby Isaac DMLabelLink last = NULL; 5890c58f1c22SToby Isaac PetscBool hasLabel; 5891c58f1c22SToby Isaac PetscErrorCode ierr; 5892c58f1c22SToby Isaac 5893c58f1c22SToby Isaac PetscFunctionBegin; 5894c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5895c58f1c22SToby Isaac ierr = DMHasLabel(dm, name, &hasLabel);CHKERRQ(ierr); 5896c58f1c22SToby Isaac *label = NULL; 5897c58f1c22SToby Isaac if (!hasLabel) PetscFunctionReturn(0); 5898c58f1c22SToby Isaac while (next) { 5899c58f1c22SToby Isaac ierr = PetscStrcmp(name, next->label->name, &hasLabel);CHKERRQ(ierr); 5900c58f1c22SToby Isaac if (hasLabel) { 5901c58f1c22SToby Isaac if (last) last->next = next->next; 5902c58f1c22SToby Isaac else dm->labels->next = next->next; 5903c58f1c22SToby Isaac next->next = NULL; 5904c58f1c22SToby Isaac *label = next->label; 5905c58f1c22SToby Isaac ierr = PetscStrcmp(name, "depth", &hasLabel);CHKERRQ(ierr); 5906c58f1c22SToby Isaac if (hasLabel) { 5907c58f1c22SToby Isaac dm->depthLabel = NULL; 5908c58f1c22SToby Isaac } 5909c58f1c22SToby Isaac ierr = PetscFree(next);CHKERRQ(ierr); 5910c58f1c22SToby Isaac break; 5911c58f1c22SToby Isaac } 5912c58f1c22SToby Isaac last = next; 5913c58f1c22SToby Isaac next = next->next; 5914c58f1c22SToby Isaac } 5915c58f1c22SToby Isaac PetscFunctionReturn(0); 5916c58f1c22SToby Isaac } 5917c58f1c22SToby Isaac 5918c58f1c22SToby Isaac /*@C 5919c58f1c22SToby Isaac DMGetLabelOutput - Get the output flag for a given label 5920c58f1c22SToby Isaac 5921c58f1c22SToby Isaac Not Collective 5922c58f1c22SToby Isaac 5923c58f1c22SToby Isaac Input Parameters: 5924c58f1c22SToby Isaac + dm - The DM object 5925c58f1c22SToby Isaac - name - The label name 5926c58f1c22SToby Isaac 5927c58f1c22SToby Isaac Output Parameter: 5928c58f1c22SToby Isaac . output - The flag for output 5929c58f1c22SToby Isaac 5930c58f1c22SToby Isaac Level: developer 5931c58f1c22SToby Isaac 5932c58f1c22SToby Isaac .keywords: mesh 5933c58f1c22SToby Isaac .seealso: DMSetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5934c58f1c22SToby Isaac @*/ 5935c58f1c22SToby Isaac PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output) 5936c58f1c22SToby Isaac { 5937c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5938c58f1c22SToby Isaac PetscErrorCode ierr; 5939c58f1c22SToby Isaac 5940c58f1c22SToby Isaac PetscFunctionBegin; 5941c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5942c58f1c22SToby Isaac PetscValidPointer(name, 2); 5943c58f1c22SToby Isaac PetscValidPointer(output, 3); 5944c58f1c22SToby Isaac while (next) { 5945c58f1c22SToby Isaac PetscBool flg; 5946c58f1c22SToby Isaac 5947c58f1c22SToby Isaac ierr = PetscStrcmp(name, next->label->name, &flg);CHKERRQ(ierr); 5948c58f1c22SToby Isaac if (flg) {*output = next->output; PetscFunctionReturn(0);} 5949c58f1c22SToby Isaac next = next->next; 5950c58f1c22SToby Isaac } 5951c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 5952c58f1c22SToby Isaac } 5953c58f1c22SToby Isaac 5954c58f1c22SToby Isaac /*@C 5955c58f1c22SToby Isaac DMSetLabelOutput - Set the output flag for a given label 5956c58f1c22SToby Isaac 5957c58f1c22SToby Isaac Not Collective 5958c58f1c22SToby Isaac 5959c58f1c22SToby Isaac Input Parameters: 5960c58f1c22SToby Isaac + dm - The DM object 5961c58f1c22SToby Isaac . name - The label name 5962c58f1c22SToby Isaac - output - The flag for output 5963c58f1c22SToby Isaac 5964c58f1c22SToby Isaac Level: developer 5965c58f1c22SToby Isaac 5966c58f1c22SToby Isaac .keywords: mesh 5967c58f1c22SToby Isaac .seealso: DMGetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 5968c58f1c22SToby Isaac @*/ 5969c58f1c22SToby Isaac PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output) 5970c58f1c22SToby Isaac { 5971c58f1c22SToby Isaac DMLabelLink next = dm->labels->next; 5972c58f1c22SToby Isaac PetscErrorCode ierr; 5973c58f1c22SToby Isaac 5974c58f1c22SToby Isaac PetscFunctionBegin; 5975c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5976c58f1c22SToby Isaac PetscValidPointer(name, 2); 5977c58f1c22SToby Isaac while (next) { 5978c58f1c22SToby Isaac PetscBool flg; 5979c58f1c22SToby Isaac 5980c58f1c22SToby Isaac ierr = PetscStrcmp(name, next->label->name, &flg);CHKERRQ(ierr); 5981c58f1c22SToby Isaac if (flg) {next->output = output; PetscFunctionReturn(0);} 5982c58f1c22SToby Isaac next = next->next; 5983c58f1c22SToby Isaac } 5984c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 5985c58f1c22SToby Isaac } 5986c58f1c22SToby Isaac 5987c58f1c22SToby Isaac 5988c58f1c22SToby Isaac /*@ 5989c58f1c22SToby Isaac DMCopyLabels - Copy labels from one mesh to another with a superset of the points 5990c58f1c22SToby Isaac 5991c58f1c22SToby Isaac Collective on DM 5992c58f1c22SToby Isaac 5993c58f1c22SToby Isaac Input Parameter: 59942e17dfb7SMatthew G. Knepley . dmA - The DM object with initial labels 5995c58f1c22SToby Isaac 5996c58f1c22SToby Isaac Output Parameter: 59972e17dfb7SMatthew G. Knepley . dmB - The DM object with copied labels 5998c58f1c22SToby Isaac 5999c58f1c22SToby Isaac Level: intermediate 6000c58f1c22SToby Isaac 6001c58f1c22SToby Isaac Note: This is typically used when interpolating or otherwise adding to a mesh 6002c58f1c22SToby Isaac 6003c58f1c22SToby Isaac .keywords: mesh 6004c58f1c22SToby Isaac .seealso: DMCopyCoordinates(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMGetCoordinateSection() 6005c58f1c22SToby Isaac @*/ 6006c58f1c22SToby Isaac PetscErrorCode DMCopyLabels(DM dmA, DM dmB) 6007c58f1c22SToby Isaac { 6008c58f1c22SToby Isaac PetscInt numLabels, l; 6009c58f1c22SToby Isaac PetscErrorCode ierr; 6010c58f1c22SToby Isaac 6011c58f1c22SToby Isaac PetscFunctionBegin; 6012c58f1c22SToby Isaac if (dmA == dmB) PetscFunctionReturn(0); 6013c58f1c22SToby Isaac ierr = DMGetNumLabels(dmA, &numLabels);CHKERRQ(ierr); 6014c58f1c22SToby Isaac for (l = 0; l < numLabels; ++l) { 6015c58f1c22SToby Isaac DMLabel label, labelNew; 6016c58f1c22SToby Isaac const char *name; 6017c58f1c22SToby Isaac PetscBool flg; 6018c58f1c22SToby Isaac 6019c58f1c22SToby Isaac ierr = DMGetLabelName(dmA, l, &name);CHKERRQ(ierr); 6020c58f1c22SToby Isaac ierr = PetscStrcmp(name, "depth", &flg);CHKERRQ(ierr); 6021c58f1c22SToby Isaac if (flg) continue; 60227d5acc75SStefano Zampini ierr = PetscStrcmp(name, "dim", &flg);CHKERRQ(ierr); 60237d5acc75SStefano Zampini if (flg) continue; 6024c58f1c22SToby Isaac ierr = DMGetLabel(dmA, name, &label);CHKERRQ(ierr); 6025c58f1c22SToby Isaac ierr = DMLabelDuplicate(label, &labelNew);CHKERRQ(ierr); 6026c58f1c22SToby Isaac ierr = DMAddLabel(dmB, labelNew);CHKERRQ(ierr); 6027c58f1c22SToby Isaac } 6028c58f1c22SToby Isaac PetscFunctionReturn(0); 6029c58f1c22SToby Isaac } 6030a8fb8f29SToby Isaac 6031a8fb8f29SToby Isaac /*@ 6032a8fb8f29SToby Isaac DMGetCoarseDM - Get the coarse mesh from which this was obtained by refinement 6033a8fb8f29SToby Isaac 6034a8fb8f29SToby Isaac Input Parameter: 6035a8fb8f29SToby Isaac . dm - The DM object 6036a8fb8f29SToby Isaac 6037a8fb8f29SToby Isaac Output Parameter: 6038a8fb8f29SToby Isaac . cdm - The coarse DM 6039a8fb8f29SToby Isaac 6040a8fb8f29SToby Isaac Level: intermediate 6041a8fb8f29SToby Isaac 6042a8fb8f29SToby Isaac .seealso: DMSetCoarseDM() 6043a8fb8f29SToby Isaac @*/ 6044a8fb8f29SToby Isaac PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm) 6045a8fb8f29SToby Isaac { 6046a8fb8f29SToby Isaac PetscFunctionBegin; 6047a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6048a8fb8f29SToby Isaac PetscValidPointer(cdm, 2); 6049a8fb8f29SToby Isaac *cdm = dm->coarseMesh; 6050a8fb8f29SToby Isaac PetscFunctionReturn(0); 6051a8fb8f29SToby Isaac } 6052a8fb8f29SToby Isaac 6053a8fb8f29SToby Isaac /*@ 6054a8fb8f29SToby Isaac DMSetCoarseDM - Set the coarse mesh from which this was obtained by refinement 6055a8fb8f29SToby Isaac 6056a8fb8f29SToby Isaac Input Parameters: 6057a8fb8f29SToby Isaac + dm - The DM object 6058a8fb8f29SToby Isaac - cdm - The coarse DM 6059a8fb8f29SToby Isaac 6060a8fb8f29SToby Isaac Level: intermediate 6061a8fb8f29SToby Isaac 6062a8fb8f29SToby Isaac .seealso: DMGetCoarseDM() 6063a8fb8f29SToby Isaac @*/ 6064a8fb8f29SToby Isaac PetscErrorCode DMSetCoarseDM(DM dm, DM cdm) 6065a8fb8f29SToby Isaac { 6066a8fb8f29SToby Isaac PetscErrorCode ierr; 6067a8fb8f29SToby Isaac 6068a8fb8f29SToby Isaac PetscFunctionBegin; 6069a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6070a8fb8f29SToby Isaac if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 6071a8fb8f29SToby Isaac ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr); 6072a8fb8f29SToby Isaac ierr = DMDestroy(&dm->coarseMesh);CHKERRQ(ierr); 6073a8fb8f29SToby Isaac dm->coarseMesh = cdm; 6074a8fb8f29SToby Isaac PetscFunctionReturn(0); 6075a8fb8f29SToby Isaac } 6076a8fb8f29SToby Isaac 607788bdff64SToby Isaac /*@ 607888bdff64SToby Isaac DMGetFineDM - Get the fine mesh from which this was obtained by refinement 607988bdff64SToby Isaac 608088bdff64SToby Isaac Input Parameter: 608188bdff64SToby Isaac . dm - The DM object 608288bdff64SToby Isaac 608388bdff64SToby Isaac Output Parameter: 608488bdff64SToby Isaac . fdm - The fine DM 608588bdff64SToby Isaac 608688bdff64SToby Isaac Level: intermediate 608788bdff64SToby Isaac 608888bdff64SToby Isaac .seealso: DMSetFineDM() 608988bdff64SToby Isaac @*/ 609088bdff64SToby Isaac PetscErrorCode DMGetFineDM(DM dm, DM *fdm) 609188bdff64SToby Isaac { 609288bdff64SToby Isaac PetscFunctionBegin; 609388bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 609488bdff64SToby Isaac PetscValidPointer(fdm, 2); 609588bdff64SToby Isaac *fdm = dm->fineMesh; 609688bdff64SToby Isaac PetscFunctionReturn(0); 609788bdff64SToby Isaac } 609888bdff64SToby Isaac 609988bdff64SToby Isaac /*@ 610088bdff64SToby Isaac DMSetFineDM - Set the fine mesh from which this was obtained by refinement 610188bdff64SToby Isaac 610288bdff64SToby Isaac Input Parameters: 610388bdff64SToby Isaac + dm - The DM object 610488bdff64SToby Isaac - fdm - The fine DM 610588bdff64SToby Isaac 610688bdff64SToby Isaac Level: intermediate 610788bdff64SToby Isaac 610888bdff64SToby Isaac .seealso: DMGetFineDM() 610988bdff64SToby Isaac @*/ 611088bdff64SToby Isaac PetscErrorCode DMSetFineDM(DM dm, DM fdm) 611188bdff64SToby Isaac { 611288bdff64SToby Isaac PetscErrorCode ierr; 611388bdff64SToby Isaac 611488bdff64SToby Isaac PetscFunctionBegin; 611588bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 611688bdff64SToby Isaac if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2); 611788bdff64SToby Isaac ierr = PetscObjectReference((PetscObject)fdm);CHKERRQ(ierr); 611888bdff64SToby Isaac ierr = DMDestroy(&dm->fineMesh);CHKERRQ(ierr); 611988bdff64SToby Isaac dm->fineMesh = fdm; 612088bdff64SToby Isaac PetscFunctionReturn(0); 612188bdff64SToby Isaac } 612288bdff64SToby Isaac 6123a6ba4734SToby Isaac /*=== DMBoundary code ===*/ 6124a6ba4734SToby Isaac 6125a6ba4734SToby Isaac PetscErrorCode DMCopyBoundary(DM dm, DM dmNew) 6126a6ba4734SToby Isaac { 6127a6ba4734SToby Isaac PetscErrorCode ierr; 6128a6ba4734SToby Isaac 6129a6ba4734SToby Isaac PetscFunctionBegin; 6130e6f8dbb6SToby Isaac ierr = PetscDSCopyBoundary(dm->prob,dmNew->prob);CHKERRQ(ierr); 6131a6ba4734SToby Isaac PetscFunctionReturn(0); 6132a6ba4734SToby Isaac } 6133a6ba4734SToby Isaac 6134a6ba4734SToby Isaac /*@C 6135a6ba4734SToby Isaac DMAddBoundary - Add a boundary condition to the model 6136a6ba4734SToby Isaac 6137a6ba4734SToby Isaac Input Parameters: 61384c258f51SMatthew G. Knepley + dm - The DM, with a PetscDS that matches the problem being constrained 6139f971fd6bSMatthew G. Knepley . type - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann) 6140a6ba4734SToby Isaac . name - The BC name 6141a6ba4734SToby Isaac . labelname - The label defining constrained points 6142a6ba4734SToby Isaac . field - The field to constrain 6143a6ba4734SToby Isaac . numcomps - The number of constrained field components 6144a6ba4734SToby Isaac . comps - An array of constrained component numbers 6145a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 6146a6ba4734SToby Isaac . numids - The number of DMLabel ids for constrained points 6147a6ba4734SToby Isaac . ids - An array of ids for constrained points 6148a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 6149a6ba4734SToby Isaac 6150a6ba4734SToby Isaac Options Database Keys: 6151a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 6152a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 6153a6ba4734SToby Isaac 6154a6ba4734SToby Isaac Level: developer 6155a6ba4734SToby Isaac 6156a6ba4734SToby Isaac .seealso: DMGetBoundary() 6157a6ba4734SToby Isaac @*/ 6158a30ec4eaSSatish 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) 6159a6ba4734SToby Isaac { 6160a6ba4734SToby Isaac PetscErrorCode ierr; 6161a6ba4734SToby Isaac 6162a6ba4734SToby Isaac PetscFunctionBegin; 6163a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6164f971fd6bSMatthew G. Knepley ierr = PetscDSAddBoundary(dm->prob,type,name,labelname,field,numcomps,comps,bcFunc,numids,ids,ctx);CHKERRQ(ierr); 6165a6ba4734SToby Isaac PetscFunctionReturn(0); 6166a6ba4734SToby Isaac } 6167a6ba4734SToby Isaac 6168a6ba4734SToby Isaac /*@ 6169a6ba4734SToby Isaac DMGetNumBoundary - Get the number of registered BC 6170a6ba4734SToby Isaac 6171a6ba4734SToby Isaac Input Parameters: 6172a6ba4734SToby Isaac . dm - The mesh object 6173a6ba4734SToby Isaac 6174a6ba4734SToby Isaac Output Parameters: 6175a6ba4734SToby Isaac . numBd - The number of BC 6176a6ba4734SToby Isaac 6177a6ba4734SToby Isaac Level: intermediate 6178a6ba4734SToby Isaac 6179a6ba4734SToby Isaac .seealso: DMAddBoundary(), DMGetBoundary() 6180a6ba4734SToby Isaac @*/ 6181a6ba4734SToby Isaac PetscErrorCode DMGetNumBoundary(DM dm, PetscInt *numBd) 6182a6ba4734SToby Isaac { 618358ebd649SToby Isaac PetscErrorCode ierr; 6184a6ba4734SToby Isaac 6185a6ba4734SToby Isaac PetscFunctionBegin; 6186a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 618758ebd649SToby Isaac ierr = PetscDSGetNumBoundary(dm->prob,numBd);CHKERRQ(ierr); 6188a6ba4734SToby Isaac PetscFunctionReturn(0); 6189a6ba4734SToby Isaac } 6190a6ba4734SToby Isaac 6191a6ba4734SToby Isaac /*@C 61921c531cf8SMatthew G. Knepley DMGetBoundary - Get a model boundary condition 6193a6ba4734SToby Isaac 6194a6ba4734SToby Isaac Input Parameters: 6195a6ba4734SToby Isaac + dm - The mesh object 6196a6ba4734SToby Isaac - bd - The BC number 6197a6ba4734SToby Isaac 6198a6ba4734SToby Isaac Output Parameters: 6199f971fd6bSMatthew G. Knepley + type - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann) 6200a6ba4734SToby Isaac . name - The BC name 6201a6ba4734SToby Isaac . labelname - The label defining constrained points 6202a6ba4734SToby Isaac . field - The field to constrain 6203a6ba4734SToby Isaac . numcomps - The number of constrained field components 6204a6ba4734SToby Isaac . comps - An array of constrained component numbers 6205a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 6206a6ba4734SToby Isaac . numids - The number of DMLabel ids for constrained points 6207a6ba4734SToby Isaac . ids - An array of ids for constrained points 6208a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 6209a6ba4734SToby Isaac 6210a6ba4734SToby Isaac Options Database Keys: 6211a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 6212a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 6213a6ba4734SToby Isaac 6214a6ba4734SToby Isaac Level: developer 6215a6ba4734SToby Isaac 6216a6ba4734SToby Isaac .seealso: DMAddBoundary() 6217a6ba4734SToby Isaac @*/ 6218a30ec4eaSSatish 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) 6219a6ba4734SToby Isaac { 622058ebd649SToby Isaac PetscErrorCode ierr; 6221a6ba4734SToby Isaac 6222a6ba4734SToby Isaac PetscFunctionBegin; 6223a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6224f971fd6bSMatthew G. Knepley ierr = PetscDSGetBoundary(dm->prob,bd,type,name,labelname,field,numcomps,comps,func,numids,ids,ctx);CHKERRQ(ierr); 6225a6ba4734SToby Isaac PetscFunctionReturn(0); 6226a6ba4734SToby Isaac } 6227a6ba4734SToby Isaac 6228e6f8dbb6SToby Isaac static PetscErrorCode DMPopulateBoundary(DM dm) 6229e6f8dbb6SToby Isaac { 6230dff059c6SToby Isaac DMBoundary *lastnext; 6231e6f8dbb6SToby Isaac DSBoundary dsbound; 6232e6f8dbb6SToby Isaac PetscErrorCode ierr; 6233e6f8dbb6SToby Isaac 6234e6f8dbb6SToby Isaac PetscFunctionBegin; 6235e6f8dbb6SToby Isaac dsbound = dm->prob->boundary; 623647a1f5adSToby Isaac if (dm->boundary) { 623747a1f5adSToby Isaac DMBoundary next = dm->boundary; 623847a1f5adSToby Isaac 623947a1f5adSToby Isaac /* quick check to see if the PetscDS has changed */ 624047a1f5adSToby Isaac if (next->dsboundary == dsbound) PetscFunctionReturn(0); 624147a1f5adSToby Isaac /* the PetscDS has changed: tear down and rebuild */ 624247a1f5adSToby Isaac while (next) { 624347a1f5adSToby Isaac DMBoundary b = next; 624447a1f5adSToby Isaac 624547a1f5adSToby Isaac next = b->next; 624647a1f5adSToby Isaac ierr = PetscFree(b);CHKERRQ(ierr); 6247a6ba4734SToby Isaac } 624847a1f5adSToby Isaac dm->boundary = NULL; 6249a6ba4734SToby Isaac } 625047a1f5adSToby Isaac 6251dff059c6SToby Isaac lastnext = &(dm->boundary); 6252e6f8dbb6SToby Isaac while (dsbound) { 6253e6f8dbb6SToby Isaac DMBoundary dmbound; 6254e6f8dbb6SToby Isaac 6255e6f8dbb6SToby Isaac ierr = PetscNew(&dmbound);CHKERRQ(ierr); 6256e6f8dbb6SToby Isaac dmbound->dsboundary = dsbound; 6257e6f8dbb6SToby Isaac ierr = DMGetLabel(dm, dsbound->labelname, &(dmbound->label));CHKERRQ(ierr); 6258994fe344SLisandro Dalcin if (!dmbound->label) {ierr = PetscInfo2(dm, "DSBoundary %s wants label %s, which is not in this dm.\n",dsbound->name,dsbound->labelname);CHKERRQ(ierr);} 625947a1f5adSToby Isaac /* push on the back instead of the front so that it is in the same order as in the PetscDS */ 6260dff059c6SToby Isaac *lastnext = dmbound; 6261dff059c6SToby Isaac lastnext = &(dmbound->next); 6262dff059c6SToby Isaac dsbound = dsbound->next; 6263a6ba4734SToby Isaac } 6264a6ba4734SToby Isaac PetscFunctionReturn(0); 6265a6ba4734SToby Isaac } 6266a6ba4734SToby Isaac 6267a6ba4734SToby Isaac PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd) 6268a6ba4734SToby Isaac { 6269b95f2879SToby Isaac DMBoundary b; 6270a6ba4734SToby Isaac PetscErrorCode ierr; 6271a6ba4734SToby Isaac 6272a6ba4734SToby Isaac PetscFunctionBegin; 6273a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6274a6ba4734SToby Isaac PetscValidPointer(isBd, 3); 6275a6ba4734SToby Isaac *isBd = PETSC_FALSE; 6276e6f8dbb6SToby Isaac ierr = DMPopulateBoundary(dm);CHKERRQ(ierr); 6277b95f2879SToby Isaac b = dm->boundary; 6278a6ba4734SToby Isaac while (b && !(*isBd)) { 6279e6f8dbb6SToby Isaac DMLabel label = b->label; 6280e6f8dbb6SToby Isaac DSBoundary dsb = b->dsboundary; 62813424c85cSToby Isaac 62823424c85cSToby Isaac if (label) { 6283a6ba4734SToby Isaac PetscInt i; 6284a6ba4734SToby Isaac 6285e6f8dbb6SToby Isaac for (i = 0; i < dsb->numids && !(*isBd); ++i) { 6286e6f8dbb6SToby Isaac ierr = DMLabelStratumHasPoint(label, dsb->ids[i], point, isBd);CHKERRQ(ierr); 6287a6ba4734SToby Isaac } 6288a6ba4734SToby Isaac } 6289a6ba4734SToby Isaac b = b->next; 6290a6ba4734SToby Isaac } 6291a6ba4734SToby Isaac PetscFunctionReturn(0); 6292a6ba4734SToby Isaac } 62934d6f44ffSToby Isaac 62944d6f44ffSToby Isaac /*@C 62954d6f44ffSToby Isaac DMProjectFunction - This projects the given function into the function space provided. 62964d6f44ffSToby Isaac 62974d6f44ffSToby Isaac Input Parameters: 62984d6f44ffSToby Isaac + dm - The DM 62990709b2feSToby Isaac . time - The time 63004d6f44ffSToby Isaac . funcs - The coordinate functions to evaluate, one per field 63014d6f44ffSToby Isaac . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 63024d6f44ffSToby Isaac - mode - The insertion mode for values 63034d6f44ffSToby Isaac 63044d6f44ffSToby Isaac Output Parameter: 63054d6f44ffSToby Isaac . X - vector 63064d6f44ffSToby Isaac 63074d6f44ffSToby Isaac Calling sequence of func: 63080709b2feSToby Isaac $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 63094d6f44ffSToby Isaac 63104d6f44ffSToby Isaac + dim - The spatial dimension 63114d6f44ffSToby Isaac . x - The coordinates 63124d6f44ffSToby Isaac . Nf - The number of fields 63134d6f44ffSToby Isaac . u - The output field values 63144d6f44ffSToby Isaac - ctx - optional user-defined function context 63154d6f44ffSToby Isaac 63164d6f44ffSToby Isaac Level: developer 63174d6f44ffSToby Isaac 63182716604bSToby Isaac .seealso: DMComputeL2Diff() 63194d6f44ffSToby Isaac @*/ 63200709b2feSToby Isaac PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X) 63214d6f44ffSToby Isaac { 63224d6f44ffSToby Isaac Vec localX; 63234d6f44ffSToby Isaac PetscErrorCode ierr; 63244d6f44ffSToby Isaac 63254d6f44ffSToby Isaac PetscFunctionBegin; 63264d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 63274d6f44ffSToby Isaac ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr); 63280709b2feSToby Isaac ierr = DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr); 63294d6f44ffSToby Isaac ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr); 63304d6f44ffSToby Isaac ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr); 63314d6f44ffSToby Isaac ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr); 63324d6f44ffSToby Isaac PetscFunctionReturn(0); 63334d6f44ffSToby Isaac } 63344d6f44ffSToby Isaac 63350709b2feSToby Isaac PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 63364d6f44ffSToby Isaac { 63374d6f44ffSToby Isaac PetscErrorCode ierr; 63384d6f44ffSToby Isaac 63394d6f44ffSToby Isaac PetscFunctionBegin; 63404d6f44ffSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 63414d6f44ffSToby Isaac PetscValidHeaderSpecific(localX,VEC_CLASSID,5); 63420918c465SMatthew G. Knepley if (!dm->ops->projectfunctionlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLocal",((PetscObject)dm)->type_name); 63430709b2feSToby Isaac ierr = (dm->ops->projectfunctionlocal) (dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr); 63444d6f44ffSToby Isaac PetscFunctionReturn(0); 63454d6f44ffSToby Isaac } 63464d6f44ffSToby Isaac 63472c53366bSMatthew G. Knepley PetscErrorCode DMProjectFunctionLabel(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X) 63482c53366bSMatthew G. Knepley { 63492c53366bSMatthew G. Knepley Vec localX; 63502c53366bSMatthew G. Knepley PetscErrorCode ierr; 63512c53366bSMatthew G. Knepley 63522c53366bSMatthew G. Knepley PetscFunctionBegin; 63532c53366bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 63542c53366bSMatthew G. Knepley ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr); 63552c53366bSMatthew G. Knepley ierr = DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr); 63562c53366bSMatthew G. Knepley ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr); 63572c53366bSMatthew G. Knepley ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr); 63582c53366bSMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr); 63592c53366bSMatthew G. Knepley PetscFunctionReturn(0); 63602c53366bSMatthew G. Knepley } 63612c53366bSMatthew G. Knepley 63621c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFunctionLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 63634d6f44ffSToby Isaac { 63644d6f44ffSToby Isaac PetscErrorCode ierr; 63654d6f44ffSToby Isaac 63664d6f44ffSToby Isaac PetscFunctionBegin; 63674d6f44ffSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 63684d6f44ffSToby Isaac PetscValidHeaderSpecific(localX,VEC_CLASSID,5); 63690918c465SMatthew G. Knepley if (!dm->ops->projectfunctionlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLabelLocal",((PetscObject)dm)->type_name); 63701c531cf8SMatthew G. Knepley ierr = (dm->ops->projectfunctionlabellocal) (dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr); 63714d6f44ffSToby Isaac PetscFunctionReturn(0); 63724d6f44ffSToby Isaac } 63732716604bSToby Isaac 63748c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal(DM dm, PetscReal time, Vec localU, 63758c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 63768c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 63778c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 6378191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 63798c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 63808c6c5593SMatthew G. Knepley { 63818c6c5593SMatthew G. Knepley PetscErrorCode ierr; 63828c6c5593SMatthew G. Knepley 63838c6c5593SMatthew G. Knepley PetscFunctionBegin; 63848c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 63858c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,3); 63868c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,6); 63870918c465SMatthew G. Knepley if (!dm->ops->projectfieldlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name); 63888c6c5593SMatthew G. Knepley ierr = (dm->ops->projectfieldlocal) (dm, time, localU, funcs, mode, localX);CHKERRQ(ierr); 63898c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 63908c6c5593SMatthew G. Knepley } 63918c6c5593SMatthew G. Knepley 63921c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, 63938c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 63948c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 63958c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 6396191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 63978c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 63988c6c5593SMatthew G. Knepley { 63998c6c5593SMatthew G. Knepley PetscErrorCode ierr; 64008c6c5593SMatthew G. Knepley 64018c6c5593SMatthew G. Knepley PetscFunctionBegin; 64028c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 64038c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,6); 64048c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,9); 64050918c465SMatthew G. Knepley if (!dm->ops->projectfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name); 64061c531cf8SMatthew G. Knepley ierr = (dm->ops->projectfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX);CHKERRQ(ierr); 64078c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 64088c6c5593SMatthew G. Knepley } 64098c6c5593SMatthew G. Knepley 64102716604bSToby Isaac /*@C 64112716604bSToby Isaac DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h. 64122716604bSToby Isaac 64132716604bSToby Isaac Input Parameters: 64142716604bSToby Isaac + dm - The DM 64150709b2feSToby Isaac . time - The time 64162716604bSToby Isaac . funcs - The functions to evaluate for each field component 64172716604bSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 6418574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 64192716604bSToby Isaac 64202716604bSToby Isaac Output Parameter: 64212716604bSToby Isaac . diff - The diff ||u - u_h||_2 64222716604bSToby Isaac 64232716604bSToby Isaac Level: developer 64242716604bSToby Isaac 64251189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff() 64262716604bSToby Isaac @*/ 64270709b2feSToby Isaac PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff) 64282716604bSToby Isaac { 64292716604bSToby Isaac PetscErrorCode ierr; 64302716604bSToby Isaac 64312716604bSToby Isaac PetscFunctionBegin; 64322716604bSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6433b698f381SToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 64340918c465SMatthew G. Knepley if (!dm->ops->computel2diff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2Diff",((PetscObject)dm)->type_name); 64350709b2feSToby Isaac ierr = (dm->ops->computel2diff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr); 64362716604bSToby Isaac PetscFunctionReturn(0); 64372716604bSToby Isaac } 6438b698f381SToby Isaac 6439b698f381SToby Isaac /*@C 6440b698f381SToby Isaac DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h. 6441b698f381SToby Isaac 6442b698f381SToby Isaac Input Parameters: 6443b698f381SToby Isaac + dm - The DM 6444b698f381SToby Isaac , time - The time 6445b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component 6446b698f381SToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 6447574a98acSMatthew G. Knepley . X - The coefficient vector u_h, a global vector 6448b698f381SToby Isaac - n - The vector to project along 6449b698f381SToby Isaac 6450b698f381SToby Isaac Output Parameter: 6451b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2 6452b698f381SToby Isaac 6453b698f381SToby Isaac Level: developer 6454b698f381SToby Isaac 6455b698f381SToby Isaac .seealso: DMProjectFunction(), DMComputeL2Diff() 6456b698f381SToby Isaac @*/ 6457b698f381SToby 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) 6458b698f381SToby Isaac { 6459b698f381SToby Isaac PetscErrorCode ierr; 6460b698f381SToby Isaac 6461b698f381SToby Isaac PetscFunctionBegin; 6462b698f381SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6463b698f381SToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 6464b698f381SToby Isaac if (!dm->ops->computel2gradientdiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2GradientDiff",((PetscObject)dm)->type_name); 6465b698f381SToby Isaac ierr = (dm->ops->computel2gradientdiff)(dm,time,funcs,ctxs,X,n,diff);CHKERRQ(ierr); 6466b698f381SToby Isaac PetscFunctionReturn(0); 6467b698f381SToby Isaac } 6468b698f381SToby Isaac 64692a16baeaSToby Isaac /*@C 64702a16baeaSToby Isaac DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components. 64712a16baeaSToby Isaac 64722a16baeaSToby Isaac Input Parameters: 64732a16baeaSToby Isaac + dm - The DM 64742a16baeaSToby Isaac . time - The time 64752a16baeaSToby Isaac . funcs - The functions to evaluate for each field component 64762a16baeaSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 6477574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 64782a16baeaSToby Isaac 64792a16baeaSToby Isaac Output Parameter: 64802a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2 64812a16baeaSToby Isaac 64822a16baeaSToby Isaac Level: developer 64832a16baeaSToby Isaac 64841189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff() 64852a16baeaSToby Isaac @*/ 64861189c1efSToby Isaac PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[]) 64872a16baeaSToby Isaac { 64882a16baeaSToby Isaac PetscErrorCode ierr; 64892a16baeaSToby Isaac 64902a16baeaSToby Isaac PetscFunctionBegin; 64912a16baeaSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 64922a16baeaSToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 64930918c465SMatthew G. Knepley if (!dm->ops->computel2fielddiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2FieldDiff",((PetscObject)dm)->type_name); 64942a16baeaSToby Isaac ierr = (dm->ops->computel2fielddiff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr); 64952a16baeaSToby Isaac PetscFunctionReturn(0); 64962a16baeaSToby Isaac } 64972a16baeaSToby Isaac 6498df0b854cSToby Isaac /*@C 6499df0b854cSToby Isaac DMAdaptLabel - Adapt a dm based on a label with values interpreted as coarsening and refining flags. Specific implementations of DM maybe have 6500cd3c525cSToby Isaac specialized flags, but all implementations should accept flag values DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN. 6501df0b854cSToby Isaac 6502df0b854cSToby Isaac Collective on dm 6503df0b854cSToby Isaac 6504df0b854cSToby Isaac Input parameters: 6505df0b854cSToby Isaac + dm - the pre-adaptation DM object 6506a1b0c543SToby Isaac - label - label with the flags 6507df0b854cSToby Isaac 6508df0b854cSToby Isaac Output parameters: 65090d1cd5e0SMatthew G. Knepley . dmAdapt - the adapted DM object: may be NULL if an adapted DM could not be produced. 6510df0b854cSToby Isaac 6511df0b854cSToby Isaac Level: intermediate 65120d1cd5e0SMatthew G. Knepley 65130d1cd5e0SMatthew G. Knepley .seealso: DMAdaptMetric(), DMCoarsen(), DMRefine() 6514df0b854cSToby Isaac @*/ 65150d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptLabel(DM dm, DMLabel label, DM *dmAdapt) 6516df0b854cSToby Isaac { 6517df0b854cSToby Isaac PetscErrorCode ierr; 6518df0b854cSToby Isaac 6519df0b854cSToby Isaac PetscFunctionBegin; 6520df0b854cSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6521a1b0c543SToby Isaac PetscValidPointer(label,2); 65220d1cd5e0SMatthew G. Knepley PetscValidPointer(dmAdapt,3); 65230d1cd5e0SMatthew G. Knepley *dmAdapt = NULL; 65246f25b0d8SLisandro Dalcin if (!dm->ops->adaptlabel) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptLabel",((PetscObject)dm)->type_name); 65250d1cd5e0SMatthew G. Knepley ierr = (dm->ops->adaptlabel)(dm, label, dmAdapt);CHKERRQ(ierr); 65260d1cd5e0SMatthew G. Knepley PetscFunctionReturn(0); 65270d1cd5e0SMatthew G. Knepley } 65280d1cd5e0SMatthew G. Knepley 65290d1cd5e0SMatthew G. Knepley /*@C 65300d1cd5e0SMatthew G. Knepley DMAdaptMetric - Generates a mesh adapted to the specified metric field using the pragmatic library. 65310d1cd5e0SMatthew G. Knepley 65320d1cd5e0SMatthew G. Knepley Input Parameters: 65330d1cd5e0SMatthew G. Knepley + dm - The DM object 65340d1cd5e0SMatthew G. Knepley . metric - The metric to which the mesh is adapted, defined vertex-wise. 65356f25b0d8SLisandro Dalcin - 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_". 65360d1cd5e0SMatthew G. Knepley 65370d1cd5e0SMatthew G. Knepley Output Parameter: 65380d1cd5e0SMatthew G. Knepley . dmAdapt - Pointer to the DM object containing the adapted mesh 65390d1cd5e0SMatthew G. Knepley 65400d1cd5e0SMatthew G. Knepley Note: The label in the adapted mesh will be registered under the name of the input DMLabel object 65410d1cd5e0SMatthew G. Knepley 65420d1cd5e0SMatthew G. Knepley Level: advanced 65430d1cd5e0SMatthew G. Knepley 65440d1cd5e0SMatthew G. Knepley .seealso: DMAdaptLabel(), DMCoarsen(), DMRefine() 65450d1cd5e0SMatthew G. Knepley @*/ 65460d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptMetric(DM dm, Vec metric, DMLabel bdLabel, DM *dmAdapt) 65470d1cd5e0SMatthew G. Knepley { 65480d1cd5e0SMatthew G. Knepley PetscErrorCode ierr; 65490d1cd5e0SMatthew G. Knepley 65500d1cd5e0SMatthew G. Knepley PetscFunctionBegin; 65510d1cd5e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 65520d1cd5e0SMatthew G. Knepley PetscValidHeaderSpecific(metric, VEC_CLASSID, 2); 65530d1cd5e0SMatthew G. Knepley if (bdLabel) PetscValidPointer(bdLabel, 3); 65540d1cd5e0SMatthew G. Knepley PetscValidPointer(dmAdapt, 4); 65556f25b0d8SLisandro Dalcin *dmAdapt = NULL; 65566f25b0d8SLisandro Dalcin if (!dm->ops->adaptmetric) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptMetric",((PetscObject)dm)->type_name); 65570d1cd5e0SMatthew G. Knepley ierr = (dm->ops->adaptmetric)(dm, metric, bdLabel, dmAdapt);CHKERRQ(ierr); 6558df0b854cSToby Isaac PetscFunctionReturn(0); 6559df0b854cSToby Isaac } 6560c4088d22SMatthew G. Knepley 6561502a2867SDave May /*@C 6562502a2867SDave May DMGetNeighbors - Gets an array containing the MPI rank of all the processes neighbors 6563502a2867SDave May 6564502a2867SDave May Not Collective 6565502a2867SDave May 6566502a2867SDave May Input Parameter: 6567502a2867SDave May . dm - The DM 6568502a2867SDave May 6569502a2867SDave May Output Parameter: 6570502a2867SDave May . nranks - the number of neighbours 6571502a2867SDave May . ranks - the neighbors ranks 6572502a2867SDave May 6573502a2867SDave May Notes: 6574502a2867SDave May Do not free the array, it is freed when the DM is destroyed. 6575502a2867SDave May 6576502a2867SDave May Level: beginner 6577502a2867SDave May 6578dee935c1SDave May .seealso: DMDAGetNeighbors(), PetscSFGetRanks() 6579502a2867SDave May @*/ 6580502a2867SDave May PetscErrorCode DMGetNeighbors(DM dm,PetscInt *nranks,const PetscMPIInt *ranks[]) 6581502a2867SDave May { 6582502a2867SDave May PetscErrorCode ierr; 6583502a2867SDave May 6584502a2867SDave May PetscFunctionBegin; 6585502a2867SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 65860918c465SMatthew G. Knepley if (!dm->ops->getneighbors) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMGetNeighbors",((PetscObject)dm)->type_name); 6587502a2867SDave May ierr = (dm->ops->getneighbors)(dm,nranks,ranks);CHKERRQ(ierr); 6588502a2867SDave May PetscFunctionReturn(0); 6589502a2867SDave May } 6590502a2867SDave May 6591531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */ 6592531c7667SBarry Smith 6593531c7667SBarry Smith /* 6594531c7667SBarry Smith Converts the input vector to a ghosted vector and then calls the standard coloring code. 6595531c7667SBarry Smith This has be a different function because it requires DM which is not defined in the Mat library 6596531c7667SBarry Smith */ 6597531c7667SBarry Smith PetscErrorCode MatFDColoringApply_AIJDM(Mat J,MatFDColoring coloring,Vec x1,void *sctx) 6598531c7667SBarry Smith { 6599531c7667SBarry Smith PetscErrorCode ierr; 6600531c7667SBarry Smith 6601531c7667SBarry Smith PetscFunctionBegin; 6602531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 6603531c7667SBarry Smith Vec x1local; 6604531c7667SBarry Smith DM dm; 6605531c7667SBarry Smith ierr = MatGetDM(J,&dm);CHKERRQ(ierr); 6606531c7667SBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_INCOMP,"IS_COLORING_LOCAL requires a DM"); 6607531c7667SBarry Smith ierr = DMGetLocalVector(dm,&x1local);CHKERRQ(ierr); 6608531c7667SBarry Smith ierr = DMGlobalToLocalBegin(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr); 6609531c7667SBarry Smith ierr = DMGlobalToLocalEnd(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr); 6610531c7667SBarry Smith x1 = x1local; 6611531c7667SBarry Smith } 6612531c7667SBarry Smith ierr = MatFDColoringApply_AIJ(J,coloring,x1,sctx);CHKERRQ(ierr); 6613531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 6614531c7667SBarry Smith DM dm; 6615531c7667SBarry Smith ierr = MatGetDM(J,&dm);CHKERRQ(ierr); 6616531c7667SBarry Smith ierr = DMRestoreLocalVector(dm,&x1);CHKERRQ(ierr); 6617531c7667SBarry Smith } 6618531c7667SBarry Smith PetscFunctionReturn(0); 6619531c7667SBarry Smith } 6620531c7667SBarry Smith 6621531c7667SBarry Smith /*@ 6622531c7667SBarry Smith MatFDColoringUseDM - allows a MatFDColoring object to use the DM associated with the matrix to use a IS_COLORING_LOCAL coloring 6623531c7667SBarry Smith 6624531c7667SBarry Smith Input Parameter: 6625531c7667SBarry Smith . coloring - the MatFDColoring object 6626531c7667SBarry Smith 662795452b02SPatrick Sanan Developer Notes: 662895452b02SPatrick Sanan this routine exists because the PETSc Mat library does not know about the DM objects 6629531c7667SBarry Smith 66301b266c99SBarry Smith Level: advanced 66311b266c99SBarry Smith 6632531c7667SBarry Smith .seealso: MatFDColoring, MatFDColoringCreate(), ISColoringType 6633531c7667SBarry Smith @*/ 6634531c7667SBarry Smith PetscErrorCode MatFDColoringUseDM(Mat coloring,MatFDColoring fdcoloring) 6635531c7667SBarry Smith { 6636531c7667SBarry Smith PetscFunctionBegin; 6637531c7667SBarry Smith coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM; 6638531c7667SBarry Smith PetscFunctionReturn(0); 6639531c7667SBarry Smith } 66408320bc6fSPatrick Sanan 66418320bc6fSPatrick Sanan /*@ 66428320bc6fSPatrick Sanan DMGetCompatibility - determine if two DMs are compatible 66438320bc6fSPatrick Sanan 66448320bc6fSPatrick Sanan Collective 66458320bc6fSPatrick Sanan 66468320bc6fSPatrick Sanan Input Parameters: 66478320bc6fSPatrick Sanan + dm - the first DM 66488320bc6fSPatrick Sanan - dm2 - the second DM 66498320bc6fSPatrick Sanan 66508320bc6fSPatrick Sanan Output Parameters: 66518320bc6fSPatrick Sanan + compatible - whether or not the two DMs are compatible 66528320bc6fSPatrick Sanan - set - whether or not the compatible value was set 66538320bc6fSPatrick Sanan 66548320bc6fSPatrick Sanan Notes: 66558320bc6fSPatrick Sanan Two DMs are deemed compatible if they represent the same parallel decomposition 66568320bc6fSPatrick Sanan of the same topology. This implies that the the section (field data) on one 66578320bc6fSPatrick Sanan "makes sense" with respect to the topology and parallel decomposition of the other. 66588320bc6fSPatrick Sanan Loosely speaking, compatibile DMs represent the same domain, with the same parallel 66598320bc6fSPatrick Sanan decomposition, with different data. 66608320bc6fSPatrick Sanan 66618320bc6fSPatrick Sanan Typically, one would confirm compatibility if intending to simultaneously iterate 66628320bc6fSPatrick Sanan over a pair of vectors obtained from different DMs. 66638320bc6fSPatrick Sanan 66648320bc6fSPatrick Sanan For example, two DMDA objects are compatible if they have the same local 66658320bc6fSPatrick Sanan and global sizes and the same stencil width. They can have different numbers 66668320bc6fSPatrick Sanan of degrees of freedom per node. Thus, one could use the node numbering from 66678320bc6fSPatrick Sanan either DM in bounds for a loop over vectors derived from either DM. 66688320bc6fSPatrick Sanan 66698320bc6fSPatrick Sanan Consider the operation of summing data living on a 2-dof DMDA to data living 66708320bc6fSPatrick Sanan on a 1-dof DMDA, which should be compatible, as in the following snippet. 66718320bc6fSPatrick Sanan .vb 66728320bc6fSPatrick Sanan ... 66738320bc6fSPatrick Sanan ierr = DMGetCompatibility(da1,da2,&compatible,&set);CHKERRQ(ierr); 66748320bc6fSPatrick Sanan if (set && compatible) { 66758320bc6fSPatrick Sanan ierr = DMDAVecGetArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr); 66768320bc6fSPatrick Sanan ierr = DMDAVecGetArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr); 66778320bc6fSPatrick Sanan ierr = DMDAGetCorners(da1,&x,&y,NULL,&m,&n);CHKERRQ(ierr); 66788320bc6fSPatrick Sanan for (j=y; j<y+n; ++j) { 66798320bc6fSPatrick Sanan for (i=x; i<x+m, ++i) { 66808320bc6fSPatrick Sanan arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1]; 66818320bc6fSPatrick Sanan } 66828320bc6fSPatrick Sanan } 66838320bc6fSPatrick Sanan ierr = DMDAVecRestoreArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr); 66848320bc6fSPatrick Sanan ierr = DMDAVecRestoreArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr); 66858320bc6fSPatrick Sanan } else { 66868320bc6fSPatrick Sanan SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible"); 66878320bc6fSPatrick Sanan } 66888320bc6fSPatrick Sanan ... 66898320bc6fSPatrick Sanan .ve 66908320bc6fSPatrick Sanan 66918320bc6fSPatrick Sanan Checking compatibility might be expensive for a given implementation of DM, 66928320bc6fSPatrick Sanan or might be impossible to unambiguously confirm or deny. For this reason, 66938320bc6fSPatrick Sanan this function may decline to determine compatibility, and hence users should 66948320bc6fSPatrick Sanan always check the "set" output parameter. 66958320bc6fSPatrick Sanan 66968320bc6fSPatrick Sanan A DM is always compatible with itself. 66978320bc6fSPatrick Sanan 66988320bc6fSPatrick Sanan In the current implementation, DMs which live on "unequal" communicators 66998320bc6fSPatrick Sanan (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed 67008320bc6fSPatrick Sanan incompatible. 67018320bc6fSPatrick Sanan 67028320bc6fSPatrick Sanan This function is labeled "Collective," as information about all subdomains 67038320bc6fSPatrick Sanan is required on each rank. However, in DM implementations which store all this 67048320bc6fSPatrick Sanan information locally, this function may be merely "Logically Collective". 67058320bc6fSPatrick Sanan 67068320bc6fSPatrick Sanan Developer Notes: 67078320bc6fSPatrick Sanan Compatibility is assumed to be a symmetric concept; if DM A is compatible with DM B, 67088320bc6fSPatrick Sanan the DM B is compatible with DM A. Thus, this function checks the implementations 67098320bc6fSPatrick Sanan of both dm and dm2 (if they are of different types), attempting to determine 67108320bc6fSPatrick Sanan compatibility. It is left to DM implementers to ensure that symmetry is 67118320bc6fSPatrick Sanan preserved. The simplest way to do this is, when implementing type-specific 67128320bc6fSPatrick Sanan logic for this function, to check for existing logic in the implementation 67138320bc6fSPatrick Sanan of other DM types and let *set = PETSC_FALSE if found; the logic of this 67148320bc6fSPatrick Sanan function will then call that logic. 67158320bc6fSPatrick Sanan 67168320bc6fSPatrick Sanan Level: advanced 67178320bc6fSPatrick Sanan 67188320bc6fSPatrick Sanan .seealso: DM, DMDACreateCompatibleDMDA() 67198320bc6fSPatrick Sanan @*/ 67208320bc6fSPatrick Sanan 67218320bc6fSPatrick Sanan PetscErrorCode DMGetCompatibility(DM dm,DM dm2,PetscBool *compatible,PetscBool *set) 67228320bc6fSPatrick Sanan { 67238320bc6fSPatrick Sanan PetscErrorCode ierr; 67248320bc6fSPatrick Sanan PetscMPIInt compareResult; 67258320bc6fSPatrick Sanan DMType type,type2; 67268320bc6fSPatrick Sanan PetscBool sameType; 67278320bc6fSPatrick Sanan 67288320bc6fSPatrick Sanan PetscFunctionBegin; 67298320bc6fSPatrick Sanan PetscValidHeaderSpecific(dm,DM_CLASSID,1); 67308320bc6fSPatrick Sanan PetscValidHeaderSpecific(dm2,DM_CLASSID,2); 67318320bc6fSPatrick Sanan 67328320bc6fSPatrick Sanan /* Declare a DM compatible with itself */ 67338320bc6fSPatrick Sanan if (dm == dm2) { 67348320bc6fSPatrick Sanan *set = PETSC_TRUE; 67358320bc6fSPatrick Sanan *compatible = PETSC_TRUE; 67368320bc6fSPatrick Sanan PetscFunctionReturn(0); 67378320bc6fSPatrick Sanan } 67388320bc6fSPatrick Sanan 67398320bc6fSPatrick Sanan /* Declare a DM incompatible with a DM that lives on an "unequal" 67408320bc6fSPatrick Sanan communicator. Note that this does not preclude compatibility with 67418320bc6fSPatrick Sanan DMs living on "congruent" or "similar" communicators, but this must be 67428320bc6fSPatrick Sanan determined by the implementation-specific logic */ 67438320bc6fSPatrick Sanan ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dm),PetscObjectComm((PetscObject)dm2),&compareResult);CHKERRQ(ierr); 67448320bc6fSPatrick Sanan if (compareResult == MPI_UNEQUAL) { 67458320bc6fSPatrick Sanan *set = PETSC_TRUE; 67468320bc6fSPatrick Sanan *compatible = PETSC_FALSE; 67478320bc6fSPatrick Sanan PetscFunctionReturn(0); 67488320bc6fSPatrick Sanan } 67498320bc6fSPatrick Sanan 67508320bc6fSPatrick Sanan /* Pass to the implementation-specific routine, if one exists. */ 67518320bc6fSPatrick Sanan if (dm->ops->getcompatibility) { 67528320bc6fSPatrick Sanan ierr = (*dm->ops->getcompatibility)(dm,dm2,compatible,set);CHKERRQ(ierr); 67538320bc6fSPatrick Sanan if (*set) { 67548320bc6fSPatrick Sanan PetscFunctionReturn(0); 67558320bc6fSPatrick Sanan } 67568320bc6fSPatrick Sanan } 67578320bc6fSPatrick Sanan 67588320bc6fSPatrick Sanan /* If dm and dm2 are of different types, then attempt to check compatibility 67598320bc6fSPatrick Sanan with an implementation of this function from dm2 */ 67608320bc6fSPatrick Sanan ierr = DMGetType(dm,&type);CHKERRQ(ierr); 67618320bc6fSPatrick Sanan ierr = DMGetType(dm2,&type2);CHKERRQ(ierr); 67628320bc6fSPatrick Sanan ierr = PetscStrcmp(type,type2,&sameType);CHKERRQ(ierr); 67638320bc6fSPatrick Sanan if (!sameType && dm2->ops->getcompatibility) { 67648320bc6fSPatrick Sanan ierr = (*dm2->ops->getcompatibility)(dm2,dm,compatible,set);CHKERRQ(ierr); /* Note argument order */ 67658320bc6fSPatrick Sanan } else { 67668320bc6fSPatrick Sanan *set = PETSC_FALSE; 67678320bc6fSPatrick Sanan } 67688320bc6fSPatrick Sanan PetscFunctionReturn(0); 67698320bc6fSPatrick Sanan } 6770