1d0295fc0SJunchao Zhang #include <petscvec.h> 2af0996ceSBarry Smith #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/ 3c58f1c22SToby Isaac #include <petsc/private/dmlabelimpl.h> /*I "petscdmlabel.h" I*/ 4e6f8dbb6SToby Isaac #include <petsc/private/petscdsimpl.h> /*I "petscds.h" I*/ 53e922f36SToby Isaac #include <petscdmplex.h> 6f19dbd58SToby Isaac #include <petscdmfield.h> 70c312b8eSJed Brown #include <petscsf.h> 82764a2aaSMatthew G. Knepley #include <petscds.h> 947c6ae99SBarry Smith 1000d952a4SJed Brown #if defined(PETSC_HAVE_VALGRIND) 1100d952a4SJed Brown # include <valgrind/memcheck.h> 1200d952a4SJed Brown #endif 1300d952a4SJed Brown 14732e2eb9SMatthew G Knepley PetscClassId DM_CLASSID; 15d67d17b1SMatthew G. Knepley PetscClassId DMLABEL_CLASSID; 16557cf195SMatthew G. Knepley PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal, DM_LocalToLocal, DM_LocatePoints, DM_Coarsen, DM_Refine, DM_CreateInterpolation, DM_CreateRestriction, DM_CreateInjection, DM_CreateMatrix, DM_Load, DM_AdaptInterpolator; 1767a56275SMatthew G Knepley 18ea78f98cSLisandro Dalcin const char *const DMBoundaryTypes[] = {"NONE","GHOSTED","MIRROR","PERIODIC","TWIST","DMBoundaryType","DM_BOUNDARY_", NULL}; 19d1b3049bSMatthew G. Knepley const char *const DMBoundaryConditionTypes[] = {"INVALID","ESSENTIAL","NATURAL","INVALID","INVALID","ESSENTIAL_FIELD","NATURAL_FIELD","INVALID","INVALID","ESSENTIAL_BD_FIELD","NATURAL_RIEMANN","DMBoundaryConditionType","DM_BC_", NULL}; 20da9060c4SMatthew G. Knepley const char *const DMPolytopeTypes[] = {"vertex", "segment", "tensor_segment", "triangle", "quadrilateral", "tensor_quad", "tetrahedron", "hexahedron", "triangular_prism", "tensor_triangular_prism", "tensor_quadrilateral_prism", "pyramid", "FV_ghost_cell", "interior_ghost_cell", "unknown", "invalid", "DMPolytopeType", "DM_POLYTOPE_", NULL}; 2160c22052SBarry Smith 22a4121054SBarry Smith /*@ 23de043629SMatthew G Knepley DMCreate - Creates an empty DM object. The type can then be set with DMSetType(). 24a4121054SBarry Smith 25a4121054SBarry Smith If you never call DMSetType() it will generate an 26a4121054SBarry Smith error when you try to use the vector. 27a4121054SBarry Smith 28d083f849SBarry Smith Collective 29a4121054SBarry Smith 30a4121054SBarry Smith Input Parameter: 31a4121054SBarry Smith . comm - The communicator for the DM object 32a4121054SBarry Smith 33a4121054SBarry Smith Output Parameter: 34a4121054SBarry Smith . dm - The DM object 35a4121054SBarry Smith 36a4121054SBarry Smith Level: beginner 37a4121054SBarry Smith 388472ad0fSDave May .seealso: DMSetType(), DMDA, DMSLICED, DMCOMPOSITE, DMPLEX, DMMOAB, DMNETWORK 39a4121054SBarry Smith @*/ 407087cfbeSBarry Smith PetscErrorCode DMCreate(MPI_Comm comm,DM *dm) 41a4121054SBarry Smith { 42a4121054SBarry Smith DM v; 43e5e52638SMatthew G. Knepley PetscDS ds; 44a4121054SBarry Smith PetscErrorCode ierr; 45a4121054SBarry Smith 46a4121054SBarry Smith PetscFunctionBegin; 471411c6eeSJed Brown PetscValidPointer(dm,2); 480298fd71SBarry Smith *dm = NULL; 49607a6623SBarry Smith ierr = DMInitializePackage();CHKERRQ(ierr); 50a4121054SBarry Smith 5173107ff1SLisandro Dalcin ierr = PetscHeaderCreate(v, DM_CLASSID, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView);CHKERRQ(ierr); 52e7c4fc90SDmitry Karpeev 5349be4549SMatthew G. Knepley v->setupcalled = PETSC_FALSE; 5449be4549SMatthew G. Knepley v->setfromoptionscalled = PETSC_FALSE; 550298fd71SBarry Smith v->ltogmap = NULL; 561411c6eeSJed Brown v->bs = 1; 57171400e9SBarry Smith v->coloringtype = IS_COLORING_GLOBAL; 5888ed4aceSMatthew G Knepley ierr = PetscSFCreate(comm, &v->sf);CHKERRQ(ierr); 591bb6d2a8SBarry Smith ierr = PetscSFCreate(comm, &v->sectionSF);CHKERRQ(ierr); 60c58f1c22SToby Isaac v->labels = NULL; 6134aa8a36SMatthew G. Knepley v->adjacency[0] = PETSC_FALSE; 6234aa8a36SMatthew G. Knepley v->adjacency[1] = PETSC_TRUE; 63c58f1c22SToby Isaac v->depthLabel = NULL; 64ba2698f1SMatthew G. Knepley v->celltypeLabel = NULL; 651bb6d2a8SBarry Smith v->localSection = NULL; 661bb6d2a8SBarry Smith v->globalSection = NULL; 67fba222abSToby Isaac v->defaultConstraintSection = NULL; 68fba222abSToby Isaac v->defaultConstraintMat = NULL; 69c6b900c6SMatthew G. Knepley v->L = NULL; 70c6b900c6SMatthew G. Knepley v->maxCell = NULL; 715dc8c3f7SMatthew G. Knepley v->bdtype = NULL; 729a9a41abSToby Isaac v->dimEmbed = PETSC_DEFAULT; 7396173672SStefano Zampini v->dim = PETSC_DETERMINE; 74435a35e8SMatthew G Knepley { 75435a35e8SMatthew G Knepley PetscInt i; 76435a35e8SMatthew G Knepley for (i = 0; i < 10; ++i) { 770298fd71SBarry Smith v->nullspaceConstructors[i] = NULL; 78f9d4088aSMatthew G. Knepley v->nearnullspaceConstructors[i] = NULL; 79435a35e8SMatthew G Knepley } 80435a35e8SMatthew G Knepley } 81e5e52638SMatthew G. Knepley ierr = PetscDSCreate(PetscObjectComm((PetscObject) v), &ds);CHKERRQ(ierr); 82b3cf3223SMatthew G. Knepley ierr = DMSetRegionDS(v, NULL, NULL, ds);CHKERRQ(ierr); 83e5e52638SMatthew G. Knepley ierr = PetscDSDestroy(&ds);CHKERRQ(ierr); 8414f150ffSMatthew G. Knepley v->dmBC = NULL; 85a8fb8f29SToby Isaac v->coarseMesh = NULL; 86f4d763aaSMatthew G. Knepley v->outputSequenceNum = -1; 87cdb7a50dSMatthew G. Knepley v->outputSequenceVal = 0.0; 88c0dedaeaSBarry Smith ierr = DMSetVecType(v,VECSTANDARD);CHKERRQ(ierr); 89b412c318SBarry Smith ierr = DMSetMatType(v,MATAIJ);CHKERRQ(ierr); 904a7a4c06SLawrence Mitchell 911411c6eeSJed Brown *dm = v; 92a4121054SBarry Smith PetscFunctionReturn(0); 93a4121054SBarry Smith } 94a4121054SBarry Smith 9538221697SMatthew G. Knepley /*@ 9638221697SMatthew G. Knepley DMClone - Creates a DM object with the same topology as the original. 9738221697SMatthew G. Knepley 98d083f849SBarry Smith Collective 9938221697SMatthew G. Knepley 10038221697SMatthew G. Knepley Input Parameter: 10138221697SMatthew G. Knepley . dm - The original DM object 10238221697SMatthew G. Knepley 10338221697SMatthew G. Knepley Output Parameter: 10438221697SMatthew G. Knepley . newdm - The new DM object 10538221697SMatthew G. Knepley 10638221697SMatthew G. Knepley Level: beginner 10738221697SMatthew G. Knepley 1081cb8cacdSPatrick Sanan Notes: 1091cb8cacdSPatrick Sanan For some DM implementations this is a shallow clone, the result of which may share (referent counted) information with its parent. For example, 1101cb8cacdSPatrick Sanan DMClone() applied to a DMPLEX object will result in a new DMPLEX that shares the topology with the original DMPLEX. It does not 1111cb8cacdSPatrick Sanan share the PetscSection of the original DM. 1121bb6d2a8SBarry Smith 11389706ed2SPatrick Sanan The clone is considered set up iff the original is. 11489706ed2SPatrick Sanan 11592cfd99aSMartin Diehl .seealso: DMDestroy(), DMCreate(), DMSetType(), DMSetLocalSection(), DMSetGlobalSection() 1161bb6d2a8SBarry Smith 11738221697SMatthew G. Knepley @*/ 11838221697SMatthew G. Knepley PetscErrorCode DMClone(DM dm, DM *newdm) 11938221697SMatthew G. Knepley { 12038221697SMatthew G. Knepley PetscSF sf; 12138221697SMatthew G. Knepley Vec coords; 12238221697SMatthew G. Knepley void *ctx; 123a3219837SMatthew G. Knepley PetscInt dim, cdim; 12438221697SMatthew G. Knepley PetscErrorCode ierr; 12538221697SMatthew G. Knepley 12638221697SMatthew G. Knepley PetscFunctionBegin; 12738221697SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 12838221697SMatthew G. Knepley PetscValidPointer(newdm,2); 12938221697SMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject) dm), newdm);CHKERRQ(ierr); 1305d80c0bfSVaclav Hapla ierr = DMCopyLabels(dm, *newdm, PETSC_COPY_VALUES, PETSC_TRUE);CHKERRQ(ierr); 131ddf8437dSMatthew G. Knepley (*newdm)->leveldown = dm->leveldown; 132ddf8437dSMatthew G. Knepley (*newdm)->levelup = dm->levelup; 133c8a6034eSMark (*newdm)->prealloc_only = dm->prealloc_only; 134a587d139SMark ierr = PetscFree((*newdm)->vectype);CHKERRQ(ierr); 135a587d139SMark ierr = PetscStrallocpy(dm->vectype,(char**)&(*newdm)->vectype);CHKERRQ(ierr); 136a587d139SMark ierr = PetscFree((*newdm)->mattype);CHKERRQ(ierr); 137a587d139SMark ierr = PetscStrallocpy(dm->mattype,(char**)&(*newdm)->mattype);CHKERRQ(ierr); 1381de53e9aSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1391de53e9aSMatthew G. Knepley ierr = DMSetDimension(*newdm, dim);CHKERRQ(ierr); 14038221697SMatthew G. Knepley if (dm->ops->clone) { 14138221697SMatthew G. Knepley ierr = (*dm->ops->clone)(dm, newdm);CHKERRQ(ierr); 14238221697SMatthew G. Knepley } 1433f22bcbcSToby Isaac (*newdm)->setupcalled = dm->setupcalled; 14438221697SMatthew G. Knepley ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 14538221697SMatthew G. Knepley ierr = DMSetPointSF(*newdm, sf);CHKERRQ(ierr); 14638221697SMatthew G. Knepley ierr = DMGetApplicationContext(dm, &ctx);CHKERRQ(ierr); 14738221697SMatthew G. Knepley ierr = DMSetApplicationContext(*newdm, ctx);CHKERRQ(ierr); 148be4c1c3eSMatthew G. Knepley if (dm->coordinateDM) { 149be4c1c3eSMatthew G. Knepley DM ncdm; 150be4c1c3eSMatthew G. Knepley PetscSection cs; 1515a0206caSToby Isaac PetscInt pEnd = -1, pEndMax = -1; 152be4c1c3eSMatthew G. Knepley 15392fd8e1eSJed Brown ierr = DMGetLocalSection(dm->coordinateDM, &cs);CHKERRQ(ierr); 154be4c1c3eSMatthew G. Knepley if (cs) {ierr = PetscSectionGetChart(cs, NULL, &pEnd);CHKERRQ(ierr);} 155ffc4695bSBarry Smith ierr = MPI_Allreduce(&pEnd,&pEndMax,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 1565a0206caSToby Isaac if (pEndMax >= 0) { 157be4c1c3eSMatthew G. Knepley ierr = DMClone(dm->coordinateDM, &ncdm);CHKERRQ(ierr); 15883bfc06fSMatthew Knepley ierr = DMCopyDisc(dm->coordinateDM, ncdm);CHKERRQ(ierr); 15992fd8e1eSJed Brown ierr = DMSetLocalSection(ncdm, cs);CHKERRQ(ierr); 160a61e840bSMatthew G. Knepley ierr = DMSetCoordinateDM(*newdm, ncdm);CHKERRQ(ierr); 161be4c1c3eSMatthew G. Knepley ierr = DMDestroy(&ncdm);CHKERRQ(ierr); 162be4c1c3eSMatthew G. Knepley } 163be4c1c3eSMatthew G. Knepley } 164a3219837SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 165a3219837SMatthew G. Knepley ierr = DMSetCoordinateDim(*newdm, cdim);CHKERRQ(ierr); 16638221697SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coords);CHKERRQ(ierr); 16738221697SMatthew G. Knepley if (coords) { 16838221697SMatthew G. Knepley ierr = DMSetCoordinatesLocal(*newdm, coords);CHKERRQ(ierr); 16938221697SMatthew G. Knepley } else { 17038221697SMatthew G. Knepley ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr); 17138221697SMatthew G. Knepley if (coords) {ierr = DMSetCoordinates(*newdm, coords);CHKERRQ(ierr);} 17238221697SMatthew G. Knepley } 17390b157c4SStefano Zampini { 17490b157c4SStefano Zampini PetscBool isper; 175c6b900c6SMatthew G. Knepley const PetscReal *maxCell, *L; 1765dc8c3f7SMatthew G. Knepley const DMBoundaryType *bd; 17790b157c4SStefano Zampini ierr = DMGetPeriodicity(dm, &isper, &maxCell, &L, &bd);CHKERRQ(ierr); 17890b157c4SStefano Zampini ierr = DMSetPeriodicity(*newdm, isper, maxCell, L, bd);CHKERRQ(ierr); 179c6b900c6SMatthew G. Knepley } 18034aa8a36SMatthew G. Knepley { 18134aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 18234aa8a36SMatthew G. Knepley 18334aa8a36SMatthew G. Knepley ierr = DMGetAdjacency(dm, PETSC_DEFAULT, &useCone, &useClosure);CHKERRQ(ierr); 18434aa8a36SMatthew G. Knepley ierr = DMSetAdjacency(*newdm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr); 18534aa8a36SMatthew G. Knepley } 18638221697SMatthew G. Knepley PetscFunctionReturn(0); 18738221697SMatthew G. Knepley } 18838221697SMatthew G. Knepley 1899a42bb27SBarry Smith /*@C 190564755cdSBarry Smith DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector() 1919a42bb27SBarry Smith 192d083f849SBarry Smith Logically Collective on da 1939a42bb27SBarry Smith 1949a42bb27SBarry Smith Input Parameter: 1959a42bb27SBarry Smith + da - initial distributed array 196e9e886b6SKarl Rupp . ctype - the vector type, currently either VECSTANDARD, VECCUDA, or VECVIENNACL 1979a42bb27SBarry Smith 1989a42bb27SBarry Smith Options Database: 199dd85299cSBarry Smith . -dm_vec_type ctype 2009a42bb27SBarry Smith 2019a42bb27SBarry Smith Level: intermediate 2029a42bb27SBarry Smith 203a2a9ebe5SBarry Smith .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType, DMGetVecType(), DMSetMatType(), DMGetMatType() 2049a42bb27SBarry Smith @*/ 20519fd82e9SBarry Smith PetscErrorCode DMSetVecType(DM da,VecType ctype) 2069a42bb27SBarry Smith { 2079a42bb27SBarry Smith PetscErrorCode ierr; 2089a42bb27SBarry Smith 2099a42bb27SBarry Smith PetscFunctionBegin; 2109a42bb27SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 2119a42bb27SBarry Smith ierr = PetscFree(da->vectype);CHKERRQ(ierr); 21219fd82e9SBarry Smith ierr = PetscStrallocpy(ctype,(char**)&da->vectype);CHKERRQ(ierr); 2139a42bb27SBarry Smith PetscFunctionReturn(0); 2149a42bb27SBarry Smith } 2159a42bb27SBarry Smith 216c0dedaeaSBarry Smith /*@C 217c0dedaeaSBarry Smith DMGetVecType - Gets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector() 218c0dedaeaSBarry Smith 219d083f849SBarry Smith Logically Collective on da 220c0dedaeaSBarry Smith 221c0dedaeaSBarry Smith Input Parameter: 222c0dedaeaSBarry Smith . da - initial distributed array 223c0dedaeaSBarry Smith 224c0dedaeaSBarry Smith Output Parameter: 225c0dedaeaSBarry Smith . ctype - the vector type 226c0dedaeaSBarry Smith 227c0dedaeaSBarry Smith Level: intermediate 228c0dedaeaSBarry Smith 229a2a9ebe5SBarry Smith .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType, DMSetMatType(), DMGetMatType(), DMSetVecType() 230c0dedaeaSBarry Smith @*/ 231c0dedaeaSBarry Smith PetscErrorCode DMGetVecType(DM da,VecType *ctype) 232c0dedaeaSBarry Smith { 233c0dedaeaSBarry Smith PetscFunctionBegin; 234c0dedaeaSBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 235c0dedaeaSBarry Smith *ctype = da->vectype; 236c0dedaeaSBarry Smith PetscFunctionReturn(0); 237c0dedaeaSBarry Smith } 238c0dedaeaSBarry Smith 2395f1ad066SMatthew G Knepley /*@ 24034f98d34SBarry Smith VecGetDM - Gets the DM defining the data layout of the vector 2415f1ad066SMatthew G Knepley 2425f1ad066SMatthew G Knepley Not collective 2435f1ad066SMatthew G Knepley 2445f1ad066SMatthew G Knepley Input Parameter: 2455f1ad066SMatthew G Knepley . v - The Vec 2465f1ad066SMatthew G Knepley 2475f1ad066SMatthew G Knepley Output Parameter: 2485f1ad066SMatthew G Knepley . dm - The DM 2495f1ad066SMatthew G Knepley 2505f1ad066SMatthew G Knepley Level: intermediate 2515f1ad066SMatthew G Knepley 2525f1ad066SMatthew G Knepley .seealso: VecSetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType() 2535f1ad066SMatthew G Knepley @*/ 2545f1ad066SMatthew G Knepley PetscErrorCode VecGetDM(Vec v, DM *dm) 2555f1ad066SMatthew G Knepley { 2565f1ad066SMatthew G Knepley PetscErrorCode ierr; 2575f1ad066SMatthew G Knepley 2585f1ad066SMatthew G Knepley PetscFunctionBegin; 2595f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,1); 2605f1ad066SMatthew G Knepley PetscValidPointer(dm,2); 2615f1ad066SMatthew G Knepley ierr = PetscObjectQuery((PetscObject) v, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr); 2625f1ad066SMatthew G Knepley PetscFunctionReturn(0); 2635f1ad066SMatthew G Knepley } 2645f1ad066SMatthew G Knepley 2655f1ad066SMatthew G Knepley /*@ 266d9805387SMatthew G. Knepley VecSetDM - Sets the DM defining the data layout of the vector. 2675f1ad066SMatthew G Knepley 2685f1ad066SMatthew G Knepley Not collective 2695f1ad066SMatthew G Knepley 2705f1ad066SMatthew G Knepley Input Parameters: 2715f1ad066SMatthew G Knepley + v - The Vec 2725f1ad066SMatthew G Knepley - dm - The DM 2735f1ad066SMatthew G Knepley 274d9805387SMatthew 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. 275d9805387SMatthew G. Knepley 2765f1ad066SMatthew G Knepley Level: intermediate 2775f1ad066SMatthew G Knepley 2785f1ad066SMatthew G Knepley .seealso: VecGetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType() 2795f1ad066SMatthew G Knepley @*/ 2805f1ad066SMatthew G Knepley PetscErrorCode VecSetDM(Vec v, DM dm) 2815f1ad066SMatthew G Knepley { 2825f1ad066SMatthew G Knepley PetscErrorCode ierr; 2835f1ad066SMatthew G Knepley 2845f1ad066SMatthew G Knepley PetscFunctionBegin; 2855f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,1); 286d7f50e27SLisandro Dalcin if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2); 2875f1ad066SMatthew G Knepley ierr = PetscObjectCompose((PetscObject) v, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 2885f1ad066SMatthew G Knepley PetscFunctionReturn(0); 2895f1ad066SMatthew G Knepley } 2905f1ad066SMatthew G Knepley 291521d9a4cSLisandro Dalcin /*@C 2928f1509bcSBarry Smith DMSetISColoringType - Sets the type of coloring, global or local, that is created by the DM 2938f1509bcSBarry Smith 294d083f849SBarry Smith Logically Collective on dm 2958f1509bcSBarry Smith 2968f1509bcSBarry Smith Input Parameters: 2978f1509bcSBarry Smith + dm - the DM context 2988f1509bcSBarry Smith - ctype - the matrix type 2998f1509bcSBarry Smith 3008f1509bcSBarry Smith Options Database: 3018f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3028f1509bcSBarry Smith 3038f1509bcSBarry Smith Level: intermediate 3048f1509bcSBarry Smith 3058f1509bcSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(), 3068f1509bcSBarry Smith DMGetISColoringType() 3078f1509bcSBarry Smith @*/ 3088f1509bcSBarry Smith PetscErrorCode DMSetISColoringType(DM dm,ISColoringType ctype) 3098f1509bcSBarry Smith { 3108f1509bcSBarry Smith PetscFunctionBegin; 3118f1509bcSBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3128f1509bcSBarry Smith dm->coloringtype = ctype; 3138f1509bcSBarry Smith PetscFunctionReturn(0); 3148f1509bcSBarry Smith } 3158f1509bcSBarry Smith 3168f1509bcSBarry Smith /*@C 3178f1509bcSBarry Smith DMGetISColoringType - Gets the type of coloring, global or local, that is created by the DM 318521d9a4cSLisandro Dalcin 319d083f849SBarry Smith Logically Collective on dm 320521d9a4cSLisandro Dalcin 321521d9a4cSLisandro Dalcin Input Parameter: 3228f1509bcSBarry Smith . dm - the DM context 3238f1509bcSBarry Smith 3248f1509bcSBarry Smith Output Parameter: 3258f1509bcSBarry Smith . ctype - the matrix type 3268f1509bcSBarry Smith 3278f1509bcSBarry Smith Options Database: 3288f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3298f1509bcSBarry Smith 3308f1509bcSBarry Smith Level: intermediate 3318f1509bcSBarry Smith 3328f1509bcSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(), 3338f1509bcSBarry Smith DMGetISColoringType() 3348f1509bcSBarry Smith @*/ 3358f1509bcSBarry Smith PetscErrorCode DMGetISColoringType(DM dm,ISColoringType *ctype) 3368f1509bcSBarry Smith { 3378f1509bcSBarry Smith PetscFunctionBegin; 3388f1509bcSBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3398f1509bcSBarry Smith *ctype = dm->coloringtype; 3408f1509bcSBarry Smith PetscFunctionReturn(0); 3418f1509bcSBarry Smith } 3428f1509bcSBarry Smith 3438f1509bcSBarry Smith /*@C 3448f1509bcSBarry Smith DMSetMatType - Sets the type of matrix created with DMCreateMatrix() 3458f1509bcSBarry Smith 346d083f849SBarry Smith Logically Collective on dm 3478f1509bcSBarry Smith 3488f1509bcSBarry Smith Input Parameters: 349521d9a4cSLisandro Dalcin + dm - the DM context 350a2b5a043SBarry Smith - ctype - the matrix type 351521d9a4cSLisandro Dalcin 352521d9a4cSLisandro Dalcin Options Database: 353521d9a4cSLisandro Dalcin . -dm_mat_type ctype 354521d9a4cSLisandro Dalcin 355521d9a4cSLisandro Dalcin Level: intermediate 356521d9a4cSLisandro Dalcin 357a2a9ebe5SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(), DMSetMatType(), DMGetMatType() 358521d9a4cSLisandro Dalcin @*/ 35919fd82e9SBarry Smith PetscErrorCode DMSetMatType(DM dm,MatType ctype) 360521d9a4cSLisandro Dalcin { 361521d9a4cSLisandro Dalcin PetscErrorCode ierr; 36288f0584fSBarry Smith 363521d9a4cSLisandro Dalcin PetscFunctionBegin; 364521d9a4cSLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 365521d9a4cSLisandro Dalcin ierr = PetscFree(dm->mattype);CHKERRQ(ierr); 36619fd82e9SBarry Smith ierr = PetscStrallocpy(ctype,(char**)&dm->mattype);CHKERRQ(ierr); 367521d9a4cSLisandro Dalcin PetscFunctionReturn(0); 368521d9a4cSLisandro Dalcin } 369521d9a4cSLisandro Dalcin 370c0dedaeaSBarry Smith /*@C 371c0dedaeaSBarry Smith DMGetMatType - Gets the type of matrix created with DMCreateMatrix() 372c0dedaeaSBarry Smith 373d083f849SBarry Smith Logically Collective on dm 374c0dedaeaSBarry Smith 375c0dedaeaSBarry Smith Input Parameter: 376c0dedaeaSBarry Smith . dm - the DM context 377c0dedaeaSBarry Smith 378c0dedaeaSBarry Smith Output Parameter: 379c0dedaeaSBarry Smith . ctype - the matrix type 380c0dedaeaSBarry Smith 381c0dedaeaSBarry Smith Options Database: 382c0dedaeaSBarry Smith . -dm_mat_type ctype 383c0dedaeaSBarry Smith 384c0dedaeaSBarry Smith Level: intermediate 385c0dedaeaSBarry Smith 386a2a9ebe5SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMSetMatType(), DMSetMatType(), DMGetMatType() 387c0dedaeaSBarry Smith @*/ 388c0dedaeaSBarry Smith PetscErrorCode DMGetMatType(DM dm,MatType *ctype) 389c0dedaeaSBarry Smith { 390c0dedaeaSBarry Smith PetscFunctionBegin; 391c0dedaeaSBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 392c0dedaeaSBarry Smith *ctype = dm->mattype; 393c0dedaeaSBarry Smith PetscFunctionReturn(0); 394c0dedaeaSBarry Smith } 395c0dedaeaSBarry Smith 396c688c046SMatthew G Knepley /*@ 39734f98d34SBarry Smith MatGetDM - Gets the DM defining the data layout of the matrix 398c688c046SMatthew G Knepley 399c688c046SMatthew G Knepley Not collective 400c688c046SMatthew G Knepley 401c688c046SMatthew G Knepley Input Parameter: 402c688c046SMatthew G Knepley . A - The Mat 403c688c046SMatthew G Knepley 404c688c046SMatthew G Knepley Output Parameter: 405c688c046SMatthew G Knepley . dm - The DM 406c688c046SMatthew G Knepley 407c688c046SMatthew G Knepley Level: intermediate 408c688c046SMatthew G Knepley 4098f1509bcSBarry Smith Developer Note: Since the Mat class doesn't know about the DM class the DM object is associated with 4108f1509bcSBarry Smith the Mat through a PetscObjectCompose() operation 4118f1509bcSBarry Smith 412c688c046SMatthew G Knepley .seealso: MatSetDM(), DMCreateMatrix(), DMSetMatType() 413c688c046SMatthew G Knepley @*/ 414c688c046SMatthew G Knepley PetscErrorCode MatGetDM(Mat A, DM *dm) 415c688c046SMatthew G Knepley { 416c688c046SMatthew G Knepley PetscErrorCode ierr; 417c688c046SMatthew G Knepley 418c688c046SMatthew G Knepley PetscFunctionBegin; 419c688c046SMatthew G Knepley PetscValidHeaderSpecific(A,MAT_CLASSID,1); 420c688c046SMatthew G Knepley PetscValidPointer(dm,2); 421c688c046SMatthew G Knepley ierr = PetscObjectQuery((PetscObject) A, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr); 422c688c046SMatthew G Knepley PetscFunctionReturn(0); 423c688c046SMatthew G Knepley } 424c688c046SMatthew G Knepley 425c688c046SMatthew G Knepley /*@ 426c688c046SMatthew G Knepley MatSetDM - Sets the DM defining the data layout of the matrix 427c688c046SMatthew G Knepley 428c688c046SMatthew G Knepley Not collective 429c688c046SMatthew G Knepley 430c688c046SMatthew G Knepley Input Parameters: 431c688c046SMatthew G Knepley + A - The Mat 432c688c046SMatthew G Knepley - dm - The DM 433c688c046SMatthew G Knepley 434c688c046SMatthew G Knepley Level: intermediate 435c688c046SMatthew G Knepley 4368f1509bcSBarry Smith Developer Note: Since the Mat class doesn't know about the DM class the DM object is associated with 4378f1509bcSBarry Smith the Mat through a PetscObjectCompose() operation 4388f1509bcSBarry Smith 4398f1509bcSBarry Smith 440c688c046SMatthew G Knepley .seealso: MatGetDM(), DMCreateMatrix(), DMSetMatType() 441c688c046SMatthew G Knepley @*/ 442c688c046SMatthew G Knepley PetscErrorCode MatSetDM(Mat A, DM dm) 443c688c046SMatthew G Knepley { 444c688c046SMatthew G Knepley PetscErrorCode ierr; 445c688c046SMatthew G Knepley 446c688c046SMatthew G Knepley PetscFunctionBegin; 447c688c046SMatthew G Knepley PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4488865f1eaSKarl Rupp if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2); 449c688c046SMatthew G Knepley ierr = PetscObjectCompose((PetscObject) A, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 450c688c046SMatthew G Knepley PetscFunctionReturn(0); 451c688c046SMatthew G Knepley } 452c688c046SMatthew G Knepley 4539a42bb27SBarry Smith /*@C 4549a42bb27SBarry Smith DMSetOptionsPrefix - Sets the prefix used for searching for all 4556757b960SDave May DM options in the database. 4569a42bb27SBarry Smith 457d083f849SBarry Smith Logically Collective on dm 4589a42bb27SBarry Smith 4599a42bb27SBarry Smith Input Parameter: 4608353ddbbSDave May + da - the DM context 4619a42bb27SBarry Smith - prefix - the prefix to prepend to all option names 4629a42bb27SBarry Smith 4639a42bb27SBarry Smith Notes: 4649a42bb27SBarry Smith A hyphen (-) must NOT be given at the beginning of the prefix name. 4659a42bb27SBarry Smith The first character of all runtime options is AUTOMATICALLY the hyphen. 4669a42bb27SBarry Smith 4679a42bb27SBarry Smith Level: advanced 4689a42bb27SBarry Smith 4699a42bb27SBarry Smith .seealso: DMSetFromOptions() 4709a42bb27SBarry Smith @*/ 4717087cfbeSBarry Smith PetscErrorCode DMSetOptionsPrefix(DM dm,const char prefix[]) 4729a42bb27SBarry Smith { 4739a42bb27SBarry Smith PetscErrorCode ierr; 4749a42bb27SBarry Smith 4759a42bb27SBarry Smith PetscFunctionBegin; 4769a42bb27SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4779a42bb27SBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 478691be533SLawrence Mitchell if (dm->sf) { 479691be533SLawrence Mitchell ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->sf,prefix);CHKERRQ(ierr); 480691be533SLawrence Mitchell } 4811bb6d2a8SBarry Smith if (dm->sectionSF) { 4821bb6d2a8SBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->sectionSF,prefix);CHKERRQ(ierr); 483691be533SLawrence Mitchell } 4849a42bb27SBarry Smith PetscFunctionReturn(0); 4859a42bb27SBarry Smith } 4869a42bb27SBarry Smith 48731697293SDave May /*@C 48831697293SDave May DMAppendOptionsPrefix - Appends to the prefix used for searching for all 48931697293SDave May DM options in the database. 49031697293SDave May 491d083f849SBarry Smith Logically Collective on dm 49231697293SDave May 49331697293SDave May Input Parameters: 49431697293SDave May + dm - the DM context 49531697293SDave May - prefix - the prefix string to prepend to all DM option requests 49631697293SDave May 49731697293SDave May Notes: 49831697293SDave May A hyphen (-) must NOT be given at the beginning of the prefix name. 49931697293SDave May The first character of all runtime options is AUTOMATICALLY the hyphen. 50031697293SDave May 50131697293SDave May Level: advanced 50231697293SDave May 50331697293SDave May .seealso: DMSetOptionsPrefix(), DMGetOptionsPrefix() 50431697293SDave May @*/ 50531697293SDave May PetscErrorCode DMAppendOptionsPrefix(DM dm,const char prefix[]) 50631697293SDave May { 50731697293SDave May PetscErrorCode ierr; 50831697293SDave May 50931697293SDave May PetscFunctionBegin; 51031697293SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 51131697293SDave May ierr = PetscObjectAppendOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 51231697293SDave May PetscFunctionReturn(0); 51331697293SDave May } 51431697293SDave May 51531697293SDave May /*@C 51631697293SDave May DMGetOptionsPrefix - Gets the prefix used for searching for all 51731697293SDave May DM options in the database. 51831697293SDave May 51931697293SDave May Not Collective 52031697293SDave May 52131697293SDave May Input Parameters: 52231697293SDave May . dm - the DM context 52331697293SDave May 52431697293SDave May Output Parameters: 52531697293SDave May . prefix - pointer to the prefix string used is returned 52631697293SDave May 52795452b02SPatrick Sanan Notes: 52895452b02SPatrick Sanan On the fortran side, the user should pass in a string 'prefix' of 52931697293SDave May sufficient length to hold the prefix. 53031697293SDave May 53131697293SDave May Level: advanced 53231697293SDave May 53331697293SDave May .seealso: DMSetOptionsPrefix(), DMAppendOptionsPrefix() 53431697293SDave May @*/ 53531697293SDave May PetscErrorCode DMGetOptionsPrefix(DM dm,const char *prefix[]) 53631697293SDave May { 53731697293SDave May PetscErrorCode ierr; 53831697293SDave May 53931697293SDave May PetscFunctionBegin; 54031697293SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 54131697293SDave May ierr = PetscObjectGetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 54231697293SDave May PetscFunctionReturn(0); 54331697293SDave May } 54431697293SDave May 54588bdff64SToby Isaac static PetscErrorCode DMCountNonCyclicReferences(DM dm, PetscBool recurseCoarse, PetscBool recurseFine, PetscInt *ncrefct) 54688bdff64SToby Isaac { 5476eb26441SStefano Zampini PetscInt refct = ((PetscObject) dm)->refct; 54888bdff64SToby Isaac PetscErrorCode ierr; 54988bdff64SToby Isaac 55088bdff64SToby Isaac PetscFunctionBegin; 551aab5bcd8SJed Brown *ncrefct = 0; 55288bdff64SToby Isaac if (dm->coarseMesh && dm->coarseMesh->fineMesh == dm) { 55388bdff64SToby Isaac refct--; 55488bdff64SToby Isaac if (recurseCoarse) { 55588bdff64SToby Isaac PetscInt coarseCount; 55688bdff64SToby Isaac 55788bdff64SToby Isaac ierr = DMCountNonCyclicReferences(dm->coarseMesh, PETSC_TRUE, PETSC_FALSE,&coarseCount);CHKERRQ(ierr); 55888bdff64SToby Isaac refct += coarseCount; 55988bdff64SToby Isaac } 56088bdff64SToby Isaac } 56188bdff64SToby Isaac if (dm->fineMesh && dm->fineMesh->coarseMesh == dm) { 56288bdff64SToby Isaac refct--; 56388bdff64SToby Isaac if (recurseFine) { 56488bdff64SToby Isaac PetscInt fineCount; 56588bdff64SToby Isaac 56688bdff64SToby Isaac ierr = DMCountNonCyclicReferences(dm->fineMesh, PETSC_FALSE, PETSC_TRUE,&fineCount);CHKERRQ(ierr); 56788bdff64SToby Isaac refct += fineCount; 56888bdff64SToby Isaac } 56988bdff64SToby Isaac } 57088bdff64SToby Isaac *ncrefct = refct; 57188bdff64SToby Isaac PetscFunctionReturn(0); 57288bdff64SToby Isaac } 57388bdff64SToby Isaac 574f4cdcedcSVaclav Hapla PetscErrorCode DMDestroyLabelLinkList_Internal(DM dm) 575354557abSToby Isaac { 5765d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 577354557abSToby Isaac PetscErrorCode ierr; 578354557abSToby Isaac 579354557abSToby Isaac PetscFunctionBegin; 580354557abSToby Isaac /* destroy the labels */ 581354557abSToby Isaac while (next) { 582354557abSToby Isaac DMLabelLink tmp = next->next; 583354557abSToby Isaac 5845d80c0bfSVaclav Hapla if (next->label == dm->depthLabel) dm->depthLabel = NULL; 585ba2698f1SMatthew G. Knepley if (next->label == dm->celltypeLabel) dm->celltypeLabel = NULL; 586354557abSToby Isaac ierr = DMLabelDestroy(&next->label);CHKERRQ(ierr); 587354557abSToby Isaac ierr = PetscFree(next);CHKERRQ(ierr); 588354557abSToby Isaac next = tmp; 589354557abSToby Isaac } 5905d80c0bfSVaclav Hapla dm->labels = NULL; 591354557abSToby Isaac PetscFunctionReturn(0); 592354557abSToby Isaac } 593354557abSToby Isaac 5941fb7b255SJunchao Zhang /*@C 5958472ad0fSDave May DMDestroy - Destroys a vector packer or DM. 59647c6ae99SBarry Smith 597d083f849SBarry 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 { 6096eb26441SStefano Zampini PetscInt 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; 620ea78f98cSLisandro Dalcin if (--cnt > 0) {*dm = NULL; PetscFunctionReturn(0);} 6216bf464f9SBarry Smith if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0); 6226bf464f9SBarry Smith ((PetscObject)(*dm))->refct = 0; 6236eb26441SStefano Zampini 6246eb26441SStefano Zampini ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr); 6256eb26441SStefano Zampini ierr = DMClearLocalVectors(*dm);CHKERRQ(ierr); 6266eb26441SStefano Zampini 627f490541aSPeter Brune nnext=(*dm)->namedglobal; 6280298fd71SBarry Smith (*dm)->namedglobal = NULL; 629f490541aSPeter Brune for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named vectors */ 6302348bcf4SPeter Brune nnext = nlink->next; 6312348bcf4SPeter 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); 6322348bcf4SPeter Brune ierr = PetscFree(nlink->name);CHKERRQ(ierr); 6332348bcf4SPeter Brune ierr = VecDestroy(&nlink->X);CHKERRQ(ierr); 6342348bcf4SPeter Brune ierr = PetscFree(nlink);CHKERRQ(ierr); 6352348bcf4SPeter Brune } 636f490541aSPeter Brune nnext=(*dm)->namedlocal; 6370298fd71SBarry Smith (*dm)->namedlocal = NULL; 638f490541aSPeter Brune for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named local vectors */ 639f490541aSPeter Brune nnext = nlink->next; 640f490541aSPeter 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); 641f490541aSPeter Brune ierr = PetscFree(nlink->name);CHKERRQ(ierr); 642f490541aSPeter Brune ierr = VecDestroy(&nlink->X);CHKERRQ(ierr); 643f490541aSPeter Brune ierr = PetscFree(nlink);CHKERRQ(ierr); 644f490541aSPeter Brune } 6452348bcf4SPeter Brune 646b17ce1afSJed Brown /* Destroy the list of hooks */ 647c833c3b5SJed Brown { 648c833c3b5SJed Brown DMCoarsenHookLink link,next; 649b17ce1afSJed Brown for (link=(*dm)->coarsenhook; link; link=next) { 650b17ce1afSJed Brown next = link->next; 651b17ce1afSJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 652b17ce1afSJed Brown } 6530298fd71SBarry Smith (*dm)->coarsenhook = NULL; 654c833c3b5SJed Brown } 655c833c3b5SJed Brown { 656c833c3b5SJed Brown DMRefineHookLink link,next; 657c833c3b5SJed Brown for (link=(*dm)->refinehook; link; link=next) { 658c833c3b5SJed Brown next = link->next; 659c833c3b5SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 660c833c3b5SJed Brown } 6610298fd71SBarry Smith (*dm)->refinehook = NULL; 662c833c3b5SJed Brown } 663be081cd6SPeter Brune { 664be081cd6SPeter Brune DMSubDomainHookLink link,next; 665be081cd6SPeter Brune for (link=(*dm)->subdomainhook; link; link=next) { 666be081cd6SPeter Brune next = link->next; 667be081cd6SPeter Brune ierr = PetscFree(link);CHKERRQ(ierr); 668be081cd6SPeter Brune } 6690298fd71SBarry Smith (*dm)->subdomainhook = NULL; 670be081cd6SPeter Brune } 671baf369e7SPeter Brune { 672baf369e7SPeter Brune DMGlobalToLocalHookLink link,next; 673baf369e7SPeter Brune for (link=(*dm)->gtolhook; link; link=next) { 674baf369e7SPeter Brune next = link->next; 675baf369e7SPeter Brune ierr = PetscFree(link);CHKERRQ(ierr); 676baf369e7SPeter Brune } 6770298fd71SBarry Smith (*dm)->gtolhook = NULL; 678baf369e7SPeter Brune } 679d4d07f1eSToby Isaac { 680d4d07f1eSToby Isaac DMLocalToGlobalHookLink link,next; 681d4d07f1eSToby Isaac for (link=(*dm)->ltoghook; link; link=next) { 682d4d07f1eSToby Isaac next = link->next; 683d4d07f1eSToby Isaac ierr = PetscFree(link);CHKERRQ(ierr); 684d4d07f1eSToby Isaac } 685d4d07f1eSToby Isaac (*dm)->ltoghook = NULL; 686d4d07f1eSToby Isaac } 687aa1993deSMatthew G Knepley /* Destroy the work arrays */ 688aa1993deSMatthew G Knepley { 689aa1993deSMatthew G Knepley DMWorkLink link,next; 690aa1993deSMatthew G Knepley if ((*dm)->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Work array still checked out"); 691aa1993deSMatthew G Knepley for (link=(*dm)->workin; link; link=next) { 692aa1993deSMatthew G Knepley next = link->next; 693aa1993deSMatthew G Knepley ierr = PetscFree(link->mem);CHKERRQ(ierr); 694aa1993deSMatthew G Knepley ierr = PetscFree(link);CHKERRQ(ierr); 695aa1993deSMatthew G Knepley } 6960298fd71SBarry Smith (*dm)->workin = NULL; 697aa1993deSMatthew G Knepley } 698c58f1c22SToby Isaac /* destroy the labels */ 699f4cdcedcSVaclav Hapla ierr = DMDestroyLabelLinkList_Internal(*dm);CHKERRQ(ierr); 700f4cdcedcSVaclav Hapla /* destroy the fields */ 701e5e52638SMatthew G. Knepley ierr = DMClearFields(*dm);CHKERRQ(ierr); 702f4cdcedcSVaclav Hapla /* destroy the boundaries */ 703e6f8dbb6SToby Isaac { 704e6f8dbb6SToby Isaac DMBoundary next = (*dm)->boundary; 705e6f8dbb6SToby Isaac while (next) { 706e6f8dbb6SToby Isaac DMBoundary b = next; 707e6f8dbb6SToby Isaac 708e6f8dbb6SToby Isaac next = b->next; 709e6f8dbb6SToby Isaac ierr = PetscFree(b);CHKERRQ(ierr); 710e6f8dbb6SToby Isaac } 711e6f8dbb6SToby Isaac } 712b17ce1afSJed Brown 71352536dc3SBarry Smith ierr = PetscObjectDestroy(&(*dm)->dmksp);CHKERRQ(ierr); 71452536dc3SBarry Smith ierr = PetscObjectDestroy(&(*dm)->dmsnes);CHKERRQ(ierr); 71552536dc3SBarry Smith ierr = PetscObjectDestroy(&(*dm)->dmts);CHKERRQ(ierr); 71652536dc3SBarry Smith 7171a266240SBarry Smith if ((*dm)->ctx && (*dm)->ctxdestroy) { 7181a266240SBarry Smith ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr); 7191a266240SBarry Smith } 72071cd77b2SBarry Smith ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr); 7216bf464f9SBarry Smith ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr); 7226bf464f9SBarry Smith ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr); 723073dac72SJed Brown ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr); 72488ed4aceSMatthew G Knepley 7251bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&(*dm)->localSection);CHKERRQ(ierr); 7261bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&(*dm)->globalSection);CHKERRQ(ierr); 7278b1ab98fSJed Brown ierr = PetscLayoutDestroy(&(*dm)->map);CHKERRQ(ierr); 728fba222abSToby Isaac ierr = PetscSectionDestroy(&(*dm)->defaultConstraintSection);CHKERRQ(ierr); 729fba222abSToby Isaac ierr = MatDestroy(&(*dm)->defaultConstraintMat);CHKERRQ(ierr); 73088ed4aceSMatthew G Knepley ierr = PetscSFDestroy(&(*dm)->sf);CHKERRQ(ierr); 7311bb6d2a8SBarry Smith ierr = PetscSFDestroy(&(*dm)->sectionSF);CHKERRQ(ierr); 732736995cdSBlaise Bourdin if ((*dm)->useNatural) { 733736995cdSBlaise Bourdin if ((*dm)->sfNatural) { 7348e4ac7eaSMatthew G. Knepley ierr = PetscSFDestroy(&(*dm)->sfNatural);CHKERRQ(ierr); 735736995cdSBlaise Bourdin } 736736995cdSBlaise Bourdin ierr = PetscObjectDereference((PetscObject) (*dm)->sfMigration);CHKERRQ(ierr); 737736995cdSBlaise Bourdin } 73888bdff64SToby Isaac if ((*dm)->coarseMesh && (*dm)->coarseMesh->fineMesh == *dm) { 73988bdff64SToby Isaac ierr = DMSetFineDM((*dm)->coarseMesh,NULL);CHKERRQ(ierr); 74088bdff64SToby Isaac } 7416eb26441SStefano Zampini 742a8fb8f29SToby Isaac ierr = DMDestroy(&(*dm)->coarseMesh);CHKERRQ(ierr); 74388bdff64SToby Isaac if ((*dm)->fineMesh && (*dm)->fineMesh->coarseMesh == *dm) { 74488bdff64SToby Isaac ierr = DMSetCoarseDM((*dm)->fineMesh,NULL);CHKERRQ(ierr); 74588bdff64SToby Isaac } 74688bdff64SToby Isaac ierr = DMDestroy(&(*dm)->fineMesh);CHKERRQ(ierr); 747f19dbd58SToby Isaac ierr = DMFieldDestroy(&(*dm)->coordinateField);CHKERRQ(ierr); 7486636e97aSMatthew G Knepley ierr = DMDestroy(&(*dm)->coordinateDM);CHKERRQ(ierr); 7496636e97aSMatthew G Knepley ierr = VecDestroy(&(*dm)->coordinates);CHKERRQ(ierr); 7506636e97aSMatthew G Knepley ierr = VecDestroy(&(*dm)->coordinatesLocal);CHKERRQ(ierr); 751412e9a14SMatthew G. Knepley ierr = PetscFree((*dm)->L);CHKERRQ(ierr); 752412e9a14SMatthew G. Knepley ierr = PetscFree((*dm)->maxCell);CHKERRQ(ierr); 753412e9a14SMatthew G. Knepley ierr = PetscFree((*dm)->bdtype);CHKERRQ(ierr); 754ca3d3a14SMatthew G. Knepley if ((*dm)->transformDestroy) {ierr = (*(*dm)->transformDestroy)(*dm, (*dm)->transformCtx);CHKERRQ(ierr);} 755ca3d3a14SMatthew G. Knepley ierr = DMDestroy(&(*dm)->transformDM);CHKERRQ(ierr); 756ca3d3a14SMatthew G. Knepley ierr = VecDestroy(&(*dm)->transform);CHKERRQ(ierr); 7576636e97aSMatthew G Knepley 758e5e52638SMatthew G. Knepley ierr = DMClearDS(*dm);CHKERRQ(ierr); 75914f150ffSMatthew G. Knepley ierr = DMDestroy(&(*dm)->dmBC);CHKERRQ(ierr); 760e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 761e04113cfSBarry Smith ierr = PetscObjectSAWsViewOff((PetscObject)*dm);CHKERRQ(ierr); 762732e2eb9SMatthew G Knepley 763ed3c66a1SDave May if ((*dm)->ops->destroy) { 7646bf464f9SBarry Smith ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr); 765ed3c66a1SDave May } 766c0f0dcc3SMatthew G. Knepley ierr = DMMonitorCancel(*dm);CHKERRQ(ierr); 767435a35e8SMatthew G Knepley /* We do not destroy (*dm)->data here so that we can reference count backend objects */ 768732e2eb9SMatthew G Knepley ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr); 76947c6ae99SBarry Smith PetscFunctionReturn(0); 77047c6ae99SBarry Smith } 77147c6ae99SBarry Smith 772d7bf68aeSBarry Smith /*@ 773d7bf68aeSBarry Smith DMSetUp - sets up the data structures inside a DM object 774d7bf68aeSBarry Smith 775d083f849SBarry Smith Collective on dm 776d7bf68aeSBarry Smith 777d7bf68aeSBarry Smith Input Parameter: 778d7bf68aeSBarry Smith . dm - the DM object to setup 779d7bf68aeSBarry Smith 780d7bf68aeSBarry Smith Level: developer 781d7bf68aeSBarry Smith 782e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 783d7bf68aeSBarry Smith 784d7bf68aeSBarry Smith @*/ 7857087cfbeSBarry Smith PetscErrorCode DMSetUp(DM dm) 786d7bf68aeSBarry Smith { 787d7bf68aeSBarry Smith PetscErrorCode ierr; 788d7bf68aeSBarry Smith 789d7bf68aeSBarry Smith PetscFunctionBegin; 790171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7918387afaaSJed Brown if (dm->setupcalled) PetscFunctionReturn(0); 792d7bf68aeSBarry Smith if (dm->ops->setup) { 793d7bf68aeSBarry Smith ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr); 794d7bf68aeSBarry Smith } 7958387afaaSJed Brown dm->setupcalled = PETSC_TRUE; 796d7bf68aeSBarry Smith PetscFunctionReturn(0); 797d7bf68aeSBarry Smith } 798d7bf68aeSBarry Smith 799d7bf68aeSBarry Smith /*@ 800d7bf68aeSBarry Smith DMSetFromOptions - sets parameters in a DM from the options database 801d7bf68aeSBarry Smith 802d083f849SBarry Smith Collective on dm 803d7bf68aeSBarry Smith 804d7bf68aeSBarry Smith Input Parameter: 805d7bf68aeSBarry Smith . dm - the DM object to set options for 806d7bf68aeSBarry Smith 807732e2eb9SMatthew G Knepley Options Database: 8084164ae61SDominic Meiser + -dm_preallocate_only - Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros 8094164ae61SDominic Meiser . -dm_vec_type <type> - type of vector to create inside DM 8104164ae61SDominic Meiser . -dm_mat_type <type> - type of matrix to create inside DM 8118f1509bcSBarry Smith - -dm_is_coloring_type - <global or local> 812732e2eb9SMatthew G Knepley 813384a6580SVaclav Hapla DMPLEX Specific Checks 814384a6580SVaclav Hapla + -dm_plex_check_symmetry - Check that the adjacency information in the mesh is symmetric - DMPlexCheckSymmetry() 815384a6580SVaclav Hapla . -dm_plex_check_skeleton - Check that each cell has the correct number of vertices (only for homogeneous simplex or tensor meshes) - DMPlexCheckSkeleton() 816384a6580SVaclav Hapla . -dm_plex_check_faces - Check that the faces of each cell give a vertex order this is consistent with what we expect from the cell type - DMPlexCheckFaces() 817384a6580SVaclav Hapla . -dm_plex_check_geometry - Check that cells have positive volume - DMPlexCheckGeometry() 818384a6580SVaclav Hapla . -dm_plex_check_pointsf - Check some necessary conditions for PointSF - DMPlexCheckPointSF() 819384a6580SVaclav Hapla . -dm_plex_check_interface_cones - Check points on inter-partition interfaces have conforming order of cone points - DMPlexCheckInterfaceCones() 820384a6580SVaclav Hapla - -dm_plex_check_all - Perform all the checks above 821d7bf68aeSBarry Smith 82295eb5ee5SVaclav Hapla Level: intermediate 82395eb5ee5SVaclav Hapla 82495eb5ee5SVaclav Hapla .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), 82595eb5ee5SVaclav Hapla DMPlexCheckSymmetry(), DMPlexCheckSkeleton(), DMPlexCheckFaces(), DMPlexCheckGeometry(), DMPlexCheckPointSF(), DMPlexCheckInterfaceCones() 826d7bf68aeSBarry Smith 827d7bf68aeSBarry Smith @*/ 8287087cfbeSBarry Smith PetscErrorCode DMSetFromOptions(DM dm) 829d7bf68aeSBarry Smith { 8307781c08eSBarry Smith char typeName[256]; 831ca266f36SBarry Smith PetscBool flg; 832d7bf68aeSBarry Smith PetscErrorCode ierr; 833d7bf68aeSBarry Smith 834d7bf68aeSBarry Smith PetscFunctionBegin; 835171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 83649be4549SMatthew G. Knepley dm->setfromoptionscalled = PETSC_TRUE; 83749be4549SMatthew G. Knepley if (dm->sf) {ierr = PetscSFSetFromOptions(dm->sf);CHKERRQ(ierr);} 8381bb6d2a8SBarry Smith if (dm->sectionSF) {ierr = PetscSFSetFromOptions(dm->sectionSF);CHKERRQ(ierr);} 8393194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr); 8400298fd71SBarry 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); 841a264d7a6SBarry Smith ierr = PetscOptionsFList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr); 842f9ba7244SBarry Smith if (flg) { 843f9ba7244SBarry Smith ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr); 844f9ba7244SBarry Smith } 845a264d7a6SBarry 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); 846073dac72SJed Brown if (flg) { 847521d9a4cSLisandro Dalcin ierr = DMSetMatType(dm,typeName);CHKERRQ(ierr); 848073dac72SJed Brown } 8498f1509bcSBarry Smith ierr = PetscOptionsEnum("-dm_is_coloring_type","Global or local coloring of Jacobian","DMSetISColoringType",ISColoringTypes,(PetscEnum)dm->coloringtype,(PetscEnum*)&dm->coloringtype,NULL);CHKERRQ(ierr); 850f9ba7244SBarry Smith if (dm->ops->setfromoptions) { 851e55864a3SBarry Smith ierr = (*dm->ops->setfromoptions)(PetscOptionsObject,dm);CHKERRQ(ierr); 852f9ba7244SBarry Smith } 853f9ba7244SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 8540633abcbSJed Brown ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) dm);CHKERRQ(ierr); 85582fcb398SMatthew G Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 856d7bf68aeSBarry Smith PetscFunctionReturn(0); 857d7bf68aeSBarry Smith } 858d7bf68aeSBarry Smith 859fc9bc008SSatish Balay /*@C 860fe2efc57SMark DMViewFromOptions - View from Options 861fe2efc57SMark 862fe2efc57SMark Collective on DM 863fe2efc57SMark 864fe2efc57SMark Input Parameters: 865fe2efc57SMark + dm - the DM object 866736c3998SJose E. Roman . obj - Optional object 867736c3998SJose E. Roman - name - command line option 868fe2efc57SMark 869fe2efc57SMark Level: intermediate 870fe2efc57SMark .seealso: DM, DMView, PetscObjectViewFromOptions(), DMCreate() 871fe2efc57SMark @*/ 872fe2efc57SMark PetscErrorCode DMViewFromOptions(DM dm,PetscObject obj,const char name[]) 873fe2efc57SMark { 874fe2efc57SMark PetscErrorCode ierr; 875fe2efc57SMark 876fe2efc57SMark PetscFunctionBegin; 877fe2efc57SMark PetscValidHeaderSpecific(dm,DM_CLASSID,1); 878fe2efc57SMark ierr = PetscObjectViewFromOptions((PetscObject)dm,obj,name);CHKERRQ(ierr); 879fe2efc57SMark PetscFunctionReturn(0); 880fe2efc57SMark } 881fe2efc57SMark 882fe2efc57SMark /*@C 883224748a4SBarry Smith DMView - Views a DM 88447c6ae99SBarry Smith 885d083f849SBarry Smith Collective on dm 88647c6ae99SBarry Smith 88747c6ae99SBarry Smith Input Parameter: 88847c6ae99SBarry Smith + dm - the DM object to view 88947c6ae99SBarry Smith - v - the viewer 89047c6ae99SBarry Smith 891224748a4SBarry Smith Level: beginner 89247c6ae99SBarry Smith 893e727c939SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 89447c6ae99SBarry Smith 89547c6ae99SBarry Smith @*/ 8967087cfbeSBarry Smith PetscErrorCode DMView(DM dm,PetscViewer v) 89747c6ae99SBarry Smith { 89847c6ae99SBarry Smith PetscErrorCode ierr; 89932c0f0efSBarry Smith PetscBool isbinary; 90076a8abe0SBarry Smith PetscMPIInt size; 90176a8abe0SBarry Smith PetscViewerFormat format; 90247c6ae99SBarry Smith 90347c6ae99SBarry Smith PetscFunctionBegin; 904171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 9053014e516SBarry Smith if (!v) { 906ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)dm),&v);CHKERRQ(ierr); 9073014e516SBarry Smith } 908b1b135c8SBarry Smith PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,2); 90974903a4fSStefano Zampini /* Ideally, we would like to have this test on. 91074903a4fSStefano Zampini However, it currently breaks socket viz via GLVis. 91174903a4fSStefano Zampini During DMView(parallel_mesh,glvis_viewer), each 91274903a4fSStefano Zampini process opens a sequential ASCII socket to visualize 91374903a4fSStefano Zampini the local mesh, and PetscObjectView(dm,local_socket) 91474903a4fSStefano Zampini is internally called inside VecView_GLVis, incurring 91574903a4fSStefano Zampini in an error here */ 91674903a4fSStefano Zampini /* PetscCheckSameComm(dm,1,v,2); */ 9178bfd1ab9SVaclav Hapla ierr = PetscViewerCheckWritable(v);CHKERRQ(ierr); 918b1b135c8SBarry Smith 91976a8abe0SBarry Smith ierr = PetscViewerGetFormat(v,&format);CHKERRQ(ierr); 920ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&size);CHKERRMPI(ierr); 92176a8abe0SBarry Smith if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 92298c3331eSBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)dm,v);CHKERRQ(ierr); 92332c0f0efSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 92432c0f0efSBarry Smith if (isbinary) { 92555849f57SBarry Smith PetscInt classid = DM_FILE_CLASSID; 92632c0f0efSBarry Smith char type[256]; 92732c0f0efSBarry Smith 928f253e43cSLisandro Dalcin ierr = PetscViewerBinaryWrite(v,&classid,1,PETSC_INT);CHKERRQ(ierr); 92932c0f0efSBarry Smith ierr = PetscStrncpy(type,((PetscObject)dm)->type_name,256);CHKERRQ(ierr); 930f253e43cSLisandro Dalcin ierr = PetscViewerBinaryWrite(v,type,256,PETSC_CHAR);CHKERRQ(ierr); 93132c0f0efSBarry Smith } 9320c010503SBarry Smith if (dm->ops->view) { 9330c010503SBarry Smith ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr); 93447c6ae99SBarry Smith } 93547c6ae99SBarry Smith PetscFunctionReturn(0); 93647c6ae99SBarry Smith } 93747c6ae99SBarry Smith 93847c6ae99SBarry Smith /*@ 9398472ad0fSDave May DMCreateGlobalVector - Creates a global vector from a DM object 94047c6ae99SBarry Smith 941d083f849SBarry Smith Collective on dm 94247c6ae99SBarry Smith 94347c6ae99SBarry Smith Input Parameter: 94447c6ae99SBarry Smith . dm - the DM object 94547c6ae99SBarry Smith 94647c6ae99SBarry Smith Output Parameter: 94747c6ae99SBarry Smith . vec - the global vector 94847c6ae99SBarry Smith 949073dac72SJed Brown Level: beginner 95047c6ae99SBarry Smith 951ec075b9fSPatrick Sanan .seealso DMCreateLocalVector(), DMGetGlobalVector(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 95247c6ae99SBarry Smith 95347c6ae99SBarry Smith @*/ 9547087cfbeSBarry Smith PetscErrorCode DMCreateGlobalVector(DM dm,Vec *vec) 95547c6ae99SBarry Smith { 95647c6ae99SBarry Smith PetscErrorCode ierr; 95747c6ae99SBarry Smith 95847c6ae99SBarry Smith PetscFunctionBegin; 959171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 960b9d85ea2SLisandro Dalcin PetscValidPointer(vec,2); 961b9d85ea2SLisandro Dalcin if (!dm->ops->createglobalvector) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateGlobalVector",((PetscObject)dm)->type_name); 96247c6ae99SBarry Smith ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr); 96376bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 964c6b011d8SStefano Zampini DM vdm; 965c6b011d8SStefano Zampini 966c6b011d8SStefano Zampini ierr = VecGetDM(*vec,&vdm);CHKERRQ(ierr); 967c6b011d8SStefano Zampini if (!vdm) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"DM type '%s' did not attach the DM to the vector\n",((PetscObject)dm)->type_name); 968c6b011d8SStefano Zampini } 96947c6ae99SBarry Smith PetscFunctionReturn(0); 97047c6ae99SBarry Smith } 97147c6ae99SBarry Smith 97247c6ae99SBarry Smith /*@ 9738472ad0fSDave May DMCreateLocalVector - Creates a local vector from a DM object 97447c6ae99SBarry Smith 97547c6ae99SBarry Smith Not Collective 97647c6ae99SBarry Smith 97747c6ae99SBarry Smith Input Parameter: 97847c6ae99SBarry Smith . dm - the DM object 97947c6ae99SBarry Smith 98047c6ae99SBarry Smith Output Parameter: 98147c6ae99SBarry Smith . vec - the local vector 98247c6ae99SBarry Smith 983073dac72SJed Brown Level: beginner 98447c6ae99SBarry Smith 985ec075b9fSPatrick Sanan .seealso DMCreateGlobalVector(), DMGetLocalVector(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 98647c6ae99SBarry Smith 98747c6ae99SBarry Smith @*/ 9887087cfbeSBarry Smith PetscErrorCode DMCreateLocalVector(DM dm,Vec *vec) 98947c6ae99SBarry Smith { 99047c6ae99SBarry Smith PetscErrorCode ierr; 99147c6ae99SBarry Smith 99247c6ae99SBarry Smith PetscFunctionBegin; 993171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 994b9d85ea2SLisandro Dalcin PetscValidPointer(vec,2); 995b9d85ea2SLisandro Dalcin if (!dm->ops->createlocalvector) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateLocalVector",((PetscObject)dm)->type_name); 99647c6ae99SBarry Smith ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr); 99776bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 998c6b011d8SStefano Zampini DM vdm; 999c6b011d8SStefano Zampini 1000c6b011d8SStefano Zampini ierr = VecGetDM(*vec,&vdm);CHKERRQ(ierr); 1001c6b011d8SStefano Zampini if (!vdm) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"DM type '%s' did not attach the DM to the vector\n",((PetscObject)dm)->type_name); 1002c6b011d8SStefano Zampini } 100347c6ae99SBarry Smith PetscFunctionReturn(0); 100447c6ae99SBarry Smith } 100547c6ae99SBarry Smith 10061411c6eeSJed Brown /*@ 10071411c6eeSJed Brown DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM. 10081411c6eeSJed Brown 1009d083f849SBarry Smith Collective on dm 10101411c6eeSJed Brown 10111411c6eeSJed Brown Input Parameter: 10121411c6eeSJed Brown . dm - the DM that provides the mapping 10131411c6eeSJed Brown 10141411c6eeSJed Brown Output Parameter: 10151411c6eeSJed Brown . ltog - the mapping 10161411c6eeSJed Brown 10171411c6eeSJed Brown Level: intermediate 10181411c6eeSJed Brown 10191411c6eeSJed Brown Notes: 10201411c6eeSJed Brown This mapping can then be used by VecSetLocalToGlobalMapping() or 10211411c6eeSJed Brown MatSetLocalToGlobalMapping(). 10221411c6eeSJed Brown 1023fc31e74dSBarry Smith .seealso: DMCreateLocalVector() 10241411c6eeSJed Brown @*/ 10257087cfbeSBarry Smith PetscErrorCode DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog) 10261411c6eeSJed Brown { 10270be3e97aSMatthew G. Knepley PetscInt bs = -1, bsLocal[2], bsMinMax[2]; 10281411c6eeSJed Brown PetscErrorCode ierr; 10291411c6eeSJed Brown 10301411c6eeSJed Brown PetscFunctionBegin; 10311411c6eeSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 10321411c6eeSJed Brown PetscValidPointer(ltog,2); 10331411c6eeSJed Brown if (!dm->ltogmap) { 103437d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 103537d0c07bSMatthew G Knepley 103692fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 103737d0c07bSMatthew G Knepley if (section) { 1038a974ec88SMatthew G. Knepley const PetscInt *cdofs; 103937d0c07bSMatthew G Knepley PetscInt *ltog; 1040ccf3bd66SMatthew G. Knepley PetscInt pStart, pEnd, n, p, k, l; 104137d0c07bSMatthew G Knepley 1042e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 104337d0c07bSMatthew G Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 1044ccf3bd66SMatthew G. Knepley ierr = PetscSectionGetStorageSize(section, &n);CHKERRQ(ierr); 1045ccf3bd66SMatthew G. Knepley ierr = PetscMalloc1(n, <og);CHKERRQ(ierr); /* We want the local+overlap size */ 104637d0c07bSMatthew G Knepley for (p = pStart, l = 0; p < pEnd; ++p) { 1047a974ec88SMatthew G. Knepley PetscInt bdof, cdof, dof, off, c, cind = 0; 104837d0c07bSMatthew G Knepley 104937d0c07bSMatthew G Knepley /* Should probably use constrained dofs */ 105037d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 1051a974ec88SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr); 1052a974ec88SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, p, &cdofs);CHKERRQ(ierr); 105337d0c07bSMatthew G Knepley ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr); 10541a7dc684SMatthew G. Knepley /* If you have dofs, and constraints, and they are unequal, we set the blocksize to 1 */ 10551a7dc684SMatthew G. Knepley bdof = cdof && (dof-cdof) ? 1 : dof; 10561a7dc684SMatthew G. Knepley if (dof) { 1057b190aa46SMatthew G. Knepley if (bs < 0) {bs = bdof;} 1058b190aa46SMatthew G. Knepley else if (bs != bdof) {bs = 1;} 10591a7dc684SMatthew G. Knepley } 106037d0c07bSMatthew G Knepley for (c = 0; c < dof; ++c, ++l) { 1061a974ec88SMatthew G. Knepley if ((cind < cdof) && (c == cdofs[cind])) ltog[l] = off < 0 ? off-c : off+c; 1062a974ec88SMatthew G. Knepley else ltog[l] = (off < 0 ? -(off+1) : off) + c; 106337d0c07bSMatthew G Knepley } 106437d0c07bSMatthew G Knepley } 1065bff27382SMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 10660be3e97aSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 10670be3e97aSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 10680be3e97aSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 10690be3e97aSMatthew G. Knepley else {bs = bsMinMax[0];} 10707591dbb2SMatthew G. Knepley bs = bs < 0 ? 1 : bs; 10717591dbb2SMatthew G. Knepley /* Must reduce indices by blocksize */ 1072ccf3bd66SMatthew G. Knepley if (bs > 1) { 1073ccf3bd66SMatthew G. Knepley for (l = 0, k = 0; l < n; l += bs, ++k) ltog[k] = ltog[l]/bs; 1074ccf3bd66SMatthew G. Knepley n /= bs; 1075ccf3bd66SMatthew G. Knepley } 1076ccf3bd66SMatthew G. Knepley ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, n, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr); 10773bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)dm, (PetscObject)dm->ltogmap);CHKERRQ(ierr); 107837d0c07bSMatthew G Knepley } else { 1079b9d85ea2SLisandro Dalcin if (!dm->ops->getlocaltoglobalmapping) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMGetLocalToGlobalMapping",((PetscObject)dm)->type_name); 1080184d77edSJed Brown ierr = (*dm->ops->getlocaltoglobalmapping)(dm);CHKERRQ(ierr); 10811411c6eeSJed Brown } 108237d0c07bSMatthew G Knepley } 10831411c6eeSJed Brown *ltog = dm->ltogmap; 10841411c6eeSJed Brown PetscFunctionReturn(0); 10851411c6eeSJed Brown } 10861411c6eeSJed Brown 10871411c6eeSJed Brown /*@ 10881411c6eeSJed Brown DMGetBlockSize - Gets the inherent block size associated with a DM 10891411c6eeSJed Brown 10901411c6eeSJed Brown Not Collective 10911411c6eeSJed Brown 10921411c6eeSJed Brown Input Parameter: 10931411c6eeSJed Brown . dm - the DM with block structure 10941411c6eeSJed Brown 10951411c6eeSJed Brown Output Parameter: 10961411c6eeSJed Brown . bs - the block size, 1 implies no exploitable block structure 10971411c6eeSJed Brown 10981411c6eeSJed Brown Level: intermediate 10991411c6eeSJed Brown 1100fc31e74dSBarry Smith .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMapping() 11011411c6eeSJed Brown @*/ 11027087cfbeSBarry Smith PetscErrorCode DMGetBlockSize(DM dm,PetscInt *bs) 11031411c6eeSJed Brown { 11041411c6eeSJed Brown PetscFunctionBegin; 11051411c6eeSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1106534a8f05SLisandro Dalcin PetscValidIntPointer(bs,2); 11071411c6eeSJed 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"); 11081411c6eeSJed Brown *bs = dm->bs; 11091411c6eeSJed Brown PetscFunctionReturn(0); 11101411c6eeSJed Brown } 11111411c6eeSJed Brown 111248eeb7c8SBarry Smith /*@C 11138472ad0fSDave May DMCreateInterpolation - Gets interpolation matrix between two DM objects 111447c6ae99SBarry Smith 1115a5bc1bf3SBarry Smith Collective on dmc 111647c6ae99SBarry Smith 111747c6ae99SBarry Smith Input Parameter: 1118a5bc1bf3SBarry Smith + dmc - the DM object 1119a5bc1bf3SBarry Smith - dmf - the second, finer DM object 112047c6ae99SBarry Smith 112147c6ae99SBarry Smith Output Parameter: 112247c6ae99SBarry Smith + mat - the interpolation 112347c6ae99SBarry Smith - vec - the scaling (optional) 112447c6ae99SBarry Smith 112547c6ae99SBarry Smith Level: developer 112647c6ae99SBarry Smith 112795452b02SPatrick Sanan Notes: 112895452b02SPatrick 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 112985afcc9aSBarry Smith DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation. 1130d52bd9f3SBarry Smith 11311f588964SMatthew G Knepley For DMDA objects you can use this interpolation (more precisely the interpolation from the DMGetCoordinateDM()) to interpolate the mesh coordinate vectors 1132d52bd9f3SBarry Smith EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic. 113385afcc9aSBarry Smith 113485afcc9aSBarry Smith 11352ed6491fSPatrick Sanan .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateRestriction(), DMCreateInterpolationScale() 113647c6ae99SBarry Smith 113747c6ae99SBarry Smith @*/ 1138a5bc1bf3SBarry Smith PetscErrorCode DMCreateInterpolation(DM dmc,DM dmf,Mat *mat,Vec *vec) 113947c6ae99SBarry Smith { 114047c6ae99SBarry Smith PetscErrorCode ierr; 114147c6ae99SBarry Smith 114247c6ae99SBarry Smith PetscFunctionBegin; 1143a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 1144a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf,DM_CLASSID,2); 1145c7d20fa0SStefano Zampini PetscValidPointer(mat,3); 1146a5bc1bf3SBarry Smith if (!dmc->ops->createinterpolation) SETERRQ1(PetscObjectComm((PetscObject)dmc),PETSC_ERR_SUP,"DM type %s does not implement DMCreateInterpolation",((PetscObject)dmc)->type_name); 1147a5bc1bf3SBarry Smith ierr = PetscLogEventBegin(DM_CreateInterpolation,dmc,dmf,0,0);CHKERRQ(ierr); 1148a5bc1bf3SBarry Smith ierr = (*dmc->ops->createinterpolation)(dmc,dmf,mat,vec);CHKERRQ(ierr); 1149a5bc1bf3SBarry Smith ierr = PetscLogEventEnd(DM_CreateInterpolation,dmc,dmf,0,0);CHKERRQ(ierr); 115047c6ae99SBarry Smith PetscFunctionReturn(0); 115147c6ae99SBarry Smith } 115247c6ae99SBarry Smith 11533ad4599aSBarry Smith /*@ 1154d3e313eaSPatrick Sanan DMCreateInterpolationScale - Forms L = 1/(R*1) such that diag(L)*R preserves scale and is thus suitable for state (versus residual) restriction. 11552ed6491fSPatrick Sanan 11562ed6491fSPatrick Sanan Input Parameters: 11572ed6491fSPatrick Sanan + dac - DM that defines a coarse mesh 11582ed6491fSPatrick Sanan . daf - DM that defines a fine mesh 11592ed6491fSPatrick Sanan - mat - the restriction (or interpolation operator) from fine to coarse 11602ed6491fSPatrick Sanan 11612ed6491fSPatrick Sanan Output Parameter: 11622ed6491fSPatrick Sanan . scale - the scaled vector 11632ed6491fSPatrick Sanan 11642ed6491fSPatrick Sanan Level: developer 11652ed6491fSPatrick Sanan 11662ed6491fSPatrick Sanan .seealso: DMCreateInterpolation() 11672ed6491fSPatrick Sanan 11682ed6491fSPatrick Sanan @*/ 11692ed6491fSPatrick Sanan PetscErrorCode DMCreateInterpolationScale(DM dac,DM daf,Mat mat,Vec *scale) 11702ed6491fSPatrick Sanan { 11712ed6491fSPatrick Sanan PetscErrorCode ierr; 11722ed6491fSPatrick Sanan Vec fine; 11732ed6491fSPatrick Sanan PetscScalar one = 1.0; 11742ed6491fSPatrick Sanan 11752ed6491fSPatrick Sanan PetscFunctionBegin; 11762ed6491fSPatrick Sanan ierr = DMCreateGlobalVector(daf,&fine);CHKERRQ(ierr); 11772ed6491fSPatrick Sanan ierr = DMCreateGlobalVector(dac,scale);CHKERRQ(ierr); 11782ed6491fSPatrick Sanan ierr = VecSet(fine,one);CHKERRQ(ierr); 11792ed6491fSPatrick Sanan ierr = MatRestrict(mat,fine,*scale);CHKERRQ(ierr); 11802ed6491fSPatrick Sanan ierr = VecDestroy(&fine);CHKERRQ(ierr); 11812ed6491fSPatrick Sanan ierr = VecReciprocal(*scale);CHKERRQ(ierr); 11822ed6491fSPatrick Sanan PetscFunctionReturn(0); 11832ed6491fSPatrick Sanan } 11842ed6491fSPatrick Sanan 11852ed6491fSPatrick Sanan /*@ 11863ad4599aSBarry Smith DMCreateRestriction - Gets restriction matrix between two DM objects 11873ad4599aSBarry Smith 1188a5bc1bf3SBarry Smith Collective on dmc 11893ad4599aSBarry Smith 11903ad4599aSBarry Smith Input Parameter: 1191a5bc1bf3SBarry Smith + dmc - the DM object 1192a5bc1bf3SBarry Smith - dmf - the second, finer DM object 11933ad4599aSBarry Smith 11943ad4599aSBarry Smith Output Parameter: 11953ad4599aSBarry Smith . mat - the restriction 11963ad4599aSBarry Smith 11973ad4599aSBarry Smith 11983ad4599aSBarry Smith Level: developer 11993ad4599aSBarry Smith 120095452b02SPatrick Sanan Notes: 120195452b02SPatrick 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 12023ad4599aSBarry Smith DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation. 12033ad4599aSBarry Smith 12043ad4599aSBarry Smith 12053ad4599aSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateInterpolation() 12063ad4599aSBarry Smith 12073ad4599aSBarry Smith @*/ 1208a5bc1bf3SBarry Smith PetscErrorCode DMCreateRestriction(DM dmc,DM dmf,Mat *mat) 12093ad4599aSBarry Smith { 12103ad4599aSBarry Smith PetscErrorCode ierr; 12113ad4599aSBarry Smith 12123ad4599aSBarry Smith PetscFunctionBegin; 1213a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 1214a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf,DM_CLASSID,2); 12155a84ad33SLisandro Dalcin PetscValidPointer(mat,3); 1216a5bc1bf3SBarry Smith if (!dmc->ops->createrestriction) SETERRQ1(PetscObjectComm((PetscObject)dmc),PETSC_ERR_SUP,"DM type %s does not implement DMCreateRestriction",((PetscObject)dmc)->type_name); 1217a5bc1bf3SBarry Smith ierr = PetscLogEventBegin(DM_CreateRestriction,dmc,dmf,0,0);CHKERRQ(ierr); 1218a5bc1bf3SBarry Smith ierr = (*dmc->ops->createrestriction)(dmc,dmf,mat);CHKERRQ(ierr); 1219a5bc1bf3SBarry Smith ierr = PetscLogEventEnd(DM_CreateRestriction,dmc,dmf,0,0);CHKERRQ(ierr); 12203ad4599aSBarry Smith PetscFunctionReturn(0); 12213ad4599aSBarry Smith } 12223ad4599aSBarry Smith 122347c6ae99SBarry Smith /*@ 12248472ad0fSDave May DMCreateInjection - Gets injection matrix between two DM objects 122547c6ae99SBarry Smith 1226a5bc1bf3SBarry Smith Collective on dac 122747c6ae99SBarry Smith 122847c6ae99SBarry Smith Input Parameter: 1229a5bc1bf3SBarry Smith + dac - the DM object 1230a5bc1bf3SBarry Smith - daf - the second, finer DM object 123147c6ae99SBarry Smith 123247c6ae99SBarry Smith Output Parameter: 12336dbf9973SLawrence Mitchell . mat - the injection 123447c6ae99SBarry Smith 123547c6ae99SBarry Smith Level: developer 123647c6ae99SBarry Smith 123795452b02SPatrick Sanan Notes: 123895452b02SPatrick 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 123985afcc9aSBarry Smith DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection. 124085afcc9aSBarry Smith 1241e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation() 124247c6ae99SBarry Smith 124347c6ae99SBarry Smith @*/ 1244a5bc1bf3SBarry Smith PetscErrorCode DMCreateInjection(DM dac,DM daf,Mat *mat) 124547c6ae99SBarry Smith { 124647c6ae99SBarry Smith PetscErrorCode ierr; 124747c6ae99SBarry Smith 124847c6ae99SBarry Smith PetscFunctionBegin; 1249a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dac,DM_CLASSID,1); 1250a5bc1bf3SBarry Smith PetscValidHeaderSpecific(daf,DM_CLASSID,2); 12515a84ad33SLisandro Dalcin PetscValidPointer(mat,3); 1252a5bc1bf3SBarry Smith if (!dac->ops->createinjection) SETERRQ1(PetscObjectComm((PetscObject)dac),PETSC_ERR_SUP,"DM type %s does not implement DMCreateInjection",((PetscObject)dac)->type_name); 1253a5bc1bf3SBarry Smith ierr = PetscLogEventBegin(DM_CreateInjection,dac,daf,0,0);CHKERRQ(ierr); 1254a5bc1bf3SBarry Smith ierr = (*dac->ops->createinjection)(dac,daf,mat);CHKERRQ(ierr); 1255a5bc1bf3SBarry Smith ierr = PetscLogEventEnd(DM_CreateInjection,dac,daf,0,0);CHKERRQ(ierr); 125647c6ae99SBarry Smith PetscFunctionReturn(0); 125747c6ae99SBarry Smith } 125847c6ae99SBarry Smith 1259b412c318SBarry Smith /*@ 1260bd041c0cSMatthew G. Knepley DMCreateMassMatrix - Gets mass matrix between two DM objects, M_ij = \int \phi_i \psi_j 1261bd041c0cSMatthew G. Knepley 1262a5bc1bf3SBarry Smith Collective on dac 1263bd041c0cSMatthew G. Knepley 1264bd041c0cSMatthew G. Knepley Input Parameter: 1265a5bc1bf3SBarry Smith + dac - the DM object 1266a5bc1bf3SBarry Smith - daf - the second, finer DM object 1267bd041c0cSMatthew G. Knepley 1268bd041c0cSMatthew G. Knepley Output Parameter: 1269bd041c0cSMatthew G. Knepley . mat - the interpolation 1270bd041c0cSMatthew G. Knepley 1271bd041c0cSMatthew G. Knepley Level: developer 1272bd041c0cSMatthew G. Knepley 1273bd041c0cSMatthew G. Knepley .seealso DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateRestriction(), DMCreateInterpolation(), DMCreateInjection() 1274bd041c0cSMatthew G. Knepley @*/ 1275a5bc1bf3SBarry Smith PetscErrorCode DMCreateMassMatrix(DM dac, DM daf, Mat *mat) 1276bd041c0cSMatthew G. Knepley { 1277bd041c0cSMatthew G. Knepley PetscErrorCode ierr; 1278bd041c0cSMatthew G. Knepley 1279bd041c0cSMatthew G. Knepley PetscFunctionBegin; 1280a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dac, DM_CLASSID, 1); 1281a5bc1bf3SBarry Smith PetscValidHeaderSpecific(daf, DM_CLASSID, 2); 12825a84ad33SLisandro Dalcin PetscValidPointer(mat,3); 1283a5bc1bf3SBarry Smith if (!dac->ops->createmassmatrix) SETERRQ1(PetscObjectComm((PetscObject)dac),PETSC_ERR_SUP,"DM type %s does not implement DMCreateMassMatrix",((PetscObject)dac)->type_name); 1284a5bc1bf3SBarry Smith ierr = (*dac->ops->createmassmatrix)(dac, daf, mat);CHKERRQ(ierr); 1285bd041c0cSMatthew G. Knepley PetscFunctionReturn(0); 1286bd041c0cSMatthew G. Knepley } 1287bd041c0cSMatthew G. Knepley 1288bd041c0cSMatthew G. Knepley /*@ 1289b412c318SBarry Smith DMCreateColoring - Gets coloring for a DM 129047c6ae99SBarry Smith 1291d083f849SBarry Smith Collective on dm 129247c6ae99SBarry Smith 129347c6ae99SBarry Smith Input Parameter: 129447c6ae99SBarry Smith + dm - the DM object 12955bdb020cSBarry Smith - ctype - IS_COLORING_LOCAL or IS_COLORING_GLOBAL 129647c6ae99SBarry Smith 129747c6ae99SBarry Smith Output Parameter: 129847c6ae99SBarry Smith . coloring - the coloring 129947c6ae99SBarry Smith 1300ec5066bdSBarry Smith Notes: 1301ec5066bdSBarry Smith Coloring of matrices can be computed directly from the sparse matrix nonzero structure via the MatColoring object or from the mesh from which the 1302ec5066bdSBarry Smith matrix comes from. In general using the mesh produces a more optimal coloring (fewer colors). 1303ec5066bdSBarry Smith 1304ec5066bdSBarry Smith This produces a coloring with the distance of 2, see MatSetColoringDistance() which can be used for efficiently computing Jacobians with MatFDColoringCreate() 1305ec5066bdSBarry Smith 130647c6ae99SBarry Smith Level: developer 130747c6ae99SBarry Smith 1308ec5066bdSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix(), DMSetMatType(), MatColoring, MatFDColoringCreate() 130947c6ae99SBarry Smith 1310aab9d709SJed Brown @*/ 1311b412c318SBarry Smith PetscErrorCode DMCreateColoring(DM dm,ISColoringType ctype,ISColoring *coloring) 131247c6ae99SBarry Smith { 131347c6ae99SBarry Smith PetscErrorCode ierr; 131447c6ae99SBarry Smith 131547c6ae99SBarry Smith PetscFunctionBegin; 1316171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 13175a84ad33SLisandro Dalcin PetscValidPointer(coloring,3); 1318b9d85ea2SLisandro Dalcin if (!dm->ops->getcoloring) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateColoring",((PetscObject)dm)->type_name); 1319b412c318SBarry Smith ierr = (*dm->ops->getcoloring)(dm,ctype,coloring);CHKERRQ(ierr); 132047c6ae99SBarry Smith PetscFunctionReturn(0); 132147c6ae99SBarry Smith } 132247c6ae99SBarry Smith 1323b412c318SBarry Smith /*@ 13248472ad0fSDave May DMCreateMatrix - Gets empty Jacobian for a DM 132547c6ae99SBarry Smith 1326d083f849SBarry Smith Collective on dm 132747c6ae99SBarry Smith 132847c6ae99SBarry Smith Input Parameter: 1329b412c318SBarry Smith . dm - the DM object 133047c6ae99SBarry Smith 133147c6ae99SBarry Smith Output Parameter: 133247c6ae99SBarry Smith . mat - the empty Jacobian 133347c6ae99SBarry Smith 1334073dac72SJed Brown Level: beginner 133547c6ae99SBarry Smith 133695452b02SPatrick Sanan Notes: 133795452b02SPatrick Sanan This properly preallocates the number of nonzeros in the sparse matrix so you 133894013140SBarry Smith do not need to do it yourself. 133994013140SBarry Smith 134094013140SBarry Smith By default it also sets the nonzero structure and puts in the zero entries. To prevent setting 13417889ec69SBarry Smith the nonzero pattern call DMSetMatrixPreallocateOnly() 134294013140SBarry Smith 134394013140SBarry 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 134494013140SBarry Smith internally by PETSc. 134594013140SBarry Smith 134694013140SBarry Smith For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires 1347aa219208SBarry Smith the indices for the global numbering for DMDAs which is complicated. 134894013140SBarry Smith 1349b412c318SBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMSetMatType() 135047c6ae99SBarry Smith 1351aab9d709SJed Brown @*/ 1352b412c318SBarry Smith PetscErrorCode DMCreateMatrix(DM dm,Mat *mat) 135347c6ae99SBarry Smith { 135447c6ae99SBarry Smith PetscErrorCode ierr; 135547c6ae99SBarry Smith 135647c6ae99SBarry Smith PetscFunctionBegin; 1357171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1358c7b7c8a4SJed Brown PetscValidPointer(mat,3); 1359b9d85ea2SLisandro Dalcin if (!dm->ops->creatematrix) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateMatrix",((PetscObject)dm)->type_name); 13605a84ad33SLisandro Dalcin ierr = MatInitializePackage();CHKERRQ(ierr); 1361fdc842d1SBarry Smith ierr = PetscLogEventBegin(DM_CreateMatrix,0,0,0,0);CHKERRQ(ierr); 1362b412c318SBarry Smith ierr = (*dm->ops->creatematrix)(dm,mat);CHKERRQ(ierr); 136376bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1364c6b011d8SStefano Zampini DM mdm; 1365c6b011d8SStefano Zampini 1366c6b011d8SStefano Zampini ierr = MatGetDM(*mat,&mdm);CHKERRQ(ierr); 1367c6b011d8SStefano Zampini if (!mdm) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"DM type '%s' did not attach the DM to the matrix\n",((PetscObject)dm)->type_name); 1368c6b011d8SStefano Zampini } 1369e571a35bSMatthew G. Knepley /* Handle nullspace and near nullspace */ 1370e5e52638SMatthew G. Knepley if (dm->Nf) { 1371e571a35bSMatthew G. Knepley MatNullSpace nullSpace; 1372649ef022SMatthew Knepley PetscInt Nf, f; 1373e571a35bSMatthew G. Knepley 1374e5e52638SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 1375649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1376649ef022SMatthew Knepley if (dm->nullspaceConstructors[f]) { 1377649ef022SMatthew Knepley ierr = (*dm->nullspaceConstructors[f])(dm, f, f, &nullSpace);CHKERRQ(ierr); 1378e571a35bSMatthew G. Knepley ierr = MatSetNullSpace(*mat, nullSpace);CHKERRQ(ierr); 1379e571a35bSMatthew G. Knepley ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr); 1380649ef022SMatthew Knepley break; 1381e571a35bSMatthew G. Knepley } 1382649ef022SMatthew Knepley } 1383649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1384649ef022SMatthew Knepley if (dm->nearnullspaceConstructors[f]) { 1385649ef022SMatthew Knepley ierr = (*dm->nearnullspaceConstructors[f])(dm, f, f, &nullSpace);CHKERRQ(ierr); 1386e571a35bSMatthew G. Knepley ierr = MatSetNearNullSpace(*mat, nullSpace);CHKERRQ(ierr); 1387e571a35bSMatthew G. Knepley ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr); 1388e571a35bSMatthew G. Knepley } 1389e571a35bSMatthew G. Knepley } 1390e571a35bSMatthew G. Knepley } 1391fdc842d1SBarry Smith ierr = PetscLogEventEnd(DM_CreateMatrix,0,0,0,0);CHKERRQ(ierr); 139247c6ae99SBarry Smith PetscFunctionReturn(0); 139347c6ae99SBarry Smith } 139447c6ae99SBarry Smith 1395732e2eb9SMatthew G Knepley /*@ 1396950540a4SJed Brown DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly 1397732e2eb9SMatthew G Knepley preallocated but the nonzero structure and zero values will not be set. 1398732e2eb9SMatthew G Knepley 1399d083f849SBarry Smith Logically Collective on dm 1400732e2eb9SMatthew G Knepley 1401732e2eb9SMatthew G Knepley Input Parameter: 1402732e2eb9SMatthew G Knepley + dm - the DM 1403732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation 1404732e2eb9SMatthew G Knepley 1405732e2eb9SMatthew G Knepley Level: developer 1406b06ff27eSHong Zhang .seealso DMCreateMatrix(), DMSetMatrixStructureOnly() 1407732e2eb9SMatthew G Knepley @*/ 1408732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only) 1409732e2eb9SMatthew G Knepley { 1410732e2eb9SMatthew G Knepley PetscFunctionBegin; 1411732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1412732e2eb9SMatthew G Knepley dm->prealloc_only = only; 1413732e2eb9SMatthew G Knepley PetscFunctionReturn(0); 1414732e2eb9SMatthew G Knepley } 1415732e2eb9SMatthew G Knepley 1416b06ff27eSHong Zhang /*@ 1417b06ff27eSHong Zhang DMSetMatrixStructureOnly - When DMCreateMatrix() is called, the matrix structure will be created 1418b06ff27eSHong Zhang but the array for values will not be allocated. 1419b06ff27eSHong Zhang 1420d083f849SBarry Smith Logically Collective on dm 1421b06ff27eSHong Zhang 1422b06ff27eSHong Zhang Input Parameter: 1423b06ff27eSHong Zhang + dm - the DM 1424b06ff27eSHong Zhang - only - PETSC_TRUE if only want matrix stucture 1425b06ff27eSHong Zhang 1426b06ff27eSHong Zhang Level: developer 1427b06ff27eSHong Zhang .seealso DMCreateMatrix(), DMSetMatrixPreallocateOnly() 1428b06ff27eSHong Zhang @*/ 1429b06ff27eSHong Zhang PetscErrorCode DMSetMatrixStructureOnly(DM dm, PetscBool only) 1430b06ff27eSHong Zhang { 1431b06ff27eSHong Zhang PetscFunctionBegin; 1432b06ff27eSHong Zhang PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1433b06ff27eSHong Zhang dm->structure_only = only; 1434b06ff27eSHong Zhang PetscFunctionReturn(0); 1435b06ff27eSHong Zhang } 1436b06ff27eSHong Zhang 1437a89ea682SMatthew G Knepley /*@C 1438aa1993deSMatthew G Knepley DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray() 1439a89ea682SMatthew G Knepley 1440a89ea682SMatthew G Knepley Not Collective 1441a89ea682SMatthew G Knepley 1442a89ea682SMatthew G Knepley Input Parameters: 1443a89ea682SMatthew G Knepley + dm - the DM object 1444aa1993deSMatthew G Knepley . count - The minium size 144569291d52SBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, MPIU_INT) 1446a89ea682SMatthew G Knepley 1447a89ea682SMatthew G Knepley Output Parameter: 1448a89ea682SMatthew G Knepley . array - the work array 1449a89ea682SMatthew G Knepley 1450a89ea682SMatthew G Knepley Level: developer 1451a89ea682SMatthew G Knepley 1452a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate() 1453a89ea682SMatthew G Knepley @*/ 145469291d52SBarry Smith PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,MPI_Datatype dtype,void *mem) 1455a89ea682SMatthew G Knepley { 1456a89ea682SMatthew G Knepley PetscErrorCode ierr; 1457aa1993deSMatthew G Knepley DMWorkLink link; 145869291d52SBarry Smith PetscMPIInt dsize; 1459a89ea682SMatthew G Knepley 1460a89ea682SMatthew G Knepley PetscFunctionBegin; 1461a89ea682SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1462aa1993deSMatthew G Knepley PetscValidPointer(mem,4); 1463aa1993deSMatthew G Knepley if (dm->workin) { 1464aa1993deSMatthew G Knepley link = dm->workin; 1465aa1993deSMatthew G Knepley dm->workin = dm->workin->next; 1466aa1993deSMatthew G Knepley } else { 1467b00a9115SJed Brown ierr = PetscNewLog(dm,&link);CHKERRQ(ierr); 1468a89ea682SMatthew G Knepley } 1469ffc4695bSBarry Smith ierr = MPI_Type_size(dtype,&dsize);CHKERRMPI(ierr); 14705056fcd2SBarry Smith if (((size_t)dsize*count) > link->bytes) { 1471aa1993deSMatthew G Knepley ierr = PetscFree(link->mem);CHKERRQ(ierr); 1472854ce69bSBarry Smith ierr = PetscMalloc(dsize*count,&link->mem);CHKERRQ(ierr); 1473854ce69bSBarry Smith link->bytes = dsize*count; 1474aa1993deSMatthew G Knepley } 1475aa1993deSMatthew G Knepley link->next = dm->workout; 1476aa1993deSMatthew G Knepley dm->workout = link; 147700d952a4SJed Brown #if defined(PETSC_HAVE_VALGRIND) 147800d952a4SJed Brown VALGRIND_MAKE_MEM_NOACCESS((char*)link->mem + (size_t)dsize*count, link->bytes - (size_t)dsize*count); 147900d952a4SJed Brown VALGRIND_MAKE_MEM_UNDEFINED(link->mem, (size_t)dsize*count); 148000d952a4SJed Brown #endif 1481aa1993deSMatthew G Knepley *(void**)mem = link->mem; 1482a89ea682SMatthew G Knepley PetscFunctionReturn(0); 1483a89ea682SMatthew G Knepley } 1484a89ea682SMatthew G Knepley 1485aa1993deSMatthew G Knepley /*@C 1486aa1993deSMatthew G Knepley DMRestoreWorkArray - Restores a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray() 1487aa1993deSMatthew G Knepley 1488aa1993deSMatthew G Knepley Not Collective 1489aa1993deSMatthew G Knepley 1490aa1993deSMatthew G Knepley Input Parameters: 1491aa1993deSMatthew G Knepley + dm - the DM object 1492aa1993deSMatthew G Knepley . count - The minium size 149369291d52SBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, MPIU_INT 1494aa1993deSMatthew G Knepley 1495aa1993deSMatthew G Knepley Output Parameter: 1496aa1993deSMatthew G Knepley . array - the work array 1497aa1993deSMatthew G Knepley 1498aa1993deSMatthew G Knepley Level: developer 1499aa1993deSMatthew G Knepley 150095452b02SPatrick Sanan Developer Notes: 150195452b02SPatrick Sanan count and dtype are ignored, they are only needed for DMGetWorkArray() 1502aa1993deSMatthew G Knepley .seealso DMDestroy(), DMCreate() 1503aa1993deSMatthew G Knepley @*/ 150469291d52SBarry Smith PetscErrorCode DMRestoreWorkArray(DM dm,PetscInt count,MPI_Datatype dtype,void *mem) 1505aa1993deSMatthew G Knepley { 1506aa1993deSMatthew G Knepley DMWorkLink *p,link; 1507aa1993deSMatthew G Knepley 1508aa1993deSMatthew G Knepley PetscFunctionBegin; 1509aa1993deSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1510aa1993deSMatthew G Knepley PetscValidPointer(mem,4); 1511aa1993deSMatthew G Knepley for (p=&dm->workout; (link=*p); p=&link->next) { 1512aa1993deSMatthew G Knepley if (link->mem == *(void**)mem) { 1513aa1993deSMatthew G Knepley *p = link->next; 1514aa1993deSMatthew G Knepley link->next = dm->workin; 1515aa1993deSMatthew G Knepley dm->workin = link; 15160298fd71SBarry Smith *(void**)mem = NULL; 1517aa1993deSMatthew G Knepley PetscFunctionReturn(0); 1518aa1993deSMatthew G Knepley } 1519aa1993deSMatthew G Knepley } 1520aa1993deSMatthew G Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out"); 1521aa1993deSMatthew G Knepley } 1522e7c4fc90SDmitry Karpeev 15238cda7954SMatthew G. Knepley /*@C 15248cda7954SMatthew G. Knepley DMSetNullSpaceConstructor - Provide a callback function which constructs the nullspace for a given field 15258cda7954SMatthew G. Knepley 15268cda7954SMatthew G. Knepley Logically collective on DM 15278cda7954SMatthew G. Knepley 15288cda7954SMatthew G. Knepley Input Parameters: 15298cda7954SMatthew G. Knepley + dm - The DM 15308cda7954SMatthew G. Knepley . field - The field number for the nullspace 15318cda7954SMatthew G. Knepley - nullsp - A callback to create the nullspace 15328cda7954SMatthew G. Knepley 15338cda7954SMatthew G. Knepley Notes: 15348cda7954SMatthew G. Knepley The callback is intended to provide nullspaces when function spaces are joined or split, such as in DMCreateSubDM(). The calling sequence is 15358cda7954SMatthew G. Knepley $ PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 15368cda7954SMatthew G. Knepley $ dm - The present DM 15378cda7954SMatthew G. Knepley $ origField - The field number given above, in the original DM 15388cda7954SMatthew G. Knepley $ field - The field number in dm 15398cda7954SMatthew G. Knepley $ nullSpace - The nullspace for the given field 15408cda7954SMatthew G. Knepley 15418cda7954SMatthew G. Knepley This function is currently not available from Fortran. 15428cda7954SMatthew G. Knepley 15438cda7954SMatthew G. Knepley .seealso: DMGetNullSpaceConstructor(), DMSetNearNullSpaceConstructor(), DMGetNearNullSpaceConstructor(), DMCreateSubDM(), DMCreateSuperDM() 15448cda7954SMatthew G. Knepley */ 15458cda7954SMatthew G. Knepley PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1546435a35e8SMatthew G Knepley { 1547435a35e8SMatthew G Knepley PetscFunctionBegin; 1548435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 154982f516ccSBarry Smith if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field); 1550435a35e8SMatthew G Knepley dm->nullspaceConstructors[field] = nullsp; 1551435a35e8SMatthew G Knepley PetscFunctionReturn(0); 1552435a35e8SMatthew G Knepley } 1553435a35e8SMatthew G Knepley 15548cda7954SMatthew G. Knepley /*@C 15558cda7954SMatthew G. Knepley DMGetNullSpaceConstructor - Return the callback function which constructs the nullspace for a given field, or NULL 15568cda7954SMatthew G. Knepley 15578cda7954SMatthew G. Knepley Not collective 15588cda7954SMatthew G. Knepley 15598cda7954SMatthew G. Knepley Input Parameters: 15608cda7954SMatthew G. Knepley + dm - The DM 15618cda7954SMatthew G. Knepley - field - The field number for the nullspace 15628cda7954SMatthew G. Knepley 15638cda7954SMatthew G. Knepley Output Parameter: 15648cda7954SMatthew G. Knepley . nullsp - A callback to create the nullspace 15658cda7954SMatthew G. Knepley 15668cda7954SMatthew G. Knepley Notes: 15678cda7954SMatthew G. Knepley The callback is intended to provide nullspaces when function spaces are joined or split, such as in DMCreateSubDM(). The calling sequence is 15688cda7954SMatthew G. Knepley $ PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 15698cda7954SMatthew G. Knepley $ dm - The present DM 15708cda7954SMatthew G. Knepley $ origField - The field number given above, in the original DM 15718cda7954SMatthew G. Knepley $ field - The field number in dm 15728cda7954SMatthew G. Knepley $ nullSpace - The nullspace for the given field 15738cda7954SMatthew G. Knepley 15748cda7954SMatthew G. Knepley This function is currently not available from Fortran. 15758cda7954SMatthew G. Knepley 15768cda7954SMatthew G. Knepley .seealso: DMSetNullSpaceConstructor(), DMSetNearNullSpaceConstructor(), DMGetNearNullSpaceConstructor(), DMCreateSubDM(), DMCreateSuperDM() 15778cda7954SMatthew G. Knepley */ 15788cda7954SMatthew G. Knepley PetscErrorCode DMGetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 15790a50eb56SMatthew G. Knepley { 15800a50eb56SMatthew G. Knepley PetscFunctionBegin; 15810a50eb56SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1582f9d4088aSMatthew G. Knepley PetscValidPointer(nullsp, 3); 15830a50eb56SMatthew G. Knepley if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field); 15840a50eb56SMatthew G. Knepley *nullsp = dm->nullspaceConstructors[field]; 15850a50eb56SMatthew G. Knepley PetscFunctionReturn(0); 15860a50eb56SMatthew G. Knepley } 15870a50eb56SMatthew G. Knepley 15888cda7954SMatthew G. Knepley /*@C 15898cda7954SMatthew G. Knepley DMSetNearNullSpaceConstructor - Provide a callback function which constructs the near-nullspace for a given field 15908cda7954SMatthew G. Knepley 15918cda7954SMatthew G. Knepley Logically collective on DM 15928cda7954SMatthew G. Knepley 15938cda7954SMatthew G. Knepley Input Parameters: 15948cda7954SMatthew G. Knepley + dm - The DM 15958cda7954SMatthew G. Knepley . field - The field number for the nullspace 15968cda7954SMatthew G. Knepley - nullsp - A callback to create the near-nullspace 15978cda7954SMatthew G. Knepley 15988cda7954SMatthew G. Knepley Notes: 15998cda7954SMatthew G. Knepley The callback is intended to provide nullspaces when function spaces are joined or split, such as in DMCreateSubDM(). The calling sequence is 16008cda7954SMatthew G. Knepley $ PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 16018cda7954SMatthew G. Knepley $ dm - The present DM 16028cda7954SMatthew G. Knepley $ origField - The field number given above, in the original DM 16038cda7954SMatthew G. Knepley $ field - The field number in dm 16048cda7954SMatthew G. Knepley $ nullSpace - The nullspace for the given field 16058cda7954SMatthew G. Knepley 16068cda7954SMatthew G. Knepley This function is currently not available from Fortran. 16078cda7954SMatthew G. Knepley 16088cda7954SMatthew G. Knepley .seealso: DMGetNearNullSpaceConstructor(), DMSetNullSpaceConstructor(), DMGetNullSpaceConstructor(), DMCreateSubDM(), DMCreateSuperDM() 16098cda7954SMatthew G. Knepley */ 16108cda7954SMatthew G. Knepley PetscErrorCode DMSetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1611f9d4088aSMatthew G. Knepley { 1612f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1613f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1614f9d4088aSMatthew G. Knepley if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field); 1615f9d4088aSMatthew G. Knepley dm->nearnullspaceConstructors[field] = nullsp; 1616f9d4088aSMatthew G. Knepley PetscFunctionReturn(0); 1617f9d4088aSMatthew G. Knepley } 1618f9d4088aSMatthew G. Knepley 16198cda7954SMatthew G. Knepley /*@C 16208cda7954SMatthew G. Knepley DMGetNearNullSpaceConstructor - Return the callback function which constructs the near-nullspace for a given field, or NULL 16218cda7954SMatthew G. Knepley 16228cda7954SMatthew G. Knepley Not collective 16238cda7954SMatthew G. Knepley 16248cda7954SMatthew G. Knepley Input Parameters: 16258cda7954SMatthew G. Knepley + dm - The DM 16268cda7954SMatthew G. Knepley - field - The field number for the nullspace 16278cda7954SMatthew G. Knepley 16288cda7954SMatthew G. Knepley Output Parameter: 16298cda7954SMatthew G. Knepley . nullsp - A callback to create the near-nullspace 16308cda7954SMatthew G. Knepley 16318cda7954SMatthew G. Knepley Notes: 16328cda7954SMatthew G. Knepley The callback is intended to provide nullspaces when function spaces are joined or split, such as in DMCreateSubDM(). The calling sequence is 16338cda7954SMatthew G. Knepley $ PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 16348cda7954SMatthew G. Knepley $ dm - The present DM 16358cda7954SMatthew G. Knepley $ origField - The field number given above, in the original DM 16368cda7954SMatthew G. Knepley $ field - The field number in dm 16378cda7954SMatthew G. Knepley $ nullSpace - The nullspace for the given field 16388cda7954SMatthew G. Knepley 16398cda7954SMatthew G. Knepley This function is currently not available from Fortran. 16408cda7954SMatthew G. Knepley 16418cda7954SMatthew G. Knepley .seealso: DMSetNearNullSpaceConstructor(), DMSetNullSpaceConstructor(), DMGetNullSpaceConstructor(), DMCreateSubDM(), DMCreateSuperDM() 16428cda7954SMatthew G. Knepley */ 16438cda7954SMatthew G. Knepley PetscErrorCode DMGetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1644f9d4088aSMatthew G. Knepley { 1645f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1646f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1647f9d4088aSMatthew G. Knepley PetscValidPointer(nullsp, 3); 1648f9d4088aSMatthew G. Knepley if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field); 1649f9d4088aSMatthew G. Knepley *nullsp = dm->nearnullspaceConstructors[field]; 1650f9d4088aSMatthew G. Knepley PetscFunctionReturn(0); 1651f9d4088aSMatthew G. Knepley } 1652f9d4088aSMatthew G. Knepley 16534f3b5142SJed Brown /*@C 16544d343eeaSMatthew G Knepley DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field 16554d343eeaSMatthew G Knepley 16564d343eeaSMatthew G Knepley Not collective 16574d343eeaSMatthew G Knepley 16584d343eeaSMatthew G Knepley Input Parameter: 16594d343eeaSMatthew G Knepley . dm - the DM object 16604d343eeaSMatthew G Knepley 16614d343eeaSMatthew G Knepley Output Parameters: 16620298fd71SBarry Smith + numFields - The number of fields (or NULL if not requested) 16630298fd71SBarry Smith . fieldNames - The name for each field (or NULL if not requested) 16640298fd71SBarry Smith - fields - The global indices for each field (or NULL if not requested) 16654d343eeaSMatthew G Knepley 16664d343eeaSMatthew G Knepley Level: intermediate 16674d343eeaSMatthew G Knepley 166821c9b008SJed Brown Notes: 166921c9b008SJed Brown The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 167021c9b008SJed Brown PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with 167121c9b008SJed Brown PetscFree(). 167221c9b008SJed Brown 16734d343eeaSMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 16744d343eeaSMatthew G Knepley @*/ 167537d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields) 16764d343eeaSMatthew G Knepley { 167737d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 16784d343eeaSMatthew G Knepley PetscErrorCode ierr; 16794d343eeaSMatthew G Knepley 16804d343eeaSMatthew G Knepley PetscFunctionBegin; 16814d343eeaSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 168269ca1f37SDmitry Karpeev if (numFields) { 1683534a8f05SLisandro Dalcin PetscValidIntPointer(numFields,2); 168469ca1f37SDmitry Karpeev *numFields = 0; 168569ca1f37SDmitry Karpeev } 168637d0c07bSMatthew G Knepley if (fieldNames) { 168737d0c07bSMatthew G Knepley PetscValidPointer(fieldNames,3); 16880298fd71SBarry Smith *fieldNames = NULL; 168969ca1f37SDmitry Karpeev } 169069ca1f37SDmitry Karpeev if (fields) { 169169ca1f37SDmitry Karpeev PetscValidPointer(fields,4); 16920298fd71SBarry Smith *fields = NULL; 169369ca1f37SDmitry Karpeev } 169492fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 169537d0c07bSMatthew G Knepley if (section) { 16963a544194SStefano Zampini PetscInt *fieldSizes, *fieldNc, **fieldIndices; 169737d0c07bSMatthew G Knepley PetscInt nF, f, pStart, pEnd, p; 169837d0c07bSMatthew G Knepley 1699e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 170037d0c07bSMatthew G Knepley ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr); 17013a544194SStefano Zampini ierr = PetscMalloc3(nF,&fieldSizes,nF,&fieldNc,nF,&fieldIndices);CHKERRQ(ierr); 170237d0c07bSMatthew G Knepley ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 170337d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 170437d0c07bSMatthew G Knepley fieldSizes[f] = 0; 17053a544194SStefano Zampini ierr = PetscSectionGetFieldComponents(section, f, &fieldNc[f]);CHKERRQ(ierr); 170637d0c07bSMatthew G Knepley } 170737d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 170837d0c07bSMatthew G Knepley PetscInt gdof; 170937d0c07bSMatthew G Knepley 171037d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 171137d0c07bSMatthew G Knepley if (gdof > 0) { 171237d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 17133a544194SStefano Zampini PetscInt fdof, fcdof, fpdof; 171437d0c07bSMatthew G Knepley 171537d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 171637d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 17173a544194SStefano Zampini fpdof = fdof-fcdof; 17183a544194SStefano Zampini if (fpdof && fpdof != fieldNc[f]) { 17193a544194SStefano Zampini /* Layout does not admit a pointwise block size */ 17203a544194SStefano Zampini fieldNc[f] = 1; 17213a544194SStefano Zampini } 17223a544194SStefano Zampini fieldSizes[f] += fpdof; 172337d0c07bSMatthew G Knepley } 172437d0c07bSMatthew G Knepley } 172537d0c07bSMatthew G Knepley } 172637d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 1727785e854fSJed Brown ierr = PetscMalloc1(fieldSizes[f], &fieldIndices[f]);CHKERRQ(ierr); 172837d0c07bSMatthew G Knepley fieldSizes[f] = 0; 172937d0c07bSMatthew G Knepley } 173037d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 173137d0c07bSMatthew G Knepley PetscInt gdof, goff; 173237d0c07bSMatthew G Knepley 173337d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 173437d0c07bSMatthew G Knepley if (gdof > 0) { 173537d0c07bSMatthew G Knepley ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr); 173637d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 173737d0c07bSMatthew G Knepley PetscInt fdof, fcdof, fc; 173837d0c07bSMatthew G Knepley 173937d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 174037d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 174137d0c07bSMatthew G Knepley for (fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) { 174237d0c07bSMatthew G Knepley fieldIndices[f][fieldSizes[f]] = goff++; 174337d0c07bSMatthew G Knepley } 174437d0c07bSMatthew G Knepley } 174537d0c07bSMatthew G Knepley } 174637d0c07bSMatthew G Knepley } 17478865f1eaSKarl Rupp if (numFields) *numFields = nF; 174837d0c07bSMatthew G Knepley if (fieldNames) { 1749785e854fSJed Brown ierr = PetscMalloc1(nF, fieldNames);CHKERRQ(ierr); 175037d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 175137d0c07bSMatthew G Knepley const char *fieldName; 175237d0c07bSMatthew G Knepley 175337d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr); 175437d0c07bSMatthew G Knepley ierr = PetscStrallocpy(fieldName, (char**) &(*fieldNames)[f]);CHKERRQ(ierr); 175537d0c07bSMatthew G Knepley } 175637d0c07bSMatthew G Knepley } 175737d0c07bSMatthew G Knepley if (fields) { 1758785e854fSJed Brown ierr = PetscMalloc1(nF, fields);CHKERRQ(ierr); 175937d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 17603a544194SStefano Zampini PetscInt bs, in[2], out[2]; 17613a544194SStefano Zampini 176282f516ccSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr); 17633a544194SStefano Zampini in[0] = -fieldNc[f]; 17643a544194SStefano Zampini in[1] = fieldNc[f]; 17653a544194SStefano Zampini ierr = MPIU_Allreduce(in, out, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 17663a544194SStefano Zampini bs = (-out[0] == out[1]) ? out[1] : 1; 17673a544194SStefano Zampini ierr = ISSetBlockSize((*fields)[f], bs);CHKERRQ(ierr); 176837d0c07bSMatthew G Knepley } 176937d0c07bSMatthew G Knepley } 17703a544194SStefano Zampini ierr = PetscFree3(fieldSizes,fieldNc,fieldIndices);CHKERRQ(ierr); 17718865f1eaSKarl Rupp } else if (dm->ops->createfieldis) { 17728865f1eaSKarl Rupp ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr); 177369ca1f37SDmitry Karpeev } 17744d343eeaSMatthew G Knepley PetscFunctionReturn(0); 17754d343eeaSMatthew G Knepley } 17764d343eeaSMatthew G Knepley 177716621825SDmitry Karpeev 177816621825SDmitry Karpeev /*@C 177916621825SDmitry Karpeev DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems 178016621825SDmitry Karpeev corresponding to different fields: each IS contains the global indices of the dofs of the 178116621825SDmitry Karpeev corresponding field. The optional list of DMs define the DM for each subproblem. 1782e7c4fc90SDmitry Karpeev Generalizes DMCreateFieldIS(). 1783e7c4fc90SDmitry Karpeev 1784e7c4fc90SDmitry Karpeev Not collective 1785e7c4fc90SDmitry Karpeev 1786e7c4fc90SDmitry Karpeev Input Parameter: 1787e7c4fc90SDmitry Karpeev . dm - the DM object 1788e7c4fc90SDmitry Karpeev 1789e7c4fc90SDmitry Karpeev Output Parameters: 17900298fd71SBarry Smith + len - The number of subproblems in the field decomposition (or NULL if not requested) 17910298fd71SBarry Smith . namelist - The name for each field (or NULL if not requested) 17920298fd71SBarry Smith . islist - The global indices for each field (or NULL if not requested) 17930298fd71SBarry Smith - dmlist - The DMs for each field subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined) 1794e7c4fc90SDmitry Karpeev 1795e7c4fc90SDmitry Karpeev Level: intermediate 1796e7c4fc90SDmitry Karpeev 1797e7c4fc90SDmitry Karpeev Notes: 1798e7c4fc90SDmitry Karpeev The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 1799e7c4fc90SDmitry Karpeev PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(), 1800e7c4fc90SDmitry Karpeev and all of the arrays should be freed with PetscFree(). 1801e7c4fc90SDmitry Karpeev 1802e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 1803e7c4fc90SDmitry Karpeev @*/ 180416621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist) 1805e7c4fc90SDmitry Karpeev { 1806e7c4fc90SDmitry Karpeev PetscErrorCode ierr; 1807e7c4fc90SDmitry Karpeev 1808e7c4fc90SDmitry Karpeev PetscFunctionBegin; 1809e7c4fc90SDmitry Karpeev PetscValidHeaderSpecific(dm,DM_CLASSID,1); 18108865f1eaSKarl Rupp if (len) { 1811534a8f05SLisandro Dalcin PetscValidIntPointer(len,2); 18128865f1eaSKarl Rupp *len = 0; 18138865f1eaSKarl Rupp } 18148865f1eaSKarl Rupp if (namelist) { 18158865f1eaSKarl Rupp PetscValidPointer(namelist,3); 1816ea78f98cSLisandro Dalcin *namelist = NULL; 18178865f1eaSKarl Rupp } 18188865f1eaSKarl Rupp if (islist) { 18198865f1eaSKarl Rupp PetscValidPointer(islist,4); 1820ea78f98cSLisandro Dalcin *islist = NULL; 18218865f1eaSKarl Rupp } 18228865f1eaSKarl Rupp if (dmlist) { 18238865f1eaSKarl Rupp PetscValidPointer(dmlist,5); 1824ea78f98cSLisandro Dalcin *dmlist = NULL; 18258865f1eaSKarl Rupp } 1826f3f0edfdSDmitry Karpeev /* 1827f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 1828f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 1829f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 1830f3f0edfdSDmitry Karpeev */ 1831ce94432eSBarry Smith if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 183216621825SDmitry Karpeev if (!dm->ops->createfielddecomposition) { 1833435a35e8SMatthew G Knepley PetscSection section; 1834435a35e8SMatthew G Knepley PetscInt numFields, f; 1835435a35e8SMatthew G Knepley 183692fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 1837435a35e8SMatthew G Knepley if (section) {ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr);} 1838435a35e8SMatthew G Knepley if (section && numFields && dm->ops->createsubdm) { 1839f25d98f1SMatthew G. Knepley if (len) *len = numFields; 184003dc3394SMatthew G. Knepley if (namelist) {ierr = PetscMalloc1(numFields,namelist);CHKERRQ(ierr);} 184103dc3394SMatthew G. Knepley if (islist) {ierr = PetscMalloc1(numFields,islist);CHKERRQ(ierr);} 184203dc3394SMatthew G. Knepley if (dmlist) {ierr = PetscMalloc1(numFields,dmlist);CHKERRQ(ierr);} 1843435a35e8SMatthew G Knepley for (f = 0; f < numFields; ++f) { 1844435a35e8SMatthew G Knepley const char *fieldName; 1845435a35e8SMatthew G Knepley 184603dc3394SMatthew G. Knepley ierr = DMCreateSubDM(dm, 1, &f, islist ? &(*islist)[f] : NULL, dmlist ? &(*dmlist)[f] : NULL);CHKERRQ(ierr); 184703dc3394SMatthew G. Knepley if (namelist) { 1848435a35e8SMatthew G Knepley ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr); 1849435a35e8SMatthew G Knepley ierr = PetscStrallocpy(fieldName, (char**) &(*namelist)[f]);CHKERRQ(ierr); 1850435a35e8SMatthew G Knepley } 185103dc3394SMatthew G. Knepley } 1852435a35e8SMatthew G Knepley } else { 185369ca1f37SDmitry Karpeev ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr); 1854e7c4fc90SDmitry Karpeev /* By default there are no DMs associated with subproblems. */ 18550298fd71SBarry Smith if (dmlist) *dmlist = NULL; 1856e7c4fc90SDmitry Karpeev } 18578865f1eaSKarl Rupp } else { 185816621825SDmitry Karpeev ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist);CHKERRQ(ierr); 185916621825SDmitry Karpeev } 186016621825SDmitry Karpeev PetscFunctionReturn(0); 186116621825SDmitry Karpeev } 186216621825SDmitry Karpeev 1863564cec59SMatthew G. Knepley /*@ 1864435a35e8SMatthew G Knepley DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in. 1865435a35e8SMatthew G Knepley The fields are defined by DMCreateFieldIS(). 1866435a35e8SMatthew G Knepley 1867435a35e8SMatthew G Knepley Not collective 1868435a35e8SMatthew G Knepley 1869435a35e8SMatthew G Knepley Input Parameters: 18702adcc780SMatthew G. Knepley + dm - The DM object 18712adcc780SMatthew G. Knepley . numFields - The number of fields in this subproblem 18722adcc780SMatthew G. Knepley - fields - The field numbers of the selected fields 1873435a35e8SMatthew G Knepley 1874435a35e8SMatthew G Knepley Output Parameters: 18752adcc780SMatthew G. Knepley + is - The global indices for the subproblem 18762adcc780SMatthew G. Knepley - subdm - The DM for the subproblem 1877435a35e8SMatthew G Knepley 18785d3b26e6SMatthew G. Knepley Note: You need to call DMPlexSetMigrationSF() on the original DM if you want the Global-To-Natural map to be automatically constructed 18795d3b26e6SMatthew G. Knepley 1880435a35e8SMatthew G Knepley Level: intermediate 1881435a35e8SMatthew G Knepley 18825d3b26e6SMatthew G. Knepley .seealso DMPlexSetMigrationSF(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 1883435a35e8SMatthew G Knepley @*/ 188437bc7515SMatthew G. Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 1885435a35e8SMatthew G Knepley { 1886435a35e8SMatthew G Knepley PetscErrorCode ierr; 1887435a35e8SMatthew G Knepley 1888435a35e8SMatthew G Knepley PetscFunctionBegin; 1889435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1890435a35e8SMatthew G Knepley PetscValidPointer(fields,3); 18918865f1eaSKarl Rupp if (is) PetscValidPointer(is,4); 18928865f1eaSKarl Rupp if (subdm) PetscValidPointer(subdm,5); 1893b9d85ea2SLisandro Dalcin if (!dm->ops->createsubdm) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateSubDM",((PetscObject)dm)->type_name); 1894435a35e8SMatthew G Knepley ierr = (*dm->ops->createsubdm)(dm, numFields, fields, is, subdm);CHKERRQ(ierr); 1895435a35e8SMatthew G Knepley PetscFunctionReturn(0); 1896435a35e8SMatthew G Knepley } 1897435a35e8SMatthew G Knepley 18982adcc780SMatthew G. Knepley /*@C 18992adcc780SMatthew G. Knepley DMCreateSuperDM - Returns an arrays of ISes and DM encapsulating a superproblem defined by the DMs passed in. 19002adcc780SMatthew G. Knepley 19012adcc780SMatthew G. Knepley Not collective 19022adcc780SMatthew G. Knepley 19032adcc780SMatthew G. Knepley Input Parameter: 19042adcc780SMatthew G. Knepley + dms - The DM objects 19052adcc780SMatthew G. Knepley - len - The number of DMs 19062adcc780SMatthew G. Knepley 19072adcc780SMatthew G. Knepley Output Parameters: 1908a42bd24dSMatthew G. Knepley + is - The global indices for the subproblem, or NULL 19092adcc780SMatthew G. Knepley - superdm - The DM for the superproblem 19102adcc780SMatthew G. Knepley 19115d3b26e6SMatthew G. Knepley Note: You need to call DMPlexSetMigrationSF() on the original DM if you want the Global-To-Natural map to be automatically constructed 19125d3b26e6SMatthew G. Knepley 19132adcc780SMatthew G. Knepley Level: intermediate 19142adcc780SMatthew G. Knepley 19155d3b26e6SMatthew G. Knepley .seealso DMPlexSetMigrationSF(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 19162adcc780SMatthew G. Knepley @*/ 19172adcc780SMatthew G. Knepley PetscErrorCode DMCreateSuperDM(DM dms[], PetscInt len, IS **is, DM *superdm) 19182adcc780SMatthew G. Knepley { 19192adcc780SMatthew G. Knepley PetscInt i; 19202adcc780SMatthew G. Knepley PetscErrorCode ierr; 19212adcc780SMatthew G. Knepley 19222adcc780SMatthew G. Knepley PetscFunctionBegin; 19232adcc780SMatthew G. Knepley PetscValidPointer(dms,1); 19242adcc780SMatthew G. Knepley for (i = 0; i < len; ++i) {PetscValidHeaderSpecific(dms[i],DM_CLASSID,1);} 19252adcc780SMatthew G. Knepley if (is) PetscValidPointer(is,3); 1926a42bd24dSMatthew G. Knepley PetscValidPointer(superdm,4); 19272adcc780SMatthew G. Knepley if (len < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of DMs must be nonnegative: %D", len); 19282adcc780SMatthew G. Knepley if (len) { 1929b9d85ea2SLisandro Dalcin DM dm = dms[0]; 1930b9d85ea2SLisandro Dalcin if (!dm->ops->createsuperdm) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateSuperDM",((PetscObject)dm)->type_name); 1931b9d85ea2SLisandro Dalcin ierr = (*dm->ops->createsuperdm)(dms, len, is, superdm);CHKERRQ(ierr); 19322adcc780SMatthew G. Knepley } 19332adcc780SMatthew G. Knepley PetscFunctionReturn(0); 19342adcc780SMatthew G. Knepley } 19352adcc780SMatthew G. Knepley 193616621825SDmitry Karpeev 193716621825SDmitry Karpeev /*@C 19388d4ac253SDmitry Karpeev DMCreateDomainDecomposition - Returns lists of IS objects defining a decomposition of a problem into subproblems 19398d4ac253SDmitry Karpeev corresponding to restrictions to pairs nested subdomains: each IS contains the global 19408d4ac253SDmitry Karpeev indices of the dofs of the corresponding subdomains. The inner subdomains conceptually 19418d4ac253SDmitry Karpeev define a nonoverlapping covering, while outer subdomains can overlap. 19428d4ac253SDmitry Karpeev The optional list of DMs define the DM for each subproblem. 194316621825SDmitry Karpeev 194416621825SDmitry Karpeev Not collective 194516621825SDmitry Karpeev 194616621825SDmitry Karpeev Input Parameter: 194716621825SDmitry Karpeev . dm - the DM object 194816621825SDmitry Karpeev 194916621825SDmitry Karpeev Output Parameters: 19500298fd71SBarry Smith + len - The number of subproblems in the domain decomposition (or NULL if not requested) 19510298fd71SBarry Smith . namelist - The name for each subdomain (or NULL if not requested) 19520298fd71SBarry Smith . innerislist - The global indices for each inner subdomain (or NULL, if not requested) 19530298fd71SBarry Smith . outerislist - The global indices for each outer subdomain (or NULL, if not requested) 19540298fd71SBarry Smith - dmlist - The DMs for each subdomain subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined) 195516621825SDmitry Karpeev 195616621825SDmitry Karpeev Level: intermediate 195716621825SDmitry Karpeev 195816621825SDmitry Karpeev Notes: 195916621825SDmitry Karpeev The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 196016621825SDmitry Karpeev PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(), 196116621825SDmitry Karpeev and all of the arrays should be freed with PetscFree(). 196216621825SDmitry Karpeev 1963245d9833Sprj- .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldDecomposition() 196416621825SDmitry Karpeev @*/ 19658d4ac253SDmitry Karpeev PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist) 196616621825SDmitry Karpeev { 196716621825SDmitry Karpeev PetscErrorCode ierr; 1968be081cd6SPeter Brune DMSubDomainHookLink link; 1969be081cd6SPeter Brune PetscInt i,l; 197016621825SDmitry Karpeev 197116621825SDmitry Karpeev PetscFunctionBegin; 197216621825SDmitry Karpeev PetscValidHeaderSpecific(dm,DM_CLASSID,1); 197314a18fd3SPeter Brune if (len) {PetscValidPointer(len,2); *len = 0;} 19740298fd71SBarry Smith if (namelist) {PetscValidPointer(namelist,3); *namelist = NULL;} 19750298fd71SBarry Smith if (innerislist) {PetscValidPointer(innerislist,4); *innerislist = NULL;} 19760298fd71SBarry Smith if (outerislist) {PetscValidPointer(outerislist,5); *outerislist = NULL;} 19770298fd71SBarry Smith if (dmlist) {PetscValidPointer(dmlist,6); *dmlist = NULL;} 1978f3f0edfdSDmitry Karpeev /* 1979f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 1980f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 1981f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 1982f3f0edfdSDmitry Karpeev */ 1983ce94432eSBarry Smith if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 198416621825SDmitry Karpeev if (dm->ops->createdomaindecomposition) { 1985be081cd6SPeter Brune ierr = (*dm->ops->createdomaindecomposition)(dm,&l,namelist,innerislist,outerislist,dmlist);CHKERRQ(ierr); 198614a18fd3SPeter Brune /* copy subdomain hooks and context over to the subdomain DMs */ 1987f891f5b9SPatrick Sanan if (dmlist && *dmlist) { 1988be081cd6SPeter Brune for (i = 0; i < l; i++) { 1989be081cd6SPeter Brune for (link=dm->subdomainhook; link; link=link->next) { 1990be081cd6SPeter Brune if (link->ddhook) {ierr = (*link->ddhook)(dm,(*dmlist)[i],link->ctx);CHKERRQ(ierr);} 1991be081cd6SPeter Brune } 1992648262bbSPatrick Sanan if (dm->ctx) (*dmlist)[i]->ctx = dm->ctx; 1993e7c4fc90SDmitry Karpeev } 199414a18fd3SPeter Brune } 199514a18fd3SPeter Brune if (len) *len = l; 199614a18fd3SPeter Brune } 1997e30e807fSPeter Brune PetscFunctionReturn(0); 1998e30e807fSPeter Brune } 1999e30e807fSPeter Brune 2000e30e807fSPeter Brune 2001e30e807fSPeter Brune /*@C 2002e30e807fSPeter Brune DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector 2003e30e807fSPeter Brune 2004e30e807fSPeter Brune Not collective 2005e30e807fSPeter Brune 2006e30e807fSPeter Brune Input Parameters: 2007e30e807fSPeter Brune + dm - the DM object 2008e30e807fSPeter Brune . n - the number of subdomain scatters 2009e30e807fSPeter Brune - subdms - the local subdomains 2010e30e807fSPeter Brune 2011e30e807fSPeter Brune Output Parameters: 2012e30e807fSPeter Brune + n - the number of scatters returned 2013e30e807fSPeter Brune . iscat - scatter from global vector to nonoverlapping global vector entries on subdomain 2014e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain 2015e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts) 2016e30e807fSPeter Brune 201795452b02SPatrick Sanan Notes: 201895452b02SPatrick Sanan This is an alternative to the iis and ois arguments in DMCreateDomainDecomposition that allow for the solution 2019e30e807fSPeter Brune of general nonlinear problems with overlapping subdomain methods. While merely having index sets that enable subsets 2020e30e807fSPeter Brune of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of 2021e30e807fSPeter Brune solution and residual data. 2022e30e807fSPeter Brune 2023e30e807fSPeter Brune Level: developer 2024e30e807fSPeter Brune 2025e30e807fSPeter Brune .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 2026e30e807fSPeter Brune @*/ 2027e30e807fSPeter Brune PetscErrorCode DMCreateDomainDecompositionScatters(DM dm,PetscInt n,DM *subdms,VecScatter **iscat,VecScatter **oscat,VecScatter **gscat) 2028e30e807fSPeter Brune { 2029e30e807fSPeter Brune PetscErrorCode ierr; 2030e30e807fSPeter Brune 2031e30e807fSPeter Brune PetscFunctionBegin; 2032e30e807fSPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2033e30e807fSPeter Brune PetscValidPointer(subdms,3); 2034b9d85ea2SLisandro Dalcin if (!dm->ops->createddscatters) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateDomainDecompositionScatters",((PetscObject)dm)->type_name); 2035e30e807fSPeter Brune ierr = (*dm->ops->createddscatters)(dm,n,subdms,iscat,oscat,gscat);CHKERRQ(ierr); 2036e7c4fc90SDmitry Karpeev PetscFunctionReturn(0); 2037e7c4fc90SDmitry Karpeev } 2038e7c4fc90SDmitry Karpeev 203947c6ae99SBarry Smith /*@ 204047c6ae99SBarry Smith DMRefine - Refines a DM object 204147c6ae99SBarry Smith 2042d083f849SBarry Smith Collective on dm 204347c6ae99SBarry Smith 204447c6ae99SBarry Smith Input Parameter: 204547c6ae99SBarry Smith + dm - the DM object 204691d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL) 204747c6ae99SBarry Smith 204847c6ae99SBarry Smith Output Parameter: 20490298fd71SBarry Smith . dmf - the refined DM, or NULL 2050ae0a1c52SMatthew G Knepley 2051412e9a14SMatthew G. Knepley Options Dtabase Keys: 2052412e9a14SMatthew G. Knepley . -dm_plex_cell_refiner <strategy> - chooses the refinement strategy, e.g. regular, tohex 2053412e9a14SMatthew G. Knepley 20540298fd71SBarry Smith Note: If no refinement was done, the return value is NULL 205547c6ae99SBarry Smith 205647c6ae99SBarry Smith Level: developer 205747c6ae99SBarry Smith 2058e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 205947c6ae99SBarry Smith @*/ 20607087cfbeSBarry Smith PetscErrorCode DMRefine(DM dm,MPI_Comm comm,DM *dmf) 206147c6ae99SBarry Smith { 206247c6ae99SBarry Smith PetscErrorCode ierr; 2063c833c3b5SJed Brown DMRefineHookLink link; 206447c6ae99SBarry Smith 206547c6ae99SBarry Smith PetscFunctionBegin; 2066732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2067b9d85ea2SLisandro Dalcin if (!dm->ops->refine) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMRefine",((PetscObject)dm)->type_name); 20681ac00216SMatthew G. Knepley ierr = PetscLogEventBegin(DM_Refine,dm,0,0,0);CHKERRQ(ierr); 206947c6ae99SBarry Smith ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr); 20704057135bSMatthew G Knepley if (*dmf) { 207143842a1eSJed Brown (*dmf)->ops->creatematrix = dm->ops->creatematrix; 20728865f1eaSKarl Rupp 20738cd211a4SJed Brown ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr); 20748865f1eaSKarl Rupp 2075644e2e5bSBarry Smith (*dmf)->ctx = dm->ctx; 20760598a293SJed Brown (*dmf)->leveldown = dm->leveldown; 2077656b349aSBarry Smith (*dmf)->levelup = dm->levelup + 1; 20788865f1eaSKarl Rupp 2079e4b4b23bSJed Brown ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr); 2080c833c3b5SJed Brown for (link=dm->refinehook; link; link=link->next) { 20818865f1eaSKarl Rupp if (link->refinehook) { 20828865f1eaSKarl Rupp ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr); 20838865f1eaSKarl Rupp } 2084c833c3b5SJed Brown } 2085c833c3b5SJed Brown } 20861ac00216SMatthew G. Knepley ierr = PetscLogEventEnd(DM_Refine,dm,0,0,0);CHKERRQ(ierr); 2087c833c3b5SJed Brown PetscFunctionReturn(0); 2088c833c3b5SJed Brown } 2089c833c3b5SJed Brown 2090bb9467b5SJed Brown /*@C 2091c833c3b5SJed Brown DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid 2092c833c3b5SJed Brown 2093c833c3b5SJed Brown Logically Collective 2094c833c3b5SJed Brown 2095c833c3b5SJed Brown Input Arguments: 2096c833c3b5SJed Brown + coarse - nonlinear solver context on which to run a hook when restricting to a coarser level 2097c833c3b5SJed Brown . refinehook - function to run when setting up a coarser level 2098c833c3b5SJed Brown . interphook - function to run to update data on finer levels (once per SNESSolve()) 20990298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2100c833c3b5SJed Brown 2101c833c3b5SJed Brown Calling sequence of refinehook: 2102c833c3b5SJed Brown $ refinehook(DM coarse,DM fine,void *ctx); 2103c833c3b5SJed Brown 2104c833c3b5SJed Brown + coarse - coarse level DM 2105c833c3b5SJed Brown . fine - fine level DM to interpolate problem to 2106c833c3b5SJed Brown - ctx - optional user-defined function context 2107c833c3b5SJed Brown 2108c833c3b5SJed Brown Calling sequence for interphook: 2109c833c3b5SJed Brown $ interphook(DM coarse,Mat interp,DM fine,void *ctx) 2110c833c3b5SJed Brown 2111c833c3b5SJed Brown + coarse - coarse level DM 2112c833c3b5SJed Brown . interp - matrix interpolating a coarse-level solution to the finer grid 2113c833c3b5SJed Brown . fine - fine level DM to update 2114c833c3b5SJed Brown - ctx - optional user-defined function context 2115c833c3b5SJed Brown 2116c833c3b5SJed Brown Level: advanced 2117c833c3b5SJed Brown 2118c833c3b5SJed Brown Notes: 2119c833c3b5SJed Brown This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing 2120c833c3b5SJed Brown 2121c833c3b5SJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 2122c833c3b5SJed Brown 2123bb9467b5SJed Brown This function is currently not available from Fortran. 2124bb9467b5SJed Brown 2125c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 2126c833c3b5SJed Brown @*/ 2127c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx) 2128c833c3b5SJed Brown { 2129c833c3b5SJed Brown PetscErrorCode ierr; 2130c833c3b5SJed Brown DMRefineHookLink link,*p; 2131c833c3b5SJed Brown 2132c833c3b5SJed Brown PetscFunctionBegin; 2133c833c3b5SJed Brown PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 21343d8e3701SJed Brown for (p=&coarse->refinehook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */ 21353d8e3701SJed Brown if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) PetscFunctionReturn(0); 21363d8e3701SJed Brown } 213795dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 2138c833c3b5SJed Brown link->refinehook = refinehook; 2139c833c3b5SJed Brown link->interphook = interphook; 2140c833c3b5SJed Brown link->ctx = ctx; 21410298fd71SBarry Smith link->next = NULL; 2142c833c3b5SJed Brown *p = link; 2143c833c3b5SJed Brown PetscFunctionReturn(0); 2144c833c3b5SJed Brown } 2145c833c3b5SJed Brown 21463d8e3701SJed Brown /*@C 21473d8e3701SJed Brown DMRefineHookRemove - remove a callback from the list of hooks to be run when interpolating a nonlinear problem to a finer grid 21483d8e3701SJed Brown 21493d8e3701SJed Brown Logically Collective 21503d8e3701SJed Brown 21513d8e3701SJed Brown Input Arguments: 21523d8e3701SJed Brown + coarse - nonlinear solver context on which to run a hook when restricting to a coarser level 21533d8e3701SJed Brown . refinehook - function to run when setting up a coarser level 21543d8e3701SJed Brown . interphook - function to run to update data on finer levels (once per SNESSolve()) 21553d8e3701SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 21563d8e3701SJed Brown 21573d8e3701SJed Brown Level: advanced 21583d8e3701SJed Brown 21593d8e3701SJed Brown Notes: 21603d8e3701SJed Brown This function does nothing if the hook is not in the list. 21613d8e3701SJed Brown 21623d8e3701SJed Brown This function is currently not available from Fortran. 21633d8e3701SJed Brown 21643d8e3701SJed Brown .seealso: DMCoarsenHookRemove(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 21653d8e3701SJed Brown @*/ 21663d8e3701SJed Brown PetscErrorCode DMRefineHookRemove(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx) 21673d8e3701SJed Brown { 21683d8e3701SJed Brown PetscErrorCode ierr; 21693d8e3701SJed Brown DMRefineHookLink link,*p; 21703d8e3701SJed Brown 21713d8e3701SJed Brown PetscFunctionBegin; 21723d8e3701SJed Brown PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 21733d8e3701SJed Brown for (p=&coarse->refinehook; *p; p=&(*p)->next) { /* Search the list of current hooks */ 21743d8e3701SJed Brown if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) { 21753d8e3701SJed Brown link = *p; 21763d8e3701SJed Brown *p = link->next; 21773d8e3701SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 21783d8e3701SJed Brown break; 21793d8e3701SJed Brown } 21803d8e3701SJed Brown } 21813d8e3701SJed Brown PetscFunctionReturn(0); 21823d8e3701SJed Brown } 21833d8e3701SJed Brown 2184c833c3b5SJed Brown /*@ 2185c833c3b5SJed Brown DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd() 2186c833c3b5SJed Brown 2187c833c3b5SJed Brown Collective if any hooks are 2188c833c3b5SJed Brown 2189c833c3b5SJed Brown Input Arguments: 2190c833c3b5SJed Brown + coarse - coarser DM to use as a base 2191e91eccc2SStefano Zampini . interp - interpolation matrix, apply using MatInterpolate() 2192c833c3b5SJed Brown - fine - finer DM to update 2193c833c3b5SJed Brown 2194c833c3b5SJed Brown Level: developer 2195c833c3b5SJed Brown 2196c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate() 2197c833c3b5SJed Brown @*/ 2198c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine) 2199c833c3b5SJed Brown { 2200c833c3b5SJed Brown PetscErrorCode ierr; 2201c833c3b5SJed Brown DMRefineHookLink link; 2202c833c3b5SJed Brown 2203c833c3b5SJed Brown PetscFunctionBegin; 2204c833c3b5SJed Brown for (link=fine->refinehook; link; link=link->next) { 22058865f1eaSKarl Rupp if (link->interphook) { 22068865f1eaSKarl Rupp ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr); 22078865f1eaSKarl Rupp } 22084057135bSMatthew G Knepley } 220947c6ae99SBarry Smith PetscFunctionReturn(0); 221047c6ae99SBarry Smith } 221147c6ae99SBarry Smith 2212eb3f98d2SBarry Smith /*@ 22131f3379b2SToby Isaac DMInterpolateSolution - Interpolates a solution from a coarse mesh to a fine mesh. 22141f3379b2SToby Isaac 22151f3379b2SToby Isaac Collective on DM 22161f3379b2SToby Isaac 22171f3379b2SToby Isaac Input Arguments: 22181f3379b2SToby Isaac + coarse - coarse DM 22191f3379b2SToby Isaac . fine - fine DM 22201f3379b2SToby Isaac . interp - (optional) the matrix computed by DMCreateInterpolation(). Implementations may not need this, but if it 22211f3379b2SToby Isaac is available it can avoid some recomputation. If it is provided, MatInterpolate() will be used if 22221f3379b2SToby Isaac the coarse DM does not have a specialized implementation. 22231f3379b2SToby Isaac - coarseSol - solution on the coarse mesh 22241f3379b2SToby Isaac 22251f3379b2SToby Isaac Output Arguments: 22261f3379b2SToby Isaac . fineSol - the interpolation of coarseSol to the fine mesh 22271f3379b2SToby Isaac 22281f3379b2SToby Isaac Level: developer 22291f3379b2SToby Isaac 22301f3379b2SToby Isaac Note: This function exists because the interpolation of a solution vector between meshes is not always a linear 22311f3379b2SToby Isaac map. For example, if a boundary value problem has an inhomogeneous Dirichlet boundary condition that is compressed 22321f3379b2SToby Isaac out of the solution vector. Or if interpolation is inherently a nonlinear operation, such as a method using 22331f3379b2SToby Isaac slope-limiting reconstruction. 22341f3379b2SToby Isaac 22351f3379b2SToby Isaac .seealso DMInterpolate(), DMCreateInterpolation() 22361f3379b2SToby Isaac @*/ 22371f3379b2SToby Isaac PetscErrorCode DMInterpolateSolution(DM coarse, DM fine, Mat interp, Vec coarseSol, Vec fineSol) 22381f3379b2SToby Isaac { 22391f3379b2SToby Isaac PetscErrorCode (*interpsol)(DM,DM,Mat,Vec,Vec) = NULL; 22401f3379b2SToby Isaac PetscErrorCode ierr; 22411f3379b2SToby Isaac 22421f3379b2SToby Isaac PetscFunctionBegin; 22431f3379b2SToby Isaac PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 22441f3379b2SToby Isaac PetscValidHeaderSpecific(coarse,DM_CLASSID,2); 22451f3379b2SToby Isaac if (interp) PetscValidHeaderSpecific(interp,MAT_CLASSID,3); 22461f3379b2SToby Isaac PetscValidHeaderSpecific(coarseSol,VEC_CLASSID,4); 22471f3379b2SToby Isaac PetscValidHeaderSpecific(fineSol,VEC_CLASSID,5); 22481f3379b2SToby Isaac 22491f3379b2SToby Isaac ierr = PetscObjectQueryFunction((PetscObject)coarse,"DMInterpolateSolution_C", &interpsol);CHKERRQ(ierr); 22501f3379b2SToby Isaac if (interpsol) { 22511f3379b2SToby Isaac ierr = (*interpsol)(coarse, fine, interp, coarseSol, fineSol);CHKERRQ(ierr); 22521f3379b2SToby Isaac } else if (interp) { 22531f3379b2SToby Isaac ierr = MatInterpolate(interp, coarseSol, fineSol);CHKERRQ(ierr); 22541f3379b2SToby Isaac } else SETERRQ1(PetscObjectComm((PetscObject)coarse), PETSC_ERR_SUP, "DM %s does not implement DMInterpolateSolution()", ((PetscObject)coarse)->type_name); 22551f3379b2SToby Isaac PetscFunctionReturn(0); 22561f3379b2SToby Isaac } 22571f3379b2SToby Isaac 22581f3379b2SToby Isaac /*@ 2259aed49f88SRichard Tran Mills DMGetRefineLevel - Gets the number of refinements that have generated this DM. 2260eb3f98d2SBarry Smith 2261eb3f98d2SBarry Smith Not Collective 2262eb3f98d2SBarry Smith 2263eb3f98d2SBarry Smith Input Parameter: 2264eb3f98d2SBarry Smith . dm - the DM object 2265eb3f98d2SBarry Smith 2266eb3f98d2SBarry Smith Output Parameter: 2267eb3f98d2SBarry Smith . level - number of refinements 2268eb3f98d2SBarry Smith 2269eb3f98d2SBarry Smith Level: developer 2270eb3f98d2SBarry Smith 22716a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 2272eb3f98d2SBarry Smith 2273eb3f98d2SBarry Smith @*/ 2274eb3f98d2SBarry Smith PetscErrorCode DMGetRefineLevel(DM dm,PetscInt *level) 2275eb3f98d2SBarry Smith { 2276eb3f98d2SBarry Smith PetscFunctionBegin; 2277eb3f98d2SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2278eb3f98d2SBarry Smith *level = dm->levelup; 2279eb3f98d2SBarry Smith PetscFunctionReturn(0); 2280eb3f98d2SBarry Smith } 2281eb3f98d2SBarry Smith 2282fef3a512SBarry Smith /*@ 2283aed49f88SRichard Tran Mills DMSetRefineLevel - Sets the number of refinements that have generated this DM. 2284fef3a512SBarry Smith 2285fef3a512SBarry Smith Not Collective 2286fef3a512SBarry Smith 2287fef3a512SBarry Smith Input Parameter: 2288fef3a512SBarry Smith + dm - the DM object 2289fef3a512SBarry Smith - level - number of refinements 2290fef3a512SBarry Smith 2291fef3a512SBarry Smith Level: advanced 2292fef3a512SBarry Smith 229395452b02SPatrick Sanan Notes: 229495452b02SPatrick Sanan This value is used by PCMG to determine how many multigrid levels to use 2295fef3a512SBarry Smith 2296fef3a512SBarry Smith .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 2297fef3a512SBarry Smith 2298fef3a512SBarry Smith @*/ 2299fef3a512SBarry Smith PetscErrorCode DMSetRefineLevel(DM dm,PetscInt level) 2300fef3a512SBarry Smith { 2301fef3a512SBarry Smith PetscFunctionBegin; 2302fef3a512SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2303fef3a512SBarry Smith dm->levelup = level; 2304fef3a512SBarry Smith PetscFunctionReturn(0); 2305fef3a512SBarry Smith } 2306fef3a512SBarry Smith 2307ca3d3a14SMatthew G. Knepley PetscErrorCode DMGetBasisTransformDM_Internal(DM dm, DM *tdm) 2308ca3d3a14SMatthew G. Knepley { 2309ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2310ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2311ca3d3a14SMatthew G. Knepley PetscValidPointer(tdm, 2); 2312ca3d3a14SMatthew G. Knepley *tdm = dm->transformDM; 2313ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2314ca3d3a14SMatthew G. Knepley } 2315ca3d3a14SMatthew G. Knepley 2316ca3d3a14SMatthew G. Knepley PetscErrorCode DMGetBasisTransformVec_Internal(DM dm, Vec *tv) 2317ca3d3a14SMatthew G. Knepley { 2318ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2319ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2320ca3d3a14SMatthew G. Knepley PetscValidPointer(tv, 2); 2321ca3d3a14SMatthew G. Knepley *tv = dm->transform; 2322ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2323ca3d3a14SMatthew G. Knepley } 2324ca3d3a14SMatthew G. Knepley 2325ca3d3a14SMatthew G. Knepley /*@ 2326c0f8e1fdSMatthew G. Knepley DMHasBasisTransform - Whether we employ a basis transformation from functions in global vectors to functions in local vectors 2327ca3d3a14SMatthew G. Knepley 2328ca3d3a14SMatthew G. Knepley Input Parameter: 2329ca3d3a14SMatthew G. Knepley . dm - The DM 2330ca3d3a14SMatthew G. Knepley 2331ca3d3a14SMatthew G. Knepley Output Parameter: 2332ca3d3a14SMatthew G. Knepley . flg - PETSC_TRUE if a basis transformation should be done 2333ca3d3a14SMatthew G. Knepley 2334ca3d3a14SMatthew G. Knepley Level: developer 2335ca3d3a14SMatthew G. Knepley 2336436bc73aSJed Brown .seealso: DMPlexGlobalToLocalBasis(), DMPlexLocalToGlobalBasis(), DMPlexCreateBasisRotation() 2337ca3d3a14SMatthew G. Knepley @*/ 2338ca3d3a14SMatthew G. Knepley PetscErrorCode DMHasBasisTransform(DM dm, PetscBool *flg) 2339ca3d3a14SMatthew G. Knepley { 2340ca3d3a14SMatthew G. Knepley Vec tv; 2341ca3d3a14SMatthew G. Knepley PetscErrorCode ierr; 2342ca3d3a14SMatthew G. Knepley 2343ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2344ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2345534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 2346ca3d3a14SMatthew G. Knepley ierr = DMGetBasisTransformVec_Internal(dm, &tv);CHKERRQ(ierr); 2347ca3d3a14SMatthew G. Knepley *flg = tv ? PETSC_TRUE : PETSC_FALSE; 2348ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2349ca3d3a14SMatthew G. Knepley } 2350ca3d3a14SMatthew G. Knepley 2351ca3d3a14SMatthew G. Knepley PetscErrorCode DMConstructBasisTransform_Internal(DM dm) 2352ca3d3a14SMatthew G. Knepley { 2353ca3d3a14SMatthew G. Knepley PetscSection s, ts; 2354ca3d3a14SMatthew G. Knepley PetscScalar *ta; 2355ca3d3a14SMatthew G. Knepley PetscInt cdim, pStart, pEnd, p, Nf, f, Nc, dof; 2356ca3d3a14SMatthew G. Knepley PetscErrorCode ierr; 2357ca3d3a14SMatthew G. Knepley 2358ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2359ca3d3a14SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 236092fd8e1eSJed Brown ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr); 2361ca3d3a14SMatthew G. Knepley ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 2362ca3d3a14SMatthew G. Knepley ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr); 2363ca3d3a14SMatthew G. Knepley ierr = DMClone(dm, &dm->transformDM);CHKERRQ(ierr); 236492fd8e1eSJed Brown ierr = DMGetLocalSection(dm->transformDM, &ts);CHKERRQ(ierr); 2365ca3d3a14SMatthew G. Knepley ierr = PetscSectionSetNumFields(ts, Nf);CHKERRQ(ierr); 2366ca3d3a14SMatthew G. Knepley ierr = PetscSectionSetChart(ts, pStart, pEnd);CHKERRQ(ierr); 2367ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2368ca3d3a14SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(s, f, &Nc);CHKERRQ(ierr); 2369ca3d3a14SMatthew G. Knepley /* We could start to label fields by their transformation properties */ 2370ca3d3a14SMatthew G. Knepley if (Nc != cdim) continue; 2371ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2372ca3d3a14SMatthew G. Knepley ierr = PetscSectionGetFieldDof(s, p, f, &dof);CHKERRQ(ierr); 2373ca3d3a14SMatthew G. Knepley if (!dof) continue; 2374ca3d3a14SMatthew G. Knepley ierr = PetscSectionSetFieldDof(ts, p, f, PetscSqr(cdim));CHKERRQ(ierr); 2375ca3d3a14SMatthew G. Knepley ierr = PetscSectionAddDof(ts, p, PetscSqr(cdim));CHKERRQ(ierr); 2376ca3d3a14SMatthew G. Knepley } 2377ca3d3a14SMatthew G. Knepley } 2378ca3d3a14SMatthew G. Knepley ierr = PetscSectionSetUp(ts);CHKERRQ(ierr); 2379ca3d3a14SMatthew G. Knepley ierr = DMCreateLocalVector(dm->transformDM, &dm->transform);CHKERRQ(ierr); 2380ca3d3a14SMatthew G. Knepley ierr = VecGetArray(dm->transform, &ta);CHKERRQ(ierr); 2381ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2382ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2383ca3d3a14SMatthew G. Knepley ierr = PetscSectionGetFieldDof(ts, p, f, &dof);CHKERRQ(ierr); 2384ca3d3a14SMatthew G. Knepley if (dof) { 2385ca3d3a14SMatthew G. Knepley PetscReal x[3] = {0.0, 0.0, 0.0}; 2386ca3d3a14SMatthew G. Knepley PetscScalar *tva; 2387ca3d3a14SMatthew G. Knepley const PetscScalar *A; 2388ca3d3a14SMatthew G. Knepley 2389ca3d3a14SMatthew G. Knepley /* TODO Get quadrature point for this dual basis vector for coordinate */ 2390ca3d3a14SMatthew G. Knepley ierr = (*dm->transformGetMatrix)(dm, x, PETSC_TRUE, &A, dm->transformCtx);CHKERRQ(ierr); 2391ca3d3a14SMatthew G. Knepley ierr = DMPlexPointLocalFieldRef(dm->transformDM, p, f, ta, (void *) &tva);CHKERRQ(ierr); 2392580bdb30SBarry Smith ierr = PetscArraycpy(tva, A, PetscSqr(cdim));CHKERRQ(ierr); 2393ca3d3a14SMatthew G. Knepley } 2394ca3d3a14SMatthew G. Knepley } 2395ca3d3a14SMatthew G. Knepley } 2396ca3d3a14SMatthew G. Knepley ierr = VecRestoreArray(dm->transform, &ta);CHKERRQ(ierr); 2397ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2398ca3d3a14SMatthew G. Knepley } 2399ca3d3a14SMatthew G. Knepley 2400ca3d3a14SMatthew G. Knepley PetscErrorCode DMCopyTransform(DM dm, DM newdm) 2401ca3d3a14SMatthew G. Knepley { 2402ca3d3a14SMatthew G. Knepley PetscErrorCode ierr; 2403ca3d3a14SMatthew G. Knepley 2404ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2405ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2406ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(newdm, DM_CLASSID, 2); 2407ca3d3a14SMatthew G. Knepley newdm->transformCtx = dm->transformCtx; 2408ca3d3a14SMatthew G. Knepley newdm->transformSetUp = dm->transformSetUp; 2409ca3d3a14SMatthew G. Knepley newdm->transformDestroy = NULL; 2410ca3d3a14SMatthew G. Knepley newdm->transformGetMatrix = dm->transformGetMatrix; 2411ca3d3a14SMatthew G. Knepley if (newdm->transformSetUp) {ierr = DMConstructBasisTransform_Internal(newdm);CHKERRQ(ierr);} 2412ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2413ca3d3a14SMatthew G. Knepley } 2414ca3d3a14SMatthew G. Knepley 2415bb9467b5SJed Brown /*@C 2416baf369e7SPeter Brune DMGlobalToLocalHookAdd - adds a callback to be run when global to local is called 2417baf369e7SPeter Brune 2418baf369e7SPeter Brune Logically Collective 2419baf369e7SPeter Brune 2420baf369e7SPeter Brune Input Arguments: 2421baf369e7SPeter Brune + dm - the DM 2422baf369e7SPeter Brune . beginhook - function to run at the beginning of DMGlobalToLocalBegin() 2423baf369e7SPeter Brune . endhook - function to run after DMGlobalToLocalEnd() has completed 24240298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2425baf369e7SPeter Brune 2426baf369e7SPeter Brune Calling sequence for beginhook: 2427baf369e7SPeter Brune $ beginhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx) 2428baf369e7SPeter Brune 2429baf369e7SPeter Brune + dm - global DM 2430baf369e7SPeter Brune . g - global vector 2431baf369e7SPeter Brune . mode - mode 2432baf369e7SPeter Brune . l - local vector 2433baf369e7SPeter Brune - ctx - optional user-defined function context 2434baf369e7SPeter Brune 2435baf369e7SPeter Brune 2436baf369e7SPeter Brune Calling sequence for endhook: 2437ec4806b8SPeter Brune $ endhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx) 2438baf369e7SPeter Brune 2439baf369e7SPeter Brune + global - global DM 2440baf369e7SPeter Brune - ctx - optional user-defined function context 2441baf369e7SPeter Brune 2442baf369e7SPeter Brune Level: advanced 2443baf369e7SPeter Brune 2444baf369e7SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 2445baf369e7SPeter Brune @*/ 2446baf369e7SPeter Brune PetscErrorCode DMGlobalToLocalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx) 2447baf369e7SPeter Brune { 2448baf369e7SPeter Brune PetscErrorCode ierr; 2449baf369e7SPeter Brune DMGlobalToLocalHookLink link,*p; 2450baf369e7SPeter Brune 2451baf369e7SPeter Brune PetscFunctionBegin; 2452baf369e7SPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2453baf369e7SPeter Brune for (p=&dm->gtolhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 245495dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 2455baf369e7SPeter Brune link->beginhook = beginhook; 2456baf369e7SPeter Brune link->endhook = endhook; 2457baf369e7SPeter Brune link->ctx = ctx; 24580298fd71SBarry Smith link->next = NULL; 2459baf369e7SPeter Brune *p = link; 2460baf369e7SPeter Brune PetscFunctionReturn(0); 2461baf369e7SPeter Brune } 2462baf369e7SPeter Brune 24634c274da1SToby Isaac static PetscErrorCode DMGlobalToLocalHook_Constraints(DM dm, Vec g, InsertMode mode, Vec l, void *ctx) 24644c274da1SToby Isaac { 24654c274da1SToby Isaac Mat cMat; 24664c274da1SToby Isaac Vec cVec; 24674c274da1SToby Isaac PetscSection section, cSec; 24684c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 24694c274da1SToby Isaac PetscErrorCode ierr; 24704c274da1SToby Isaac 24714c274da1SToby Isaac PetscFunctionBegin; 24724c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 24734c274da1SToby Isaac ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr); 24744c274da1SToby Isaac if (cMat && (mode == INSERT_VALUES || mode == INSERT_ALL_VALUES || mode == INSERT_BC_VALUES)) { 24755db9a05bSToby Isaac PetscInt nRows; 24765db9a05bSToby Isaac 24775db9a05bSToby Isaac ierr = MatGetSize(cMat,&nRows,NULL);CHKERRQ(ierr); 24785db9a05bSToby Isaac if (nRows <= 0) PetscFunctionReturn(0); 247992fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 24807711e48fSToby Isaac ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr); 24814c274da1SToby Isaac ierr = MatMult(cMat,l,cVec);CHKERRQ(ierr); 24824c274da1SToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 24834c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 24844c274da1SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 24854c274da1SToby Isaac if (dof) { 24864c274da1SToby Isaac PetscScalar *vals; 24874c274da1SToby Isaac ierr = VecGetValuesSection(cVec,cSec,p,&vals);CHKERRQ(ierr); 24884c274da1SToby Isaac ierr = VecSetValuesSection(l,section,p,vals,INSERT_ALL_VALUES);CHKERRQ(ierr); 24894c274da1SToby Isaac } 24904c274da1SToby Isaac } 24914c274da1SToby Isaac ierr = VecDestroy(&cVec);CHKERRQ(ierr); 24924c274da1SToby Isaac } 24934c274da1SToby Isaac PetscFunctionReturn(0); 24944c274da1SToby Isaac } 24954c274da1SToby Isaac 249647c6ae99SBarry Smith /*@ 249701729b5cSPatrick Sanan DMGlobalToLocal - update local vectors from global vector 249801729b5cSPatrick Sanan 2499d083f849SBarry Smith Neighbor-wise Collective on dm 250001729b5cSPatrick Sanan 250101729b5cSPatrick Sanan Input Parameters: 250201729b5cSPatrick Sanan + dm - the DM object 250301729b5cSPatrick Sanan . g - the global vector 250401729b5cSPatrick Sanan . mode - INSERT_VALUES or ADD_VALUES 250501729b5cSPatrick Sanan - l - the local vector 250601729b5cSPatrick Sanan 250701729b5cSPatrick Sanan Notes: 250801729b5cSPatrick Sanan The communication involved in this update can be overlapped with computation by using 250901729b5cSPatrick Sanan DMGlobalToLocalBegin() and DMGlobalToLocalEnd(). 251001729b5cSPatrick Sanan 251101729b5cSPatrick Sanan Level: beginner 251201729b5cSPatrick Sanan 251301729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd() 251401729b5cSPatrick Sanan 251501729b5cSPatrick Sanan @*/ 251601729b5cSPatrick Sanan PetscErrorCode DMGlobalToLocal(DM dm,Vec g,InsertMode mode,Vec l) 251701729b5cSPatrick Sanan { 251801729b5cSPatrick Sanan PetscErrorCode ierr; 251901729b5cSPatrick Sanan 252001729b5cSPatrick Sanan PetscFunctionBegin; 252101729b5cSPatrick Sanan ierr = DMGlobalToLocalBegin(dm,g,mode,l);CHKERRQ(ierr); 252201729b5cSPatrick Sanan ierr = DMGlobalToLocalEnd(dm,g,mode,l);CHKERRQ(ierr); 252301729b5cSPatrick Sanan PetscFunctionReturn(0); 252401729b5cSPatrick Sanan } 252501729b5cSPatrick Sanan 252601729b5cSPatrick Sanan /*@ 252747c6ae99SBarry Smith DMGlobalToLocalBegin - Begins updating local vectors from global vector 252847c6ae99SBarry Smith 2529d083f849SBarry Smith Neighbor-wise Collective on dm 253047c6ae99SBarry Smith 253147c6ae99SBarry Smith Input Parameters: 253247c6ae99SBarry Smith + dm - the DM object 253347c6ae99SBarry Smith . g - the global vector 253447c6ae99SBarry Smith . mode - INSERT_VALUES or ADD_VALUES 253547c6ae99SBarry Smith - l - the local vector 253647c6ae99SBarry Smith 253701729b5cSPatrick Sanan Level: intermediate 253847c6ae99SBarry Smith 253901729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd() 254047c6ae99SBarry Smith 254147c6ae99SBarry Smith @*/ 25427087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l) 254347c6ae99SBarry Smith { 25447128ae9fSMatthew G Knepley PetscSF sf; 254547c6ae99SBarry Smith PetscErrorCode ierr; 2546baf369e7SPeter Brune DMGlobalToLocalHookLink link; 254747c6ae99SBarry Smith 2548d0295fc0SJunchao Zhang 254947c6ae99SBarry Smith PetscFunctionBegin; 2550171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2551baf369e7SPeter Brune for (link=dm->gtolhook; link; link=link->next) { 25528865f1eaSKarl Rupp if (link->beginhook) { 25538865f1eaSKarl Rupp ierr = (*link->beginhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr); 25548865f1eaSKarl Rupp } 2555baf369e7SPeter Brune } 25561bb6d2a8SBarry Smith ierr = DMGetSectionSF(dm, &sf);CHKERRQ(ierr); 25577128ae9fSMatthew G Knepley if (sf) { 2558ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2559ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2560d0295fc0SJunchao Zhang PetscMemType lmtype,gmtype; 25617128ae9fSMatthew G Knepley 256282f516ccSBarry Smith if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 2563a256111fSJunchao Zhang ierr = VecGetArrayAndMemType(l, &lArray, &lmtype);CHKERRQ(ierr); 2564a256111fSJunchao Zhang ierr = VecGetArrayReadAndMemType(g, &gArray, &gmtype);CHKERRQ(ierr); 2565ad227feaSJunchao Zhang ierr = PetscSFBcastWithMemTypeBegin(sf, MPIU_SCALAR, gmtype, gArray, lmtype, lArray, MPI_REPLACE);CHKERRQ(ierr); 2566a256111fSJunchao Zhang ierr = VecRestoreArrayAndMemType(l, &lArray);CHKERRQ(ierr); 2567a256111fSJunchao Zhang ierr = VecRestoreArrayReadAndMemType(g, &gArray);CHKERRQ(ierr); 25687128ae9fSMatthew G Knepley } else { 256933907cc2SStefano Zampini if (!dm->ops->globaltolocalbegin) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMGlobalToLocalBegin() for type %s",((PetscObject)dm)->type_name); 2570843c4018SMatthew G Knepley ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 25717128ae9fSMatthew G Knepley } 257247c6ae99SBarry Smith PetscFunctionReturn(0); 257347c6ae99SBarry Smith } 257447c6ae99SBarry Smith 257547c6ae99SBarry Smith /*@ 257647c6ae99SBarry Smith DMGlobalToLocalEnd - Ends updating local vectors from global vector 257747c6ae99SBarry Smith 2578d083f849SBarry Smith Neighbor-wise Collective on dm 257947c6ae99SBarry Smith 258047c6ae99SBarry Smith Input Parameters: 258147c6ae99SBarry Smith + dm - the DM object 258247c6ae99SBarry Smith . g - the global vector 258347c6ae99SBarry Smith . mode - INSERT_VALUES or ADD_VALUES 258447c6ae99SBarry Smith - l - the local vector 258547c6ae99SBarry Smith 258601729b5cSPatrick Sanan Level: intermediate 258747c6ae99SBarry Smith 258801729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd() 258947c6ae99SBarry Smith 259047c6ae99SBarry Smith @*/ 25917087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l) 259247c6ae99SBarry Smith { 25937128ae9fSMatthew G Knepley PetscSF sf; 259447c6ae99SBarry Smith PetscErrorCode ierr; 2595ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2596ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2597ca3d3a14SMatthew G. Knepley PetscBool transform; 2598baf369e7SPeter Brune DMGlobalToLocalHookLink link; 2599d0295fc0SJunchao Zhang PetscMemType lmtype,gmtype; 260047c6ae99SBarry Smith 260147c6ae99SBarry Smith PetscFunctionBegin; 2602171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 26031bb6d2a8SBarry Smith ierr = DMGetSectionSF(dm, &sf);CHKERRQ(ierr); 2604ca3d3a14SMatthew G. Knepley ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr); 26057128ae9fSMatthew G Knepley if (sf) { 260682f516ccSBarry Smith if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 26077128ae9fSMatthew G Knepley 2608a256111fSJunchao Zhang ierr = VecGetArrayAndMemType(l, &lArray, &lmtype);CHKERRQ(ierr); 2609a256111fSJunchao Zhang ierr = VecGetArrayReadAndMemType(g, &gArray, &gmtype);CHKERRQ(ierr); 2610ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray,MPI_REPLACE);CHKERRQ(ierr); 2611a256111fSJunchao Zhang ierr = VecRestoreArrayAndMemType(l, &lArray);CHKERRQ(ierr); 2612a256111fSJunchao Zhang ierr = VecRestoreArrayReadAndMemType(g, &gArray);CHKERRQ(ierr); 2613ca3d3a14SMatthew G. Knepley if (transform) {ierr = DMPlexGlobalToLocalBasis(dm, l);CHKERRQ(ierr);} 26147128ae9fSMatthew G Knepley } else { 261533907cc2SStefano Zampini if (!dm->ops->globaltolocalend) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMGlobalToLocalEnd() for type %s",((PetscObject)dm)->type_name); 2616843c4018SMatthew G Knepley ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 26177128ae9fSMatthew G Knepley } 26184c274da1SToby Isaac ierr = DMGlobalToLocalHook_Constraints(dm,g,mode,l,NULL);CHKERRQ(ierr); 2619baf369e7SPeter Brune for (link=dm->gtolhook; link; link=link->next) { 2620baf369e7SPeter Brune if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);} 2621baf369e7SPeter Brune } 262247c6ae99SBarry Smith PetscFunctionReturn(0); 262347c6ae99SBarry Smith } 262447c6ae99SBarry Smith 2625d4d07f1eSToby Isaac /*@C 2626d4d07f1eSToby Isaac DMLocalToGlobalHookAdd - adds a callback to be run when a local to global is called 2627d4d07f1eSToby Isaac 2628d4d07f1eSToby Isaac Logically Collective 2629d4d07f1eSToby Isaac 2630d4d07f1eSToby Isaac Input Arguments: 2631d4d07f1eSToby Isaac + dm - the DM 2632d4d07f1eSToby Isaac . beginhook - function to run at the beginning of DMLocalToGlobalBegin() 2633d4d07f1eSToby Isaac . endhook - function to run after DMLocalToGlobalEnd() has completed 2634d4d07f1eSToby Isaac - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2635d4d07f1eSToby Isaac 2636d4d07f1eSToby Isaac Calling sequence for beginhook: 2637d4d07f1eSToby Isaac $ beginhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx) 2638d4d07f1eSToby Isaac 2639d4d07f1eSToby Isaac + dm - global DM 2640d4d07f1eSToby Isaac . l - local vector 2641d4d07f1eSToby Isaac . mode - mode 2642d4d07f1eSToby Isaac . g - global vector 2643d4d07f1eSToby Isaac - ctx - optional user-defined function context 2644d4d07f1eSToby Isaac 2645d4d07f1eSToby Isaac 2646d4d07f1eSToby Isaac Calling sequence for endhook: 2647d4d07f1eSToby Isaac $ endhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx) 2648d4d07f1eSToby Isaac 2649d4d07f1eSToby Isaac + global - global DM 2650d4d07f1eSToby Isaac . l - local vector 2651d4d07f1eSToby Isaac . mode - mode 2652d4d07f1eSToby Isaac . g - global vector 2653d4d07f1eSToby Isaac - ctx - optional user-defined function context 2654d4d07f1eSToby Isaac 2655d4d07f1eSToby Isaac Level: advanced 2656d4d07f1eSToby Isaac 2657d4d07f1eSToby Isaac .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 2658d4d07f1eSToby Isaac @*/ 2659d4d07f1eSToby Isaac PetscErrorCode DMLocalToGlobalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx) 2660d4d07f1eSToby Isaac { 2661d4d07f1eSToby Isaac PetscErrorCode ierr; 2662d4d07f1eSToby Isaac DMLocalToGlobalHookLink link,*p; 2663d4d07f1eSToby Isaac 2664d4d07f1eSToby Isaac PetscFunctionBegin; 2665d4d07f1eSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2666d4d07f1eSToby Isaac for (p=&dm->ltoghook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 266795dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 2668d4d07f1eSToby Isaac link->beginhook = beginhook; 2669d4d07f1eSToby Isaac link->endhook = endhook; 2670d4d07f1eSToby Isaac link->ctx = ctx; 2671d4d07f1eSToby Isaac link->next = NULL; 2672d4d07f1eSToby Isaac *p = link; 2673d4d07f1eSToby Isaac PetscFunctionReturn(0); 2674d4d07f1eSToby Isaac } 2675d4d07f1eSToby Isaac 26764c274da1SToby Isaac static PetscErrorCode DMLocalToGlobalHook_Constraints(DM dm, Vec l, InsertMode mode, Vec g, void *ctx) 26774c274da1SToby Isaac { 26784c274da1SToby Isaac Mat cMat; 26794c274da1SToby Isaac Vec cVec; 26804c274da1SToby Isaac PetscSection section, cSec; 26814c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 26824c274da1SToby Isaac PetscErrorCode ierr; 26834c274da1SToby Isaac 26844c274da1SToby Isaac PetscFunctionBegin; 26854c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 26864c274da1SToby Isaac ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr); 26874c274da1SToby Isaac if (cMat && (mode == ADD_VALUES || mode == ADD_ALL_VALUES || mode == ADD_BC_VALUES)) { 26885db9a05bSToby Isaac PetscInt nRows; 26895db9a05bSToby Isaac 26905db9a05bSToby Isaac ierr = MatGetSize(cMat,&nRows,NULL);CHKERRQ(ierr); 26915db9a05bSToby Isaac if (nRows <= 0) PetscFunctionReturn(0); 269292fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 26937711e48fSToby Isaac ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr); 26944c274da1SToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 26954c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 26964c274da1SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 26974c274da1SToby Isaac if (dof) { 26984c274da1SToby Isaac PetscInt d; 26994c274da1SToby Isaac PetscScalar *vals; 27004c274da1SToby Isaac ierr = VecGetValuesSection(l,section,p,&vals);CHKERRQ(ierr); 27014c274da1SToby Isaac ierr = VecSetValuesSection(cVec,cSec,p,vals,mode);CHKERRQ(ierr); 27024c274da1SToby Isaac /* for this to be the true transpose, we have to zero the values that 27034c274da1SToby Isaac * we just extracted */ 27044c274da1SToby Isaac for (d = 0; d < dof; d++) { 27054c274da1SToby Isaac vals[d] = 0.; 27064c274da1SToby Isaac } 27074c274da1SToby Isaac } 27084c274da1SToby Isaac } 27094c274da1SToby Isaac ierr = MatMultTransposeAdd(cMat,cVec,l,l);CHKERRQ(ierr); 27104c274da1SToby Isaac ierr = VecDestroy(&cVec);CHKERRQ(ierr); 27114c274da1SToby Isaac } 27124c274da1SToby Isaac PetscFunctionReturn(0); 27134c274da1SToby Isaac } 271401729b5cSPatrick Sanan /*@ 271501729b5cSPatrick Sanan DMLocalToGlobal - updates global vectors from local vectors 271601729b5cSPatrick Sanan 2717d083f849SBarry Smith Neighbor-wise Collective on dm 271801729b5cSPatrick Sanan 271901729b5cSPatrick Sanan Input Parameters: 272001729b5cSPatrick Sanan + dm - the DM object 272101729b5cSPatrick Sanan . l - the local vector 272201729b5cSPatrick Sanan . 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. 272301729b5cSPatrick Sanan - g - the global vector 272401729b5cSPatrick Sanan 272501729b5cSPatrick Sanan Notes: 272601729b5cSPatrick Sanan The communication involved in this update can be overlapped with computation by using 272701729b5cSPatrick Sanan DMLocalToGlobalBegin() and DMLocalToGlobalEnd(). 272801729b5cSPatrick Sanan 272901729b5cSPatrick Sanan In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation. 273001729b5cSPatrick Sanan INSERT_VALUES is not supported for DMDA; in that case simply compute the values directly into a global vector instead of a local one. 273101729b5cSPatrick Sanan 273201729b5cSPatrick Sanan Level: beginner 273301729b5cSPatrick Sanan 273401729b5cSPatrick Sanan .seealso DMLocalToGlobalBegin(), DMLocalToGlobalEnd(), DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin() 273501729b5cSPatrick Sanan 273601729b5cSPatrick Sanan @*/ 273701729b5cSPatrick Sanan PetscErrorCode DMLocalToGlobal(DM dm,Vec l,InsertMode mode,Vec g) 273801729b5cSPatrick Sanan { 273901729b5cSPatrick Sanan PetscErrorCode ierr; 274001729b5cSPatrick Sanan 274101729b5cSPatrick Sanan PetscFunctionBegin; 274201729b5cSPatrick Sanan ierr = DMLocalToGlobalBegin(dm,l,mode,g);CHKERRQ(ierr); 274301729b5cSPatrick Sanan ierr = DMLocalToGlobalEnd(dm,l,mode,g);CHKERRQ(ierr); 274401729b5cSPatrick Sanan PetscFunctionReturn(0); 274501729b5cSPatrick Sanan } 27464c274da1SToby Isaac 274747c6ae99SBarry Smith /*@ 274801729b5cSPatrick Sanan DMLocalToGlobalBegin - begins updating global vectors from local vectors 27499a42bb27SBarry Smith 2750d083f849SBarry Smith Neighbor-wise Collective on dm 27519a42bb27SBarry Smith 27529a42bb27SBarry Smith Input Parameters: 27539a42bb27SBarry Smith + dm - the DM object 2754f6813fd5SJed Brown . l - the local vector 27551eb28f2eSBarry 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. 27561eb28f2eSBarry Smith - g - the global vector 27579a42bb27SBarry Smith 275895452b02SPatrick Sanan Notes: 275995452b02SPatrick Sanan In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation. 276084330215SMatthew 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. 27619a42bb27SBarry Smith 276201729b5cSPatrick Sanan Level: intermediate 27639a42bb27SBarry Smith 276401729b5cSPatrick Sanan .seealso DMLocalToGlobal(), DMLocalToGlobalEnd(), DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin() 27659a42bb27SBarry Smith 27669a42bb27SBarry Smith @*/ 27677087cfbeSBarry Smith PetscErrorCode DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g) 27689a42bb27SBarry Smith { 27697128ae9fSMatthew G Knepley PetscSF sf; 277084330215SMatthew G. Knepley PetscSection s, gs; 2771d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 2772ca3d3a14SMatthew G. Knepley Vec tmpl; 2773ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 2774ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 2775fa88e482SJed Brown PetscBool isInsert, transform, l_inplace = PETSC_FALSE, g_inplace = PETSC_FALSE; 277684330215SMatthew G. Knepley PetscErrorCode ierr; 2777d0295fc0SJunchao Zhang PetscMemType lmtype=PETSC_MEMTYPE_HOST,gmtype=PETSC_MEMTYPE_HOST; 27789a42bb27SBarry Smith 27799a42bb27SBarry Smith PetscFunctionBegin; 2780171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2781d4d07f1eSToby Isaac for (link=dm->ltoghook; link; link=link->next) { 2782d4d07f1eSToby Isaac if (link->beginhook) { 2783d4d07f1eSToby Isaac ierr = (*link->beginhook)(dm,l,mode,g,link->ctx);CHKERRQ(ierr); 2784d4d07f1eSToby Isaac } 2785d4d07f1eSToby Isaac } 27864c274da1SToby Isaac ierr = DMLocalToGlobalHook_Constraints(dm,l,mode,g,NULL);CHKERRQ(ierr); 27871bb6d2a8SBarry Smith ierr = DMGetSectionSF(dm, &sf);CHKERRQ(ierr); 278892fd8e1eSJed Brown ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr); 27897128ae9fSMatthew G Knepley switch (mode) { 27907128ae9fSMatthew G Knepley case INSERT_VALUES: 27917128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 2792304ab55fSMatthew G. Knepley case INSERT_BC_VALUES: 279384330215SMatthew G. Knepley isInsert = PETSC_TRUE; break; 27947128ae9fSMatthew G Knepley case ADD_VALUES: 27957128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 2796304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 279784330215SMatthew G. Knepley isInsert = PETSC_FALSE; break; 27987128ae9fSMatthew G Knepley default: 279982f516ccSBarry Smith SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 28007128ae9fSMatthew G Knepley } 2801ca3d3a14SMatthew G. Knepley if ((sf && !isInsert) || (s && isInsert)) { 2802ca3d3a14SMatthew G. Knepley ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr); 2803ca3d3a14SMatthew G. Knepley if (transform) { 2804ca3d3a14SMatthew G. Knepley ierr = DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr); 2805ca3d3a14SMatthew G. Knepley ierr = VecCopy(l, tmpl);CHKERRQ(ierr); 2806ca3d3a14SMatthew G. Knepley ierr = DMPlexLocalToGlobalBasis(dm, tmpl);CHKERRQ(ierr); 2807ca3d3a14SMatthew G. Knepley ierr = VecGetArrayRead(tmpl, &lArray);CHKERRQ(ierr); 2808fa88e482SJed Brown } else if (isInsert) { 2809ae5cfb4aSMatthew G. Knepley ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr); 2810fa88e482SJed Brown } else { 2811a256111fSJunchao Zhang ierr = VecGetArrayReadAndMemType(l, &lArray, &lmtype);CHKERRQ(ierr); 2812fa88e482SJed Brown l_inplace = PETSC_TRUE; 2813ca3d3a14SMatthew G. Knepley } 2814fa88e482SJed Brown if (s && isInsert) { 28157128ae9fSMatthew G Knepley ierr = VecGetArray(g, &gArray);CHKERRQ(ierr); 2816fa88e482SJed Brown } else { 2817a256111fSJunchao Zhang ierr = VecGetArrayAndMemType(g, &gArray, &gmtype);CHKERRQ(ierr); 2818fa88e482SJed Brown g_inplace = PETSC_TRUE; 2819fa88e482SJed Brown } 2820ca3d3a14SMatthew G. Knepley if (sf && !isInsert) { 2821d0295fc0SJunchao Zhang ierr = PetscSFReduceWithMemTypeBegin(sf, MPIU_SCALAR, lmtype, lArray, gmtype, gArray, MPIU_SUM);CHKERRQ(ierr); 282284330215SMatthew G. Knepley } else if (s && isInsert) { 282384330215SMatthew G. Knepley PetscInt gStart, pStart, pEnd, p; 282484330215SMatthew G. Knepley 2825e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, &gs);CHKERRQ(ierr); 282684330215SMatthew G. Knepley ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 282784330215SMatthew G. Knepley ierr = VecGetOwnershipRange(g, &gStart, NULL);CHKERRQ(ierr); 282884330215SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2829b3b16f48SMatthew G. Knepley PetscInt dof, gdof, cdof, gcdof, off, goff, d, e; 283084330215SMatthew G. Knepley 283184330215SMatthew G. Knepley ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 283203442857SMatthew G. Knepley ierr = PetscSectionGetDof(gs, p, &gdof);CHKERRQ(ierr); 283384330215SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 2834b3b16f48SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(gs, p, &gcdof);CHKERRQ(ierr); 283584330215SMatthew G. Knepley ierr = PetscSectionGetOffset(s, p, &off);CHKERRQ(ierr); 283684330215SMatthew G. Knepley ierr = PetscSectionGetOffset(gs, p, &goff);CHKERRQ(ierr); 2837b3b16f48SMatthew G. Knepley /* Ignore off-process data and points with no global data */ 283803442857SMatthew G. Knepley if (!gdof || goff < 0) continue; 2839b3b16f48SMatthew 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); 2840b3b16f48SMatthew G. Knepley /* If no constraints are enforced in the global vector */ 2841b3b16f48SMatthew G. Knepley if (!gcdof) { 284284330215SMatthew G. Knepley for (d = 0; d < dof; ++d) gArray[goff-gStart+d] = lArray[off+d]; 2843b3b16f48SMatthew G. Knepley /* If constraints are enforced in the global vector */ 2844b3b16f48SMatthew G. Knepley } else if (cdof == gcdof) { 284584330215SMatthew G. Knepley const PetscInt *cdofs; 284684330215SMatthew G. Knepley PetscInt cind = 0; 284784330215SMatthew G. Knepley 284884330215SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(s, p, &cdofs);CHKERRQ(ierr); 2849b3b16f48SMatthew G. Knepley for (d = 0, e = 0; d < dof; ++d) { 285084330215SMatthew G. Knepley if ((cind < cdof) && (d == cdofs[cind])) {++cind; continue;} 2851b3b16f48SMatthew G. Knepley gArray[goff-gStart+e++] = lArray[off+d]; 285284330215SMatthew G. Knepley } 2853b3b16f48SMatthew 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); 285484330215SMatthew G. Knepley } 2855ca3d3a14SMatthew G. Knepley } 2856fa88e482SJed Brown if (g_inplace) { 2857a256111fSJunchao Zhang ierr = VecRestoreArrayAndMemType(g, &gArray);CHKERRQ(ierr); 2858fa88e482SJed Brown } else { 28597128ae9fSMatthew G Knepley ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr); 2860fa88e482SJed Brown } 2861ca3d3a14SMatthew G. Knepley if (transform) { 2862ca3d3a14SMatthew G. Knepley ierr = VecRestoreArrayRead(tmpl, &lArray);CHKERRQ(ierr); 2863ca3d3a14SMatthew G. Knepley ierr = DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr); 2864fa88e482SJed Brown } else if (l_inplace) { 2865a256111fSJunchao Zhang ierr = VecRestoreArrayReadAndMemType(l, &lArray);CHKERRQ(ierr); 2866ca3d3a14SMatthew G. Knepley } else { 2867ca3d3a14SMatthew G. Knepley ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr); 2868ca3d3a14SMatthew G. Knepley } 28697128ae9fSMatthew G Knepley } else { 2870b9d85ea2SLisandro Dalcin if (!dm->ops->localtoglobalbegin) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMLocalToGlobalBegin() for type %s",((PetscObject)dm)->type_name); 2871843c4018SMatthew G Knepley ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr); 28727128ae9fSMatthew G Knepley } 28739a42bb27SBarry Smith PetscFunctionReturn(0); 28749a42bb27SBarry Smith } 28759a42bb27SBarry Smith 28769a42bb27SBarry Smith /*@ 28779a42bb27SBarry Smith DMLocalToGlobalEnd - updates global vectors from local vectors 287847c6ae99SBarry Smith 2879d083f849SBarry Smith Neighbor-wise Collective on dm 288047c6ae99SBarry Smith 288147c6ae99SBarry Smith Input Parameters: 288247c6ae99SBarry Smith + dm - the DM object 2883f6813fd5SJed Brown . l - the local vector 288447c6ae99SBarry Smith . mode - INSERT_VALUES or ADD_VALUES 2885f6813fd5SJed Brown - g - the global vector 288647c6ae99SBarry Smith 288701729b5cSPatrick Sanan Level: intermediate 288847c6ae99SBarry Smith 2889e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd() 289047c6ae99SBarry Smith 289147c6ae99SBarry Smith @*/ 28927087cfbeSBarry Smith PetscErrorCode DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g) 289347c6ae99SBarry Smith { 28947128ae9fSMatthew G Knepley PetscSF sf; 289584330215SMatthew G. Knepley PetscSection s; 2896d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 2897ca3d3a14SMatthew G. Knepley PetscBool isInsert, transform; 289884330215SMatthew G. Knepley PetscErrorCode ierr; 289947c6ae99SBarry Smith 290047c6ae99SBarry Smith PetscFunctionBegin; 2901171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 29021bb6d2a8SBarry Smith ierr = DMGetSectionSF(dm, &sf);CHKERRQ(ierr); 290392fd8e1eSJed Brown ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr); 29047128ae9fSMatthew G Knepley switch (mode) { 29057128ae9fSMatthew G Knepley case INSERT_VALUES: 29067128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 290784330215SMatthew G. Knepley isInsert = PETSC_TRUE; break; 29087128ae9fSMatthew G Knepley case ADD_VALUES: 29097128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 291084330215SMatthew G. Knepley isInsert = PETSC_FALSE; break; 29117128ae9fSMatthew G Knepley default: 291282f516ccSBarry Smith SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 29137128ae9fSMatthew G Knepley } 291484330215SMatthew G. Knepley if (sf && !isInsert) { 2915ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 2916ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 2917ca3d3a14SMatthew G. Knepley Vec tmpl; 291884330215SMatthew G. Knepley 2919ca3d3a14SMatthew G. Knepley ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr); 2920ca3d3a14SMatthew G. Knepley if (transform) { 2921ca3d3a14SMatthew G. Knepley ierr = DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr); 2922ca3d3a14SMatthew G. Knepley ierr = VecGetArrayRead(tmpl, &lArray);CHKERRQ(ierr); 2923ca3d3a14SMatthew G. Knepley } else { 2924a256111fSJunchao Zhang ierr = VecGetArrayReadAndMemType(l, &lArray, NULL);CHKERRQ(ierr); 2925ca3d3a14SMatthew G. Knepley } 2926a256111fSJunchao Zhang ierr = VecGetArrayAndMemType(g, &gArray, NULL);CHKERRQ(ierr); 2927a9b180a6SBarry Smith ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM);CHKERRQ(ierr); 2928ca3d3a14SMatthew G. Knepley if (transform) { 2929ca3d3a14SMatthew G. Knepley ierr = VecRestoreArrayRead(tmpl, &lArray);CHKERRQ(ierr); 2930ca3d3a14SMatthew G. Knepley ierr = DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr); 2931ca3d3a14SMatthew G. Knepley } else { 2932a256111fSJunchao Zhang ierr = VecRestoreArrayReadAndMemType(l, &lArray);CHKERRQ(ierr); 2933ca3d3a14SMatthew G. Knepley } 2934a256111fSJunchao Zhang ierr = VecRestoreArrayAndMemType(g, &gArray);CHKERRQ(ierr); 293584330215SMatthew G. Knepley } else if (s && isInsert) { 29367128ae9fSMatthew G Knepley } else { 2937b9d85ea2SLisandro Dalcin if (!dm->ops->localtoglobalend) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMLocalToGlobalEnd() for type %s",((PetscObject)dm)->type_name); 2938843c4018SMatthew G Knepley ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr); 29397128ae9fSMatthew G Knepley } 2940d4d07f1eSToby Isaac for (link=dm->ltoghook; link; link=link->next) { 2941d4d07f1eSToby Isaac if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);} 2942d4d07f1eSToby Isaac } 294347c6ae99SBarry Smith PetscFunctionReturn(0); 294447c6ae99SBarry Smith } 294547c6ae99SBarry Smith 2946f089877aSRichard Tran Mills /*@ 2947bc0a1609SRichard Tran Mills DMLocalToLocalBegin - Maps from a local vector (including ghost points 2948bc0a1609SRichard Tran Mills that contain irrelevant values) to another local vector where the ghost 2949d78e899eSRichard Tran Mills points in the second are set correctly. Must be followed by DMLocalToLocalEnd(). 2950f089877aSRichard Tran Mills 2951d083f849SBarry Smith Neighbor-wise Collective on dm 2952f089877aSRichard Tran Mills 2953f089877aSRichard Tran Mills Input Parameters: 2954f089877aSRichard Tran Mills + dm - the DM object 2955bc0a1609SRichard Tran Mills . g - the original local vector 2956bc0a1609SRichard Tran Mills - mode - one of INSERT_VALUES or ADD_VALUES 2957f089877aSRichard Tran Mills 2958bc0a1609SRichard Tran Mills Output Parameter: 2959bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 2960f089877aSRichard Tran Mills 2961f089877aSRichard Tran Mills Level: intermediate 2962f089877aSRichard Tran Mills 2963bc0a1609SRichard Tran Mills Notes: 2964bc0a1609SRichard Tran Mills The local vectors used here need not be the same as those 2965bc0a1609SRichard Tran Mills obtained from DMCreateLocalVector(), BUT they 2966bc0a1609SRichard Tran Mills must have the same parallel data layout; they could, for example, be 2967bc0a1609SRichard Tran Mills obtained with VecDuplicate() from the DM originating vectors. 2968bc0a1609SRichard Tran Mills 2969bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalEnd(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 2970f089877aSRichard Tran Mills 2971f089877aSRichard Tran Mills @*/ 2972f089877aSRichard Tran Mills PetscErrorCode DMLocalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l) 2973f089877aSRichard Tran Mills { 2974f089877aSRichard Tran Mills PetscErrorCode ierr; 2975f089877aSRichard Tran Mills 2976f089877aSRichard Tran Mills PetscFunctionBegin; 2977f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2978bb358533SPatrick Sanan if (!dm->ops->localtolocalbegin) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM does not support local to local maps"); 2979f089877aSRichard Tran Mills ierr = (*dm->ops->localtolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 2980f089877aSRichard Tran Mills PetscFunctionReturn(0); 2981f089877aSRichard Tran Mills } 2982f089877aSRichard Tran Mills 2983f089877aSRichard Tran Mills /*@ 2984bc0a1609SRichard Tran Mills DMLocalToLocalEnd - Maps from a local vector (including ghost points 2985bc0a1609SRichard Tran Mills that contain irrelevant values) to another local vector where the ghost 2986d78e899eSRichard Tran Mills points in the second are set correctly. Must be preceded by DMLocalToLocalBegin(). 2987f089877aSRichard Tran Mills 2988d083f849SBarry Smith Neighbor-wise Collective on dm 2989f089877aSRichard Tran Mills 2990f089877aSRichard Tran Mills Input Parameters: 2991bc0a1609SRichard Tran Mills + da - the DM object 2992bc0a1609SRichard Tran Mills . g - the original local vector 2993bc0a1609SRichard Tran Mills - mode - one of INSERT_VALUES or ADD_VALUES 2994f089877aSRichard Tran Mills 2995bc0a1609SRichard Tran Mills Output Parameter: 2996bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 2997f089877aSRichard Tran Mills 2998f089877aSRichard Tran Mills Level: intermediate 2999f089877aSRichard Tran Mills 3000bc0a1609SRichard Tran Mills Notes: 3001bc0a1609SRichard Tran Mills The local vectors used here need not be the same as those 3002bc0a1609SRichard Tran Mills obtained from DMCreateLocalVector(), BUT they 3003bc0a1609SRichard Tran Mills must have the same parallel data layout; they could, for example, be 3004bc0a1609SRichard Tran Mills obtained with VecDuplicate() from the DM originating vectors. 3005bc0a1609SRichard Tran Mills 3006bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalBegin(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 3007f089877aSRichard Tran Mills 3008f089877aSRichard Tran Mills @*/ 3009f089877aSRichard Tran Mills PetscErrorCode DMLocalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l) 3010f089877aSRichard Tran Mills { 3011f089877aSRichard Tran Mills PetscErrorCode ierr; 3012f089877aSRichard Tran Mills 3013f089877aSRichard Tran Mills PetscFunctionBegin; 3014f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3015bb358533SPatrick Sanan if (!dm->ops->localtolocalend) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM does not support local to local maps"); 3016f089877aSRichard Tran Mills ierr = (*dm->ops->localtolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 3017f089877aSRichard Tran Mills PetscFunctionReturn(0); 3018f089877aSRichard Tran Mills } 3019f089877aSRichard Tran Mills 3020f089877aSRichard Tran Mills 302147c6ae99SBarry Smith /*@ 302247c6ae99SBarry Smith DMCoarsen - Coarsens a DM object 302347c6ae99SBarry Smith 3024d083f849SBarry Smith Collective on dm 302547c6ae99SBarry Smith 302647c6ae99SBarry Smith Input Parameter: 302747c6ae99SBarry Smith + dm - the DM object 302891d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL) 302947c6ae99SBarry Smith 303047c6ae99SBarry Smith Output Parameter: 303147c6ae99SBarry Smith . dmc - the coarsened DM 303247c6ae99SBarry Smith 303347c6ae99SBarry Smith Level: developer 303447c6ae99SBarry Smith 3035e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 303647c6ae99SBarry Smith 303747c6ae99SBarry Smith @*/ 30387087cfbeSBarry Smith PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc) 303947c6ae99SBarry Smith { 304047c6ae99SBarry Smith PetscErrorCode ierr; 3041b17ce1afSJed Brown DMCoarsenHookLink link; 304247c6ae99SBarry Smith 304347c6ae99SBarry Smith PetscFunctionBegin; 3044171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3045b9d85ea2SLisandro Dalcin if (!dm->ops->coarsen) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCoarsen",((PetscObject)dm)->type_name); 304647a35634SPatrick Farrell ierr = PetscLogEventBegin(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr); 304747c6ae99SBarry Smith ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr); 3048b9d85ea2SLisandro Dalcin if (*dmc) { 3049a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dm,*dmc);CHKERRQ(ierr); 305043842a1eSJed Brown (*dmc)->ops->creatematrix = dm->ops->creatematrix; 30518cd211a4SJed Brown ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr); 3052644e2e5bSBarry Smith (*dmc)->ctx = dm->ctx; 30530598a293SJed Brown (*dmc)->levelup = dm->levelup; 3054656b349aSBarry Smith (*dmc)->leveldown = dm->leveldown + 1; 3055e4b4b23bSJed Brown ierr = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr); 3056b17ce1afSJed Brown for (link=dm->coarsenhook; link; link=link->next) { 3057b17ce1afSJed Brown if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);} 3058b17ce1afSJed Brown } 3059b9d85ea2SLisandro Dalcin } 306047a35634SPatrick Farrell ierr = PetscLogEventEnd(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr); 3061b9d85ea2SLisandro Dalcin if (!(*dmc)) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "NULL coarse mesh produced"); 3062b17ce1afSJed Brown PetscFunctionReturn(0); 3063b17ce1afSJed Brown } 3064b17ce1afSJed Brown 3065bb9467b5SJed Brown /*@C 3066b17ce1afSJed Brown DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid 3067b17ce1afSJed Brown 3068b17ce1afSJed Brown Logically Collective 3069b17ce1afSJed Brown 3070b17ce1afSJed Brown Input Arguments: 3071b17ce1afSJed Brown + fine - nonlinear solver context on which to run a hook when restricting to a coarser level 3072b17ce1afSJed Brown . coarsenhook - function to run when setting up a coarser level 3073b17ce1afSJed Brown . restricthook - function to run to update data on coarser levels (once per SNESSolve()) 30740298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3075b17ce1afSJed Brown 3076b17ce1afSJed Brown Calling sequence of coarsenhook: 3077b17ce1afSJed Brown $ coarsenhook(DM fine,DM coarse,void *ctx); 3078b17ce1afSJed Brown 3079b17ce1afSJed Brown + fine - fine level DM 3080b17ce1afSJed Brown . coarse - coarse level DM to restrict problem to 3081b17ce1afSJed Brown - ctx - optional user-defined function context 3082b17ce1afSJed Brown 3083b17ce1afSJed Brown Calling sequence for restricthook: 3084c833c3b5SJed Brown $ restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx) 3085b17ce1afSJed Brown 3086b17ce1afSJed Brown + fine - fine level DM 3087b17ce1afSJed Brown . mrestrict - matrix restricting a fine-level solution to the coarse grid 3088c833c3b5SJed Brown . rscale - scaling vector for restriction 3089c833c3b5SJed Brown . inject - matrix restricting by injection 3090b17ce1afSJed Brown . coarse - coarse level DM to update 3091b17ce1afSJed Brown - ctx - optional user-defined function context 3092b17ce1afSJed Brown 3093b17ce1afSJed Brown Level: advanced 3094b17ce1afSJed Brown 3095b17ce1afSJed Brown Notes: 3096b17ce1afSJed Brown This function is only needed if auxiliary data needs to be set up on coarse grids. 3097b17ce1afSJed Brown 3098b17ce1afSJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 3099b17ce1afSJed Brown 3100b17ce1afSJed Brown In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3101b17ce1afSJed Brown extract the finest level information from its context (instead of from the SNES). 3102b17ce1afSJed Brown 3103bb9467b5SJed Brown This function is currently not available from Fortran. 3104bb9467b5SJed Brown 3105dc822a44SJed Brown .seealso: DMCoarsenHookRemove(), DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 3106b17ce1afSJed Brown @*/ 3107b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx) 3108b17ce1afSJed Brown { 3109b17ce1afSJed Brown PetscErrorCode ierr; 3110b17ce1afSJed Brown DMCoarsenHookLink link,*p; 3111b17ce1afSJed Brown 3112b17ce1afSJed Brown PetscFunctionBegin; 3113b17ce1afSJed Brown PetscValidHeaderSpecific(fine,DM_CLASSID,1); 31141e3d8eccSJed Brown for (p=&fine->coarsenhook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */ 31151e3d8eccSJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0); 31161e3d8eccSJed Brown } 311795dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 3118b17ce1afSJed Brown link->coarsenhook = coarsenhook; 3119b17ce1afSJed Brown link->restricthook = restricthook; 3120b17ce1afSJed Brown link->ctx = ctx; 31210298fd71SBarry Smith link->next = NULL; 3122b17ce1afSJed Brown *p = link; 3123b17ce1afSJed Brown PetscFunctionReturn(0); 3124b17ce1afSJed Brown } 3125b17ce1afSJed Brown 3126dc822a44SJed Brown /*@C 3127dc822a44SJed Brown DMCoarsenHookRemove - remove a callback from the list of hooks to be run when restricting a nonlinear problem to the coarse grid 3128dc822a44SJed Brown 3129dc822a44SJed Brown Logically Collective 3130dc822a44SJed Brown 3131dc822a44SJed Brown Input Arguments: 3132dc822a44SJed Brown + fine - nonlinear solver context on which to run a hook when restricting to a coarser level 3133dc822a44SJed Brown . coarsenhook - function to run when setting up a coarser level 3134dc822a44SJed Brown . restricthook - function to run to update data on coarser levels (once per SNESSolve()) 3135dc822a44SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3136dc822a44SJed Brown 3137dc822a44SJed Brown Level: advanced 3138dc822a44SJed Brown 3139dc822a44SJed Brown Notes: 3140dc822a44SJed Brown This function does nothing if the hook is not in the list. 3141dc822a44SJed Brown 3142dc822a44SJed Brown This function is currently not available from Fortran. 3143dc822a44SJed Brown 3144dc822a44SJed Brown .seealso: DMCoarsenHookAdd(), DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 3145dc822a44SJed Brown @*/ 3146dc822a44SJed Brown PetscErrorCode DMCoarsenHookRemove(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx) 3147dc822a44SJed Brown { 3148dc822a44SJed Brown PetscErrorCode ierr; 3149dc822a44SJed Brown DMCoarsenHookLink link,*p; 3150dc822a44SJed Brown 3151dc822a44SJed Brown PetscFunctionBegin; 3152dc822a44SJed Brown PetscValidHeaderSpecific(fine,DM_CLASSID,1); 3153dc822a44SJed Brown for (p=&fine->coarsenhook; *p; p=&(*p)->next) { /* Search the list of current hooks */ 3154dc822a44SJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3155dc822a44SJed Brown link = *p; 3156dc822a44SJed Brown *p = link->next; 3157dc822a44SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 3158dc822a44SJed Brown break; 3159dc822a44SJed Brown } 3160dc822a44SJed Brown } 3161dc822a44SJed Brown PetscFunctionReturn(0); 3162dc822a44SJed Brown } 3163dc822a44SJed Brown 3164dc822a44SJed Brown 3165b17ce1afSJed Brown /*@ 3166b17ce1afSJed Brown DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd() 3167b17ce1afSJed Brown 3168b17ce1afSJed Brown Collective if any hooks are 3169b17ce1afSJed Brown 3170b17ce1afSJed Brown Input Arguments: 3171b17ce1afSJed Brown + fine - finer DM to use as a base 3172b17ce1afSJed Brown . restrct - restriction matrix, apply using MatRestrict() 3173e91eccc2SStefano Zampini . rscale - scaling vector for restriction 3174b17ce1afSJed Brown . inject - injection matrix, also use MatRestrict() 3175e91eccc2SStefano Zampini - coarse - coarser DM to update 3176b17ce1afSJed Brown 3177b17ce1afSJed Brown Level: developer 3178b17ce1afSJed Brown 3179b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict() 3180b17ce1afSJed Brown @*/ 3181b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse) 3182b17ce1afSJed Brown { 3183b17ce1afSJed Brown PetscErrorCode ierr; 3184b17ce1afSJed Brown DMCoarsenHookLink link; 3185b17ce1afSJed Brown 3186b17ce1afSJed Brown PetscFunctionBegin; 3187b17ce1afSJed Brown for (link=fine->coarsenhook; link; link=link->next) { 31888865f1eaSKarl Rupp if (link->restricthook) { 31898865f1eaSKarl Rupp ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr); 31908865f1eaSKarl Rupp } 3191b17ce1afSJed Brown } 319247c6ae99SBarry Smith PetscFunctionReturn(0); 319347c6ae99SBarry Smith } 319447c6ae99SBarry Smith 3195bb9467b5SJed Brown /*@C 3196be081cd6SPeter Brune DMSubDomainHookAdd - adds a callback to be run when restricting a problem to the coarse grid 31975dbd56e3SPeter Brune 3198d083f849SBarry Smith Logically Collective on global 31995dbd56e3SPeter Brune 32005dbd56e3SPeter Brune Input Arguments: 32015dbd56e3SPeter Brune + global - global DM 3202ec4806b8SPeter Brune . ddhook - function to run to pass data to the decomposition DM upon its creation 32035dbd56e3SPeter Brune . restricthook - function to run to update data on block solve (at the beginning of the block solve) 32040298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 32055dbd56e3SPeter Brune 3206ec4806b8SPeter Brune 3207ec4806b8SPeter Brune Calling sequence for ddhook: 3208ec4806b8SPeter Brune $ ddhook(DM global,DM block,void *ctx) 3209ec4806b8SPeter Brune 3210ec4806b8SPeter Brune + global - global DM 3211ec4806b8SPeter Brune . block - block DM 3212ec4806b8SPeter Brune - ctx - optional user-defined function context 3213ec4806b8SPeter Brune 32145dbd56e3SPeter Brune Calling sequence for restricthook: 3215ec4806b8SPeter Brune $ restricthook(DM global,VecScatter out,VecScatter in,DM block,void *ctx) 32165dbd56e3SPeter Brune 32175dbd56e3SPeter Brune + global - global DM 32185dbd56e3SPeter Brune . out - scatter to the outer (with ghost and overlap points) block vector 32195dbd56e3SPeter Brune . in - scatter to block vector values only owned locally 3220ec4806b8SPeter Brune . block - block DM 32215dbd56e3SPeter Brune - ctx - optional user-defined function context 32225dbd56e3SPeter Brune 32235dbd56e3SPeter Brune Level: advanced 32245dbd56e3SPeter Brune 32255dbd56e3SPeter Brune Notes: 3226ec4806b8SPeter Brune This function is only needed if auxiliary data needs to be set up on subdomain DMs. 32275dbd56e3SPeter Brune 32285dbd56e3SPeter Brune If this function is called multiple times, the hooks will be run in the order they are added. 32295dbd56e3SPeter Brune 32305dbd56e3SPeter Brune In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3231ec4806b8SPeter Brune extract the global information from its context (instead of from the SNES). 32325dbd56e3SPeter Brune 3233bb9467b5SJed Brown This function is currently not available from Fortran. 3234bb9467b5SJed Brown 32355dbd56e3SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 32365dbd56e3SPeter Brune @*/ 3237be081cd6SPeter Brune PetscErrorCode DMSubDomainHookAdd(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx) 32385dbd56e3SPeter Brune { 32395dbd56e3SPeter Brune PetscErrorCode ierr; 3240be081cd6SPeter Brune DMSubDomainHookLink link,*p; 32415dbd56e3SPeter Brune 32425dbd56e3SPeter Brune PetscFunctionBegin; 32435dbd56e3SPeter Brune PetscValidHeaderSpecific(global,DM_CLASSID,1); 3244b3a6b972SJed Brown for (p=&global->subdomainhook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */ 3245b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0); 3246b3a6b972SJed Brown } 324795dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 32485dbd56e3SPeter Brune link->restricthook = restricthook; 3249be081cd6SPeter Brune link->ddhook = ddhook; 32505dbd56e3SPeter Brune link->ctx = ctx; 32510298fd71SBarry Smith link->next = NULL; 32525dbd56e3SPeter Brune *p = link; 32535dbd56e3SPeter Brune PetscFunctionReturn(0); 32545dbd56e3SPeter Brune } 32555dbd56e3SPeter Brune 3256b3a6b972SJed Brown /*@C 3257b3a6b972SJed Brown DMSubDomainHookRemove - remove a callback from the list to be run when restricting a problem to the coarse grid 3258b3a6b972SJed Brown 3259b3a6b972SJed Brown Logically Collective 3260b3a6b972SJed Brown 3261b3a6b972SJed Brown Input Arguments: 3262b3a6b972SJed Brown + global - global DM 3263b3a6b972SJed Brown . ddhook - function to run to pass data to the decomposition DM upon its creation 3264b3a6b972SJed Brown . restricthook - function to run to update data on block solve (at the beginning of the block solve) 3265b3a6b972SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3266b3a6b972SJed Brown 3267b3a6b972SJed Brown Level: advanced 3268b3a6b972SJed Brown 3269b3a6b972SJed Brown Notes: 3270b3a6b972SJed Brown 3271b3a6b972SJed Brown This function is currently not available from Fortran. 3272b3a6b972SJed Brown 3273b3a6b972SJed Brown .seealso: DMSubDomainHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 3274b3a6b972SJed Brown @*/ 3275b3a6b972SJed Brown PetscErrorCode DMSubDomainHookRemove(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx) 3276b3a6b972SJed Brown { 3277b3a6b972SJed Brown PetscErrorCode ierr; 3278b3a6b972SJed Brown DMSubDomainHookLink link,*p; 3279b3a6b972SJed Brown 3280b3a6b972SJed Brown PetscFunctionBegin; 3281b3a6b972SJed Brown PetscValidHeaderSpecific(global,DM_CLASSID,1); 3282b3a6b972SJed Brown for (p=&global->subdomainhook; *p; p=&(*p)->next) { /* Search the list of current hooks */ 3283b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3284b3a6b972SJed Brown link = *p; 3285b3a6b972SJed Brown *p = link->next; 3286b3a6b972SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 3287b3a6b972SJed Brown break; 3288b3a6b972SJed Brown } 3289b3a6b972SJed Brown } 3290b3a6b972SJed Brown PetscFunctionReturn(0); 3291b3a6b972SJed Brown } 3292b3a6b972SJed Brown 32935dbd56e3SPeter Brune /*@ 3294be081cd6SPeter Brune DMSubDomainRestrict - restricts user-defined problem data to a block DM by running hooks registered by DMSubDomainHookAdd() 32955dbd56e3SPeter Brune 32965dbd56e3SPeter Brune Collective if any hooks are 32975dbd56e3SPeter Brune 32985dbd56e3SPeter Brune Input Arguments: 32995dbd56e3SPeter Brune + fine - finer DM to use as a base 3300be081cd6SPeter Brune . oscatter - scatter from domain global vector filling subdomain global vector with overlap 3301be081cd6SPeter Brune . gscatter - scatter from domain global vector filling subdomain local vector with ghosts 33025dbd56e3SPeter Brune - coarse - coarer DM to update 33035dbd56e3SPeter Brune 33045dbd56e3SPeter Brune Level: developer 33055dbd56e3SPeter Brune 33065dbd56e3SPeter Brune .seealso: DMCoarsenHookAdd(), MatRestrict() 33075dbd56e3SPeter Brune @*/ 3308be081cd6SPeter Brune PetscErrorCode DMSubDomainRestrict(DM global,VecScatter oscatter,VecScatter gscatter,DM subdm) 33095dbd56e3SPeter Brune { 33105dbd56e3SPeter Brune PetscErrorCode ierr; 3311be081cd6SPeter Brune DMSubDomainHookLink link; 33125dbd56e3SPeter Brune 33135dbd56e3SPeter Brune PetscFunctionBegin; 3314be081cd6SPeter Brune for (link=global->subdomainhook; link; link=link->next) { 33158865f1eaSKarl Rupp if (link->restricthook) { 33168865f1eaSKarl Rupp ierr = (*link->restricthook)(global,oscatter,gscatter,subdm,link->ctx);CHKERRQ(ierr); 33178865f1eaSKarl Rupp } 33185dbd56e3SPeter Brune } 33195dbd56e3SPeter Brune PetscFunctionReturn(0); 33205dbd56e3SPeter Brune } 33215dbd56e3SPeter Brune 33225fe1f584SPeter Brune /*@ 33236a7d9d85SPeter Brune DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM. 33245fe1f584SPeter Brune 33255fe1f584SPeter Brune Not Collective 33265fe1f584SPeter Brune 33275fe1f584SPeter Brune Input Parameter: 33285fe1f584SPeter Brune . dm - the DM object 33295fe1f584SPeter Brune 33305fe1f584SPeter Brune Output Parameter: 33316a7d9d85SPeter Brune . level - number of coarsenings 33325fe1f584SPeter Brune 33335fe1f584SPeter Brune Level: developer 33345fe1f584SPeter Brune 33356a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 33365fe1f584SPeter Brune 33375fe1f584SPeter Brune @*/ 33385fe1f584SPeter Brune PetscErrorCode DMGetCoarsenLevel(DM dm,PetscInt *level) 33395fe1f584SPeter Brune { 33405fe1f584SPeter Brune PetscFunctionBegin; 33415fe1f584SPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3342b9d85ea2SLisandro Dalcin PetscValidIntPointer(level,2); 33435fe1f584SPeter Brune *level = dm->leveldown; 33445fe1f584SPeter Brune PetscFunctionReturn(0); 33455fe1f584SPeter Brune } 33465fe1f584SPeter Brune 33479a64c4a8SMatthew G. Knepley /*@ 33489a64c4a8SMatthew G. Knepley DMSetCoarsenLevel - Sets the number of coarsenings that have generated this DM. 33499a64c4a8SMatthew G. Knepley 33509a64c4a8SMatthew G. Knepley Not Collective 33519a64c4a8SMatthew G. Knepley 33529a64c4a8SMatthew G. Knepley Input Parameters: 33539a64c4a8SMatthew G. Knepley + dm - the DM object 33549a64c4a8SMatthew G. Knepley - level - number of coarsenings 33559a64c4a8SMatthew G. Knepley 33569a64c4a8SMatthew G. Knepley Level: developer 33579a64c4a8SMatthew G. Knepley 33589a64c4a8SMatthew G. Knepley .seealso DMCoarsen(), DMGetCoarsenLevel(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 33599a64c4a8SMatthew G. Knepley @*/ 33609a64c4a8SMatthew G. Knepley PetscErrorCode DMSetCoarsenLevel(DM dm,PetscInt level) 33619a64c4a8SMatthew G. Knepley { 33629a64c4a8SMatthew G. Knepley PetscFunctionBegin; 33639a64c4a8SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 33649a64c4a8SMatthew G. Knepley dm->leveldown = level; 33659a64c4a8SMatthew G. Knepley PetscFunctionReturn(0); 33669a64c4a8SMatthew G. Knepley } 33679a64c4a8SMatthew G. Knepley 33685fe1f584SPeter Brune 33695fe1f584SPeter Brune 337047c6ae99SBarry Smith /*@C 337147c6ae99SBarry Smith DMRefineHierarchy - Refines a DM object, all levels at once 337247c6ae99SBarry Smith 3373d083f849SBarry Smith Collective on dm 337447c6ae99SBarry Smith 337547c6ae99SBarry Smith Input Parameter: 337647c6ae99SBarry Smith + dm - the DM object 337747c6ae99SBarry Smith - nlevels - the number of levels of refinement 337847c6ae99SBarry Smith 337947c6ae99SBarry Smith Output Parameter: 338047c6ae99SBarry Smith . dmf - the refined DM hierarchy 338147c6ae99SBarry Smith 338247c6ae99SBarry Smith Level: developer 338347c6ae99SBarry Smith 3384e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 338547c6ae99SBarry Smith 338647c6ae99SBarry Smith @*/ 33877087cfbeSBarry Smith PetscErrorCode DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[]) 338847c6ae99SBarry Smith { 338947c6ae99SBarry Smith PetscErrorCode ierr; 339047c6ae99SBarry Smith 339147c6ae99SBarry Smith PetscFunctionBegin; 3392171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3393ce94432eSBarry Smith if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 339447c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 3395b9d85ea2SLisandro Dalcin PetscValidPointer(dmf,3); 339647c6ae99SBarry Smith if (dm->ops->refinehierarchy) { 339747c6ae99SBarry Smith ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr); 339847c6ae99SBarry Smith } else if (dm->ops->refine) { 339947c6ae99SBarry Smith PetscInt i; 340047c6ae99SBarry Smith 3401ce94432eSBarry Smith ierr = DMRefine(dm,PetscObjectComm((PetscObject)dm),&dmf[0]);CHKERRQ(ierr); 340247c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 3403ce94432eSBarry Smith ierr = DMRefine(dmf[i-1],PetscObjectComm((PetscObject)dm),&dmf[i]);CHKERRQ(ierr); 340447c6ae99SBarry Smith } 3405ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No RefineHierarchy for this DM yet"); 340647c6ae99SBarry Smith PetscFunctionReturn(0); 340747c6ae99SBarry Smith } 340847c6ae99SBarry Smith 340947c6ae99SBarry Smith /*@C 341047c6ae99SBarry Smith DMCoarsenHierarchy - Coarsens a DM object, all levels at once 341147c6ae99SBarry Smith 3412d083f849SBarry Smith Collective on dm 341347c6ae99SBarry Smith 341447c6ae99SBarry Smith Input Parameter: 341547c6ae99SBarry Smith + dm - the DM object 341647c6ae99SBarry Smith - nlevels - the number of levels of coarsening 341747c6ae99SBarry Smith 341847c6ae99SBarry Smith Output Parameter: 341947c6ae99SBarry Smith . dmc - the coarsened DM hierarchy 342047c6ae99SBarry Smith 342147c6ae99SBarry Smith Level: developer 342247c6ae99SBarry Smith 3423e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 342447c6ae99SBarry Smith 342547c6ae99SBarry Smith @*/ 34267087cfbeSBarry Smith PetscErrorCode DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[]) 342747c6ae99SBarry Smith { 342847c6ae99SBarry Smith PetscErrorCode ierr; 342947c6ae99SBarry Smith 343047c6ae99SBarry Smith PetscFunctionBegin; 3431171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3432ce94432eSBarry Smith if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 343347c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 343447c6ae99SBarry Smith PetscValidPointer(dmc,3); 343547c6ae99SBarry Smith if (dm->ops->coarsenhierarchy) { 343647c6ae99SBarry Smith ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr); 343747c6ae99SBarry Smith } else if (dm->ops->coarsen) { 343847c6ae99SBarry Smith PetscInt i; 343947c6ae99SBarry Smith 3440ce94432eSBarry Smith ierr = DMCoarsen(dm,PetscObjectComm((PetscObject)dm),&dmc[0]);CHKERRQ(ierr); 344147c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 3442ce94432eSBarry Smith ierr = DMCoarsen(dmc[i-1],PetscObjectComm((PetscObject)dm),&dmc[i]);CHKERRQ(ierr); 344347c6ae99SBarry Smith } 3444ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet"); 344547c6ae99SBarry Smith PetscFunctionReturn(0); 344647c6ae99SBarry Smith } 344747c6ae99SBarry Smith 34481a266240SBarry Smith /*@C 34491a266240SBarry Smith DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed 34501a266240SBarry Smith 34511a266240SBarry Smith Not Collective 34521a266240SBarry Smith 34531a266240SBarry Smith Input Parameters: 34541a266240SBarry Smith + dm - the DM object 34551a266240SBarry Smith - destroy - the destroy function 34561a266240SBarry Smith 34571a266240SBarry Smith Level: intermediate 34581a266240SBarry Smith 3459e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 34601a266240SBarry Smith 3461f07f9ceaSJed Brown @*/ 34621a266240SBarry Smith PetscErrorCode DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**)) 34631a266240SBarry Smith { 34641a266240SBarry Smith PetscFunctionBegin; 3465171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 34661a266240SBarry Smith dm->ctxdestroy = destroy; 34671a266240SBarry Smith PetscFunctionReturn(0); 34681a266240SBarry Smith } 34691a266240SBarry Smith 3470b07ff414SBarry Smith /*@ 34711b2093e4SBarry Smith DMSetApplicationContext - Set a user context into a DM object 347247c6ae99SBarry Smith 347347c6ae99SBarry Smith Not Collective 347447c6ae99SBarry Smith 347547c6ae99SBarry Smith Input Parameters: 347647c6ae99SBarry Smith + dm - the DM object 347747c6ae99SBarry Smith - ctx - the user context 347847c6ae99SBarry Smith 347947c6ae99SBarry Smith Level: intermediate 348047c6ae99SBarry Smith 3481e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 348247c6ae99SBarry Smith 348347c6ae99SBarry Smith @*/ 34841b2093e4SBarry Smith PetscErrorCode DMSetApplicationContext(DM dm,void *ctx) 348547c6ae99SBarry Smith { 348647c6ae99SBarry Smith PetscFunctionBegin; 3487171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 348847c6ae99SBarry Smith dm->ctx = ctx; 348947c6ae99SBarry Smith PetscFunctionReturn(0); 349047c6ae99SBarry Smith } 349147c6ae99SBarry Smith 349247c6ae99SBarry Smith /*@ 34931b2093e4SBarry Smith DMGetApplicationContext - Gets a user context from a DM object 349447c6ae99SBarry Smith 349547c6ae99SBarry Smith Not Collective 349647c6ae99SBarry Smith 349747c6ae99SBarry Smith Input Parameter: 349847c6ae99SBarry Smith . dm - the DM object 349947c6ae99SBarry Smith 350047c6ae99SBarry Smith Output Parameter: 350147c6ae99SBarry Smith . ctx - the user context 350247c6ae99SBarry Smith 350347c6ae99SBarry Smith Level: intermediate 350447c6ae99SBarry Smith 3505e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 350647c6ae99SBarry Smith 350747c6ae99SBarry Smith @*/ 35081b2093e4SBarry Smith PetscErrorCode DMGetApplicationContext(DM dm,void *ctx) 350947c6ae99SBarry Smith { 351047c6ae99SBarry Smith PetscFunctionBegin; 3511171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 35121b2093e4SBarry Smith *(void**)ctx = dm->ctx; 351347c6ae99SBarry Smith PetscFunctionReturn(0); 351447c6ae99SBarry Smith } 351547c6ae99SBarry Smith 351608da532bSDmitry Karpeev /*@C 3517df3898eeSBarry Smith DMSetVariableBounds - sets a function to compute the lower and upper bound vectors for SNESVI. 351808da532bSDmitry Karpeev 3519d083f849SBarry Smith Logically Collective on dm 352008da532bSDmitry Karpeev 352108da532bSDmitry Karpeev Input Parameter: 352208da532bSDmitry Karpeev + dm - the DM object 35230298fd71SBarry Smith - f - the function that computes variable bounds used by SNESVI (use NULL to cancel a previous function that was set) 352408da532bSDmitry Karpeev 352508da532bSDmitry Karpeev Level: intermediate 352608da532bSDmitry Karpeev 3527835c3ec7SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), 352808da532bSDmitry Karpeev DMSetJacobian() 352908da532bSDmitry Karpeev 353008da532bSDmitry Karpeev @*/ 353108da532bSDmitry Karpeev PetscErrorCode DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec)) 353208da532bSDmitry Karpeev { 353308da532bSDmitry Karpeev PetscFunctionBegin; 35345a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 353508da532bSDmitry Karpeev dm->ops->computevariablebounds = f; 353608da532bSDmitry Karpeev PetscFunctionReturn(0); 353708da532bSDmitry Karpeev } 353808da532bSDmitry Karpeev 353908da532bSDmitry Karpeev /*@ 354008da532bSDmitry Karpeev DMHasVariableBounds - does the DM object have a variable bounds function? 354108da532bSDmitry Karpeev 354208da532bSDmitry Karpeev Not Collective 354308da532bSDmitry Karpeev 354408da532bSDmitry Karpeev Input Parameter: 354508da532bSDmitry Karpeev . dm - the DM object to destroy 354608da532bSDmitry Karpeev 354708da532bSDmitry Karpeev Output Parameter: 354808da532bSDmitry Karpeev . flg - PETSC_TRUE if the variable bounds function exists 354908da532bSDmitry Karpeev 355008da532bSDmitry Karpeev Level: developer 355108da532bSDmitry Karpeev 355274e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 355308da532bSDmitry Karpeev 355408da532bSDmitry Karpeev @*/ 355508da532bSDmitry Karpeev PetscErrorCode DMHasVariableBounds(DM dm,PetscBool *flg) 355608da532bSDmitry Karpeev { 355708da532bSDmitry Karpeev PetscFunctionBegin; 35585a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3559534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 356008da532bSDmitry Karpeev *flg = (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE; 356108da532bSDmitry Karpeev PetscFunctionReturn(0); 356208da532bSDmitry Karpeev } 356308da532bSDmitry Karpeev 356408da532bSDmitry Karpeev /*@C 356508da532bSDmitry Karpeev DMComputeVariableBounds - compute variable bounds used by SNESVI. 356608da532bSDmitry Karpeev 3567d083f849SBarry Smith Logically Collective on dm 356808da532bSDmitry Karpeev 356908da532bSDmitry Karpeev Input Parameters: 3570907376e6SBarry Smith . dm - the DM object 357108da532bSDmitry Karpeev 357208da532bSDmitry Karpeev Output parameters: 357308da532bSDmitry Karpeev + xl - lower bound 357408da532bSDmitry Karpeev - xu - upper bound 357508da532bSDmitry Karpeev 3576907376e6SBarry Smith Level: advanced 3577907376e6SBarry Smith 357895452b02SPatrick Sanan Notes: 357995452b02SPatrick Sanan This is generally not called by users. It calls the function provided by the user with DMSetVariableBounds() 358008da532bSDmitry Karpeev 358174e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 358208da532bSDmitry Karpeev 358308da532bSDmitry Karpeev @*/ 358408da532bSDmitry Karpeev PetscErrorCode DMComputeVariableBounds(DM dm, Vec xl, Vec xu) 358508da532bSDmitry Karpeev { 358608da532bSDmitry Karpeev PetscErrorCode ierr; 35875fd66863SKarl Rupp 358808da532bSDmitry Karpeev PetscFunctionBegin; 35895a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 359008da532bSDmitry Karpeev PetscValidHeaderSpecific(xl,VEC_CLASSID,2); 35915a84ad33SLisandro Dalcin PetscValidHeaderSpecific(xu,VEC_CLASSID,3); 3592b9d85ea2SLisandro Dalcin if (!dm->ops->computevariablebounds) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeVariableBounds",((PetscObject)dm)->type_name); 359308da532bSDmitry Karpeev ierr = (*dm->ops->computevariablebounds)(dm, xl,xu);CHKERRQ(ierr); 359408da532bSDmitry Karpeev PetscFunctionReturn(0); 359508da532bSDmitry Karpeev } 359608da532bSDmitry Karpeev 3597b0ae01b7SPeter Brune /*@ 3598b0ae01b7SPeter Brune DMHasColoring - does the DM object have a method of providing a coloring? 3599b0ae01b7SPeter Brune 3600b0ae01b7SPeter Brune Not Collective 3601b0ae01b7SPeter Brune 3602b0ae01b7SPeter Brune Input Parameter: 3603b0ae01b7SPeter Brune . dm - the DM object 3604b0ae01b7SPeter Brune 3605b0ae01b7SPeter Brune Output Parameter: 3606b0ae01b7SPeter Brune . flg - PETSC_TRUE if the DM has facilities for DMCreateColoring(). 3607b0ae01b7SPeter Brune 3608b0ae01b7SPeter Brune Level: developer 3609b0ae01b7SPeter Brune 36101565f0a7SPatrick Sanan .seealso DMCreateColoring() 3611b0ae01b7SPeter Brune 3612b0ae01b7SPeter Brune @*/ 3613b0ae01b7SPeter Brune PetscErrorCode DMHasColoring(DM dm,PetscBool *flg) 3614b0ae01b7SPeter Brune { 3615b0ae01b7SPeter Brune PetscFunctionBegin; 36165a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3617534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 3618b0ae01b7SPeter Brune *flg = (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE; 3619b0ae01b7SPeter Brune PetscFunctionReturn(0); 3620b0ae01b7SPeter Brune } 3621b0ae01b7SPeter Brune 36223ad4599aSBarry Smith /*@ 36233ad4599aSBarry Smith DMHasCreateRestriction - does the DM object have a method of providing a restriction? 36243ad4599aSBarry Smith 36253ad4599aSBarry Smith Not Collective 36263ad4599aSBarry Smith 36273ad4599aSBarry Smith Input Parameter: 36283ad4599aSBarry Smith . dm - the DM object 36293ad4599aSBarry Smith 36303ad4599aSBarry Smith Output Parameter: 36313ad4599aSBarry Smith . flg - PETSC_TRUE if the DM has facilities for DMCreateRestriction(). 36323ad4599aSBarry Smith 36333ad4599aSBarry Smith Level: developer 36343ad4599aSBarry Smith 36351565f0a7SPatrick Sanan .seealso DMCreateRestriction() 36363ad4599aSBarry Smith 36373ad4599aSBarry Smith @*/ 36383ad4599aSBarry Smith PetscErrorCode DMHasCreateRestriction(DM dm,PetscBool *flg) 36393ad4599aSBarry Smith { 36403ad4599aSBarry Smith PetscFunctionBegin; 36415a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3642534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 36433ad4599aSBarry Smith *flg = (dm->ops->createrestriction) ? PETSC_TRUE : PETSC_FALSE; 36443ad4599aSBarry Smith PetscFunctionReturn(0); 36453ad4599aSBarry Smith } 36463ad4599aSBarry Smith 3647a7058e45SLawrence Mitchell 3648a7058e45SLawrence Mitchell /*@ 3649a7058e45SLawrence Mitchell DMHasCreateInjection - does the DM object have a method of providing an injection? 3650a7058e45SLawrence Mitchell 3651a7058e45SLawrence Mitchell Not Collective 3652a7058e45SLawrence Mitchell 3653a7058e45SLawrence Mitchell Input Parameter: 3654a7058e45SLawrence Mitchell . dm - the DM object 3655a7058e45SLawrence Mitchell 3656a7058e45SLawrence Mitchell Output Parameter: 3657a7058e45SLawrence Mitchell . flg - PETSC_TRUE if the DM has facilities for DMCreateInjection(). 3658a7058e45SLawrence Mitchell 3659a7058e45SLawrence Mitchell Level: developer 3660a7058e45SLawrence Mitchell 36611565f0a7SPatrick Sanan .seealso DMCreateInjection() 3662a7058e45SLawrence Mitchell 3663a7058e45SLawrence Mitchell @*/ 3664a7058e45SLawrence Mitchell PetscErrorCode DMHasCreateInjection(DM dm,PetscBool *flg) 3665a7058e45SLawrence Mitchell { 36664a7a4c06SLawrence Mitchell PetscErrorCode ierr; 36675a84ad33SLisandro Dalcin 3668a7058e45SLawrence Mitchell PetscFunctionBegin; 36695a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3670534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 36715a84ad33SLisandro Dalcin if (dm->ops->hascreateinjection) { 36724a7a4c06SLawrence Mitchell ierr = (*dm->ops->hascreateinjection)(dm,flg);CHKERRQ(ierr); 36735a84ad33SLisandro Dalcin } else { 36745a84ad33SLisandro Dalcin *flg = (dm->ops->createinjection) ? PETSC_TRUE : PETSC_FALSE; 36755a84ad33SLisandro Dalcin } 3676a7058e45SLawrence Mitchell PetscFunctionReturn(0); 3677a7058e45SLawrence Mitchell } 3678a7058e45SLawrence Mitchell 36790298fd71SBarry Smith PetscFunctionList DMList = NULL; 3680264ace61SBarry Smith PetscBool DMRegisterAllCalled = PETSC_FALSE; 3681264ace61SBarry Smith 3682264ace61SBarry Smith /*@C 3683264ace61SBarry Smith DMSetType - Builds a DM, for a particular DM implementation. 3684264ace61SBarry Smith 3685d083f849SBarry Smith Collective on dm 3686264ace61SBarry Smith 3687264ace61SBarry Smith Input Parameters: 3688264ace61SBarry Smith + dm - The DM object 3689264ace61SBarry Smith - method - The name of the DM type 3690264ace61SBarry Smith 3691264ace61SBarry Smith Options Database Key: 3692264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types 3693264ace61SBarry Smith 3694264ace61SBarry Smith Notes: 3695e1589f56SBarry Smith See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D). 3696264ace61SBarry Smith 3697264ace61SBarry Smith Level: intermediate 3698264ace61SBarry Smith 3699264ace61SBarry Smith .seealso: DMGetType(), DMCreate() 3700264ace61SBarry Smith @*/ 370119fd82e9SBarry Smith PetscErrorCode DMSetType(DM dm, DMType method) 3702264ace61SBarry Smith { 3703264ace61SBarry Smith PetscErrorCode (*r)(DM); 3704264ace61SBarry Smith PetscBool match; 3705264ace61SBarry Smith PetscErrorCode ierr; 3706264ace61SBarry Smith 3707264ace61SBarry Smith PetscFunctionBegin; 3708264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID,1); 3709251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr); 3710264ace61SBarry Smith if (match) PetscFunctionReturn(0); 3711264ace61SBarry Smith 37120f51fdf8SToby Isaac ierr = DMRegisterAll();CHKERRQ(ierr); 37131c9cd337SJed Brown ierr = PetscFunctionListFind(DMList,method,&r);CHKERRQ(ierr); 3714ce94432eSBarry Smith if (!r) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method); 3715264ace61SBarry Smith 3716264ace61SBarry Smith if (dm->ops->destroy) { 3717264ace61SBarry Smith ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr); 3718264ace61SBarry Smith } 3719d57f96a3SLisandro Dalcin ierr = PetscMemzero(dm->ops,sizeof(*dm->ops));CHKERRQ(ierr); 3720264ace61SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr); 3721d57f96a3SLisandro Dalcin ierr = (*r)(dm);CHKERRQ(ierr); 3722264ace61SBarry Smith PetscFunctionReturn(0); 3723264ace61SBarry Smith } 3724264ace61SBarry Smith 3725264ace61SBarry Smith /*@C 3726264ace61SBarry Smith DMGetType - Gets the DM type name (as a string) from the DM. 3727264ace61SBarry Smith 3728264ace61SBarry Smith Not Collective 3729264ace61SBarry Smith 3730264ace61SBarry Smith Input Parameter: 3731264ace61SBarry Smith . dm - The DM 3732264ace61SBarry Smith 3733264ace61SBarry Smith Output Parameter: 3734264ace61SBarry Smith . type - The DM type name 3735264ace61SBarry Smith 3736264ace61SBarry Smith Level: intermediate 3737264ace61SBarry Smith 3738264ace61SBarry Smith .seealso: DMSetType(), DMCreate() 3739264ace61SBarry Smith @*/ 374019fd82e9SBarry Smith PetscErrorCode DMGetType(DM dm, DMType *type) 3741264ace61SBarry Smith { 3742264ace61SBarry Smith PetscErrorCode ierr; 3743264ace61SBarry Smith 3744264ace61SBarry Smith PetscFunctionBegin; 3745264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID,1); 3746c959eef4SJed Brown PetscValidPointer(type,2); 3747607a6623SBarry Smith ierr = DMRegisterAll();CHKERRQ(ierr); 3748264ace61SBarry Smith *type = ((PetscObject)dm)->type_name; 3749264ace61SBarry Smith PetscFunctionReturn(0); 3750264ace61SBarry Smith } 3751264ace61SBarry Smith 375267a56275SMatthew G Knepley /*@C 375367a56275SMatthew G Knepley DMConvert - Converts a DM to another DM, either of the same or different type. 375467a56275SMatthew G Knepley 3755d083f849SBarry Smith Collective on dm 375667a56275SMatthew G Knepley 375767a56275SMatthew G Knepley Input Parameters: 375867a56275SMatthew G Knepley + dm - the DM 375967a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type) 376067a56275SMatthew G Knepley 376167a56275SMatthew G Knepley Output Parameter: 376267a56275SMatthew G Knepley . M - pointer to new DM 376367a56275SMatthew G Knepley 376467a56275SMatthew G Knepley Notes: 376567a56275SMatthew G Knepley Cannot be used to convert a sequential DM to parallel or parallel to sequential, 376667a56275SMatthew G Knepley the MPI communicator of the generated DM is always the same as the communicator 376767a56275SMatthew G Knepley of the input DM. 376867a56275SMatthew G Knepley 376967a56275SMatthew G Knepley Level: intermediate 377067a56275SMatthew G Knepley 377167a56275SMatthew G Knepley .seealso: DMCreate() 377267a56275SMatthew G Knepley @*/ 377319fd82e9SBarry Smith PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M) 377467a56275SMatthew G Knepley { 377567a56275SMatthew G Knepley DM B; 377667a56275SMatthew G Knepley char convname[256]; 3777c067b6caSMatthew G. Knepley PetscBool sametype/*, issame */; 377867a56275SMatthew G Knepley PetscErrorCode ierr; 377967a56275SMatthew G Knepley 378067a56275SMatthew G Knepley PetscFunctionBegin; 378167a56275SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 378267a56275SMatthew G Knepley PetscValidType(dm,1); 378367a56275SMatthew G Knepley PetscValidPointer(M,3); 3784251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr); 3785c067b6caSMatthew G. Knepley /* ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr); */ 3786c067b6caSMatthew G. Knepley if (sametype) { 3787c067b6caSMatthew G. Knepley *M = dm; 3788c067b6caSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr); 3789c067b6caSMatthew G. Knepley PetscFunctionReturn(0); 3790c067b6caSMatthew G. Knepley } else { 37910298fd71SBarry Smith PetscErrorCode (*conv)(DM, DMType, DM*) = NULL; 379267a56275SMatthew G Knepley 379367a56275SMatthew G Knepley /* 379467a56275SMatthew G Knepley Order of precedence: 379567a56275SMatthew G Knepley 1) See if a specialized converter is known to the current DM. 379667a56275SMatthew G Knepley 2) See if a specialized converter is known to the desired DM class. 379767a56275SMatthew G Knepley 3) See if a good general converter is registered for the desired class 379867a56275SMatthew G Knepley 4) See if a good general converter is known for the current matrix. 379967a56275SMatthew G Knepley 5) Use a really basic converter. 380067a56275SMatthew G Knepley */ 380167a56275SMatthew G Knepley 380267a56275SMatthew G Knepley /* 1) See if a specialized converter is known to the current DM and the desired class */ 3803a126751eSBarry Smith ierr = PetscStrncpy(convname,"DMConvert_",sizeof(convname));CHKERRQ(ierr); 3804a126751eSBarry Smith ierr = PetscStrlcat(convname,((PetscObject) dm)->type_name,sizeof(convname));CHKERRQ(ierr); 3805a126751eSBarry Smith ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 3806a126751eSBarry Smith ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 3807a126751eSBarry Smith ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 38080005d66cSJed Brown ierr = PetscObjectQueryFunction((PetscObject)dm,convname,&conv);CHKERRQ(ierr); 380967a56275SMatthew G Knepley if (conv) goto foundconv; 381067a56275SMatthew G Knepley 381167a56275SMatthew G Knepley /* 2) See if a specialized converter is known to the desired DM class. */ 381282f516ccSBarry Smith ierr = DMCreate(PetscObjectComm((PetscObject)dm), &B);CHKERRQ(ierr); 381367a56275SMatthew G Knepley ierr = DMSetType(B, newtype);CHKERRQ(ierr); 3814a126751eSBarry Smith ierr = PetscStrncpy(convname,"DMConvert_",sizeof(convname));CHKERRQ(ierr); 3815a126751eSBarry Smith ierr = PetscStrlcat(convname,((PetscObject) dm)->type_name,sizeof(convname));CHKERRQ(ierr); 3816a126751eSBarry Smith ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 3817a126751eSBarry Smith ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 3818a126751eSBarry Smith ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 38190005d66cSJed Brown ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 382067a56275SMatthew G Knepley if (conv) { 3821fcfd50ebSBarry Smith ierr = DMDestroy(&B);CHKERRQ(ierr); 382267a56275SMatthew G Knepley goto foundconv; 382367a56275SMatthew G Knepley } 382467a56275SMatthew G Knepley 382567a56275SMatthew G Knepley #if 0 382667a56275SMatthew G Knepley /* 3) See if a good general converter is registered for the desired class */ 382767a56275SMatthew G Knepley conv = B->ops->convertfrom; 3828fcfd50ebSBarry Smith ierr = DMDestroy(&B);CHKERRQ(ierr); 382967a56275SMatthew G Knepley if (conv) goto foundconv; 383067a56275SMatthew G Knepley 383167a56275SMatthew G Knepley /* 4) See if a good general converter is known for the current matrix */ 383267a56275SMatthew G Knepley if (dm->ops->convert) { 383367a56275SMatthew G Knepley conv = dm->ops->convert; 383467a56275SMatthew G Knepley } 383567a56275SMatthew G Knepley if (conv) goto foundconv; 383667a56275SMatthew G Knepley #endif 383767a56275SMatthew G Knepley 383867a56275SMatthew G Knepley /* 5) Use a really basic converter. */ 383982f516ccSBarry Smith SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype); 384067a56275SMatthew G Knepley 384167a56275SMatthew G Knepley foundconv: 384267a56275SMatthew G Knepley ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr); 384367a56275SMatthew G Knepley ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr); 384412fa691eSMatthew G. Knepley /* Things that are independent of DM type: We should consult DMClone() here */ 384590b157c4SStefano Zampini { 384690b157c4SStefano Zampini PetscBool isper; 384712fa691eSMatthew G. Knepley const PetscReal *maxCell, *L; 384812fa691eSMatthew G. Knepley const DMBoundaryType *bd; 384990b157c4SStefano Zampini ierr = DMGetPeriodicity(dm, &isper, &maxCell, &L, &bd);CHKERRQ(ierr); 385090b157c4SStefano Zampini ierr = DMSetPeriodicity(*M, isper, maxCell, L, bd);CHKERRQ(ierr); 3851c8a6034eSMark (*M)->prealloc_only = dm->prealloc_only; 3852a587d139SMark ierr = PetscFree((*M)->vectype);CHKERRQ(ierr); 3853a587d139SMark ierr = PetscStrallocpy(dm->vectype,(char**)&(*M)->vectype);CHKERRQ(ierr); 3854a587d139SMark ierr = PetscFree((*M)->mattype);CHKERRQ(ierr); 3855a587d139SMark ierr = PetscStrallocpy(dm->mattype,(char**)&(*M)->mattype);CHKERRQ(ierr); 385612fa691eSMatthew G. Knepley } 385767a56275SMatthew G Knepley ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr); 385867a56275SMatthew G Knepley } 385967a56275SMatthew G Knepley ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr); 386067a56275SMatthew G Knepley PetscFunctionReturn(0); 386167a56275SMatthew G Knepley } 3862264ace61SBarry Smith 3863264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/ 3864264ace61SBarry Smith 3865264ace61SBarry Smith /*@C 38661c84c290SBarry Smith DMRegister - Adds a new DM component implementation 38671c84c290SBarry Smith 38681c84c290SBarry Smith Not Collective 38691c84c290SBarry Smith 38701c84c290SBarry Smith Input Parameters: 38711c84c290SBarry Smith + name - The name of a new user-defined creation routine 38721c84c290SBarry Smith - create_func - The creation routine itself 38731c84c290SBarry Smith 38741c84c290SBarry Smith Notes: 38751c84c290SBarry Smith DMRegister() may be called multiple times to add several user-defined DMs 38761c84c290SBarry Smith 38771c84c290SBarry Smith 38781c84c290SBarry Smith Sample usage: 38791c84c290SBarry Smith .vb 3880bdf89e91SBarry Smith DMRegister("my_da", MyDMCreate); 38811c84c290SBarry Smith .ve 38821c84c290SBarry Smith 38831c84c290SBarry Smith Then, your DM type can be chosen with the procedural interface via 38841c84c290SBarry Smith .vb 38851c84c290SBarry Smith DMCreate(MPI_Comm, DM *); 38861c84c290SBarry Smith DMSetType(DM,"my_da"); 38871c84c290SBarry Smith .ve 38881c84c290SBarry Smith or at runtime via the option 38891c84c290SBarry Smith .vb 38901c84c290SBarry Smith -da_type my_da 38911c84c290SBarry Smith .ve 3892264ace61SBarry Smith 3893264ace61SBarry Smith Level: advanced 38941c84c290SBarry Smith 3895bdf89e91SBarry Smith .seealso: DMRegisterAll(), DMRegisterDestroy() 38961c84c290SBarry Smith 3897264ace61SBarry Smith @*/ 3898bdf89e91SBarry Smith PetscErrorCode DMRegister(const char sname[],PetscErrorCode (*function)(DM)) 3899264ace61SBarry Smith { 3900264ace61SBarry Smith PetscErrorCode ierr; 3901264ace61SBarry Smith 3902264ace61SBarry Smith PetscFunctionBegin; 39031d36bdfdSBarry Smith ierr = DMInitializePackage();CHKERRQ(ierr); 3904a240a19fSJed Brown ierr = PetscFunctionListAdd(&DMList,sname,function);CHKERRQ(ierr); 3905264ace61SBarry Smith PetscFunctionReturn(0); 3906264ace61SBarry Smith } 3907264ace61SBarry Smith 3908b859378eSBarry Smith /*@C 390955849f57SBarry Smith DMLoad - Loads a DM that has been stored in binary with DMView(). 3910b859378eSBarry Smith 3911d083f849SBarry Smith Collective on viewer 3912b859378eSBarry Smith 3913b859378eSBarry Smith Input Parameters: 3914b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or 3915b859378eSBarry Smith some related function before a call to DMLoad(). 3916b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or 3917b859378eSBarry Smith HDF5 file viewer, obtained from PetscViewerHDF5Open() 3918b859378eSBarry Smith 3919b859378eSBarry Smith Level: intermediate 3920b859378eSBarry Smith 3921b859378eSBarry Smith Notes: 392255849f57SBarry Smith The type is determined by the data in the file, any type set into the DM before this call is ignored. 3923b859378eSBarry Smith 3924b859378eSBarry Smith Notes for advanced users: 3925b859378eSBarry Smith Most users should not need to know the details of the binary storage 3926b859378eSBarry Smith format, since DMLoad() and DMView() completely hide these details. 3927b859378eSBarry Smith But for anyone who's interested, the standard binary matrix storage 3928b859378eSBarry Smith format is 3929b859378eSBarry Smith .vb 3930b859378eSBarry Smith has not yet been determined 3931b859378eSBarry Smith .ve 3932b859378eSBarry Smith 3933b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad() 3934b859378eSBarry Smith @*/ 3935b859378eSBarry Smith PetscErrorCode DMLoad(DM newdm, PetscViewer viewer) 3936b859378eSBarry Smith { 39379331c7a4SMatthew G. Knepley PetscBool isbinary, ishdf5; 3938b859378eSBarry Smith PetscErrorCode ierr; 3939b859378eSBarry Smith 3940b859378eSBarry Smith PetscFunctionBegin; 3941b859378eSBarry Smith PetscValidHeaderSpecific(newdm,DM_CLASSID,1); 3942b859378eSBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 3943fb694a9eSVaclav Hapla ierr = PetscViewerCheckReadable(viewer);CHKERRQ(ierr); 394432c0f0efSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 39459331c7a4SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 394658cd63d5SVaclav Hapla ierr = PetscLogEventBegin(DM_Load,viewer,0,0,0);CHKERRQ(ierr); 39479331c7a4SMatthew G. Knepley if (isbinary) { 39489331c7a4SMatthew G. Knepley PetscInt classid; 39499331c7a4SMatthew G. Knepley char type[256]; 3950b859378eSBarry Smith 3951060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr); 39529200755eSBarry Smith if (classid != DM_FILE_CLASSID) SETERRQ1(PetscObjectComm((PetscObject)newdm),PETSC_ERR_ARG_WRONG,"Not DM next in file, classid found %d",(int)classid); 3953060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr); 395432c0f0efSBarry Smith ierr = DMSetType(newdm, type);CHKERRQ(ierr); 39559331c7a4SMatthew G. Knepley if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);} 39569331c7a4SMatthew G. Knepley } else if (ishdf5) { 39579331c7a4SMatthew G. Knepley if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);} 39589331c7a4SMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()"); 395958cd63d5SVaclav Hapla ierr = PetscLogEventEnd(DM_Load,viewer,0,0,0);CHKERRQ(ierr); 3960b859378eSBarry Smith PetscFunctionReturn(0); 3961b859378eSBarry Smith } 3962b859378eSBarry Smith 3963b2e4378dSMatthew G. Knepley /*@ 3964b2e4378dSMatthew G. Knepley DMGetLocalBoundingBox - Returns the bounding box for the piece of the DM on this process. 3965b2e4378dSMatthew G. Knepley 3966b2e4378dSMatthew G. Knepley Not collective 3967b2e4378dSMatthew G. Knepley 3968b2e4378dSMatthew G. Knepley Input Parameter: 3969b2e4378dSMatthew G. Knepley . dm - the DM 3970b2e4378dSMatthew G. Knepley 3971b2e4378dSMatthew G. Knepley Output Parameters: 3972b2e4378dSMatthew G. Knepley + lmin - local minimum coordinates (length coord dim, optional) 3973b2e4378dSMatthew G. Knepley - lmax - local maximim coordinates (length coord dim, optional) 3974b2e4378dSMatthew G. Knepley 3975b2e4378dSMatthew G. Knepley Level: beginner 3976b2e4378dSMatthew G. Knepley 3977b2e4378dSMatthew G. Knepley Note: If the DM is a DMDA and has no coordinates, the index bounds are returned instead. 3978b2e4378dSMatthew G. Knepley 3979b2e4378dSMatthew G. Knepley 3980b2e4378dSMatthew G. Knepley .seealso: DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetBoundingBox() 3981b2e4378dSMatthew G. Knepley @*/ 3982b2e4378dSMatthew G. Knepley PetscErrorCode DMGetLocalBoundingBox(DM dm, PetscReal lmin[], PetscReal lmax[]) 3983b2e4378dSMatthew G. Knepley { 3984b2e4378dSMatthew G. Knepley Vec coords = NULL; 3985b2e4378dSMatthew G. Knepley PetscReal min[3] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MAX_REAL}; 3986b2e4378dSMatthew G. Knepley PetscReal max[3] = {PETSC_MIN_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 3987b2e4378dSMatthew G. Knepley const PetscScalar *local_coords; 3988b2e4378dSMatthew G. Knepley PetscInt N, Ni; 3989b2e4378dSMatthew G. Knepley PetscInt cdim, i, j; 3990b2e4378dSMatthew G. Knepley PetscErrorCode ierr; 3991b2e4378dSMatthew G. Knepley 3992b2e4378dSMatthew G. Knepley PetscFunctionBegin; 3993b2e4378dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3994b2e4378dSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 3995b2e4378dSMatthew G. Knepley ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr); 3996b2e4378dSMatthew G. Knepley if (coords) { 3997b2e4378dSMatthew G. Knepley ierr = VecGetArrayRead(coords, &local_coords);CHKERRQ(ierr); 3998b2e4378dSMatthew G. Knepley ierr = VecGetLocalSize(coords, &N);CHKERRQ(ierr); 3999b2e4378dSMatthew G. Knepley Ni = N/cdim; 4000b2e4378dSMatthew G. Knepley for (i = 0; i < Ni; ++i) { 4001b2e4378dSMatthew G. Knepley for (j = 0; j < 3; ++j) { 4002b2e4378dSMatthew G. Knepley min[j] = j < cdim ? PetscMin(min[j], PetscRealPart(local_coords[i*cdim+j])) : 0; 4003b2e4378dSMatthew G. Knepley max[j] = j < cdim ? PetscMax(max[j], PetscRealPart(local_coords[i*cdim+j])) : 0; 4004b2e4378dSMatthew G. Knepley } 4005b2e4378dSMatthew G. Knepley } 4006b2e4378dSMatthew G. Knepley ierr = VecRestoreArrayRead(coords, &local_coords);CHKERRQ(ierr); 4007b2e4378dSMatthew G. Knepley } else { 4008b2e4378dSMatthew G. Knepley PetscBool isda; 4009b2e4378dSMatthew G. Knepley 4010b2e4378dSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) dm, DMDA, &isda);CHKERRQ(ierr); 4011b2e4378dSMatthew G. Knepley if (isda) {ierr = DMGetLocalBoundingIndices_DMDA(dm, min, max);CHKERRQ(ierr);} 4012b2e4378dSMatthew G. Knepley } 4013b2e4378dSMatthew G. Knepley if (lmin) {ierr = PetscArraycpy(lmin, min, cdim);CHKERRQ(ierr);} 4014b2e4378dSMatthew G. Knepley if (lmax) {ierr = PetscArraycpy(lmax, max, cdim);CHKERRQ(ierr);} 4015b2e4378dSMatthew G. Knepley PetscFunctionReturn(0); 4016b2e4378dSMatthew G. Knepley } 4017b2e4378dSMatthew G. Knepley 4018b2e4378dSMatthew G. Knepley /*@ 4019b2e4378dSMatthew G. Knepley DMGetBoundingBox - Returns the global bounding box for the DM. 4020b2e4378dSMatthew G. Knepley 4021b2e4378dSMatthew G. Knepley Collective 4022b2e4378dSMatthew G. Knepley 4023b2e4378dSMatthew G. Knepley Input Parameter: 4024b2e4378dSMatthew G. Knepley . dm - the DM 4025b2e4378dSMatthew G. Knepley 4026b2e4378dSMatthew G. Knepley Output Parameters: 4027b2e4378dSMatthew G. Knepley + gmin - global minimum coordinates (length coord dim, optional) 4028b2e4378dSMatthew G. Knepley - gmax - global maximim coordinates (length coord dim, optional) 4029b2e4378dSMatthew G. Knepley 4030b2e4378dSMatthew G. Knepley Level: beginner 4031b2e4378dSMatthew G. Knepley 4032b2e4378dSMatthew G. Knepley .seealso: DMGetLocalBoundingBox(), DMGetCoordinates(), DMGetCoordinatesLocal() 4033b2e4378dSMatthew G. Knepley @*/ 4034b2e4378dSMatthew G. Knepley PetscErrorCode DMGetBoundingBox(DM dm, PetscReal gmin[], PetscReal gmax[]) 4035b2e4378dSMatthew G. Knepley { 4036b2e4378dSMatthew G. Knepley PetscReal lmin[3], lmax[3]; 40376ce308c4SMatthew G. Knepley PetscInt cdim; 40386ce308c4SMatthew G. Knepley PetscMPIInt count; 4039b2e4378dSMatthew G. Knepley PetscErrorCode ierr; 4040b2e4378dSMatthew G. Knepley 4041b2e4378dSMatthew G. Knepley PetscFunctionBegin; 4042b2e4378dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4043b2e4378dSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 4044b2e4378dSMatthew G. Knepley ierr = PetscMPIIntCast(cdim, &count);CHKERRQ(ierr); 4045b2e4378dSMatthew G. Knepley ierr = DMGetLocalBoundingBox(dm, lmin, lmax);CHKERRQ(ierr); 4046b2e4378dSMatthew G. Knepley if (gmin) {ierr = MPIU_Allreduce(lmin, gmin, count, MPIU_REAL, MPIU_MIN, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);} 4047b2e4378dSMatthew G. Knepley if (gmax) {ierr = MPIU_Allreduce(lmax, gmax, count, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);} 4048b2e4378dSMatthew G. Knepley PetscFunctionReturn(0); 4049b2e4378dSMatthew G. Knepley } 4050b2e4378dSMatthew G. Knepley 40517da65231SMatthew G Knepley /******************************** FEM Support **********************************/ 40527da65231SMatthew G Knepley 4053a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) 4054a6dfd86eSKarl Rupp { 40551d47ebbbSSatish Balay PetscInt f; 40561b30c384SMatthew G Knepley PetscErrorCode ierr; 40571b30c384SMatthew G Knepley 40587da65231SMatthew G Knepley PetscFunctionBegin; 405974778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr); 40601d47ebbbSSatish Balay for (f = 0; f < len; ++f) { 406157622a8eSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, " | %g |\n", (double)PetscRealPart(x[f]));CHKERRQ(ierr); 40627da65231SMatthew G Knepley } 40637da65231SMatthew G Knepley PetscFunctionReturn(0); 40647da65231SMatthew G Knepley } 40657da65231SMatthew G Knepley 4066a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) 4067a6dfd86eSKarl Rupp { 40681b30c384SMatthew G Knepley PetscInt f, g; 40697da65231SMatthew G Knepley PetscErrorCode ierr; 40707da65231SMatthew G Knepley 40717da65231SMatthew G Knepley PetscFunctionBegin; 407274778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr); 40731d47ebbbSSatish Balay for (f = 0; f < rows; ++f) { 407474778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, " |");CHKERRQ(ierr); 40751d47ebbbSSatish Balay for (g = 0; g < cols; ++g) { 4076e3556bceSMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5g", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr); 40777da65231SMatthew G Knepley } 407874778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr); 40797da65231SMatthew G Knepley } 40807da65231SMatthew G Knepley PetscFunctionReturn(0); 40817da65231SMatthew G Knepley } 4082e7c4fc90SDmitry Karpeev 40836113b454SMatthew G. Knepley PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X) 4084e759306cSMatthew G. Knepley { 40850c5b8624SToby Isaac PetscInt localSize, bs; 40860c5b8624SToby Isaac PetscMPIInt size; 40870c5b8624SToby Isaac Vec x, xglob; 40880c5b8624SToby Isaac const PetscScalar *xarray; 4089e759306cSMatthew G. Knepley PetscErrorCode ierr; 4090e759306cSMatthew G. Knepley 4091e759306cSMatthew G. Knepley PetscFunctionBegin; 4092ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm),&size);CHKERRMPI(ierr); 4093e759306cSMatthew G. Knepley ierr = VecDuplicate(X, &x);CHKERRQ(ierr); 4094e759306cSMatthew G. Knepley ierr = VecCopy(X, x);CHKERRQ(ierr); 40956113b454SMatthew G. Knepley ierr = VecChop(x, tol);CHKERRQ(ierr); 40960c5b8624SToby Isaac ierr = PetscPrintf(PetscObjectComm((PetscObject) dm),"%s:\n",name);CHKERRQ(ierr); 40970c5b8624SToby Isaac if (size > 1) { 40980c5b8624SToby Isaac ierr = VecGetLocalSize(x,&localSize);CHKERRQ(ierr); 40990c5b8624SToby Isaac ierr = VecGetArrayRead(x,&xarray);CHKERRQ(ierr); 41000c5b8624SToby Isaac ierr = VecGetBlockSize(x,&bs);CHKERRQ(ierr); 41010c5b8624SToby Isaac ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject) dm),bs,localSize,PETSC_DETERMINE,xarray,&xglob);CHKERRQ(ierr); 41020c5b8624SToby Isaac } else { 41030c5b8624SToby Isaac xglob = x; 41040c5b8624SToby Isaac } 41050c5b8624SToby Isaac ierr = VecView(xglob,PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject) dm)));CHKERRQ(ierr); 41060c5b8624SToby Isaac if (size > 1) { 41070c5b8624SToby Isaac ierr = VecDestroy(&xglob);CHKERRQ(ierr); 41080c5b8624SToby Isaac ierr = VecRestoreArrayRead(x,&xarray);CHKERRQ(ierr); 41090c5b8624SToby Isaac } 4110e759306cSMatthew G. Knepley ierr = VecDestroy(&x);CHKERRQ(ierr); 4111e759306cSMatthew G. Knepley PetscFunctionReturn(0); 4112e759306cSMatthew G. Knepley } 4113e759306cSMatthew G. Knepley 411488ed4aceSMatthew G Knepley /*@ 41151bb6d2a8SBarry Smith DMGetSection - Get the PetscSection encoding the local data layout for the DM. This is equivalent to DMGetLocalSection(). Deprecated in v3.12 4116061576a5SJed Brown 4117061576a5SJed Brown Input Parameter: 4118061576a5SJed Brown . dm - The DM 4119061576a5SJed Brown 4120061576a5SJed Brown Output Parameter: 4121061576a5SJed Brown . section - The PetscSection 4122061576a5SJed Brown 4123061576a5SJed Brown Options Database Keys: 4124061576a5SJed Brown . -dm_petscsection_view - View the Section created by the DM 4125061576a5SJed Brown 4126061576a5SJed Brown Level: advanced 4127061576a5SJed Brown 4128061576a5SJed Brown Notes: 4129061576a5SJed Brown Use DMGetLocalSection() in new code. 4130061576a5SJed Brown 4131061576a5SJed Brown This gets a borrowed reference, so the user should not destroy this PetscSection. 4132061576a5SJed Brown 4133061576a5SJed Brown .seealso: DMGetLocalSection(), DMSetLocalSection(), DMGetGlobalSection() 4134061576a5SJed Brown @*/ 4135061576a5SJed Brown PetscErrorCode DMGetSection(DM dm, PetscSection *section) 4136061576a5SJed Brown { 4137061576a5SJed Brown PetscErrorCode ierr; 4138061576a5SJed Brown 4139061576a5SJed Brown PetscFunctionBegin; 4140061576a5SJed Brown ierr = DMGetLocalSection(dm,section);CHKERRQ(ierr); 4141061576a5SJed Brown PetscFunctionReturn(0); 4142061576a5SJed Brown } 4143061576a5SJed Brown 4144061576a5SJed Brown /*@ 4145061576a5SJed Brown DMGetLocalSection - Get the PetscSection encoding the local data layout for the DM. 414688ed4aceSMatthew G Knepley 414788ed4aceSMatthew G Knepley Input Parameter: 414888ed4aceSMatthew G Knepley . dm - The DM 414988ed4aceSMatthew G Knepley 415088ed4aceSMatthew G Knepley Output Parameter: 415188ed4aceSMatthew G Knepley . section - The PetscSection 415288ed4aceSMatthew G Knepley 4153e5893cccSMatthew G. Knepley Options Database Keys: 4154e5893cccSMatthew G. Knepley . -dm_petscsection_view - View the Section created by the DM 4155e5893cccSMatthew G. Knepley 415688ed4aceSMatthew G Knepley Level: intermediate 415788ed4aceSMatthew G Knepley 415888ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSection. 415988ed4aceSMatthew G Knepley 4160061576a5SJed Brown .seealso: DMSetLocalSection(), DMGetGlobalSection() 416188ed4aceSMatthew G Knepley @*/ 4162061576a5SJed Brown PetscErrorCode DMGetLocalSection(DM dm, PetscSection *section) 41630adebc6cSBarry Smith { 4164fd59a867SMatthew G. Knepley PetscErrorCode ierr; 4165fd59a867SMatthew G. Knepley 416688ed4aceSMatthew G Knepley PetscFunctionBegin; 416788ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 416888ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 41691bb6d2a8SBarry Smith if (!dm->localSection && dm->ops->createlocalsection) { 4170e5e52638SMatthew G. Knepley PetscInt d; 4171e5e52638SMatthew G. Knepley 4172e5e52638SMatthew G. Knepley if (dm->setfromoptionscalled) for (d = 0; d < dm->Nds; ++d) {ierr = PetscDSSetFromOptions(dm->probs[d].ds);CHKERRQ(ierr);} 41731bb6d2a8SBarry Smith ierr = (*dm->ops->createlocalsection)(dm);CHKERRQ(ierr); 41741bb6d2a8SBarry Smith if (dm->localSection) {ierr = PetscObjectViewFromOptions((PetscObject) dm->localSection, NULL, "-dm_petscsection_view");CHKERRQ(ierr);} 41752f0f8703SMatthew G. Knepley } 41761bb6d2a8SBarry Smith *section = dm->localSection; 417788ed4aceSMatthew G Knepley PetscFunctionReturn(0); 417888ed4aceSMatthew G Knepley } 417988ed4aceSMatthew G Knepley 418088ed4aceSMatthew G Knepley /*@ 41811bb6d2a8SBarry Smith DMSetSection - Set the PetscSection encoding the local data layout for the DM. This is equivalent to DMSetLocalSection(). Deprecated in v3.12 4182061576a5SJed Brown 4183061576a5SJed Brown Input Parameters: 4184061576a5SJed Brown + dm - The DM 4185061576a5SJed Brown - section - The PetscSection 4186061576a5SJed Brown 4187061576a5SJed Brown Level: advanced 4188061576a5SJed Brown 4189061576a5SJed Brown Notes: 4190061576a5SJed Brown Use DMSetLocalSection() in new code. 4191061576a5SJed Brown 4192061576a5SJed Brown Any existing Section will be destroyed 4193061576a5SJed Brown 4194061576a5SJed Brown .seealso: DMSetLocalSection(), DMGetLocalSection(), DMSetGlobalSection() 4195061576a5SJed Brown @*/ 4196061576a5SJed Brown PetscErrorCode DMSetSection(DM dm, PetscSection section) 4197061576a5SJed Brown { 4198061576a5SJed Brown PetscErrorCode ierr; 4199061576a5SJed Brown 4200061576a5SJed Brown PetscFunctionBegin; 4201061576a5SJed Brown ierr = DMSetLocalSection(dm,section);CHKERRQ(ierr); 4202061576a5SJed Brown PetscFunctionReturn(0); 4203061576a5SJed Brown } 4204061576a5SJed Brown 4205061576a5SJed Brown /*@ 4206061576a5SJed Brown DMSetLocalSection - Set the PetscSection encoding the local data layout for the DM. 420788ed4aceSMatthew G Knepley 420888ed4aceSMatthew G Knepley Input Parameters: 420988ed4aceSMatthew G Knepley + dm - The DM 421088ed4aceSMatthew G Knepley - section - The PetscSection 421188ed4aceSMatthew G Knepley 421288ed4aceSMatthew G Knepley Level: intermediate 421388ed4aceSMatthew G Knepley 421488ed4aceSMatthew G Knepley Note: Any existing Section will be destroyed 421588ed4aceSMatthew G Knepley 4216061576a5SJed Brown .seealso: DMGetLocalSection(), DMSetGlobalSection() 421788ed4aceSMatthew G Knepley @*/ 4218061576a5SJed Brown PetscErrorCode DMSetLocalSection(DM dm, PetscSection section) 42190adebc6cSBarry Smith { 4220c473ab19SMatthew G. Knepley PetscInt numFields = 0; 4221af122d2aSMatthew G Knepley PetscInt f; 422288ed4aceSMatthew G Knepley PetscErrorCode ierr; 422388ed4aceSMatthew G Knepley 422488ed4aceSMatthew G Knepley PetscFunctionBegin; 422588ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4226b9d85ea2SLisandro Dalcin if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 42271d799100SJed Brown ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 42281bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&dm->localSection);CHKERRQ(ierr); 42291bb6d2a8SBarry Smith dm->localSection = section; 42301bb6d2a8SBarry Smith if (section) {ierr = PetscSectionGetNumFields(dm->localSection, &numFields);CHKERRQ(ierr);} 4231af122d2aSMatthew G Knepley if (numFields) { 4232af122d2aSMatthew G Knepley ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr); 4233af122d2aSMatthew G Knepley for (f = 0; f < numFields; ++f) { 42340f21e855SMatthew G. Knepley PetscObject disc; 4235af122d2aSMatthew G Knepley const char *name; 4236af122d2aSMatthew G Knepley 42371bb6d2a8SBarry Smith ierr = PetscSectionGetFieldName(dm->localSection, f, &name);CHKERRQ(ierr); 423844a7f3ddSMatthew G. Knepley ierr = DMGetField(dm, f, NULL, &disc);CHKERRQ(ierr); 42390f21e855SMatthew G. Knepley ierr = PetscObjectSetName(disc, name);CHKERRQ(ierr); 4240af122d2aSMatthew G Knepley } 4241af122d2aSMatthew G Knepley } 4242e87a4003SBarry Smith /* The global section will be rebuilt in the next call to DMGetGlobalSection(). */ 42431bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&dm->globalSection);CHKERRQ(ierr); 424488ed4aceSMatthew G Knepley PetscFunctionReturn(0); 424588ed4aceSMatthew G Knepley } 424688ed4aceSMatthew G Knepley 42479435951eSToby Isaac /*@ 4248b7385021SStefano Zampini DMGetDefaultConstraints - Get the PetscSection and Mat that specify the local constraint interpolation. See DMSetDefaultConstraints() for a description of the purpose of constraint interpolation. 42499435951eSToby Isaac 4250e228b242SToby Isaac not collective 4251e228b242SToby Isaac 42529435951eSToby Isaac Input Parameter: 42539435951eSToby Isaac . dm - The DM 42549435951eSToby Isaac 42559435951eSToby Isaac Output Parameter: 42569435951eSToby 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. 42579435951eSToby 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. 42589435951eSToby Isaac 42599435951eSToby Isaac Level: advanced 42609435951eSToby Isaac 42619435951eSToby Isaac Note: This gets borrowed references, so the user should not destroy the PetscSection or the Mat. 42629435951eSToby Isaac 42639435951eSToby Isaac .seealso: DMSetDefaultConstraints() 42649435951eSToby Isaac @*/ 42659435951eSToby Isaac PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat) 42669435951eSToby Isaac { 42679435951eSToby Isaac PetscErrorCode ierr; 42689435951eSToby Isaac 42699435951eSToby Isaac PetscFunctionBegin; 42709435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 42719435951eSToby Isaac if (!dm->defaultConstraintSection && !dm->defaultConstraintMat && dm->ops->createdefaultconstraints) {ierr = (*dm->ops->createdefaultconstraints)(dm);CHKERRQ(ierr);} 427245a75d81SToby Isaac if (section) {*section = dm->defaultConstraintSection;} 427345a75d81SToby Isaac if (mat) {*mat = dm->defaultConstraintMat;} 42749435951eSToby Isaac PetscFunctionReturn(0); 42759435951eSToby Isaac } 42769435951eSToby Isaac 42779435951eSToby Isaac /*@ 4278b7385021SStefano Zampini DMSetDefaultConstraints - Set the PetscSection and Mat that specify the local constraint interpolation. 42799435951eSToby Isaac 42809435951eSToby 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(). 42819435951eSToby Isaac 42829435951eSToby 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. 42839435951eSToby Isaac 4284e228b242SToby Isaac collective on dm 4285e228b242SToby Isaac 42869435951eSToby Isaac Input Parameters: 42879435951eSToby Isaac + dm - The DM 4288e228b242SToby 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). 4289e228b242SToby 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). 42909435951eSToby Isaac 42919435951eSToby Isaac Level: advanced 42929435951eSToby Isaac 42939435951eSToby Isaac Note: This increments the references of the PetscSection and the Mat, so they user can destroy them 42949435951eSToby Isaac 42959435951eSToby Isaac .seealso: DMGetDefaultConstraints() 42969435951eSToby Isaac @*/ 42979435951eSToby Isaac PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat) 42989435951eSToby Isaac { 4299e228b242SToby Isaac PetscMPIInt result; 43009435951eSToby Isaac PetscErrorCode ierr; 43019435951eSToby Isaac 43029435951eSToby Isaac PetscFunctionBegin; 43039435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4304e228b242SToby Isaac if (section) { 4305e228b242SToby Isaac PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 4306ffc4695bSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)section),&result);CHKERRMPI(ierr); 4307f60917d2SBarry Smith if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint section must have local communicator"); 4308e228b242SToby Isaac } 4309e228b242SToby Isaac if (mat) { 4310e228b242SToby Isaac PetscValidHeaderSpecific(mat,MAT_CLASSID,3); 4311ffc4695bSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)mat),&result);CHKERRMPI(ierr); 4312f60917d2SBarry Smith if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint matrix must have local communicator"); 4313e228b242SToby Isaac } 43149435951eSToby Isaac ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 43159435951eSToby Isaac ierr = PetscSectionDestroy(&dm->defaultConstraintSection);CHKERRQ(ierr); 43169435951eSToby Isaac dm->defaultConstraintSection = section; 43179435951eSToby Isaac ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 43189435951eSToby Isaac ierr = MatDestroy(&dm->defaultConstraintMat);CHKERRQ(ierr); 43199435951eSToby Isaac dm->defaultConstraintMat = mat; 43209435951eSToby Isaac PetscFunctionReturn(0); 43219435951eSToby Isaac } 43229435951eSToby Isaac 4323497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 4324507e4973SMatthew G. Knepley /* 4325507e4973SMatthew G. Knepley DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections. 4326507e4973SMatthew G. Knepley 4327507e4973SMatthew G. Knepley Input Parameters: 4328507e4973SMatthew G. Knepley + dm - The DM 4329507e4973SMatthew G. Knepley . localSection - PetscSection describing the local data layout 4330507e4973SMatthew G. Knepley - globalSection - PetscSection describing the global data layout 4331507e4973SMatthew G. Knepley 4332507e4973SMatthew G. Knepley Level: intermediate 4333507e4973SMatthew G. Knepley 43341bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMSetSectionSF() 4335507e4973SMatthew G. Knepley */ 4336f741bcd2SMatthew G. Knepley static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection) 4337507e4973SMatthew G. Knepley { 4338507e4973SMatthew G. Knepley MPI_Comm comm; 4339507e4973SMatthew G. Knepley PetscLayout layout; 4340507e4973SMatthew G. Knepley const PetscInt *ranges; 4341507e4973SMatthew G. Knepley PetscInt pStart, pEnd, p, nroots; 4342507e4973SMatthew G. Knepley PetscMPIInt size, rank; 4343507e4973SMatthew G. Knepley PetscBool valid = PETSC_TRUE, gvalid; 4344507e4973SMatthew G. Knepley PetscErrorCode ierr; 4345507e4973SMatthew G. Knepley 4346507e4973SMatthew G. Knepley PetscFunctionBegin; 4347507e4973SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 4348507e4973SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4349ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 4350ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 4351507e4973SMatthew G. Knepley ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr); 4352507e4973SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr); 4353507e4973SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr); 4354507e4973SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr); 4355507e4973SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr); 4356507e4973SMatthew G. Knepley ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr); 4357507e4973SMatthew G. Knepley ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr); 4358507e4973SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 4359f741bcd2SMatthew G. Knepley PetscInt dof, cdof, off, gdof, gcdof, goff, gsize, d; 4360507e4973SMatthew G. Knepley 4361507e4973SMatthew G. Knepley ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr); 4362507e4973SMatthew G. Knepley ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr); 4363507e4973SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr); 4364507e4973SMatthew G. Knepley ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr); 4365507e4973SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr); 4366507e4973SMatthew G. Knepley ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr); 4367507e4973SMatthew G. Knepley if (!gdof) continue; /* Censored point */ 4368507e4973SMatthew 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;} 4369507e4973SMatthew 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;} 4370507e4973SMatthew G. Knepley if (gdof < 0) { 4371507e4973SMatthew G. Knepley gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof; 4372507e4973SMatthew G. Knepley for (d = 0; d < gsize; ++d) { 4373507e4973SMatthew G. Knepley PetscInt offset = -(goff+1) + d, r; 4374507e4973SMatthew G. Knepley 4375507e4973SMatthew G. Knepley ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr); 4376507e4973SMatthew G. Knepley if (r < 0) r = -(r+2); 4377507e4973SMatthew 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;} 4378507e4973SMatthew G. Knepley } 4379507e4973SMatthew G. Knepley } 4380507e4973SMatthew G. Knepley } 4381507e4973SMatthew G. Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 4382507e4973SMatthew G. Knepley ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr); 4383b2566f29SBarry Smith ierr = MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRQ(ierr); 4384507e4973SMatthew G. Knepley if (!gvalid) { 4385507e4973SMatthew G. Knepley ierr = DMView(dm, NULL);CHKERRQ(ierr); 4386507e4973SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections"); 4387507e4973SMatthew G. Knepley } 4388507e4973SMatthew G. Knepley PetscFunctionReturn(0); 4389507e4973SMatthew G. Knepley } 4390f741bcd2SMatthew G. Knepley #endif 4391507e4973SMatthew G. Knepley 439288ed4aceSMatthew G Knepley /*@ 4393e87a4003SBarry Smith DMGetGlobalSection - Get the PetscSection encoding the global data layout for the DM. 439488ed4aceSMatthew G Knepley 4395d083f849SBarry Smith Collective on dm 43968b1ab98fSJed Brown 439788ed4aceSMatthew G Knepley Input Parameter: 439888ed4aceSMatthew G Knepley . dm - The DM 439988ed4aceSMatthew G Knepley 440088ed4aceSMatthew G Knepley Output Parameter: 440188ed4aceSMatthew G Knepley . section - The PetscSection 440288ed4aceSMatthew G Knepley 440388ed4aceSMatthew G Knepley Level: intermediate 440488ed4aceSMatthew G Knepley 440588ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSection. 440688ed4aceSMatthew G Knepley 440792fd8e1eSJed Brown .seealso: DMSetLocalSection(), DMGetLocalSection() 440888ed4aceSMatthew G Knepley @*/ 4409e87a4003SBarry Smith PetscErrorCode DMGetGlobalSection(DM dm, PetscSection *section) 44100adebc6cSBarry Smith { 441188ed4aceSMatthew G Knepley PetscErrorCode ierr; 441288ed4aceSMatthew G Knepley 441388ed4aceSMatthew G Knepley PetscFunctionBegin; 441488ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 441588ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 44161bb6d2a8SBarry Smith if (!dm->globalSection) { 4417fd59a867SMatthew G. Knepley PetscSection s; 4418fd59a867SMatthew G. Knepley 441992fd8e1eSJed Brown ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr); 4420fd59a867SMatthew 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"); 442133907cc2SStefano Zampini if (!dm->sf) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a point PetscSF in order to create a global PetscSection"); 44221bb6d2a8SBarry Smith ierr = PetscSectionCreateGlobalSection(s, dm->sf, PETSC_FALSE, PETSC_FALSE, &dm->globalSection);CHKERRQ(ierr); 4423cf06b437SMatthew G. Knepley ierr = PetscLayoutDestroy(&dm->map);CHKERRQ(ierr); 44241bb6d2a8SBarry Smith ierr = PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->globalSection, &dm->map);CHKERRQ(ierr); 44251bb6d2a8SBarry Smith ierr = PetscSectionViewFromOptions(dm->globalSection, NULL, "-global_section_view");CHKERRQ(ierr); 442688ed4aceSMatthew G Knepley } 44271bb6d2a8SBarry Smith *section = dm->globalSection; 442888ed4aceSMatthew G Knepley PetscFunctionReturn(0); 442988ed4aceSMatthew G Knepley } 443088ed4aceSMatthew G Knepley 4431b21d0597SMatthew G Knepley /*@ 4432e87a4003SBarry Smith DMSetGlobalSection - Set the PetscSection encoding the global data layout for the DM. 4433b21d0597SMatthew G Knepley 4434b21d0597SMatthew G Knepley Input Parameters: 4435b21d0597SMatthew G Knepley + dm - The DM 44365080bbdbSMatthew G Knepley - section - The PetscSection, or NULL 4437b21d0597SMatthew G Knepley 4438b21d0597SMatthew G Knepley Level: intermediate 4439b21d0597SMatthew G Knepley 4440b21d0597SMatthew G Knepley Note: Any existing Section will be destroyed 4441b21d0597SMatthew G Knepley 444292fd8e1eSJed Brown .seealso: DMGetGlobalSection(), DMSetLocalSection() 4443b21d0597SMatthew G Knepley @*/ 4444e87a4003SBarry Smith PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section) 44450adebc6cSBarry Smith { 4446b21d0597SMatthew G Knepley PetscErrorCode ierr; 4447b21d0597SMatthew G Knepley 4448b21d0597SMatthew G Knepley PetscFunctionBegin; 4449b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 44505080bbdbSMatthew G Knepley if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 44511d799100SJed Brown ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 44521bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&dm->globalSection);CHKERRQ(ierr); 44531bb6d2a8SBarry Smith dm->globalSection = section; 4454497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 44551bb6d2a8SBarry Smith if (section) {ierr = DMDefaultSectionCheckConsistency_Internal(dm, dm->localSection, section);CHKERRQ(ierr);} 4456507e4973SMatthew G. Knepley #endif 4457b21d0597SMatthew G Knepley PetscFunctionReturn(0); 4458b21d0597SMatthew G Knepley } 4459b21d0597SMatthew G Knepley 446088ed4aceSMatthew G Knepley /*@ 44611bb6d2a8SBarry Smith DMGetSectionSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set, 446288ed4aceSMatthew G Knepley it is created from the default PetscSection layouts in the DM. 446388ed4aceSMatthew G Knepley 446488ed4aceSMatthew G Knepley Input Parameter: 446588ed4aceSMatthew G Knepley . dm - The DM 446688ed4aceSMatthew G Knepley 446788ed4aceSMatthew G Knepley Output Parameter: 446888ed4aceSMatthew G Knepley . sf - The PetscSF 446988ed4aceSMatthew G Knepley 447088ed4aceSMatthew G Knepley Level: intermediate 447188ed4aceSMatthew G Knepley 447288ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSF. 447388ed4aceSMatthew G Knepley 44741bb6d2a8SBarry Smith .seealso: DMSetSectionSF(), DMCreateSectionSF() 447588ed4aceSMatthew G Knepley @*/ 44761bb6d2a8SBarry Smith PetscErrorCode DMGetSectionSF(DM dm, PetscSF *sf) 44770adebc6cSBarry Smith { 447888ed4aceSMatthew G Knepley PetscInt nroots; 447988ed4aceSMatthew G Knepley PetscErrorCode ierr; 448088ed4aceSMatthew G Knepley 448188ed4aceSMatthew G Knepley PetscFunctionBegin; 448288ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 448388ed4aceSMatthew G Knepley PetscValidPointer(sf, 2); 44841bb6d2a8SBarry Smith if (!dm->sectionSF) { 44851bb6d2a8SBarry Smith ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm),&dm->sectionSF);CHKERRQ(ierr); 448633907cc2SStefano Zampini } 44871bb6d2a8SBarry Smith ierr = PetscSFGetGraph(dm->sectionSF, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 448888ed4aceSMatthew G Knepley if (nroots < 0) { 448988ed4aceSMatthew G Knepley PetscSection section, gSection; 449088ed4aceSMatthew G Knepley 449192fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 449231ea6d37SMatthew G Knepley if (section) { 4493e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, &gSection);CHKERRQ(ierr); 44941bb6d2a8SBarry Smith ierr = DMCreateSectionSF(dm, section, gSection);CHKERRQ(ierr); 449531ea6d37SMatthew G Knepley } else { 44960298fd71SBarry Smith *sf = NULL; 449731ea6d37SMatthew G Knepley PetscFunctionReturn(0); 449831ea6d37SMatthew G Knepley } 449988ed4aceSMatthew G Knepley } 45001bb6d2a8SBarry Smith *sf = dm->sectionSF; 450188ed4aceSMatthew G Knepley PetscFunctionReturn(0); 450288ed4aceSMatthew G Knepley } 450388ed4aceSMatthew G Knepley 450488ed4aceSMatthew G Knepley /*@ 45051bb6d2a8SBarry Smith DMSetSectionSF - Set the PetscSF encoding the parallel dof overlap for the DM 450688ed4aceSMatthew G Knepley 450788ed4aceSMatthew G Knepley Input Parameters: 450888ed4aceSMatthew G Knepley + dm - The DM 450988ed4aceSMatthew G Knepley - sf - The PetscSF 451088ed4aceSMatthew G Knepley 451188ed4aceSMatthew G Knepley Level: intermediate 451288ed4aceSMatthew G Knepley 451388ed4aceSMatthew G Knepley Note: Any previous SF is destroyed 451488ed4aceSMatthew G Knepley 45151bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMCreateSectionSF() 451688ed4aceSMatthew G Knepley @*/ 45171bb6d2a8SBarry Smith PetscErrorCode DMSetSectionSF(DM dm, PetscSF sf) 45180adebc6cSBarry Smith { 451988ed4aceSMatthew G Knepley PetscErrorCode ierr; 452088ed4aceSMatthew G Knepley 452188ed4aceSMatthew G Knepley PetscFunctionBegin; 452288ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4523b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 452433907cc2SStefano Zampini ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr); 45251bb6d2a8SBarry Smith ierr = PetscSFDestroy(&dm->sectionSF);CHKERRQ(ierr); 45261bb6d2a8SBarry Smith dm->sectionSF = sf; 452788ed4aceSMatthew G Knepley PetscFunctionReturn(0); 452888ed4aceSMatthew G Knepley } 452988ed4aceSMatthew G Knepley 453088ed4aceSMatthew G Knepley /*@C 45311bb6d2a8SBarry Smith DMCreateSectionSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections 453288ed4aceSMatthew G Knepley describing the data layout. 453388ed4aceSMatthew G Knepley 453488ed4aceSMatthew G Knepley Input Parameters: 453588ed4aceSMatthew G Knepley + dm - The DM 453688ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout 453788ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout 453888ed4aceSMatthew G Knepley 45391bb6d2a8SBarry Smith Notes: One usually uses DMGetSectionSF() to obtain the PetscSF 454088ed4aceSMatthew G Knepley 45411bb6d2a8SBarry Smith Level: developer 45421bb6d2a8SBarry Smith 45431bb6d2a8SBarry Smith Developer Note: Since this routine has for arguments the two sections from the DM and puts the resulting PetscSF 45441bb6d2a8SBarry Smith directly into the DM, perhaps this function should not take the local and global sections as 45451bb6d2a8SBarry Smith input and should just obtain them from the DM? 45461bb6d2a8SBarry Smith 45471bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMSetSectionSF(), DMGetLocalSection(), DMGetGlobalSection() 454888ed4aceSMatthew G Knepley @*/ 45491bb6d2a8SBarry Smith PetscErrorCode DMCreateSectionSF(DM dm, PetscSection localSection, PetscSection globalSection) 455088ed4aceSMatthew G Knepley { 455188ed4aceSMatthew G Knepley PetscErrorCode ierr; 455288ed4aceSMatthew G Knepley 455388ed4aceSMatthew G Knepley PetscFunctionBegin; 455488ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4555b0c7db22SLisandro Dalcin ierr = PetscSFSetGraphSection(dm->sectionSF, localSection, globalSection);CHKERRQ(ierr); 455688ed4aceSMatthew G Knepley PetscFunctionReturn(0); 455788ed4aceSMatthew G Knepley } 4558af122d2aSMatthew G Knepley 4559b21d0597SMatthew G Knepley /*@ 4560b21d0597SMatthew G Knepley DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM. 4561b21d0597SMatthew G Knepley 4562b21d0597SMatthew G Knepley Input Parameter: 4563b21d0597SMatthew G Knepley . dm - The DM 4564b21d0597SMatthew G Knepley 4565b21d0597SMatthew G Knepley Output Parameter: 4566b21d0597SMatthew G Knepley . sf - The PetscSF 4567b21d0597SMatthew G Knepley 4568b21d0597SMatthew G Knepley Level: intermediate 4569b21d0597SMatthew G Knepley 4570b21d0597SMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSF. 4571b21d0597SMatthew G Knepley 45721bb6d2a8SBarry Smith .seealso: DMSetPointSF(), DMGetSectionSF(), DMSetSectionSF(), DMCreateSectionSF() 4573b21d0597SMatthew G Knepley @*/ 45740adebc6cSBarry Smith PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) 45750adebc6cSBarry Smith { 4576b21d0597SMatthew G Knepley PetscFunctionBegin; 4577b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4578b21d0597SMatthew G Knepley PetscValidPointer(sf, 2); 4579b21d0597SMatthew G Knepley *sf = dm->sf; 4580b21d0597SMatthew G Knepley PetscFunctionReturn(0); 4581b21d0597SMatthew G Knepley } 4582b21d0597SMatthew G Knepley 4583057b4bcdSMatthew G Knepley /*@ 4584057b4bcdSMatthew G Knepley DMSetPointSF - Set the PetscSF encoding the parallel section point overlap for the DM. 4585057b4bcdSMatthew G Knepley 4586057b4bcdSMatthew G Knepley Input Parameters: 4587057b4bcdSMatthew G Knepley + dm - The DM 4588057b4bcdSMatthew G Knepley - sf - The PetscSF 4589057b4bcdSMatthew G Knepley 4590057b4bcdSMatthew G Knepley Level: intermediate 4591057b4bcdSMatthew G Knepley 45921bb6d2a8SBarry Smith .seealso: DMGetPointSF(), DMGetSectionSF(), DMSetSectionSF(), DMCreateSectionSF() 4593057b4bcdSMatthew G Knepley @*/ 45940adebc6cSBarry Smith PetscErrorCode DMSetPointSF(DM dm, PetscSF sf) 45950adebc6cSBarry Smith { 4596057b4bcdSMatthew G Knepley PetscErrorCode ierr; 4597057b4bcdSMatthew G Knepley 4598057b4bcdSMatthew G Knepley PetscFunctionBegin; 4599057b4bcdSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4600b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 4601057b4bcdSMatthew G Knepley ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr); 460233907cc2SStefano Zampini ierr = PetscSFDestroy(&dm->sf);CHKERRQ(ierr); 4603057b4bcdSMatthew G Knepley dm->sf = sf; 4604057b4bcdSMatthew G Knepley PetscFunctionReturn(0); 4605057b4bcdSMatthew G Knepley } 4606057b4bcdSMatthew G Knepley 460734aa8a36SMatthew G. Knepley static PetscErrorCode DMSetDefaultAdjacency_Private(DM dm, PetscInt f, PetscObject disc) 460834aa8a36SMatthew G. Knepley { 460934aa8a36SMatthew G. Knepley PetscClassId id; 461034aa8a36SMatthew G. Knepley PetscErrorCode ierr; 461134aa8a36SMatthew G. Knepley 461234aa8a36SMatthew G. Knepley PetscFunctionBegin; 461334aa8a36SMatthew G. Knepley ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr); 461434aa8a36SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 461534aa8a36SMatthew G. Knepley ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr); 461634aa8a36SMatthew G. Knepley } else if (id == PETSCFV_CLASSID) { 461734aa8a36SMatthew G. Knepley ierr = DMSetAdjacency(dm, f, PETSC_TRUE, PETSC_FALSE);CHKERRQ(ierr); 461817c1d62eSMatthew G. Knepley } else { 461917c1d62eSMatthew G. Knepley ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr); 462034aa8a36SMatthew G. Knepley } 462134aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 462234aa8a36SMatthew G. Knepley } 462334aa8a36SMatthew G. Knepley 462444a7f3ddSMatthew G. Knepley static PetscErrorCode DMFieldEnlarge_Static(DM dm, PetscInt NfNew) 462544a7f3ddSMatthew G. Knepley { 462644a7f3ddSMatthew G. Knepley RegionField *tmpr; 462744a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf, f; 462844a7f3ddSMatthew G. Knepley PetscErrorCode ierr; 462944a7f3ddSMatthew G. Knepley 463044a7f3ddSMatthew G. Knepley PetscFunctionBegin; 463144a7f3ddSMatthew G. Knepley if (Nf >= NfNew) PetscFunctionReturn(0); 463244a7f3ddSMatthew G. Knepley ierr = PetscMalloc1(NfNew, &tmpr);CHKERRQ(ierr); 463344a7f3ddSMatthew G. Knepley for (f = 0; f < Nf; ++f) tmpr[f] = dm->fields[f]; 4634e0b68406SMatthew Knepley for (f = Nf; f < NfNew; ++f) {tmpr[f].disc = NULL; tmpr[f].label = NULL; tmpr[f].avoidTensor = PETSC_FALSE;} 463544a7f3ddSMatthew G. Knepley ierr = PetscFree(dm->fields);CHKERRQ(ierr); 463644a7f3ddSMatthew G. Knepley dm->Nf = NfNew; 463744a7f3ddSMatthew G. Knepley dm->fields = tmpr; 463844a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 463944a7f3ddSMatthew G. Knepley } 464044a7f3ddSMatthew G. Knepley 464144a7f3ddSMatthew G. Knepley /*@ 464244a7f3ddSMatthew G. Knepley DMClearFields - Remove all fields from the DM 464344a7f3ddSMatthew G. Knepley 4644d083f849SBarry Smith Logically collective on dm 464544a7f3ddSMatthew G. Knepley 464644a7f3ddSMatthew G. Knepley Input Parameter: 464744a7f3ddSMatthew G. Knepley . dm - The DM 464844a7f3ddSMatthew G. Knepley 464944a7f3ddSMatthew G. Knepley Level: intermediate 465044a7f3ddSMatthew G. Knepley 465144a7f3ddSMatthew G. Knepley .seealso: DMGetNumFields(), DMSetNumFields(), DMSetField() 465244a7f3ddSMatthew G. Knepley @*/ 465344a7f3ddSMatthew G. Knepley PetscErrorCode DMClearFields(DM dm) 465444a7f3ddSMatthew G. Knepley { 465544a7f3ddSMatthew G. Knepley PetscInt f; 465644a7f3ddSMatthew G. Knepley PetscErrorCode ierr; 465744a7f3ddSMatthew G. Knepley 465844a7f3ddSMatthew G. Knepley PetscFunctionBegin; 465944a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 466044a7f3ddSMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 466144a7f3ddSMatthew G. Knepley ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr); 466244a7f3ddSMatthew G. Knepley ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr); 466344a7f3ddSMatthew G. Knepley } 466444a7f3ddSMatthew G. Knepley ierr = PetscFree(dm->fields);CHKERRQ(ierr); 466544a7f3ddSMatthew G. Knepley dm->fields = NULL; 466644a7f3ddSMatthew G. Knepley dm->Nf = 0; 466744a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 466844a7f3ddSMatthew G. Knepley } 466944a7f3ddSMatthew G. Knepley 4670689b5837SMatthew G. Knepley /*@ 4671689b5837SMatthew G. Knepley DMGetNumFields - Get the number of fields in the DM 4672689b5837SMatthew G. Knepley 4673689b5837SMatthew G. Knepley Not collective 4674689b5837SMatthew G. Knepley 4675689b5837SMatthew G. Knepley Input Parameter: 4676689b5837SMatthew G. Knepley . dm - The DM 4677689b5837SMatthew G. Knepley 4678689b5837SMatthew G. Knepley Output Parameter: 4679689b5837SMatthew G. Knepley . Nf - The number of fields 4680689b5837SMatthew G. Knepley 4681689b5837SMatthew G. Knepley Level: intermediate 4682689b5837SMatthew G. Knepley 4683689b5837SMatthew G. Knepley .seealso: DMSetNumFields(), DMSetField() 4684689b5837SMatthew G. Knepley @*/ 46850f21e855SMatthew G. Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields) 46860f21e855SMatthew G. Knepley { 46870f21e855SMatthew G. Knepley PetscFunctionBegin; 46880f21e855SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4689534a8f05SLisandro Dalcin PetscValidIntPointer(numFields, 2); 469044a7f3ddSMatthew G. Knepley *numFields = dm->Nf; 4691af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4692af122d2aSMatthew G Knepley } 4693af122d2aSMatthew G Knepley 4694689b5837SMatthew G. Knepley /*@ 4695689b5837SMatthew G. Knepley DMSetNumFields - Set the number of fields in the DM 4696689b5837SMatthew G. Knepley 4697d083f849SBarry Smith Logically collective on dm 4698689b5837SMatthew G. Knepley 4699689b5837SMatthew G. Knepley Input Parameters: 4700689b5837SMatthew G. Knepley + dm - The DM 4701689b5837SMatthew G. Knepley - Nf - The number of fields 4702689b5837SMatthew G. Knepley 4703689b5837SMatthew G. Knepley Level: intermediate 4704689b5837SMatthew G. Knepley 4705689b5837SMatthew G. Knepley .seealso: DMGetNumFields(), DMSetField() 4706689b5837SMatthew G. Knepley @*/ 4707af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields) 4708af122d2aSMatthew G Knepley { 47090f21e855SMatthew G. Knepley PetscInt Nf, f; 4710af122d2aSMatthew G Knepley PetscErrorCode ierr; 4711af122d2aSMatthew G Knepley 4712af122d2aSMatthew G Knepley PetscFunctionBegin; 4713af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 471444a7f3ddSMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 47150f21e855SMatthew G. Knepley for (f = Nf; f < numFields; ++f) { 47160f21e855SMatthew G. Knepley PetscContainer obj; 47170f21e855SMatthew G. Knepley 47180f21e855SMatthew G. Knepley ierr = PetscContainerCreate(PetscObjectComm((PetscObject) dm), &obj);CHKERRQ(ierr); 471944a7f3ddSMatthew G. Knepley ierr = DMAddField(dm, NULL, (PetscObject) obj);CHKERRQ(ierr); 47200f21e855SMatthew G. Knepley ierr = PetscContainerDestroy(&obj);CHKERRQ(ierr); 4721af122d2aSMatthew G Knepley } 4722af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4723af122d2aSMatthew G Knepley } 4724af122d2aSMatthew G Knepley 4725c1929be8SMatthew G. Knepley /*@ 4726c1929be8SMatthew G. Knepley DMGetField - Return the discretization object for a given DM field 4727c1929be8SMatthew G. Knepley 4728c1929be8SMatthew G. Knepley Not collective 4729c1929be8SMatthew G. Knepley 4730c1929be8SMatthew G. Knepley Input Parameters: 4731c1929be8SMatthew G. Knepley + dm - The DM 4732c1929be8SMatthew G. Knepley - f - The field number 4733c1929be8SMatthew G. Knepley 473444a7f3ddSMatthew G. Knepley Output Parameters: 473544a7f3ddSMatthew G. Knepley + label - The label indicating the support of the field, or NULL for the entire mesh 473644a7f3ddSMatthew G. Knepley - field - The discretization object 4737c1929be8SMatthew G. Knepley 473844a7f3ddSMatthew G. Knepley Level: intermediate 4739c1929be8SMatthew G. Knepley 474044a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMSetField() 4741c1929be8SMatthew G. Knepley @*/ 474244a7f3ddSMatthew G. Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, DMLabel *label, PetscObject *field) 4743af122d2aSMatthew G Knepley { 4744af122d2aSMatthew G Knepley PetscFunctionBegin; 4745af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 474644a7f3ddSMatthew G. Knepley PetscValidPointer(field, 3); 474744a7f3ddSMatthew G. Knepley if ((f < 0) || (f >= dm->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, dm->Nf); 474844a7f3ddSMatthew G. Knepley if (label) *label = dm->fields[f].label; 474944a7f3ddSMatthew G. Knepley if (field) *field = dm->fields[f].disc; 4750decb47aaSMatthew G. Knepley PetscFunctionReturn(0); 4751decb47aaSMatthew G. Knepley } 4752decb47aaSMatthew G. Knepley 4753083401c6SMatthew G. Knepley /* Does not clear the DS */ 4754083401c6SMatthew G. Knepley PetscErrorCode DMSetField_Internal(DM dm, PetscInt f, DMLabel label, PetscObject field) 4755083401c6SMatthew G. Knepley { 4756083401c6SMatthew G. Knepley PetscErrorCode ierr; 4757083401c6SMatthew G. Knepley 4758083401c6SMatthew G. Knepley PetscFunctionBegin; 4759083401c6SMatthew G. Knepley ierr = DMFieldEnlarge_Static(dm, f+1);CHKERRQ(ierr); 4760083401c6SMatthew G. Knepley ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr); 4761083401c6SMatthew G. Knepley ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr); 4762083401c6SMatthew G. Knepley dm->fields[f].label = label; 4763083401c6SMatthew G. Knepley dm->fields[f].disc = field; 4764083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 4765083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr); 4766083401c6SMatthew G. Knepley PetscFunctionReturn(0); 4767083401c6SMatthew G. Knepley } 4768083401c6SMatthew G. Knepley 4769c1929be8SMatthew G. Knepley /*@ 4770c1929be8SMatthew G. Knepley DMSetField - Set the discretization object for a given DM field 4771c1929be8SMatthew G. Knepley 4772d083f849SBarry Smith Logically collective on dm 4773c1929be8SMatthew G. Knepley 4774c1929be8SMatthew G. Knepley Input Parameters: 4775c1929be8SMatthew G. Knepley + dm - The DM 4776c1929be8SMatthew G. Knepley . f - The field number 477744a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh 4778c1929be8SMatthew G. Knepley - field - The discretization object 4779c1929be8SMatthew G. Knepley 478044a7f3ddSMatthew G. Knepley Level: intermediate 4781c1929be8SMatthew G. Knepley 478244a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMGetField() 4783c1929be8SMatthew G. Knepley @*/ 478444a7f3ddSMatthew G. Knepley PetscErrorCode DMSetField(DM dm, PetscInt f, DMLabel label, PetscObject field) 4785decb47aaSMatthew G. Knepley { 4786decb47aaSMatthew G. Knepley PetscErrorCode ierr; 4787decb47aaSMatthew G. Knepley 4788decb47aaSMatthew G. Knepley PetscFunctionBegin; 4789decb47aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4790e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 479144a7f3ddSMatthew G. Knepley PetscValidHeader(field, 4); 4792e5e52638SMatthew G. Knepley if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 4793083401c6SMatthew G. Knepley ierr = DMSetField_Internal(dm, f, label, field);CHKERRQ(ierr); 479434aa8a36SMatthew G. Knepley ierr = DMSetDefaultAdjacency_Private(dm, f, field);CHKERRQ(ierr); 47952df9ee95SMatthew G. Knepley ierr = DMClearDS(dm);CHKERRQ(ierr); 479644a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 479744a7f3ddSMatthew G. Knepley } 479844a7f3ddSMatthew G. Knepley 479944a7f3ddSMatthew G. Knepley /*@ 480044a7f3ddSMatthew G. Knepley DMAddField - Add the discretization object for the given DM field 480144a7f3ddSMatthew G. Knepley 4802d083f849SBarry Smith Logically collective on dm 480344a7f3ddSMatthew G. Knepley 480444a7f3ddSMatthew G. Knepley Input Parameters: 480544a7f3ddSMatthew G. Knepley + dm - The DM 480644a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh 480744a7f3ddSMatthew G. Knepley - field - The discretization object 480844a7f3ddSMatthew G. Knepley 480944a7f3ddSMatthew G. Knepley Level: intermediate 481044a7f3ddSMatthew G. Knepley 481144a7f3ddSMatthew G. Knepley .seealso: DMSetField(), DMGetField() 481244a7f3ddSMatthew G. Knepley @*/ 481344a7f3ddSMatthew G. Knepley PetscErrorCode DMAddField(DM dm, DMLabel label, PetscObject field) 481444a7f3ddSMatthew G. Knepley { 481544a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf; 481644a7f3ddSMatthew G. Knepley PetscErrorCode ierr; 481744a7f3ddSMatthew G. Knepley 481844a7f3ddSMatthew G. Knepley PetscFunctionBegin; 481944a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 482044a7f3ddSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 482144a7f3ddSMatthew G. Knepley PetscValidHeader(field, 3); 482244a7f3ddSMatthew G. Knepley ierr = DMFieldEnlarge_Static(dm, Nf+1);CHKERRQ(ierr); 482344a7f3ddSMatthew G. Knepley dm->fields[Nf].label = label; 482444a7f3ddSMatthew G. Knepley dm->fields[Nf].disc = field; 482544a7f3ddSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 482644a7f3ddSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr); 482734aa8a36SMatthew G. Knepley ierr = DMSetDefaultAdjacency_Private(dm, Nf, field);CHKERRQ(ierr); 48282df9ee95SMatthew G. Knepley ierr = DMClearDS(dm);CHKERRQ(ierr); 4829af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4830af122d2aSMatthew G Knepley } 48316636e97aSMatthew G Knepley 4832e5e52638SMatthew G. Knepley /*@ 4833e0b68406SMatthew Knepley DMSetFieldAvoidTensor - Set flag to avoid defining the field on tensor cells 4834e0b68406SMatthew Knepley 4835e0b68406SMatthew Knepley Logically collective on dm 4836e0b68406SMatthew Knepley 4837e0b68406SMatthew Knepley Input Parameters: 4838e0b68406SMatthew Knepley + dm - The DM 4839e0b68406SMatthew Knepley . f - The field index 4840e0b68406SMatthew Knepley - avoidTensor - The flag to avoid defining the field on tensor cells 4841e0b68406SMatthew Knepley 4842e0b68406SMatthew Knepley Level: intermediate 4843e0b68406SMatthew Knepley 4844e0b68406SMatthew Knepley .seealso: DMGetFieldAvoidTensor(), DMSetField(), DMGetField() 4845e0b68406SMatthew Knepley @*/ 4846e0b68406SMatthew Knepley PetscErrorCode DMSetFieldAvoidTensor(DM dm, PetscInt f, PetscBool avoidTensor) 4847e0b68406SMatthew Knepley { 4848e0b68406SMatthew Knepley PetscFunctionBegin; 4849e0b68406SMatthew Knepley if ((f < 0) || (f >= dm->Nf)) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Field %D is not in [0, %D)", f, dm->Nf); 4850e0b68406SMatthew Knepley dm->fields[f].avoidTensor = avoidTensor; 4851e0b68406SMatthew Knepley PetscFunctionReturn(0); 4852e0b68406SMatthew Knepley } 4853e0b68406SMatthew Knepley 4854e0b68406SMatthew Knepley /*@ 4855e0b68406SMatthew Knepley DMGetFieldAvoidTensor - Get flag to avoid defining the field on tensor cells 4856e0b68406SMatthew Knepley 4857e0b68406SMatthew Knepley Logically collective on dm 4858e0b68406SMatthew Knepley 4859e0b68406SMatthew Knepley Input Parameters: 4860e0b68406SMatthew Knepley + dm - The DM 4861e0b68406SMatthew Knepley - f - The field index 4862e0b68406SMatthew Knepley 4863e0b68406SMatthew Knepley Output Parameter: 4864e0b68406SMatthew Knepley . avoidTensor - The flag to avoid defining the field on tensor cells 4865e0b68406SMatthew Knepley 4866e0b68406SMatthew Knepley Level: intermediate 4867e0b68406SMatthew Knepley 4868e0b68406SMatthew Knepley .seealso: DMSetFieldAvoidTensor(), DMSetField(), DMGetField() 4869e0b68406SMatthew Knepley @*/ 4870e0b68406SMatthew Knepley PetscErrorCode DMGetFieldAvoidTensor(DM dm, PetscInt f, PetscBool *avoidTensor) 4871e0b68406SMatthew Knepley { 4872e0b68406SMatthew Knepley PetscFunctionBegin; 4873e0b68406SMatthew Knepley if ((f < 0) || (f >= dm->Nf)) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Field %D is not in [0, %D)", f, dm->Nf); 4874e0b68406SMatthew Knepley *avoidTensor = dm->fields[f].avoidTensor; 4875e0b68406SMatthew Knepley PetscFunctionReturn(0); 4876e0b68406SMatthew Knepley } 4877e0b68406SMatthew Knepley 4878e0b68406SMatthew Knepley /*@ 4879e5e52638SMatthew G. Knepley DMCopyFields - Copy the discretizations for the DM into another DM 4880e5e52638SMatthew G. Knepley 4881d083f849SBarry Smith Collective on dm 4882e5e52638SMatthew G. Knepley 4883e5e52638SMatthew G. Knepley Input Parameter: 4884e5e52638SMatthew G. Knepley . dm - The DM 4885e5e52638SMatthew G. Knepley 4886e5e52638SMatthew G. Knepley Output Parameter: 4887e5e52638SMatthew G. Knepley . newdm - The DM 4888e5e52638SMatthew G. Knepley 4889e5e52638SMatthew G. Knepley Level: advanced 4890e5e52638SMatthew G. Knepley 4891e5e52638SMatthew G. Knepley .seealso: DMGetField(), DMSetField(), DMAddField(), DMCopyDS(), DMGetDS(), DMGetCellDS() 4892e5e52638SMatthew G. Knepley @*/ 4893e5e52638SMatthew G. Knepley PetscErrorCode DMCopyFields(DM dm, DM newdm) 4894e5e52638SMatthew G. Knepley { 4895e5e52638SMatthew G. Knepley PetscInt Nf, f; 4896e5e52638SMatthew G. Knepley PetscErrorCode ierr; 4897e5e52638SMatthew G. Knepley 4898e5e52638SMatthew G. Knepley PetscFunctionBegin; 4899e5e52638SMatthew G. Knepley if (dm == newdm) PetscFunctionReturn(0); 4900e5e52638SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 4901e5e52638SMatthew G. Knepley ierr = DMClearFields(newdm);CHKERRQ(ierr); 4902e5e52638SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 4903e5e52638SMatthew G. Knepley DMLabel label; 4904e5e52638SMatthew G. Knepley PetscObject field; 490534aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 4906e5e52638SMatthew G. Knepley 4907e5e52638SMatthew G. Knepley ierr = DMGetField(dm, f, &label, &field);CHKERRQ(ierr); 4908e5e52638SMatthew G. Knepley ierr = DMSetField(newdm, f, label, field);CHKERRQ(ierr); 490934aa8a36SMatthew G. Knepley ierr = DMGetAdjacency(dm, f, &useCone, &useClosure);CHKERRQ(ierr); 491034aa8a36SMatthew G. Knepley ierr = DMSetAdjacency(newdm, f, useCone, useClosure);CHKERRQ(ierr); 491134aa8a36SMatthew G. Knepley } 491234aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 491334aa8a36SMatthew G. Knepley } 491434aa8a36SMatthew G. Knepley 491534aa8a36SMatthew G. Knepley /*@ 491634aa8a36SMatthew G. Knepley DMGetAdjacency - Returns the flags for determining variable influence 491734aa8a36SMatthew G. Knepley 491834aa8a36SMatthew G. Knepley Not collective 491934aa8a36SMatthew G. Knepley 492034aa8a36SMatthew G. Knepley Input Parameters: 492134aa8a36SMatthew G. Knepley + dm - The DM object 492234aa8a36SMatthew G. Knepley - f - The field number, or PETSC_DEFAULT for the default adjacency 492334aa8a36SMatthew G. Knepley 492434aa8a36SMatthew G. Knepley Output Parameter: 492534aa8a36SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 492634aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 492734aa8a36SMatthew G. Knepley 492834aa8a36SMatthew G. Knepley Notes: 492934aa8a36SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 493034aa8a36SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 493134aa8a36SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 4932979e053dSMatthew G. Knepley Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 493334aa8a36SMatthew G. Knepley 493434aa8a36SMatthew G. Knepley Level: developer 493534aa8a36SMatthew G. Knepley 493634aa8a36SMatthew G. Knepley .seealso: DMSetAdjacency(), DMGetField(), DMSetField() 493734aa8a36SMatthew G. Knepley @*/ 493834aa8a36SMatthew G. Knepley PetscErrorCode DMGetAdjacency(DM dm, PetscInt f, PetscBool *useCone, PetscBool *useClosure) 493934aa8a36SMatthew G. Knepley { 494034aa8a36SMatthew G. Knepley PetscFunctionBegin; 494134aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4942534a8f05SLisandro Dalcin if (useCone) PetscValidBoolPointer(useCone, 3); 4943534a8f05SLisandro Dalcin if (useClosure) PetscValidBoolPointer(useClosure, 4); 494434aa8a36SMatthew G. Knepley if (f < 0) { 494534aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->adjacency[0]; 494634aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->adjacency[1]; 494734aa8a36SMatthew G. Knepley } else { 494834aa8a36SMatthew G. Knepley PetscInt Nf; 494934aa8a36SMatthew G. Knepley PetscErrorCode ierr; 495034aa8a36SMatthew G. Knepley 495134aa8a36SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 495234aa8a36SMatthew G. Knepley if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf); 495334aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->fields[f].adjacency[0]; 495434aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->fields[f].adjacency[1]; 495534aa8a36SMatthew G. Knepley } 495634aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 495734aa8a36SMatthew G. Knepley } 495834aa8a36SMatthew G. Knepley 495934aa8a36SMatthew G. Knepley /*@ 496034aa8a36SMatthew G. Knepley DMSetAdjacency - Set the flags for determining variable influence 496134aa8a36SMatthew G. Knepley 496234aa8a36SMatthew G. Knepley Not collective 496334aa8a36SMatthew G. Knepley 496434aa8a36SMatthew G. Knepley Input Parameters: 496534aa8a36SMatthew G. Knepley + dm - The DM object 496634aa8a36SMatthew G. Knepley . f - The field number 496734aa8a36SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 496834aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 496934aa8a36SMatthew G. Knepley 497034aa8a36SMatthew G. Knepley Notes: 497134aa8a36SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 497234aa8a36SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 497334aa8a36SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 4974979e053dSMatthew G. Knepley Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 497534aa8a36SMatthew G. Knepley 497634aa8a36SMatthew G. Knepley Level: developer 497734aa8a36SMatthew G. Knepley 497834aa8a36SMatthew G. Knepley .seealso: DMGetAdjacency(), DMGetField(), DMSetField() 497934aa8a36SMatthew G. Knepley @*/ 498034aa8a36SMatthew G. Knepley PetscErrorCode DMSetAdjacency(DM dm, PetscInt f, PetscBool useCone, PetscBool useClosure) 498134aa8a36SMatthew G. Knepley { 498234aa8a36SMatthew G. Knepley PetscFunctionBegin; 498334aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 498434aa8a36SMatthew G. Knepley if (f < 0) { 498534aa8a36SMatthew G. Knepley dm->adjacency[0] = useCone; 498634aa8a36SMatthew G. Knepley dm->adjacency[1] = useClosure; 498734aa8a36SMatthew G. Knepley } else { 498834aa8a36SMatthew G. Knepley PetscInt Nf; 498934aa8a36SMatthew G. Knepley PetscErrorCode ierr; 499034aa8a36SMatthew G. Knepley 499134aa8a36SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 499234aa8a36SMatthew G. Knepley if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf); 499334aa8a36SMatthew G. Knepley dm->fields[f].adjacency[0] = useCone; 499434aa8a36SMatthew G. Knepley dm->fields[f].adjacency[1] = useClosure; 4995e5e52638SMatthew G. Knepley } 4996e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 4997e5e52638SMatthew G. Knepley } 4998e5e52638SMatthew G. Knepley 4999b0441da4SMatthew G. Knepley /*@ 5000b0441da4SMatthew G. Knepley DMGetBasicAdjacency - Returns the flags for determining variable influence, using either the default or field 0 if it is defined 5001b0441da4SMatthew G. Knepley 5002b0441da4SMatthew G. Knepley Not collective 5003b0441da4SMatthew G. Knepley 5004b0441da4SMatthew G. Knepley Input Parameters: 5005b0441da4SMatthew G. Knepley . dm - The DM object 5006b0441da4SMatthew G. Knepley 5007b0441da4SMatthew G. Knepley Output Parameter: 5008b0441da4SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 5009b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5010b0441da4SMatthew G. Knepley 5011b0441da4SMatthew G. Knepley Notes: 5012b0441da4SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 5013b0441da4SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 5014b0441da4SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5015b0441da4SMatthew G. Knepley 5016b0441da4SMatthew G. Knepley Level: developer 5017b0441da4SMatthew G. Knepley 5018b0441da4SMatthew G. Knepley .seealso: DMSetBasicAdjacency(), DMGetField(), DMSetField() 5019b0441da4SMatthew G. Knepley @*/ 5020b0441da4SMatthew G. Knepley PetscErrorCode DMGetBasicAdjacency(DM dm, PetscBool *useCone, PetscBool *useClosure) 5021b0441da4SMatthew G. Knepley { 5022b0441da4SMatthew G. Knepley PetscInt Nf; 5023b0441da4SMatthew G. Knepley PetscErrorCode ierr; 5024b0441da4SMatthew G. Knepley 5025b0441da4SMatthew G. Knepley PetscFunctionBegin; 5026b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5027534a8f05SLisandro Dalcin if (useCone) PetscValidBoolPointer(useCone, 3); 5028534a8f05SLisandro Dalcin if (useClosure) PetscValidBoolPointer(useClosure, 4); 5029b0441da4SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 5030b0441da4SMatthew G. Knepley if (!Nf) { 5031b0441da4SMatthew G. Knepley ierr = DMGetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr); 5032b0441da4SMatthew G. Knepley } else { 5033b0441da4SMatthew G. Knepley ierr = DMGetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr); 5034b0441da4SMatthew G. Knepley } 5035b0441da4SMatthew G. Knepley PetscFunctionReturn(0); 5036b0441da4SMatthew G. Knepley } 5037b0441da4SMatthew G. Knepley 5038b0441da4SMatthew G. Knepley /*@ 5039b0441da4SMatthew G. Knepley DMSetBasicAdjacency - Set the flags for determining variable influence, using either the default or field 0 if it is defined 5040b0441da4SMatthew G. Knepley 5041b0441da4SMatthew G. Knepley Not collective 5042b0441da4SMatthew G. Knepley 5043b0441da4SMatthew G. Knepley Input Parameters: 5044b0441da4SMatthew G. Knepley + dm - The DM object 5045b0441da4SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 5046b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5047b0441da4SMatthew G. Knepley 5048b0441da4SMatthew G. Knepley Notes: 5049b0441da4SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 5050b0441da4SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 5051b0441da4SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5052b0441da4SMatthew G. Knepley 5053b0441da4SMatthew G. Knepley Level: developer 5054b0441da4SMatthew G. Knepley 5055b0441da4SMatthew G. Knepley .seealso: DMGetBasicAdjacency(), DMGetField(), DMSetField() 5056b0441da4SMatthew G. Knepley @*/ 5057b0441da4SMatthew G. Knepley PetscErrorCode DMSetBasicAdjacency(DM dm, PetscBool useCone, PetscBool useClosure) 5058b0441da4SMatthew G. Knepley { 5059b0441da4SMatthew G. Knepley PetscInt Nf; 5060b0441da4SMatthew G. Knepley PetscErrorCode ierr; 5061b0441da4SMatthew G. Knepley 5062b0441da4SMatthew G. Knepley PetscFunctionBegin; 5063b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5064b0441da4SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 5065b0441da4SMatthew G. Knepley if (!Nf) { 5066b0441da4SMatthew G. Knepley ierr = DMSetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr); 5067b0441da4SMatthew G. Knepley } else { 5068b0441da4SMatthew G. Knepley ierr = DMSetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr); 5069e5e52638SMatthew G. Knepley } 5070e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5071e5e52638SMatthew G. Knepley } 5072e5e52638SMatthew G. Knepley 5073783e2ec8SMatthew G. Knepley /* Complete labels that are being used for FEM BC */ 5074783e2ec8SMatthew G. Knepley static PetscErrorCode DMCompleteBoundaryLabel_Internal(DM dm, PetscDS ds, PetscInt field, PetscInt bdNum, const char labelname[]) 5075783e2ec8SMatthew G. Knepley { 5076783e2ec8SMatthew G. Knepley DMLabel label; 5077783e2ec8SMatthew G. Knepley PetscObject obj; 5078783e2ec8SMatthew G. Knepley PetscClassId id; 5079783e2ec8SMatthew G. Knepley PetscInt Nbd, bd; 5080783e2ec8SMatthew G. Knepley PetscBool isFE = PETSC_FALSE; 5081783e2ec8SMatthew G. Knepley PetscBool duplicate = PETSC_FALSE; 5082783e2ec8SMatthew G. Knepley PetscErrorCode ierr; 5083783e2ec8SMatthew G. Knepley 5084783e2ec8SMatthew G. Knepley PetscFunctionBegin; 5085783e2ec8SMatthew G. Knepley ierr = DMGetField(dm, field, NULL, &obj);CHKERRQ(ierr); 5086783e2ec8SMatthew G. Knepley ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 5087783e2ec8SMatthew G. Knepley if (id == PETSCFE_CLASSID) isFE = PETSC_TRUE; 5088783e2ec8SMatthew G. Knepley ierr = DMGetLabel(dm, labelname, &label);CHKERRQ(ierr); 5089783e2ec8SMatthew G. Knepley if (isFE && label) { 5090783e2ec8SMatthew G. Knepley /* Only want to modify label once */ 5091783e2ec8SMatthew G. Knepley ierr = PetscDSGetNumBoundary(ds, &Nbd);CHKERRQ(ierr); 5092783e2ec8SMatthew G. Knepley for (bd = 0; bd < PetscMin(Nbd, bdNum); ++bd) { 5093783e2ec8SMatthew G. Knepley const char *lname; 5094783e2ec8SMatthew G. Knepley 509556cf3b9cSMatthew G. Knepley ierr = PetscDSGetBoundary(ds, bd, NULL, NULL, &lname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 5096783e2ec8SMatthew G. Knepley ierr = PetscStrcmp(lname, labelname, &duplicate);CHKERRQ(ierr); 5097783e2ec8SMatthew G. Knepley if (duplicate) break; 5098783e2ec8SMatthew G. Knepley } 5099783e2ec8SMatthew G. Knepley if (!duplicate) { 5100783e2ec8SMatthew G. Knepley DM plex; 5101783e2ec8SMatthew G. Knepley 5102783e2ec8SMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 5103783e2ec8SMatthew G. Knepley if (plex) {ierr = DMPlexLabelComplete(plex, label);CHKERRQ(ierr);} 5104783e2ec8SMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 5105783e2ec8SMatthew G. Knepley } 5106783e2ec8SMatthew G. Knepley } 5107783e2ec8SMatthew G. Knepley PetscFunctionReturn(0); 5108783e2ec8SMatthew G. Knepley } 5109783e2ec8SMatthew G. Knepley 5110e5e52638SMatthew G. Knepley static PetscErrorCode DMDSEnlarge_Static(DM dm, PetscInt NdsNew) 5111e5e52638SMatthew G. Knepley { 5112e5e52638SMatthew G. Knepley DMSpace *tmpd; 5113e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5114e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5115e5e52638SMatthew G. Knepley 5116e5e52638SMatthew G. Knepley PetscFunctionBegin; 5117e5e52638SMatthew G. Knepley if (Nds >= NdsNew) PetscFunctionReturn(0); 5118e5e52638SMatthew G. Knepley ierr = PetscMalloc1(NdsNew, &tmpd);CHKERRQ(ierr); 5119e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) tmpd[s] = dm->probs[s]; 5120b3cf3223SMatthew G. Knepley for (s = Nds; s < NdsNew; ++s) {tmpd[s].ds = NULL; tmpd[s].label = NULL; tmpd[s].fields = NULL;} 5121e5e52638SMatthew G. Knepley ierr = PetscFree(dm->probs);CHKERRQ(ierr); 5122e5e52638SMatthew G. Knepley dm->Nds = NdsNew; 5123e5e52638SMatthew G. Knepley dm->probs = tmpd; 5124e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5125e5e52638SMatthew G. Knepley } 5126e5e52638SMatthew G. Knepley 5127e5e52638SMatthew G. Knepley /*@ 5128e5e52638SMatthew G. Knepley DMGetNumDS - Get the number of discrete systems in the DM 5129e5e52638SMatthew G. Knepley 5130e5e52638SMatthew G. Knepley Not collective 5131e5e52638SMatthew G. Knepley 5132e5e52638SMatthew G. Knepley Input Parameter: 5133e5e52638SMatthew G. Knepley . dm - The DM 5134e5e52638SMatthew G. Knepley 5135e5e52638SMatthew G. Knepley Output Parameter: 5136e5e52638SMatthew G. Knepley . Nds - The number of PetscDS objects 5137e5e52638SMatthew G. Knepley 5138e5e52638SMatthew G. Knepley Level: intermediate 5139e5e52638SMatthew G. Knepley 5140e5e52638SMatthew G. Knepley .seealso: DMGetDS(), DMGetCellDS() 5141e5e52638SMatthew G. Knepley @*/ 5142e5e52638SMatthew G. Knepley PetscErrorCode DMGetNumDS(DM dm, PetscInt *Nds) 5143e5e52638SMatthew G. Knepley { 5144e5e52638SMatthew G. Knepley PetscFunctionBegin; 5145e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5146534a8f05SLisandro Dalcin PetscValidIntPointer(Nds, 2); 5147e5e52638SMatthew G. Knepley *Nds = dm->Nds; 5148e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5149e5e52638SMatthew G. Knepley } 5150e5e52638SMatthew G. Knepley 5151e5e52638SMatthew G. Knepley /*@ 5152e5e52638SMatthew G. Knepley DMClearDS - Remove all discrete systems from the DM 5153e5e52638SMatthew G. Knepley 5154d083f849SBarry Smith Logically collective on dm 5155e5e52638SMatthew G. Knepley 5156e5e52638SMatthew G. Knepley Input Parameter: 5157e5e52638SMatthew G. Knepley . dm - The DM 5158e5e52638SMatthew G. Knepley 5159e5e52638SMatthew G. Knepley Level: intermediate 5160e5e52638SMatthew G. Knepley 5161e5e52638SMatthew G. Knepley .seealso: DMGetNumDS(), DMGetDS(), DMSetField() 5162e5e52638SMatthew G. Knepley @*/ 5163e5e52638SMatthew G. Knepley PetscErrorCode DMClearDS(DM dm) 5164e5e52638SMatthew G. Knepley { 5165e5e52638SMatthew G. Knepley PetscInt s; 5166e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5167e5e52638SMatthew G. Knepley 5168e5e52638SMatthew G. Knepley PetscFunctionBegin; 5169e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5170e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5171e5e52638SMatthew G. Knepley ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr); 5172e5e52638SMatthew G. Knepley ierr = DMLabelDestroy(&dm->probs[s].label);CHKERRQ(ierr); 5173b3cf3223SMatthew G. Knepley ierr = ISDestroy(&dm->probs[s].fields);CHKERRQ(ierr); 5174e5e52638SMatthew G. Knepley } 5175e5e52638SMatthew G. Knepley ierr = PetscFree(dm->probs);CHKERRQ(ierr); 5176e5e52638SMatthew G. Knepley dm->probs = NULL; 5177e5e52638SMatthew G. Knepley dm->Nds = 0; 5178e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5179e5e52638SMatthew G. Knepley } 5180e5e52638SMatthew G. Knepley 5181e5e52638SMatthew G. Knepley /*@ 5182e5e52638SMatthew G. Knepley DMGetDS - Get the default PetscDS 5183e5e52638SMatthew G. Knepley 5184e5e52638SMatthew G. Knepley Not collective 5185e5e52638SMatthew G. Knepley 5186e5e52638SMatthew G. Knepley Input Parameter: 5187e5e52638SMatthew G. Knepley . dm - The DM 5188e5e52638SMatthew G. Knepley 5189e5e52638SMatthew G. Knepley Output Parameter: 5190e5e52638SMatthew G. Knepley . prob - The default PetscDS 5191e5e52638SMatthew G. Knepley 5192e5e52638SMatthew G. Knepley Level: intermediate 5193e5e52638SMatthew G. Knepley 5194e5e52638SMatthew G. Knepley .seealso: DMGetCellDS(), DMGetRegionDS() 5195e5e52638SMatthew G. Knepley @*/ 5196e5e52638SMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *prob) 5197e5e52638SMatthew G. Knepley { 5198b0143b4dSMatthew G. Knepley PetscErrorCode ierr; 5199b0143b4dSMatthew G. Knepley 5200e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5201e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5202e5e52638SMatthew G. Knepley PetscValidPointer(prob, 2); 5203b0143b4dSMatthew G. Knepley if (dm->Nds <= 0) { 5204b0143b4dSMatthew G. Knepley PetscDS ds; 5205b0143b4dSMatthew G. Knepley 5206b0143b4dSMatthew G. Knepley ierr = PetscDSCreate(PetscObjectComm((PetscObject) dm), &ds);CHKERRQ(ierr); 5207b3cf3223SMatthew G. Knepley ierr = DMSetRegionDS(dm, NULL, NULL, ds);CHKERRQ(ierr); 5208b0143b4dSMatthew G. Knepley ierr = PetscDSDestroy(&ds);CHKERRQ(ierr); 5209b0143b4dSMatthew G. Knepley } 5210b0143b4dSMatthew G. Knepley *prob = dm->probs[0].ds; 5211e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5212e5e52638SMatthew G. Knepley } 5213e5e52638SMatthew G. Knepley 5214e5e52638SMatthew G. Knepley /*@ 5215e5e52638SMatthew G. Knepley DMGetCellDS - Get the PetscDS defined on a given cell 5216e5e52638SMatthew G. Knepley 5217e5e52638SMatthew G. Knepley Not collective 5218e5e52638SMatthew G. Knepley 5219e5e52638SMatthew G. Knepley Input Parameters: 5220e5e52638SMatthew G. Knepley + dm - The DM 5221e5e52638SMatthew G. Knepley - point - Cell for the DS 5222e5e52638SMatthew G. Knepley 5223e5e52638SMatthew G. Knepley Output Parameter: 5224e5e52638SMatthew G. Knepley . prob - The PetscDS defined on the given cell 5225e5e52638SMatthew G. Knepley 5226e5e52638SMatthew G. Knepley Level: developer 5227e5e52638SMatthew G. Knepley 5228b0143b4dSMatthew G. Knepley .seealso: DMGetDS(), DMSetRegionDS() 5229e5e52638SMatthew G. Knepley @*/ 5230e5e52638SMatthew G. Knepley PetscErrorCode DMGetCellDS(DM dm, PetscInt point, PetscDS *prob) 5231e5e52638SMatthew G. Knepley { 5232e5e52638SMatthew G. Knepley PetscDS probDef = NULL; 5233e5e52638SMatthew G. Knepley PetscInt s; 5234e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5235e5e52638SMatthew G. Knepley 5236e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5237e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5238e5e52638SMatthew G. Knepley PetscValidPointer(prob, 3); 5239360cf244SMatthew G. Knepley if (point < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Mesh point cannot be negative: %D", point); 5240e5e52638SMatthew G. Knepley *prob = NULL; 5241e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5242e5e52638SMatthew G. Knepley PetscInt val; 5243e5e52638SMatthew G. Knepley 5244e5e52638SMatthew G. Knepley if (!dm->probs[s].label) {probDef = dm->probs[s].ds;} 5245e5e52638SMatthew G. Knepley else { 5246e5e52638SMatthew G. Knepley ierr = DMLabelGetValue(dm->probs[s].label, point, &val);CHKERRQ(ierr); 5247e5e52638SMatthew G. Knepley if (val >= 0) {*prob = dm->probs[s].ds; break;} 5248e5e52638SMatthew G. Knepley } 5249e5e52638SMatthew G. Knepley } 5250e5e52638SMatthew G. Knepley if (!*prob) *prob = probDef; 5251e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5252e5e52638SMatthew G. Knepley } 5253e5e52638SMatthew G. Knepley 5254e5e52638SMatthew G. Knepley /*@ 5255e5e52638SMatthew G. Knepley DMGetRegionDS - Get the PetscDS for a given mesh region, defined by a DMLabel 5256e5e52638SMatthew G. Knepley 5257e5e52638SMatthew G. Knepley Not collective 5258e5e52638SMatthew G. Knepley 5259e5e52638SMatthew G. Knepley Input Parameters: 5260e5e52638SMatthew G. Knepley + dm - The DM 5261e5e52638SMatthew G. Knepley - label - The DMLabel defining the mesh region, or NULL for the entire mesh 5262e5e52638SMatthew G. Knepley 5263b3cf3223SMatthew G. Knepley Output Parameters: 5264b3cf3223SMatthew G. Knepley + fields - The IS containing the DM field numbers for the fields in this DS, or NULL 5265b3cf3223SMatthew G. Knepley - prob - The PetscDS defined on the given region, or NULL 5266e5e52638SMatthew G. Knepley 5267e5e52638SMatthew G. Knepley Note: If the label is missing, this function returns an error 5268e5e52638SMatthew G. Knepley 5269e5e52638SMatthew G. Knepley Level: advanced 5270e5e52638SMatthew G. Knepley 5271e5e52638SMatthew G. Knepley .seealso: DMGetRegionNumDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS() 5272e5e52638SMatthew G. Knepley @*/ 5273b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionDS(DM dm, DMLabel label, IS *fields, PetscDS *ds) 5274e5e52638SMatthew G. Knepley { 5275e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5276e5e52638SMatthew G. Knepley 5277e5e52638SMatthew G. Knepley PetscFunctionBegin; 5278e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5279e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5280b3cf3223SMatthew G. Knepley if (fields) {PetscValidPointer(fields, 3); *fields = NULL;} 5281b3cf3223SMatthew G. Knepley if (ds) {PetscValidPointer(ds, 4); *ds = NULL;} 5282e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5283b3cf3223SMatthew G. Knepley if (dm->probs[s].label == label) { 5284b3cf3223SMatthew G. Knepley if (fields) *fields = dm->probs[s].fields; 5285b3cf3223SMatthew G. Knepley if (ds) *ds = dm->probs[s].ds; 5286b3cf3223SMatthew G. Knepley PetscFunctionReturn(0); 5287b3cf3223SMatthew G. Knepley } 5288e5e52638SMatthew G. Knepley } 52892df9ee95SMatthew G. Knepley PetscFunctionReturn(0); 5290e5e52638SMatthew G. Knepley } 5291e5e52638SMatthew G. Knepley 5292e5e52638SMatthew G. Knepley /*@ 5293083401c6SMatthew G. Knepley DMSetRegionDS - Set the PetscDS for a given mesh region, defined by a DMLabel 5294083401c6SMatthew G. Knepley 5295083401c6SMatthew G. Knepley Collective on dm 5296083401c6SMatthew G. Knepley 5297083401c6SMatthew G. Knepley Input Parameters: 5298083401c6SMatthew G. Knepley + dm - The DM 5299083401c6SMatthew G. Knepley . label - The DMLabel defining the mesh region, or NULL for the entire mesh 5300083401c6SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL for all fields 5301083401c6SMatthew G. Knepley - prob - The PetscDS defined on the given cell 5302083401c6SMatthew G. Knepley 5303083401c6SMatthew G. Knepley Note: If the label has a DS defined, it will be replaced. Otherwise, it will be added to the DM. If DS is replaced, 5304083401c6SMatthew G. Knepley the fields argument is ignored. 5305083401c6SMatthew G. Knepley 5306083401c6SMatthew G. Knepley Level: advanced 5307083401c6SMatthew G. Knepley 5308083401c6SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionNumDS(), DMGetDS(), DMGetCellDS() 5309083401c6SMatthew G. Knepley @*/ 5310083401c6SMatthew G. Knepley PetscErrorCode DMSetRegionDS(DM dm, DMLabel label, IS fields, PetscDS ds) 5311083401c6SMatthew G. Knepley { 5312083401c6SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5313083401c6SMatthew G. Knepley PetscErrorCode ierr; 5314083401c6SMatthew G. Knepley 5315083401c6SMatthew G. Knepley PetscFunctionBegin; 5316083401c6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5317083401c6SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5318083401c6SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 3); 5319083401c6SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5320083401c6SMatthew G. Knepley if (dm->probs[s].label == label) { 5321083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr); 5322083401c6SMatthew G. Knepley dm->probs[s].ds = ds; 5323083401c6SMatthew G. Knepley PetscFunctionReturn(0); 5324083401c6SMatthew G. Knepley } 5325083401c6SMatthew G. Knepley } 5326083401c6SMatthew G. Knepley ierr = DMDSEnlarge_Static(dm, Nds+1);CHKERRQ(ierr); 5327083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 5328083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) fields);CHKERRQ(ierr); 5329083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) ds);CHKERRQ(ierr); 5330083401c6SMatthew G. Knepley if (!label) { 5331083401c6SMatthew G. Knepley /* Put the NULL label at the front, so it is returned as the default */ 5332083401c6SMatthew G. Knepley for (s = Nds-1; s >=0; --s) dm->probs[s+1] = dm->probs[s]; 5333083401c6SMatthew G. Knepley Nds = 0; 5334083401c6SMatthew G. Knepley } 5335083401c6SMatthew G. Knepley dm->probs[Nds].label = label; 5336083401c6SMatthew G. Knepley dm->probs[Nds].fields = fields; 5337083401c6SMatthew G. Knepley dm->probs[Nds].ds = ds; 5338083401c6SMatthew G. Knepley PetscFunctionReturn(0); 5339083401c6SMatthew G. Knepley } 5340083401c6SMatthew G. Knepley 5341083401c6SMatthew G. Knepley /*@ 5342e5e52638SMatthew G. Knepley DMGetRegionNumDS - Get the PetscDS for a given mesh region, defined by the region number 5343e5e52638SMatthew G. Knepley 5344e5e52638SMatthew G. Knepley Not collective 5345e5e52638SMatthew G. Knepley 5346e5e52638SMatthew G. Knepley Input Parameters: 5347e5e52638SMatthew G. Knepley + dm - The DM 5348e5e52638SMatthew G. Knepley - num - The region number, in [0, Nds) 5349e5e52638SMatthew G. Knepley 5350e5e52638SMatthew G. Knepley Output Parameters: 5351b3cf3223SMatthew G. Knepley + label - The region label, or NULL 5352b3cf3223SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL 5353083401c6SMatthew G. Knepley - ds - The PetscDS defined on the given region, or NULL 5354e5e52638SMatthew G. Knepley 5355e5e52638SMatthew G. Knepley Level: advanced 5356e5e52638SMatthew G. Knepley 5357e5e52638SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS() 5358e5e52638SMatthew G. Knepley @*/ 5359b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionNumDS(DM dm, PetscInt num, DMLabel *label, IS *fields, PetscDS *ds) 5360e5e52638SMatthew G. Knepley { 5361e5e52638SMatthew G. Knepley PetscInt Nds; 5362e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5363e5e52638SMatthew G. Knepley 5364e5e52638SMatthew G. Knepley PetscFunctionBegin; 5365e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5366e5e52638SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 5367e5e52638SMatthew G. Knepley if ((num < 0) || (num >= Nds)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Region number %D is not in [0, %D)", num, Nds); 5368e5e52638SMatthew G. Knepley if (label) { 5369e5e52638SMatthew G. Knepley PetscValidPointer(label, 3); 5370e5e52638SMatthew G. Knepley *label = dm->probs[num].label; 5371e5e52638SMatthew G. Knepley } 5372b3cf3223SMatthew G. Knepley if (fields) { 5373b3cf3223SMatthew G. Knepley PetscValidPointer(fields, 4); 5374b3cf3223SMatthew G. Knepley *fields = dm->probs[num].fields; 5375b3cf3223SMatthew G. Knepley } 5376e5e52638SMatthew G. Knepley if (ds) { 5377b3cf3223SMatthew G. Knepley PetscValidPointer(ds, 5); 5378e5e52638SMatthew G. Knepley *ds = dm->probs[num].ds; 5379e5e52638SMatthew G. Knepley } 5380e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5381e5e52638SMatthew G. Knepley } 5382e5e52638SMatthew G. Knepley 5383e5e52638SMatthew G. Knepley /*@ 5384083401c6SMatthew G. Knepley DMSetRegionNumDS - Set the PetscDS for a given mesh region, defined by the region number 5385e5e52638SMatthew G. Knepley 5386083401c6SMatthew G. Knepley Not collective 5387e5e52638SMatthew G. Knepley 5388e5e52638SMatthew G. Knepley Input Parameters: 5389e5e52638SMatthew G. Knepley + dm - The DM 5390083401c6SMatthew G. Knepley . num - The region number, in [0, Nds) 5391083401c6SMatthew G. Knepley . label - The region label, or NULL 5392083401c6SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL to prevent setting 5393083401c6SMatthew G. Knepley - ds - The PetscDS defined on the given region, or NULL to prevent setting 5394e5e52638SMatthew G. Knepley 5395e5e52638SMatthew G. Knepley Level: advanced 5396e5e52638SMatthew G. Knepley 5397083401c6SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS() 5398e5e52638SMatthew G. Knepley @*/ 5399083401c6SMatthew G. Knepley PetscErrorCode DMSetRegionNumDS(DM dm, PetscInt num, DMLabel label, IS fields, PetscDS ds) 5400e5e52638SMatthew G. Knepley { 5401083401c6SMatthew G. Knepley PetscInt Nds; 5402e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5403e5e52638SMatthew G. Knepley 5404e5e52638SMatthew G. Knepley PetscFunctionBegin; 5405e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5406083401c6SMatthew G. Knepley if (label) {PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3);} 5407083401c6SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 5408083401c6SMatthew G. Knepley if ((num < 0) || (num >= Nds)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Region number %D is not in [0, %D)", num, Nds); 5409e5e52638SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 5410083401c6SMatthew G. Knepley ierr = DMLabelDestroy(&dm->probs[num].label);CHKERRQ(ierr); 5411083401c6SMatthew G. Knepley dm->probs[num].label = label; 5412083401c6SMatthew G. Knepley if (fields) { 5413083401c6SMatthew G. Knepley PetscValidHeaderSpecific(fields, IS_CLASSID, 4); 5414b3cf3223SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) fields);CHKERRQ(ierr); 5415083401c6SMatthew G. Knepley ierr = ISDestroy(&dm->probs[num].fields);CHKERRQ(ierr); 5416083401c6SMatthew G. Knepley dm->probs[num].fields = fields; 5417e5e52638SMatthew G. Knepley } 5418083401c6SMatthew G. Knepley if (ds) { 5419083401c6SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 5); 5420083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) ds);CHKERRQ(ierr); 5421083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&dm->probs[num].ds);CHKERRQ(ierr); 5422083401c6SMatthew G. Knepley dm->probs[num].ds = ds; 5423083401c6SMatthew G. Knepley } 5424e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5425e5e52638SMatthew G. Knepley } 5426e5e52638SMatthew G. Knepley 5427e5e52638SMatthew G. Knepley /*@ 54281d3af9e0SMatthew G. Knepley DMFindRegionNum - Find the region number for a given PetscDS, or -1 if it is not found. 54291d3af9e0SMatthew G. Knepley 54301d3af9e0SMatthew G. Knepley Not collective 54311d3af9e0SMatthew G. Knepley 54321d3af9e0SMatthew G. Knepley Input Parameters: 54331d3af9e0SMatthew G. Knepley + dm - The DM 54341d3af9e0SMatthew G. Knepley - ds - The PetscDS defined on the given region 54351d3af9e0SMatthew G. Knepley 54361d3af9e0SMatthew G. Knepley Output Parameter: 54371d3af9e0SMatthew G. Knepley . num - The region number, in [0, Nds), or -1 if not found 54381d3af9e0SMatthew G. Knepley 54391d3af9e0SMatthew G. Knepley Level: advanced 54401d3af9e0SMatthew G. Knepley 54411d3af9e0SMatthew G. Knepley .seealso: DMGetRegionNumDS(), DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS() 54421d3af9e0SMatthew G. Knepley @*/ 54431d3af9e0SMatthew G. Knepley PetscErrorCode DMFindRegionNum(DM dm, PetscDS ds, PetscInt *num) 54441d3af9e0SMatthew G. Knepley { 54451d3af9e0SMatthew G. Knepley PetscInt Nds, n; 54461d3af9e0SMatthew G. Knepley PetscErrorCode ierr; 54471d3af9e0SMatthew G. Knepley 54481d3af9e0SMatthew G. Knepley PetscFunctionBegin; 54491d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 54501d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 2); 54511d3af9e0SMatthew G. Knepley PetscValidPointer(num, 3); 54521d3af9e0SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 54531d3af9e0SMatthew G. Knepley for (n = 0; n < Nds; ++n) if (ds == dm->probs[n].ds) break; 54541d3af9e0SMatthew G. Knepley if (n >= Nds) *num = -1; 54551d3af9e0SMatthew G. Knepley else *num = n; 54561d3af9e0SMatthew G. Knepley PetscFunctionReturn(0); 54571d3af9e0SMatthew G. Knepley } 54581d3af9e0SMatthew G. Knepley 54591d3af9e0SMatthew G. Knepley /*@ 5460e5e52638SMatthew G. Knepley DMCreateDS - Create the discrete systems for the DM based upon the fields added to the DM 5461e5e52638SMatthew G. Knepley 5462d083f849SBarry Smith Collective on dm 5463e5e52638SMatthew G. Knepley 5464e5e52638SMatthew G. Knepley Input Parameter: 5465e5e52638SMatthew G. Knepley . dm - The DM 5466e5e52638SMatthew G. Knepley 5467e5e52638SMatthew G. Knepley Note: If the label has a DS defined, it will be replaced. Otherwise, it will be added to the DM. 5468e5e52638SMatthew G. Knepley 5469e5e52638SMatthew G. Knepley Level: intermediate 5470e5e52638SMatthew G. Knepley 5471e5e52638SMatthew G. Knepley .seealso: DMSetField, DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS() 5472e5e52638SMatthew G. Knepley @*/ 5473e5e52638SMatthew G. Knepley PetscErrorCode DMCreateDS(DM dm) 5474e5e52638SMatthew G. Knepley { 5475e5e52638SMatthew G. Knepley MPI_Comm comm; 5476083401c6SMatthew G. Knepley PetscDS dsDef; 5477083401c6SMatthew G. Knepley DMLabel *labelSet; 5478f9244615SMatthew G. Knepley PetscInt dE, Nf = dm->Nf, f, s, Nl, l, Ndef, k; 5479f9244615SMatthew G. Knepley PetscBool doSetup = PETSC_TRUE, flg; 5480e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5481e5e52638SMatthew G. Knepley 5482e5e52638SMatthew G. Knepley PetscFunctionBegin; 5483e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5484e5e52638SMatthew G. Knepley if (!dm->fields) PetscFunctionReturn(0); 5485e5e52638SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 5486083401c6SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 5487083401c6SMatthew G. Knepley /* Determine how many regions we have */ 5488083401c6SMatthew G. Knepley ierr = PetscMalloc1(Nf, &labelSet);CHKERRQ(ierr); 5489083401c6SMatthew G. Knepley Nl = 0; 5490083401c6SMatthew G. Knepley Ndef = 0; 5491083401c6SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5492083401c6SMatthew G. Knepley DMLabel label = dm->fields[f].label; 5493083401c6SMatthew G. Knepley PetscInt l; 5494083401c6SMatthew G. Knepley 5495083401c6SMatthew G. Knepley if (!label) {++Ndef; continue;} 5496083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) if (label == labelSet[l]) break; 5497083401c6SMatthew G. Knepley if (l < Nl) continue; 5498083401c6SMatthew G. Knepley labelSet[Nl++] = label; 5499083401c6SMatthew G. Knepley } 5500083401c6SMatthew G. Knepley /* Create default DS if there are no labels to intersect with */ 5501083401c6SMatthew G. Knepley ierr = DMGetRegionDS(dm, NULL, NULL, &dsDef);CHKERRQ(ierr); 5502083401c6SMatthew G. Knepley if (!dsDef && Ndef && !Nl) { 5503b3cf3223SMatthew G. Knepley IS fields; 5504b3cf3223SMatthew G. Knepley PetscInt *fld, nf; 5505b3cf3223SMatthew G. Knepley 5506b3cf3223SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) ++nf; 5507083401c6SMatthew G. Knepley if (nf) { 5508b3cf3223SMatthew G. Knepley ierr = PetscMalloc1(nf, &fld);CHKERRQ(ierr); 5509b3cf3223SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) fld[nf++] = f; 551088f0c812SMatthew G. Knepley ierr = ISCreate(PETSC_COMM_SELF, &fields);CHKERRQ(ierr); 551188f0c812SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_");CHKERRQ(ierr); 551288f0c812SMatthew G. Knepley ierr = ISSetType(fields, ISGENERAL);CHKERRQ(ierr); 551388f0c812SMatthew G. Knepley ierr = ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER);CHKERRQ(ierr); 551488f0c812SMatthew G. Knepley 5515083401c6SMatthew G. Knepley ierr = PetscDSCreate(comm, &dsDef);CHKERRQ(ierr); 5516083401c6SMatthew G. Knepley ierr = DMSetRegionDS(dm, NULL, fields, dsDef);CHKERRQ(ierr); 5517083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&dsDef);CHKERRQ(ierr); 5518b3cf3223SMatthew G. Knepley ierr = ISDestroy(&fields);CHKERRQ(ierr); 55192df9ee95SMatthew G. Knepley } 5520083401c6SMatthew G. Knepley } 5521083401c6SMatthew G. Knepley ierr = DMGetRegionDS(dm, NULL, NULL, &dsDef);CHKERRQ(ierr); 5522083401c6SMatthew G. Knepley if (dsDef) {ierr = PetscDSSetCoordinateDimension(dsDef, dE);CHKERRQ(ierr);} 5523083401c6SMatthew G. Knepley /* Intersect labels with default fields */ 5524083401c6SMatthew G. Knepley if (Ndef && Nl) { 55250122748bSMatthew G. Knepley DM plex; 5526083401c6SMatthew G. Knepley DMLabel cellLabel; 5527083401c6SMatthew G. Knepley IS fieldIS, allcellIS, defcellIS = NULL; 5528083401c6SMatthew G. Knepley PetscInt *fields; 5529083401c6SMatthew G. Knepley const PetscInt *cells; 5530083401c6SMatthew G. Knepley PetscInt depth, nf = 0, n, c; 55310122748bSMatthew G. Knepley 55320122748bSMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 55330122748bSMatthew G. Knepley ierr = DMPlexGetDepth(plex, &depth);CHKERRQ(ierr); 5534083401c6SMatthew G. Knepley ierr = DMGetStratumIS(plex, "dim", depth, &allcellIS);CHKERRQ(ierr); 5535083401c6SMatthew G. Knepley if (!allcellIS) {ierr = DMGetStratumIS(plex, "depth", depth, &allcellIS);CHKERRQ(ierr);} 5536083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5537083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5538083401c6SMatthew G. Knepley IS pointIS; 5539083401c6SMatthew G. Knepley 5540083401c6SMatthew G. Knepley ierr = ISDestroy(&defcellIS);CHKERRQ(ierr); 5541083401c6SMatthew G. Knepley ierr = DMLabelGetStratumIS(label, 1, &pointIS);CHKERRQ(ierr); 5542083401c6SMatthew G. Knepley ierr = ISDifference(allcellIS, pointIS, &defcellIS);CHKERRQ(ierr); 5543083401c6SMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 5544083401c6SMatthew G. Knepley } 5545083401c6SMatthew G. Knepley ierr = ISDestroy(&allcellIS);CHKERRQ(ierr); 5546083401c6SMatthew G. Knepley 5547083401c6SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, "defaultCells", &cellLabel);CHKERRQ(ierr); 5548083401c6SMatthew G. Knepley ierr = ISGetLocalSize(defcellIS, &n);CHKERRQ(ierr); 5549083401c6SMatthew G. Knepley ierr = ISGetIndices(defcellIS, &cells);CHKERRQ(ierr); 5550083401c6SMatthew G. Knepley for (c = 0; c < n; ++c) {ierr = DMLabelSetValue(cellLabel, cells[c], 1);CHKERRQ(ierr);} 5551083401c6SMatthew G. Knepley ierr = ISRestoreIndices(defcellIS, &cells);CHKERRQ(ierr); 5552083401c6SMatthew G. Knepley ierr = ISDestroy(&defcellIS);CHKERRQ(ierr); 5553083401c6SMatthew G. Knepley ierr = DMPlexLabelComplete(plex, cellLabel);CHKERRQ(ierr); 5554083401c6SMatthew G. Knepley 5555083401c6SMatthew G. Knepley ierr = PetscMalloc1(Ndef, &fields);CHKERRQ(ierr); 5556083401c6SMatthew G. Knepley for (f = 0; f < Nf; ++f) if (!dm->fields[f].label) fields[nf++] = f; 5557083401c6SMatthew G. Knepley ierr = ISCreate(PETSC_COMM_SELF, &fieldIS);CHKERRQ(ierr); 5558083401c6SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) fieldIS, "dm_fields_");CHKERRQ(ierr); 5559083401c6SMatthew G. Knepley ierr = ISSetType(fieldIS, ISGENERAL);CHKERRQ(ierr); 5560083401c6SMatthew G. Knepley ierr = ISGeneralSetIndices(fieldIS, nf, fields, PETSC_OWN_POINTER);CHKERRQ(ierr); 5561083401c6SMatthew G. Knepley 5562083401c6SMatthew G. Knepley ierr = PetscDSCreate(comm, &dsDef);CHKERRQ(ierr); 5563083401c6SMatthew G. Knepley ierr = DMSetRegionDS(dm, cellLabel, fieldIS, dsDef);CHKERRQ(ierr); 5564083401c6SMatthew G. Knepley ierr = DMLabelDestroy(&cellLabel);CHKERRQ(ierr); 5565083401c6SMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(dsDef, dE);CHKERRQ(ierr); 5566083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&dsDef);CHKERRQ(ierr); 5567083401c6SMatthew G. Knepley ierr = ISDestroy(&fieldIS);CHKERRQ(ierr); 55680122748bSMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 5569083401c6SMatthew G. Knepley } 5570083401c6SMatthew G. Knepley /* Create label DSes 5571083401c6SMatthew G. Knepley - WE ONLY SUPPORT IDENTICAL OR DISJOINT LABELS 5572083401c6SMatthew G. Knepley */ 5573083401c6SMatthew G. Knepley /* TODO Should check that labels are disjoint */ 5574083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5575083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5576083401c6SMatthew G. Knepley PetscDS ds; 5577083401c6SMatthew G. Knepley IS fields; 5578083401c6SMatthew G. Knepley PetscInt *fld, nf; 5579083401c6SMatthew G. Knepley 5580083401c6SMatthew G. Knepley ierr = PetscDSCreate(comm, &ds);CHKERRQ(ierr); 5581083401c6SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (label == dm->fields[f].label || !dm->fields[f].label) ++nf; 5582083401c6SMatthew G. Knepley ierr = PetscMalloc1(nf, &fld);CHKERRQ(ierr); 5583083401c6SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (label == dm->fields[f].label || !dm->fields[f].label) fld[nf++] = f; 5584083401c6SMatthew G. Knepley ierr = ISCreate(PETSC_COMM_SELF, &fields);CHKERRQ(ierr); 5585083401c6SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_");CHKERRQ(ierr); 5586083401c6SMatthew G. Knepley ierr = ISSetType(fields, ISGENERAL);CHKERRQ(ierr); 5587083401c6SMatthew G. Knepley ierr = ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER);CHKERRQ(ierr); 5588083401c6SMatthew G. Knepley ierr = DMSetRegionDS(dm, label, fields, ds);CHKERRQ(ierr); 5589083401c6SMatthew G. Knepley ierr = ISDestroy(&fields);CHKERRQ(ierr); 5590083401c6SMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(ds, dE);CHKERRQ(ierr); 5591083401c6SMatthew G. Knepley { 5592083401c6SMatthew G. Knepley DMPolytopeType ct; 5593083401c6SMatthew G. Knepley PetscInt lStart, lEnd; 5594083401c6SMatthew G. Knepley PetscBool isHybridLocal = PETSC_FALSE, isHybrid; 55950122748bSMatthew G. Knepley 5596e5e52638SMatthew G. Knepley ierr = DMLabelGetBounds(label, &lStart, &lEnd);CHKERRQ(ierr); 5597665f567fSMatthew G. Knepley if (lStart >= 0) { 5598412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, lStart, &ct);CHKERRQ(ierr); 5599412e9a14SMatthew G. Knepley switch (ct) { 5600412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 5601412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 5602412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 5603412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 5604083401c6SMatthew G. Knepley isHybridLocal = PETSC_TRUE;break; 5605083401c6SMatthew G. Knepley default: break; 5606412e9a14SMatthew G. Knepley } 5607665f567fSMatthew G. Knepley } 5608ffc4695bSBarry Smith ierr = MPI_Allreduce(&isHybridLocal, &isHybrid, 1, MPIU_BOOL, MPI_LOR, comm);CHKERRMPI(ierr); 5609083401c6SMatthew G. Knepley ierr = PetscDSSetHybrid(ds, isHybrid);CHKERRQ(ierr); 5610e5e52638SMatthew G. Knepley } 5611083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&ds);CHKERRQ(ierr); 5612e5e52638SMatthew G. Knepley } 5613083401c6SMatthew G. Knepley ierr = PetscFree(labelSet);CHKERRQ(ierr); 5614e5e52638SMatthew G. Knepley /* Set fields in DSes */ 5615083401c6SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5616083401c6SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 5617083401c6SMatthew G. Knepley IS fields = dm->probs[s].fields; 5618083401c6SMatthew G. Knepley const PetscInt *fld; 5619083401c6SMatthew G. Knepley PetscInt nf; 5620e5e52638SMatthew G. Knepley 5621083401c6SMatthew G. Knepley ierr = ISGetLocalSize(fields, &nf);CHKERRQ(ierr); 5622083401c6SMatthew G. Knepley ierr = ISGetIndices(fields, &fld);CHKERRQ(ierr); 5623083401c6SMatthew G. Knepley for (f = 0; f < nf; ++f) { 5624083401c6SMatthew G. Knepley PetscObject disc = dm->fields[fld[f]].disc; 5625083401c6SMatthew G. Knepley PetscBool isHybrid; 5626e5e52638SMatthew G. Knepley PetscClassId id; 5627e5e52638SMatthew G. Knepley 5628083401c6SMatthew G. Knepley ierr = PetscDSGetHybrid(ds, &isHybrid);CHKERRQ(ierr); 5629083401c6SMatthew G. Knepley /* If this is a cohesive cell, then it needs the lower dimensional discretization */ 5630083401c6SMatthew G. Knepley if (isHybrid && f < nf-1) {ierr = PetscFEGetHeightSubspace((PetscFE) disc, 1, (PetscFE *) &disc);CHKERRQ(ierr);} 5631083401c6SMatthew G. Knepley ierr = PetscDSSetDiscretization(ds, f, disc);CHKERRQ(ierr); 5632083401c6SMatthew G. Knepley /* We allow people to have placeholder fields and construct the Section by hand */ 5633e5e52638SMatthew G. Knepley ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr); 5634e5e52638SMatthew G. Knepley if ((id != PETSCFE_CLASSID) && (id != PETSCFV_CLASSID)) doSetup = PETSC_FALSE; 5635e5e52638SMatthew G. Knepley } 5636083401c6SMatthew G. Knepley ierr = ISRestoreIndices(fields, &fld);CHKERRQ(ierr); 5637e5e52638SMatthew G. Knepley } 5638f9244615SMatthew G. Knepley /* Allow k-jet tabulation */ 5639f9244615SMatthew G. Knepley ierr = PetscOptionsGetInt(NULL, ((PetscObject) dm)->prefix, "-dm_ds_jet_degree", &k, &flg);CHKERRQ(ierr); 5640f9244615SMatthew G. Knepley if (flg) { 56413b4aee56SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 56423b4aee56SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 56433b4aee56SMatthew G. Knepley PetscInt Nf, f; 56443b4aee56SMatthew G. Knepley 56453b4aee56SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 56463b4aee56SMatthew G. Knepley for (f = 0; f < Nf; ++f) {ierr = PetscDSSetJetDegree(ds, f, k);CHKERRQ(ierr);} 56473b4aee56SMatthew G. Knepley } 5648f9244615SMatthew G. Knepley } 5649e5e52638SMatthew G. Knepley /* Setup DSes */ 5650e5e52638SMatthew G. Knepley if (doSetup) { 5651e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) {ierr = PetscDSSetUp(dm->probs[s].ds);CHKERRQ(ierr);} 5652e5e52638SMatthew G. Knepley } 5653e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5654e5e52638SMatthew G. Knepley } 5655e5e52638SMatthew G. Knepley 5656e5e52638SMatthew G. Knepley /*@ 56577f96f943SMatthew G. Knepley DMComputeExactSolution - Compute the exact solution for a given DM, using the PetscDS information. 56587f96f943SMatthew G. Knepley 5659f2cacb80SMatthew G. Knepley Collective on DM 5660f2cacb80SMatthew G. Knepley 56617f96f943SMatthew G. Knepley Input Parameters: 56627f96f943SMatthew G. Knepley + dm - The DM 56637f96f943SMatthew G. Knepley - time - The time 56647f96f943SMatthew G. Knepley 56657f96f943SMatthew G. Knepley Output Parameters: 5666f2cacb80SMatthew G. Knepley + u - The vector will be filled with exact solution values, or NULL 5667f2cacb80SMatthew G. Knepley - u_t - The vector will be filled with the time derivative of exact solution values, or NULL 56687f96f943SMatthew G. Knepley 56697f96f943SMatthew G. Knepley Note: The user must call PetscDSSetExactSolution() beforehand 56707f96f943SMatthew G. Knepley 56717f96f943SMatthew G. Knepley Level: developer 56727f96f943SMatthew G. Knepley 56737f96f943SMatthew G. Knepley .seealso: PetscDSSetExactSolution() 56747f96f943SMatthew G. Knepley @*/ 5675f2cacb80SMatthew G. Knepley PetscErrorCode DMComputeExactSolution(DM dm, PetscReal time, Vec u, Vec u_t) 56767f96f943SMatthew G. Knepley { 56777f96f943SMatthew G. Knepley PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx); 56787f96f943SMatthew G. Knepley void **ectxs; 56797f96f943SMatthew G. Knepley PetscInt Nf, Nds, s; 56807f96f943SMatthew G. Knepley PetscErrorCode ierr; 56817f96f943SMatthew G. Knepley 56827f96f943SMatthew G. Knepley PetscFunctionBegin; 5683f2cacb80SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5684f2cacb80SMatthew G. Knepley if (u) PetscValidHeaderSpecific(u, VEC_CLASSID, 3); 5685f2cacb80SMatthew G. Knepley if (u_t) PetscValidHeaderSpecific(u_t, VEC_CLASSID, 4); 56867f96f943SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 56877f96f943SMatthew G. Knepley ierr = PetscMalloc2(Nf, &exacts, Nf, &ectxs);CHKERRQ(ierr); 56887f96f943SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 56897f96f943SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 56907f96f943SMatthew G. Knepley PetscDS ds; 56917f96f943SMatthew G. Knepley DMLabel label; 56927f96f943SMatthew G. Knepley IS fieldIS; 56937f96f943SMatthew G. Knepley const PetscInt *fields, id = 1; 56947f96f943SMatthew G. Knepley PetscInt dsNf, f; 56957f96f943SMatthew G. Knepley 56967f96f943SMatthew G. Knepley ierr = DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds);CHKERRQ(ierr); 56977f96f943SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &dsNf);CHKERRQ(ierr); 56987f96f943SMatthew G. Knepley ierr = ISGetIndices(fieldIS, &fields);CHKERRQ(ierr); 56997f96f943SMatthew G. Knepley ierr = PetscArrayzero(exacts, Nf);CHKERRQ(ierr); 57007f96f943SMatthew G. Knepley ierr = PetscArrayzero(ectxs, Nf);CHKERRQ(ierr); 5701f2cacb80SMatthew G. Knepley if (u) { 57027f96f943SMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 57037f96f943SMatthew G. Knepley const PetscInt field = fields[f]; 57047f96f943SMatthew G. Knepley ierr = PetscDSGetExactSolution(ds, field, &exacts[field], &ectxs[field]);CHKERRQ(ierr); 57057f96f943SMatthew G. Knepley } 57067f96f943SMatthew G. Knepley ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr); 57077f96f943SMatthew G. Knepley if (label) { 57087f96f943SMatthew G. Knepley ierr = DMProjectFunctionLabel(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, u);CHKERRQ(ierr); 57097f96f943SMatthew G. Knepley } else { 57107f96f943SMatthew G. Knepley ierr = DMProjectFunction(dm, time, exacts, ectxs, INSERT_ALL_VALUES, u);CHKERRQ(ierr); 57117f96f943SMatthew G. Knepley } 57127f96f943SMatthew G. Knepley } 5713f2cacb80SMatthew G. Knepley if (u_t) { 5714f2cacb80SMatthew G. Knepley ierr = PetscArrayzero(exacts, Nf);CHKERRQ(ierr); 5715f2cacb80SMatthew G. Knepley ierr = PetscArrayzero(ectxs, Nf);CHKERRQ(ierr); 5716f2cacb80SMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 5717f2cacb80SMatthew G. Knepley const PetscInt field = fields[f]; 5718f2cacb80SMatthew G. Knepley ierr = PetscDSGetExactSolutionTimeDerivative(ds, field, &exacts[field], &ectxs[field]);CHKERRQ(ierr); 5719f2cacb80SMatthew G. Knepley } 5720f2cacb80SMatthew G. Knepley ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr); 5721f2cacb80SMatthew G. Knepley if (label) { 5722f2cacb80SMatthew G. Knepley ierr = DMProjectFunctionLabel(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, u_t);CHKERRQ(ierr); 5723f2cacb80SMatthew G. Knepley } else { 5724f2cacb80SMatthew G. Knepley ierr = DMProjectFunction(dm, time, exacts, ectxs, INSERT_ALL_VALUES, u_t);CHKERRQ(ierr); 5725f2cacb80SMatthew G. Knepley } 5726f2cacb80SMatthew G. Knepley } 5727f2cacb80SMatthew G. Knepley } 5728f2cacb80SMatthew G. Knepley if (u) { 57297f96f943SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) u, "Exact Solution");CHKERRQ(ierr); 57307f96f943SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) u, "exact_");CHKERRQ(ierr); 5731f2cacb80SMatthew G. Knepley } 5732f2cacb80SMatthew G. Knepley if (u_t) { 5733f2cacb80SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) u, "Exact Solution Time Derivative");CHKERRQ(ierr); 5734f2cacb80SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) u_t, "exact_t_");CHKERRQ(ierr); 5735f2cacb80SMatthew G. Knepley } 57367f96f943SMatthew G. Knepley ierr = PetscFree2(exacts, ectxs);CHKERRQ(ierr); 57377f96f943SMatthew G. Knepley PetscFunctionReturn(0); 57387f96f943SMatthew G. Knepley } 57397f96f943SMatthew G. Knepley 57407f96f943SMatthew G. Knepley /*@ 5741e5e52638SMatthew G. Knepley DMCopyDS - Copy the discrete systems for the DM into another DM 5742e5e52638SMatthew G. Knepley 5743d083f849SBarry Smith Collective on dm 5744e5e52638SMatthew G. Knepley 5745e5e52638SMatthew G. Knepley Input Parameter: 5746e5e52638SMatthew G. Knepley . dm - The DM 5747e5e52638SMatthew G. Knepley 5748e5e52638SMatthew G. Knepley Output Parameter: 5749e5e52638SMatthew G. Knepley . newdm - The DM 5750e5e52638SMatthew G. Knepley 5751e5e52638SMatthew G. Knepley Level: advanced 5752e5e52638SMatthew G. Knepley 5753e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS() 5754e5e52638SMatthew G. Knepley @*/ 5755e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDS(DM dm, DM newdm) 5756e5e52638SMatthew G. Knepley { 5757e5e52638SMatthew G. Knepley PetscInt Nds, s; 5758e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5759e5e52638SMatthew G. Knepley 5760e5e52638SMatthew G. Knepley PetscFunctionBegin; 5761e5e52638SMatthew G. Knepley if (dm == newdm) PetscFunctionReturn(0); 5762e5e52638SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 5763e5e52638SMatthew G. Knepley ierr = DMClearDS(newdm);CHKERRQ(ierr); 5764e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5765e5e52638SMatthew G. Knepley DMLabel label; 5766b3cf3223SMatthew G. Knepley IS fields; 5767e5e52638SMatthew G. Knepley PetscDS ds; 5768783e2ec8SMatthew G. Knepley PetscInt Nbd, bd; 5769e5e52638SMatthew G. Knepley 5770b3cf3223SMatthew G. Knepley ierr = DMGetRegionNumDS(dm, s, &label, &fields, &ds);CHKERRQ(ierr); 5771b3cf3223SMatthew G. Knepley ierr = DMSetRegionDS(newdm, label, fields, ds);CHKERRQ(ierr); 5772783e2ec8SMatthew G. Knepley ierr = PetscDSGetNumBoundary(ds, &Nbd);CHKERRQ(ierr); 5773783e2ec8SMatthew G. Knepley for (bd = 0; bd < Nbd; ++bd) { 5774783e2ec8SMatthew G. Knepley const char *labelname, *name; 5775783e2ec8SMatthew G. Knepley PetscInt field; 5776783e2ec8SMatthew G. Knepley 5777783e2ec8SMatthew G. Knepley /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */ 577856cf3b9cSMatthew G. Knepley ierr = PetscDSGetBoundary(ds, bd, NULL, &name, &labelname, &field, NULL, NULL, NULL, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 5779783e2ec8SMatthew G. Knepley ierr = DMCompleteBoundaryLabel_Internal(newdm, ds, field, bd, labelname);CHKERRQ(ierr); 5780783e2ec8SMatthew G. Knepley } 5781e5e52638SMatthew G. Knepley } 5782e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5783e5e52638SMatthew G. Knepley } 5784e5e52638SMatthew G. Knepley 5785e5e52638SMatthew G. Knepley /*@ 5786e5e52638SMatthew G. Knepley DMCopyDisc - Copy the fields and discrete systems for the DM into another DM 5787e5e52638SMatthew G. Knepley 5788d083f849SBarry Smith Collective on dm 5789e5e52638SMatthew G. Knepley 5790e5e52638SMatthew G. Knepley Input Parameter: 5791e5e52638SMatthew G. Knepley . dm - The DM 5792e5e52638SMatthew G. Knepley 5793e5e52638SMatthew G. Knepley Output Parameter: 5794e5e52638SMatthew G. Knepley . newdm - The DM 5795e5e52638SMatthew G. Knepley 5796e5e52638SMatthew G. Knepley Level: advanced 5797e5e52638SMatthew G. Knepley 5798e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMCopyDS() 5799e5e52638SMatthew G. Knepley @*/ 5800e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDisc(DM dm, DM newdm) 5801e5e52638SMatthew G. Knepley { 5802e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5803e5e52638SMatthew G. Knepley 5804e5e52638SMatthew G. Knepley PetscFunctionBegin; 5805e5e52638SMatthew G. Knepley ierr = DMCopyFields(dm, newdm);CHKERRQ(ierr); 5806e5e52638SMatthew G. Knepley ierr = DMCopyDS(dm, newdm);CHKERRQ(ierr); 5807e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5808e5e52638SMatthew G. Knepley } 5809e5e52638SMatthew G. Knepley 5810b64e0483SPeter Brune PetscErrorCode DMRestrictHook_Coordinates(DM dm,DM dmc,void *ctx) 5811b64e0483SPeter Brune { 5812b64e0483SPeter Brune DM dm_coord,dmc_coord; 5813b64e0483SPeter Brune PetscErrorCode ierr; 5814b64e0483SPeter Brune Vec coords,ccoords; 58156dbf9973SLawrence Mitchell Mat inject; 5816b64e0483SPeter Brune PetscFunctionBegin; 5817b64e0483SPeter Brune ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr); 5818b64e0483SPeter Brune ierr = DMGetCoordinateDM(dmc,&dmc_coord);CHKERRQ(ierr); 5819b64e0483SPeter Brune ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr); 5820b64e0483SPeter Brune ierr = DMGetCoordinates(dmc,&ccoords);CHKERRQ(ierr); 5821b64e0483SPeter Brune if (coords && !ccoords) { 5822b64e0483SPeter Brune ierr = DMCreateGlobalVector(dmc_coord,&ccoords);CHKERRQ(ierr); 58236668ed41SLisandro Dalcin ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr); 58246dbf9973SLawrence Mitchell ierr = DMCreateInjection(dmc_coord,dm_coord,&inject);CHKERRQ(ierr); 58252adcf181SLawrence Mitchell ierr = MatRestrict(inject,coords,ccoords);CHKERRQ(ierr); 58266dbf9973SLawrence Mitchell ierr = MatDestroy(&inject);CHKERRQ(ierr); 5827b64e0483SPeter Brune ierr = DMSetCoordinates(dmc,ccoords);CHKERRQ(ierr); 5828b64e0483SPeter Brune ierr = VecDestroy(&ccoords);CHKERRQ(ierr); 5829b64e0483SPeter Brune } 5830b64e0483SPeter Brune PetscFunctionReturn(0); 5831b64e0483SPeter Brune } 5832b64e0483SPeter Brune 583303dadc2fSPeter Brune static PetscErrorCode DMSubDomainHook_Coordinates(DM dm,DM subdm,void *ctx) 583403dadc2fSPeter Brune { 583503dadc2fSPeter Brune DM dm_coord,subdm_coord; 583603dadc2fSPeter Brune PetscErrorCode ierr; 583703dadc2fSPeter Brune Vec coords,ccoords,clcoords; 583803dadc2fSPeter Brune VecScatter *scat_i,*scat_g; 583903dadc2fSPeter Brune PetscFunctionBegin; 584003dadc2fSPeter Brune ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr); 584103dadc2fSPeter Brune ierr = DMGetCoordinateDM(subdm,&subdm_coord);CHKERRQ(ierr); 584203dadc2fSPeter Brune ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr); 584303dadc2fSPeter Brune ierr = DMGetCoordinates(subdm,&ccoords);CHKERRQ(ierr); 584403dadc2fSPeter Brune if (coords && !ccoords) { 584503dadc2fSPeter Brune ierr = DMCreateGlobalVector(subdm_coord,&ccoords);CHKERRQ(ierr); 58466668ed41SLisandro Dalcin ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr); 584703dadc2fSPeter Brune ierr = DMCreateLocalVector(subdm_coord,&clcoords);CHKERRQ(ierr); 584824640c55SToby Isaac ierr = PetscObjectSetName((PetscObject)clcoords,"coordinates");CHKERRQ(ierr); 584903dadc2fSPeter Brune ierr = DMCreateDomainDecompositionScatters(dm_coord,1,&subdm_coord,NULL,&scat_i,&scat_g);CHKERRQ(ierr); 585003dadc2fSPeter Brune ierr = VecScatterBegin(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 585103dadc2fSPeter Brune ierr = VecScatterEnd(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 58521ed9ada7SJunchao Zhang ierr = VecScatterBegin(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 585303dadc2fSPeter Brune ierr = VecScatterEnd(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 585403dadc2fSPeter Brune ierr = DMSetCoordinates(subdm,ccoords);CHKERRQ(ierr); 585503dadc2fSPeter Brune ierr = DMSetCoordinatesLocal(subdm,clcoords);CHKERRQ(ierr); 585603dadc2fSPeter Brune ierr = VecScatterDestroy(&scat_i[0]);CHKERRQ(ierr); 585703dadc2fSPeter Brune ierr = VecScatterDestroy(&scat_g[0]);CHKERRQ(ierr); 585803dadc2fSPeter Brune ierr = VecDestroy(&ccoords);CHKERRQ(ierr); 585903dadc2fSPeter Brune ierr = VecDestroy(&clcoords);CHKERRQ(ierr); 586003dadc2fSPeter Brune ierr = PetscFree(scat_i);CHKERRQ(ierr); 586103dadc2fSPeter Brune ierr = PetscFree(scat_g);CHKERRQ(ierr); 586203dadc2fSPeter Brune } 586303dadc2fSPeter Brune PetscFunctionReturn(0); 586403dadc2fSPeter Brune } 586503dadc2fSPeter Brune 5866c73cfb54SMatthew G. Knepley /*@ 5867c73cfb54SMatthew G. Knepley DMGetDimension - Return the topological dimension of the DM 5868c73cfb54SMatthew G. Knepley 5869c73cfb54SMatthew G. Knepley Not collective 5870c73cfb54SMatthew G. Knepley 5871c73cfb54SMatthew G. Knepley Input Parameter: 5872c73cfb54SMatthew G. Knepley . dm - The DM 5873c73cfb54SMatthew G. Knepley 5874c73cfb54SMatthew G. Knepley Output Parameter: 5875c73cfb54SMatthew G. Knepley . dim - The topological dimension 5876c73cfb54SMatthew G. Knepley 5877c73cfb54SMatthew G. Knepley Level: beginner 5878c73cfb54SMatthew G. Knepley 5879c73cfb54SMatthew G. Knepley .seealso: DMSetDimension(), DMCreate() 5880c73cfb54SMatthew G. Knepley @*/ 5881c73cfb54SMatthew G. Knepley PetscErrorCode DMGetDimension(DM dm, PetscInt *dim) 5882c73cfb54SMatthew G. Knepley { 5883c73cfb54SMatthew G. Knepley PetscFunctionBegin; 5884c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5885534a8f05SLisandro Dalcin PetscValidIntPointer(dim, 2); 5886c73cfb54SMatthew G. Knepley *dim = dm->dim; 5887c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 5888c73cfb54SMatthew G. Knepley } 5889c73cfb54SMatthew G. Knepley 5890c73cfb54SMatthew G. Knepley /*@ 5891c73cfb54SMatthew G. Knepley DMSetDimension - Set the topological dimension of the DM 5892c73cfb54SMatthew G. Knepley 5893c73cfb54SMatthew G. Knepley Collective on dm 5894c73cfb54SMatthew G. Knepley 5895c73cfb54SMatthew G. Knepley Input Parameters: 5896c73cfb54SMatthew G. Knepley + dm - The DM 5897c73cfb54SMatthew G. Knepley - dim - The topological dimension 5898c73cfb54SMatthew G. Knepley 5899c73cfb54SMatthew G. Knepley Level: beginner 5900c73cfb54SMatthew G. Knepley 5901c73cfb54SMatthew G. Knepley .seealso: DMGetDimension(), DMCreate() 5902c73cfb54SMatthew G. Knepley @*/ 5903c73cfb54SMatthew G. Knepley PetscErrorCode DMSetDimension(DM dm, PetscInt dim) 5904c73cfb54SMatthew G. Knepley { 5905e5e52638SMatthew G. Knepley PetscDS ds; 5906f17e8794SMatthew G. Knepley PetscErrorCode ierr; 5907f17e8794SMatthew G. Knepley 5908c73cfb54SMatthew G. Knepley PetscFunctionBegin; 5909c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5910c73cfb54SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 5911c73cfb54SMatthew G. Knepley dm->dim = dim; 5912e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 5913e5e52638SMatthew G. Knepley if (ds->dimEmbed < 0) {ierr = PetscDSSetCoordinateDimension(ds, dm->dim);CHKERRQ(ierr);} 5914c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 5915c73cfb54SMatthew G. Knepley } 5916c73cfb54SMatthew G. Knepley 5917793f3fe5SMatthew G. Knepley /*@ 5918793f3fe5SMatthew G. Knepley DMGetDimPoints - Get the half-open interval for all points of a given dimension 5919793f3fe5SMatthew G. Knepley 5920d083f849SBarry Smith Collective on dm 5921793f3fe5SMatthew G. Knepley 5922793f3fe5SMatthew G. Knepley Input Parameters: 5923793f3fe5SMatthew G. Knepley + dm - the DM 5924793f3fe5SMatthew G. Knepley - dim - the dimension 5925793f3fe5SMatthew G. Knepley 5926793f3fe5SMatthew G. Knepley Output Parameters: 5927793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension 5928aa049354SPatrick Sanan - pEnd - The first point following points of the given dimension 5929793f3fe5SMatthew G. Knepley 5930793f3fe5SMatthew G. Knepley Note: 5931793f3fe5SMatthew G. Knepley The points are vertices in the Hasse diagram encoding the topology. This is explained in 5932a8d69d7bSBarry Smith https://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme, 5933793f3fe5SMatthew G. Knepley then the interval is empty. 5934793f3fe5SMatthew G. Knepley 5935793f3fe5SMatthew G. Knepley Level: intermediate 5936793f3fe5SMatthew G. Knepley 5937793f3fe5SMatthew G. Knepley .seealso: DMPLEX, DMPlexGetDepthStratum(), DMPlexGetHeightStratum() 5938793f3fe5SMatthew G. Knepley @*/ 5939793f3fe5SMatthew G. Knepley PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 5940793f3fe5SMatthew G. Knepley { 5941793f3fe5SMatthew G. Knepley PetscInt d; 5942793f3fe5SMatthew G. Knepley PetscErrorCode ierr; 5943793f3fe5SMatthew G. Knepley 5944793f3fe5SMatthew G. Knepley PetscFunctionBegin; 5945793f3fe5SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 5946793f3fe5SMatthew G. Knepley ierr = DMGetDimension(dm, &d);CHKERRQ(ierr); 5947793f3fe5SMatthew G. Knepley if ((dim < 0) || (dim > d)) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %d 1", dim, d); 5948b9d85ea2SLisandro Dalcin if (!dm->ops->getdimpoints) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "DM type %s does not implement DMGetDimPoints",((PetscObject)dm)->type_name); 5949793f3fe5SMatthew G. Knepley ierr = (*dm->ops->getdimpoints)(dm, dim, pStart, pEnd);CHKERRQ(ierr); 5950793f3fe5SMatthew G. Knepley PetscFunctionReturn(0); 5951793f3fe5SMatthew G. Knepley } 5952793f3fe5SMatthew G. Knepley 59536636e97aSMatthew G Knepley /*@ 59546636e97aSMatthew G Knepley DMSetCoordinates - Sets into the DM a global vector that holds the coordinates 59556636e97aSMatthew G Knepley 5956d083f849SBarry Smith Collective on dm 59576636e97aSMatthew G Knepley 59586636e97aSMatthew G Knepley Input Parameters: 59596636e97aSMatthew G Knepley + dm - the DM 59606636e97aSMatthew G Knepley - c - coordinate vector 59616636e97aSMatthew G Knepley 59622dd40e9bSPatrick Sanan Notes: 59632dd40e9bSPatrick Sanan The coordinates do include those for ghost points, which are in the local vector. 59642dd40e9bSPatrick Sanan 59652dd40e9bSPatrick Sanan The vector c should be destroyed by the caller. 59666636e97aSMatthew G Knepley 59676636e97aSMatthew G Knepley Level: intermediate 59686636e97aSMatthew G Knepley 596960c22052SBarry Smith .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMDASetUniformCoordinates() 59706636e97aSMatthew G Knepley @*/ 59716636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c) 59726636e97aSMatthew G Knepley { 59736636e97aSMatthew G Knepley PetscErrorCode ierr; 59746636e97aSMatthew G Knepley 59756636e97aSMatthew G Knepley PetscFunctionBegin; 59766636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 59776636e97aSMatthew G Knepley PetscValidHeaderSpecific(c,VEC_CLASSID,2); 59786636e97aSMatthew G Knepley ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr); 59796636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr); 59806636e97aSMatthew G Knepley dm->coordinates = c; 59816636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr); 5982b64e0483SPeter Brune ierr = DMCoarsenHookAdd(dm,DMRestrictHook_Coordinates,NULL,NULL);CHKERRQ(ierr); 598303dadc2fSPeter Brune ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_Coordinates,NULL,NULL);CHKERRQ(ierr); 59846636e97aSMatthew G Knepley PetscFunctionReturn(0); 59856636e97aSMatthew G Knepley } 59866636e97aSMatthew G Knepley 59876636e97aSMatthew G Knepley /*@ 59886636e97aSMatthew G Knepley DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates 59896636e97aSMatthew G Knepley 59907058e716SVaclav Hapla Not collective 59916636e97aSMatthew G Knepley 59926636e97aSMatthew G Knepley Input Parameters: 59936636e97aSMatthew G Knepley + dm - the DM 59946636e97aSMatthew G Knepley - c - coordinate vector 59956636e97aSMatthew G Knepley 59962dd40e9bSPatrick Sanan Notes: 59976636e97aSMatthew G Knepley The coordinates of ghost points can be set using DMSetCoordinates() 59986636e97aSMatthew G Knepley followed by DMGetCoordinatesLocal(). This is intended to enable the 59996636e97aSMatthew G Knepley setting of ghost coordinates outside of the domain. 60006636e97aSMatthew G Knepley 60012dd40e9bSPatrick Sanan The vector c should be destroyed by the caller. 60022dd40e9bSPatrick Sanan 60036636e97aSMatthew G Knepley Level: intermediate 60046636e97aSMatthew G Knepley 60056636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM() 60066636e97aSMatthew G Knepley @*/ 60076636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c) 60086636e97aSMatthew G Knepley { 60096636e97aSMatthew G Knepley PetscErrorCode ierr; 60106636e97aSMatthew G Knepley 60116636e97aSMatthew G Knepley PetscFunctionBegin; 60126636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 60136636e97aSMatthew G Knepley PetscValidHeaderSpecific(c,VEC_CLASSID,2); 60146636e97aSMatthew G Knepley ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr); 60156636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr); 60168865f1eaSKarl Rupp 60176636e97aSMatthew G Knepley dm->coordinatesLocal = c; 60188865f1eaSKarl Rupp 60196636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr); 60206636e97aSMatthew G Knepley PetscFunctionReturn(0); 60216636e97aSMatthew G Knepley } 60226636e97aSMatthew G Knepley 60236636e97aSMatthew G Knepley /*@ 60246636e97aSMatthew G Knepley DMGetCoordinates - Gets a global vector with the coordinates associated with the DM. 60256636e97aSMatthew G Knepley 6026d083f849SBarry Smith Collective on dm 60276636e97aSMatthew G Knepley 60286636e97aSMatthew G Knepley Input Parameter: 60296636e97aSMatthew G Knepley . dm - the DM 60306636e97aSMatthew G Knepley 60316636e97aSMatthew G Knepley Output Parameter: 60326636e97aSMatthew G Knepley . c - global coordinate vector 60336636e97aSMatthew G Knepley 60346636e97aSMatthew G Knepley Note: 603560c22052SBarry Smith This is a borrowed reference, so the user should NOT destroy this vector. When the DM is 603660c22052SBarry Smith destroyed the array will no longer be valid. 60376636e97aSMatthew G Knepley 60386636e97aSMatthew G Knepley Each process has only the local coordinates (does NOT have the ghost coordinates). 60396636e97aSMatthew G Knepley 60406636e97aSMatthew G Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 60416636e97aSMatthew G Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 60426636e97aSMatthew G Knepley 60436636e97aSMatthew G Knepley Level: intermediate 60446636e97aSMatthew G Knepley 604560c22052SBarry Smith .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMDASetUniformCoordinates() 60466636e97aSMatthew G Knepley @*/ 60476636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c) 60486636e97aSMatthew G Knepley { 60496636e97aSMatthew G Knepley PetscErrorCode ierr; 60506636e97aSMatthew G Knepley 60516636e97aSMatthew G Knepley PetscFunctionBegin; 60526636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 60536636e97aSMatthew G Knepley PetscValidPointer(c,2); 60541f588964SMatthew G Knepley if (!dm->coordinates && dm->coordinatesLocal) { 60550298fd71SBarry Smith DM cdm = NULL; 60561970a576SMatthew G. Knepley PetscBool localized; 60576636e97aSMatthew G Knepley 60586636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 60596636e97aSMatthew G Knepley ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr); 60601970a576SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 60611970a576SMatthew G. Knepley /* Block size is not correctly set by CreateGlobalVector() if coordinates are localized */ 60621970a576SMatthew G. Knepley if (localized) { 60631970a576SMatthew G. Knepley PetscInt cdim; 60641970a576SMatthew G. Knepley 60651970a576SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 60661970a576SMatthew G. Knepley ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr); 60671970a576SMatthew G. Knepley } 60686636e97aSMatthew G Knepley ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr); 60696636e97aSMatthew G Knepley ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr); 60706636e97aSMatthew G Knepley ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr); 60716636e97aSMatthew G Knepley } 60726636e97aSMatthew G Knepley *c = dm->coordinates; 60736636e97aSMatthew G Knepley PetscFunctionReturn(0); 60746636e97aSMatthew G Knepley } 60756636e97aSMatthew G Knepley 60766636e97aSMatthew G Knepley /*@ 607781e9a530SVaclav Hapla DMGetCoordinatesLocalSetUp - Prepares a local vector of coordinates, so that DMGetCoordinatesLocalNoncollective() can be used as non-collective afterwards. 607881e9a530SVaclav Hapla 6079d083f849SBarry Smith Collective on dm 608081e9a530SVaclav Hapla 608181e9a530SVaclav Hapla Input Parameter: 608281e9a530SVaclav Hapla . dm - the DM 608381e9a530SVaclav Hapla 608481e9a530SVaclav Hapla Level: advanced 608581e9a530SVaclav Hapla 608681e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalNoncollective() 608781e9a530SVaclav Hapla @*/ 608881e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalSetUp(DM dm) 608981e9a530SVaclav Hapla { 609081e9a530SVaclav Hapla PetscErrorCode ierr; 609181e9a530SVaclav Hapla 609281e9a530SVaclav Hapla PetscFunctionBegin; 609381e9a530SVaclav Hapla PetscValidHeaderSpecific(dm,DM_CLASSID,1); 609481e9a530SVaclav Hapla if (!dm->coordinatesLocal && dm->coordinates) { 60951970a576SMatthew G. Knepley DM cdm = NULL; 60961970a576SMatthew G. Knepley PetscBool localized; 60971970a576SMatthew G. Knepley 609881e9a530SVaclav Hapla ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 609981e9a530SVaclav Hapla ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr); 61001970a576SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 61011970a576SMatthew G. Knepley /* Block size is not correctly set by CreateLocalVector() if coordinates are localized */ 61021970a576SMatthew G. Knepley if (localized) { 61031970a576SMatthew G. Knepley PetscInt cdim; 61041970a576SMatthew G. Knepley 61051970a576SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 61061970a576SMatthew G. Knepley ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr); 61071970a576SMatthew G. Knepley } 610881e9a530SVaclav Hapla ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr); 610981e9a530SVaclav Hapla ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr); 611081e9a530SVaclav Hapla ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr); 611181e9a530SVaclav Hapla } 611281e9a530SVaclav Hapla PetscFunctionReturn(0); 611381e9a530SVaclav Hapla } 611481e9a530SVaclav Hapla 611581e9a530SVaclav Hapla /*@ 61166636e97aSMatthew G Knepley DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM. 61176636e97aSMatthew G Knepley 6118d083f849SBarry Smith Collective on dm 61196636e97aSMatthew G Knepley 61206636e97aSMatthew G Knepley Input Parameter: 61216636e97aSMatthew G Knepley . dm - the DM 61226636e97aSMatthew G Knepley 61236636e97aSMatthew G Knepley Output Parameter: 61246636e97aSMatthew G Knepley . c - coordinate vector 61256636e97aSMatthew G Knepley 61266636e97aSMatthew G Knepley Note: 61276636e97aSMatthew G Knepley This is a borrowed reference, so the user should NOT destroy this vector 61286636e97aSMatthew G Knepley 61296636e97aSMatthew G Knepley Each process has the local and ghost coordinates 61306636e97aSMatthew G Knepley 61316636e97aSMatthew G Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 61326636e97aSMatthew G Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 61336636e97aSMatthew G Knepley 61346636e97aSMatthew G Knepley Level: intermediate 61356636e97aSMatthew G Knepley 613681e9a530SVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM(), DMGetCoordinatesLocalNoncollective() 61376636e97aSMatthew G Knepley @*/ 61386636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c) 61396636e97aSMatthew G Knepley { 61406636e97aSMatthew G Knepley PetscErrorCode ierr; 61416636e97aSMatthew G Knepley 61426636e97aSMatthew G Knepley PetscFunctionBegin; 61436636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 61446636e97aSMatthew G Knepley PetscValidPointer(c,2); 614581e9a530SVaclav Hapla ierr = DMGetCoordinatesLocalSetUp(dm);CHKERRQ(ierr); 61466636e97aSMatthew G Knepley *c = dm->coordinatesLocal; 61476636e97aSMatthew G Knepley PetscFunctionReturn(0); 61486636e97aSMatthew G Knepley } 61496636e97aSMatthew G Knepley 615081e9a530SVaclav Hapla /*@ 615181e9a530SVaclav Hapla DMGetCoordinatesLocalNoncollective - Non-collective version of DMGetCoordinatesLocal(). Fails if global coordinates have been set and DMGetCoordinatesLocalSetUp() not called. 615281e9a530SVaclav Hapla 615381e9a530SVaclav Hapla Not collective 615481e9a530SVaclav Hapla 615581e9a530SVaclav Hapla Input Parameter: 615681e9a530SVaclav Hapla . dm - the DM 615781e9a530SVaclav Hapla 615881e9a530SVaclav Hapla Output Parameter: 615981e9a530SVaclav Hapla . c - coordinate vector 616081e9a530SVaclav Hapla 616181e9a530SVaclav Hapla Level: advanced 616281e9a530SVaclav Hapla 616381e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalSetUp(), DMGetCoordinatesLocal(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM() 616481e9a530SVaclav Hapla @*/ 616581e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalNoncollective(DM dm, Vec *c) 616681e9a530SVaclav Hapla { 616781e9a530SVaclav Hapla PetscFunctionBegin; 616881e9a530SVaclav Hapla PetscValidHeaderSpecific(dm,DM_CLASSID,1); 616981e9a530SVaclav Hapla PetscValidPointer(c,2); 617081e9a530SVaclav Hapla if (!dm->coordinatesLocal && dm->coordinates) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called"); 61716636e97aSMatthew G Knepley *c = dm->coordinatesLocal; 61726636e97aSMatthew G Knepley PetscFunctionReturn(0); 61736636e97aSMatthew G Knepley } 61746636e97aSMatthew G Knepley 61752db98f8dSVaclav Hapla /*@ 61762db98f8dSVaclav Hapla DMGetCoordinatesLocalTuple - Gets a local vector with the coordinates of specified points and section describing its layout. 61772db98f8dSVaclav Hapla 61782db98f8dSVaclav Hapla Not collective 61792db98f8dSVaclav Hapla 61802db98f8dSVaclav Hapla Input Parameter: 61812db98f8dSVaclav Hapla + dm - the DM 61822db98f8dSVaclav Hapla - p - the IS of points whose coordinates will be returned 61832db98f8dSVaclav Hapla 61842db98f8dSVaclav Hapla Output Parameter: 61852db98f8dSVaclav Hapla + pCoordSection - the PetscSection describing the layout of pCoord, i.e. each point corresponds to one point in p, and DOFs correspond to coordinates 61862db98f8dSVaclav Hapla - pCoord - the Vec with coordinates of points in p 61872db98f8dSVaclav Hapla 61882db98f8dSVaclav Hapla Note: 61892db98f8dSVaclav Hapla DMGetCoordinatesLocalSetUp() must be called first. This function employs DMGetCoordinatesLocalNoncollective() so it is not collective. 61902db98f8dSVaclav Hapla 61912db98f8dSVaclav Hapla This creates a new vector, so the user SHOULD destroy this vector 61922db98f8dSVaclav Hapla 61932db98f8dSVaclav Hapla Each process has the local and ghost coordinates 61942db98f8dSVaclav Hapla 61952db98f8dSVaclav Hapla For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 61962db98f8dSVaclav Hapla and (x_0,y_0,z_0,x_1,y_1,z_1...) 61972db98f8dSVaclav Hapla 61982db98f8dSVaclav Hapla Level: advanced 61992db98f8dSVaclav Hapla 62002db98f8dSVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinatesLocal(), DMGetCoordinatesLocalNoncollective(), DMGetCoordinatesLocalSetUp(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM() 62012db98f8dSVaclav Hapla @*/ 62022db98f8dSVaclav Hapla PetscErrorCode DMGetCoordinatesLocalTuple(DM dm, IS p, PetscSection *pCoordSection, Vec *pCoord) 62032db98f8dSVaclav Hapla { 62042db98f8dSVaclav Hapla PetscSection cs, newcs; 62052db98f8dSVaclav Hapla Vec coords; 62062db98f8dSVaclav Hapla const PetscScalar *arr; 62072db98f8dSVaclav Hapla PetscScalar *newarr=NULL; 62082db98f8dSVaclav Hapla PetscInt n; 62092db98f8dSVaclav Hapla PetscErrorCode ierr; 62102db98f8dSVaclav Hapla 62112db98f8dSVaclav Hapla PetscFunctionBegin; 62122db98f8dSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 62132db98f8dSVaclav Hapla PetscValidHeaderSpecific(p, IS_CLASSID, 2); 62142db98f8dSVaclav Hapla if (pCoordSection) PetscValidPointer(pCoordSection, 3); 62152db98f8dSVaclav Hapla if (pCoord) PetscValidPointer(pCoord, 4); 62162db98f8dSVaclav Hapla if (!dm->coordinatesLocal) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called or coordinates not set"); 62171bb6d2a8SBarry Smith if (!dm->coordinateDM || !dm->coordinateDM->localSection) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM not supported"); 62181bb6d2a8SBarry Smith cs = dm->coordinateDM->localSection; 62192db98f8dSVaclav Hapla coords = dm->coordinatesLocal; 62202db98f8dSVaclav Hapla ierr = VecGetArrayRead(coords, &arr);CHKERRQ(ierr); 62212db98f8dSVaclav Hapla ierr = PetscSectionExtractDofsFromArray(cs, MPIU_SCALAR, arr, p, &newcs, pCoord ? ((void**)&newarr) : NULL);CHKERRQ(ierr); 62222db98f8dSVaclav Hapla ierr = VecRestoreArrayRead(coords, &arr);CHKERRQ(ierr); 62232db98f8dSVaclav Hapla if (pCoord) { 62242db98f8dSVaclav Hapla ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr); 62252db98f8dSVaclav Hapla /* set array in two steps to mimic PETSC_OWN_POINTER */ 62262db98f8dSVaclav Hapla ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)p), 1, n, NULL, pCoord);CHKERRQ(ierr); 62272db98f8dSVaclav Hapla ierr = VecReplaceArray(*pCoord, newarr);CHKERRQ(ierr); 6228ad9ac99dSVaclav Hapla } else { 6229ad9ac99dSVaclav Hapla ierr = PetscFree(newarr);CHKERRQ(ierr); 62302db98f8dSVaclav Hapla } 6231ad9ac99dSVaclav Hapla if (pCoordSection) {*pCoordSection = newcs;} 6232ad9ac99dSVaclav Hapla else {ierr = PetscSectionDestroy(&newcs);CHKERRQ(ierr);} 62332db98f8dSVaclav Hapla PetscFunctionReturn(0); 62342db98f8dSVaclav Hapla } 62352db98f8dSVaclav Hapla 6236f19dbd58SToby Isaac PetscErrorCode DMGetCoordinateField(DM dm, DMField *field) 6237f19dbd58SToby Isaac { 6238f19dbd58SToby Isaac PetscErrorCode ierr; 6239f19dbd58SToby Isaac 6240f19dbd58SToby Isaac PetscFunctionBegin; 6241f19dbd58SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6242f19dbd58SToby Isaac PetscValidPointer(field,2); 6243f19dbd58SToby Isaac if (!dm->coordinateField) { 6244f19dbd58SToby Isaac if (dm->ops->createcoordinatefield) { 6245f19dbd58SToby Isaac ierr = (*dm->ops->createcoordinatefield)(dm,&dm->coordinateField);CHKERRQ(ierr); 6246f19dbd58SToby Isaac } 6247f19dbd58SToby Isaac } 6248f19dbd58SToby Isaac *field = dm->coordinateField; 6249f19dbd58SToby Isaac PetscFunctionReturn(0); 6250f19dbd58SToby Isaac } 6251f19dbd58SToby Isaac 6252f19dbd58SToby Isaac PetscErrorCode DMSetCoordinateField(DM dm, DMField field) 6253f19dbd58SToby Isaac { 6254f19dbd58SToby Isaac PetscErrorCode ierr; 6255f19dbd58SToby Isaac 6256f19dbd58SToby Isaac PetscFunctionBegin; 6257f19dbd58SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6258f19dbd58SToby Isaac if (field) PetscValidHeaderSpecific(field,DMFIELD_CLASSID,2); 6259c4e6da2cSBarry Smith ierr = PetscObjectReference((PetscObject)field);CHKERRQ(ierr); 6260f19dbd58SToby Isaac ierr = DMFieldDestroy(&dm->coordinateField);CHKERRQ(ierr); 6261f19dbd58SToby Isaac dm->coordinateField = field; 6262f19dbd58SToby Isaac PetscFunctionReturn(0); 6263f19dbd58SToby Isaac } 6264f19dbd58SToby Isaac 62656636e97aSMatthew G Knepley /*@ 62661cfe2091SMatthew G. Knepley DMGetCoordinateDM - Gets the DM that prescribes coordinate layout and scatters between global and local coordinates 62676636e97aSMatthew G Knepley 6268d083f849SBarry Smith Collective on dm 62696636e97aSMatthew G Knepley 62706636e97aSMatthew G Knepley Input Parameter: 62716636e97aSMatthew G Knepley . dm - the DM 62726636e97aSMatthew G Knepley 62736636e97aSMatthew G Knepley Output Parameter: 62746636e97aSMatthew G Knepley . cdm - coordinate DM 62756636e97aSMatthew G Knepley 62766636e97aSMatthew G Knepley Level: intermediate 62776636e97aSMatthew G Knepley 62781cfe2091SMatthew G. Knepley .seealso: DMSetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal() 62796636e97aSMatthew G Knepley @*/ 62806636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm) 62816636e97aSMatthew G Knepley { 62826636e97aSMatthew G Knepley PetscErrorCode ierr; 62836636e97aSMatthew G Knepley 62846636e97aSMatthew G Knepley PetscFunctionBegin; 62856636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 62866636e97aSMatthew G Knepley PetscValidPointer(cdm,2); 62876636e97aSMatthew G Knepley if (!dm->coordinateDM) { 6288308f8a94SToby Isaac DM cdm; 6289308f8a94SToby Isaac 629082f516ccSBarry Smith if (!dm->ops->createcoordinatedm) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unable to create coordinates for this DM"); 6291308f8a94SToby Isaac ierr = (*dm->ops->createcoordinatedm)(dm, &cdm);CHKERRQ(ierr); 6292308f8a94SToby Isaac /* Just in case the DM sets the coordinate DM when creating it (DMP4est can do this, because it may not setup 6293308f8a94SToby Isaac * until the call to CreateCoordinateDM) */ 6294308f8a94SToby Isaac ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr); 6295308f8a94SToby Isaac dm->coordinateDM = cdm; 62966636e97aSMatthew G Knepley } 62976636e97aSMatthew G Knepley *cdm = dm->coordinateDM; 62986636e97aSMatthew G Knepley PetscFunctionReturn(0); 62996636e97aSMatthew G Knepley } 6300e87bb0d3SMatthew G Knepley 63011cfe2091SMatthew G. Knepley /*@ 63021cfe2091SMatthew G. Knepley DMSetCoordinateDM - Sets the DM that prescribes coordinate layout and scatters between global and local coordinates 63031cfe2091SMatthew G. Knepley 6304d083f849SBarry Smith Logically Collective on dm 63051cfe2091SMatthew G. Knepley 63061cfe2091SMatthew G. Knepley Input Parameters: 63071cfe2091SMatthew G. Knepley + dm - the DM 63081cfe2091SMatthew G. Knepley - cdm - coordinate DM 63091cfe2091SMatthew G. Knepley 63101cfe2091SMatthew G. Knepley Level: intermediate 63111cfe2091SMatthew G. Knepley 63121cfe2091SMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal() 63131cfe2091SMatthew G. Knepley @*/ 63141cfe2091SMatthew G. Knepley PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm) 63151cfe2091SMatthew G. Knepley { 63161cfe2091SMatthew G. Knepley PetscErrorCode ierr; 63171cfe2091SMatthew G. Knepley 63181cfe2091SMatthew G. Knepley PetscFunctionBegin; 63191cfe2091SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 63201cfe2091SMatthew G. Knepley PetscValidHeaderSpecific(cdm,DM_CLASSID,2); 6321f26b38b9SToby Isaac ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr); 63221cfe2091SMatthew G. Knepley ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr); 63231cfe2091SMatthew G. Knepley dm->coordinateDM = cdm; 63241cfe2091SMatthew G. Knepley PetscFunctionReturn(0); 63251cfe2091SMatthew G. Knepley } 63261cfe2091SMatthew G. Knepley 632746e270d4SMatthew G. Knepley /*@ 632846e270d4SMatthew G. Knepley DMGetCoordinateDim - Retrieve the dimension of embedding space for coordinate values. 632946e270d4SMatthew G. Knepley 633046e270d4SMatthew G. Knepley Not Collective 633146e270d4SMatthew G. Knepley 633246e270d4SMatthew G. Knepley Input Parameter: 633346e270d4SMatthew G. Knepley . dm - The DM object 633446e270d4SMatthew G. Knepley 633546e270d4SMatthew G. Knepley Output Parameter: 633646e270d4SMatthew G. Knepley . dim - The embedding dimension 633746e270d4SMatthew G. Knepley 633846e270d4SMatthew G. Knepley Level: intermediate 633946e270d4SMatthew G. Knepley 634092fd8e1eSJed Brown .seealso: DMSetCoordinateDim(), DMGetCoordinateSection(), DMGetCoordinateDM(), DMGetLocalSection(), DMSetLocalSection() 634146e270d4SMatthew G. Knepley @*/ 634246e270d4SMatthew G. Knepley PetscErrorCode DMGetCoordinateDim(DM dm, PetscInt *dim) 634346e270d4SMatthew G. Knepley { 634446e270d4SMatthew G. Knepley PetscFunctionBegin; 634546e270d4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6346534a8f05SLisandro Dalcin PetscValidIntPointer(dim, 2); 63479a9a41abSToby Isaac if (dm->dimEmbed == PETSC_DEFAULT) { 63489a9a41abSToby Isaac dm->dimEmbed = dm->dim; 63499a9a41abSToby Isaac } 635046e270d4SMatthew G. Knepley *dim = dm->dimEmbed; 635146e270d4SMatthew G. Knepley PetscFunctionReturn(0); 635246e270d4SMatthew G. Knepley } 635346e270d4SMatthew G. Knepley 635446e270d4SMatthew G. Knepley /*@ 635546e270d4SMatthew G. Knepley DMSetCoordinateDim - Set the dimension of the embedding space for coordinate values. 635646e270d4SMatthew G. Knepley 635746e270d4SMatthew G. Knepley Not Collective 635846e270d4SMatthew G. Knepley 635946e270d4SMatthew G. Knepley Input Parameters: 636046e270d4SMatthew G. Knepley + dm - The DM object 636146e270d4SMatthew G. Knepley - dim - The embedding dimension 636246e270d4SMatthew G. Knepley 636346e270d4SMatthew G. Knepley Level: intermediate 636446e270d4SMatthew G. Knepley 636592fd8e1eSJed Brown .seealso: DMGetCoordinateDim(), DMSetCoordinateSection(), DMGetCoordinateSection(), DMGetLocalSection(), DMSetLocalSection() 636646e270d4SMatthew G. Knepley @*/ 636746e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateDim(DM dm, PetscInt dim) 636846e270d4SMatthew G. Knepley { 6369e5e52638SMatthew G. Knepley PetscDS ds; 6370f17e8794SMatthew G. Knepley PetscErrorCode ierr; 6371f17e8794SMatthew G. Knepley 637246e270d4SMatthew G. Knepley PetscFunctionBegin; 637346e270d4SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 637446e270d4SMatthew G. Knepley dm->dimEmbed = dim; 6375e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 6376e5e52638SMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(ds, dim);CHKERRQ(ierr); 637746e270d4SMatthew G. Knepley PetscFunctionReturn(0); 637846e270d4SMatthew G. Knepley } 637946e270d4SMatthew G. Knepley 6380e8abe2deSMatthew G. Knepley /*@ 6381e8abe2deSMatthew G. Knepley DMGetCoordinateSection - Retrieve the layout of coordinate values over the mesh. 6382e8abe2deSMatthew G. Knepley 6383d083f849SBarry Smith Collective on dm 6384e8abe2deSMatthew G. Knepley 6385e8abe2deSMatthew G. Knepley Input Parameter: 6386e8abe2deSMatthew G. Knepley . dm - The DM object 6387e8abe2deSMatthew G. Knepley 6388e8abe2deSMatthew G. Knepley Output Parameter: 6389e8abe2deSMatthew G. Knepley . section - The PetscSection object 6390e8abe2deSMatthew G. Knepley 6391e8abe2deSMatthew G. Knepley Level: intermediate 6392e8abe2deSMatthew G. Knepley 639392fd8e1eSJed Brown .seealso: DMGetCoordinateDM(), DMGetLocalSection(), DMSetLocalSection() 6394e8abe2deSMatthew G. Knepley @*/ 6395e8abe2deSMatthew G. Knepley PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section) 6396e8abe2deSMatthew G. Knepley { 6397e8abe2deSMatthew G. Knepley DM cdm; 6398e8abe2deSMatthew G. Knepley PetscErrorCode ierr; 6399e8abe2deSMatthew G. Knepley 6400e8abe2deSMatthew G. Knepley PetscFunctionBegin; 6401e8abe2deSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6402e8abe2deSMatthew G. Knepley PetscValidPointer(section, 2); 6403e8abe2deSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 640492fd8e1eSJed Brown ierr = DMGetLocalSection(cdm, section);CHKERRQ(ierr); 6405e8abe2deSMatthew G. Knepley PetscFunctionReturn(0); 6406e8abe2deSMatthew G. Knepley } 6407e8abe2deSMatthew G. Knepley 6408e8abe2deSMatthew G. Knepley /*@ 6409e8abe2deSMatthew G. Knepley DMSetCoordinateSection - Set the layout of coordinate values over the mesh. 6410e8abe2deSMatthew G. Knepley 6411e8abe2deSMatthew G. Knepley Not Collective 6412e8abe2deSMatthew G. Knepley 6413e8abe2deSMatthew G. Knepley Input Parameters: 6414e8abe2deSMatthew G. Knepley + dm - The DM object 641546e270d4SMatthew G. Knepley . dim - The embedding dimension, or PETSC_DETERMINE 6416e8abe2deSMatthew G. Knepley - section - The PetscSection object 6417e8abe2deSMatthew G. Knepley 6418e8abe2deSMatthew G. Knepley Level: intermediate 6419e8abe2deSMatthew G. Knepley 642092fd8e1eSJed Brown .seealso: DMGetCoordinateSection(), DMGetLocalSection(), DMSetLocalSection() 6421e8abe2deSMatthew G. Knepley @*/ 642246e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateSection(DM dm, PetscInt dim, PetscSection section) 6423e8abe2deSMatthew G. Knepley { 6424e8abe2deSMatthew G. Knepley DM cdm; 6425e8abe2deSMatthew G. Knepley PetscErrorCode ierr; 6426e8abe2deSMatthew G. Knepley 6427e8abe2deSMatthew G. Knepley PetscFunctionBegin; 6428e8abe2deSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 642946e270d4SMatthew G. Knepley PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,3); 6430e8abe2deSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 643192fd8e1eSJed Brown ierr = DMSetLocalSection(cdm, section);CHKERRQ(ierr); 643246e270d4SMatthew G. Knepley if (dim == PETSC_DETERMINE) { 64334c1069a6SMatthew G. Knepley PetscInt d = PETSC_DEFAULT; 643446e270d4SMatthew G. Knepley PetscInt pStart, pEnd, vStart, vEnd, v, dd; 643546e270d4SMatthew G. Knepley 643646e270d4SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 643746e270d4SMatthew G. Knepley ierr = DMGetDimPoints(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 643846e270d4SMatthew G. Knepley pStart = PetscMax(vStart, pStart); 643946e270d4SMatthew G. Knepley pEnd = PetscMin(vEnd, pEnd); 644046e270d4SMatthew G. Knepley for (v = pStart; v < pEnd; ++v) { 644146e270d4SMatthew G. Knepley ierr = PetscSectionGetDof(section, v, &dd);CHKERRQ(ierr); 644246e270d4SMatthew G. Knepley if (dd) {d = dd; break;} 644346e270d4SMatthew G. Knepley } 6444ebfe4b0dSMatthew G. Knepley if (d >= 0) {ierr = DMSetCoordinateDim(dm, d);CHKERRQ(ierr);} 644546e270d4SMatthew G. Knepley } 6446e8abe2deSMatthew G. Knepley PetscFunctionReturn(0); 6447e8abe2deSMatthew G. Knepley } 6448e8abe2deSMatthew G. Knepley 6449d864a3eaSLisandro Dalcin /*@ 6450d864a3eaSLisandro Dalcin DMProjectCoordinates - Project coordinates to a different space 6451d864a3eaSLisandro Dalcin 6452d864a3eaSLisandro Dalcin Input Parameters: 6453d864a3eaSLisandro Dalcin + dm - The DM object 6454d864a3eaSLisandro Dalcin - disc - The new coordinate discretization 6455d864a3eaSLisandro Dalcin 6456d864a3eaSLisandro Dalcin Level: intermediate 6457d864a3eaSLisandro Dalcin 6458d864a3eaSLisandro Dalcin .seealso: DMGetCoordinateField() 6459d864a3eaSLisandro Dalcin @*/ 6460d864a3eaSLisandro Dalcin PetscErrorCode DMProjectCoordinates(DM dm, PetscFE disc) 6461d864a3eaSLisandro Dalcin { 6462d864a3eaSLisandro Dalcin PetscObject discOld; 6463d864a3eaSLisandro Dalcin PetscClassId classid; 6464d864a3eaSLisandro Dalcin DM cdmOld,cdmNew; 6465d864a3eaSLisandro Dalcin Vec coordsOld,coordsNew; 6466d864a3eaSLisandro Dalcin Mat matInterp; 6467d864a3eaSLisandro Dalcin PetscErrorCode ierr; 6468d864a3eaSLisandro Dalcin 6469d864a3eaSLisandro Dalcin PetscFunctionBegin; 6470d864a3eaSLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6471d864a3eaSLisandro Dalcin PetscValidHeaderSpecific(disc,PETSCFE_CLASSID,2); 6472d864a3eaSLisandro Dalcin 6473d864a3eaSLisandro Dalcin ierr = DMGetCoordinateDM(dm, &cdmOld);CHKERRQ(ierr); 6474d864a3eaSLisandro Dalcin /* Check current discretization is compatible */ 6475d864a3eaSLisandro Dalcin ierr = DMGetField(cdmOld, 0, NULL, &discOld);CHKERRQ(ierr); 6476d864a3eaSLisandro Dalcin ierr = PetscObjectGetClassId(discOld, &classid);CHKERRQ(ierr); 647729ad44c5SMatthew G. Knepley if (classid != PETSCFE_CLASSID) { 647829ad44c5SMatthew G. Knepley if (classid == PETSC_CONTAINER_CLASSID) { 647929ad44c5SMatthew G. Knepley PetscFE feLinear; 648029ad44c5SMatthew G. Knepley DMPolytopeType ct; 648129ad44c5SMatthew G. Knepley PetscInt dim, dE, cStart; 648229ad44c5SMatthew G. Knepley PetscBool simplex; 648329ad44c5SMatthew G. Knepley 648429ad44c5SMatthew G. Knepley /* Assume linear vertex coordinates */ 648529ad44c5SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 648629ad44c5SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 648729ad44c5SMatthew G. Knepley ierr = DMPlexGetHeightStratum(cdmOld, 0, &cStart, NULL);CHKERRQ(ierr); 648829ad44c5SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 648929ad44c5SMatthew G. Knepley switch (ct) { 649029ad44c5SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 649129ad44c5SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 649229ad44c5SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot autoamtically create coordinate space for prisms"); 649329ad44c5SMatthew G. Knepley default: break; 649429ad44c5SMatthew G. Knepley } 649529ad44c5SMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 649629ad44c5SMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, dE, simplex, 1, -1, &feLinear);CHKERRQ(ierr); 649729ad44c5SMatthew G. Knepley ierr = DMSetField(cdmOld, 0, NULL, (PetscObject) feLinear);CHKERRQ(ierr); 649829ad44c5SMatthew G. Knepley ierr = PetscFEDestroy(&feLinear);CHKERRQ(ierr); 649929ad44c5SMatthew G. Knepley ierr = DMCreateDS(cdmOld);CHKERRQ(ierr); 650029ad44c5SMatthew G. Knepley } else { 650129ad44c5SMatthew G. Knepley const char *discname; 650229ad44c5SMatthew G. Knepley 650329ad44c5SMatthew G. Knepley ierr = PetscObjectGetType(discOld, &discname);CHKERRQ(ierr); 650429ad44c5SMatthew G. Knepley SETERRQ1(PetscObjectComm(discOld), PETSC_ERR_SUP, "Discretization type %s not supported", discname); 650529ad44c5SMatthew G. Knepley } 650629ad44c5SMatthew G. Knepley } 6507d864a3eaSLisandro Dalcin /* Make a fresh clone of the coordinate DM */ 6508d864a3eaSLisandro Dalcin ierr = DMClone(cdmOld, &cdmNew);CHKERRQ(ierr); 6509d864a3eaSLisandro Dalcin ierr = DMSetField(cdmNew, 0, NULL, (PetscObject) disc);CHKERRQ(ierr); 6510d864a3eaSLisandro Dalcin ierr = DMCreateDS(cdmNew);CHKERRQ(ierr); 6511d864a3eaSLisandro Dalcin /* Project the coordinate vector from old to new space */ 6512d864a3eaSLisandro Dalcin ierr = DMGetCoordinates(dm, &coordsOld);CHKERRQ(ierr); 6513d864a3eaSLisandro Dalcin ierr = DMCreateGlobalVector(cdmNew, &coordsNew);CHKERRQ(ierr); 6514d864a3eaSLisandro Dalcin ierr = DMCreateInterpolation(cdmOld, cdmNew, &matInterp, NULL);CHKERRQ(ierr); 6515d864a3eaSLisandro Dalcin ierr = MatInterpolate(matInterp, coordsOld, coordsNew);CHKERRQ(ierr); 6516d864a3eaSLisandro Dalcin ierr = MatDestroy(&matInterp);CHKERRQ(ierr); 6517d864a3eaSLisandro Dalcin /* Set new coordinate structures */ 6518d864a3eaSLisandro Dalcin ierr = DMSetCoordinateField(dm, NULL);CHKERRQ(ierr); 6519d864a3eaSLisandro Dalcin ierr = DMSetCoordinateDM(dm, cdmNew);CHKERRQ(ierr); 6520d864a3eaSLisandro Dalcin ierr = DMSetCoordinates(dm, coordsNew);CHKERRQ(ierr); 6521d864a3eaSLisandro Dalcin ierr = VecDestroy(&coordsNew);CHKERRQ(ierr); 6522d864a3eaSLisandro Dalcin ierr = DMDestroy(&cdmNew);CHKERRQ(ierr); 6523d864a3eaSLisandro Dalcin PetscFunctionReturn(0); 6524d864a3eaSLisandro Dalcin } 6525d864a3eaSLisandro Dalcin 65265dc8c3f7SMatthew G. Knepley /*@C 652790b157c4SStefano Zampini DMGetPeriodicity - Get the description of mesh periodicity 65285dc8c3f7SMatthew G. Knepley 65295dc8c3f7SMatthew G. Knepley Input Parameters: 653090b157c4SStefano Zampini . dm - The DM object 653190b157c4SStefano Zampini 653290b157c4SStefano Zampini Output Parameters: 653390b157c4SStefano Zampini + per - Whether the DM is periodic or not 65345dc8c3f7SMatthew 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 65355dc8c3f7SMatthew G. Knepley . L - If we assume the mesh is a torus, this is the length of each coordinate 65365dc8c3f7SMatthew G. Knepley - bd - This describes the type of periodicity in each topological dimension 65375dc8c3f7SMatthew G. Knepley 65385dc8c3f7SMatthew G. Knepley Level: developer 65395dc8c3f7SMatthew G. Knepley 65405dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity() 65415dc8c3f7SMatthew G. Knepley @*/ 654290b157c4SStefano Zampini PetscErrorCode DMGetPeriodicity(DM dm, PetscBool *per, const PetscReal **maxCell, const PetscReal **L, const DMBoundaryType **bd) 6543c6b900c6SMatthew G. Knepley { 6544c6b900c6SMatthew G. Knepley PetscFunctionBegin; 6545c6b900c6SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 654690b157c4SStefano Zampini if (per) *per = dm->periodic; 6547c6b900c6SMatthew G. Knepley if (L) *L = dm->L; 6548c6b900c6SMatthew G. Knepley if (maxCell) *maxCell = dm->maxCell; 65495dc8c3f7SMatthew G. Knepley if (bd) *bd = dm->bdtype; 6550c6b900c6SMatthew G. Knepley PetscFunctionReturn(0); 6551c6b900c6SMatthew G. Knepley } 6552c6b900c6SMatthew G. Knepley 65535dc8c3f7SMatthew G. Knepley /*@C 65545dc8c3f7SMatthew G. Knepley DMSetPeriodicity - Set the description of mesh periodicity 65555dc8c3f7SMatthew G. Knepley 65565dc8c3f7SMatthew G. Knepley Input Parameters: 65575dc8c3f7SMatthew G. Knepley + dm - The DM object 6558db2bf62eSStefano Zampini . per - Whether the DM is periodic or not. 6559db2bf62eSStefano Zampini . maxCell - Over distances greater than this, we can assume a point has crossed over to another sheet, when trying to localize cell coordinates. Pass NULL to remove such information. 65605dc8c3f7SMatthew G. Knepley . L - If we assume the mesh is a torus, this is the length of each coordinate 65615dc8c3f7SMatthew G. Knepley - bd - This describes the type of periodicity in each topological dimension 65625dc8c3f7SMatthew G. Knepley 6563db2bf62eSStefano Zampini Notes: If per is PETSC_TRUE and maxCell is not provided, coordinates need to be already localized, or must be localized by hand by the user. 6564db2bf62eSStefano Zampini 65655dc8c3f7SMatthew G. Knepley Level: developer 65665dc8c3f7SMatthew G. Knepley 65675dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity() 65685dc8c3f7SMatthew G. Knepley @*/ 656990b157c4SStefano Zampini PetscErrorCode DMSetPeriodicity(DM dm, PetscBool per, const PetscReal maxCell[], const PetscReal L[], const DMBoundaryType bd[]) 6570c6b900c6SMatthew G. Knepley { 6571c6b900c6SMatthew G. Knepley PetscInt dim, d; 6572c6b900c6SMatthew G. Knepley PetscErrorCode ierr; 6573c6b900c6SMatthew G. Knepley 6574c6b900c6SMatthew G. Knepley PetscFunctionBegin; 6575c6b900c6SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 657690b157c4SStefano Zampini PetscValidLogicalCollectiveBool(dm,per,2); 6577412e9a14SMatthew G. Knepley if (maxCell) {PetscValidRealPointer(maxCell,3);} 6578412e9a14SMatthew G. Knepley if (L) {PetscValidRealPointer(L,4);} 6579412e9a14SMatthew G. Knepley if (bd) {PetscValidPointer(bd,5);} 65805dc8c3f7SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 658190b157c4SStefano Zampini if (maxCell) { 6582412e9a14SMatthew G. Knepley if (!dm->maxCell) {ierr = PetscMalloc1(dim, &dm->maxCell);CHKERRQ(ierr);} 6583412e9a14SMatthew G. Knepley for (d = 0; d < dim; ++d) dm->maxCell[d] = maxCell[d]; 6584db2bf62eSStefano Zampini } else { /* remove maxCell information to disable automatic computation of localized vertices */ 6585db2bf62eSStefano Zampini ierr = PetscFree(dm->maxCell);CHKERRQ(ierr); 6586412e9a14SMatthew G. Knepley } 6587db2bf62eSStefano Zampini 6588412e9a14SMatthew G. Knepley if (L) { 6589412e9a14SMatthew G. Knepley if (!dm->L) {ierr = PetscMalloc1(dim, &dm->L);CHKERRQ(ierr);} 6590412e9a14SMatthew G. Knepley for (d = 0; d < dim; ++d) dm->L[d] = L[d]; 6591412e9a14SMatthew G. Knepley } 6592412e9a14SMatthew G. Knepley if (bd) { 6593412e9a14SMatthew G. Knepley if (!dm->bdtype) {ierr = PetscMalloc1(dim, &dm->bdtype);CHKERRQ(ierr);} 6594412e9a14SMatthew G. Knepley for (d = 0; d < dim; ++d) dm->bdtype[d] = bd[d]; 659590b157c4SStefano Zampini } 6596072d7d67SStefano Zampini dm->periodic = per; 6597c6b900c6SMatthew G. Knepley PetscFunctionReturn(0); 6598c6b900c6SMatthew G. Knepley } 6599c6b900c6SMatthew G. Knepley 66002e17dfb7SMatthew G. Knepley /*@ 66012e17dfb7SMatthew 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. 66022e17dfb7SMatthew G. Knepley 66032e17dfb7SMatthew G. Knepley Input Parameters: 66042e17dfb7SMatthew G. Knepley + dm - The DM 660565da65dcSMatthew G. Knepley . in - The input coordinate point (dim numbers) 660665da65dcSMatthew G. Knepley - endpoint - Include the endpoint L_i 66072e17dfb7SMatthew G. Knepley 66082e17dfb7SMatthew G. Knepley Output Parameter: 66092e17dfb7SMatthew G. Knepley . out - The localized coordinate point 66102e17dfb7SMatthew G. Knepley 66112e17dfb7SMatthew G. Knepley Level: developer 66122e17dfb7SMatthew G. Knepley 66132e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate() 66142e17dfb7SMatthew G. Knepley @*/ 661565da65dcSMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate(DM dm, const PetscScalar in[], PetscBool endpoint, PetscScalar out[]) 66162e17dfb7SMatthew G. Knepley { 66172e17dfb7SMatthew G. Knepley PetscInt dim, d; 66182e17dfb7SMatthew G. Knepley PetscErrorCode ierr; 66192e17dfb7SMatthew G. Knepley 66202e17dfb7SMatthew G. Knepley PetscFunctionBegin; 66212e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 66222e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 66232e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 66242e17dfb7SMatthew G. Knepley } else { 662565da65dcSMatthew G. Knepley if (endpoint) { 662665da65dcSMatthew G. Knepley for (d = 0; d < dim; ++d) { 6627da3333bfSMatthew 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)) { 6628da3333bfSMatthew G. Knepley out[d] = in[d] - dm->L[d]*(PetscFloorReal(PetscRealPart(in[d])/dm->L[d]) - 1); 662965da65dcSMatthew G. Knepley } else { 6630da3333bfSMatthew G. Knepley out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]); 663165da65dcSMatthew G. Knepley } 663265da65dcSMatthew G. Knepley } 663365da65dcSMatthew G. Knepley } else { 66342e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 66351118d4bcSLisandro Dalcin out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]); 66362e17dfb7SMatthew G. Knepley } 66372e17dfb7SMatthew G. Knepley } 663865da65dcSMatthew G. Knepley } 66392e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 66402e17dfb7SMatthew G. Knepley } 66412e17dfb7SMatthew G. Knepley 66422e17dfb7SMatthew G. Knepley /* 66432e17dfb7SMatthew 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. 66442e17dfb7SMatthew G. Knepley 66452e17dfb7SMatthew G. Knepley Input Parameters: 66462e17dfb7SMatthew G. Knepley + dm - The DM 66472e17dfb7SMatthew G. Knepley . dim - The spatial dimension 66482e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it 66492e17dfb7SMatthew G. Knepley - in - The input coordinate point (dim numbers) 66502e17dfb7SMatthew G. Knepley 66512e17dfb7SMatthew G. Knepley Output Parameter: 66522e17dfb7SMatthew G. Knepley . out - The localized coordinate point 66532e17dfb7SMatthew G. Knepley 66542e17dfb7SMatthew G. Knepley Level: developer 66552e17dfb7SMatthew G. Knepley 66562e17dfb7SMatthew 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 66572e17dfb7SMatthew G. Knepley 66582e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate() 66592e17dfb7SMatthew G. Knepley */ 66602e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[]) 66612e17dfb7SMatthew G. Knepley { 66622e17dfb7SMatthew G. Knepley PetscInt d; 66632e17dfb7SMatthew G. Knepley 66642e17dfb7SMatthew G. Knepley PetscFunctionBegin; 66652e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 66662e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 66672e17dfb7SMatthew G. Knepley } else { 66682e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 6669908eca10SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) { 66702e17dfb7SMatthew G. Knepley out[d] = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d]; 66712e17dfb7SMatthew G. Knepley } else { 66722e17dfb7SMatthew G. Knepley out[d] = in[d]; 66732e17dfb7SMatthew G. Knepley } 66742e17dfb7SMatthew G. Knepley } 66752e17dfb7SMatthew G. Knepley } 66762e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 66772e17dfb7SMatthew G. Knepley } 6678a5801f52SStefano Zampini 66792e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinateReal_Internal(DM dm, PetscInt dim, const PetscReal anchor[], const PetscReal in[], PetscReal out[]) 66802e17dfb7SMatthew G. Knepley { 66812e17dfb7SMatthew G. Knepley PetscInt d; 66822e17dfb7SMatthew G. Knepley 66832e17dfb7SMatthew G. Knepley PetscFunctionBegin; 66842e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 66852e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 66862e17dfb7SMatthew G. Knepley } else { 66872e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 6688908eca10SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsReal(anchor[d] - in[d]) > dm->maxCell[d])) { 66892e17dfb7SMatthew G. Knepley out[d] = anchor[d] > in[d] ? dm->L[d] + in[d] : in[d] - dm->L[d]; 66902e17dfb7SMatthew G. Knepley } else { 66912e17dfb7SMatthew G. Knepley out[d] = in[d]; 66922e17dfb7SMatthew G. Knepley } 66932e17dfb7SMatthew G. Knepley } 66942e17dfb7SMatthew G. Knepley } 66952e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 66962e17dfb7SMatthew G. Knepley } 66972e17dfb7SMatthew G. Knepley 66982e17dfb7SMatthew G. Knepley /* 66992e17dfb7SMatthew 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. 67002e17dfb7SMatthew G. Knepley 67012e17dfb7SMatthew G. Knepley Input Parameters: 67022e17dfb7SMatthew G. Knepley + dm - The DM 67032e17dfb7SMatthew G. Knepley . dim - The spatial dimension 67042e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it 67052e17dfb7SMatthew G. Knepley . in - The input coordinate delta (dim numbers) 67062e17dfb7SMatthew G. Knepley - out - The input coordinate point (dim numbers) 67072e17dfb7SMatthew G. Knepley 67082e17dfb7SMatthew G. Knepley Output Parameter: 67092e17dfb7SMatthew G. Knepley . out - The localized coordinate in + out 67102e17dfb7SMatthew G. Knepley 67112e17dfb7SMatthew G. Knepley Level: developer 67122e17dfb7SMatthew G. Knepley 67132e17dfb7SMatthew 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 67142e17dfb7SMatthew G. Knepley 67152e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeCoordinate() 67162e17dfb7SMatthew G. Knepley */ 67172e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeAddCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[]) 67182e17dfb7SMatthew G. Knepley { 67192e17dfb7SMatthew G. Knepley PetscInt d; 67202e17dfb7SMatthew G. Knepley 67212e17dfb7SMatthew G. Knepley PetscFunctionBegin; 67222e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 67232e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] += in[d]; 67242e17dfb7SMatthew G. Knepley } else { 67252e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 6726412e9a14SMatthew G. Knepley const PetscReal maxC = dm->maxCell[d]; 6727412e9a14SMatthew G. Knepley 6728412e9a14SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > maxC)) { 6729412e9a14SMatthew G. Knepley const PetscScalar newCoord = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d]; 6730412e9a14SMatthew G. Knepley 6731412e9a14SMatthew G. Knepley if (PetscAbsScalar(newCoord - anchor[d]) > maxC) 6732412e9a14SMatthew G. Knepley SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "%D-Coordinate %g more than %g away from anchor %g", d, (double) PetscRealPart(in[d]), (double) maxC, (double) PetscRealPart(anchor[d])); 6733412e9a14SMatthew G. Knepley out[d] += newCoord; 67342e17dfb7SMatthew G. Knepley } else { 67352e17dfb7SMatthew G. Knepley out[d] += in[d]; 67362e17dfb7SMatthew G. Knepley } 67372e17dfb7SMatthew G. Knepley } 67382e17dfb7SMatthew G. Knepley } 67392e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 67402e17dfb7SMatthew G. Knepley } 67412e17dfb7SMatthew G. Knepley 674236447a5eSToby Isaac /*@ 67438f700142SStefano Zampini DMGetCoordinatesLocalizedLocal - Check if the DM coordinates have been localized for cells on this process 67448f700142SStefano Zampini 67458f700142SStefano Zampini Not collective 674636447a5eSToby Isaac 674736447a5eSToby Isaac Input Parameter: 674836447a5eSToby Isaac . dm - The DM 674936447a5eSToby Isaac 675036447a5eSToby Isaac Output Parameter: 675136447a5eSToby Isaac areLocalized - True if localized 675236447a5eSToby Isaac 675336447a5eSToby Isaac Level: developer 675436447a5eSToby Isaac 67558f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMGetCoordinatesLocalized(), DMSetPeriodicity() 675636447a5eSToby Isaac @*/ 67578f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalizedLocal(DM dm,PetscBool *areLocalized) 675836447a5eSToby Isaac { 675936447a5eSToby Isaac DM cdm; 676036447a5eSToby Isaac PetscSection coordSection; 676146a3a80fSLisandro Dalcin PetscInt cStart, cEnd, sStart, sEnd, c, dof; 676246a3a80fSLisandro Dalcin PetscBool isPlex, alreadyLocalized; 676336447a5eSToby Isaac PetscErrorCode ierr; 676436447a5eSToby Isaac 676536447a5eSToby Isaac PetscFunctionBegin; 676636447a5eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6767534a8f05SLisandro Dalcin PetscValidBoolPointer(areLocalized, 2); 67688b09590cSToby Isaac *areLocalized = PETSC_FALSE; 676946a3a80fSLisandro Dalcin 677036447a5eSToby Isaac /* We need some generic way of refering to cells/vertices */ 677136447a5eSToby Isaac ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 677246a3a80fSLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isPlex);CHKERRQ(ierr); 67739f7230bfSMatthew G. Knepley if (!isPlex) PetscFunctionReturn(0); 677446a3a80fSLisandro Dalcin 67759f7230bfSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 677646a3a80fSLisandro Dalcin ierr = DMPlexGetHeightStratum(cdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 677736447a5eSToby Isaac ierr = PetscSectionGetChart(coordSection, &sStart, &sEnd);CHKERRQ(ierr); 677836447a5eSToby Isaac alreadyLocalized = PETSC_FALSE; 677946a3a80fSLisandro Dalcin for (c = cStart; c < cEnd; ++c) { 678046a3a80fSLisandro Dalcin if (c < sStart || c >= sEnd) continue; 678136447a5eSToby Isaac ierr = PetscSectionGetDof(coordSection, c, &dof);CHKERRQ(ierr); 678246a3a80fSLisandro Dalcin if (dof) { alreadyLocalized = PETSC_TRUE; break; } 678336447a5eSToby Isaac } 67848f700142SStefano Zampini *areLocalized = alreadyLocalized; 678536447a5eSToby Isaac PetscFunctionReturn(0); 678636447a5eSToby Isaac } 678736447a5eSToby Isaac 67888f700142SStefano Zampini /*@ 67898f700142SStefano Zampini DMGetCoordinatesLocalized - Check if the DM coordinates have been localized for cells 67908f700142SStefano Zampini 67918f700142SStefano Zampini Collective on dm 67928f700142SStefano Zampini 67938f700142SStefano Zampini Input Parameter: 67948f700142SStefano Zampini . dm - The DM 67958f700142SStefano Zampini 67968f700142SStefano Zampini Output Parameter: 67978f700142SStefano Zampini areLocalized - True if localized 67988f700142SStefano Zampini 67998f700142SStefano Zampini Level: developer 68008f700142SStefano Zampini 68018f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMSetPeriodicity(), DMGetCoordinatesLocalizedLocal() 68028f700142SStefano Zampini @*/ 68038f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalized(DM dm,PetscBool *areLocalized) 68048f700142SStefano Zampini { 68058f700142SStefano Zampini PetscBool localized; 68068f700142SStefano Zampini PetscErrorCode ierr; 68078f700142SStefano Zampini 68088f700142SStefano Zampini PetscFunctionBegin; 68098f700142SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6810534a8f05SLisandro Dalcin PetscValidBoolPointer(areLocalized, 2); 68118f700142SStefano Zampini ierr = DMGetCoordinatesLocalizedLocal(dm,&localized);CHKERRQ(ierr); 68128f700142SStefano Zampini ierr = MPIU_Allreduce(&localized,areLocalized,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 68138f700142SStefano Zampini PetscFunctionReturn(0); 68148f700142SStefano Zampini } 681536447a5eSToby Isaac 68162e17dfb7SMatthew G. Knepley /*@ 6817492b8470SStefano Zampini DMLocalizeCoordinates - If a mesh is periodic, create local coordinates for cells having periodic faces 68182e17dfb7SMatthew G. Knepley 68198f700142SStefano Zampini Collective on dm 68208f700142SStefano Zampini 68212e17dfb7SMatthew G. Knepley Input Parameter: 68222e17dfb7SMatthew G. Knepley . dm - The DM 68232e17dfb7SMatthew G. Knepley 68242e17dfb7SMatthew G. Knepley Level: developer 68252e17dfb7SMatthew G. Knepley 68268f700142SStefano Zampini .seealso: DMSetPeriodicity(), DMLocalizeCoordinate(), DMLocalizeAddCoordinate() 68272e17dfb7SMatthew G. Knepley @*/ 68282e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinates(DM dm) 68292e17dfb7SMatthew G. Knepley { 68302e17dfb7SMatthew G. Knepley DM cdm; 68312e17dfb7SMatthew G. Knepley PetscSection coordSection, cSection; 68322e17dfb7SMatthew G. Knepley Vec coordinates, cVec; 68333e922f36SToby Isaac PetscScalar *coords, *coords2, *anchor, *localized; 68343e922f36SToby Isaac PetscInt Nc, vStart, vEnd, v, sStart, sEnd, newStart = PETSC_MAX_INT, newEnd = PETSC_MIN_INT, dof, d, off, off2, bs, coordSize; 6835e0ae35bbSToby Isaac PetscBool alreadyLocalized, alreadyLocalizedGlobal; 68363e922f36SToby Isaac PetscInt maxHeight = 0, h; 68373e922f36SToby Isaac PetscInt *pStart = NULL, *pEnd = NULL; 68382e17dfb7SMatthew G. Knepley PetscErrorCode ierr; 68392e17dfb7SMatthew G. Knepley 68402e17dfb7SMatthew G. Knepley PetscFunctionBegin; 68412e17dfb7SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 684292c9c85fSStefano Zampini if (!dm->periodic) PetscFunctionReturn(0); 6843f7cbd40bSStefano Zampini ierr = DMGetCoordinatesLocalized(dm, &alreadyLocalized);CHKERRQ(ierr); 6844f7cbd40bSStefano Zampini if (alreadyLocalized) PetscFunctionReturn(0); 6845f7cbd40bSStefano Zampini 68462e17dfb7SMatthew G. Knepley /* We need some generic way of refering to cells/vertices */ 68472e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 68482e17dfb7SMatthew G. Knepley { 68492e17dfb7SMatthew G. Knepley PetscBool isplex; 68502e17dfb7SMatthew G. Knepley 68512e17dfb7SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isplex);CHKERRQ(ierr); 68522e17dfb7SMatthew G. Knepley if (isplex) { 68532e17dfb7SMatthew G. Knepley ierr = DMPlexGetDepthStratum(cdm, 0, &vStart, &vEnd);CHKERRQ(ierr); 68543e922f36SToby Isaac ierr = DMPlexGetMaxProjectionHeight(cdm,&maxHeight);CHKERRQ(ierr); 685569291d52SBarry Smith ierr = DMGetWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 68563e922f36SToby Isaac pEnd = &pStart[maxHeight + 1]; 68573e922f36SToby Isaac newStart = vStart; 68583e922f36SToby Isaac newEnd = vEnd; 68593e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 68603e922f36SToby Isaac ierr = DMPlexGetHeightStratum(cdm, h, &pStart[h], &pEnd[h]);CHKERRQ(ierr); 68613e922f36SToby Isaac newStart = PetscMin(newStart,pStart[h]); 68623e922f36SToby Isaac newEnd = PetscMax(newEnd,pEnd[h]); 68633e922f36SToby Isaac } 68642e17dfb7SMatthew G. Knepley } else SETERRQ(PetscObjectComm((PetscObject) cdm), PETSC_ERR_ARG_WRONG, "Coordinate localization requires a DMPLEX coordinate DM"); 68652e17dfb7SMatthew G. Knepley } 68662e17dfb7SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 686743eeeb2dSStefano Zampini if (!coordinates) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Missing local coordinates vector"); 68682e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 68693e922f36SToby Isaac ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 6870e0ae35bbSToby Isaac ierr = PetscSectionGetChart(coordSection,&sStart,&sEnd);CHKERRQ(ierr); 68713e922f36SToby Isaac 68722e17dfb7SMatthew G. Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &cSection);CHKERRQ(ierr); 68732e17dfb7SMatthew G. Knepley ierr = PetscSectionSetNumFields(cSection, 1);CHKERRQ(ierr); 68742e17dfb7SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(coordSection, 0, &Nc);CHKERRQ(ierr); 68752e17dfb7SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(cSection, 0, Nc);CHKERRQ(ierr); 68763e922f36SToby Isaac ierr = PetscSectionSetChart(cSection, newStart, newEnd);CHKERRQ(ierr); 68773e922f36SToby Isaac 687869291d52SBarry Smith ierr = DMGetWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 68793e922f36SToby Isaac localized = &anchor[bs]; 68803e922f36SToby Isaac alreadyLocalized = alreadyLocalizedGlobal = PETSC_TRUE; 68813e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 68823e922f36SToby Isaac PetscInt cStart = pStart[h], cEnd = pEnd[h], c; 68833e922f36SToby Isaac 68843e922f36SToby Isaac for (c = cStart; c < cEnd; ++c) { 68853e922f36SToby Isaac PetscScalar *cellCoords = NULL; 68863e922f36SToby Isaac PetscInt b; 68873e922f36SToby Isaac 68883e922f36SToby Isaac if (c < sStart || c >= sEnd) alreadyLocalized = PETSC_FALSE; 68893e922f36SToby Isaac ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 68903e922f36SToby Isaac for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b]; 68913e922f36SToby Isaac for (d = 0; d < dof/bs; ++d) { 68923e922f36SToby Isaac ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], localized);CHKERRQ(ierr); 68933e922f36SToby Isaac for (b = 0; b < bs; b++) { 68943e922f36SToby Isaac if (cellCoords[d*bs + b] != localized[b]) break; 68953e922f36SToby Isaac } 68963e922f36SToby Isaac if (b < bs) break; 68973e922f36SToby Isaac } 68983e922f36SToby Isaac if (d < dof/bs) { 68993e922f36SToby Isaac if (c >= sStart && c < sEnd) { 69003e922f36SToby Isaac PetscInt cdof; 69013e922f36SToby Isaac 69023e922f36SToby Isaac ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 69033e922f36SToby Isaac if (cdof != dof) alreadyLocalized = PETSC_FALSE; 69043e922f36SToby Isaac } 69053e922f36SToby Isaac ierr = PetscSectionSetDof(cSection, c, dof);CHKERRQ(ierr); 69063e922f36SToby Isaac ierr = PetscSectionSetFieldDof(cSection, c, 0, dof);CHKERRQ(ierr); 69073e922f36SToby Isaac } 69083e922f36SToby Isaac ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 69093e922f36SToby Isaac } 69103e922f36SToby Isaac } 6911ffc4695bSBarry Smith ierr = MPI_Allreduce(&alreadyLocalized,&alreadyLocalizedGlobal,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 69123e922f36SToby Isaac if (alreadyLocalizedGlobal) { 691369291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 69143e922f36SToby Isaac ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr); 691569291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 69163e922f36SToby Isaac PetscFunctionReturn(0); 69173e922f36SToby Isaac } 69182e17dfb7SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 69192e17dfb7SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 69202e17dfb7SMatthew G. Knepley ierr = PetscSectionSetDof(cSection, v, dof);CHKERRQ(ierr); 69212e17dfb7SMatthew G. Knepley ierr = PetscSectionSetFieldDof(cSection, v, 0, dof);CHKERRQ(ierr); 69222e17dfb7SMatthew G. Knepley } 69232e17dfb7SMatthew G. Knepley ierr = PetscSectionSetUp(cSection);CHKERRQ(ierr); 69242e17dfb7SMatthew G. Knepley ierr = PetscSectionGetStorageSize(cSection, &coordSize);CHKERRQ(ierr); 6925c2be7e5eSLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &cVec);CHKERRQ(ierr); 69262e17dfb7SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject)cVec,"coordinates");CHKERRQ(ierr); 69272e17dfb7SMatthew G. Knepley ierr = VecSetBlockSize(cVec, bs);CHKERRQ(ierr); 69282e17dfb7SMatthew G. Knepley ierr = VecSetSizes(cVec, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 69292e17dfb7SMatthew G. Knepley ierr = VecSetType(cVec, VECSTANDARD);CHKERRQ(ierr); 6930c2be7e5eSLisandro Dalcin ierr = VecGetArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr); 69312e17dfb7SMatthew G. Knepley ierr = VecGetArray(cVec, &coords2);CHKERRQ(ierr); 69322e17dfb7SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 69332e17dfb7SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 69342e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 69352e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(cSection, v, &off2);CHKERRQ(ierr); 69362e17dfb7SMatthew G. Knepley for (d = 0; d < dof; ++d) coords2[off2+d] = coords[off+d]; 69372e17dfb7SMatthew G. Knepley } 69383e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 69393e922f36SToby Isaac PetscInt cStart = pStart[h], cEnd = pEnd[h], c; 69403e922f36SToby Isaac 69412e17dfb7SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 69422e17dfb7SMatthew G. Knepley PetscScalar *cellCoords = NULL; 69433e922f36SToby Isaac PetscInt b, cdof; 69442e17dfb7SMatthew G. Knepley 69453e922f36SToby Isaac ierr = PetscSectionGetDof(cSection,c,&cdof);CHKERRQ(ierr); 69463e922f36SToby Isaac if (!cdof) continue; 69472e17dfb7SMatthew G. Knepley ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 69482e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(cSection, c, &off2);CHKERRQ(ierr); 69492e17dfb7SMatthew G. Knepley for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b]; 69502e17dfb7SMatthew G. Knepley for (d = 0; d < dof/bs; ++d) {ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], &coords2[off2+d*bs]);CHKERRQ(ierr);} 69512e17dfb7SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 69522e17dfb7SMatthew G. Knepley } 69533e922f36SToby Isaac } 695469291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 695569291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 6956c2be7e5eSLisandro Dalcin ierr = VecRestoreArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr); 69572e17dfb7SMatthew G. Knepley ierr = VecRestoreArray(cVec, &coords2);CHKERRQ(ierr); 69582e17dfb7SMatthew G. Knepley ierr = DMSetCoordinateSection(dm, PETSC_DETERMINE, cSection);CHKERRQ(ierr); 69592e17dfb7SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, cVec);CHKERRQ(ierr); 69602e17dfb7SMatthew G. Knepley ierr = VecDestroy(&cVec);CHKERRQ(ierr); 69612e17dfb7SMatthew G. Knepley ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr); 69622e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 69632e17dfb7SMatthew G. Knepley } 69642e17dfb7SMatthew G. Knepley 6965e87bb0d3SMatthew G Knepley /*@ 69663a93e3b7SToby Isaac DMLocatePoints - Locate the points in v in the mesh and return a PetscSF of the containing cells 6967e87bb0d3SMatthew G Knepley 6968d083f849SBarry Smith Collective on v (see explanation below) 6969e87bb0d3SMatthew G Knepley 6970e87bb0d3SMatthew G Knepley Input Parameters: 6971e87bb0d3SMatthew G Knepley + dm - The DM 69723a93e3b7SToby Isaac . v - The Vec of points 697362a38674SMatthew G. Knepley . ltype - The type of point location, e.g. DM_POINTLOCATION_NONE or DM_POINTLOCATION_NEAREST 69743a93e3b7SToby Isaac - cells - Points to either NULL, or a PetscSF with guesses for which cells contain each point. 6975e87bb0d3SMatthew G Knepley 697661e3bb9bSMatthew G Knepley Output Parameter: 697762a38674SMatthew G. Knepley + v - The Vec of points, which now contains the nearest mesh points to the given points if DM_POINTLOCATION_NEAREST is used 697862a38674SMatthew G. Knepley - cells - The PetscSF containing the ranks and local indices of the containing points. 69793a93e3b7SToby Isaac 6980e87bb0d3SMatthew G Knepley 6981e87bb0d3SMatthew G Knepley Level: developer 698261e3bb9bSMatthew G Knepley 698362a38674SMatthew G. Knepley Notes: 69843a93e3b7SToby Isaac To do a search of the local cells of the mesh, v should have PETSC_COMM_SELF as its communicator. 698562a38674SMatthew G. Knepley To do a search of all the cells in the distributed mesh, v should have the same communicator as dm. 69863a93e3b7SToby Isaac 69873a93e3b7SToby Isaac If *cellSF is NULL on input, a PetscSF will be created. 698862a38674SMatthew G. Knepley If *cellSF is not NULL on input, it should point to an existing PetscSF, whose graph will be used as initial guesses. 69893a93e3b7SToby Isaac 69903a93e3b7SToby Isaac An array that maps each point to its containing cell can be obtained with 69913a93e3b7SToby Isaac 699262a38674SMatthew G. Knepley $ const PetscSFNode *cells; 699362a38674SMatthew G. Knepley $ PetscInt nFound; 6994a6216909SToby Isaac $ const PetscInt *found; 699562a38674SMatthew G. Knepley $ 6996a6216909SToby Isaac $ PetscSFGetGraph(cellSF,NULL,&nFound,&found,&cells); 69973a93e3b7SToby Isaac 69983a93e3b7SToby 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 69993a93e3b7SToby Isaac the index of the cell in its rank's local numbering. 70003a93e3b7SToby Isaac 700162a38674SMatthew G. Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMPointLocationType 700261e3bb9bSMatthew G Knepley @*/ 700362a38674SMatthew G. Knepley PetscErrorCode DMLocatePoints(DM dm, Vec v, DMPointLocationType ltype, PetscSF *cellSF) 7004e87bb0d3SMatthew G Knepley { 7005735aa83eSMatthew G Knepley PetscErrorCode ierr; 7006735aa83eSMatthew G Knepley 7007e87bb0d3SMatthew G Knepley PetscFunctionBegin; 7008e87bb0d3SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7009e87bb0d3SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,2); 7010e0fc9d1bSMatthew G. Knepley PetscValidPointer(cellSF,4); 70113a93e3b7SToby Isaac if (*cellSF) { 70123a93e3b7SToby Isaac PetscMPIInt result; 70133a93e3b7SToby Isaac 7014e0fc9d1bSMatthew G. Knepley PetscValidHeaderSpecific(*cellSF,PETSCSF_CLASSID,4); 7015ffc4695bSBarry Smith ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)v),PetscObjectComm((PetscObject)*cellSF),&result);CHKERRMPI(ierr); 70163a93e3b7SToby 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"); 7017e0fc9d1bSMatthew G. Knepley } else { 70183a93e3b7SToby Isaac ierr = PetscSFCreate(PetscObjectComm((PetscObject)v),cellSF);CHKERRQ(ierr); 70193a93e3b7SToby Isaac } 7020b9d85ea2SLisandro Dalcin if (!dm->ops->locatepoints) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Point location not available for this DM"); 702147a35634SPatrick Farrell ierr = PetscLogEventBegin(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr); 702262a38674SMatthew G. Knepley ierr = (*dm->ops->locatepoints)(dm,v,ltype,*cellSF);CHKERRQ(ierr); 702347a35634SPatrick Farrell ierr = PetscLogEventEnd(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr); 7024e87bb0d3SMatthew G Knepley PetscFunctionReturn(0); 7025e87bb0d3SMatthew G Knepley } 702614f150ffSMatthew G. Knepley 7027f4d763aaSMatthew G. Knepley /*@ 7028f4d763aaSMatthew G. Knepley DMGetOutputDM - Retrieve the DM associated with the layout for output 7029f4d763aaSMatthew G. Knepley 70308f700142SStefano Zampini Collective on dm 70318f700142SStefano Zampini 7032f4d763aaSMatthew G. Knepley Input Parameter: 7033f4d763aaSMatthew G. Knepley . dm - The original DM 7034f4d763aaSMatthew G. Knepley 7035f4d763aaSMatthew G. Knepley Output Parameter: 7036f4d763aaSMatthew G. Knepley . odm - The DM which provides the layout for output 7037f4d763aaSMatthew G. Knepley 7038f4d763aaSMatthew G. Knepley Level: intermediate 7039f4d763aaSMatthew G. Knepley 7040e87a4003SBarry Smith .seealso: VecView(), DMGetGlobalSection() 7041f4d763aaSMatthew G. Knepley @*/ 704214f150ffSMatthew G. Knepley PetscErrorCode DMGetOutputDM(DM dm, DM *odm) 704314f150ffSMatthew G. Knepley { 7044c26acbdeSMatthew G. Knepley PetscSection section; 70452d4e4a49SMatthew G. Knepley PetscBool hasConstraints, ghasConstraints; 704614f150ffSMatthew G. Knepley PetscErrorCode ierr; 704714f150ffSMatthew G. Knepley 704814f150ffSMatthew G. Knepley PetscFunctionBegin; 704914f150ffSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 705014f150ffSMatthew G. Knepley PetscValidPointer(odm,2); 705192fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 7052c26acbdeSMatthew G. Knepley ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr); 7053ffc4695bSBarry Smith ierr = MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 70542d4e4a49SMatthew G. Knepley if (!ghasConstraints) { 7055c26acbdeSMatthew G. Knepley *odm = dm; 7056c26acbdeSMatthew G. Knepley PetscFunctionReturn(0); 7057c26acbdeSMatthew G. Knepley } 705814f150ffSMatthew G. Knepley if (!dm->dmBC) { 7059c26acbdeSMatthew G. Knepley PetscSection newSection, gsection; 706014f150ffSMatthew G. Knepley PetscSF sf; 706114f150ffSMatthew G. Knepley 706214f150ffSMatthew G. Knepley ierr = DMClone(dm, &dm->dmBC);CHKERRQ(ierr); 7063e5e52638SMatthew G. Knepley ierr = DMCopyDisc(dm, dm->dmBC);CHKERRQ(ierr); 706414f150ffSMatthew G. Knepley ierr = PetscSectionClone(section, &newSection);CHKERRQ(ierr); 706592fd8e1eSJed Brown ierr = DMSetLocalSection(dm->dmBC, newSection);CHKERRQ(ierr); 706614f150ffSMatthew G. Knepley ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr); 706714f150ffSMatthew G. Knepley ierr = DMGetPointSF(dm->dmBC, &sf);CHKERRQ(ierr); 706815b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr); 7069e87a4003SBarry Smith ierr = DMSetGlobalSection(dm->dmBC, gsection);CHKERRQ(ierr); 707014f150ffSMatthew G. Knepley ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr); 707114f150ffSMatthew G. Knepley } 707214f150ffSMatthew G. Knepley *odm = dm->dmBC; 707314f150ffSMatthew G. Knepley PetscFunctionReturn(0); 707414f150ffSMatthew G. Knepley } 7075f4d763aaSMatthew G. Knepley 7076f4d763aaSMatthew G. Knepley /*@ 7077cdb7a50dSMatthew G. Knepley DMGetOutputSequenceNumber - Retrieve the sequence number/value for output 7078f4d763aaSMatthew G. Knepley 7079f4d763aaSMatthew G. Knepley Input Parameter: 7080f4d763aaSMatthew G. Knepley . dm - The original DM 7081f4d763aaSMatthew G. Knepley 7082cdb7a50dSMatthew G. Knepley Output Parameters: 7083cdb7a50dSMatthew G. Knepley + num - The output sequence number 7084cdb7a50dSMatthew G. Knepley - val - The output sequence value 7085f4d763aaSMatthew G. Knepley 7086f4d763aaSMatthew G. Knepley Level: intermediate 7087f4d763aaSMatthew G. Knepley 7088f4d763aaSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 7089f4d763aaSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 7090f4d763aaSMatthew G. Knepley 7091f4d763aaSMatthew G. Knepley .seealso: VecView() 7092f4d763aaSMatthew G. Knepley @*/ 7093cdb7a50dSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val) 7094f4d763aaSMatthew G. Knepley { 7095f4d763aaSMatthew G. Knepley PetscFunctionBegin; 7096f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7097534a8f05SLisandro Dalcin if (num) {PetscValidIntPointer(num,2); *num = dm->outputSequenceNum;} 7098534a8f05SLisandro Dalcin if (val) {PetscValidRealPointer(val,3);*val = dm->outputSequenceVal;} 7099f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 7100f4d763aaSMatthew G. Knepley } 7101f4d763aaSMatthew G. Knepley 7102f4d763aaSMatthew G. Knepley /*@ 7103cdb7a50dSMatthew G. Knepley DMSetOutputSequenceNumber - Set the sequence number/value for output 7104f4d763aaSMatthew G. Knepley 7105f4d763aaSMatthew G. Knepley Input Parameters: 7106f4d763aaSMatthew G. Knepley + dm - The original DM 7107cdb7a50dSMatthew G. Knepley . num - The output sequence number 7108cdb7a50dSMatthew G. Knepley - val - The output sequence value 7109f4d763aaSMatthew G. Knepley 7110f4d763aaSMatthew G. Knepley Level: intermediate 7111f4d763aaSMatthew G. Knepley 7112f4d763aaSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 7113f4d763aaSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 7114f4d763aaSMatthew G. Knepley 7115f4d763aaSMatthew G. Knepley .seealso: VecView() 7116f4d763aaSMatthew G. Knepley @*/ 7117cdb7a50dSMatthew G. Knepley PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val) 7118f4d763aaSMatthew G. Knepley { 7119f4d763aaSMatthew G. Knepley PetscFunctionBegin; 7120f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7121f4d763aaSMatthew G. Knepley dm->outputSequenceNum = num; 7122cdb7a50dSMatthew G. Knepley dm->outputSequenceVal = val; 7123cdb7a50dSMatthew G. Knepley PetscFunctionReturn(0); 7124cdb7a50dSMatthew G. Knepley } 7125cdb7a50dSMatthew G. Knepley 7126cdb7a50dSMatthew G. Knepley /*@C 7127cdb7a50dSMatthew G. Knepley DMOutputSequenceLoad - Retrieve the sequence value from a Viewer 7128cdb7a50dSMatthew G. Knepley 7129cdb7a50dSMatthew G. Knepley Input Parameters: 7130cdb7a50dSMatthew G. Knepley + dm - The original DM 7131cdb7a50dSMatthew G. Knepley . name - The sequence name 7132cdb7a50dSMatthew G. Knepley - num - The output sequence number 7133cdb7a50dSMatthew G. Knepley 7134cdb7a50dSMatthew G. Knepley Output Parameter: 7135cdb7a50dSMatthew G. Knepley . val - The output sequence value 7136cdb7a50dSMatthew G. Knepley 7137cdb7a50dSMatthew G. Knepley Level: intermediate 7138cdb7a50dSMatthew G. Knepley 7139cdb7a50dSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 7140cdb7a50dSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 7141cdb7a50dSMatthew G. Knepley 7142cdb7a50dSMatthew G. Knepley .seealso: DMGetOutputSequenceNumber(), DMSetOutputSequenceNumber(), VecView() 7143cdb7a50dSMatthew G. Knepley @*/ 7144cdb7a50dSMatthew G. Knepley PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val) 7145cdb7a50dSMatthew G. Knepley { 7146cdb7a50dSMatthew G. Knepley PetscBool ishdf5; 7147cdb7a50dSMatthew G. Knepley PetscErrorCode ierr; 7148cdb7a50dSMatthew G. Knepley 7149cdb7a50dSMatthew G. Knepley PetscFunctionBegin; 7150cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7151cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 7152534a8f05SLisandro Dalcin PetscValidRealPointer(val,4); 7153cdb7a50dSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 7154cdb7a50dSMatthew G. Knepley if (ishdf5) { 7155cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 7156cdb7a50dSMatthew G. Knepley PetscScalar value; 7157cdb7a50dSMatthew G. Knepley 715839d25373SMatthew G. Knepley ierr = DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer);CHKERRQ(ierr); 71594aeb217fSMatthew G. Knepley *val = PetscRealPart(value); 7160cdb7a50dSMatthew G. Knepley #endif 7161cdb7a50dSMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()"); 7162f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 7163f4d763aaSMatthew G. Knepley } 71648e4ac7eaSMatthew G. Knepley 71658e4ac7eaSMatthew G. Knepley /*@ 71668e4ac7eaSMatthew G. Knepley DMGetUseNatural - Get the flag for creating a mapping to the natural order on distribution 71678e4ac7eaSMatthew G. Knepley 71688e4ac7eaSMatthew G. Knepley Not collective 71698e4ac7eaSMatthew G. Knepley 71708e4ac7eaSMatthew G. Knepley Input Parameter: 71718e4ac7eaSMatthew G. Knepley . dm - The DM 71728e4ac7eaSMatthew G. Knepley 71738e4ac7eaSMatthew G. Knepley Output Parameter: 71748e4ac7eaSMatthew G. Knepley . useNatural - The flag to build the mapping to a natural order during distribution 71758e4ac7eaSMatthew G. Knepley 71768e4ac7eaSMatthew G. Knepley Level: beginner 71778e4ac7eaSMatthew G. Knepley 71788e4ac7eaSMatthew G. Knepley .seealso: DMSetUseNatural(), DMCreate() 71798e4ac7eaSMatthew G. Knepley @*/ 71808e4ac7eaSMatthew G. Knepley PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural) 71818e4ac7eaSMatthew G. Knepley { 71828e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 71838e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7184534a8f05SLisandro Dalcin PetscValidBoolPointer(useNatural, 2); 71858e4ac7eaSMatthew G. Knepley *useNatural = dm->useNatural; 71868e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 71878e4ac7eaSMatthew G. Knepley } 71888e4ac7eaSMatthew G. Knepley 71898e4ac7eaSMatthew G. Knepley /*@ 71905d3b26e6SMatthew G. Knepley DMSetUseNatural - Set the flag for creating a mapping to the natural order after distribution 71918e4ac7eaSMatthew G. Knepley 71928e4ac7eaSMatthew G. Knepley Collective on dm 71938e4ac7eaSMatthew G. Knepley 71948e4ac7eaSMatthew G. Knepley Input Parameters: 71958e4ac7eaSMatthew G. Knepley + dm - The DM 71968e4ac7eaSMatthew G. Knepley - useNatural - The flag to build the mapping to a natural order during distribution 71978e4ac7eaSMatthew G. Knepley 71985d3b26e6SMatthew G. Knepley Note: This also causes the map to be build after DMCreateSubDM() and DMCreateSuperDM() 71995d3b26e6SMatthew G. Knepley 72008e4ac7eaSMatthew G. Knepley Level: beginner 72018e4ac7eaSMatthew G. Knepley 72025d3b26e6SMatthew G. Knepley .seealso: DMGetUseNatural(), DMCreate(), DMPlexDistribute(), DMCreateSubDM(), DMCreateSuperDM() 72038e4ac7eaSMatthew G. Knepley @*/ 72048e4ac7eaSMatthew G. Knepley PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural) 72058e4ac7eaSMatthew G. Knepley { 72068e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 72078e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72088833efb5SBlaise Bourdin PetscValidLogicalCollectiveBool(dm, useNatural, 2); 72098e4ac7eaSMatthew G. Knepley dm->useNatural = useNatural; 72108e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 72118e4ac7eaSMatthew G. Knepley } 7212c58f1c22SToby Isaac 7213c58f1c22SToby Isaac 7214c58f1c22SToby Isaac /*@C 7215c58f1c22SToby Isaac DMCreateLabel - Create a label of the given name if it does not already exist 7216c58f1c22SToby Isaac 7217c58f1c22SToby Isaac Not Collective 7218c58f1c22SToby Isaac 7219c58f1c22SToby Isaac Input Parameters: 7220c58f1c22SToby Isaac + dm - The DM object 7221c58f1c22SToby Isaac - name - The label name 7222c58f1c22SToby Isaac 7223c58f1c22SToby Isaac Level: intermediate 7224c58f1c22SToby Isaac 7225c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7226c58f1c22SToby Isaac @*/ 7227c58f1c22SToby Isaac PetscErrorCode DMCreateLabel(DM dm, const char name[]) 7228c58f1c22SToby Isaac { 72295d80c0bfSVaclav Hapla PetscBool flg; 72305d80c0bfSVaclav Hapla DMLabel label; 7231c58f1c22SToby Isaac PetscErrorCode ierr; 7232c58f1c22SToby Isaac 7233c58f1c22SToby Isaac PetscFunctionBegin; 7234c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7235c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 72365d80c0bfSVaclav Hapla ierr = DMHasLabel(dm, name, &flg);CHKERRQ(ierr); 7237c58f1c22SToby Isaac if (!flg) { 72385d80c0bfSVaclav Hapla ierr = DMLabelCreate(PETSC_COMM_SELF, name, &label);CHKERRQ(ierr); 72395d80c0bfSVaclav Hapla ierr = DMAddLabel(dm, label);CHKERRQ(ierr); 72405d80c0bfSVaclav Hapla ierr = DMLabelDestroy(&label);CHKERRQ(ierr); 7241c58f1c22SToby Isaac } 7242c58f1c22SToby Isaac PetscFunctionReturn(0); 7243c58f1c22SToby Isaac } 7244c58f1c22SToby Isaac 7245c58f1c22SToby Isaac /*@C 72460fdc7489SMatthew Knepley DMCreateLabelAtIndex - Create a label of the given name at the iven index. If it already exists, move it to this index. 72470fdc7489SMatthew Knepley 72480fdc7489SMatthew Knepley Not Collective 72490fdc7489SMatthew Knepley 72500fdc7489SMatthew Knepley Input Parameters: 72510fdc7489SMatthew Knepley + dm - The DM object 72520fdc7489SMatthew Knepley . l - The index for the label 72530fdc7489SMatthew Knepley - name - The label name 72540fdc7489SMatthew Knepley 72550fdc7489SMatthew Knepley Level: intermediate 72560fdc7489SMatthew Knepley 72570fdc7489SMatthew Knepley .seealso: DMCreateLabel(), DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 72580fdc7489SMatthew Knepley @*/ 72590fdc7489SMatthew Knepley PetscErrorCode DMCreateLabelAtIndex(DM dm, PetscInt l, const char name[]) 72600fdc7489SMatthew Knepley { 72610fdc7489SMatthew Knepley DMLabelLink orig, prev = NULL; 72620fdc7489SMatthew Knepley DMLabel label; 72630fdc7489SMatthew Knepley PetscInt Nl, m; 72640fdc7489SMatthew Knepley PetscBool flg, match; 72650fdc7489SMatthew Knepley const char *lname; 72660fdc7489SMatthew Knepley PetscErrorCode ierr; 72670fdc7489SMatthew Knepley 72680fdc7489SMatthew Knepley PetscFunctionBegin; 72690fdc7489SMatthew Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72700fdc7489SMatthew Knepley PetscValidCharPointer(name, 2); 72710fdc7489SMatthew Knepley ierr = DMHasLabel(dm, name, &flg);CHKERRQ(ierr); 72720fdc7489SMatthew Knepley if (!flg) { 72730fdc7489SMatthew Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, name, &label);CHKERRQ(ierr); 72740fdc7489SMatthew Knepley ierr = DMAddLabel(dm, label);CHKERRQ(ierr); 72750fdc7489SMatthew Knepley ierr = DMLabelDestroy(&label);CHKERRQ(ierr); 72760fdc7489SMatthew Knepley } 72770fdc7489SMatthew Knepley ierr = DMGetNumLabels(dm, &Nl);CHKERRQ(ierr); 72780fdc7489SMatthew Knepley if (l >= Nl) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label index %D must be in [0, %D)", l, Nl); 72790fdc7489SMatthew Knepley for (m = 0, orig = dm->labels; m < Nl; ++m, prev = orig, orig = orig->next) { 72800fdc7489SMatthew Knepley ierr = PetscObjectGetName((PetscObject) orig->label, &lname);CHKERRQ(ierr); 72810fdc7489SMatthew Knepley ierr = PetscStrcmp(name, lname, &match);CHKERRQ(ierr); 72820fdc7489SMatthew Knepley if (match) break; 72830fdc7489SMatthew Knepley } 72840fdc7489SMatthew Knepley if (m == l) PetscFunctionReturn(0); 72850fdc7489SMatthew Knepley if (!m) dm->labels = orig->next; 72860fdc7489SMatthew Knepley else prev->next = orig->next; 72870fdc7489SMatthew Knepley if (!l) { 72880fdc7489SMatthew Knepley orig->next = dm->labels; 72890fdc7489SMatthew Knepley dm->labels = orig; 72900fdc7489SMatthew Knepley } else { 72910fdc7489SMatthew Knepley for (m = 0, prev = dm->labels; m < l-1; ++m, prev = prev->next); 72920fdc7489SMatthew Knepley orig->next = prev->next; 72930fdc7489SMatthew Knepley prev->next = orig; 72940fdc7489SMatthew Knepley } 72950fdc7489SMatthew Knepley PetscFunctionReturn(0); 72960fdc7489SMatthew Knepley } 72970fdc7489SMatthew Knepley 72980fdc7489SMatthew Knepley /*@C 7299c58f1c22SToby Isaac DMGetLabelValue - Get the value in a Sieve Label for the given point, with 0 as the default 7300c58f1c22SToby Isaac 7301c58f1c22SToby Isaac Not Collective 7302c58f1c22SToby Isaac 7303c58f1c22SToby Isaac Input Parameters: 7304c58f1c22SToby Isaac + dm - The DM object 7305c58f1c22SToby Isaac . name - The label name 7306c58f1c22SToby Isaac - point - The mesh point 7307c58f1c22SToby Isaac 7308c58f1c22SToby Isaac Output Parameter: 7309c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label 7310c58f1c22SToby Isaac 7311c58f1c22SToby Isaac Level: beginner 7312c58f1c22SToby Isaac 7313c58f1c22SToby Isaac .seealso: DMLabelGetValue(), DMSetLabelValue(), DMGetStratumIS() 7314c58f1c22SToby Isaac @*/ 7315c58f1c22SToby Isaac PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value) 7316c58f1c22SToby Isaac { 7317c58f1c22SToby Isaac DMLabel label; 7318c58f1c22SToby Isaac PetscErrorCode ierr; 7319c58f1c22SToby Isaac 7320c58f1c22SToby Isaac PetscFunctionBegin; 7321c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7322c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7323c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 732413903a91SSatish Balay if (!label) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name); 7325c58f1c22SToby Isaac ierr = DMLabelGetValue(label, point, value);CHKERRQ(ierr); 7326c58f1c22SToby Isaac PetscFunctionReturn(0); 7327c58f1c22SToby Isaac } 7328c58f1c22SToby Isaac 7329c58f1c22SToby Isaac /*@C 7330c58f1c22SToby Isaac DMSetLabelValue - Add a point to a Sieve Label with given value 7331c58f1c22SToby Isaac 7332c58f1c22SToby Isaac Not Collective 7333c58f1c22SToby Isaac 7334c58f1c22SToby Isaac Input Parameters: 7335c58f1c22SToby Isaac + dm - The DM object 7336c58f1c22SToby Isaac . name - The label name 7337c58f1c22SToby Isaac . point - The mesh point 7338c58f1c22SToby Isaac - value - The label value for this point 7339c58f1c22SToby Isaac 7340c58f1c22SToby Isaac Output Parameter: 7341c58f1c22SToby Isaac 7342c58f1c22SToby Isaac Level: beginner 7343c58f1c22SToby Isaac 7344c58f1c22SToby Isaac .seealso: DMLabelSetValue(), DMGetStratumIS(), DMClearLabelValue() 7345c58f1c22SToby Isaac @*/ 7346c58f1c22SToby Isaac PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 7347c58f1c22SToby Isaac { 7348c58f1c22SToby Isaac DMLabel label; 7349c58f1c22SToby Isaac PetscErrorCode ierr; 7350c58f1c22SToby Isaac 7351c58f1c22SToby Isaac PetscFunctionBegin; 7352c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7353c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7354c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7355c58f1c22SToby Isaac if (!label) { 7356c58f1c22SToby Isaac ierr = DMCreateLabel(dm, name);CHKERRQ(ierr); 7357c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7358c58f1c22SToby Isaac } 7359c58f1c22SToby Isaac ierr = DMLabelSetValue(label, point, value);CHKERRQ(ierr); 7360c58f1c22SToby Isaac PetscFunctionReturn(0); 7361c58f1c22SToby Isaac } 7362c58f1c22SToby Isaac 7363c58f1c22SToby Isaac /*@C 7364c58f1c22SToby Isaac DMClearLabelValue - Remove a point from a Sieve Label with given value 7365c58f1c22SToby Isaac 7366c58f1c22SToby Isaac Not Collective 7367c58f1c22SToby Isaac 7368c58f1c22SToby Isaac Input Parameters: 7369c58f1c22SToby Isaac + dm - The DM object 7370c58f1c22SToby Isaac . name - The label name 7371c58f1c22SToby Isaac . point - The mesh point 7372c58f1c22SToby Isaac - value - The label value for this point 7373c58f1c22SToby Isaac 7374c58f1c22SToby Isaac Output Parameter: 7375c58f1c22SToby Isaac 7376c58f1c22SToby Isaac Level: beginner 7377c58f1c22SToby Isaac 7378c58f1c22SToby Isaac .seealso: DMLabelClearValue(), DMSetLabelValue(), DMGetStratumIS() 7379c58f1c22SToby Isaac @*/ 7380c58f1c22SToby Isaac PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 7381c58f1c22SToby Isaac { 7382c58f1c22SToby Isaac DMLabel label; 7383c58f1c22SToby Isaac PetscErrorCode ierr; 7384c58f1c22SToby Isaac 7385c58f1c22SToby Isaac PetscFunctionBegin; 7386c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7387c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7388c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7389c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7390c58f1c22SToby Isaac ierr = DMLabelClearValue(label, point, value);CHKERRQ(ierr); 7391c58f1c22SToby Isaac PetscFunctionReturn(0); 7392c58f1c22SToby Isaac } 7393c58f1c22SToby Isaac 7394c58f1c22SToby Isaac /*@C 7395c58f1c22SToby Isaac DMGetLabelSize - Get the number of different integer ids in a Label 7396c58f1c22SToby Isaac 7397c58f1c22SToby Isaac Not Collective 7398c58f1c22SToby Isaac 7399c58f1c22SToby Isaac Input Parameters: 7400c58f1c22SToby Isaac + dm - The DM object 7401c58f1c22SToby Isaac - name - The label name 7402c58f1c22SToby Isaac 7403c58f1c22SToby Isaac Output Parameter: 7404c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist 7405c58f1c22SToby Isaac 7406c58f1c22SToby Isaac Level: beginner 7407c58f1c22SToby Isaac 7408df813f42SMatthew G. Knepley .seealso: DMLabelGetNumValues(), DMSetLabelValue() 7409c58f1c22SToby Isaac @*/ 7410c58f1c22SToby Isaac PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size) 7411c58f1c22SToby Isaac { 7412c58f1c22SToby Isaac DMLabel label; 7413c58f1c22SToby Isaac PetscErrorCode ierr; 7414c58f1c22SToby Isaac 7415c58f1c22SToby Isaac PetscFunctionBegin; 7416c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7417c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7418534a8f05SLisandro Dalcin PetscValidIntPointer(size, 3); 7419c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7420c58f1c22SToby Isaac *size = 0; 7421c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7422c58f1c22SToby Isaac ierr = DMLabelGetNumValues(label, size);CHKERRQ(ierr); 7423c58f1c22SToby Isaac PetscFunctionReturn(0); 7424c58f1c22SToby Isaac } 7425c58f1c22SToby Isaac 7426c58f1c22SToby Isaac /*@C 7427c58f1c22SToby Isaac DMGetLabelIdIS - Get the integer ids in a label 7428c58f1c22SToby Isaac 7429c58f1c22SToby Isaac Not Collective 7430c58f1c22SToby Isaac 7431c58f1c22SToby Isaac Input Parameters: 7432c58f1c22SToby Isaac + mesh - The DM object 7433c58f1c22SToby Isaac - name - The label name 7434c58f1c22SToby Isaac 7435c58f1c22SToby Isaac Output Parameter: 7436c58f1c22SToby Isaac . ids - The integer ids, or NULL if the label does not exist 7437c58f1c22SToby Isaac 7438c58f1c22SToby Isaac Level: beginner 7439c58f1c22SToby Isaac 7440c58f1c22SToby Isaac .seealso: DMLabelGetValueIS(), DMGetLabelSize() 7441c58f1c22SToby Isaac @*/ 7442c58f1c22SToby Isaac PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids) 7443c58f1c22SToby Isaac { 7444c58f1c22SToby Isaac DMLabel label; 7445c58f1c22SToby Isaac PetscErrorCode ierr; 7446c58f1c22SToby Isaac 7447c58f1c22SToby Isaac PetscFunctionBegin; 7448c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7449c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7450c58f1c22SToby Isaac PetscValidPointer(ids, 3); 7451c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7452c58f1c22SToby Isaac *ids = NULL; 7453dab2e251SBlaise Bourdin if (label) { 7454c58f1c22SToby Isaac ierr = DMLabelGetValueIS(label, ids);CHKERRQ(ierr); 7455dab2e251SBlaise Bourdin } else { 7456dab2e251SBlaise Bourdin /* returning an empty IS */ 7457dab2e251SBlaise Bourdin ierr = ISCreateGeneral(PETSC_COMM_SELF,0,NULL,PETSC_USE_POINTER,ids);CHKERRQ(ierr); 7458dab2e251SBlaise Bourdin } 7459c58f1c22SToby Isaac PetscFunctionReturn(0); 7460c58f1c22SToby Isaac } 7461c58f1c22SToby Isaac 7462c58f1c22SToby Isaac /*@C 7463c58f1c22SToby Isaac DMGetStratumSize - Get the number of points in a label stratum 7464c58f1c22SToby Isaac 7465c58f1c22SToby Isaac Not Collective 7466c58f1c22SToby Isaac 7467c58f1c22SToby Isaac Input Parameters: 7468c58f1c22SToby Isaac + dm - The DM object 7469c58f1c22SToby Isaac . name - The label name 7470c58f1c22SToby Isaac - value - The stratum value 7471c58f1c22SToby Isaac 7472c58f1c22SToby Isaac Output Parameter: 7473c58f1c22SToby Isaac . size - The stratum size 7474c58f1c22SToby Isaac 7475c58f1c22SToby Isaac Level: beginner 7476c58f1c22SToby Isaac 7477c58f1c22SToby Isaac .seealso: DMLabelGetStratumSize(), DMGetLabelSize(), DMGetLabelIds() 7478c58f1c22SToby Isaac @*/ 7479c58f1c22SToby Isaac PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size) 7480c58f1c22SToby Isaac { 7481c58f1c22SToby Isaac DMLabel label; 7482c58f1c22SToby Isaac PetscErrorCode ierr; 7483c58f1c22SToby Isaac 7484c58f1c22SToby Isaac PetscFunctionBegin; 7485c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7486c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7487534a8f05SLisandro Dalcin PetscValidIntPointer(size, 4); 7488c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7489c58f1c22SToby Isaac *size = 0; 7490c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7491c58f1c22SToby Isaac ierr = DMLabelGetStratumSize(label, value, size);CHKERRQ(ierr); 7492c58f1c22SToby Isaac PetscFunctionReturn(0); 7493c58f1c22SToby Isaac } 7494c58f1c22SToby Isaac 7495c58f1c22SToby Isaac /*@C 7496c58f1c22SToby Isaac DMGetStratumIS - Get the points in a label stratum 7497c58f1c22SToby Isaac 7498c58f1c22SToby Isaac Not Collective 7499c58f1c22SToby Isaac 7500c58f1c22SToby Isaac Input Parameters: 7501c58f1c22SToby Isaac + dm - The DM object 7502c58f1c22SToby Isaac . name - The label name 7503c58f1c22SToby Isaac - value - The stratum value 7504c58f1c22SToby Isaac 7505c58f1c22SToby Isaac Output Parameter: 7506c58f1c22SToby Isaac . points - The stratum points, or NULL if the label does not exist or does not have that value 7507c58f1c22SToby Isaac 7508c58f1c22SToby Isaac Level: beginner 7509c58f1c22SToby Isaac 7510c58f1c22SToby Isaac .seealso: DMLabelGetStratumIS(), DMGetStratumSize() 7511c58f1c22SToby Isaac @*/ 7512c58f1c22SToby Isaac PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points) 7513c58f1c22SToby Isaac { 7514c58f1c22SToby Isaac DMLabel label; 7515c58f1c22SToby Isaac PetscErrorCode ierr; 7516c58f1c22SToby Isaac 7517c58f1c22SToby Isaac PetscFunctionBegin; 7518c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7519c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7520c58f1c22SToby Isaac PetscValidPointer(points, 4); 7521c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7522c58f1c22SToby Isaac *points = NULL; 7523c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7524c58f1c22SToby Isaac ierr = DMLabelGetStratumIS(label, value, points);CHKERRQ(ierr); 7525c58f1c22SToby Isaac PetscFunctionReturn(0); 7526c58f1c22SToby Isaac } 7527c58f1c22SToby Isaac 75284de306b1SToby Isaac /*@C 75299044fa66SMatthew G. Knepley DMSetStratumIS - Set the points in a label stratum 75304de306b1SToby Isaac 75314de306b1SToby Isaac Not Collective 75324de306b1SToby Isaac 75334de306b1SToby Isaac Input Parameters: 75344de306b1SToby Isaac + dm - The DM object 75354de306b1SToby Isaac . name - The label name 75364de306b1SToby Isaac . value - The stratum value 75374de306b1SToby Isaac - points - The stratum points 75384de306b1SToby Isaac 75394de306b1SToby Isaac Level: beginner 75404de306b1SToby Isaac 75414de306b1SToby Isaac .seealso: DMLabelSetStratumIS(), DMGetStratumSize() 75424de306b1SToby Isaac @*/ 75434de306b1SToby Isaac PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points) 75444de306b1SToby Isaac { 75454de306b1SToby Isaac DMLabel label; 75464de306b1SToby Isaac PetscErrorCode ierr; 75474de306b1SToby Isaac 75484de306b1SToby Isaac PetscFunctionBegin; 75494de306b1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 75504de306b1SToby Isaac PetscValidCharPointer(name, 2); 75514de306b1SToby Isaac PetscValidPointer(points, 4); 75524de306b1SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 75534de306b1SToby Isaac if (!label) PetscFunctionReturn(0); 75544de306b1SToby Isaac ierr = DMLabelSetStratumIS(label, value, points);CHKERRQ(ierr); 75554de306b1SToby Isaac PetscFunctionReturn(0); 75564de306b1SToby Isaac } 75574de306b1SToby Isaac 7558c58f1c22SToby Isaac /*@C 7559c58f1c22SToby Isaac DMClearLabelStratum - Remove all points from a stratum from a Sieve Label 7560c58f1c22SToby Isaac 7561c58f1c22SToby Isaac Not Collective 7562c58f1c22SToby Isaac 7563c58f1c22SToby Isaac Input Parameters: 7564c58f1c22SToby Isaac + dm - The DM object 7565c58f1c22SToby Isaac . name - The label name 7566c58f1c22SToby Isaac - value - The label value for this point 7567c58f1c22SToby Isaac 7568c58f1c22SToby Isaac Output Parameter: 7569c58f1c22SToby Isaac 7570c58f1c22SToby Isaac Level: beginner 7571c58f1c22SToby Isaac 7572c58f1c22SToby Isaac .seealso: DMLabelClearStratum(), DMSetLabelValue(), DMGetStratumIS(), DMClearLabelValue() 7573c58f1c22SToby Isaac @*/ 7574c58f1c22SToby Isaac PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value) 7575c58f1c22SToby Isaac { 7576c58f1c22SToby Isaac DMLabel label; 7577c58f1c22SToby Isaac PetscErrorCode ierr; 7578c58f1c22SToby Isaac 7579c58f1c22SToby Isaac PetscFunctionBegin; 7580c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7581c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7582c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7583c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7584c58f1c22SToby Isaac ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr); 7585c58f1c22SToby Isaac PetscFunctionReturn(0); 7586c58f1c22SToby Isaac } 7587c58f1c22SToby Isaac 7588c58f1c22SToby Isaac /*@ 7589c58f1c22SToby Isaac DMGetNumLabels - Return the number of labels defined by the mesh 7590c58f1c22SToby Isaac 7591c58f1c22SToby Isaac Not Collective 7592c58f1c22SToby Isaac 7593c58f1c22SToby Isaac Input Parameter: 7594c58f1c22SToby Isaac . dm - The DM object 7595c58f1c22SToby Isaac 7596c58f1c22SToby Isaac Output Parameter: 7597c58f1c22SToby Isaac . numLabels - the number of Labels 7598c58f1c22SToby Isaac 7599c58f1c22SToby Isaac Level: intermediate 7600c58f1c22SToby Isaac 7601c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7602c58f1c22SToby Isaac @*/ 7603c58f1c22SToby Isaac PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels) 7604c58f1c22SToby Isaac { 76055d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7606c58f1c22SToby Isaac PetscInt n = 0; 7607c58f1c22SToby Isaac 7608c58f1c22SToby Isaac PetscFunctionBegin; 7609c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7610534a8f05SLisandro Dalcin PetscValidIntPointer(numLabels, 2); 7611c58f1c22SToby Isaac while (next) {++n; next = next->next;} 7612c58f1c22SToby Isaac *numLabels = n; 7613c58f1c22SToby Isaac PetscFunctionReturn(0); 7614c58f1c22SToby Isaac } 7615c58f1c22SToby Isaac 7616c58f1c22SToby Isaac /*@C 7617c58f1c22SToby Isaac DMGetLabelName - Return the name of nth label 7618c58f1c22SToby Isaac 7619c58f1c22SToby Isaac Not Collective 7620c58f1c22SToby Isaac 7621c58f1c22SToby Isaac Input Parameters: 7622c58f1c22SToby Isaac + dm - The DM object 7623c58f1c22SToby Isaac - n - the label number 7624c58f1c22SToby Isaac 7625c58f1c22SToby Isaac Output Parameter: 7626c58f1c22SToby Isaac . name - the label name 7627c58f1c22SToby Isaac 7628c58f1c22SToby Isaac Level: intermediate 7629c58f1c22SToby Isaac 7630c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7631c58f1c22SToby Isaac @*/ 7632c58f1c22SToby Isaac PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name) 7633c58f1c22SToby Isaac { 76345d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7635c58f1c22SToby Isaac PetscInt l = 0; 7636d67d17b1SMatthew G. Knepley PetscErrorCode ierr; 7637c58f1c22SToby Isaac 7638c58f1c22SToby Isaac PetscFunctionBegin; 7639c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7640c58f1c22SToby Isaac PetscValidPointer(name, 3); 7641c58f1c22SToby Isaac while (next) { 7642c58f1c22SToby Isaac if (l == n) { 7643d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, name);CHKERRQ(ierr); 7644c58f1c22SToby Isaac PetscFunctionReturn(0); 7645c58f1c22SToby Isaac } 7646c58f1c22SToby Isaac ++l; 7647c58f1c22SToby Isaac next = next->next; 7648c58f1c22SToby Isaac } 7649c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n); 7650c58f1c22SToby Isaac } 7651c58f1c22SToby Isaac 7652c58f1c22SToby Isaac /*@C 7653c58f1c22SToby Isaac DMHasLabel - Determine whether the mesh has a label of a given name 7654c58f1c22SToby Isaac 7655c58f1c22SToby Isaac Not Collective 7656c58f1c22SToby Isaac 7657c58f1c22SToby Isaac Input Parameters: 7658c58f1c22SToby Isaac + dm - The DM object 7659c58f1c22SToby Isaac - name - The label name 7660c58f1c22SToby Isaac 7661c58f1c22SToby Isaac Output Parameter: 7662c58f1c22SToby Isaac . hasLabel - PETSC_TRUE if the label is present 7663c58f1c22SToby Isaac 7664c58f1c22SToby Isaac Level: intermediate 7665c58f1c22SToby Isaac 7666c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7667c58f1c22SToby Isaac @*/ 7668c58f1c22SToby Isaac PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel) 7669c58f1c22SToby Isaac { 76705d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7671d67d17b1SMatthew G. Knepley const char *lname; 7672c58f1c22SToby Isaac PetscErrorCode ierr; 7673c58f1c22SToby Isaac 7674c58f1c22SToby Isaac PetscFunctionBegin; 7675c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7676c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7677534a8f05SLisandro Dalcin PetscValidBoolPointer(hasLabel, 3); 7678c58f1c22SToby Isaac *hasLabel = PETSC_FALSE; 7679c58f1c22SToby Isaac while (next) { 7680d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 7681d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, hasLabel);CHKERRQ(ierr); 7682c58f1c22SToby Isaac if (*hasLabel) break; 7683c58f1c22SToby Isaac next = next->next; 7684c58f1c22SToby Isaac } 7685c58f1c22SToby Isaac PetscFunctionReturn(0); 7686c58f1c22SToby Isaac } 7687c58f1c22SToby Isaac 7688c58f1c22SToby Isaac /*@C 7689c58f1c22SToby Isaac DMGetLabel - Return the label of a given name, or NULL 7690c58f1c22SToby Isaac 7691c58f1c22SToby Isaac Not Collective 7692c58f1c22SToby Isaac 7693c58f1c22SToby Isaac Input Parameters: 7694c58f1c22SToby Isaac + dm - The DM object 7695c58f1c22SToby Isaac - name - The label name 7696c58f1c22SToby Isaac 7697c58f1c22SToby Isaac Output Parameter: 7698c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent 7699c58f1c22SToby Isaac 77006d7c9049SMatthew G. Knepley Note: Some of the default labels in a DMPlex will be 77016d7c9049SMatthew G. Knepley $ "depth" - Holds the depth (co-dimension) of each mesh point 77026d7c9049SMatthew G. Knepley $ "celltype" - Holds the topological type of each cell 77036d7c9049SMatthew G. Knepley $ "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 77046d7c9049SMatthew G. Knepley $ "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 77056d7c9049SMatthew G. Knepley $ "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 77066d7c9049SMatthew G. Knepley $ "Vertex Sets" - Mirrors the vertex sets defined by GMsh 77076d7c9049SMatthew G. Knepley 7708c58f1c22SToby Isaac Level: intermediate 7709c58f1c22SToby Isaac 77106d7c9049SMatthew G. Knepley .seealso: DMCreateLabel(), DMHasLabel(), DMPlexGetDepthLabel(), DMPlexGetCellType() 7711c58f1c22SToby Isaac @*/ 7712c58f1c22SToby Isaac PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label) 7713c58f1c22SToby Isaac { 77145d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7715c58f1c22SToby Isaac PetscBool hasLabel; 7716d67d17b1SMatthew G. Knepley const char *lname; 7717c58f1c22SToby Isaac PetscErrorCode ierr; 7718c58f1c22SToby Isaac 7719c58f1c22SToby Isaac PetscFunctionBegin; 7720c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7721c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7722c58f1c22SToby Isaac PetscValidPointer(label, 3); 7723c58f1c22SToby Isaac *label = NULL; 7724c58f1c22SToby Isaac while (next) { 7725d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 7726d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr); 7727c58f1c22SToby Isaac if (hasLabel) { 7728c58f1c22SToby Isaac *label = next->label; 7729c58f1c22SToby Isaac break; 7730c58f1c22SToby Isaac } 7731c58f1c22SToby Isaac next = next->next; 7732c58f1c22SToby Isaac } 7733c58f1c22SToby Isaac PetscFunctionReturn(0); 7734c58f1c22SToby Isaac } 7735c58f1c22SToby Isaac 7736c58f1c22SToby Isaac /*@C 7737c58f1c22SToby Isaac DMGetLabelByNum - Return the nth label 7738c58f1c22SToby Isaac 7739c58f1c22SToby Isaac Not Collective 7740c58f1c22SToby Isaac 7741c58f1c22SToby Isaac Input Parameters: 7742c58f1c22SToby Isaac + dm - The DM object 7743c58f1c22SToby Isaac - n - the label number 7744c58f1c22SToby Isaac 7745c58f1c22SToby Isaac Output Parameter: 7746c58f1c22SToby Isaac . label - the label 7747c58f1c22SToby Isaac 7748c58f1c22SToby Isaac Level: intermediate 7749c58f1c22SToby Isaac 7750c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7751c58f1c22SToby Isaac @*/ 7752c58f1c22SToby Isaac PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label) 7753c58f1c22SToby Isaac { 77545d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7755c58f1c22SToby Isaac PetscInt l = 0; 7756c58f1c22SToby Isaac 7757c58f1c22SToby Isaac PetscFunctionBegin; 7758c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7759c58f1c22SToby Isaac PetscValidPointer(label, 3); 7760c58f1c22SToby Isaac while (next) { 7761c58f1c22SToby Isaac if (l == n) { 7762c58f1c22SToby Isaac *label = next->label; 7763c58f1c22SToby Isaac PetscFunctionReturn(0); 7764c58f1c22SToby Isaac } 7765c58f1c22SToby Isaac ++l; 7766c58f1c22SToby Isaac next = next->next; 7767c58f1c22SToby Isaac } 7768c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n); 7769c58f1c22SToby Isaac } 7770c58f1c22SToby Isaac 7771c58f1c22SToby Isaac /*@C 7772c58f1c22SToby Isaac DMAddLabel - Add the label to this mesh 7773c58f1c22SToby Isaac 7774c58f1c22SToby Isaac Not Collective 7775c58f1c22SToby Isaac 7776c58f1c22SToby Isaac Input Parameters: 7777c58f1c22SToby Isaac + dm - The DM object 7778c58f1c22SToby Isaac - label - The DMLabel 7779c58f1c22SToby Isaac 7780c58f1c22SToby Isaac Level: developer 7781c58f1c22SToby Isaac 7782c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7783c58f1c22SToby Isaac @*/ 7784c58f1c22SToby Isaac PetscErrorCode DMAddLabel(DM dm, DMLabel label) 7785c58f1c22SToby Isaac { 77865d80c0bfSVaclav Hapla DMLabelLink l, *p, tmpLabel; 7787c58f1c22SToby Isaac PetscBool hasLabel; 7788d67d17b1SMatthew G. Knepley const char *lname; 77895d80c0bfSVaclav Hapla PetscBool flg; 7790c58f1c22SToby Isaac PetscErrorCode ierr; 7791c58f1c22SToby Isaac 7792c58f1c22SToby Isaac PetscFunctionBegin; 7793c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7794d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 7795d67d17b1SMatthew G. Knepley ierr = DMHasLabel(dm, lname, &hasLabel);CHKERRQ(ierr); 7796d67d17b1SMatthew G. Knepley if (hasLabel) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname); 7797c58f1c22SToby Isaac ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr); 7798c58f1c22SToby Isaac tmpLabel->label = label; 7799c58f1c22SToby Isaac tmpLabel->output = PETSC_TRUE; 78005d80c0bfSVaclav Hapla for (p=&dm->labels; (l=*p); p=&l->next) {} 78015d80c0bfSVaclav Hapla *p = tmpLabel; 780208f633c4SVaclav Hapla ierr = PetscObjectReference((PetscObject)label);CHKERRQ(ierr); 78035d80c0bfSVaclav Hapla ierr = PetscStrcmp(lname, "depth", &flg);CHKERRQ(ierr); 78045d80c0bfSVaclav Hapla if (flg) dm->depthLabel = label; 7805ba2698f1SMatthew G. Knepley ierr = PetscStrcmp(lname, "celltype", &flg);CHKERRQ(ierr); 7806ba2698f1SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 7807c58f1c22SToby Isaac PetscFunctionReturn(0); 7808c58f1c22SToby Isaac } 7809c58f1c22SToby Isaac 7810c58f1c22SToby Isaac /*@C 7811e5472504SVaclav Hapla DMRemoveLabel - Remove the label given by name from this mesh 7812c58f1c22SToby Isaac 7813c58f1c22SToby Isaac Not Collective 7814c58f1c22SToby Isaac 7815c58f1c22SToby Isaac Input Parameters: 7816c58f1c22SToby Isaac + dm - The DM object 7817c58f1c22SToby Isaac - name - The label name 7818c58f1c22SToby Isaac 7819c58f1c22SToby Isaac Output Parameter: 7820c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent 7821c58f1c22SToby Isaac 7822c58f1c22SToby Isaac Level: developer 7823c58f1c22SToby Isaac 7824e5472504SVaclav Hapla Notes: 7825e5472504SVaclav Hapla DMRemoveLabel(dm,name,NULL) removes the label from dm and calls 7826e5472504SVaclav Hapla DMLabelDestroy() on the label. 7827e5472504SVaclav Hapla 7828e5472504SVaclav Hapla DMRemoveLabel(dm,name,&label) removes the label from dm, but it DOES NOT 7829e5472504SVaclav Hapla call DMLabelDestroy(). Instead, the label is returned and the user is 7830e5472504SVaclav Hapla responsible of calling DMLabelDestroy() at some point. 7831e5472504SVaclav Hapla 7832e5472504SVaclav Hapla .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabel(), DMGetLabelValue(), DMSetLabelValue(), DMLabelDestroy(), DMRemoveLabelBySelf() 7833c58f1c22SToby Isaac @*/ 7834c58f1c22SToby Isaac PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label) 7835c58f1c22SToby Isaac { 783695d578d6SVaclav Hapla DMLabelLink link, *pnext; 7837c58f1c22SToby Isaac PetscBool hasLabel; 7838d67d17b1SMatthew G. Knepley const char *lname; 7839c58f1c22SToby Isaac PetscErrorCode ierr; 7840c58f1c22SToby Isaac 7841c58f1c22SToby Isaac PetscFunctionBegin; 7842c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7843e5472504SVaclav Hapla PetscValidCharPointer(name, 2); 7844e5472504SVaclav Hapla if (label) { 7845e5472504SVaclav Hapla PetscValidPointer(label, 3); 7846c58f1c22SToby Isaac *label = NULL; 7847e5472504SVaclav Hapla } 78485d80c0bfSVaclav Hapla for (pnext=&dm->labels; (link=*pnext); pnext=&link->next) { 784995d578d6SVaclav Hapla ierr = PetscObjectGetName((PetscObject) link->label, &lname);CHKERRQ(ierr); 7850d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr); 7851c58f1c22SToby Isaac if (hasLabel) { 785295d578d6SVaclav Hapla *pnext = link->next; /* Remove from list */ 7853c58f1c22SToby Isaac ierr = PetscStrcmp(name, "depth", &hasLabel);CHKERRQ(ierr); 785495d578d6SVaclav Hapla if (hasLabel) dm->depthLabel = NULL; 7855ba2698f1SMatthew G. Knepley ierr = PetscStrcmp(name, "celltype", &hasLabel);CHKERRQ(ierr); 7856ba2698f1SMatthew G. Knepley if (hasLabel) dm->celltypeLabel = NULL; 785795d578d6SVaclav Hapla if (label) *label = link->label; 785895d578d6SVaclav Hapla else {ierr = DMLabelDestroy(&link->label);CHKERRQ(ierr);} 785995d578d6SVaclav Hapla ierr = PetscFree(link);CHKERRQ(ierr); 7860c58f1c22SToby Isaac break; 7861c58f1c22SToby Isaac } 7862c58f1c22SToby Isaac } 7863c58f1c22SToby Isaac PetscFunctionReturn(0); 7864c58f1c22SToby Isaac } 7865c58f1c22SToby Isaac 7866306894acSVaclav Hapla /*@ 7867306894acSVaclav Hapla DMRemoveLabelBySelf - Remove the label from this mesh 7868306894acSVaclav Hapla 7869306894acSVaclav Hapla Not Collective 7870306894acSVaclav Hapla 7871306894acSVaclav Hapla Input Parameters: 7872306894acSVaclav Hapla + dm - The DM object 7873306894acSVaclav Hapla . label - (Optional) The DMLabel to be removed from the DM 7874306894acSVaclav Hapla - failNotFound - Should it fail if the label is not found in the DM? 7875306894acSVaclav Hapla 7876306894acSVaclav Hapla Level: developer 7877306894acSVaclav Hapla 7878306894acSVaclav Hapla Notes: 7879306894acSVaclav Hapla Only exactly the same instance is removed if found, name match is ignored. 7880306894acSVaclav Hapla If the DM has an exclusive reference to the label, it gets destroyed and 7881306894acSVaclav Hapla *label nullified. 7882306894acSVaclav Hapla 7883306894acSVaclav Hapla .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabel() DMGetLabelValue(), DMSetLabelValue(), DMLabelDestroy(), DMRemoveLabel() 7884306894acSVaclav Hapla @*/ 7885306894acSVaclav Hapla PetscErrorCode DMRemoveLabelBySelf(DM dm, DMLabel *label, PetscBool failNotFound) 7886306894acSVaclav Hapla { 788743e45a93SVaclav Hapla DMLabelLink link, *pnext; 7888306894acSVaclav Hapla PetscBool hasLabel = PETSC_FALSE; 7889306894acSVaclav Hapla PetscErrorCode ierr; 7890306894acSVaclav Hapla 7891306894acSVaclav Hapla PetscFunctionBegin; 7892306894acSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7893306894acSVaclav Hapla PetscValidPointer(label, 2); 7894f39a9ae0SVaclav Hapla if (!*label && !failNotFound) PetscFunctionReturn(0); 7895306894acSVaclav Hapla PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 2); 7896306894acSVaclav Hapla PetscValidLogicalCollectiveBool(dm,failNotFound,3); 78975d80c0bfSVaclav Hapla for (pnext=&dm->labels; (link=*pnext); pnext=&link->next) { 789843e45a93SVaclav Hapla if (*label == link->label) { 7899306894acSVaclav Hapla hasLabel = PETSC_TRUE; 790043e45a93SVaclav Hapla *pnext = link->next; /* Remove from list */ 7901306894acSVaclav Hapla if (*label == dm->depthLabel) dm->depthLabel = NULL; 7902ba2698f1SMatthew G. Knepley if (*label == dm->celltypeLabel) dm->celltypeLabel = NULL; 790343e45a93SVaclav Hapla if (((PetscObject) link->label)->refct < 2) *label = NULL; /* nullify if exclusive reference */ 790443e45a93SVaclav Hapla ierr = DMLabelDestroy(&link->label);CHKERRQ(ierr); 790543e45a93SVaclav Hapla ierr = PetscFree(link);CHKERRQ(ierr); 7906306894acSVaclav Hapla break; 7907306894acSVaclav Hapla } 7908306894acSVaclav Hapla } 7909306894acSVaclav Hapla if (!hasLabel && failNotFound) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Given label not found in DM"); 7910306894acSVaclav Hapla PetscFunctionReturn(0); 7911306894acSVaclav Hapla } 7912306894acSVaclav Hapla 7913c58f1c22SToby Isaac /*@C 7914c58f1c22SToby Isaac DMGetLabelOutput - Get the output flag for a given label 7915c58f1c22SToby Isaac 7916c58f1c22SToby Isaac Not Collective 7917c58f1c22SToby Isaac 7918c58f1c22SToby Isaac Input Parameters: 7919c58f1c22SToby Isaac + dm - The DM object 7920c58f1c22SToby Isaac - name - The label name 7921c58f1c22SToby Isaac 7922c58f1c22SToby Isaac Output Parameter: 7923c58f1c22SToby Isaac . output - The flag for output 7924c58f1c22SToby Isaac 7925c58f1c22SToby Isaac Level: developer 7926c58f1c22SToby Isaac 7927c58f1c22SToby Isaac .seealso: DMSetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7928c58f1c22SToby Isaac @*/ 7929c58f1c22SToby Isaac PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output) 7930c58f1c22SToby Isaac { 79315d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7932d67d17b1SMatthew G. Knepley const char *lname; 7933c58f1c22SToby Isaac PetscErrorCode ierr; 7934c58f1c22SToby Isaac 7935c58f1c22SToby Isaac PetscFunctionBegin; 7936c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7937c58f1c22SToby Isaac PetscValidPointer(name, 2); 7938c58f1c22SToby Isaac PetscValidPointer(output, 3); 7939c58f1c22SToby Isaac while (next) { 7940c58f1c22SToby Isaac PetscBool flg; 7941c58f1c22SToby Isaac 7942d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 7943d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr); 7944c58f1c22SToby Isaac if (flg) {*output = next->output; PetscFunctionReturn(0);} 7945c58f1c22SToby Isaac next = next->next; 7946c58f1c22SToby Isaac } 7947c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7948c58f1c22SToby Isaac } 7949c58f1c22SToby Isaac 7950c58f1c22SToby Isaac /*@C 7951c58f1c22SToby Isaac DMSetLabelOutput - Set the output flag for a given label 7952c58f1c22SToby Isaac 7953c58f1c22SToby Isaac Not Collective 7954c58f1c22SToby Isaac 7955c58f1c22SToby Isaac Input Parameters: 7956c58f1c22SToby Isaac + dm - The DM object 7957c58f1c22SToby Isaac . name - The label name 7958c58f1c22SToby Isaac - output - The flag for output 7959c58f1c22SToby Isaac 7960c58f1c22SToby Isaac Level: developer 7961c58f1c22SToby Isaac 7962c58f1c22SToby Isaac .seealso: DMGetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7963c58f1c22SToby Isaac @*/ 7964c58f1c22SToby Isaac PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output) 7965c58f1c22SToby Isaac { 79665d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7967d67d17b1SMatthew G. Knepley const char *lname; 7968c58f1c22SToby Isaac PetscErrorCode ierr; 7969c58f1c22SToby Isaac 7970c58f1c22SToby Isaac PetscFunctionBegin; 7971c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7972534a8f05SLisandro Dalcin PetscValidCharPointer(name, 2); 7973c58f1c22SToby Isaac while (next) { 7974c58f1c22SToby Isaac PetscBool flg; 7975c58f1c22SToby Isaac 7976d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 7977d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr); 7978c58f1c22SToby Isaac if (flg) {next->output = output; PetscFunctionReturn(0);} 7979c58f1c22SToby Isaac next = next->next; 7980c58f1c22SToby Isaac } 7981c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7982c58f1c22SToby Isaac } 7983c58f1c22SToby Isaac 7984c58f1c22SToby Isaac /*@ 7985c58f1c22SToby Isaac DMCopyLabels - Copy labels from one mesh to another with a superset of the points 7986c58f1c22SToby Isaac 7987d083f849SBarry Smith Collective on dmA 7988c58f1c22SToby Isaac 7989c58f1c22SToby Isaac Input Parameter: 79905d80c0bfSVaclav Hapla + dmA - The DM object with initial labels 79912e17dfb7SMatthew G. Knepley . dmB - The DM object with copied labels 79925d80c0bfSVaclav Hapla . mode - Copy labels by pointers (PETSC_OWN_POINTER) or duplicate them (PETSC_COPY_VALUES) 7993ba2698f1SMatthew G. Knepley - all - Copy all labels including "depth", "dim", and "celltype" (PETSC_TRUE) which are otherwise ignored (PETSC_FALSE) 7994c58f1c22SToby Isaac 7995c58f1c22SToby Isaac Level: intermediate 7996c58f1c22SToby Isaac 7997c58f1c22SToby Isaac Note: This is typically used when interpolating or otherwise adding to a mesh 7998c58f1c22SToby Isaac 79995d80c0bfSVaclav Hapla .seealso: DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMGetCoordinateSection(), DMShareLabels() 8000c58f1c22SToby Isaac @*/ 80015d80c0bfSVaclav Hapla PetscErrorCode DMCopyLabels(DM dmA, DM dmB, PetscCopyMode mode, PetscBool all) 8002c58f1c22SToby Isaac { 8003c58f1c22SToby Isaac DMLabel label, labelNew; 8004c58f1c22SToby Isaac const char *name; 8005c58f1c22SToby Isaac PetscBool flg; 80065d80c0bfSVaclav Hapla DMLabelLink link; 80075d80c0bfSVaclav Hapla PetscErrorCode ierr; 8008c58f1c22SToby Isaac 80095d80c0bfSVaclav Hapla PetscFunctionBegin; 80105d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 80115d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 80125d80c0bfSVaclav Hapla PetscValidLogicalCollectiveEnum(dmA, mode,3); 80135d80c0bfSVaclav Hapla PetscValidLogicalCollectiveBool(dmA, all, 4); 80145d80c0bfSVaclav Hapla if (mode==PETSC_USE_POINTER) SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_SUP, "PETSC_USE_POINTER not supported for objects"); 80155d80c0bfSVaclav Hapla if (dmA == dmB) PetscFunctionReturn(0); 80165d80c0bfSVaclav Hapla for (link=dmA->labels; link; link=link->next) { 80175d80c0bfSVaclav Hapla label=link->label; 80185d80c0bfSVaclav Hapla ierr = PetscObjectGetName((PetscObject)label, &name);CHKERRQ(ierr); 80195d80c0bfSVaclav Hapla if (!all) { 8020c58f1c22SToby Isaac ierr = PetscStrcmp(name, "depth", &flg);CHKERRQ(ierr); 8021c58f1c22SToby Isaac if (flg) continue; 80227d5acc75SStefano Zampini ierr = PetscStrcmp(name, "dim", &flg);CHKERRQ(ierr); 80237d5acc75SStefano Zampini if (flg) continue; 8024ba2698f1SMatthew G. Knepley ierr = PetscStrcmp(name, "celltype", &flg);CHKERRQ(ierr); 8025ba2698f1SMatthew G. Knepley if (flg) continue; 80265d80c0bfSVaclav Hapla } 80275d80c0bfSVaclav Hapla if (mode==PETSC_COPY_VALUES) { 8028c58f1c22SToby Isaac ierr = DMLabelDuplicate(label, &labelNew);CHKERRQ(ierr); 80295d80c0bfSVaclav Hapla } else { 80305d80c0bfSVaclav Hapla labelNew = label; 80315d80c0bfSVaclav Hapla } 8032c58f1c22SToby Isaac ierr = DMAddLabel(dmB, labelNew);CHKERRQ(ierr); 80335d80c0bfSVaclav Hapla if (mode==PETSC_COPY_VALUES) {ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr);} 8034c58f1c22SToby Isaac } 8035c58f1c22SToby Isaac PetscFunctionReturn(0); 8036c58f1c22SToby Isaac } 8037*461a15a0SLisandro Dalcin 8038*461a15a0SLisandro Dalcin PetscErrorCode DMSetLabelValue_Fast(DM dm, DMLabel *label, const char name[], PetscInt point, PetscInt value) 8039*461a15a0SLisandro Dalcin { 8040*461a15a0SLisandro Dalcin PetscErrorCode ierr; 8041*461a15a0SLisandro Dalcin PetscFunctionBegin; 8042*461a15a0SLisandro Dalcin PetscValidPointer(label,2); 8043*461a15a0SLisandro Dalcin if (!*label) { 8044*461a15a0SLisandro Dalcin ierr = DMCreateLabel(dm, name);CHKERRQ(ierr); 8045*461a15a0SLisandro Dalcin ierr = DMGetLabel(dm, name, label);CHKERRQ(ierr); 8046*461a15a0SLisandro Dalcin } 8047*461a15a0SLisandro Dalcin ierr = DMLabelSetValue(*label, point, value);CHKERRQ(ierr); 8048*461a15a0SLisandro Dalcin PetscFunctionReturn(0); 8049*461a15a0SLisandro Dalcin } 8050*461a15a0SLisandro Dalcin 80510fdc7489SMatthew Knepley /* 80520fdc7489SMatthew Knepley Many mesh programs, such as Triangle and TetGen, allow only a single label for each mesh point. Therefore, we would 80530fdc7489SMatthew Knepley like to encode all label IDs using a single, universal label. We can do this by assigning an integer to every 80540fdc7489SMatthew Knepley (label, id) pair in the DM. 80550fdc7489SMatthew Knepley 80560fdc7489SMatthew Knepley However, a mesh point can have multiple labels, so we must separate all these values. We will assign a bit range to 80570fdc7489SMatthew Knepley each label. 80580fdc7489SMatthew Knepley */ 80590fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelCreate(DM dm, DMUniversalLabel *universal) 80600fdc7489SMatthew Knepley { 80610fdc7489SMatthew Knepley DMUniversalLabel ul; 80620fdc7489SMatthew Knepley PetscBool *active; 80630fdc7489SMatthew Knepley PetscInt pStart, pEnd, p, Nl, l, m; 80640fdc7489SMatthew Knepley PetscErrorCode ierr; 80650fdc7489SMatthew Knepley 80660fdc7489SMatthew Knepley PetscFunctionBegin; 80670fdc7489SMatthew Knepley ierr = PetscMalloc1(1, &ul);CHKERRQ(ierr); 80680fdc7489SMatthew Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, "universal", &ul->label);CHKERRQ(ierr); 80690fdc7489SMatthew Knepley ierr = DMGetNumLabels(dm, &Nl);CHKERRQ(ierr); 80700fdc7489SMatthew Knepley ierr = PetscCalloc1(Nl, &active);CHKERRQ(ierr); 80710fdc7489SMatthew Knepley ul->Nl = 0; 80720fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 80730fdc7489SMatthew Knepley PetscBool isdepth, iscelltype; 80740fdc7489SMatthew Knepley const char *name; 80750fdc7489SMatthew Knepley 80760fdc7489SMatthew Knepley ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 80770fdc7489SMatthew Knepley ierr = PetscStrncmp(name, "depth", 6, &isdepth);CHKERRQ(ierr); 80780fdc7489SMatthew Knepley ierr = PetscStrncmp(name, "celltype", 9, &iscelltype);CHKERRQ(ierr); 80790fdc7489SMatthew Knepley active[l] = !(isdepth || iscelltype) ? PETSC_TRUE : PETSC_FALSE; 80800fdc7489SMatthew Knepley if (active[l]) ++ul->Nl; 80810fdc7489SMatthew Knepley } 80820fdc7489SMatthew Knepley ierr = PetscCalloc5(ul->Nl, &ul->names, ul->Nl, &ul->indices, ul->Nl+1, &ul->offsets, ul->Nl+1, &ul->bits, ul->Nl, &ul->masks);CHKERRQ(ierr); 80830fdc7489SMatthew Knepley ul->Nv = 0; 80840fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 80850fdc7489SMatthew Knepley DMLabel label; 80860fdc7489SMatthew Knepley PetscInt nv; 80870fdc7489SMatthew Knepley const char *name; 80880fdc7489SMatthew Knepley 80890fdc7489SMatthew Knepley if (!active[l]) continue; 80900fdc7489SMatthew Knepley ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 80910fdc7489SMatthew Knepley ierr = DMGetLabelByNum(dm, l, &label);CHKERRQ(ierr); 80920fdc7489SMatthew Knepley ierr = DMLabelGetNumValues(label, &nv);CHKERRQ(ierr); 80930fdc7489SMatthew Knepley ierr = PetscStrallocpy(name, &ul->names[m]);CHKERRQ(ierr); 80940fdc7489SMatthew Knepley ul->indices[m] = l; 80950fdc7489SMatthew Knepley ul->Nv += nv; 80960fdc7489SMatthew Knepley ul->offsets[m+1] = nv; 80970fdc7489SMatthew Knepley ul->bits[m+1] = PetscCeilReal(PetscLog2Real(nv+1)); 80980fdc7489SMatthew Knepley ++m; 80990fdc7489SMatthew Knepley } 81000fdc7489SMatthew Knepley for (l = 1; l <= ul->Nl; ++l) { 81010fdc7489SMatthew Knepley ul->offsets[l] = ul->offsets[l-1] + ul->offsets[l]; 81020fdc7489SMatthew Knepley ul->bits[l] = ul->bits[l-1] + ul->bits[l]; 81030fdc7489SMatthew Knepley } 81040fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 81050fdc7489SMatthew Knepley PetscInt b; 81060fdc7489SMatthew Knepley 81070fdc7489SMatthew Knepley ul->masks[l] = 0; 81080fdc7489SMatthew Knepley for (b = ul->bits[l]; b < ul->bits[l+1]; ++b) ul->masks[l] |= 1 << b; 81090fdc7489SMatthew Knepley } 81100fdc7489SMatthew Knepley ierr = PetscMalloc1(ul->Nv, &ul->values);CHKERRQ(ierr); 81110fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 81120fdc7489SMatthew Knepley DMLabel label; 81130fdc7489SMatthew Knepley IS valueIS; 81140fdc7489SMatthew Knepley const PetscInt *varr; 81150fdc7489SMatthew Knepley PetscInt nv, v; 81160fdc7489SMatthew Knepley 81170fdc7489SMatthew Knepley if (!active[l]) continue; 81180fdc7489SMatthew Knepley ierr = DMGetLabelByNum(dm, l, &label);CHKERRQ(ierr); 81190fdc7489SMatthew Knepley ierr = DMLabelGetNumValues(label, &nv);CHKERRQ(ierr); 81200fdc7489SMatthew Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 81210fdc7489SMatthew Knepley ierr = ISGetIndices(valueIS, &varr);CHKERRQ(ierr); 81220fdc7489SMatthew Knepley for (v = 0; v < nv; ++v) { 81230fdc7489SMatthew Knepley ul->values[ul->offsets[m]+v] = varr[v]; 81240fdc7489SMatthew Knepley } 81250fdc7489SMatthew Knepley ierr = ISRestoreIndices(valueIS, &varr);CHKERRQ(ierr); 81260fdc7489SMatthew Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 81270fdc7489SMatthew Knepley ierr = PetscSortInt(nv, &ul->values[ul->offsets[m]]);CHKERRQ(ierr); 81280fdc7489SMatthew Knepley ++m; 81290fdc7489SMatthew Knepley } 81300fdc7489SMatthew Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 81310fdc7489SMatthew Knepley for (p = pStart; p < pEnd; ++p) { 81320fdc7489SMatthew Knepley PetscInt uval = 0; 81330fdc7489SMatthew Knepley PetscBool marked = PETSC_FALSE; 81340fdc7489SMatthew Knepley 81350fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 81360fdc7489SMatthew Knepley DMLabel label; 81370649b39aSStefano Zampini PetscInt val, defval, loc, nv; 81380fdc7489SMatthew Knepley 81390fdc7489SMatthew Knepley if (!active[l]) continue; 81400fdc7489SMatthew Knepley ierr = DMGetLabelByNum(dm, l, &label);CHKERRQ(ierr); 81410fdc7489SMatthew Knepley ierr = DMLabelGetValue(label, p, &val);CHKERRQ(ierr); 81420fdc7489SMatthew Knepley ierr = DMLabelGetDefaultValue(label, &defval);CHKERRQ(ierr); 81430fdc7489SMatthew Knepley if (val == defval) {++m; continue;} 81440649b39aSStefano Zampini nv = ul->offsets[m+1]-ul->offsets[m]; 81450fdc7489SMatthew Knepley marked = PETSC_TRUE; 81460fdc7489SMatthew Knepley ierr = PetscFindInt(val, nv, &ul->values[ul->offsets[m]], &loc);CHKERRQ(ierr); 81470fdc7489SMatthew Knepley if (loc < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Label value %D not found in compression array", val); 81480fdc7489SMatthew Knepley uval += (loc+1) << ul->bits[m]; 81490fdc7489SMatthew Knepley ++m; 81500fdc7489SMatthew Knepley } 81510fdc7489SMatthew Knepley if (marked) {ierr = DMLabelSetValue(ul->label, p, uval);CHKERRQ(ierr);} 81520fdc7489SMatthew Knepley } 81530fdc7489SMatthew Knepley ierr = PetscFree(active);CHKERRQ(ierr); 81540fdc7489SMatthew Knepley *universal = ul; 81550fdc7489SMatthew Knepley PetscFunctionReturn(0); 81560fdc7489SMatthew Knepley } 81570fdc7489SMatthew Knepley 81580fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelDestroy(DMUniversalLabel *universal) 81590fdc7489SMatthew Knepley { 81600fdc7489SMatthew Knepley PetscInt l; 81610fdc7489SMatthew Knepley PetscErrorCode ierr; 81620fdc7489SMatthew Knepley 81630fdc7489SMatthew Knepley PetscFunctionBegin; 81640fdc7489SMatthew Knepley for (l = 0; l < (*universal)->Nl; ++l) {ierr = PetscFree((*universal)->names[l]);CHKERRQ(ierr);} 81650fdc7489SMatthew Knepley ierr = DMLabelDestroy(&(*universal)->label);CHKERRQ(ierr); 81660fdc7489SMatthew Knepley ierr = PetscFree5((*universal)->names, (*universal)->indices, (*universal)->offsets, (*universal)->bits, (*universal)->masks);CHKERRQ(ierr); 81670fdc7489SMatthew Knepley ierr = PetscFree((*universal)->values);CHKERRQ(ierr); 81680fdc7489SMatthew Knepley ierr = PetscFree(*universal);CHKERRQ(ierr); 81690fdc7489SMatthew Knepley *universal = NULL; 81700fdc7489SMatthew Knepley PetscFunctionReturn(0); 81710fdc7489SMatthew Knepley } 81720fdc7489SMatthew Knepley 81730fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelGetLabel(DMUniversalLabel ul, DMLabel *ulabel) 81740fdc7489SMatthew Knepley { 81750fdc7489SMatthew Knepley PetscFunctionBegin; 81760fdc7489SMatthew Knepley PetscValidPointer(ulabel, 2); 81770fdc7489SMatthew Knepley *ulabel = ul->label; 81780fdc7489SMatthew Knepley PetscFunctionReturn(0); 81790fdc7489SMatthew Knepley } 81800fdc7489SMatthew Knepley 81810fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelCreateLabels(DMUniversalLabel ul, PetscBool preserveOrder, DM dm) 81820fdc7489SMatthew Knepley { 81830fdc7489SMatthew Knepley PetscInt Nl = ul->Nl, l; 81840fdc7489SMatthew Knepley PetscErrorCode ierr; 81850fdc7489SMatthew Knepley 81860fdc7489SMatthew Knepley PetscFunctionBegin; 81870fdc7489SMatthew Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 81880fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 81890fdc7489SMatthew Knepley if (preserveOrder) {ierr = DMCreateLabelAtIndex(dm, ul->indices[l], ul->names[l]);CHKERRQ(ierr);} 81900fdc7489SMatthew Knepley else {ierr = DMCreateLabel(dm, ul->names[l]);CHKERRQ(ierr);} 81910fdc7489SMatthew Knepley } 81920fdc7489SMatthew Knepley if (preserveOrder) { 81930fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 81940fdc7489SMatthew Knepley const char *name; 81950fdc7489SMatthew Knepley PetscBool match; 81960fdc7489SMatthew Knepley 81970fdc7489SMatthew Knepley ierr = DMGetLabelName(dm, ul->indices[l], &name);CHKERRQ(ierr); 81980fdc7489SMatthew Knepley ierr = PetscStrcmp(name, ul->names[l], &match);CHKERRQ(ierr); 81990fdc7489SMatthew Knepley if (!match) SETERRQ3(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Label %D name %s does not match new name %s", l, name, ul->names[l]); 82000fdc7489SMatthew Knepley } 82010fdc7489SMatthew Knepley } 82020fdc7489SMatthew Knepley PetscFunctionReturn(0); 82030fdc7489SMatthew Knepley } 82040fdc7489SMatthew Knepley 82050fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelSetLabelValue(DMUniversalLabel ul, DM dm, PetscBool useIndex, PetscInt p, PetscInt value) 82060fdc7489SMatthew Knepley { 82070fdc7489SMatthew Knepley PetscInt l; 82080fdc7489SMatthew Knepley PetscErrorCode ierr; 82090fdc7489SMatthew Knepley 82100fdc7489SMatthew Knepley PetscFunctionBegin; 82110fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 82120fdc7489SMatthew Knepley DMLabel label; 82130fdc7489SMatthew Knepley PetscInt lval = (value & ul->masks[l]) >> ul->bits[l]; 82140fdc7489SMatthew Knepley 82150fdc7489SMatthew Knepley if (lval) { 82160fdc7489SMatthew Knepley if (useIndex) {ierr = DMGetLabelByNum(dm, ul->indices[l], &label);CHKERRQ(ierr);} 82170fdc7489SMatthew Knepley else {ierr = DMGetLabel(dm, ul->names[l], &label);CHKERRQ(ierr);} 82180fdc7489SMatthew Knepley ierr = DMLabelSetValue(label, p, ul->values[ul->offsets[l]+lval-1]);CHKERRQ(ierr); 82190fdc7489SMatthew Knepley } 82200fdc7489SMatthew Knepley } 82210fdc7489SMatthew Knepley PetscFunctionReturn(0); 82220fdc7489SMatthew Knepley } 8223a8fb8f29SToby Isaac 8224a8fb8f29SToby Isaac /*@ 8225a8fb8f29SToby Isaac DMGetCoarseDM - Get the coarse mesh from which this was obtained by refinement 8226a8fb8f29SToby Isaac 8227a8fb8f29SToby Isaac Input Parameter: 8228a8fb8f29SToby Isaac . dm - The DM object 8229a8fb8f29SToby Isaac 8230a8fb8f29SToby Isaac Output Parameter: 8231a8fb8f29SToby Isaac . cdm - The coarse DM 8232a8fb8f29SToby Isaac 8233a8fb8f29SToby Isaac Level: intermediate 8234a8fb8f29SToby Isaac 8235a8fb8f29SToby Isaac .seealso: DMSetCoarseDM() 8236a8fb8f29SToby Isaac @*/ 8237a8fb8f29SToby Isaac PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm) 8238a8fb8f29SToby Isaac { 8239a8fb8f29SToby Isaac PetscFunctionBegin; 8240a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8241a8fb8f29SToby Isaac PetscValidPointer(cdm, 2); 8242a8fb8f29SToby Isaac *cdm = dm->coarseMesh; 8243a8fb8f29SToby Isaac PetscFunctionReturn(0); 8244a8fb8f29SToby Isaac } 8245a8fb8f29SToby Isaac 8246a8fb8f29SToby Isaac /*@ 8247a8fb8f29SToby Isaac DMSetCoarseDM - Set the coarse mesh from which this was obtained by refinement 8248a8fb8f29SToby Isaac 8249a8fb8f29SToby Isaac Input Parameters: 8250a8fb8f29SToby Isaac + dm - The DM object 8251a8fb8f29SToby Isaac - cdm - The coarse DM 8252a8fb8f29SToby Isaac 8253a8fb8f29SToby Isaac Level: intermediate 8254a8fb8f29SToby Isaac 8255a8fb8f29SToby Isaac .seealso: DMGetCoarseDM() 8256a8fb8f29SToby Isaac @*/ 8257a8fb8f29SToby Isaac PetscErrorCode DMSetCoarseDM(DM dm, DM cdm) 8258a8fb8f29SToby Isaac { 8259a8fb8f29SToby Isaac PetscErrorCode ierr; 8260a8fb8f29SToby Isaac 8261a8fb8f29SToby Isaac PetscFunctionBegin; 8262a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8263a8fb8f29SToby Isaac if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 8264a8fb8f29SToby Isaac ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr); 8265a8fb8f29SToby Isaac ierr = DMDestroy(&dm->coarseMesh);CHKERRQ(ierr); 8266a8fb8f29SToby Isaac dm->coarseMesh = cdm; 8267a8fb8f29SToby Isaac PetscFunctionReturn(0); 8268a8fb8f29SToby Isaac } 8269a8fb8f29SToby Isaac 827088bdff64SToby Isaac /*@ 827188bdff64SToby Isaac DMGetFineDM - Get the fine mesh from which this was obtained by refinement 827288bdff64SToby Isaac 827388bdff64SToby Isaac Input Parameter: 827488bdff64SToby Isaac . dm - The DM object 827588bdff64SToby Isaac 827688bdff64SToby Isaac Output Parameter: 827788bdff64SToby Isaac . fdm - The fine DM 827888bdff64SToby Isaac 827988bdff64SToby Isaac Level: intermediate 828088bdff64SToby Isaac 828188bdff64SToby Isaac .seealso: DMSetFineDM() 828288bdff64SToby Isaac @*/ 828388bdff64SToby Isaac PetscErrorCode DMGetFineDM(DM dm, DM *fdm) 828488bdff64SToby Isaac { 828588bdff64SToby Isaac PetscFunctionBegin; 828688bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 828788bdff64SToby Isaac PetscValidPointer(fdm, 2); 828888bdff64SToby Isaac *fdm = dm->fineMesh; 828988bdff64SToby Isaac PetscFunctionReturn(0); 829088bdff64SToby Isaac } 829188bdff64SToby Isaac 829288bdff64SToby Isaac /*@ 829388bdff64SToby Isaac DMSetFineDM - Set the fine mesh from which this was obtained by refinement 829488bdff64SToby Isaac 829588bdff64SToby Isaac Input Parameters: 829688bdff64SToby Isaac + dm - The DM object 829788bdff64SToby Isaac - fdm - The fine DM 829888bdff64SToby Isaac 829988bdff64SToby Isaac Level: intermediate 830088bdff64SToby Isaac 830188bdff64SToby Isaac .seealso: DMGetFineDM() 830288bdff64SToby Isaac @*/ 830388bdff64SToby Isaac PetscErrorCode DMSetFineDM(DM dm, DM fdm) 830488bdff64SToby Isaac { 830588bdff64SToby Isaac PetscErrorCode ierr; 830688bdff64SToby Isaac 830788bdff64SToby Isaac PetscFunctionBegin; 830888bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 830988bdff64SToby Isaac if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2); 831088bdff64SToby Isaac ierr = PetscObjectReference((PetscObject)fdm);CHKERRQ(ierr); 831188bdff64SToby Isaac ierr = DMDestroy(&dm->fineMesh);CHKERRQ(ierr); 831288bdff64SToby Isaac dm->fineMesh = fdm; 831388bdff64SToby Isaac PetscFunctionReturn(0); 831488bdff64SToby Isaac } 831588bdff64SToby Isaac 8316a6ba4734SToby Isaac /*=== DMBoundary code ===*/ 8317a6ba4734SToby Isaac 8318a6ba4734SToby Isaac PetscErrorCode DMCopyBoundary(DM dm, DM dmNew) 8319a6ba4734SToby Isaac { 8320e5e52638SMatthew G. Knepley PetscInt d; 8321a6ba4734SToby Isaac PetscErrorCode ierr; 8322a6ba4734SToby Isaac 8323a6ba4734SToby Isaac PetscFunctionBegin; 8324e5e52638SMatthew G. Knepley for (d = 0; d < dm->Nds; ++d) { 832536951cb5SMatthew G. Knepley ierr = PetscDSCopyBoundary(dm->probs[d].ds, PETSC_DETERMINE, NULL, dmNew->probs[d].ds);CHKERRQ(ierr); 8326e5e52638SMatthew G. Knepley } 8327a6ba4734SToby Isaac PetscFunctionReturn(0); 8328a6ba4734SToby Isaac } 8329a6ba4734SToby Isaac 8330a6ba4734SToby Isaac /*@C 8331a6ba4734SToby Isaac DMAddBoundary - Add a boundary condition to the model 8332a6ba4734SToby Isaac 8333783e2ec8SMatthew G. Knepley Collective on dm 8334783e2ec8SMatthew G. Knepley 8335a6ba4734SToby Isaac Input Parameters: 83364c258f51SMatthew G. Knepley + dm - The DM, with a PetscDS that matches the problem being constrained 8337f971fd6bSMatthew G. Knepley . type - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann) 8338a6ba4734SToby Isaac . name - The BC name 8339a6ba4734SToby Isaac . labelname - The label defining constrained points 8340a6ba4734SToby Isaac . field - The field to constrain 8341e8ecbf3fSStefano Zampini . numcomps - The number of constrained field components (0 will constrain all fields) 8342a6ba4734SToby Isaac . comps - An array of constrained component numbers 8343a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 834456cf3b9cSMatthew G. Knepley . bcFunc_t - A pointwise function giving the time deriative of the boundary values, or NULL 8345a6ba4734SToby Isaac . numids - The number of DMLabel ids for constrained points 8346a6ba4734SToby Isaac . ids - An array of ids for constrained points 8347a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 8348a6ba4734SToby Isaac 8349a6ba4734SToby Isaac Options Database Keys: 8350a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 8351a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 8352a6ba4734SToby Isaac 835356cf3b9cSMatthew G. Knepley Note: 835456cf3b9cSMatthew G. Knepley Both bcFunc abd bcFunc_t will depend on the boundary condition type. If the type if DM_BC_ESSENTIAL, Then the calling sequence is: 835556cf3b9cSMatthew G. Knepley 835656cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[]) 835756cf3b9cSMatthew G. Knepley 835856cf3b9cSMatthew G. Knepley If the type is DM_BC_ESSENTIAL_FIELD or other _FIELD value, then the calling sequence is: 835956cf3b9cSMatthew G. Knepley 836056cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux, 836156cf3b9cSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 836256cf3b9cSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 836356cf3b9cSMatthew G. Knepley $ PetscReal time, const PetscReal x[], PetscScalar bcval[]) 836456cf3b9cSMatthew G. Knepley 836556cf3b9cSMatthew G. Knepley + dim - the spatial dimension 836656cf3b9cSMatthew G. Knepley . Nf - the number of fields 836756cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field 836856cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field 836956cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point 837056cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point 837156cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point 837256cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field 837356cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field 837456cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point 837556cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point 837656cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point 837756cf3b9cSMatthew G. Knepley . t - current time 837856cf3b9cSMatthew G. Knepley . x - coordinates of the current point 837956cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters 838056cf3b9cSMatthew G. Knepley . constants - constant parameters 838156cf3b9cSMatthew G. Knepley - bcval - output values at the current point 838256cf3b9cSMatthew G. Knepley 8383a6ba4734SToby Isaac Level: developer 8384a6ba4734SToby Isaac 838556cf3b9cSMatthew G. Knepley .seealso: DMGetBoundary(), PetscDSAddBoundary() 8386a6ba4734SToby Isaac @*/ 838756cf3b9cSMatthew G. Knepley PetscErrorCode DMAddBoundary(DM dm, DMBoundaryConditionType type, const char name[], const char labelname[], PetscInt field, PetscInt numcomps, const PetscInt *comps, void (*bcFunc)(void), void (*bcFunc_t)(void), PetscInt numids, const PetscInt *ids, void *ctx) 8388a6ba4734SToby Isaac { 8389e5e52638SMatthew G. Knepley PetscDS ds; 8390a6ba4734SToby Isaac PetscErrorCode ierr; 8391a6ba4734SToby Isaac 8392a6ba4734SToby Isaac PetscFunctionBegin; 8393a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8394783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveEnum(dm, type, 2); 8395783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, field, 5); 8396783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, numcomps, 6); 8397783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, numids, 9); 8398e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 8399783e2ec8SMatthew G. Knepley ierr = DMCompleteBoundaryLabel_Internal(dm, ds, field, PETSC_MAX_INT, labelname);CHKERRQ(ierr); 840056cf3b9cSMatthew G. Knepley ierr = PetscDSAddBoundary(ds, type,name, labelname, field, numcomps, comps, bcFunc, bcFunc_t, numids, ids, ctx);CHKERRQ(ierr); 8401a6ba4734SToby Isaac PetscFunctionReturn(0); 8402a6ba4734SToby Isaac } 8403a6ba4734SToby Isaac 8404a6ba4734SToby Isaac /*@ 8405a6ba4734SToby Isaac DMGetNumBoundary - Get the number of registered BC 8406a6ba4734SToby Isaac 8407a6ba4734SToby Isaac Input Parameters: 8408a6ba4734SToby Isaac . dm - The mesh object 8409a6ba4734SToby Isaac 8410a6ba4734SToby Isaac Output Parameters: 8411a6ba4734SToby Isaac . numBd - The number of BC 8412a6ba4734SToby Isaac 8413a6ba4734SToby Isaac Level: intermediate 8414a6ba4734SToby Isaac 8415a6ba4734SToby Isaac .seealso: DMAddBoundary(), DMGetBoundary() 8416a6ba4734SToby Isaac @*/ 8417a6ba4734SToby Isaac PetscErrorCode DMGetNumBoundary(DM dm, PetscInt *numBd) 8418a6ba4734SToby Isaac { 8419e5e52638SMatthew G. Knepley PetscDS ds; 842058ebd649SToby Isaac PetscErrorCode ierr; 8421a6ba4734SToby Isaac 8422a6ba4734SToby Isaac PetscFunctionBegin; 8423a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8424e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 8425e5e52638SMatthew G. Knepley ierr = PetscDSGetNumBoundary(ds, numBd);CHKERRQ(ierr); 8426a6ba4734SToby Isaac PetscFunctionReturn(0); 8427a6ba4734SToby Isaac } 8428a6ba4734SToby Isaac 8429a6ba4734SToby Isaac /*@C 84301c531cf8SMatthew G. Knepley DMGetBoundary - Get a model boundary condition 8431a6ba4734SToby Isaac 8432a6ba4734SToby Isaac Input Parameters: 8433a6ba4734SToby Isaac + dm - The mesh object 8434a6ba4734SToby Isaac - bd - The BC number 8435a6ba4734SToby Isaac 8436a6ba4734SToby Isaac Output Parameters: 8437f971fd6bSMatthew G. Knepley + type - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann) 8438a6ba4734SToby Isaac . name - The BC name 8439a6ba4734SToby Isaac . labelname - The label defining constrained points 8440a6ba4734SToby Isaac . field - The field to constrain 8441a6ba4734SToby Isaac . numcomps - The number of constrained field components 8442a6ba4734SToby Isaac . comps - An array of constrained component numbers 8443a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 844456cf3b9cSMatthew G. Knepley . bcFunc_t - A pointwise function giving the time derviative of the boundary values 8445a6ba4734SToby Isaac . numids - The number of DMLabel ids for constrained points 8446a6ba4734SToby Isaac . ids - An array of ids for constrained points 8447a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 8448a6ba4734SToby Isaac 8449a6ba4734SToby Isaac Options Database Keys: 8450a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 8451a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 8452a6ba4734SToby Isaac 8453a6ba4734SToby Isaac Level: developer 8454a6ba4734SToby Isaac 8455a6ba4734SToby Isaac .seealso: DMAddBoundary() 8456a6ba4734SToby Isaac @*/ 845756cf3b9cSMatthew G. Knepley PetscErrorCode DMGetBoundary(DM dm, PetscInt bd, DMBoundaryConditionType *type, const char **name, const char **labelname, PetscInt *field, PetscInt *numcomps, const PetscInt **comps, void (**func)(void), void (**func_t)(void), PetscInt *numids, const PetscInt **ids, void **ctx) 8458a6ba4734SToby Isaac { 8459e5e52638SMatthew G. Knepley PetscDS ds; 846058ebd649SToby Isaac PetscErrorCode ierr; 8461a6ba4734SToby Isaac 8462a6ba4734SToby Isaac PetscFunctionBegin; 8463a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8464e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 846556cf3b9cSMatthew G. Knepley ierr = PetscDSGetBoundary(ds, bd, type, name, labelname, field, numcomps, comps, func, func_t, numids, ids, ctx);CHKERRQ(ierr); 8466a6ba4734SToby Isaac PetscFunctionReturn(0); 8467a6ba4734SToby Isaac } 8468a6ba4734SToby Isaac 8469e6f8dbb6SToby Isaac static PetscErrorCode DMPopulateBoundary(DM dm) 8470e6f8dbb6SToby Isaac { 8471e5e52638SMatthew G. Knepley PetscDS ds; 8472dff059c6SToby Isaac DMBoundary *lastnext; 8473e6f8dbb6SToby Isaac DSBoundary dsbound; 8474e6f8dbb6SToby Isaac PetscErrorCode ierr; 8475e6f8dbb6SToby Isaac 8476e6f8dbb6SToby Isaac PetscFunctionBegin; 8477e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 8478e5e52638SMatthew G. Knepley dsbound = ds->boundary; 847947a1f5adSToby Isaac if (dm->boundary) { 848047a1f5adSToby Isaac DMBoundary next = dm->boundary; 848147a1f5adSToby Isaac 848247a1f5adSToby Isaac /* quick check to see if the PetscDS has changed */ 848347a1f5adSToby Isaac if (next->dsboundary == dsbound) PetscFunctionReturn(0); 848447a1f5adSToby Isaac /* the PetscDS has changed: tear down and rebuild */ 848547a1f5adSToby Isaac while (next) { 848647a1f5adSToby Isaac DMBoundary b = next; 848747a1f5adSToby Isaac 848847a1f5adSToby Isaac next = b->next; 848947a1f5adSToby Isaac ierr = PetscFree(b);CHKERRQ(ierr); 8490a6ba4734SToby Isaac } 849147a1f5adSToby Isaac dm->boundary = NULL; 8492a6ba4734SToby Isaac } 849347a1f5adSToby Isaac 8494dff059c6SToby Isaac lastnext = &(dm->boundary); 8495e6f8dbb6SToby Isaac while (dsbound) { 8496e6f8dbb6SToby Isaac DMBoundary dmbound; 8497e6f8dbb6SToby Isaac 8498e6f8dbb6SToby Isaac ierr = PetscNew(&dmbound);CHKERRQ(ierr); 8499e6f8dbb6SToby Isaac dmbound->dsboundary = dsbound; 8500e6f8dbb6SToby Isaac ierr = DMGetLabel(dm, dsbound->labelname, &(dmbound->label));CHKERRQ(ierr); 8501994fe344SLisandro 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);} 850247a1f5adSToby Isaac /* push on the back instead of the front so that it is in the same order as in the PetscDS */ 8503dff059c6SToby Isaac *lastnext = dmbound; 8504dff059c6SToby Isaac lastnext = &(dmbound->next); 8505dff059c6SToby Isaac dsbound = dsbound->next; 8506a6ba4734SToby Isaac } 8507a6ba4734SToby Isaac PetscFunctionReturn(0); 8508a6ba4734SToby Isaac } 8509a6ba4734SToby Isaac 8510a6ba4734SToby Isaac PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd) 8511a6ba4734SToby Isaac { 8512b95f2879SToby Isaac DMBoundary b; 8513a6ba4734SToby Isaac PetscErrorCode ierr; 8514a6ba4734SToby Isaac 8515a6ba4734SToby Isaac PetscFunctionBegin; 8516a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8517534a8f05SLisandro Dalcin PetscValidBoolPointer(isBd, 3); 8518a6ba4734SToby Isaac *isBd = PETSC_FALSE; 8519e6f8dbb6SToby Isaac ierr = DMPopulateBoundary(dm);CHKERRQ(ierr); 8520b95f2879SToby Isaac b = dm->boundary; 8521a6ba4734SToby Isaac while (b && !(*isBd)) { 8522e6f8dbb6SToby Isaac DMLabel label = b->label; 8523e6f8dbb6SToby Isaac DSBoundary dsb = b->dsboundary; 85243424c85cSToby Isaac 85253424c85cSToby Isaac if (label) { 8526a6ba4734SToby Isaac PetscInt i; 8527a6ba4734SToby Isaac 8528e6f8dbb6SToby Isaac for (i = 0; i < dsb->numids && !(*isBd); ++i) { 8529e6f8dbb6SToby Isaac ierr = DMLabelStratumHasPoint(label, dsb->ids[i], point, isBd);CHKERRQ(ierr); 8530a6ba4734SToby Isaac } 8531a6ba4734SToby Isaac } 8532a6ba4734SToby Isaac b = b->next; 8533a6ba4734SToby Isaac } 8534a6ba4734SToby Isaac PetscFunctionReturn(0); 8535a6ba4734SToby Isaac } 85364d6f44ffSToby Isaac 85374d6f44ffSToby Isaac /*@C 8538a6e0b375SMatthew G. Knepley DMProjectFunction - This projects the given function into the function space provided, putting the coefficients in a global vector. 8539a6e0b375SMatthew G. Knepley 8540a6e0b375SMatthew G. Knepley Collective on DM 85414d6f44ffSToby Isaac 85424d6f44ffSToby Isaac Input Parameters: 85434d6f44ffSToby Isaac + dm - The DM 85440709b2feSToby Isaac . time - The time 85454d6f44ffSToby Isaac . funcs - The coordinate functions to evaluate, one per field 85464d6f44ffSToby Isaac . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 85474d6f44ffSToby Isaac - mode - The insertion mode for values 85484d6f44ffSToby Isaac 85494d6f44ffSToby Isaac Output Parameter: 85504d6f44ffSToby Isaac . X - vector 85514d6f44ffSToby Isaac 85524d6f44ffSToby Isaac Calling sequence of func: 85530709b2feSToby Isaac $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 85544d6f44ffSToby Isaac 85554d6f44ffSToby Isaac + dim - The spatial dimension 85568ec8862eSJed Brown . time - The time at which to sample 85574d6f44ffSToby Isaac . x - The coordinates 85584d6f44ffSToby Isaac . Nf - The number of fields 85594d6f44ffSToby Isaac . u - The output field values 85604d6f44ffSToby Isaac - ctx - optional user-defined function context 85614d6f44ffSToby Isaac 85624d6f44ffSToby Isaac Level: developer 85634d6f44ffSToby Isaac 8564a6e0b375SMatthew G. Knepley .seealso: DMProjectFunctionLocal(), DMProjectFunctionLabel(), DMComputeL2Diff() 85654d6f44ffSToby Isaac @*/ 85660709b2feSToby Isaac PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X) 85674d6f44ffSToby Isaac { 85684d6f44ffSToby Isaac Vec localX; 85694d6f44ffSToby Isaac PetscErrorCode ierr; 85704d6f44ffSToby Isaac 85714d6f44ffSToby Isaac PetscFunctionBegin; 85724d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 85734d6f44ffSToby Isaac ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr); 85740709b2feSToby Isaac ierr = DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr); 85754d6f44ffSToby Isaac ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr); 85764d6f44ffSToby Isaac ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr); 85774d6f44ffSToby Isaac ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr); 85784d6f44ffSToby Isaac PetscFunctionReturn(0); 85794d6f44ffSToby Isaac } 85804d6f44ffSToby Isaac 8581a6e0b375SMatthew G. Knepley /*@C 8582a6e0b375SMatthew G. Knepley DMProjectFunctionLocal - This projects the given function into the function space provided, putting the coefficients in a local vector. 8583a6e0b375SMatthew G. Knepley 8584a6e0b375SMatthew G. Knepley Not collective 8585a6e0b375SMatthew G. Knepley 8586a6e0b375SMatthew G. Knepley Input Parameters: 8587a6e0b375SMatthew G. Knepley + dm - The DM 8588a6e0b375SMatthew G. Knepley . time - The time 8589a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8590a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8591a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8592a6e0b375SMatthew G. Knepley 8593a6e0b375SMatthew G. Knepley Output Parameter: 8594a6e0b375SMatthew G. Knepley . localX - vector 8595a6e0b375SMatthew G. Knepley 8596a6e0b375SMatthew G. Knepley Calling sequence of func: 8597a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 8598a6e0b375SMatthew G. Knepley 8599a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8600a6e0b375SMatthew G. Knepley . x - The coordinates 8601a6e0b375SMatthew G. Knepley . Nf - The number of fields 8602a6e0b375SMatthew G. Knepley . u - The output field values 8603a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8604a6e0b375SMatthew G. Knepley 8605a6e0b375SMatthew G. Knepley Level: developer 8606a6e0b375SMatthew G. Knepley 8607a6e0b375SMatthew G. Knepley .seealso: DMProjectFunction(), DMProjectFunctionLabel(), DMComputeL2Diff() 8608a6e0b375SMatthew G. Knepley @*/ 86090709b2feSToby Isaac PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 86104d6f44ffSToby Isaac { 86114d6f44ffSToby Isaac PetscErrorCode ierr; 86124d6f44ffSToby Isaac 86134d6f44ffSToby Isaac PetscFunctionBegin; 86144d6f44ffSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 86154d6f44ffSToby Isaac PetscValidHeaderSpecific(localX,VEC_CLASSID,5); 86160918c465SMatthew G. Knepley if (!dm->ops->projectfunctionlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLocal",((PetscObject)dm)->type_name); 86170709b2feSToby Isaac ierr = (dm->ops->projectfunctionlocal) (dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr); 86184d6f44ffSToby Isaac PetscFunctionReturn(0); 86194d6f44ffSToby Isaac } 86204d6f44ffSToby Isaac 8621a6e0b375SMatthew G. Knepley /*@C 8622a6e0b375SMatthew G. Knepley DMProjectFunctionLabel - This projects the given function into the function space provided, putting the coefficients in a global vector, setting values only for points in the given label. 8623a6e0b375SMatthew G. Knepley 8624a6e0b375SMatthew G. Knepley Collective on DM 8625a6e0b375SMatthew G. Knepley 8626a6e0b375SMatthew G. Knepley Input Parameters: 8627a6e0b375SMatthew G. Knepley + dm - The DM 8628a6e0b375SMatthew G. Knepley . time - The time 8629a6e0b375SMatthew G. Knepley . label - The DMLabel selecting the portion of the mesh for projection 8630a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8631a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8632a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8633a6e0b375SMatthew G. Knepley 8634a6e0b375SMatthew G. Knepley Output Parameter: 8635a6e0b375SMatthew G. Knepley . X - vector 8636a6e0b375SMatthew G. Knepley 8637a6e0b375SMatthew G. Knepley Calling sequence of func: 8638a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 8639a6e0b375SMatthew G. Knepley 8640a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8641a6e0b375SMatthew G. Knepley . x - The coordinates 8642a6e0b375SMatthew G. Knepley . Nf - The number of fields 8643a6e0b375SMatthew G. Knepley . u - The output field values 8644a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8645a6e0b375SMatthew G. Knepley 8646a6e0b375SMatthew G. Knepley Level: developer 8647a6e0b375SMatthew G. Knepley 8648a6e0b375SMatthew G. Knepley .seealso: DMProjectFunction(), DMProjectFunctionLocal(), DMProjectFunctionLabelLocal(), DMComputeL2Diff() 8649a6e0b375SMatthew G. Knepley @*/ 86502c53366bSMatthew 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) 86512c53366bSMatthew G. Knepley { 86522c53366bSMatthew G. Knepley Vec localX; 86532c53366bSMatthew G. Knepley PetscErrorCode ierr; 86542c53366bSMatthew G. Knepley 86552c53366bSMatthew G. Knepley PetscFunctionBegin; 86562c53366bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 86572c53366bSMatthew G. Knepley ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr); 86582c53366bSMatthew G. Knepley ierr = DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr); 86592c53366bSMatthew G. Knepley ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr); 86602c53366bSMatthew G. Knepley ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr); 86612c53366bSMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr); 86622c53366bSMatthew G. Knepley PetscFunctionReturn(0); 86632c53366bSMatthew G. Knepley } 86642c53366bSMatthew G. Knepley 8665a6e0b375SMatthew G. Knepley /*@C 8666a6e0b375SMatthew G. Knepley DMProjectFunctionLabelLocal - This projects the given function into the function space provided, putting the coefficients in a local vector, setting values only for points in the given label. 8667a6e0b375SMatthew G. Knepley 8668a6e0b375SMatthew G. Knepley Not collective 8669a6e0b375SMatthew G. Knepley 8670a6e0b375SMatthew G. Knepley Input Parameters: 8671a6e0b375SMatthew G. Knepley + dm - The DM 8672a6e0b375SMatthew G. Knepley . time - The time 8673a6e0b375SMatthew G. Knepley . label - The DMLabel selecting the portion of the mesh for projection 8674a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8675a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8676a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8677a6e0b375SMatthew G. Knepley 8678a6e0b375SMatthew G. Knepley Output Parameter: 8679a6e0b375SMatthew G. Knepley . localX - vector 8680a6e0b375SMatthew G. Knepley 8681a6e0b375SMatthew G. Knepley Calling sequence of func: 8682a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 8683a6e0b375SMatthew G. Knepley 8684a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8685a6e0b375SMatthew G. Knepley . x - The coordinates 8686a6e0b375SMatthew G. Knepley . Nf - The number of fields 8687a6e0b375SMatthew G. Knepley . u - The output field values 8688a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8689a6e0b375SMatthew G. Knepley 8690a6e0b375SMatthew G. Knepley Level: developer 8691a6e0b375SMatthew G. Knepley 8692a6e0b375SMatthew G. Knepley .seealso: DMProjectFunction(), DMProjectFunctionLocal(), DMProjectFunctionLabel(), DMComputeL2Diff() 8693a6e0b375SMatthew G. Knepley @*/ 86941c531cf8SMatthew 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) 86954d6f44ffSToby Isaac { 86964d6f44ffSToby Isaac PetscErrorCode ierr; 86974d6f44ffSToby Isaac 86984d6f44ffSToby Isaac PetscFunctionBegin; 86994d6f44ffSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 87004d6f44ffSToby Isaac PetscValidHeaderSpecific(localX,VEC_CLASSID,5); 87010918c465SMatthew G. Knepley if (!dm->ops->projectfunctionlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLabelLocal",((PetscObject)dm)->type_name); 87021c531cf8SMatthew G. Knepley ierr = (dm->ops->projectfunctionlabellocal) (dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr); 87034d6f44ffSToby Isaac PetscFunctionReturn(0); 87044d6f44ffSToby Isaac } 87052716604bSToby Isaac 8706a6e0b375SMatthew G. Knepley /*@C 8707a6e0b375SMatthew G. Knepley DMProjectFieldLocal - This projects the given function of the input fields into the function space provided, putting the coefficients in a local vector. 8708a6e0b375SMatthew G. Knepley 8709a6e0b375SMatthew G. Knepley Not collective 8710a6e0b375SMatthew G. Knepley 8711a6e0b375SMatthew G. Knepley Input Parameters: 8712a6e0b375SMatthew G. Knepley + dm - The DM 8713a6e0b375SMatthew G. Knepley . time - The time 8714a6e0b375SMatthew G. Knepley . localU - The input field vector 8715a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8716a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8717a6e0b375SMatthew G. Knepley 8718a6e0b375SMatthew G. Knepley Output Parameter: 8719a6e0b375SMatthew G. Knepley . localX - The output vector 8720a6e0b375SMatthew G. Knepley 8721a6e0b375SMatthew G. Knepley Calling sequence of func: 8722a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8723a6e0b375SMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8724a6e0b375SMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8725a6e0b375SMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8726a6e0b375SMatthew G. Knepley 8727a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8728a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8729a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8730a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8731a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8732a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8733a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8734a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8735a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8736a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8737a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8738a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8739a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8740a6e0b375SMatthew G. Knepley . t - The current time 8741a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8742a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8743a6e0b375SMatthew G. Knepley . constants - The value of each constant 8744a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8745a6e0b375SMatthew G. Knepley 8746a6e0b375SMatthew G. Knepley Note: There are three different DMs that potentially interact in this function. The output DM, dm, specifies the layout of the values calculates by funcs. 8747a6e0b375SMatthew G. Knepley The input DM, attached to U, may be different. For example, you can input the solution over the full domain, but output over a piece of the boundary, or 8748a6e0b375SMatthew G. Knepley a subdomain. You can also output a different number of fields than the input, with different discretizations. Last the auxiliary DM, attached to the 8749a6e0b375SMatthew G. Knepley auxiliary field vector, which is attached to dm, can also be different. It can have a different topology, number of fields, and discretizations. 8750a6e0b375SMatthew G. Knepley 8751a6e0b375SMatthew G. Knepley Level: intermediate 8752a6e0b375SMatthew G. Knepley 8753a6e0b375SMatthew G. Knepley .seealso: DMProjectField(), DMProjectFieldLabelLocal(), DMProjectFunction(), DMComputeL2Diff() 8754a6e0b375SMatthew G. Knepley @*/ 87558c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal(DM dm, PetscReal time, Vec localU, 87568c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 87578c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 87588c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8759191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 87608c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 87618c6c5593SMatthew G. Knepley { 87628c6c5593SMatthew G. Knepley PetscErrorCode ierr; 87638c6c5593SMatthew G. Knepley 87648c6c5593SMatthew G. Knepley PetscFunctionBegin; 87658c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 87668c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,3); 87678c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,6); 87680918c465SMatthew G. Knepley if (!dm->ops->projectfieldlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name); 87698c6c5593SMatthew G. Knepley ierr = (dm->ops->projectfieldlocal) (dm, time, localU, funcs, mode, localX);CHKERRQ(ierr); 87708c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 87718c6c5593SMatthew G. Knepley } 87728c6c5593SMatthew G. Knepley 8773a6e0b375SMatthew G. Knepley /*@C 8774a6e0b375SMatthew G. Knepley DMProjectFieldLabelLocal - This projects the given function of the input fields into the function space provided, putting the coefficients in a local vector, calculating only over the portion of the domain specified by the label. 8775a6e0b375SMatthew G. Knepley 8776a6e0b375SMatthew G. Knepley Not collective 8777a6e0b375SMatthew G. Knepley 8778a6e0b375SMatthew G. Knepley Input Parameters: 8779a6e0b375SMatthew G. Knepley + dm - The DM 8780a6e0b375SMatthew G. Knepley . time - The time 8781a6e0b375SMatthew G. Knepley . label - The DMLabel marking the portion of the domain to output 8782a6e0b375SMatthew G. Knepley . numIds - The number of label ids to use 8783a6e0b375SMatthew G. Knepley . ids - The label ids to use for marking 8784a6e0b375SMatthew G. Knepley . Nc - The number of components to set in the output, or PETSC_DETERMINE for all components 8785a6e0b375SMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8786a6e0b375SMatthew G. Knepley . localU - The input field vector 8787a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8788a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8789a6e0b375SMatthew G. Knepley 8790a6e0b375SMatthew G. Knepley Output Parameter: 8791a6e0b375SMatthew G. Knepley . localX - The output vector 8792a6e0b375SMatthew G. Knepley 8793a6e0b375SMatthew G. Knepley Calling sequence of func: 8794a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8795a6e0b375SMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8796a6e0b375SMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8797a6e0b375SMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8798a6e0b375SMatthew G. Knepley 8799a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8800a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8801a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8802a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8803a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8804a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8805a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8806a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8807a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8808a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8809a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8810a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8811a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8812a6e0b375SMatthew G. Knepley . t - The current time 8813a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8814a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8815a6e0b375SMatthew G. Knepley . constants - The value of each constant 8816a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8817a6e0b375SMatthew G. Knepley 8818a6e0b375SMatthew G. Knepley Note: There are three different DMs that potentially interact in this function. The output DM, dm, specifies the layout of the values calculates by funcs. 8819a6e0b375SMatthew G. Knepley The input DM, attached to U, may be different. For example, you can input the solution over the full domain, but output over a piece of the boundary, or 8820a6e0b375SMatthew G. Knepley a subdomain. You can also output a different number of fields than the input, with different discretizations. Last the auxiliary DM, attached to the 8821a6e0b375SMatthew G. Knepley auxiliary field vector, which is attached to dm, can also be different. It can have a different topology, number of fields, and discretizations. 8822a6e0b375SMatthew G. Knepley 8823a6e0b375SMatthew G. Knepley Level: intermediate 8824a6e0b375SMatthew G. Knepley 8825a6e0b375SMatthew G. Knepley .seealso: DMProjectField(), DMProjectFieldLabelLocal(), DMProjectFunction(), DMComputeL2Diff() 8826a6e0b375SMatthew G. Knepley @*/ 88271c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, 88288c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 88298c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 88308c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8831191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 88328c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 88338c6c5593SMatthew G. Knepley { 88348c6c5593SMatthew G. Knepley PetscErrorCode ierr; 88358c6c5593SMatthew G. Knepley 88368c6c5593SMatthew G. Knepley PetscFunctionBegin; 88378c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 88388c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,6); 88398c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,9); 8840ece3a9fcSMatthew G. Knepley if (!dm->ops->projectfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLabelLocal",((PetscObject)dm)->type_name); 88411c531cf8SMatthew G. Knepley ierr = (dm->ops->projectfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX);CHKERRQ(ierr); 88428c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 88438c6c5593SMatthew G. Knepley } 88448c6c5593SMatthew G. Knepley 88452716604bSToby Isaac /*@C 8846ece3a9fcSMatthew G. Knepley DMProjectBdFieldLabelLocal - This projects the given function of the input fields into the function space provided, putting the coefficients in a local vector, calculating only over the portion of the domain boundary specified by the label. 8847ece3a9fcSMatthew G. Knepley 8848ece3a9fcSMatthew G. Knepley Not collective 8849ece3a9fcSMatthew G. Knepley 8850ece3a9fcSMatthew G. Knepley Input Parameters: 8851ece3a9fcSMatthew G. Knepley + dm - The DM 8852ece3a9fcSMatthew G. Knepley . time - The time 8853ece3a9fcSMatthew G. Knepley . label - The DMLabel marking the portion of the domain boundary to output 8854ece3a9fcSMatthew G. Knepley . numIds - The number of label ids to use 8855ece3a9fcSMatthew G. Knepley . ids - The label ids to use for marking 8856ece3a9fcSMatthew G. Knepley . Nc - The number of components to set in the output, or PETSC_DETERMINE for all components 8857ece3a9fcSMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8858ece3a9fcSMatthew G. Knepley . localU - The input field vector 8859ece3a9fcSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8860ece3a9fcSMatthew G. Knepley - mode - The insertion mode for values 8861ece3a9fcSMatthew G. Knepley 8862ece3a9fcSMatthew G. Knepley Output Parameter: 8863ece3a9fcSMatthew G. Knepley . localX - The output vector 8864ece3a9fcSMatthew G. Knepley 8865ece3a9fcSMatthew G. Knepley Calling sequence of func: 8866ece3a9fcSMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8867ece3a9fcSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8868ece3a9fcSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8869ece3a9fcSMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8870ece3a9fcSMatthew G. Knepley 8871ece3a9fcSMatthew G. Knepley + dim - The spatial dimension 8872ece3a9fcSMatthew G. Knepley . Nf - The number of input fields 8873ece3a9fcSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8874ece3a9fcSMatthew G. Knepley . uOff - The offset of each field in u[] 8875ece3a9fcSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8876ece3a9fcSMatthew G. Knepley . u - The field values at this point in space 8877ece3a9fcSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8878ece3a9fcSMatthew G. Knepley . u_x - The field derivatives at this point in space 8879ece3a9fcSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8880ece3a9fcSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8881ece3a9fcSMatthew G. Knepley . a - The auxiliary field values at this point in space 8882ece3a9fcSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8883ece3a9fcSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8884ece3a9fcSMatthew G. Knepley . t - The current time 8885ece3a9fcSMatthew G. Knepley . x - The coordinates of this point 8886ece3a9fcSMatthew G. Knepley . n - The face normal 8887ece3a9fcSMatthew G. Knepley . numConstants - The number of constants 8888ece3a9fcSMatthew G. Knepley . constants - The value of each constant 8889ece3a9fcSMatthew G. Knepley - f - The value of the function at this point in space 8890ece3a9fcSMatthew G. Knepley 8891ece3a9fcSMatthew G. Knepley Note: 8892ece3a9fcSMatthew G. Knepley There are three different DMs that potentially interact in this function. The output DM, dm, specifies the layout of the values calculates by funcs. 8893ece3a9fcSMatthew G. Knepley The input DM, attached to U, may be different. For example, you can input the solution over the full domain, but output over a piece of the boundary, or 8894ece3a9fcSMatthew G. Knepley a subdomain. You can also output a different number of fields than the input, with different discretizations. Last the auxiliary DM, attached to the 8895ece3a9fcSMatthew G. Knepley auxiliary field vector, which is attached to dm, can also be different. It can have a different topology, number of fields, and discretizations. 8896ece3a9fcSMatthew G. Knepley 8897ece3a9fcSMatthew G. Knepley Level: intermediate 8898ece3a9fcSMatthew G. Knepley 8899ece3a9fcSMatthew G. Knepley .seealso: DMProjectField(), DMProjectFieldLabelLocal(), DMProjectFunction(), DMComputeL2Diff() 8900ece3a9fcSMatthew G. Knepley @*/ 8901ece3a9fcSMatthew G. Knepley PetscErrorCode DMProjectBdFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, 8902ece3a9fcSMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 8903ece3a9fcSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8904ece3a9fcSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8905ece3a9fcSMatthew G. Knepley PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 8906ece3a9fcSMatthew G. Knepley InsertMode mode, Vec localX) 8907ece3a9fcSMatthew G. Knepley { 8908ece3a9fcSMatthew G. Knepley PetscErrorCode ierr; 8909ece3a9fcSMatthew G. Knepley 8910ece3a9fcSMatthew G. Knepley PetscFunctionBegin; 8911ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8912ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,6); 8913ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,9); 8914ece3a9fcSMatthew G. Knepley if (!dm->ops->projectbdfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectBdFieldLabelLocal",((PetscObject)dm)->type_name); 8915ece3a9fcSMatthew G. Knepley ierr = (dm->ops->projectbdfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX);CHKERRQ(ierr); 8916ece3a9fcSMatthew G. Knepley PetscFunctionReturn(0); 8917ece3a9fcSMatthew G. Knepley } 8918ece3a9fcSMatthew G. Knepley 8919ece3a9fcSMatthew G. Knepley /*@C 89202716604bSToby Isaac DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h. 89212716604bSToby Isaac 89222716604bSToby Isaac Input Parameters: 89232716604bSToby Isaac + dm - The DM 89240709b2feSToby Isaac . time - The time 89252716604bSToby Isaac . funcs - The functions to evaluate for each field component 89262716604bSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8927574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 89282716604bSToby Isaac 89292716604bSToby Isaac Output Parameter: 89302716604bSToby Isaac . diff - The diff ||u - u_h||_2 89312716604bSToby Isaac 89322716604bSToby Isaac Level: developer 89332716604bSToby Isaac 89341189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff() 89352716604bSToby Isaac @*/ 89360709b2feSToby Isaac PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff) 89372716604bSToby Isaac { 89382716604bSToby Isaac PetscErrorCode ierr; 89392716604bSToby Isaac 89402716604bSToby Isaac PetscFunctionBegin; 89412716604bSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8942b698f381SToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 89430918c465SMatthew G. Knepley if (!dm->ops->computel2diff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2Diff",((PetscObject)dm)->type_name); 89440709b2feSToby Isaac ierr = (dm->ops->computel2diff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr); 89452716604bSToby Isaac PetscFunctionReturn(0); 89462716604bSToby Isaac } 8947b698f381SToby Isaac 8948b698f381SToby Isaac /*@C 8949b698f381SToby Isaac DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h. 8950b698f381SToby Isaac 8951d083f849SBarry Smith Collective on dm 8952d083f849SBarry Smith 8953b698f381SToby Isaac Input Parameters: 8954b698f381SToby Isaac + dm - The DM 8955b698f381SToby Isaac , time - The time 8956b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component 8957b698f381SToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8958574a98acSMatthew G. Knepley . X - The coefficient vector u_h, a global vector 8959b698f381SToby Isaac - n - The vector to project along 8960b698f381SToby Isaac 8961b698f381SToby Isaac Output Parameter: 8962b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2 8963b698f381SToby Isaac 8964b698f381SToby Isaac Level: developer 8965b698f381SToby Isaac 8966b698f381SToby Isaac .seealso: DMProjectFunction(), DMComputeL2Diff() 8967b698f381SToby Isaac @*/ 8968b698f381SToby 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) 8969b698f381SToby Isaac { 8970b698f381SToby Isaac PetscErrorCode ierr; 8971b698f381SToby Isaac 8972b698f381SToby Isaac PetscFunctionBegin; 8973b698f381SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8974b698f381SToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 8975b698f381SToby Isaac if (!dm->ops->computel2gradientdiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2GradientDiff",((PetscObject)dm)->type_name); 8976b698f381SToby Isaac ierr = (dm->ops->computel2gradientdiff)(dm,time,funcs,ctxs,X,n,diff);CHKERRQ(ierr); 8977b698f381SToby Isaac PetscFunctionReturn(0); 8978b698f381SToby Isaac } 8979b698f381SToby Isaac 89802a16baeaSToby Isaac /*@C 89812a16baeaSToby Isaac DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components. 89822a16baeaSToby Isaac 8983d083f849SBarry Smith Collective on dm 8984d083f849SBarry Smith 89852a16baeaSToby Isaac Input Parameters: 89862a16baeaSToby Isaac + dm - The DM 89872a16baeaSToby Isaac . time - The time 89882a16baeaSToby Isaac . funcs - The functions to evaluate for each field component 89892a16baeaSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8990574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 89912a16baeaSToby Isaac 89922a16baeaSToby Isaac Output Parameter: 89932a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2 89942a16baeaSToby Isaac 89952a16baeaSToby Isaac Level: developer 89962a16baeaSToby Isaac 89971189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff() 89982a16baeaSToby Isaac @*/ 89991189c1efSToby Isaac PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[]) 90002a16baeaSToby Isaac { 90012a16baeaSToby Isaac PetscErrorCode ierr; 90022a16baeaSToby Isaac 90032a16baeaSToby Isaac PetscFunctionBegin; 90042a16baeaSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 90052a16baeaSToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 90060918c465SMatthew G. Knepley if (!dm->ops->computel2fielddiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2FieldDiff",((PetscObject)dm)->type_name); 90072a16baeaSToby Isaac ierr = (dm->ops->computel2fielddiff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr); 90082a16baeaSToby Isaac PetscFunctionReturn(0); 90092a16baeaSToby Isaac } 90102a16baeaSToby Isaac 9011df0b854cSToby Isaac /*@C 9012df0b854cSToby Isaac DMAdaptLabel - Adapt a dm based on a label with values interpreted as coarsening and refining flags. Specific implementations of DM maybe have 9013cd3c525cSToby Isaac specialized flags, but all implementations should accept flag values DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN. 9014df0b854cSToby Isaac 9015df0b854cSToby Isaac Collective on dm 9016df0b854cSToby Isaac 9017df0b854cSToby Isaac Input parameters: 9018df0b854cSToby Isaac + dm - the pre-adaptation DM object 9019a1b0c543SToby Isaac - label - label with the flags 9020df0b854cSToby Isaac 9021df0b854cSToby Isaac Output parameters: 90220d1cd5e0SMatthew G. Knepley . dmAdapt - the adapted DM object: may be NULL if an adapted DM could not be produced. 9023df0b854cSToby Isaac 9024df0b854cSToby Isaac Level: intermediate 90250d1cd5e0SMatthew G. Knepley 90260d1cd5e0SMatthew G. Knepley .seealso: DMAdaptMetric(), DMCoarsen(), DMRefine() 9027df0b854cSToby Isaac @*/ 90280d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptLabel(DM dm, DMLabel label, DM *dmAdapt) 9029df0b854cSToby Isaac { 9030df0b854cSToby Isaac PetscErrorCode ierr; 9031df0b854cSToby Isaac 9032df0b854cSToby Isaac PetscFunctionBegin; 9033df0b854cSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9034a1b0c543SToby Isaac PetscValidPointer(label,2); 90350d1cd5e0SMatthew G. Knepley PetscValidPointer(dmAdapt,3); 90360d1cd5e0SMatthew G. Knepley *dmAdapt = NULL; 90376f25b0d8SLisandro Dalcin if (!dm->ops->adaptlabel) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptLabel",((PetscObject)dm)->type_name); 90380d1cd5e0SMatthew G. Knepley ierr = (dm->ops->adaptlabel)(dm, label, dmAdapt);CHKERRQ(ierr); 9039a587d139SMark if (*dmAdapt) { 9040a587d139SMark (*dmAdapt)->prealloc_only = dm->prealloc_only; /* maybe this should go .... */ 9041a587d139SMark ierr = PetscFree((*dmAdapt)->vectype);CHKERRQ(ierr); 9042a587d139SMark ierr = PetscStrallocpy(dm->vectype,(char**)&(*dmAdapt)->vectype);CHKERRQ(ierr); 9043a587d139SMark ierr = PetscFree((*dmAdapt)->mattype);CHKERRQ(ierr); 9044a587d139SMark ierr = PetscStrallocpy(dm->mattype,(char**)&(*dmAdapt)->mattype);CHKERRQ(ierr); 9045a587d139SMark } 90460d1cd5e0SMatthew G. Knepley PetscFunctionReturn(0); 90470d1cd5e0SMatthew G. Knepley } 90480d1cd5e0SMatthew G. Knepley 90490d1cd5e0SMatthew G. Knepley /*@C 90500d1cd5e0SMatthew G. Knepley DMAdaptMetric - Generates a mesh adapted to the specified metric field using the pragmatic library. 90510d1cd5e0SMatthew G. Knepley 90520d1cd5e0SMatthew G. Knepley Input Parameters: 90530d1cd5e0SMatthew G. Knepley + dm - The DM object 90540d1cd5e0SMatthew G. Knepley . metric - The metric to which the mesh is adapted, defined vertex-wise. 90556f25b0d8SLisandro 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_". 90560d1cd5e0SMatthew G. Knepley 90570d1cd5e0SMatthew G. Knepley Output Parameter: 90580d1cd5e0SMatthew G. Knepley . dmAdapt - Pointer to the DM object containing the adapted mesh 90590d1cd5e0SMatthew G. Knepley 90600d1cd5e0SMatthew G. Knepley Note: The label in the adapted mesh will be registered under the name of the input DMLabel object 90610d1cd5e0SMatthew G. Knepley 90620d1cd5e0SMatthew G. Knepley Level: advanced 90630d1cd5e0SMatthew G. Knepley 90640d1cd5e0SMatthew G. Knepley .seealso: DMAdaptLabel(), DMCoarsen(), DMRefine() 90650d1cd5e0SMatthew G. Knepley @*/ 90660d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptMetric(DM dm, Vec metric, DMLabel bdLabel, DM *dmAdapt) 90670d1cd5e0SMatthew G. Knepley { 90680d1cd5e0SMatthew G. Knepley PetscErrorCode ierr; 90690d1cd5e0SMatthew G. Knepley 90700d1cd5e0SMatthew G. Knepley PetscFunctionBegin; 90710d1cd5e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90720d1cd5e0SMatthew G. Knepley PetscValidHeaderSpecific(metric, VEC_CLASSID, 2); 90730d1cd5e0SMatthew G. Knepley if (bdLabel) PetscValidPointer(bdLabel, 3); 90740d1cd5e0SMatthew G. Knepley PetscValidPointer(dmAdapt, 4); 90756f25b0d8SLisandro Dalcin *dmAdapt = NULL; 90766f25b0d8SLisandro Dalcin if (!dm->ops->adaptmetric) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptMetric",((PetscObject)dm)->type_name); 90770d1cd5e0SMatthew G. Knepley ierr = (dm->ops->adaptmetric)(dm, metric, bdLabel, dmAdapt);CHKERRQ(ierr); 9078df0b854cSToby Isaac PetscFunctionReturn(0); 9079df0b854cSToby Isaac } 9080c4088d22SMatthew G. Knepley 9081502a2867SDave May /*@C 9082502a2867SDave May DMGetNeighbors - Gets an array containing the MPI rank of all the processes neighbors 9083502a2867SDave May 9084502a2867SDave May Not Collective 9085502a2867SDave May 9086502a2867SDave May Input Parameter: 9087502a2867SDave May . dm - The DM 9088502a2867SDave May 90890a19bb7dSprj- Output Parameters: 90900a19bb7dSprj- + nranks - the number of neighbours 90910a19bb7dSprj- - ranks - the neighbors ranks 9092502a2867SDave May 9093502a2867SDave May Notes: 9094502a2867SDave May Do not free the array, it is freed when the DM is destroyed. 9095502a2867SDave May 9096502a2867SDave May Level: beginner 9097502a2867SDave May 9098dec1416fSJunchao Zhang .seealso: DMDAGetNeighbors(), PetscSFGetRootRanks() 9099502a2867SDave May @*/ 9100502a2867SDave May PetscErrorCode DMGetNeighbors(DM dm,PetscInt *nranks,const PetscMPIInt *ranks[]) 9101502a2867SDave May { 9102502a2867SDave May PetscErrorCode ierr; 9103502a2867SDave May 9104502a2867SDave May PetscFunctionBegin; 9105502a2867SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 91060918c465SMatthew G. Knepley if (!dm->ops->getneighbors) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMGetNeighbors",((PetscObject)dm)->type_name); 9107502a2867SDave May ierr = (dm->ops->getneighbors)(dm,nranks,ranks);CHKERRQ(ierr); 9108502a2867SDave May PetscFunctionReturn(0); 9109502a2867SDave May } 9110502a2867SDave May 9111531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */ 9112531c7667SBarry Smith 9113531c7667SBarry Smith /* 9114531c7667SBarry Smith Converts the input vector to a ghosted vector and then calls the standard coloring code. 9115531c7667SBarry Smith This has be a different function because it requires DM which is not defined in the Mat library 9116531c7667SBarry Smith */ 9117531c7667SBarry Smith PetscErrorCode MatFDColoringApply_AIJDM(Mat J,MatFDColoring coloring,Vec x1,void *sctx) 9118531c7667SBarry Smith { 9119531c7667SBarry Smith PetscErrorCode ierr; 9120531c7667SBarry Smith 9121531c7667SBarry Smith PetscFunctionBegin; 9122531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 9123531c7667SBarry Smith Vec x1local; 9124531c7667SBarry Smith DM dm; 9125531c7667SBarry Smith ierr = MatGetDM(J,&dm);CHKERRQ(ierr); 9126531c7667SBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_INCOMP,"IS_COLORING_LOCAL requires a DM"); 9127531c7667SBarry Smith ierr = DMGetLocalVector(dm,&x1local);CHKERRQ(ierr); 9128531c7667SBarry Smith ierr = DMGlobalToLocalBegin(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr); 9129531c7667SBarry Smith ierr = DMGlobalToLocalEnd(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr); 9130531c7667SBarry Smith x1 = x1local; 9131531c7667SBarry Smith } 9132531c7667SBarry Smith ierr = MatFDColoringApply_AIJ(J,coloring,x1,sctx);CHKERRQ(ierr); 9133531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 9134531c7667SBarry Smith DM dm; 9135531c7667SBarry Smith ierr = MatGetDM(J,&dm);CHKERRQ(ierr); 9136531c7667SBarry Smith ierr = DMRestoreLocalVector(dm,&x1);CHKERRQ(ierr); 9137531c7667SBarry Smith } 9138531c7667SBarry Smith PetscFunctionReturn(0); 9139531c7667SBarry Smith } 9140531c7667SBarry Smith 9141531c7667SBarry Smith /*@ 9142531c7667SBarry Smith MatFDColoringUseDM - allows a MatFDColoring object to use the DM associated with the matrix to use a IS_COLORING_LOCAL coloring 9143531c7667SBarry Smith 9144531c7667SBarry Smith Input Parameter: 9145531c7667SBarry Smith . coloring - the MatFDColoring object 9146531c7667SBarry Smith 914795452b02SPatrick Sanan Developer Notes: 914895452b02SPatrick Sanan this routine exists because the PETSc Mat library does not know about the DM objects 9149531c7667SBarry Smith 91501b266c99SBarry Smith Level: advanced 91511b266c99SBarry Smith 9152531c7667SBarry Smith .seealso: MatFDColoring, MatFDColoringCreate(), ISColoringType 9153531c7667SBarry Smith @*/ 9154531c7667SBarry Smith PetscErrorCode MatFDColoringUseDM(Mat coloring,MatFDColoring fdcoloring) 9155531c7667SBarry Smith { 9156531c7667SBarry Smith PetscFunctionBegin; 9157531c7667SBarry Smith coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM; 9158531c7667SBarry Smith PetscFunctionReturn(0); 9159531c7667SBarry Smith } 91608320bc6fSPatrick Sanan 91618320bc6fSPatrick Sanan /*@ 91628320bc6fSPatrick Sanan DMGetCompatibility - determine if two DMs are compatible 91638320bc6fSPatrick Sanan 91648320bc6fSPatrick Sanan Collective 91658320bc6fSPatrick Sanan 91668320bc6fSPatrick Sanan Input Parameters: 9167a5bc1bf3SBarry Smith + dm1 - the first DM 91688320bc6fSPatrick Sanan - dm2 - the second DM 91698320bc6fSPatrick Sanan 91708320bc6fSPatrick Sanan Output Parameters: 91718320bc6fSPatrick Sanan + compatible - whether or not the two DMs are compatible 91728320bc6fSPatrick Sanan - set - whether or not the compatible value was set 91738320bc6fSPatrick Sanan 91748320bc6fSPatrick Sanan Notes: 91758320bc6fSPatrick Sanan Two DMs are deemed compatible if they represent the same parallel decomposition 91763d862458SPatrick Sanan of the same topology. This implies that the section (field data) on one 91778320bc6fSPatrick Sanan "makes sense" with respect to the topology and parallel decomposition of the other. 91783d862458SPatrick Sanan Loosely speaking, compatible DMs represent the same domain and parallel 91793d862458SPatrick Sanan decomposition, but hold different data. 91808320bc6fSPatrick Sanan 91818320bc6fSPatrick Sanan Typically, one would confirm compatibility if intending to simultaneously iterate 91828320bc6fSPatrick Sanan over a pair of vectors obtained from different DMs. 91838320bc6fSPatrick Sanan 91848320bc6fSPatrick Sanan For example, two DMDA objects are compatible if they have the same local 91858320bc6fSPatrick Sanan and global sizes and the same stencil width. They can have different numbers 91868320bc6fSPatrick Sanan of degrees of freedom per node. Thus, one could use the node numbering from 91878320bc6fSPatrick Sanan either DM in bounds for a loop over vectors derived from either DM. 91888320bc6fSPatrick Sanan 91898320bc6fSPatrick Sanan Consider the operation of summing data living on a 2-dof DMDA to data living 91908320bc6fSPatrick Sanan on a 1-dof DMDA, which should be compatible, as in the following snippet. 91918320bc6fSPatrick Sanan .vb 91928320bc6fSPatrick Sanan ... 91938320bc6fSPatrick Sanan ierr = DMGetCompatibility(da1,da2,&compatible,&set);CHKERRQ(ierr); 91948320bc6fSPatrick Sanan if (set && compatible) { 91958320bc6fSPatrick Sanan ierr = DMDAVecGetArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr); 91968320bc6fSPatrick Sanan ierr = DMDAVecGetArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr); 91973d862458SPatrick Sanan ierr = DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL);CHKERRQ(ierr); 91988320bc6fSPatrick Sanan for (j=y; j<y+n; ++j) { 91998320bc6fSPatrick Sanan for (i=x; i<x+m, ++i) { 92008320bc6fSPatrick Sanan arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1]; 92018320bc6fSPatrick Sanan } 92028320bc6fSPatrick Sanan } 92038320bc6fSPatrick Sanan ierr = DMDAVecRestoreArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr); 92048320bc6fSPatrick Sanan ierr = DMDAVecRestoreArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr); 92058320bc6fSPatrick Sanan } else { 92068320bc6fSPatrick Sanan SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible"); 92078320bc6fSPatrick Sanan } 92088320bc6fSPatrick Sanan ... 92098320bc6fSPatrick Sanan .ve 92108320bc6fSPatrick Sanan 92118320bc6fSPatrick Sanan Checking compatibility might be expensive for a given implementation of DM, 92128320bc6fSPatrick Sanan or might be impossible to unambiguously confirm or deny. For this reason, 92138320bc6fSPatrick Sanan this function may decline to determine compatibility, and hence users should 92148320bc6fSPatrick Sanan always check the "set" output parameter. 92158320bc6fSPatrick Sanan 92168320bc6fSPatrick Sanan A DM is always compatible with itself. 92178320bc6fSPatrick Sanan 92188320bc6fSPatrick Sanan In the current implementation, DMs which live on "unequal" communicators 92198320bc6fSPatrick Sanan (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed 92208320bc6fSPatrick Sanan incompatible. 92218320bc6fSPatrick Sanan 92228320bc6fSPatrick Sanan This function is labeled "Collective," as information about all subdomains 92238320bc6fSPatrick Sanan is required on each rank. However, in DM implementations which store all this 92248320bc6fSPatrick Sanan information locally, this function may be merely "Logically Collective". 92258320bc6fSPatrick Sanan 92268320bc6fSPatrick Sanan Developer Notes: 92273d862458SPatrick Sanan Compatibility is assumed to be a symmetric concept; DM A is compatible with DM B 92283d862458SPatrick Sanan iff B is compatible with A. Thus, this function checks the implementations 9229a5bc1bf3SBarry Smith of both dm and dmc (if they are of different types), attempting to determine 92308320bc6fSPatrick Sanan compatibility. It is left to DM implementers to ensure that symmetry is 92318320bc6fSPatrick Sanan preserved. The simplest way to do this is, when implementing type-specific 92323d862458SPatrick Sanan logic for this function, is to check for existing logic in the implementation 92333d862458SPatrick Sanan of other DM types and let *set = PETSC_FALSE if found. 92348320bc6fSPatrick Sanan 92358320bc6fSPatrick Sanan Level: advanced 92368320bc6fSPatrick Sanan 92373d862458SPatrick Sanan .seealso: DM, DMDACreateCompatibleDMDA(), DMStagCreateCompatibleDMStag() 92388320bc6fSPatrick Sanan @*/ 92398320bc6fSPatrick Sanan 9240a5bc1bf3SBarry Smith PetscErrorCode DMGetCompatibility(DM dm1,DM dm2,PetscBool *compatible,PetscBool *set) 92418320bc6fSPatrick Sanan { 92428320bc6fSPatrick Sanan PetscErrorCode ierr; 92438320bc6fSPatrick Sanan PetscMPIInt compareResult; 92448320bc6fSPatrick Sanan DMType type,type2; 92458320bc6fSPatrick Sanan PetscBool sameType; 92468320bc6fSPatrick Sanan 92478320bc6fSPatrick Sanan PetscFunctionBegin; 9248a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dm1,DM_CLASSID,1); 92498320bc6fSPatrick Sanan PetscValidHeaderSpecific(dm2,DM_CLASSID,2); 92508320bc6fSPatrick Sanan 92518320bc6fSPatrick Sanan /* Declare a DM compatible with itself */ 9252a5bc1bf3SBarry Smith if (dm1 == dm2) { 92538320bc6fSPatrick Sanan *set = PETSC_TRUE; 92548320bc6fSPatrick Sanan *compatible = PETSC_TRUE; 92558320bc6fSPatrick Sanan PetscFunctionReturn(0); 92568320bc6fSPatrick Sanan } 92578320bc6fSPatrick Sanan 92588320bc6fSPatrick Sanan /* Declare a DM incompatible with a DM that lives on an "unequal" 92598320bc6fSPatrick Sanan communicator. Note that this does not preclude compatibility with 92608320bc6fSPatrick Sanan DMs living on "congruent" or "similar" communicators, but this must be 92618320bc6fSPatrick Sanan determined by the implementation-specific logic */ 9262ffc4695bSBarry Smith ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dm1),PetscObjectComm((PetscObject)dm2),&compareResult);CHKERRMPI(ierr); 92638320bc6fSPatrick Sanan if (compareResult == MPI_UNEQUAL) { 92648320bc6fSPatrick Sanan *set = PETSC_TRUE; 92658320bc6fSPatrick Sanan *compatible = PETSC_FALSE; 92668320bc6fSPatrick Sanan PetscFunctionReturn(0); 92678320bc6fSPatrick Sanan } 92688320bc6fSPatrick Sanan 92698320bc6fSPatrick Sanan /* Pass to the implementation-specific routine, if one exists. */ 9270a5bc1bf3SBarry Smith if (dm1->ops->getcompatibility) { 9271a5bc1bf3SBarry Smith ierr = (*dm1->ops->getcompatibility)(dm1,dm2,compatible,set);CHKERRQ(ierr); 9272b9d85ea2SLisandro Dalcin if (*set) PetscFunctionReturn(0); 92738320bc6fSPatrick Sanan } 92748320bc6fSPatrick Sanan 9275a5bc1bf3SBarry Smith /* If dm1 and dm2 are of different types, then attempt to check compatibility 92768320bc6fSPatrick Sanan with an implementation of this function from dm2 */ 9277a5bc1bf3SBarry Smith ierr = DMGetType(dm1,&type);CHKERRQ(ierr); 92788320bc6fSPatrick Sanan ierr = DMGetType(dm2,&type2);CHKERRQ(ierr); 92798320bc6fSPatrick Sanan ierr = PetscStrcmp(type,type2,&sameType);CHKERRQ(ierr); 92808320bc6fSPatrick Sanan if (!sameType && dm2->ops->getcompatibility) { 9281a5bc1bf3SBarry Smith ierr = (*dm2->ops->getcompatibility)(dm2,dm1,compatible,set);CHKERRQ(ierr); /* Note argument order */ 92828320bc6fSPatrick Sanan } else { 92838320bc6fSPatrick Sanan *set = PETSC_FALSE; 92848320bc6fSPatrick Sanan } 92858320bc6fSPatrick Sanan PetscFunctionReturn(0); 92868320bc6fSPatrick Sanan } 9287c0f0dcc3SMatthew G. Knepley 9288c0f0dcc3SMatthew G. Knepley /*@C 9289c0f0dcc3SMatthew G. Knepley DMMonitorSet - Sets an ADDITIONAL function that is to be used after a solve to monitor discretization performance. 9290c0f0dcc3SMatthew G. Knepley 9291c0f0dcc3SMatthew G. Knepley Logically Collective on DM 9292c0f0dcc3SMatthew G. Knepley 9293c0f0dcc3SMatthew G. Knepley Input Parameters: 9294c0f0dcc3SMatthew G. Knepley + DM - the DM 9295c0f0dcc3SMatthew G. Knepley . f - the monitor function 9296c0f0dcc3SMatthew G. Knepley . mctx - [optional] user-defined context for private data for the monitor routine (use NULL if no context is desired) 9297c0f0dcc3SMatthew G. Knepley - monitordestroy - [optional] routine that frees monitor context (may be NULL) 9298c0f0dcc3SMatthew G. Knepley 9299c0f0dcc3SMatthew G. Knepley Options Database Keys: 9300c0f0dcc3SMatthew G. Knepley - -dm_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to DMMonitorSet(), but 9301c0f0dcc3SMatthew G. Knepley does not cancel those set via the options database. 9302c0f0dcc3SMatthew G. Knepley 9303c0f0dcc3SMatthew G. Knepley Notes: 9304c0f0dcc3SMatthew G. Knepley Several different monitoring routines may be set by calling 9305c0f0dcc3SMatthew G. Knepley DMMonitorSet() multiple times; all will be called in the 9306c0f0dcc3SMatthew G. Knepley order in which they were set. 9307c0f0dcc3SMatthew G. Knepley 9308c0f0dcc3SMatthew G. Knepley Fortran Notes: 9309c0f0dcc3SMatthew G. Knepley Only a single monitor function can be set for each DM object 9310c0f0dcc3SMatthew G. Knepley 9311c0f0dcc3SMatthew G. Knepley Level: intermediate 9312c0f0dcc3SMatthew G. Knepley 9313c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorCancel() 9314c0f0dcc3SMatthew G. Knepley @*/ 9315c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorSet(DM dm, PetscErrorCode (*f)(DM, void *), void *mctx, PetscErrorCode (*monitordestroy)(void**)) 9316c0f0dcc3SMatthew G. Knepley { 9317c0f0dcc3SMatthew G. Knepley PetscInt m; 9318c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9319c0f0dcc3SMatthew G. Knepley 9320c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9321c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9322c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 9323c0f0dcc3SMatthew G. Knepley PetscBool identical; 9324c0f0dcc3SMatthew G. Knepley 9325c0f0dcc3SMatthew G. Knepley ierr = PetscMonitorCompare((PetscErrorCode (*)(void)) f, mctx, monitordestroy, (PetscErrorCode (*)(void)) dm->monitor[m], dm->monitorcontext[m], dm->monitordestroy[m], &identical);CHKERRQ(ierr); 9326c0f0dcc3SMatthew G. Knepley if (identical) PetscFunctionReturn(0); 9327c0f0dcc3SMatthew G. Knepley } 9328c0f0dcc3SMatthew G. Knepley if (dm->numbermonitors >= MAXDMMONITORS) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 9329c0f0dcc3SMatthew G. Knepley dm->monitor[dm->numbermonitors] = f; 9330c0f0dcc3SMatthew G. Knepley dm->monitordestroy[dm->numbermonitors] = monitordestroy; 9331c0f0dcc3SMatthew G. Knepley dm->monitorcontext[dm->numbermonitors++] = (void *) mctx; 9332c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9333c0f0dcc3SMatthew G. Knepley } 9334c0f0dcc3SMatthew G. Knepley 9335c0f0dcc3SMatthew G. Knepley /*@ 9336c0f0dcc3SMatthew G. Knepley DMMonitorCancel - Clears all the monitor functions for a DM object. 9337c0f0dcc3SMatthew G. Knepley 9338c0f0dcc3SMatthew G. Knepley Logically Collective on DM 9339c0f0dcc3SMatthew G. Knepley 9340c0f0dcc3SMatthew G. Knepley Input Parameter: 9341c0f0dcc3SMatthew G. Knepley . dm - the DM 9342c0f0dcc3SMatthew G. Knepley 9343c0f0dcc3SMatthew G. Knepley Options Database Key: 9344c0f0dcc3SMatthew G. Knepley . -dm_monitor_cancel - cancels all monitors that have been hardwired 9345c0f0dcc3SMatthew G. Knepley into a code by calls to DMonitorSet(), but does not cancel those 9346c0f0dcc3SMatthew G. Knepley set via the options database 9347c0f0dcc3SMatthew G. Knepley 9348c0f0dcc3SMatthew G. Knepley Notes: 9349c0f0dcc3SMatthew G. Knepley There is no way to clear one specific monitor from a DM object. 9350c0f0dcc3SMatthew G. Knepley 9351c0f0dcc3SMatthew G. Knepley Level: intermediate 9352c0f0dcc3SMatthew G. Knepley 9353c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorSet() 9354c0f0dcc3SMatthew G. Knepley @*/ 9355c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorCancel(DM dm) 9356c0f0dcc3SMatthew G. Knepley { 9357c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9358c0f0dcc3SMatthew G. Knepley PetscInt m; 9359c0f0dcc3SMatthew G. Knepley 9360c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9361c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9362c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 9363c0f0dcc3SMatthew G. Knepley if (dm->monitordestroy[m]) {ierr = (*dm->monitordestroy[m])(&dm->monitorcontext[m]);CHKERRQ(ierr);} 9364c0f0dcc3SMatthew G. Knepley } 9365c0f0dcc3SMatthew G. Knepley dm->numbermonitors = 0; 9366c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9367c0f0dcc3SMatthew G. Knepley } 9368c0f0dcc3SMatthew G. Knepley 9369c0f0dcc3SMatthew G. Knepley /*@C 9370c0f0dcc3SMatthew G. Knepley DMMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 9371c0f0dcc3SMatthew G. Knepley 9372c0f0dcc3SMatthew G. Knepley Collective on DM 9373c0f0dcc3SMatthew G. Knepley 9374c0f0dcc3SMatthew G. Knepley Input Parameters: 9375c0f0dcc3SMatthew G. Knepley + dm - DM object you wish to monitor 9376c0f0dcc3SMatthew G. Knepley . name - the monitor type one is seeking 9377c0f0dcc3SMatthew G. Knepley . help - message indicating what monitoring is done 9378c0f0dcc3SMatthew G. Knepley . manual - manual page for the monitor 9379c0f0dcc3SMatthew G. Knepley . monitor - the monitor function 9380c0f0dcc3SMatthew G. Knepley - monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the DM or PetscViewer objects 9381c0f0dcc3SMatthew G. Knepley 9382c0f0dcc3SMatthew G. Knepley Output Parameter: 9383c0f0dcc3SMatthew G. Knepley . flg - Flag set if the monitor was created 9384c0f0dcc3SMatthew G. Knepley 9385c0f0dcc3SMatthew G. Knepley Level: developer 9386c0f0dcc3SMatthew G. Knepley 9387c0f0dcc3SMatthew G. Knepley .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 9388c0f0dcc3SMatthew G. Knepley PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 9389c0f0dcc3SMatthew G. Knepley PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 9390c0f0dcc3SMatthew G. Knepley PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 9391c0f0dcc3SMatthew G. Knepley PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 9392c0f0dcc3SMatthew G. Knepley PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 9393c0f0dcc3SMatthew G. Knepley PetscOptionsFList(), PetscOptionsEList() 9394c0f0dcc3SMatthew G. Knepley @*/ 9395c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorSetFromOptions(DM dm, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(DM, void *), PetscErrorCode (*monitorsetup)(DM, PetscViewerAndFormat *), PetscBool *flg) 9396c0f0dcc3SMatthew G. Knepley { 9397c0f0dcc3SMatthew G. Knepley PetscViewer viewer; 9398c0f0dcc3SMatthew G. Knepley PetscViewerFormat format; 9399c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9400c0f0dcc3SMatthew G. Knepley 9401c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9402c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9403c0f0dcc3SMatthew G. Knepley ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) dm), ((PetscObject) dm)->options, ((PetscObject) dm)->prefix, name, &viewer, &format, flg);CHKERRQ(ierr); 9404c0f0dcc3SMatthew G. Knepley if (*flg) { 9405c0f0dcc3SMatthew G. Knepley PetscViewerAndFormat *vf; 9406c0f0dcc3SMatthew G. Knepley 9407c0f0dcc3SMatthew G. Knepley ierr = PetscViewerAndFormatCreate(viewer, format, &vf);CHKERRQ(ierr); 9408c0f0dcc3SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) viewer);CHKERRQ(ierr); 9409c0f0dcc3SMatthew G. Knepley if (monitorsetup) {ierr = (*monitorsetup)(dm, vf);CHKERRQ(ierr);} 9410c0f0dcc3SMatthew G. Knepley ierr = DMMonitorSet(dm,(PetscErrorCode (*)(DM, void *)) monitor, vf, (PetscErrorCode (*)(void **)) PetscViewerAndFormatDestroy);CHKERRQ(ierr); 9411c0f0dcc3SMatthew G. Knepley } 9412c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9413c0f0dcc3SMatthew G. Knepley } 9414c0f0dcc3SMatthew G. Knepley 9415c0f0dcc3SMatthew G. Knepley /*@ 9416c0f0dcc3SMatthew G. Knepley DMMonitor - runs the user provided monitor routines, if they exist 9417c0f0dcc3SMatthew G. Knepley 9418c0f0dcc3SMatthew G. Knepley Collective on DM 9419c0f0dcc3SMatthew G. Knepley 9420c0f0dcc3SMatthew G. Knepley Input Parameters: 9421c0f0dcc3SMatthew G. Knepley . dm - The DM 9422c0f0dcc3SMatthew G. Knepley 9423c0f0dcc3SMatthew G. Knepley Level: developer 9424c0f0dcc3SMatthew G. Knepley 9425c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorSet() 9426c0f0dcc3SMatthew G. Knepley @*/ 9427c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitor(DM dm) 9428c0f0dcc3SMatthew G. Knepley { 9429c0f0dcc3SMatthew G. Knepley PetscInt m; 9430c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9431c0f0dcc3SMatthew G. Knepley 9432c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9433c0f0dcc3SMatthew G. Knepley if (!dm) PetscFunctionReturn(0); 9434c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9435c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 9436c0f0dcc3SMatthew G. Knepley ierr = (*dm->monitor[m])(dm, dm->monitorcontext[m]);CHKERRQ(ierr); 9437c0f0dcc3SMatthew G. Knepley } 9438c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9439c0f0dcc3SMatthew G. Knepley } 94402e4af2aeSMatthew G. Knepley 94412e4af2aeSMatthew G. Knepley /*@ 94422e4af2aeSMatthew G. Knepley DMComputeError - Computes the error assuming the user has given exact solution functions 94432e4af2aeSMatthew G. Knepley 94442e4af2aeSMatthew G. Knepley Collective on DM 94452e4af2aeSMatthew G. Knepley 94462e4af2aeSMatthew G. Knepley Input Parameters: 94472e4af2aeSMatthew G. Knepley + dm - The DM 94482e4af2aeSMatthew G. Knepley . sol - The solution vector 94492e4af2aeSMatthew G. Knepley . errors - An array of length Nf, the number of fields, or NULL for no output 945099c90e12SSatish Balay - errorVec - A Vec pointer, or NULL for no output 94512e4af2aeSMatthew G. Knepley 94522e4af2aeSMatthew G. Knepley Output Parameters: 94532e4af2aeSMatthew G. Knepley + errors - The error in each field 94542e4af2aeSMatthew G. Knepley - errorVec - Creates a vector to hold the cellwise error 94552e4af2aeSMatthew G. Knepley 94562e4af2aeSMatthew G. Knepley Note: The exact solutions come from the PetscDS object, and the time comes from DMGetOutputSequenceNumber(). 94572e4af2aeSMatthew G. Knepley 94582e4af2aeSMatthew G. Knepley Level: developer 94592e4af2aeSMatthew G. Knepley 94602e4af2aeSMatthew G. Knepley .seealso: DMMonitorSet(), DMGetRegionNumDS(), PetscDSGetExactSolution(), DMGetOutputSequenceNumber() 94612e4af2aeSMatthew G. Knepley @*/ 94622e4af2aeSMatthew G. Knepley PetscErrorCode DMComputeError(DM dm, Vec sol, PetscReal errors[], Vec *errorVec) 94632e4af2aeSMatthew G. Knepley { 94642e4af2aeSMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 94652e4af2aeSMatthew G. Knepley void **ctxs; 94662e4af2aeSMatthew G. Knepley PetscReal time; 94672e4af2aeSMatthew G. Knepley PetscInt Nf, f, Nds, s; 94682e4af2aeSMatthew G. Knepley PetscErrorCode ierr; 94692e4af2aeSMatthew G. Knepley 94702e4af2aeSMatthew G. Knepley PetscFunctionBegin; 94712e4af2aeSMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 94722e4af2aeSMatthew G. Knepley ierr = PetscCalloc2(Nf, &exactSol, Nf, &ctxs);CHKERRQ(ierr); 94732e4af2aeSMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 94742e4af2aeSMatthew G. Knepley for (s = 0; s < Nds; ++s) { 94752e4af2aeSMatthew G. Knepley PetscDS ds; 94762e4af2aeSMatthew G. Knepley DMLabel label; 94772e4af2aeSMatthew G. Knepley IS fieldIS; 94782e4af2aeSMatthew G. Knepley const PetscInt *fields; 94792e4af2aeSMatthew G. Knepley PetscInt dsNf; 94802e4af2aeSMatthew G. Knepley 94812e4af2aeSMatthew G. Knepley ierr = DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds);CHKERRQ(ierr); 94822e4af2aeSMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &dsNf);CHKERRQ(ierr); 94832e4af2aeSMatthew G. Knepley if (fieldIS) {ierr = ISGetIndices(fieldIS, &fields);CHKERRQ(ierr);} 94842e4af2aeSMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 94852e4af2aeSMatthew G. Knepley const PetscInt field = fields[f]; 94862e4af2aeSMatthew G. Knepley ierr = PetscDSGetExactSolution(ds, field, &exactSol[field], &ctxs[field]);CHKERRQ(ierr); 94872e4af2aeSMatthew G. Knepley } 94882e4af2aeSMatthew G. Knepley if (fieldIS) {ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr);} 94892e4af2aeSMatthew G. Knepley } 94902e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 94912e4af2aeSMatthew G. Knepley if (!exactSol[f]) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "DS must contain exact solution functions in order to calculate error, missing for field %D", f); 94922e4af2aeSMatthew G. Knepley } 94932e4af2aeSMatthew G. Knepley ierr = DMGetOutputSequenceNumber(dm, NULL, &time);CHKERRQ(ierr); 94942e4af2aeSMatthew G. Knepley if (errors) {ierr = DMComputeL2FieldDiff(dm, time, exactSol, ctxs, sol, errors);CHKERRQ(ierr);} 94952e4af2aeSMatthew G. Knepley if (errorVec) { 94962e4af2aeSMatthew G. Knepley DM edm; 94972e4af2aeSMatthew G. Knepley DMPolytopeType ct; 94982e4af2aeSMatthew G. Knepley PetscBool simplex; 94992e4af2aeSMatthew G. Knepley PetscInt dim, cStart, Nf; 95002e4af2aeSMatthew G. Knepley 95012e4af2aeSMatthew G. Knepley ierr = DMClone(dm, &edm);CHKERRQ(ierr); 95022e4af2aeSMatthew G. Knepley ierr = DMGetDimension(edm, &dim);CHKERRQ(ierr); 95032e4af2aeSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, NULL);CHKERRQ(ierr); 95042e4af2aeSMatthew G. Knepley ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 95052e4af2aeSMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 95062e4af2aeSMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 95072e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 95082e4af2aeSMatthew G. Knepley PetscFE fe, efe; 95092e4af2aeSMatthew G. Knepley PetscQuadrature q; 95102e4af2aeSMatthew G. Knepley const char *name; 95112e4af2aeSMatthew G. Knepley 95122e4af2aeSMatthew G. Knepley ierr = DMGetField(dm, f, NULL, (PetscObject *) &fe);CHKERRQ(ierr); 95132e4af2aeSMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, Nf, simplex, 0, PETSC_DETERMINE, &efe);CHKERRQ(ierr); 95142e4af2aeSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) fe, &name);CHKERRQ(ierr); 95152e4af2aeSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) efe, name);CHKERRQ(ierr); 95162e4af2aeSMatthew G. Knepley ierr = PetscFEGetQuadrature(fe, &q);CHKERRQ(ierr); 95172e4af2aeSMatthew G. Knepley ierr = PetscFESetQuadrature(efe, q);CHKERRQ(ierr); 95182e4af2aeSMatthew G. Knepley ierr = DMSetField(edm, f, NULL, (PetscObject) efe);CHKERRQ(ierr); 95192e4af2aeSMatthew G. Knepley ierr = PetscFEDestroy(&efe);CHKERRQ(ierr); 95202e4af2aeSMatthew G. Knepley } 95212e4af2aeSMatthew G. Knepley ierr = DMCreateDS(edm);CHKERRQ(ierr); 95222e4af2aeSMatthew G. Knepley 95232e4af2aeSMatthew G. Knepley ierr = DMCreateGlobalVector(edm, errorVec); 95242e4af2aeSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *errorVec, "Error");CHKERRQ(ierr); 95252e4af2aeSMatthew G. Knepley ierr = DMPlexComputeL2DiffVec(dm, time, exactSol, ctxs, sol, *errorVec);CHKERRQ(ierr); 95262e4af2aeSMatthew G. Knepley ierr = DMDestroy(&edm);CHKERRQ(ierr); 95272e4af2aeSMatthew G. Knepley } 95282e4af2aeSMatthew G. Knepley ierr = PetscFree2(exactSol, ctxs);CHKERRQ(ierr); 95292e4af2aeSMatthew G. Knepley PetscFunctionReturn(0); 95302e4af2aeSMatthew G. Knepley } 9531