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}; 19ea78f98cSLisandro Dalcin const char *const DMBoundaryConditionTypes[] = {"INVALID","ESSENTIAL","NATURAL","INVALID","INVALID","ESSENTIAL_FIELD","NATURAL_FIELD","INVALID","INVALID","INVALID","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 59447c6ae99SBarry Smith /*@ 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) { 5641f9244615SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) {ierr = PetscDSSetJetDegree(dm->probs[s].ds, 0, k);CHKERRQ(ierr);} 5642f9244615SMatthew G. Knepley } 5643e5e52638SMatthew G. Knepley /* Setup DSes */ 5644e5e52638SMatthew G. Knepley if (doSetup) { 5645e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) {ierr = PetscDSSetUp(dm->probs[s].ds);CHKERRQ(ierr);} 5646e5e52638SMatthew G. Knepley } 5647e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5648e5e52638SMatthew G. Knepley } 5649e5e52638SMatthew G. Knepley 5650e5e52638SMatthew G. Knepley /*@ 56517f96f943SMatthew G. Knepley DMComputeExactSolution - Compute the exact solution for a given DM, using the PetscDS information. 56527f96f943SMatthew G. Knepley 5653f2cacb80SMatthew G. Knepley Collective on DM 5654f2cacb80SMatthew G. Knepley 56557f96f943SMatthew G. Knepley Input Parameters: 56567f96f943SMatthew G. Knepley + dm - The DM 56577f96f943SMatthew G. Knepley - time - The time 56587f96f943SMatthew G. Knepley 56597f96f943SMatthew G. Knepley Output Parameters: 5660f2cacb80SMatthew G. Knepley + u - The vector will be filled with exact solution values, or NULL 5661f2cacb80SMatthew G. Knepley - u_t - The vector will be filled with the time derivative of exact solution values, or NULL 56627f96f943SMatthew G. Knepley 56637f96f943SMatthew G. Knepley Note: The user must call PetscDSSetExactSolution() beforehand 56647f96f943SMatthew G. Knepley 56657f96f943SMatthew G. Knepley Level: developer 56667f96f943SMatthew G. Knepley 56677f96f943SMatthew G. Knepley .seealso: PetscDSSetExactSolution() 56687f96f943SMatthew G. Knepley @*/ 5669f2cacb80SMatthew G. Knepley PetscErrorCode DMComputeExactSolution(DM dm, PetscReal time, Vec u, Vec u_t) 56707f96f943SMatthew G. Knepley { 56717f96f943SMatthew G. Knepley PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx); 56727f96f943SMatthew G. Knepley void **ectxs; 56737f96f943SMatthew G. Knepley PetscInt Nf, Nds, s; 56747f96f943SMatthew G. Knepley PetscErrorCode ierr; 56757f96f943SMatthew G. Knepley 56767f96f943SMatthew G. Knepley PetscFunctionBegin; 5677f2cacb80SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5678f2cacb80SMatthew G. Knepley if (u) PetscValidHeaderSpecific(u, VEC_CLASSID, 3); 5679f2cacb80SMatthew G. Knepley if (u_t) PetscValidHeaderSpecific(u_t, VEC_CLASSID, 4); 56807f96f943SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 56817f96f943SMatthew G. Knepley ierr = PetscMalloc2(Nf, &exacts, Nf, &ectxs);CHKERRQ(ierr); 56827f96f943SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 56837f96f943SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 56847f96f943SMatthew G. Knepley PetscDS ds; 56857f96f943SMatthew G. Knepley DMLabel label; 56867f96f943SMatthew G. Knepley IS fieldIS; 56877f96f943SMatthew G. Knepley const PetscInt *fields, id = 1; 56887f96f943SMatthew G. Knepley PetscInt dsNf, f; 56897f96f943SMatthew G. Knepley 56907f96f943SMatthew G. Knepley ierr = DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds);CHKERRQ(ierr); 56917f96f943SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &dsNf);CHKERRQ(ierr); 56927f96f943SMatthew G. Knepley ierr = ISGetIndices(fieldIS, &fields);CHKERRQ(ierr); 56937f96f943SMatthew G. Knepley ierr = PetscArrayzero(exacts, Nf);CHKERRQ(ierr); 56947f96f943SMatthew G. Knepley ierr = PetscArrayzero(ectxs, Nf);CHKERRQ(ierr); 5695f2cacb80SMatthew G. Knepley if (u) { 56967f96f943SMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 56977f96f943SMatthew G. Knepley const PetscInt field = fields[f]; 56987f96f943SMatthew G. Knepley ierr = PetscDSGetExactSolution(ds, field, &exacts[field], &ectxs[field]);CHKERRQ(ierr); 56997f96f943SMatthew G. Knepley } 57007f96f943SMatthew G. Knepley ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr); 57017f96f943SMatthew G. Knepley if (label) { 57027f96f943SMatthew G. Knepley ierr = DMProjectFunctionLabel(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, u);CHKERRQ(ierr); 57037f96f943SMatthew G. Knepley } else { 57047f96f943SMatthew G. Knepley ierr = DMProjectFunction(dm, time, exacts, ectxs, INSERT_ALL_VALUES, u);CHKERRQ(ierr); 57057f96f943SMatthew G. Knepley } 57067f96f943SMatthew G. Knepley } 5707f2cacb80SMatthew G. Knepley if (u_t) { 5708f2cacb80SMatthew G. Knepley ierr = PetscArrayzero(exacts, Nf);CHKERRQ(ierr); 5709f2cacb80SMatthew G. Knepley ierr = PetscArrayzero(ectxs, Nf);CHKERRQ(ierr); 5710f2cacb80SMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 5711f2cacb80SMatthew G. Knepley const PetscInt field = fields[f]; 5712f2cacb80SMatthew G. Knepley ierr = PetscDSGetExactSolutionTimeDerivative(ds, field, &exacts[field], &ectxs[field]);CHKERRQ(ierr); 5713f2cacb80SMatthew G. Knepley } 5714f2cacb80SMatthew G. Knepley ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr); 5715f2cacb80SMatthew G. Knepley if (label) { 5716f2cacb80SMatthew G. Knepley ierr = DMProjectFunctionLabel(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, u_t);CHKERRQ(ierr); 5717f2cacb80SMatthew G. Knepley } else { 5718f2cacb80SMatthew G. Knepley ierr = DMProjectFunction(dm, time, exacts, ectxs, INSERT_ALL_VALUES, u_t);CHKERRQ(ierr); 5719f2cacb80SMatthew G. Knepley } 5720f2cacb80SMatthew G. Knepley } 5721f2cacb80SMatthew G. Knepley } 5722f2cacb80SMatthew G. Knepley if (u) { 57237f96f943SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) u, "Exact Solution");CHKERRQ(ierr); 57247f96f943SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) u, "exact_");CHKERRQ(ierr); 5725f2cacb80SMatthew G. Knepley } 5726f2cacb80SMatthew G. Knepley if (u_t) { 5727f2cacb80SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) u, "Exact Solution Time Derivative");CHKERRQ(ierr); 5728f2cacb80SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) u_t, "exact_t_");CHKERRQ(ierr); 5729f2cacb80SMatthew G. Knepley } 57307f96f943SMatthew G. Knepley ierr = PetscFree2(exacts, ectxs);CHKERRQ(ierr); 57317f96f943SMatthew G. Knepley PetscFunctionReturn(0); 57327f96f943SMatthew G. Knepley } 57337f96f943SMatthew G. Knepley 57347f96f943SMatthew G. Knepley /*@ 5735e5e52638SMatthew G. Knepley DMCopyDS - Copy the discrete systems for the DM into another DM 5736e5e52638SMatthew G. Knepley 5737d083f849SBarry Smith Collective on dm 5738e5e52638SMatthew G. Knepley 5739e5e52638SMatthew G. Knepley Input Parameter: 5740e5e52638SMatthew G. Knepley . dm - The DM 5741e5e52638SMatthew G. Knepley 5742e5e52638SMatthew G. Knepley Output Parameter: 5743e5e52638SMatthew G. Knepley . newdm - The DM 5744e5e52638SMatthew G. Knepley 5745e5e52638SMatthew G. Knepley Level: advanced 5746e5e52638SMatthew G. Knepley 5747e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS() 5748e5e52638SMatthew G. Knepley @*/ 5749e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDS(DM dm, DM newdm) 5750e5e52638SMatthew G. Knepley { 5751e5e52638SMatthew G. Knepley PetscInt Nds, s; 5752e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5753e5e52638SMatthew G. Knepley 5754e5e52638SMatthew G. Knepley PetscFunctionBegin; 5755e5e52638SMatthew G. Knepley if (dm == newdm) PetscFunctionReturn(0); 5756e5e52638SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 5757e5e52638SMatthew G. Knepley ierr = DMClearDS(newdm);CHKERRQ(ierr); 5758e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5759e5e52638SMatthew G. Knepley DMLabel label; 5760b3cf3223SMatthew G. Knepley IS fields; 5761e5e52638SMatthew G. Knepley PetscDS ds; 5762783e2ec8SMatthew G. Knepley PetscInt Nbd, bd; 5763e5e52638SMatthew G. Knepley 5764b3cf3223SMatthew G. Knepley ierr = DMGetRegionNumDS(dm, s, &label, &fields, &ds);CHKERRQ(ierr); 5765b3cf3223SMatthew G. Knepley ierr = DMSetRegionDS(newdm, label, fields, ds);CHKERRQ(ierr); 5766783e2ec8SMatthew G. Knepley ierr = PetscDSGetNumBoundary(ds, &Nbd);CHKERRQ(ierr); 5767783e2ec8SMatthew G. Knepley for (bd = 0; bd < Nbd; ++bd) { 5768783e2ec8SMatthew G. Knepley const char *labelname, *name; 5769783e2ec8SMatthew G. Knepley PetscInt field; 5770783e2ec8SMatthew G. Knepley 5771783e2ec8SMatthew G. Knepley /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */ 577256cf3b9cSMatthew G. Knepley ierr = PetscDSGetBoundary(ds, bd, NULL, &name, &labelname, &field, NULL, NULL, NULL, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 5773783e2ec8SMatthew G. Knepley ierr = DMCompleteBoundaryLabel_Internal(newdm, ds, field, bd, labelname);CHKERRQ(ierr); 5774783e2ec8SMatthew G. Knepley } 5775e5e52638SMatthew G. Knepley } 5776e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5777e5e52638SMatthew G. Knepley } 5778e5e52638SMatthew G. Knepley 5779e5e52638SMatthew G. Knepley /*@ 5780e5e52638SMatthew G. Knepley DMCopyDisc - Copy the fields and discrete systems for the DM into another DM 5781e5e52638SMatthew G. Knepley 5782d083f849SBarry Smith Collective on dm 5783e5e52638SMatthew G. Knepley 5784e5e52638SMatthew G. Knepley Input Parameter: 5785e5e52638SMatthew G. Knepley . dm - The DM 5786e5e52638SMatthew G. Knepley 5787e5e52638SMatthew G. Knepley Output Parameter: 5788e5e52638SMatthew G. Knepley . newdm - The DM 5789e5e52638SMatthew G. Knepley 5790e5e52638SMatthew G. Knepley Level: advanced 5791e5e52638SMatthew G. Knepley 5792e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMCopyDS() 5793e5e52638SMatthew G. Knepley @*/ 5794e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDisc(DM dm, DM newdm) 5795e5e52638SMatthew G. Knepley { 5796e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5797e5e52638SMatthew G. Knepley 5798e5e52638SMatthew G. Knepley PetscFunctionBegin; 5799e5e52638SMatthew G. Knepley ierr = DMCopyFields(dm, newdm);CHKERRQ(ierr); 5800e5e52638SMatthew G. Knepley ierr = DMCopyDS(dm, newdm);CHKERRQ(ierr); 5801e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5802e5e52638SMatthew G. Knepley } 5803e5e52638SMatthew G. Knepley 5804b64e0483SPeter Brune PetscErrorCode DMRestrictHook_Coordinates(DM dm,DM dmc,void *ctx) 5805b64e0483SPeter Brune { 5806b64e0483SPeter Brune DM dm_coord,dmc_coord; 5807b64e0483SPeter Brune PetscErrorCode ierr; 5808b64e0483SPeter Brune Vec coords,ccoords; 58096dbf9973SLawrence Mitchell Mat inject; 5810b64e0483SPeter Brune PetscFunctionBegin; 5811b64e0483SPeter Brune ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr); 5812b64e0483SPeter Brune ierr = DMGetCoordinateDM(dmc,&dmc_coord);CHKERRQ(ierr); 5813b64e0483SPeter Brune ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr); 5814b64e0483SPeter Brune ierr = DMGetCoordinates(dmc,&ccoords);CHKERRQ(ierr); 5815b64e0483SPeter Brune if (coords && !ccoords) { 5816b64e0483SPeter Brune ierr = DMCreateGlobalVector(dmc_coord,&ccoords);CHKERRQ(ierr); 58176668ed41SLisandro Dalcin ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr); 58186dbf9973SLawrence Mitchell ierr = DMCreateInjection(dmc_coord,dm_coord,&inject);CHKERRQ(ierr); 58192adcf181SLawrence Mitchell ierr = MatRestrict(inject,coords,ccoords);CHKERRQ(ierr); 58206dbf9973SLawrence Mitchell ierr = MatDestroy(&inject);CHKERRQ(ierr); 5821b64e0483SPeter Brune ierr = DMSetCoordinates(dmc,ccoords);CHKERRQ(ierr); 5822b64e0483SPeter Brune ierr = VecDestroy(&ccoords);CHKERRQ(ierr); 5823b64e0483SPeter Brune } 5824b64e0483SPeter Brune PetscFunctionReturn(0); 5825b64e0483SPeter Brune } 5826b64e0483SPeter Brune 582703dadc2fSPeter Brune static PetscErrorCode DMSubDomainHook_Coordinates(DM dm,DM subdm,void *ctx) 582803dadc2fSPeter Brune { 582903dadc2fSPeter Brune DM dm_coord,subdm_coord; 583003dadc2fSPeter Brune PetscErrorCode ierr; 583103dadc2fSPeter Brune Vec coords,ccoords,clcoords; 583203dadc2fSPeter Brune VecScatter *scat_i,*scat_g; 583303dadc2fSPeter Brune PetscFunctionBegin; 583403dadc2fSPeter Brune ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr); 583503dadc2fSPeter Brune ierr = DMGetCoordinateDM(subdm,&subdm_coord);CHKERRQ(ierr); 583603dadc2fSPeter Brune ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr); 583703dadc2fSPeter Brune ierr = DMGetCoordinates(subdm,&ccoords);CHKERRQ(ierr); 583803dadc2fSPeter Brune if (coords && !ccoords) { 583903dadc2fSPeter Brune ierr = DMCreateGlobalVector(subdm_coord,&ccoords);CHKERRQ(ierr); 58406668ed41SLisandro Dalcin ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr); 584103dadc2fSPeter Brune ierr = DMCreateLocalVector(subdm_coord,&clcoords);CHKERRQ(ierr); 584224640c55SToby Isaac ierr = PetscObjectSetName((PetscObject)clcoords,"coordinates");CHKERRQ(ierr); 584303dadc2fSPeter Brune ierr = DMCreateDomainDecompositionScatters(dm_coord,1,&subdm_coord,NULL,&scat_i,&scat_g);CHKERRQ(ierr); 584403dadc2fSPeter Brune ierr = VecScatterBegin(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 584503dadc2fSPeter Brune ierr = VecScatterEnd(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 58461ed9ada7SJunchao Zhang ierr = VecScatterBegin(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 584703dadc2fSPeter Brune ierr = VecScatterEnd(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 584803dadc2fSPeter Brune ierr = DMSetCoordinates(subdm,ccoords);CHKERRQ(ierr); 584903dadc2fSPeter Brune ierr = DMSetCoordinatesLocal(subdm,clcoords);CHKERRQ(ierr); 585003dadc2fSPeter Brune ierr = VecScatterDestroy(&scat_i[0]);CHKERRQ(ierr); 585103dadc2fSPeter Brune ierr = VecScatterDestroy(&scat_g[0]);CHKERRQ(ierr); 585203dadc2fSPeter Brune ierr = VecDestroy(&ccoords);CHKERRQ(ierr); 585303dadc2fSPeter Brune ierr = VecDestroy(&clcoords);CHKERRQ(ierr); 585403dadc2fSPeter Brune ierr = PetscFree(scat_i);CHKERRQ(ierr); 585503dadc2fSPeter Brune ierr = PetscFree(scat_g);CHKERRQ(ierr); 585603dadc2fSPeter Brune } 585703dadc2fSPeter Brune PetscFunctionReturn(0); 585803dadc2fSPeter Brune } 585903dadc2fSPeter Brune 5860c73cfb54SMatthew G. Knepley /*@ 5861c73cfb54SMatthew G. Knepley DMGetDimension - Return the topological dimension of the DM 5862c73cfb54SMatthew G. Knepley 5863c73cfb54SMatthew G. Knepley Not collective 5864c73cfb54SMatthew G. Knepley 5865c73cfb54SMatthew G. Knepley Input Parameter: 5866c73cfb54SMatthew G. Knepley . dm - The DM 5867c73cfb54SMatthew G. Knepley 5868c73cfb54SMatthew G. Knepley Output Parameter: 5869c73cfb54SMatthew G. Knepley . dim - The topological dimension 5870c73cfb54SMatthew G. Knepley 5871c73cfb54SMatthew G. Knepley Level: beginner 5872c73cfb54SMatthew G. Knepley 5873c73cfb54SMatthew G. Knepley .seealso: DMSetDimension(), DMCreate() 5874c73cfb54SMatthew G. Knepley @*/ 5875c73cfb54SMatthew G. Knepley PetscErrorCode DMGetDimension(DM dm, PetscInt *dim) 5876c73cfb54SMatthew G. Knepley { 5877c73cfb54SMatthew G. Knepley PetscFunctionBegin; 5878c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5879534a8f05SLisandro Dalcin PetscValidIntPointer(dim, 2); 5880c73cfb54SMatthew G. Knepley *dim = dm->dim; 5881c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 5882c73cfb54SMatthew G. Knepley } 5883c73cfb54SMatthew G. Knepley 5884c73cfb54SMatthew G. Knepley /*@ 5885c73cfb54SMatthew G. Knepley DMSetDimension - Set the topological dimension of the DM 5886c73cfb54SMatthew G. Knepley 5887c73cfb54SMatthew G. Knepley Collective on dm 5888c73cfb54SMatthew G. Knepley 5889c73cfb54SMatthew G. Knepley Input Parameters: 5890c73cfb54SMatthew G. Knepley + dm - The DM 5891c73cfb54SMatthew G. Knepley - dim - The topological dimension 5892c73cfb54SMatthew G. Knepley 5893c73cfb54SMatthew G. Knepley Level: beginner 5894c73cfb54SMatthew G. Knepley 5895c73cfb54SMatthew G. Knepley .seealso: DMGetDimension(), DMCreate() 5896c73cfb54SMatthew G. Knepley @*/ 5897c73cfb54SMatthew G. Knepley PetscErrorCode DMSetDimension(DM dm, PetscInt dim) 5898c73cfb54SMatthew G. Knepley { 5899e5e52638SMatthew G. Knepley PetscDS ds; 5900f17e8794SMatthew G. Knepley PetscErrorCode ierr; 5901f17e8794SMatthew G. Knepley 5902c73cfb54SMatthew G. Knepley PetscFunctionBegin; 5903c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5904c73cfb54SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 5905c73cfb54SMatthew G. Knepley dm->dim = dim; 5906e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 5907e5e52638SMatthew G. Knepley if (ds->dimEmbed < 0) {ierr = PetscDSSetCoordinateDimension(ds, dm->dim);CHKERRQ(ierr);} 5908c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 5909c73cfb54SMatthew G. Knepley } 5910c73cfb54SMatthew G. Knepley 5911793f3fe5SMatthew G. Knepley /*@ 5912793f3fe5SMatthew G. Knepley DMGetDimPoints - Get the half-open interval for all points of a given dimension 5913793f3fe5SMatthew G. Knepley 5914d083f849SBarry Smith Collective on dm 5915793f3fe5SMatthew G. Knepley 5916793f3fe5SMatthew G. Knepley Input Parameters: 5917793f3fe5SMatthew G. Knepley + dm - the DM 5918793f3fe5SMatthew G. Knepley - dim - the dimension 5919793f3fe5SMatthew G. Knepley 5920793f3fe5SMatthew G. Knepley Output Parameters: 5921793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension 5922aa049354SPatrick Sanan - pEnd - The first point following points of the given dimension 5923793f3fe5SMatthew G. Knepley 5924793f3fe5SMatthew G. Knepley Note: 5925793f3fe5SMatthew G. Knepley The points are vertices in the Hasse diagram encoding the topology. This is explained in 5926a8d69d7bSBarry Smith https://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme, 5927793f3fe5SMatthew G. Knepley then the interval is empty. 5928793f3fe5SMatthew G. Knepley 5929793f3fe5SMatthew G. Knepley Level: intermediate 5930793f3fe5SMatthew G. Knepley 5931793f3fe5SMatthew G. Knepley .seealso: DMPLEX, DMPlexGetDepthStratum(), DMPlexGetHeightStratum() 5932793f3fe5SMatthew G. Knepley @*/ 5933793f3fe5SMatthew G. Knepley PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 5934793f3fe5SMatthew G. Knepley { 5935793f3fe5SMatthew G. Knepley PetscInt d; 5936793f3fe5SMatthew G. Knepley PetscErrorCode ierr; 5937793f3fe5SMatthew G. Knepley 5938793f3fe5SMatthew G. Knepley PetscFunctionBegin; 5939793f3fe5SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 5940793f3fe5SMatthew G. Knepley ierr = DMGetDimension(dm, &d);CHKERRQ(ierr); 5941793f3fe5SMatthew G. Knepley if ((dim < 0) || (dim > d)) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %d 1", dim, d); 5942b9d85ea2SLisandro Dalcin if (!dm->ops->getdimpoints) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "DM type %s does not implement DMGetDimPoints",((PetscObject)dm)->type_name); 5943793f3fe5SMatthew G. Knepley ierr = (*dm->ops->getdimpoints)(dm, dim, pStart, pEnd);CHKERRQ(ierr); 5944793f3fe5SMatthew G. Knepley PetscFunctionReturn(0); 5945793f3fe5SMatthew G. Knepley } 5946793f3fe5SMatthew G. Knepley 59476636e97aSMatthew G Knepley /*@ 59486636e97aSMatthew G Knepley DMSetCoordinates - Sets into the DM a global vector that holds the coordinates 59496636e97aSMatthew G Knepley 5950d083f849SBarry Smith Collective on dm 59516636e97aSMatthew G Knepley 59526636e97aSMatthew G Knepley Input Parameters: 59536636e97aSMatthew G Knepley + dm - the DM 59546636e97aSMatthew G Knepley - c - coordinate vector 59556636e97aSMatthew G Knepley 59562dd40e9bSPatrick Sanan Notes: 59572dd40e9bSPatrick Sanan The coordinates do include those for ghost points, which are in the local vector. 59582dd40e9bSPatrick Sanan 59592dd40e9bSPatrick Sanan The vector c should be destroyed by the caller. 59606636e97aSMatthew G Knepley 59616636e97aSMatthew G Knepley Level: intermediate 59626636e97aSMatthew G Knepley 596360c22052SBarry Smith .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMDASetUniformCoordinates() 59646636e97aSMatthew G Knepley @*/ 59656636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c) 59666636e97aSMatthew G Knepley { 59676636e97aSMatthew G Knepley PetscErrorCode ierr; 59686636e97aSMatthew G Knepley 59696636e97aSMatthew G Knepley PetscFunctionBegin; 59706636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 59716636e97aSMatthew G Knepley PetscValidHeaderSpecific(c,VEC_CLASSID,2); 59726636e97aSMatthew G Knepley ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr); 59736636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr); 59746636e97aSMatthew G Knepley dm->coordinates = c; 59756636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr); 5976b64e0483SPeter Brune ierr = DMCoarsenHookAdd(dm,DMRestrictHook_Coordinates,NULL,NULL);CHKERRQ(ierr); 597703dadc2fSPeter Brune ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_Coordinates,NULL,NULL);CHKERRQ(ierr); 59786636e97aSMatthew G Knepley PetscFunctionReturn(0); 59796636e97aSMatthew G Knepley } 59806636e97aSMatthew G Knepley 59816636e97aSMatthew G Knepley /*@ 59826636e97aSMatthew G Knepley DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates 59836636e97aSMatthew G Knepley 59847058e716SVaclav Hapla Not collective 59856636e97aSMatthew G Knepley 59866636e97aSMatthew G Knepley Input Parameters: 59876636e97aSMatthew G Knepley + dm - the DM 59886636e97aSMatthew G Knepley - c - coordinate vector 59896636e97aSMatthew G Knepley 59902dd40e9bSPatrick Sanan Notes: 59916636e97aSMatthew G Knepley The coordinates of ghost points can be set using DMSetCoordinates() 59926636e97aSMatthew G Knepley followed by DMGetCoordinatesLocal(). This is intended to enable the 59936636e97aSMatthew G Knepley setting of ghost coordinates outside of the domain. 59946636e97aSMatthew G Knepley 59952dd40e9bSPatrick Sanan The vector c should be destroyed by the caller. 59962dd40e9bSPatrick Sanan 59976636e97aSMatthew G Knepley Level: intermediate 59986636e97aSMatthew G Knepley 59996636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM() 60006636e97aSMatthew G Knepley @*/ 60016636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c) 60026636e97aSMatthew G Knepley { 60036636e97aSMatthew G Knepley PetscErrorCode ierr; 60046636e97aSMatthew G Knepley 60056636e97aSMatthew G Knepley PetscFunctionBegin; 60066636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 60076636e97aSMatthew G Knepley PetscValidHeaderSpecific(c,VEC_CLASSID,2); 60086636e97aSMatthew G Knepley ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr); 60096636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr); 60108865f1eaSKarl Rupp 60116636e97aSMatthew G Knepley dm->coordinatesLocal = c; 60128865f1eaSKarl Rupp 60136636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr); 60146636e97aSMatthew G Knepley PetscFunctionReturn(0); 60156636e97aSMatthew G Knepley } 60166636e97aSMatthew G Knepley 60176636e97aSMatthew G Knepley /*@ 60186636e97aSMatthew G Knepley DMGetCoordinates - Gets a global vector with the coordinates associated with the DM. 60196636e97aSMatthew G Knepley 6020d083f849SBarry Smith Collective on dm 60216636e97aSMatthew G Knepley 60226636e97aSMatthew G Knepley Input Parameter: 60236636e97aSMatthew G Knepley . dm - the DM 60246636e97aSMatthew G Knepley 60256636e97aSMatthew G Knepley Output Parameter: 60266636e97aSMatthew G Knepley . c - global coordinate vector 60276636e97aSMatthew G Knepley 60286636e97aSMatthew G Knepley Note: 602960c22052SBarry Smith This is a borrowed reference, so the user should NOT destroy this vector. When the DM is 603060c22052SBarry Smith destroyed the array will no longer be valid. 60316636e97aSMatthew G Knepley 60326636e97aSMatthew G Knepley Each process has only the local coordinates (does NOT have the ghost coordinates). 60336636e97aSMatthew G Knepley 60346636e97aSMatthew G Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 60356636e97aSMatthew G Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 60366636e97aSMatthew G Knepley 60376636e97aSMatthew G Knepley Level: intermediate 60386636e97aSMatthew G Knepley 603960c22052SBarry Smith .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMDASetUniformCoordinates() 60406636e97aSMatthew G Knepley @*/ 60416636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c) 60426636e97aSMatthew G Knepley { 60436636e97aSMatthew G Knepley PetscErrorCode ierr; 60446636e97aSMatthew G Knepley 60456636e97aSMatthew G Knepley PetscFunctionBegin; 60466636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 60476636e97aSMatthew G Knepley PetscValidPointer(c,2); 60481f588964SMatthew G Knepley if (!dm->coordinates && dm->coordinatesLocal) { 60490298fd71SBarry Smith DM cdm = NULL; 60501970a576SMatthew G. Knepley PetscBool localized; 60516636e97aSMatthew G Knepley 60526636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 60536636e97aSMatthew G Knepley ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr); 60541970a576SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 60551970a576SMatthew G. Knepley /* Block size is not correctly set by CreateGlobalVector() if coordinates are localized */ 60561970a576SMatthew G. Knepley if (localized) { 60571970a576SMatthew G. Knepley PetscInt cdim; 60581970a576SMatthew G. Knepley 60591970a576SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 60601970a576SMatthew G. Knepley ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr); 60611970a576SMatthew G. Knepley } 60626636e97aSMatthew G Knepley ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr); 60636636e97aSMatthew G Knepley ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr); 60646636e97aSMatthew G Knepley ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr); 60656636e97aSMatthew G Knepley } 60666636e97aSMatthew G Knepley *c = dm->coordinates; 60676636e97aSMatthew G Knepley PetscFunctionReturn(0); 60686636e97aSMatthew G Knepley } 60696636e97aSMatthew G Knepley 60706636e97aSMatthew G Knepley /*@ 607181e9a530SVaclav Hapla DMGetCoordinatesLocalSetUp - Prepares a local vector of coordinates, so that DMGetCoordinatesLocalNoncollective() can be used as non-collective afterwards. 607281e9a530SVaclav Hapla 6073d083f849SBarry Smith Collective on dm 607481e9a530SVaclav Hapla 607581e9a530SVaclav Hapla Input Parameter: 607681e9a530SVaclav Hapla . dm - the DM 607781e9a530SVaclav Hapla 607881e9a530SVaclav Hapla Level: advanced 607981e9a530SVaclav Hapla 608081e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalNoncollective() 608181e9a530SVaclav Hapla @*/ 608281e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalSetUp(DM dm) 608381e9a530SVaclav Hapla { 608481e9a530SVaclav Hapla PetscErrorCode ierr; 608581e9a530SVaclav Hapla 608681e9a530SVaclav Hapla PetscFunctionBegin; 608781e9a530SVaclav Hapla PetscValidHeaderSpecific(dm,DM_CLASSID,1); 608881e9a530SVaclav Hapla if (!dm->coordinatesLocal && dm->coordinates) { 60891970a576SMatthew G. Knepley DM cdm = NULL; 60901970a576SMatthew G. Knepley PetscBool localized; 60911970a576SMatthew G. Knepley 609281e9a530SVaclav Hapla ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 609381e9a530SVaclav Hapla ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr); 60941970a576SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 60951970a576SMatthew G. Knepley /* Block size is not correctly set by CreateLocalVector() if coordinates are localized */ 60961970a576SMatthew G. Knepley if (localized) { 60971970a576SMatthew G. Knepley PetscInt cdim; 60981970a576SMatthew G. Knepley 60991970a576SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 61001970a576SMatthew G. Knepley ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr); 61011970a576SMatthew G. Knepley } 610281e9a530SVaclav Hapla ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr); 610381e9a530SVaclav Hapla ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr); 610481e9a530SVaclav Hapla ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr); 610581e9a530SVaclav Hapla } 610681e9a530SVaclav Hapla PetscFunctionReturn(0); 610781e9a530SVaclav Hapla } 610881e9a530SVaclav Hapla 610981e9a530SVaclav Hapla /*@ 61106636e97aSMatthew G Knepley DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM. 61116636e97aSMatthew G Knepley 6112d083f849SBarry Smith Collective on dm 61136636e97aSMatthew G Knepley 61146636e97aSMatthew G Knepley Input Parameter: 61156636e97aSMatthew G Knepley . dm - the DM 61166636e97aSMatthew G Knepley 61176636e97aSMatthew G Knepley Output Parameter: 61186636e97aSMatthew G Knepley . c - coordinate vector 61196636e97aSMatthew G Knepley 61206636e97aSMatthew G Knepley Note: 61216636e97aSMatthew G Knepley This is a borrowed reference, so the user should NOT destroy this vector 61226636e97aSMatthew G Knepley 61236636e97aSMatthew G Knepley Each process has the local and ghost coordinates 61246636e97aSMatthew G Knepley 61256636e97aSMatthew G Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 61266636e97aSMatthew G Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 61276636e97aSMatthew G Knepley 61286636e97aSMatthew G Knepley Level: intermediate 61296636e97aSMatthew G Knepley 613081e9a530SVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM(), DMGetCoordinatesLocalNoncollective() 61316636e97aSMatthew G Knepley @*/ 61326636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c) 61336636e97aSMatthew G Knepley { 61346636e97aSMatthew G Knepley PetscErrorCode ierr; 61356636e97aSMatthew G Knepley 61366636e97aSMatthew G Knepley PetscFunctionBegin; 61376636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 61386636e97aSMatthew G Knepley PetscValidPointer(c,2); 613981e9a530SVaclav Hapla ierr = DMGetCoordinatesLocalSetUp(dm);CHKERRQ(ierr); 61406636e97aSMatthew G Knepley *c = dm->coordinatesLocal; 61416636e97aSMatthew G Knepley PetscFunctionReturn(0); 61426636e97aSMatthew G Knepley } 61436636e97aSMatthew G Knepley 614481e9a530SVaclav Hapla /*@ 614581e9a530SVaclav Hapla DMGetCoordinatesLocalNoncollective - Non-collective version of DMGetCoordinatesLocal(). Fails if global coordinates have been set and DMGetCoordinatesLocalSetUp() not called. 614681e9a530SVaclav Hapla 614781e9a530SVaclav Hapla Not collective 614881e9a530SVaclav Hapla 614981e9a530SVaclav Hapla Input Parameter: 615081e9a530SVaclav Hapla . dm - the DM 615181e9a530SVaclav Hapla 615281e9a530SVaclav Hapla Output Parameter: 615381e9a530SVaclav Hapla . c - coordinate vector 615481e9a530SVaclav Hapla 615581e9a530SVaclav Hapla Level: advanced 615681e9a530SVaclav Hapla 615781e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalSetUp(), DMGetCoordinatesLocal(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM() 615881e9a530SVaclav Hapla @*/ 615981e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalNoncollective(DM dm, Vec *c) 616081e9a530SVaclav Hapla { 616181e9a530SVaclav Hapla PetscFunctionBegin; 616281e9a530SVaclav Hapla PetscValidHeaderSpecific(dm,DM_CLASSID,1); 616381e9a530SVaclav Hapla PetscValidPointer(c,2); 616481e9a530SVaclav Hapla if (!dm->coordinatesLocal && dm->coordinates) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called"); 61656636e97aSMatthew G Knepley *c = dm->coordinatesLocal; 61666636e97aSMatthew G Knepley PetscFunctionReturn(0); 61676636e97aSMatthew G Knepley } 61686636e97aSMatthew G Knepley 61692db98f8dSVaclav Hapla /*@ 61702db98f8dSVaclav Hapla DMGetCoordinatesLocalTuple - Gets a local vector with the coordinates of specified points and section describing its layout. 61712db98f8dSVaclav Hapla 61722db98f8dSVaclav Hapla Not collective 61732db98f8dSVaclav Hapla 61742db98f8dSVaclav Hapla Input Parameter: 61752db98f8dSVaclav Hapla + dm - the DM 61762db98f8dSVaclav Hapla - p - the IS of points whose coordinates will be returned 61772db98f8dSVaclav Hapla 61782db98f8dSVaclav Hapla Output Parameter: 61792db98f8dSVaclav Hapla + pCoordSection - the PetscSection describing the layout of pCoord, i.e. each point corresponds to one point in p, and DOFs correspond to coordinates 61802db98f8dSVaclav Hapla - pCoord - the Vec with coordinates of points in p 61812db98f8dSVaclav Hapla 61822db98f8dSVaclav Hapla Note: 61832db98f8dSVaclav Hapla DMGetCoordinatesLocalSetUp() must be called first. This function employs DMGetCoordinatesLocalNoncollective() so it is not collective. 61842db98f8dSVaclav Hapla 61852db98f8dSVaclav Hapla This creates a new vector, so the user SHOULD destroy this vector 61862db98f8dSVaclav Hapla 61872db98f8dSVaclav Hapla Each process has the local and ghost coordinates 61882db98f8dSVaclav Hapla 61892db98f8dSVaclav Hapla For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 61902db98f8dSVaclav Hapla and (x_0,y_0,z_0,x_1,y_1,z_1...) 61912db98f8dSVaclav Hapla 61922db98f8dSVaclav Hapla Level: advanced 61932db98f8dSVaclav Hapla 61942db98f8dSVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinatesLocal(), DMGetCoordinatesLocalNoncollective(), DMGetCoordinatesLocalSetUp(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM() 61952db98f8dSVaclav Hapla @*/ 61962db98f8dSVaclav Hapla PetscErrorCode DMGetCoordinatesLocalTuple(DM dm, IS p, PetscSection *pCoordSection, Vec *pCoord) 61972db98f8dSVaclav Hapla { 61982db98f8dSVaclav Hapla PetscSection cs, newcs; 61992db98f8dSVaclav Hapla Vec coords; 62002db98f8dSVaclav Hapla const PetscScalar *arr; 62012db98f8dSVaclav Hapla PetscScalar *newarr=NULL; 62022db98f8dSVaclav Hapla PetscInt n; 62032db98f8dSVaclav Hapla PetscErrorCode ierr; 62042db98f8dSVaclav Hapla 62052db98f8dSVaclav Hapla PetscFunctionBegin; 62062db98f8dSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 62072db98f8dSVaclav Hapla PetscValidHeaderSpecific(p, IS_CLASSID, 2); 62082db98f8dSVaclav Hapla if (pCoordSection) PetscValidPointer(pCoordSection, 3); 62092db98f8dSVaclav Hapla if (pCoord) PetscValidPointer(pCoord, 4); 62102db98f8dSVaclav Hapla if (!dm->coordinatesLocal) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called or coordinates not set"); 62111bb6d2a8SBarry Smith if (!dm->coordinateDM || !dm->coordinateDM->localSection) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM not supported"); 62121bb6d2a8SBarry Smith cs = dm->coordinateDM->localSection; 62132db98f8dSVaclav Hapla coords = dm->coordinatesLocal; 62142db98f8dSVaclav Hapla ierr = VecGetArrayRead(coords, &arr);CHKERRQ(ierr); 62152db98f8dSVaclav Hapla ierr = PetscSectionExtractDofsFromArray(cs, MPIU_SCALAR, arr, p, &newcs, pCoord ? ((void**)&newarr) : NULL);CHKERRQ(ierr); 62162db98f8dSVaclav Hapla ierr = VecRestoreArrayRead(coords, &arr);CHKERRQ(ierr); 62172db98f8dSVaclav Hapla if (pCoord) { 62182db98f8dSVaclav Hapla ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr); 62192db98f8dSVaclav Hapla /* set array in two steps to mimic PETSC_OWN_POINTER */ 62202db98f8dSVaclav Hapla ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)p), 1, n, NULL, pCoord);CHKERRQ(ierr); 62212db98f8dSVaclav Hapla ierr = VecReplaceArray(*pCoord, newarr);CHKERRQ(ierr); 6222ad9ac99dSVaclav Hapla } else { 6223ad9ac99dSVaclav Hapla ierr = PetscFree(newarr);CHKERRQ(ierr); 62242db98f8dSVaclav Hapla } 6225ad9ac99dSVaclav Hapla if (pCoordSection) {*pCoordSection = newcs;} 6226ad9ac99dSVaclav Hapla else {ierr = PetscSectionDestroy(&newcs);CHKERRQ(ierr);} 62272db98f8dSVaclav Hapla PetscFunctionReturn(0); 62282db98f8dSVaclav Hapla } 62292db98f8dSVaclav Hapla 6230f19dbd58SToby Isaac PetscErrorCode DMGetCoordinateField(DM dm, DMField *field) 6231f19dbd58SToby Isaac { 6232f19dbd58SToby Isaac PetscErrorCode ierr; 6233f19dbd58SToby Isaac 6234f19dbd58SToby Isaac PetscFunctionBegin; 6235f19dbd58SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6236f19dbd58SToby Isaac PetscValidPointer(field,2); 6237f19dbd58SToby Isaac if (!dm->coordinateField) { 6238f19dbd58SToby Isaac if (dm->ops->createcoordinatefield) { 6239f19dbd58SToby Isaac ierr = (*dm->ops->createcoordinatefield)(dm,&dm->coordinateField);CHKERRQ(ierr); 6240f19dbd58SToby Isaac } 6241f19dbd58SToby Isaac } 6242f19dbd58SToby Isaac *field = dm->coordinateField; 6243f19dbd58SToby Isaac PetscFunctionReturn(0); 6244f19dbd58SToby Isaac } 6245f19dbd58SToby Isaac 6246f19dbd58SToby Isaac PetscErrorCode DMSetCoordinateField(DM dm, DMField field) 6247f19dbd58SToby Isaac { 6248f19dbd58SToby Isaac PetscErrorCode ierr; 6249f19dbd58SToby Isaac 6250f19dbd58SToby Isaac PetscFunctionBegin; 6251f19dbd58SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6252f19dbd58SToby Isaac if (field) PetscValidHeaderSpecific(field,DMFIELD_CLASSID,2); 6253c4e6da2cSBarry Smith ierr = PetscObjectReference((PetscObject)field);CHKERRQ(ierr); 6254f19dbd58SToby Isaac ierr = DMFieldDestroy(&dm->coordinateField);CHKERRQ(ierr); 6255f19dbd58SToby Isaac dm->coordinateField = field; 6256f19dbd58SToby Isaac PetscFunctionReturn(0); 6257f19dbd58SToby Isaac } 6258f19dbd58SToby Isaac 62596636e97aSMatthew G Knepley /*@ 62601cfe2091SMatthew G. Knepley DMGetCoordinateDM - Gets the DM that prescribes coordinate layout and scatters between global and local coordinates 62616636e97aSMatthew G Knepley 6262d083f849SBarry Smith Collective on dm 62636636e97aSMatthew G Knepley 62646636e97aSMatthew G Knepley Input Parameter: 62656636e97aSMatthew G Knepley . dm - the DM 62666636e97aSMatthew G Knepley 62676636e97aSMatthew G Knepley Output Parameter: 62686636e97aSMatthew G Knepley . cdm - coordinate DM 62696636e97aSMatthew G Knepley 62706636e97aSMatthew G Knepley Level: intermediate 62716636e97aSMatthew G Knepley 62721cfe2091SMatthew G. Knepley .seealso: DMSetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal() 62736636e97aSMatthew G Knepley @*/ 62746636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm) 62756636e97aSMatthew G Knepley { 62766636e97aSMatthew G Knepley PetscErrorCode ierr; 62776636e97aSMatthew G Knepley 62786636e97aSMatthew G Knepley PetscFunctionBegin; 62796636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 62806636e97aSMatthew G Knepley PetscValidPointer(cdm,2); 62816636e97aSMatthew G Knepley if (!dm->coordinateDM) { 6282308f8a94SToby Isaac DM cdm; 6283308f8a94SToby Isaac 628482f516ccSBarry Smith if (!dm->ops->createcoordinatedm) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unable to create coordinates for this DM"); 6285308f8a94SToby Isaac ierr = (*dm->ops->createcoordinatedm)(dm, &cdm);CHKERRQ(ierr); 6286308f8a94SToby Isaac /* Just in case the DM sets the coordinate DM when creating it (DMP4est can do this, because it may not setup 6287308f8a94SToby Isaac * until the call to CreateCoordinateDM) */ 6288308f8a94SToby Isaac ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr); 6289308f8a94SToby Isaac dm->coordinateDM = cdm; 62906636e97aSMatthew G Knepley } 62916636e97aSMatthew G Knepley *cdm = dm->coordinateDM; 62926636e97aSMatthew G Knepley PetscFunctionReturn(0); 62936636e97aSMatthew G Knepley } 6294e87bb0d3SMatthew G Knepley 62951cfe2091SMatthew G. Knepley /*@ 62961cfe2091SMatthew G. Knepley DMSetCoordinateDM - Sets the DM that prescribes coordinate layout and scatters between global and local coordinates 62971cfe2091SMatthew G. Knepley 6298d083f849SBarry Smith Logically Collective on dm 62991cfe2091SMatthew G. Knepley 63001cfe2091SMatthew G. Knepley Input Parameters: 63011cfe2091SMatthew G. Knepley + dm - the DM 63021cfe2091SMatthew G. Knepley - cdm - coordinate DM 63031cfe2091SMatthew G. Knepley 63041cfe2091SMatthew G. Knepley Level: intermediate 63051cfe2091SMatthew G. Knepley 63061cfe2091SMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal() 63071cfe2091SMatthew G. Knepley @*/ 63081cfe2091SMatthew G. Knepley PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm) 63091cfe2091SMatthew G. Knepley { 63101cfe2091SMatthew G. Knepley PetscErrorCode ierr; 63111cfe2091SMatthew G. Knepley 63121cfe2091SMatthew G. Knepley PetscFunctionBegin; 63131cfe2091SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 63141cfe2091SMatthew G. Knepley PetscValidHeaderSpecific(cdm,DM_CLASSID,2); 6315f26b38b9SToby Isaac ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr); 63161cfe2091SMatthew G. Knepley ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr); 63171cfe2091SMatthew G. Knepley dm->coordinateDM = cdm; 63181cfe2091SMatthew G. Knepley PetscFunctionReturn(0); 63191cfe2091SMatthew G. Knepley } 63201cfe2091SMatthew G. Knepley 632146e270d4SMatthew G. Knepley /*@ 632246e270d4SMatthew G. Knepley DMGetCoordinateDim - Retrieve the dimension of embedding space for coordinate values. 632346e270d4SMatthew G. Knepley 632446e270d4SMatthew G. Knepley Not Collective 632546e270d4SMatthew G. Knepley 632646e270d4SMatthew G. Knepley Input Parameter: 632746e270d4SMatthew G. Knepley . dm - The DM object 632846e270d4SMatthew G. Knepley 632946e270d4SMatthew G. Knepley Output Parameter: 633046e270d4SMatthew G. Knepley . dim - The embedding dimension 633146e270d4SMatthew G. Knepley 633246e270d4SMatthew G. Knepley Level: intermediate 633346e270d4SMatthew G. Knepley 633492fd8e1eSJed Brown .seealso: DMSetCoordinateDim(), DMGetCoordinateSection(), DMGetCoordinateDM(), DMGetLocalSection(), DMSetLocalSection() 633546e270d4SMatthew G. Knepley @*/ 633646e270d4SMatthew G. Knepley PetscErrorCode DMGetCoordinateDim(DM dm, PetscInt *dim) 633746e270d4SMatthew G. Knepley { 633846e270d4SMatthew G. Knepley PetscFunctionBegin; 633946e270d4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6340534a8f05SLisandro Dalcin PetscValidIntPointer(dim, 2); 63419a9a41abSToby Isaac if (dm->dimEmbed == PETSC_DEFAULT) { 63429a9a41abSToby Isaac dm->dimEmbed = dm->dim; 63439a9a41abSToby Isaac } 634446e270d4SMatthew G. Knepley *dim = dm->dimEmbed; 634546e270d4SMatthew G. Knepley PetscFunctionReturn(0); 634646e270d4SMatthew G. Knepley } 634746e270d4SMatthew G. Knepley 634846e270d4SMatthew G. Knepley /*@ 634946e270d4SMatthew G. Knepley DMSetCoordinateDim - Set the dimension of the embedding space for coordinate values. 635046e270d4SMatthew G. Knepley 635146e270d4SMatthew G. Knepley Not Collective 635246e270d4SMatthew G. Knepley 635346e270d4SMatthew G. Knepley Input Parameters: 635446e270d4SMatthew G. Knepley + dm - The DM object 635546e270d4SMatthew G. Knepley - dim - The embedding dimension 635646e270d4SMatthew G. Knepley 635746e270d4SMatthew G. Knepley Level: intermediate 635846e270d4SMatthew G. Knepley 635992fd8e1eSJed Brown .seealso: DMGetCoordinateDim(), DMSetCoordinateSection(), DMGetCoordinateSection(), DMGetLocalSection(), DMSetLocalSection() 636046e270d4SMatthew G. Knepley @*/ 636146e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateDim(DM dm, PetscInt dim) 636246e270d4SMatthew G. Knepley { 6363e5e52638SMatthew G. Knepley PetscDS ds; 6364f17e8794SMatthew G. Knepley PetscErrorCode ierr; 6365f17e8794SMatthew G. Knepley 636646e270d4SMatthew G. Knepley PetscFunctionBegin; 636746e270d4SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 636846e270d4SMatthew G. Knepley dm->dimEmbed = dim; 6369e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 6370e5e52638SMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(ds, dim);CHKERRQ(ierr); 637146e270d4SMatthew G. Knepley PetscFunctionReturn(0); 637246e270d4SMatthew G. Knepley } 637346e270d4SMatthew G. Knepley 6374e8abe2deSMatthew G. Knepley /*@ 6375e8abe2deSMatthew G. Knepley DMGetCoordinateSection - Retrieve the layout of coordinate values over the mesh. 6376e8abe2deSMatthew G. Knepley 6377d083f849SBarry Smith Collective on dm 6378e8abe2deSMatthew G. Knepley 6379e8abe2deSMatthew G. Knepley Input Parameter: 6380e8abe2deSMatthew G. Knepley . dm - The DM object 6381e8abe2deSMatthew G. Knepley 6382e8abe2deSMatthew G. Knepley Output Parameter: 6383e8abe2deSMatthew G. Knepley . section - The PetscSection object 6384e8abe2deSMatthew G. Knepley 6385e8abe2deSMatthew G. Knepley Level: intermediate 6386e8abe2deSMatthew G. Knepley 638792fd8e1eSJed Brown .seealso: DMGetCoordinateDM(), DMGetLocalSection(), DMSetLocalSection() 6388e8abe2deSMatthew G. Knepley @*/ 6389e8abe2deSMatthew G. Knepley PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section) 6390e8abe2deSMatthew G. Knepley { 6391e8abe2deSMatthew G. Knepley DM cdm; 6392e8abe2deSMatthew G. Knepley PetscErrorCode ierr; 6393e8abe2deSMatthew G. Knepley 6394e8abe2deSMatthew G. Knepley PetscFunctionBegin; 6395e8abe2deSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6396e8abe2deSMatthew G. Knepley PetscValidPointer(section, 2); 6397e8abe2deSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 639892fd8e1eSJed Brown ierr = DMGetLocalSection(cdm, section);CHKERRQ(ierr); 6399e8abe2deSMatthew G. Knepley PetscFunctionReturn(0); 6400e8abe2deSMatthew G. Knepley } 6401e8abe2deSMatthew G. Knepley 6402e8abe2deSMatthew G. Knepley /*@ 6403e8abe2deSMatthew G. Knepley DMSetCoordinateSection - Set the layout of coordinate values over the mesh. 6404e8abe2deSMatthew G. Knepley 6405e8abe2deSMatthew G. Knepley Not Collective 6406e8abe2deSMatthew G. Knepley 6407e8abe2deSMatthew G. Knepley Input Parameters: 6408e8abe2deSMatthew G. Knepley + dm - The DM object 640946e270d4SMatthew G. Knepley . dim - The embedding dimension, or PETSC_DETERMINE 6410e8abe2deSMatthew G. Knepley - section - The PetscSection object 6411e8abe2deSMatthew G. Knepley 6412e8abe2deSMatthew G. Knepley Level: intermediate 6413e8abe2deSMatthew G. Knepley 641492fd8e1eSJed Brown .seealso: DMGetCoordinateSection(), DMGetLocalSection(), DMSetLocalSection() 6415e8abe2deSMatthew G. Knepley @*/ 641646e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateSection(DM dm, PetscInt dim, PetscSection section) 6417e8abe2deSMatthew G. Knepley { 6418e8abe2deSMatthew G. Knepley DM cdm; 6419e8abe2deSMatthew G. Knepley PetscErrorCode ierr; 6420e8abe2deSMatthew G. Knepley 6421e8abe2deSMatthew G. Knepley PetscFunctionBegin; 6422e8abe2deSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 642346e270d4SMatthew G. Knepley PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,3); 6424e8abe2deSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 642592fd8e1eSJed Brown ierr = DMSetLocalSection(cdm, section);CHKERRQ(ierr); 642646e270d4SMatthew G. Knepley if (dim == PETSC_DETERMINE) { 64274c1069a6SMatthew G. Knepley PetscInt d = PETSC_DEFAULT; 642846e270d4SMatthew G. Knepley PetscInt pStart, pEnd, vStart, vEnd, v, dd; 642946e270d4SMatthew G. Knepley 643046e270d4SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 643146e270d4SMatthew G. Knepley ierr = DMGetDimPoints(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 643246e270d4SMatthew G. Knepley pStart = PetscMax(vStart, pStart); 643346e270d4SMatthew G. Knepley pEnd = PetscMin(vEnd, pEnd); 643446e270d4SMatthew G. Knepley for (v = pStart; v < pEnd; ++v) { 643546e270d4SMatthew G. Knepley ierr = PetscSectionGetDof(section, v, &dd);CHKERRQ(ierr); 643646e270d4SMatthew G. Knepley if (dd) {d = dd; break;} 643746e270d4SMatthew G. Knepley } 6438ebfe4b0dSMatthew G. Knepley if (d >= 0) {ierr = DMSetCoordinateDim(dm, d);CHKERRQ(ierr);} 643946e270d4SMatthew G. Knepley } 6440e8abe2deSMatthew G. Knepley PetscFunctionReturn(0); 6441e8abe2deSMatthew G. Knepley } 6442e8abe2deSMatthew G. Knepley 6443d864a3eaSLisandro Dalcin /*@ 6444d864a3eaSLisandro Dalcin DMProjectCoordinates - Project coordinates to a different space 6445d864a3eaSLisandro Dalcin 6446d864a3eaSLisandro Dalcin Input Parameters: 6447d864a3eaSLisandro Dalcin + dm - The DM object 6448d864a3eaSLisandro Dalcin - disc - The new coordinate discretization 6449d864a3eaSLisandro Dalcin 6450d864a3eaSLisandro Dalcin Level: intermediate 6451d864a3eaSLisandro Dalcin 6452d864a3eaSLisandro Dalcin .seealso: DMGetCoordinateField() 6453d864a3eaSLisandro Dalcin @*/ 6454d864a3eaSLisandro Dalcin PetscErrorCode DMProjectCoordinates(DM dm, PetscFE disc) 6455d864a3eaSLisandro Dalcin { 6456d864a3eaSLisandro Dalcin PetscObject discOld; 6457d864a3eaSLisandro Dalcin PetscClassId classid; 6458d864a3eaSLisandro Dalcin DM cdmOld,cdmNew; 6459d864a3eaSLisandro Dalcin Vec coordsOld,coordsNew; 6460d864a3eaSLisandro Dalcin Mat matInterp; 6461d864a3eaSLisandro Dalcin PetscErrorCode ierr; 6462d864a3eaSLisandro Dalcin 6463d864a3eaSLisandro Dalcin PetscFunctionBegin; 6464d864a3eaSLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6465d864a3eaSLisandro Dalcin PetscValidHeaderSpecific(disc,PETSCFE_CLASSID,2); 6466d864a3eaSLisandro Dalcin 6467d864a3eaSLisandro Dalcin ierr = DMGetCoordinateDM(dm, &cdmOld);CHKERRQ(ierr); 6468d864a3eaSLisandro Dalcin /* Check current discretization is compatible */ 6469d864a3eaSLisandro Dalcin ierr = DMGetField(cdmOld, 0, NULL, &discOld);CHKERRQ(ierr); 6470d864a3eaSLisandro Dalcin ierr = PetscObjectGetClassId(discOld, &classid);CHKERRQ(ierr); 647129ad44c5SMatthew G. Knepley if (classid != PETSCFE_CLASSID) { 647229ad44c5SMatthew G. Knepley if (classid == PETSC_CONTAINER_CLASSID) { 647329ad44c5SMatthew G. Knepley PetscFE feLinear; 647429ad44c5SMatthew G. Knepley DMPolytopeType ct; 647529ad44c5SMatthew G. Knepley PetscInt dim, dE, cStart; 647629ad44c5SMatthew G. Knepley PetscBool simplex; 647729ad44c5SMatthew G. Knepley 647829ad44c5SMatthew G. Knepley /* Assume linear vertex coordinates */ 647929ad44c5SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 648029ad44c5SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 648129ad44c5SMatthew G. Knepley ierr = DMPlexGetHeightStratum(cdmOld, 0, &cStart, NULL);CHKERRQ(ierr); 648229ad44c5SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 648329ad44c5SMatthew G. Knepley switch (ct) { 648429ad44c5SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 648529ad44c5SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 648629ad44c5SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot autoamtically create coordinate space for prisms"); 648729ad44c5SMatthew G. Knepley default: break; 648829ad44c5SMatthew G. Knepley } 648929ad44c5SMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 649029ad44c5SMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, dE, simplex, 1, -1, &feLinear);CHKERRQ(ierr); 649129ad44c5SMatthew G. Knepley ierr = DMSetField(cdmOld, 0, NULL, (PetscObject) feLinear);CHKERRQ(ierr); 649229ad44c5SMatthew G. Knepley ierr = PetscFEDestroy(&feLinear);CHKERRQ(ierr); 649329ad44c5SMatthew G. Knepley ierr = DMCreateDS(cdmOld);CHKERRQ(ierr); 649429ad44c5SMatthew G. Knepley } else { 649529ad44c5SMatthew G. Knepley const char *discname; 649629ad44c5SMatthew G. Knepley 649729ad44c5SMatthew G. Knepley ierr = PetscObjectGetType(discOld, &discname);CHKERRQ(ierr); 649829ad44c5SMatthew G. Knepley SETERRQ1(PetscObjectComm(discOld), PETSC_ERR_SUP, "Discretization type %s not supported", discname); 649929ad44c5SMatthew G. Knepley } 650029ad44c5SMatthew G. Knepley } 6501d864a3eaSLisandro Dalcin /* Make a fresh clone of the coordinate DM */ 6502d864a3eaSLisandro Dalcin ierr = DMClone(cdmOld, &cdmNew);CHKERRQ(ierr); 6503d864a3eaSLisandro Dalcin ierr = DMSetField(cdmNew, 0, NULL, (PetscObject) disc);CHKERRQ(ierr); 6504d864a3eaSLisandro Dalcin ierr = DMCreateDS(cdmNew);CHKERRQ(ierr); 6505d864a3eaSLisandro Dalcin /* Project the coordinate vector from old to new space */ 6506d864a3eaSLisandro Dalcin ierr = DMGetCoordinates(dm, &coordsOld);CHKERRQ(ierr); 6507d864a3eaSLisandro Dalcin ierr = DMCreateGlobalVector(cdmNew, &coordsNew);CHKERRQ(ierr); 6508d864a3eaSLisandro Dalcin ierr = DMCreateInterpolation(cdmOld, cdmNew, &matInterp, NULL);CHKERRQ(ierr); 6509d864a3eaSLisandro Dalcin ierr = MatInterpolate(matInterp, coordsOld, coordsNew);CHKERRQ(ierr); 6510d864a3eaSLisandro Dalcin ierr = MatDestroy(&matInterp);CHKERRQ(ierr); 6511d864a3eaSLisandro Dalcin /* Set new coordinate structures */ 6512d864a3eaSLisandro Dalcin ierr = DMSetCoordinateField(dm, NULL);CHKERRQ(ierr); 6513d864a3eaSLisandro Dalcin ierr = DMSetCoordinateDM(dm, cdmNew);CHKERRQ(ierr); 6514d864a3eaSLisandro Dalcin ierr = DMSetCoordinates(dm, coordsNew);CHKERRQ(ierr); 6515d864a3eaSLisandro Dalcin ierr = VecDestroy(&coordsNew);CHKERRQ(ierr); 6516d864a3eaSLisandro Dalcin ierr = DMDestroy(&cdmNew);CHKERRQ(ierr); 6517d864a3eaSLisandro Dalcin PetscFunctionReturn(0); 6518d864a3eaSLisandro Dalcin } 6519d864a3eaSLisandro Dalcin 65205dc8c3f7SMatthew G. Knepley /*@C 652190b157c4SStefano Zampini DMGetPeriodicity - Get the description of mesh periodicity 65225dc8c3f7SMatthew G. Knepley 65235dc8c3f7SMatthew G. Knepley Input Parameters: 652490b157c4SStefano Zampini . dm - The DM object 652590b157c4SStefano Zampini 652690b157c4SStefano Zampini Output Parameters: 652790b157c4SStefano Zampini + per - Whether the DM is periodic or not 65285dc8c3f7SMatthew 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 65295dc8c3f7SMatthew G. Knepley . L - If we assume the mesh is a torus, this is the length of each coordinate 65305dc8c3f7SMatthew G. Knepley - bd - This describes the type of periodicity in each topological dimension 65315dc8c3f7SMatthew G. Knepley 65325dc8c3f7SMatthew G. Knepley Level: developer 65335dc8c3f7SMatthew G. Knepley 65345dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity() 65355dc8c3f7SMatthew G. Knepley @*/ 653690b157c4SStefano Zampini PetscErrorCode DMGetPeriodicity(DM dm, PetscBool *per, const PetscReal **maxCell, const PetscReal **L, const DMBoundaryType **bd) 6537c6b900c6SMatthew G. Knepley { 6538c6b900c6SMatthew G. Knepley PetscFunctionBegin; 6539c6b900c6SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 654090b157c4SStefano Zampini if (per) *per = dm->periodic; 6541c6b900c6SMatthew G. Knepley if (L) *L = dm->L; 6542c6b900c6SMatthew G. Knepley if (maxCell) *maxCell = dm->maxCell; 65435dc8c3f7SMatthew G. Knepley if (bd) *bd = dm->bdtype; 6544c6b900c6SMatthew G. Knepley PetscFunctionReturn(0); 6545c6b900c6SMatthew G. Knepley } 6546c6b900c6SMatthew G. Knepley 65475dc8c3f7SMatthew G. Knepley /*@C 65485dc8c3f7SMatthew G. Knepley DMSetPeriodicity - Set the description of mesh periodicity 65495dc8c3f7SMatthew G. Knepley 65505dc8c3f7SMatthew G. Knepley Input Parameters: 65515dc8c3f7SMatthew G. Knepley + dm - The DM object 6552db2bf62eSStefano Zampini . per - Whether the DM is periodic or not. 6553db2bf62eSStefano 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. 65545dc8c3f7SMatthew G. Knepley . L - If we assume the mesh is a torus, this is the length of each coordinate 65555dc8c3f7SMatthew G. Knepley - bd - This describes the type of periodicity in each topological dimension 65565dc8c3f7SMatthew G. Knepley 6557db2bf62eSStefano 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. 6558db2bf62eSStefano Zampini 65595dc8c3f7SMatthew G. Knepley Level: developer 65605dc8c3f7SMatthew G. Knepley 65615dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity() 65625dc8c3f7SMatthew G. Knepley @*/ 656390b157c4SStefano Zampini PetscErrorCode DMSetPeriodicity(DM dm, PetscBool per, const PetscReal maxCell[], const PetscReal L[], const DMBoundaryType bd[]) 6564c6b900c6SMatthew G. Knepley { 6565c6b900c6SMatthew G. Knepley PetscInt dim, d; 6566c6b900c6SMatthew G. Knepley PetscErrorCode ierr; 6567c6b900c6SMatthew G. Knepley 6568c6b900c6SMatthew G. Knepley PetscFunctionBegin; 6569c6b900c6SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 657090b157c4SStefano Zampini PetscValidLogicalCollectiveBool(dm,per,2); 6571412e9a14SMatthew G. Knepley if (maxCell) {PetscValidRealPointer(maxCell,3);} 6572412e9a14SMatthew G. Knepley if (L) {PetscValidRealPointer(L,4);} 6573412e9a14SMatthew G. Knepley if (bd) {PetscValidPointer(bd,5);} 65745dc8c3f7SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 657590b157c4SStefano Zampini if (maxCell) { 6576412e9a14SMatthew G. Knepley if (!dm->maxCell) {ierr = PetscMalloc1(dim, &dm->maxCell);CHKERRQ(ierr);} 6577412e9a14SMatthew G. Knepley for (d = 0; d < dim; ++d) dm->maxCell[d] = maxCell[d]; 6578db2bf62eSStefano Zampini } else { /* remove maxCell information to disable automatic computation of localized vertices */ 6579db2bf62eSStefano Zampini ierr = PetscFree(dm->maxCell);CHKERRQ(ierr); 6580412e9a14SMatthew G. Knepley } 6581db2bf62eSStefano Zampini 6582412e9a14SMatthew G. Knepley if (L) { 6583412e9a14SMatthew G. Knepley if (!dm->L) {ierr = PetscMalloc1(dim, &dm->L);CHKERRQ(ierr);} 6584412e9a14SMatthew G. Knepley for (d = 0; d < dim; ++d) dm->L[d] = L[d]; 6585412e9a14SMatthew G. Knepley } 6586412e9a14SMatthew G. Knepley if (bd) { 6587412e9a14SMatthew G. Knepley if (!dm->bdtype) {ierr = PetscMalloc1(dim, &dm->bdtype);CHKERRQ(ierr);} 6588412e9a14SMatthew G. Knepley for (d = 0; d < dim; ++d) dm->bdtype[d] = bd[d]; 658990b157c4SStefano Zampini } 6590072d7d67SStefano Zampini dm->periodic = per; 6591c6b900c6SMatthew G. Knepley PetscFunctionReturn(0); 6592c6b900c6SMatthew G. Knepley } 6593c6b900c6SMatthew G. Knepley 65942e17dfb7SMatthew G. Knepley /*@ 65952e17dfb7SMatthew 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. 65962e17dfb7SMatthew G. Knepley 65972e17dfb7SMatthew G. Knepley Input Parameters: 65982e17dfb7SMatthew G. Knepley + dm - The DM 659965da65dcSMatthew G. Knepley . in - The input coordinate point (dim numbers) 660065da65dcSMatthew G. Knepley - endpoint - Include the endpoint L_i 66012e17dfb7SMatthew G. Knepley 66022e17dfb7SMatthew G. Knepley Output Parameter: 66032e17dfb7SMatthew G. Knepley . out - The localized coordinate point 66042e17dfb7SMatthew G. Knepley 66052e17dfb7SMatthew G. Knepley Level: developer 66062e17dfb7SMatthew G. Knepley 66072e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate() 66082e17dfb7SMatthew G. Knepley @*/ 660965da65dcSMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate(DM dm, const PetscScalar in[], PetscBool endpoint, PetscScalar out[]) 66102e17dfb7SMatthew G. Knepley { 66112e17dfb7SMatthew G. Knepley PetscInt dim, d; 66122e17dfb7SMatthew G. Knepley PetscErrorCode ierr; 66132e17dfb7SMatthew G. Knepley 66142e17dfb7SMatthew G. Knepley PetscFunctionBegin; 66152e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 66162e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 66172e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 66182e17dfb7SMatthew G. Knepley } else { 661965da65dcSMatthew G. Knepley if (endpoint) { 662065da65dcSMatthew G. Knepley for (d = 0; d < dim; ++d) { 6621da3333bfSMatthew 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)) { 6622da3333bfSMatthew G. Knepley out[d] = in[d] - dm->L[d]*(PetscFloorReal(PetscRealPart(in[d])/dm->L[d]) - 1); 662365da65dcSMatthew G. Knepley } else { 6624da3333bfSMatthew G. Knepley out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]); 662565da65dcSMatthew G. Knepley } 662665da65dcSMatthew G. Knepley } 662765da65dcSMatthew G. Knepley } else { 66282e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 66291118d4bcSLisandro Dalcin out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]); 66302e17dfb7SMatthew G. Knepley } 66312e17dfb7SMatthew G. Knepley } 663265da65dcSMatthew G. Knepley } 66332e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 66342e17dfb7SMatthew G. Knepley } 66352e17dfb7SMatthew G. Knepley 66362e17dfb7SMatthew G. Knepley /* 66372e17dfb7SMatthew 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. 66382e17dfb7SMatthew G. Knepley 66392e17dfb7SMatthew G. Knepley Input Parameters: 66402e17dfb7SMatthew G. Knepley + dm - The DM 66412e17dfb7SMatthew G. Knepley . dim - The spatial dimension 66422e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it 66432e17dfb7SMatthew G. Knepley - in - The input coordinate point (dim numbers) 66442e17dfb7SMatthew G. Knepley 66452e17dfb7SMatthew G. Knepley Output Parameter: 66462e17dfb7SMatthew G. Knepley . out - The localized coordinate point 66472e17dfb7SMatthew G. Knepley 66482e17dfb7SMatthew G. Knepley Level: developer 66492e17dfb7SMatthew G. Knepley 66502e17dfb7SMatthew 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 66512e17dfb7SMatthew G. Knepley 66522e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate() 66532e17dfb7SMatthew G. Knepley */ 66542e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[]) 66552e17dfb7SMatthew G. Knepley { 66562e17dfb7SMatthew G. Knepley PetscInt d; 66572e17dfb7SMatthew G. Knepley 66582e17dfb7SMatthew G. Knepley PetscFunctionBegin; 66592e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 66602e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 66612e17dfb7SMatthew G. Knepley } else { 66622e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 6663908eca10SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) { 66642e17dfb7SMatthew G. Knepley out[d] = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d]; 66652e17dfb7SMatthew G. Knepley } else { 66662e17dfb7SMatthew G. Knepley out[d] = in[d]; 66672e17dfb7SMatthew G. Knepley } 66682e17dfb7SMatthew G. Knepley } 66692e17dfb7SMatthew G. Knepley } 66702e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 66712e17dfb7SMatthew G. Knepley } 6672a5801f52SStefano Zampini 66732e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinateReal_Internal(DM dm, PetscInt dim, const PetscReal anchor[], const PetscReal in[], PetscReal out[]) 66742e17dfb7SMatthew G. Knepley { 66752e17dfb7SMatthew G. Knepley PetscInt d; 66762e17dfb7SMatthew G. Knepley 66772e17dfb7SMatthew G. Knepley PetscFunctionBegin; 66782e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 66792e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 66802e17dfb7SMatthew G. Knepley } else { 66812e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 6682908eca10SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsReal(anchor[d] - in[d]) > dm->maxCell[d])) { 66832e17dfb7SMatthew G. Knepley out[d] = anchor[d] > in[d] ? dm->L[d] + in[d] : in[d] - dm->L[d]; 66842e17dfb7SMatthew G. Knepley } else { 66852e17dfb7SMatthew G. Knepley out[d] = in[d]; 66862e17dfb7SMatthew G. Knepley } 66872e17dfb7SMatthew G. Knepley } 66882e17dfb7SMatthew G. Knepley } 66892e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 66902e17dfb7SMatthew G. Knepley } 66912e17dfb7SMatthew G. Knepley 66922e17dfb7SMatthew G. Knepley /* 66932e17dfb7SMatthew 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. 66942e17dfb7SMatthew G. Knepley 66952e17dfb7SMatthew G. Knepley Input Parameters: 66962e17dfb7SMatthew G. Knepley + dm - The DM 66972e17dfb7SMatthew G. Knepley . dim - The spatial dimension 66982e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it 66992e17dfb7SMatthew G. Knepley . in - The input coordinate delta (dim numbers) 67002e17dfb7SMatthew G. Knepley - out - The input coordinate point (dim numbers) 67012e17dfb7SMatthew G. Knepley 67022e17dfb7SMatthew G. Knepley Output Parameter: 67032e17dfb7SMatthew G. Knepley . out - The localized coordinate in + out 67042e17dfb7SMatthew G. Knepley 67052e17dfb7SMatthew G. Knepley Level: developer 67062e17dfb7SMatthew G. Knepley 67072e17dfb7SMatthew 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 67082e17dfb7SMatthew G. Knepley 67092e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeCoordinate() 67102e17dfb7SMatthew G. Knepley */ 67112e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeAddCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[]) 67122e17dfb7SMatthew G. Knepley { 67132e17dfb7SMatthew G. Knepley PetscInt d; 67142e17dfb7SMatthew G. Knepley 67152e17dfb7SMatthew G. Knepley PetscFunctionBegin; 67162e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 67172e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] += in[d]; 67182e17dfb7SMatthew G. Knepley } else { 67192e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 6720412e9a14SMatthew G. Knepley const PetscReal maxC = dm->maxCell[d]; 6721412e9a14SMatthew G. Knepley 6722412e9a14SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > maxC)) { 6723412e9a14SMatthew G. Knepley const PetscScalar newCoord = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d]; 6724412e9a14SMatthew G. Knepley 6725412e9a14SMatthew G. Knepley if (PetscAbsScalar(newCoord - anchor[d]) > maxC) 6726412e9a14SMatthew 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])); 6727412e9a14SMatthew G. Knepley out[d] += newCoord; 67282e17dfb7SMatthew G. Knepley } else { 67292e17dfb7SMatthew G. Knepley out[d] += in[d]; 67302e17dfb7SMatthew G. Knepley } 67312e17dfb7SMatthew G. Knepley } 67322e17dfb7SMatthew G. Knepley } 67332e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 67342e17dfb7SMatthew G. Knepley } 67352e17dfb7SMatthew G. Knepley 673636447a5eSToby Isaac /*@ 67378f700142SStefano Zampini DMGetCoordinatesLocalizedLocal - Check if the DM coordinates have been localized for cells on this process 67388f700142SStefano Zampini 67398f700142SStefano Zampini Not collective 674036447a5eSToby Isaac 674136447a5eSToby Isaac Input Parameter: 674236447a5eSToby Isaac . dm - The DM 674336447a5eSToby Isaac 674436447a5eSToby Isaac Output Parameter: 674536447a5eSToby Isaac areLocalized - True if localized 674636447a5eSToby Isaac 674736447a5eSToby Isaac Level: developer 674836447a5eSToby Isaac 67498f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMGetCoordinatesLocalized(), DMSetPeriodicity() 675036447a5eSToby Isaac @*/ 67518f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalizedLocal(DM dm,PetscBool *areLocalized) 675236447a5eSToby Isaac { 675336447a5eSToby Isaac DM cdm; 675436447a5eSToby Isaac PetscSection coordSection; 675546a3a80fSLisandro Dalcin PetscInt cStart, cEnd, sStart, sEnd, c, dof; 675646a3a80fSLisandro Dalcin PetscBool isPlex, alreadyLocalized; 675736447a5eSToby Isaac PetscErrorCode ierr; 675836447a5eSToby Isaac 675936447a5eSToby Isaac PetscFunctionBegin; 676036447a5eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6761534a8f05SLisandro Dalcin PetscValidBoolPointer(areLocalized, 2); 67628b09590cSToby Isaac *areLocalized = PETSC_FALSE; 676346a3a80fSLisandro Dalcin 676436447a5eSToby Isaac /* We need some generic way of refering to cells/vertices */ 676536447a5eSToby Isaac ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 676646a3a80fSLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isPlex);CHKERRQ(ierr); 67679f7230bfSMatthew G. Knepley if (!isPlex) PetscFunctionReturn(0); 676846a3a80fSLisandro Dalcin 67699f7230bfSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 677046a3a80fSLisandro Dalcin ierr = DMPlexGetHeightStratum(cdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 677136447a5eSToby Isaac ierr = PetscSectionGetChart(coordSection, &sStart, &sEnd);CHKERRQ(ierr); 677236447a5eSToby Isaac alreadyLocalized = PETSC_FALSE; 677346a3a80fSLisandro Dalcin for (c = cStart; c < cEnd; ++c) { 677446a3a80fSLisandro Dalcin if (c < sStart || c >= sEnd) continue; 677536447a5eSToby Isaac ierr = PetscSectionGetDof(coordSection, c, &dof);CHKERRQ(ierr); 677646a3a80fSLisandro Dalcin if (dof) { alreadyLocalized = PETSC_TRUE; break; } 677736447a5eSToby Isaac } 67788f700142SStefano Zampini *areLocalized = alreadyLocalized; 677936447a5eSToby Isaac PetscFunctionReturn(0); 678036447a5eSToby Isaac } 678136447a5eSToby Isaac 67828f700142SStefano Zampini /*@ 67838f700142SStefano Zampini DMGetCoordinatesLocalized - Check if the DM coordinates have been localized for cells 67848f700142SStefano Zampini 67858f700142SStefano Zampini Collective on dm 67868f700142SStefano Zampini 67878f700142SStefano Zampini Input Parameter: 67888f700142SStefano Zampini . dm - The DM 67898f700142SStefano Zampini 67908f700142SStefano Zampini Output Parameter: 67918f700142SStefano Zampini areLocalized - True if localized 67928f700142SStefano Zampini 67938f700142SStefano Zampini Level: developer 67948f700142SStefano Zampini 67958f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMSetPeriodicity(), DMGetCoordinatesLocalizedLocal() 67968f700142SStefano Zampini @*/ 67978f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalized(DM dm,PetscBool *areLocalized) 67988f700142SStefano Zampini { 67998f700142SStefano Zampini PetscBool localized; 68008f700142SStefano Zampini PetscErrorCode ierr; 68018f700142SStefano Zampini 68028f700142SStefano Zampini PetscFunctionBegin; 68038f700142SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6804534a8f05SLisandro Dalcin PetscValidBoolPointer(areLocalized, 2); 68058f700142SStefano Zampini ierr = DMGetCoordinatesLocalizedLocal(dm,&localized);CHKERRQ(ierr); 68068f700142SStefano Zampini ierr = MPIU_Allreduce(&localized,areLocalized,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 68078f700142SStefano Zampini PetscFunctionReturn(0); 68088f700142SStefano Zampini } 680936447a5eSToby Isaac 68102e17dfb7SMatthew G. Knepley /*@ 6811492b8470SStefano Zampini DMLocalizeCoordinates - If a mesh is periodic, create local coordinates for cells having periodic faces 68122e17dfb7SMatthew G. Knepley 68138f700142SStefano Zampini Collective on dm 68148f700142SStefano Zampini 68152e17dfb7SMatthew G. Knepley Input Parameter: 68162e17dfb7SMatthew G. Knepley . dm - The DM 68172e17dfb7SMatthew G. Knepley 68182e17dfb7SMatthew G. Knepley Level: developer 68192e17dfb7SMatthew G. Knepley 68208f700142SStefano Zampini .seealso: DMSetPeriodicity(), DMLocalizeCoordinate(), DMLocalizeAddCoordinate() 68212e17dfb7SMatthew G. Knepley @*/ 68222e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinates(DM dm) 68232e17dfb7SMatthew G. Knepley { 68242e17dfb7SMatthew G. Knepley DM cdm; 68252e17dfb7SMatthew G. Knepley PetscSection coordSection, cSection; 68262e17dfb7SMatthew G. Knepley Vec coordinates, cVec; 68273e922f36SToby Isaac PetscScalar *coords, *coords2, *anchor, *localized; 68283e922f36SToby Isaac PetscInt Nc, vStart, vEnd, v, sStart, sEnd, newStart = PETSC_MAX_INT, newEnd = PETSC_MIN_INT, dof, d, off, off2, bs, coordSize; 6829e0ae35bbSToby Isaac PetscBool alreadyLocalized, alreadyLocalizedGlobal; 68303e922f36SToby Isaac PetscInt maxHeight = 0, h; 68313e922f36SToby Isaac PetscInt *pStart = NULL, *pEnd = NULL; 68322e17dfb7SMatthew G. Knepley PetscErrorCode ierr; 68332e17dfb7SMatthew G. Knepley 68342e17dfb7SMatthew G. Knepley PetscFunctionBegin; 68352e17dfb7SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 683692c9c85fSStefano Zampini if (!dm->periodic) PetscFunctionReturn(0); 6837f7cbd40bSStefano Zampini ierr = DMGetCoordinatesLocalized(dm, &alreadyLocalized);CHKERRQ(ierr); 6838f7cbd40bSStefano Zampini if (alreadyLocalized) PetscFunctionReturn(0); 6839f7cbd40bSStefano Zampini 68402e17dfb7SMatthew G. Knepley /* We need some generic way of refering to cells/vertices */ 68412e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 68422e17dfb7SMatthew G. Knepley { 68432e17dfb7SMatthew G. Knepley PetscBool isplex; 68442e17dfb7SMatthew G. Knepley 68452e17dfb7SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isplex);CHKERRQ(ierr); 68462e17dfb7SMatthew G. Knepley if (isplex) { 68472e17dfb7SMatthew G. Knepley ierr = DMPlexGetDepthStratum(cdm, 0, &vStart, &vEnd);CHKERRQ(ierr); 68483e922f36SToby Isaac ierr = DMPlexGetMaxProjectionHeight(cdm,&maxHeight);CHKERRQ(ierr); 684969291d52SBarry Smith ierr = DMGetWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 68503e922f36SToby Isaac pEnd = &pStart[maxHeight + 1]; 68513e922f36SToby Isaac newStart = vStart; 68523e922f36SToby Isaac newEnd = vEnd; 68533e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 68543e922f36SToby Isaac ierr = DMPlexGetHeightStratum(cdm, h, &pStart[h], &pEnd[h]);CHKERRQ(ierr); 68553e922f36SToby Isaac newStart = PetscMin(newStart,pStart[h]); 68563e922f36SToby Isaac newEnd = PetscMax(newEnd,pEnd[h]); 68573e922f36SToby Isaac } 68582e17dfb7SMatthew G. Knepley } else SETERRQ(PetscObjectComm((PetscObject) cdm), PETSC_ERR_ARG_WRONG, "Coordinate localization requires a DMPLEX coordinate DM"); 68592e17dfb7SMatthew G. Knepley } 68602e17dfb7SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 686143eeeb2dSStefano Zampini if (!coordinates) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Missing local coordinates vector"); 68622e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 68633e922f36SToby Isaac ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 6864e0ae35bbSToby Isaac ierr = PetscSectionGetChart(coordSection,&sStart,&sEnd);CHKERRQ(ierr); 68653e922f36SToby Isaac 68662e17dfb7SMatthew G. Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &cSection);CHKERRQ(ierr); 68672e17dfb7SMatthew G. Knepley ierr = PetscSectionSetNumFields(cSection, 1);CHKERRQ(ierr); 68682e17dfb7SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(coordSection, 0, &Nc);CHKERRQ(ierr); 68692e17dfb7SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(cSection, 0, Nc);CHKERRQ(ierr); 68703e922f36SToby Isaac ierr = PetscSectionSetChart(cSection, newStart, newEnd);CHKERRQ(ierr); 68713e922f36SToby Isaac 687269291d52SBarry Smith ierr = DMGetWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 68733e922f36SToby Isaac localized = &anchor[bs]; 68743e922f36SToby Isaac alreadyLocalized = alreadyLocalizedGlobal = PETSC_TRUE; 68753e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 68763e922f36SToby Isaac PetscInt cStart = pStart[h], cEnd = pEnd[h], c; 68773e922f36SToby Isaac 68783e922f36SToby Isaac for (c = cStart; c < cEnd; ++c) { 68793e922f36SToby Isaac PetscScalar *cellCoords = NULL; 68803e922f36SToby Isaac PetscInt b; 68813e922f36SToby Isaac 68823e922f36SToby Isaac if (c < sStart || c >= sEnd) alreadyLocalized = PETSC_FALSE; 68833e922f36SToby Isaac ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 68843e922f36SToby Isaac for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b]; 68853e922f36SToby Isaac for (d = 0; d < dof/bs; ++d) { 68863e922f36SToby Isaac ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], localized);CHKERRQ(ierr); 68873e922f36SToby Isaac for (b = 0; b < bs; b++) { 68883e922f36SToby Isaac if (cellCoords[d*bs + b] != localized[b]) break; 68893e922f36SToby Isaac } 68903e922f36SToby Isaac if (b < bs) break; 68913e922f36SToby Isaac } 68923e922f36SToby Isaac if (d < dof/bs) { 68933e922f36SToby Isaac if (c >= sStart && c < sEnd) { 68943e922f36SToby Isaac PetscInt cdof; 68953e922f36SToby Isaac 68963e922f36SToby Isaac ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 68973e922f36SToby Isaac if (cdof != dof) alreadyLocalized = PETSC_FALSE; 68983e922f36SToby Isaac } 68993e922f36SToby Isaac ierr = PetscSectionSetDof(cSection, c, dof);CHKERRQ(ierr); 69003e922f36SToby Isaac ierr = PetscSectionSetFieldDof(cSection, c, 0, dof);CHKERRQ(ierr); 69013e922f36SToby Isaac } 69023e922f36SToby Isaac ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 69033e922f36SToby Isaac } 69043e922f36SToby Isaac } 6905ffc4695bSBarry Smith ierr = MPI_Allreduce(&alreadyLocalized,&alreadyLocalizedGlobal,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 69063e922f36SToby Isaac if (alreadyLocalizedGlobal) { 690769291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 69083e922f36SToby Isaac ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr); 690969291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 69103e922f36SToby Isaac PetscFunctionReturn(0); 69113e922f36SToby Isaac } 69122e17dfb7SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 69132e17dfb7SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 69142e17dfb7SMatthew G. Knepley ierr = PetscSectionSetDof(cSection, v, dof);CHKERRQ(ierr); 69152e17dfb7SMatthew G. Knepley ierr = PetscSectionSetFieldDof(cSection, v, 0, dof);CHKERRQ(ierr); 69162e17dfb7SMatthew G. Knepley } 69172e17dfb7SMatthew G. Knepley ierr = PetscSectionSetUp(cSection);CHKERRQ(ierr); 69182e17dfb7SMatthew G. Knepley ierr = PetscSectionGetStorageSize(cSection, &coordSize);CHKERRQ(ierr); 6919c2be7e5eSLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &cVec);CHKERRQ(ierr); 69202e17dfb7SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject)cVec,"coordinates");CHKERRQ(ierr); 69212e17dfb7SMatthew G. Knepley ierr = VecSetBlockSize(cVec, bs);CHKERRQ(ierr); 69222e17dfb7SMatthew G. Knepley ierr = VecSetSizes(cVec, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 69232e17dfb7SMatthew G. Knepley ierr = VecSetType(cVec, VECSTANDARD);CHKERRQ(ierr); 6924c2be7e5eSLisandro Dalcin ierr = VecGetArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr); 69252e17dfb7SMatthew G. Knepley ierr = VecGetArray(cVec, &coords2);CHKERRQ(ierr); 69262e17dfb7SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 69272e17dfb7SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 69282e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 69292e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(cSection, v, &off2);CHKERRQ(ierr); 69302e17dfb7SMatthew G. Knepley for (d = 0; d < dof; ++d) coords2[off2+d] = coords[off+d]; 69312e17dfb7SMatthew G. Knepley } 69323e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 69333e922f36SToby Isaac PetscInt cStart = pStart[h], cEnd = pEnd[h], c; 69343e922f36SToby Isaac 69352e17dfb7SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 69362e17dfb7SMatthew G. Knepley PetscScalar *cellCoords = NULL; 69373e922f36SToby Isaac PetscInt b, cdof; 69382e17dfb7SMatthew G. Knepley 69393e922f36SToby Isaac ierr = PetscSectionGetDof(cSection,c,&cdof);CHKERRQ(ierr); 69403e922f36SToby Isaac if (!cdof) continue; 69412e17dfb7SMatthew G. Knepley ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 69422e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(cSection, c, &off2);CHKERRQ(ierr); 69432e17dfb7SMatthew G. Knepley for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b]; 69442e17dfb7SMatthew G. Knepley for (d = 0; d < dof/bs; ++d) {ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], &coords2[off2+d*bs]);CHKERRQ(ierr);} 69452e17dfb7SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 69462e17dfb7SMatthew G. Knepley } 69473e922f36SToby Isaac } 694869291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 694969291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 6950c2be7e5eSLisandro Dalcin ierr = VecRestoreArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr); 69512e17dfb7SMatthew G. Knepley ierr = VecRestoreArray(cVec, &coords2);CHKERRQ(ierr); 69522e17dfb7SMatthew G. Knepley ierr = DMSetCoordinateSection(dm, PETSC_DETERMINE, cSection);CHKERRQ(ierr); 69532e17dfb7SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, cVec);CHKERRQ(ierr); 69542e17dfb7SMatthew G. Knepley ierr = VecDestroy(&cVec);CHKERRQ(ierr); 69552e17dfb7SMatthew G. Knepley ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr); 69562e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 69572e17dfb7SMatthew G. Knepley } 69582e17dfb7SMatthew G. Knepley 6959e87bb0d3SMatthew G Knepley /*@ 69603a93e3b7SToby Isaac DMLocatePoints - Locate the points in v in the mesh and return a PetscSF of the containing cells 6961e87bb0d3SMatthew G Knepley 6962d083f849SBarry Smith Collective on v (see explanation below) 6963e87bb0d3SMatthew G Knepley 6964e87bb0d3SMatthew G Knepley Input Parameters: 6965e87bb0d3SMatthew G Knepley + dm - The DM 69663a93e3b7SToby Isaac . v - The Vec of points 696762a38674SMatthew G. Knepley . ltype - The type of point location, e.g. DM_POINTLOCATION_NONE or DM_POINTLOCATION_NEAREST 69683a93e3b7SToby Isaac - cells - Points to either NULL, or a PetscSF with guesses for which cells contain each point. 6969e87bb0d3SMatthew G Knepley 697061e3bb9bSMatthew G Knepley Output Parameter: 697162a38674SMatthew G. Knepley + v - The Vec of points, which now contains the nearest mesh points to the given points if DM_POINTLOCATION_NEAREST is used 697262a38674SMatthew G. Knepley - cells - The PetscSF containing the ranks and local indices of the containing points. 69733a93e3b7SToby Isaac 6974e87bb0d3SMatthew G Knepley 6975e87bb0d3SMatthew G Knepley Level: developer 697661e3bb9bSMatthew G Knepley 697762a38674SMatthew G. Knepley Notes: 69783a93e3b7SToby Isaac To do a search of the local cells of the mesh, v should have PETSC_COMM_SELF as its communicator. 697962a38674SMatthew G. Knepley To do a search of all the cells in the distributed mesh, v should have the same communicator as dm. 69803a93e3b7SToby Isaac 69813a93e3b7SToby Isaac If *cellSF is NULL on input, a PetscSF will be created. 698262a38674SMatthew G. Knepley If *cellSF is not NULL on input, it should point to an existing PetscSF, whose graph will be used as initial guesses. 69833a93e3b7SToby Isaac 69843a93e3b7SToby Isaac An array that maps each point to its containing cell can be obtained with 69853a93e3b7SToby Isaac 698662a38674SMatthew G. Knepley $ const PetscSFNode *cells; 698762a38674SMatthew G. Knepley $ PetscInt nFound; 6988a6216909SToby Isaac $ const PetscInt *found; 698962a38674SMatthew G. Knepley $ 6990a6216909SToby Isaac $ PetscSFGetGraph(cellSF,NULL,&nFound,&found,&cells); 69913a93e3b7SToby Isaac 69923a93e3b7SToby 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 69933a93e3b7SToby Isaac the index of the cell in its rank's local numbering. 69943a93e3b7SToby Isaac 699562a38674SMatthew G. Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMPointLocationType 699661e3bb9bSMatthew G Knepley @*/ 699762a38674SMatthew G. Knepley PetscErrorCode DMLocatePoints(DM dm, Vec v, DMPointLocationType ltype, PetscSF *cellSF) 6998e87bb0d3SMatthew G Knepley { 6999735aa83eSMatthew G Knepley PetscErrorCode ierr; 7000735aa83eSMatthew G Knepley 7001e87bb0d3SMatthew G Knepley PetscFunctionBegin; 7002e87bb0d3SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7003e87bb0d3SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,2); 7004e0fc9d1bSMatthew G. Knepley PetscValidPointer(cellSF,4); 70053a93e3b7SToby Isaac if (*cellSF) { 70063a93e3b7SToby Isaac PetscMPIInt result; 70073a93e3b7SToby Isaac 7008e0fc9d1bSMatthew G. Knepley PetscValidHeaderSpecific(*cellSF,PETSCSF_CLASSID,4); 7009ffc4695bSBarry Smith ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)v),PetscObjectComm((PetscObject)*cellSF),&result);CHKERRMPI(ierr); 70103a93e3b7SToby 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"); 7011e0fc9d1bSMatthew G. Knepley } else { 70123a93e3b7SToby Isaac ierr = PetscSFCreate(PetscObjectComm((PetscObject)v),cellSF);CHKERRQ(ierr); 70133a93e3b7SToby Isaac } 7014b9d85ea2SLisandro Dalcin if (!dm->ops->locatepoints) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Point location not available for this DM"); 701547a35634SPatrick Farrell ierr = PetscLogEventBegin(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr); 701662a38674SMatthew G. Knepley ierr = (*dm->ops->locatepoints)(dm,v,ltype,*cellSF);CHKERRQ(ierr); 701747a35634SPatrick Farrell ierr = PetscLogEventEnd(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr); 7018e87bb0d3SMatthew G Knepley PetscFunctionReturn(0); 7019e87bb0d3SMatthew G Knepley } 702014f150ffSMatthew G. Knepley 7021f4d763aaSMatthew G. Knepley /*@ 7022f4d763aaSMatthew G. Knepley DMGetOutputDM - Retrieve the DM associated with the layout for output 7023f4d763aaSMatthew G. Knepley 70248f700142SStefano Zampini Collective on dm 70258f700142SStefano Zampini 7026f4d763aaSMatthew G. Knepley Input Parameter: 7027f4d763aaSMatthew G. Knepley . dm - The original DM 7028f4d763aaSMatthew G. Knepley 7029f4d763aaSMatthew G. Knepley Output Parameter: 7030f4d763aaSMatthew G. Knepley . odm - The DM which provides the layout for output 7031f4d763aaSMatthew G. Knepley 7032f4d763aaSMatthew G. Knepley Level: intermediate 7033f4d763aaSMatthew G. Knepley 7034e87a4003SBarry Smith .seealso: VecView(), DMGetGlobalSection() 7035f4d763aaSMatthew G. Knepley @*/ 703614f150ffSMatthew G. Knepley PetscErrorCode DMGetOutputDM(DM dm, DM *odm) 703714f150ffSMatthew G. Knepley { 7038c26acbdeSMatthew G. Knepley PetscSection section; 70392d4e4a49SMatthew G. Knepley PetscBool hasConstraints, ghasConstraints; 704014f150ffSMatthew G. Knepley PetscErrorCode ierr; 704114f150ffSMatthew G. Knepley 704214f150ffSMatthew G. Knepley PetscFunctionBegin; 704314f150ffSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 704414f150ffSMatthew G. Knepley PetscValidPointer(odm,2); 704592fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 7046c26acbdeSMatthew G. Knepley ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr); 7047ffc4695bSBarry Smith ierr = MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 70482d4e4a49SMatthew G. Knepley if (!ghasConstraints) { 7049c26acbdeSMatthew G. Knepley *odm = dm; 7050c26acbdeSMatthew G. Knepley PetscFunctionReturn(0); 7051c26acbdeSMatthew G. Knepley } 705214f150ffSMatthew G. Knepley if (!dm->dmBC) { 7053c26acbdeSMatthew G. Knepley PetscSection newSection, gsection; 705414f150ffSMatthew G. Knepley PetscSF sf; 705514f150ffSMatthew G. Knepley 705614f150ffSMatthew G. Knepley ierr = DMClone(dm, &dm->dmBC);CHKERRQ(ierr); 7057e5e52638SMatthew G. Knepley ierr = DMCopyDisc(dm, dm->dmBC);CHKERRQ(ierr); 705814f150ffSMatthew G. Knepley ierr = PetscSectionClone(section, &newSection);CHKERRQ(ierr); 705992fd8e1eSJed Brown ierr = DMSetLocalSection(dm->dmBC, newSection);CHKERRQ(ierr); 706014f150ffSMatthew G. Knepley ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr); 706114f150ffSMatthew G. Knepley ierr = DMGetPointSF(dm->dmBC, &sf);CHKERRQ(ierr); 706215b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr); 7063e87a4003SBarry Smith ierr = DMSetGlobalSection(dm->dmBC, gsection);CHKERRQ(ierr); 706414f150ffSMatthew G. Knepley ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr); 706514f150ffSMatthew G. Knepley } 706614f150ffSMatthew G. Knepley *odm = dm->dmBC; 706714f150ffSMatthew G. Knepley PetscFunctionReturn(0); 706814f150ffSMatthew G. Knepley } 7069f4d763aaSMatthew G. Knepley 7070f4d763aaSMatthew G. Knepley /*@ 7071cdb7a50dSMatthew G. Knepley DMGetOutputSequenceNumber - Retrieve the sequence number/value for output 7072f4d763aaSMatthew G. Knepley 7073f4d763aaSMatthew G. Knepley Input Parameter: 7074f4d763aaSMatthew G. Knepley . dm - The original DM 7075f4d763aaSMatthew G. Knepley 7076cdb7a50dSMatthew G. Knepley Output Parameters: 7077cdb7a50dSMatthew G. Knepley + num - The output sequence number 7078cdb7a50dSMatthew G. Knepley - val - The output sequence value 7079f4d763aaSMatthew G. Knepley 7080f4d763aaSMatthew G. Knepley Level: intermediate 7081f4d763aaSMatthew G. Knepley 7082f4d763aaSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 7083f4d763aaSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 7084f4d763aaSMatthew G. Knepley 7085f4d763aaSMatthew G. Knepley .seealso: VecView() 7086f4d763aaSMatthew G. Knepley @*/ 7087cdb7a50dSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val) 7088f4d763aaSMatthew G. Knepley { 7089f4d763aaSMatthew G. Knepley PetscFunctionBegin; 7090f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7091534a8f05SLisandro Dalcin if (num) {PetscValidIntPointer(num,2); *num = dm->outputSequenceNum;} 7092534a8f05SLisandro Dalcin if (val) {PetscValidRealPointer(val,3);*val = dm->outputSequenceVal;} 7093f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 7094f4d763aaSMatthew G. Knepley } 7095f4d763aaSMatthew G. Knepley 7096f4d763aaSMatthew G. Knepley /*@ 7097cdb7a50dSMatthew G. Knepley DMSetOutputSequenceNumber - Set the sequence number/value for output 7098f4d763aaSMatthew G. Knepley 7099f4d763aaSMatthew G. Knepley Input Parameters: 7100f4d763aaSMatthew G. Knepley + dm - The original DM 7101cdb7a50dSMatthew G. Knepley . num - The output sequence number 7102cdb7a50dSMatthew G. Knepley - val - The output sequence value 7103f4d763aaSMatthew G. Knepley 7104f4d763aaSMatthew G. Knepley Level: intermediate 7105f4d763aaSMatthew G. Knepley 7106f4d763aaSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 7107f4d763aaSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 7108f4d763aaSMatthew G. Knepley 7109f4d763aaSMatthew G. Knepley .seealso: VecView() 7110f4d763aaSMatthew G. Knepley @*/ 7111cdb7a50dSMatthew G. Knepley PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val) 7112f4d763aaSMatthew G. Knepley { 7113f4d763aaSMatthew G. Knepley PetscFunctionBegin; 7114f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7115f4d763aaSMatthew G. Knepley dm->outputSequenceNum = num; 7116cdb7a50dSMatthew G. Knepley dm->outputSequenceVal = val; 7117cdb7a50dSMatthew G. Knepley PetscFunctionReturn(0); 7118cdb7a50dSMatthew G. Knepley } 7119cdb7a50dSMatthew G. Knepley 7120cdb7a50dSMatthew G. Knepley /*@C 7121cdb7a50dSMatthew G. Knepley DMOutputSequenceLoad - Retrieve the sequence value from a Viewer 7122cdb7a50dSMatthew G. Knepley 7123cdb7a50dSMatthew G. Knepley Input Parameters: 7124cdb7a50dSMatthew G. Knepley + dm - The original DM 7125cdb7a50dSMatthew G. Knepley . name - The sequence name 7126cdb7a50dSMatthew G. Knepley - num - The output sequence number 7127cdb7a50dSMatthew G. Knepley 7128cdb7a50dSMatthew G. Knepley Output Parameter: 7129cdb7a50dSMatthew G. Knepley . val - The output sequence value 7130cdb7a50dSMatthew G. Knepley 7131cdb7a50dSMatthew G. Knepley Level: intermediate 7132cdb7a50dSMatthew G. Knepley 7133cdb7a50dSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 7134cdb7a50dSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 7135cdb7a50dSMatthew G. Knepley 7136cdb7a50dSMatthew G. Knepley .seealso: DMGetOutputSequenceNumber(), DMSetOutputSequenceNumber(), VecView() 7137cdb7a50dSMatthew G. Knepley @*/ 7138cdb7a50dSMatthew G. Knepley PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val) 7139cdb7a50dSMatthew G. Knepley { 7140cdb7a50dSMatthew G. Knepley PetscBool ishdf5; 7141cdb7a50dSMatthew G. Knepley PetscErrorCode ierr; 7142cdb7a50dSMatthew G. Knepley 7143cdb7a50dSMatthew G. Knepley PetscFunctionBegin; 7144cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7145cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 7146534a8f05SLisandro Dalcin PetscValidRealPointer(val,4); 7147cdb7a50dSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 7148cdb7a50dSMatthew G. Knepley if (ishdf5) { 7149cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 7150cdb7a50dSMatthew G. Knepley PetscScalar value; 7151cdb7a50dSMatthew G. Knepley 715239d25373SMatthew G. Knepley ierr = DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer);CHKERRQ(ierr); 71534aeb217fSMatthew G. Knepley *val = PetscRealPart(value); 7154cdb7a50dSMatthew G. Knepley #endif 7155cdb7a50dSMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()"); 7156f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 7157f4d763aaSMatthew G. Knepley } 71588e4ac7eaSMatthew G. Knepley 71598e4ac7eaSMatthew G. Knepley /*@ 71608e4ac7eaSMatthew G. Knepley DMGetUseNatural - Get the flag for creating a mapping to the natural order on distribution 71618e4ac7eaSMatthew G. Knepley 71628e4ac7eaSMatthew G. Knepley Not collective 71638e4ac7eaSMatthew G. Knepley 71648e4ac7eaSMatthew G. Knepley Input Parameter: 71658e4ac7eaSMatthew G. Knepley . dm - The DM 71668e4ac7eaSMatthew G. Knepley 71678e4ac7eaSMatthew G. Knepley Output Parameter: 71688e4ac7eaSMatthew G. Knepley . useNatural - The flag to build the mapping to a natural order during distribution 71698e4ac7eaSMatthew G. Knepley 71708e4ac7eaSMatthew G. Knepley Level: beginner 71718e4ac7eaSMatthew G. Knepley 71728e4ac7eaSMatthew G. Knepley .seealso: DMSetUseNatural(), DMCreate() 71738e4ac7eaSMatthew G. Knepley @*/ 71748e4ac7eaSMatthew G. Knepley PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural) 71758e4ac7eaSMatthew G. Knepley { 71768e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 71778e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7178534a8f05SLisandro Dalcin PetscValidBoolPointer(useNatural, 2); 71798e4ac7eaSMatthew G. Knepley *useNatural = dm->useNatural; 71808e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 71818e4ac7eaSMatthew G. Knepley } 71828e4ac7eaSMatthew G. Knepley 71838e4ac7eaSMatthew G. Knepley /*@ 71845d3b26e6SMatthew G. Knepley DMSetUseNatural - Set the flag for creating a mapping to the natural order after distribution 71858e4ac7eaSMatthew G. Knepley 71868e4ac7eaSMatthew G. Knepley Collective on dm 71878e4ac7eaSMatthew G. Knepley 71888e4ac7eaSMatthew G. Knepley Input Parameters: 71898e4ac7eaSMatthew G. Knepley + dm - The DM 71908e4ac7eaSMatthew G. Knepley - useNatural - The flag to build the mapping to a natural order during distribution 71918e4ac7eaSMatthew G. Knepley 71925d3b26e6SMatthew G. Knepley Note: This also causes the map to be build after DMCreateSubDM() and DMCreateSuperDM() 71935d3b26e6SMatthew G. Knepley 71948e4ac7eaSMatthew G. Knepley Level: beginner 71958e4ac7eaSMatthew G. Knepley 71965d3b26e6SMatthew G. Knepley .seealso: DMGetUseNatural(), DMCreate(), DMPlexDistribute(), DMCreateSubDM(), DMCreateSuperDM() 71978e4ac7eaSMatthew G. Knepley @*/ 71988e4ac7eaSMatthew G. Knepley PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural) 71998e4ac7eaSMatthew G. Knepley { 72008e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 72018e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72028833efb5SBlaise Bourdin PetscValidLogicalCollectiveBool(dm, useNatural, 2); 72038e4ac7eaSMatthew G. Knepley dm->useNatural = useNatural; 72048e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 72058e4ac7eaSMatthew G. Knepley } 7206c58f1c22SToby Isaac 7207c58f1c22SToby Isaac 7208c58f1c22SToby Isaac /*@C 7209c58f1c22SToby Isaac DMCreateLabel - Create a label of the given name if it does not already exist 7210c58f1c22SToby Isaac 7211c58f1c22SToby Isaac Not Collective 7212c58f1c22SToby Isaac 7213c58f1c22SToby Isaac Input Parameters: 7214c58f1c22SToby Isaac + dm - The DM object 7215c58f1c22SToby Isaac - name - The label name 7216c58f1c22SToby Isaac 7217c58f1c22SToby Isaac Level: intermediate 7218c58f1c22SToby Isaac 7219c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7220c58f1c22SToby Isaac @*/ 7221c58f1c22SToby Isaac PetscErrorCode DMCreateLabel(DM dm, const char name[]) 7222c58f1c22SToby Isaac { 72235d80c0bfSVaclav Hapla PetscBool flg; 72245d80c0bfSVaclav Hapla DMLabel label; 7225c58f1c22SToby Isaac PetscErrorCode ierr; 7226c58f1c22SToby Isaac 7227c58f1c22SToby Isaac PetscFunctionBegin; 7228c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7229c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 72305d80c0bfSVaclav Hapla ierr = DMHasLabel(dm, name, &flg);CHKERRQ(ierr); 7231c58f1c22SToby Isaac if (!flg) { 72325d80c0bfSVaclav Hapla ierr = DMLabelCreate(PETSC_COMM_SELF, name, &label);CHKERRQ(ierr); 72335d80c0bfSVaclav Hapla ierr = DMAddLabel(dm, label);CHKERRQ(ierr); 72345d80c0bfSVaclav Hapla ierr = DMLabelDestroy(&label);CHKERRQ(ierr); 7235c58f1c22SToby Isaac } 7236c58f1c22SToby Isaac PetscFunctionReturn(0); 7237c58f1c22SToby Isaac } 7238c58f1c22SToby Isaac 7239c58f1c22SToby Isaac /*@C 72400fdc7489SMatthew Knepley DMCreateLabelAtIndex - Create a label of the given name at the iven index. If it already exists, move it to this index. 72410fdc7489SMatthew Knepley 72420fdc7489SMatthew Knepley Not Collective 72430fdc7489SMatthew Knepley 72440fdc7489SMatthew Knepley Input Parameters: 72450fdc7489SMatthew Knepley + dm - The DM object 72460fdc7489SMatthew Knepley . l - The index for the label 72470fdc7489SMatthew Knepley - name - The label name 72480fdc7489SMatthew Knepley 72490fdc7489SMatthew Knepley Level: intermediate 72500fdc7489SMatthew Knepley 72510fdc7489SMatthew Knepley .seealso: DMCreateLabel(), DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 72520fdc7489SMatthew Knepley @*/ 72530fdc7489SMatthew Knepley PetscErrorCode DMCreateLabelAtIndex(DM dm, PetscInt l, const char name[]) 72540fdc7489SMatthew Knepley { 72550fdc7489SMatthew Knepley DMLabelLink orig, prev = NULL; 72560fdc7489SMatthew Knepley DMLabel label; 72570fdc7489SMatthew Knepley PetscInt Nl, m; 72580fdc7489SMatthew Knepley PetscBool flg, match; 72590fdc7489SMatthew Knepley const char *lname; 72600fdc7489SMatthew Knepley PetscErrorCode ierr; 72610fdc7489SMatthew Knepley 72620fdc7489SMatthew Knepley PetscFunctionBegin; 72630fdc7489SMatthew Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72640fdc7489SMatthew Knepley PetscValidCharPointer(name, 2); 72650fdc7489SMatthew Knepley ierr = DMHasLabel(dm, name, &flg);CHKERRQ(ierr); 72660fdc7489SMatthew Knepley if (!flg) { 72670fdc7489SMatthew Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, name, &label);CHKERRQ(ierr); 72680fdc7489SMatthew Knepley ierr = DMAddLabel(dm, label);CHKERRQ(ierr); 72690fdc7489SMatthew Knepley ierr = DMLabelDestroy(&label);CHKERRQ(ierr); 72700fdc7489SMatthew Knepley } 72710fdc7489SMatthew Knepley ierr = DMGetNumLabels(dm, &Nl);CHKERRQ(ierr); 72720fdc7489SMatthew Knepley if (l >= Nl) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label index %D must be in [0, %D)", l, Nl); 72730fdc7489SMatthew Knepley for (m = 0, orig = dm->labels; m < Nl; ++m, prev = orig, orig = orig->next) { 72740fdc7489SMatthew Knepley ierr = PetscObjectGetName((PetscObject) orig->label, &lname);CHKERRQ(ierr); 72750fdc7489SMatthew Knepley ierr = PetscStrcmp(name, lname, &match);CHKERRQ(ierr); 72760fdc7489SMatthew Knepley if (match) break; 72770fdc7489SMatthew Knepley } 72780fdc7489SMatthew Knepley if (m == l) PetscFunctionReturn(0); 72790fdc7489SMatthew Knepley if (!m) dm->labels = orig->next; 72800fdc7489SMatthew Knepley else prev->next = orig->next; 72810fdc7489SMatthew Knepley if (!l) { 72820fdc7489SMatthew Knepley orig->next = dm->labels; 72830fdc7489SMatthew Knepley dm->labels = orig; 72840fdc7489SMatthew Knepley } else { 72850fdc7489SMatthew Knepley for (m = 0, prev = dm->labels; m < l-1; ++m, prev = prev->next); 72860fdc7489SMatthew Knepley orig->next = prev->next; 72870fdc7489SMatthew Knepley prev->next = orig; 72880fdc7489SMatthew Knepley } 72890fdc7489SMatthew Knepley PetscFunctionReturn(0); 72900fdc7489SMatthew Knepley } 72910fdc7489SMatthew Knepley 72920fdc7489SMatthew Knepley /*@C 7293c58f1c22SToby Isaac DMGetLabelValue - Get the value in a Sieve Label for the given point, with 0 as the default 7294c58f1c22SToby Isaac 7295c58f1c22SToby Isaac Not Collective 7296c58f1c22SToby Isaac 7297c58f1c22SToby Isaac Input Parameters: 7298c58f1c22SToby Isaac + dm - The DM object 7299c58f1c22SToby Isaac . name - The label name 7300c58f1c22SToby Isaac - point - The mesh point 7301c58f1c22SToby Isaac 7302c58f1c22SToby Isaac Output Parameter: 7303c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label 7304c58f1c22SToby Isaac 7305c58f1c22SToby Isaac Level: beginner 7306c58f1c22SToby Isaac 7307c58f1c22SToby Isaac .seealso: DMLabelGetValue(), DMSetLabelValue(), DMGetStratumIS() 7308c58f1c22SToby Isaac @*/ 7309c58f1c22SToby Isaac PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value) 7310c58f1c22SToby Isaac { 7311c58f1c22SToby Isaac DMLabel label; 7312c58f1c22SToby Isaac PetscErrorCode ierr; 7313c58f1c22SToby Isaac 7314c58f1c22SToby Isaac PetscFunctionBegin; 7315c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7316c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7317c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 731813903a91SSatish Balay if (!label) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name); 7319c58f1c22SToby Isaac ierr = DMLabelGetValue(label, point, value);CHKERRQ(ierr); 7320c58f1c22SToby Isaac PetscFunctionReturn(0); 7321c58f1c22SToby Isaac } 7322c58f1c22SToby Isaac 7323c58f1c22SToby Isaac /*@C 7324c58f1c22SToby Isaac DMSetLabelValue - Add a point to a Sieve Label with given value 7325c58f1c22SToby Isaac 7326c58f1c22SToby Isaac Not Collective 7327c58f1c22SToby Isaac 7328c58f1c22SToby Isaac Input Parameters: 7329c58f1c22SToby Isaac + dm - The DM object 7330c58f1c22SToby Isaac . name - The label name 7331c58f1c22SToby Isaac . point - The mesh point 7332c58f1c22SToby Isaac - value - The label value for this point 7333c58f1c22SToby Isaac 7334c58f1c22SToby Isaac Output Parameter: 7335c58f1c22SToby Isaac 7336c58f1c22SToby Isaac Level: beginner 7337c58f1c22SToby Isaac 7338c58f1c22SToby Isaac .seealso: DMLabelSetValue(), DMGetStratumIS(), DMClearLabelValue() 7339c58f1c22SToby Isaac @*/ 7340c58f1c22SToby Isaac PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 7341c58f1c22SToby Isaac { 7342c58f1c22SToby Isaac DMLabel label; 7343c58f1c22SToby Isaac PetscErrorCode ierr; 7344c58f1c22SToby Isaac 7345c58f1c22SToby Isaac PetscFunctionBegin; 7346c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7347c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7348c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7349c58f1c22SToby Isaac if (!label) { 7350c58f1c22SToby Isaac ierr = DMCreateLabel(dm, name);CHKERRQ(ierr); 7351c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7352c58f1c22SToby Isaac } 7353c58f1c22SToby Isaac ierr = DMLabelSetValue(label, point, value);CHKERRQ(ierr); 7354c58f1c22SToby Isaac PetscFunctionReturn(0); 7355c58f1c22SToby Isaac } 7356c58f1c22SToby Isaac 7357c58f1c22SToby Isaac /*@C 7358c58f1c22SToby Isaac DMClearLabelValue - Remove a point from a Sieve Label with given value 7359c58f1c22SToby Isaac 7360c58f1c22SToby Isaac Not Collective 7361c58f1c22SToby Isaac 7362c58f1c22SToby Isaac Input Parameters: 7363c58f1c22SToby Isaac + dm - The DM object 7364c58f1c22SToby Isaac . name - The label name 7365c58f1c22SToby Isaac . point - The mesh point 7366c58f1c22SToby Isaac - value - The label value for this point 7367c58f1c22SToby Isaac 7368c58f1c22SToby Isaac Output Parameter: 7369c58f1c22SToby Isaac 7370c58f1c22SToby Isaac Level: beginner 7371c58f1c22SToby Isaac 7372c58f1c22SToby Isaac .seealso: DMLabelClearValue(), DMSetLabelValue(), DMGetStratumIS() 7373c58f1c22SToby Isaac @*/ 7374c58f1c22SToby Isaac PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 7375c58f1c22SToby Isaac { 7376c58f1c22SToby Isaac DMLabel label; 7377c58f1c22SToby Isaac PetscErrorCode ierr; 7378c58f1c22SToby Isaac 7379c58f1c22SToby Isaac PetscFunctionBegin; 7380c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7381c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7382c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7383c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7384c58f1c22SToby Isaac ierr = DMLabelClearValue(label, point, value);CHKERRQ(ierr); 7385c58f1c22SToby Isaac PetscFunctionReturn(0); 7386c58f1c22SToby Isaac } 7387c58f1c22SToby Isaac 7388c58f1c22SToby Isaac /*@C 7389c58f1c22SToby Isaac DMGetLabelSize - Get the number of different integer ids in a Label 7390c58f1c22SToby Isaac 7391c58f1c22SToby Isaac Not Collective 7392c58f1c22SToby Isaac 7393c58f1c22SToby Isaac Input Parameters: 7394c58f1c22SToby Isaac + dm - The DM object 7395c58f1c22SToby Isaac - name - The label name 7396c58f1c22SToby Isaac 7397c58f1c22SToby Isaac Output Parameter: 7398c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist 7399c58f1c22SToby Isaac 7400c58f1c22SToby Isaac Level: beginner 7401c58f1c22SToby Isaac 7402df813f42SMatthew G. Knepley .seealso: DMLabelGetNumValues(), DMSetLabelValue() 7403c58f1c22SToby Isaac @*/ 7404c58f1c22SToby Isaac PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size) 7405c58f1c22SToby Isaac { 7406c58f1c22SToby Isaac DMLabel label; 7407c58f1c22SToby Isaac PetscErrorCode ierr; 7408c58f1c22SToby Isaac 7409c58f1c22SToby Isaac PetscFunctionBegin; 7410c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7411c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7412534a8f05SLisandro Dalcin PetscValidIntPointer(size, 3); 7413c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7414c58f1c22SToby Isaac *size = 0; 7415c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7416c58f1c22SToby Isaac ierr = DMLabelGetNumValues(label, size);CHKERRQ(ierr); 7417c58f1c22SToby Isaac PetscFunctionReturn(0); 7418c58f1c22SToby Isaac } 7419c58f1c22SToby Isaac 7420c58f1c22SToby Isaac /*@C 7421c58f1c22SToby Isaac DMGetLabelIdIS - Get the integer ids in a label 7422c58f1c22SToby Isaac 7423c58f1c22SToby Isaac Not Collective 7424c58f1c22SToby Isaac 7425c58f1c22SToby Isaac Input Parameters: 7426c58f1c22SToby Isaac + mesh - The DM object 7427c58f1c22SToby Isaac - name - The label name 7428c58f1c22SToby Isaac 7429c58f1c22SToby Isaac Output Parameter: 7430c58f1c22SToby Isaac . ids - The integer ids, or NULL if the label does not exist 7431c58f1c22SToby Isaac 7432c58f1c22SToby Isaac Level: beginner 7433c58f1c22SToby Isaac 7434c58f1c22SToby Isaac .seealso: DMLabelGetValueIS(), DMGetLabelSize() 7435c58f1c22SToby Isaac @*/ 7436c58f1c22SToby Isaac PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids) 7437c58f1c22SToby Isaac { 7438c58f1c22SToby Isaac DMLabel label; 7439c58f1c22SToby Isaac PetscErrorCode ierr; 7440c58f1c22SToby Isaac 7441c58f1c22SToby Isaac PetscFunctionBegin; 7442c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7443c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7444c58f1c22SToby Isaac PetscValidPointer(ids, 3); 7445c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7446c58f1c22SToby Isaac *ids = NULL; 7447dab2e251SBlaise Bourdin if (label) { 7448c58f1c22SToby Isaac ierr = DMLabelGetValueIS(label, ids);CHKERRQ(ierr); 7449dab2e251SBlaise Bourdin } else { 7450dab2e251SBlaise Bourdin /* returning an empty IS */ 7451dab2e251SBlaise Bourdin ierr = ISCreateGeneral(PETSC_COMM_SELF,0,NULL,PETSC_USE_POINTER,ids);CHKERRQ(ierr); 7452dab2e251SBlaise Bourdin } 7453c58f1c22SToby Isaac PetscFunctionReturn(0); 7454c58f1c22SToby Isaac } 7455c58f1c22SToby Isaac 7456c58f1c22SToby Isaac /*@C 7457c58f1c22SToby Isaac DMGetStratumSize - Get the number of points in a label stratum 7458c58f1c22SToby Isaac 7459c58f1c22SToby Isaac Not Collective 7460c58f1c22SToby Isaac 7461c58f1c22SToby Isaac Input Parameters: 7462c58f1c22SToby Isaac + dm - The DM object 7463c58f1c22SToby Isaac . name - The label name 7464c58f1c22SToby Isaac - value - The stratum value 7465c58f1c22SToby Isaac 7466c58f1c22SToby Isaac Output Parameter: 7467c58f1c22SToby Isaac . size - The stratum size 7468c58f1c22SToby Isaac 7469c58f1c22SToby Isaac Level: beginner 7470c58f1c22SToby Isaac 7471c58f1c22SToby Isaac .seealso: DMLabelGetStratumSize(), DMGetLabelSize(), DMGetLabelIds() 7472c58f1c22SToby Isaac @*/ 7473c58f1c22SToby Isaac PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size) 7474c58f1c22SToby Isaac { 7475c58f1c22SToby Isaac DMLabel label; 7476c58f1c22SToby Isaac PetscErrorCode ierr; 7477c58f1c22SToby Isaac 7478c58f1c22SToby Isaac PetscFunctionBegin; 7479c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7480c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7481534a8f05SLisandro Dalcin PetscValidIntPointer(size, 4); 7482c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7483c58f1c22SToby Isaac *size = 0; 7484c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7485c58f1c22SToby Isaac ierr = DMLabelGetStratumSize(label, value, size);CHKERRQ(ierr); 7486c58f1c22SToby Isaac PetscFunctionReturn(0); 7487c58f1c22SToby Isaac } 7488c58f1c22SToby Isaac 7489c58f1c22SToby Isaac /*@C 7490c58f1c22SToby Isaac DMGetStratumIS - Get the points in a label stratum 7491c58f1c22SToby Isaac 7492c58f1c22SToby Isaac Not Collective 7493c58f1c22SToby Isaac 7494c58f1c22SToby Isaac Input Parameters: 7495c58f1c22SToby Isaac + dm - The DM object 7496c58f1c22SToby Isaac . name - The label name 7497c58f1c22SToby Isaac - value - The stratum value 7498c58f1c22SToby Isaac 7499c58f1c22SToby Isaac Output Parameter: 7500c58f1c22SToby Isaac . points - The stratum points, or NULL if the label does not exist or does not have that value 7501c58f1c22SToby Isaac 7502c58f1c22SToby Isaac Level: beginner 7503c58f1c22SToby Isaac 7504c58f1c22SToby Isaac .seealso: DMLabelGetStratumIS(), DMGetStratumSize() 7505c58f1c22SToby Isaac @*/ 7506c58f1c22SToby Isaac PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points) 7507c58f1c22SToby Isaac { 7508c58f1c22SToby Isaac DMLabel label; 7509c58f1c22SToby Isaac PetscErrorCode ierr; 7510c58f1c22SToby Isaac 7511c58f1c22SToby Isaac PetscFunctionBegin; 7512c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7513c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7514c58f1c22SToby Isaac PetscValidPointer(points, 4); 7515c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7516c58f1c22SToby Isaac *points = NULL; 7517c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7518c58f1c22SToby Isaac ierr = DMLabelGetStratumIS(label, value, points);CHKERRQ(ierr); 7519c58f1c22SToby Isaac PetscFunctionReturn(0); 7520c58f1c22SToby Isaac } 7521c58f1c22SToby Isaac 75224de306b1SToby Isaac /*@C 75239044fa66SMatthew G. Knepley DMSetStratumIS - Set the points in a label stratum 75244de306b1SToby Isaac 75254de306b1SToby Isaac Not Collective 75264de306b1SToby Isaac 75274de306b1SToby Isaac Input Parameters: 75284de306b1SToby Isaac + dm - The DM object 75294de306b1SToby Isaac . name - The label name 75304de306b1SToby Isaac . value - The stratum value 75314de306b1SToby Isaac - points - The stratum points 75324de306b1SToby Isaac 75334de306b1SToby Isaac Level: beginner 75344de306b1SToby Isaac 75354de306b1SToby Isaac .seealso: DMLabelSetStratumIS(), DMGetStratumSize() 75364de306b1SToby Isaac @*/ 75374de306b1SToby Isaac PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points) 75384de306b1SToby Isaac { 75394de306b1SToby Isaac DMLabel label; 75404de306b1SToby Isaac PetscErrorCode ierr; 75414de306b1SToby Isaac 75424de306b1SToby Isaac PetscFunctionBegin; 75434de306b1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 75444de306b1SToby Isaac PetscValidCharPointer(name, 2); 75454de306b1SToby Isaac PetscValidPointer(points, 4); 75464de306b1SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 75474de306b1SToby Isaac if (!label) PetscFunctionReturn(0); 75484de306b1SToby Isaac ierr = DMLabelSetStratumIS(label, value, points);CHKERRQ(ierr); 75494de306b1SToby Isaac PetscFunctionReturn(0); 75504de306b1SToby Isaac } 75514de306b1SToby Isaac 7552c58f1c22SToby Isaac /*@C 7553c58f1c22SToby Isaac DMClearLabelStratum - Remove all points from a stratum from a Sieve Label 7554c58f1c22SToby Isaac 7555c58f1c22SToby Isaac Not Collective 7556c58f1c22SToby Isaac 7557c58f1c22SToby Isaac Input Parameters: 7558c58f1c22SToby Isaac + dm - The DM object 7559c58f1c22SToby Isaac . name - The label name 7560c58f1c22SToby Isaac - value - The label value for this point 7561c58f1c22SToby Isaac 7562c58f1c22SToby Isaac Output Parameter: 7563c58f1c22SToby Isaac 7564c58f1c22SToby Isaac Level: beginner 7565c58f1c22SToby Isaac 7566c58f1c22SToby Isaac .seealso: DMLabelClearStratum(), DMSetLabelValue(), DMGetStratumIS(), DMClearLabelValue() 7567c58f1c22SToby Isaac @*/ 7568c58f1c22SToby Isaac PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value) 7569c58f1c22SToby Isaac { 7570c58f1c22SToby Isaac DMLabel label; 7571c58f1c22SToby Isaac PetscErrorCode ierr; 7572c58f1c22SToby Isaac 7573c58f1c22SToby Isaac PetscFunctionBegin; 7574c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7575c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7576c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7577c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7578c58f1c22SToby Isaac ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr); 7579c58f1c22SToby Isaac PetscFunctionReturn(0); 7580c58f1c22SToby Isaac } 7581c58f1c22SToby Isaac 7582c58f1c22SToby Isaac /*@ 7583c58f1c22SToby Isaac DMGetNumLabels - Return the number of labels defined by the mesh 7584c58f1c22SToby Isaac 7585c58f1c22SToby Isaac Not Collective 7586c58f1c22SToby Isaac 7587c58f1c22SToby Isaac Input Parameter: 7588c58f1c22SToby Isaac . dm - The DM object 7589c58f1c22SToby Isaac 7590c58f1c22SToby Isaac Output Parameter: 7591c58f1c22SToby Isaac . numLabels - the number of Labels 7592c58f1c22SToby Isaac 7593c58f1c22SToby Isaac Level: intermediate 7594c58f1c22SToby Isaac 7595c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7596c58f1c22SToby Isaac @*/ 7597c58f1c22SToby Isaac PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels) 7598c58f1c22SToby Isaac { 75995d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7600c58f1c22SToby Isaac PetscInt n = 0; 7601c58f1c22SToby Isaac 7602c58f1c22SToby Isaac PetscFunctionBegin; 7603c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7604534a8f05SLisandro Dalcin PetscValidIntPointer(numLabels, 2); 7605c58f1c22SToby Isaac while (next) {++n; next = next->next;} 7606c58f1c22SToby Isaac *numLabels = n; 7607c58f1c22SToby Isaac PetscFunctionReturn(0); 7608c58f1c22SToby Isaac } 7609c58f1c22SToby Isaac 7610c58f1c22SToby Isaac /*@C 7611c58f1c22SToby Isaac DMGetLabelName - Return the name of nth label 7612c58f1c22SToby Isaac 7613c58f1c22SToby Isaac Not Collective 7614c58f1c22SToby Isaac 7615c58f1c22SToby Isaac Input Parameters: 7616c58f1c22SToby Isaac + dm - The DM object 7617c58f1c22SToby Isaac - n - the label number 7618c58f1c22SToby Isaac 7619c58f1c22SToby Isaac Output Parameter: 7620c58f1c22SToby Isaac . name - the label name 7621c58f1c22SToby Isaac 7622c58f1c22SToby Isaac Level: intermediate 7623c58f1c22SToby Isaac 7624c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7625c58f1c22SToby Isaac @*/ 7626c58f1c22SToby Isaac PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name) 7627c58f1c22SToby Isaac { 76285d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7629c58f1c22SToby Isaac PetscInt l = 0; 7630d67d17b1SMatthew G. Knepley PetscErrorCode ierr; 7631c58f1c22SToby Isaac 7632c58f1c22SToby Isaac PetscFunctionBegin; 7633c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7634c58f1c22SToby Isaac PetscValidPointer(name, 3); 7635c58f1c22SToby Isaac while (next) { 7636c58f1c22SToby Isaac if (l == n) { 7637d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, name);CHKERRQ(ierr); 7638c58f1c22SToby Isaac PetscFunctionReturn(0); 7639c58f1c22SToby Isaac } 7640c58f1c22SToby Isaac ++l; 7641c58f1c22SToby Isaac next = next->next; 7642c58f1c22SToby Isaac } 7643c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n); 7644c58f1c22SToby Isaac } 7645c58f1c22SToby Isaac 7646c58f1c22SToby Isaac /*@C 7647c58f1c22SToby Isaac DMHasLabel - Determine whether the mesh has a label of a given name 7648c58f1c22SToby Isaac 7649c58f1c22SToby Isaac Not Collective 7650c58f1c22SToby Isaac 7651c58f1c22SToby Isaac Input Parameters: 7652c58f1c22SToby Isaac + dm - The DM object 7653c58f1c22SToby Isaac - name - The label name 7654c58f1c22SToby Isaac 7655c58f1c22SToby Isaac Output Parameter: 7656c58f1c22SToby Isaac . hasLabel - PETSC_TRUE if the label is present 7657c58f1c22SToby Isaac 7658c58f1c22SToby Isaac Level: intermediate 7659c58f1c22SToby Isaac 7660c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7661c58f1c22SToby Isaac @*/ 7662c58f1c22SToby Isaac PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel) 7663c58f1c22SToby Isaac { 76645d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7665d67d17b1SMatthew G. Knepley const char *lname; 7666c58f1c22SToby Isaac PetscErrorCode ierr; 7667c58f1c22SToby Isaac 7668c58f1c22SToby Isaac PetscFunctionBegin; 7669c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7670c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7671534a8f05SLisandro Dalcin PetscValidBoolPointer(hasLabel, 3); 7672c58f1c22SToby Isaac *hasLabel = PETSC_FALSE; 7673c58f1c22SToby Isaac while (next) { 7674d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 7675d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, hasLabel);CHKERRQ(ierr); 7676c58f1c22SToby Isaac if (*hasLabel) break; 7677c58f1c22SToby Isaac next = next->next; 7678c58f1c22SToby Isaac } 7679c58f1c22SToby Isaac PetscFunctionReturn(0); 7680c58f1c22SToby Isaac } 7681c58f1c22SToby Isaac 7682c58f1c22SToby Isaac /*@C 7683c58f1c22SToby Isaac DMGetLabel - Return the label of a given name, or NULL 7684c58f1c22SToby Isaac 7685c58f1c22SToby Isaac Not Collective 7686c58f1c22SToby Isaac 7687c58f1c22SToby Isaac Input Parameters: 7688c58f1c22SToby Isaac + dm - The DM object 7689c58f1c22SToby Isaac - name - The label name 7690c58f1c22SToby Isaac 7691c58f1c22SToby Isaac Output Parameter: 7692c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent 7693c58f1c22SToby Isaac 76946d7c9049SMatthew G. Knepley Note: Some of the default labels in a DMPlex will be 76956d7c9049SMatthew G. Knepley $ "depth" - Holds the depth (co-dimension) of each mesh point 76966d7c9049SMatthew G. Knepley $ "celltype" - Holds the topological type of each cell 76976d7c9049SMatthew G. Knepley $ "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 76986d7c9049SMatthew G. Knepley $ "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 76996d7c9049SMatthew G. Knepley $ "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 77006d7c9049SMatthew G. Knepley $ "Vertex Sets" - Mirrors the vertex sets defined by GMsh 77016d7c9049SMatthew G. Knepley 7702c58f1c22SToby Isaac Level: intermediate 7703c58f1c22SToby Isaac 77046d7c9049SMatthew G. Knepley .seealso: DMCreateLabel(), DMHasLabel(), DMPlexGetDepthLabel(), DMPlexGetCellType() 7705c58f1c22SToby Isaac @*/ 7706c58f1c22SToby Isaac PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label) 7707c58f1c22SToby Isaac { 77085d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7709c58f1c22SToby Isaac PetscBool hasLabel; 7710d67d17b1SMatthew G. Knepley const char *lname; 7711c58f1c22SToby Isaac PetscErrorCode ierr; 7712c58f1c22SToby Isaac 7713c58f1c22SToby Isaac PetscFunctionBegin; 7714c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7715c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7716c58f1c22SToby Isaac PetscValidPointer(label, 3); 7717c58f1c22SToby Isaac *label = NULL; 7718c58f1c22SToby Isaac while (next) { 7719d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 7720d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr); 7721c58f1c22SToby Isaac if (hasLabel) { 7722c58f1c22SToby Isaac *label = next->label; 7723c58f1c22SToby Isaac break; 7724c58f1c22SToby Isaac } 7725c58f1c22SToby Isaac next = next->next; 7726c58f1c22SToby Isaac } 7727c58f1c22SToby Isaac PetscFunctionReturn(0); 7728c58f1c22SToby Isaac } 7729c58f1c22SToby Isaac 7730c58f1c22SToby Isaac /*@C 7731c58f1c22SToby Isaac DMGetLabelByNum - Return the nth label 7732c58f1c22SToby Isaac 7733c58f1c22SToby Isaac Not Collective 7734c58f1c22SToby Isaac 7735c58f1c22SToby Isaac Input Parameters: 7736c58f1c22SToby Isaac + dm - The DM object 7737c58f1c22SToby Isaac - n - the label number 7738c58f1c22SToby Isaac 7739c58f1c22SToby Isaac Output Parameter: 7740c58f1c22SToby Isaac . label - the label 7741c58f1c22SToby Isaac 7742c58f1c22SToby Isaac Level: intermediate 7743c58f1c22SToby Isaac 7744c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7745c58f1c22SToby Isaac @*/ 7746c58f1c22SToby Isaac PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label) 7747c58f1c22SToby Isaac { 77485d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7749c58f1c22SToby Isaac PetscInt l = 0; 7750c58f1c22SToby Isaac 7751c58f1c22SToby Isaac PetscFunctionBegin; 7752c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7753c58f1c22SToby Isaac PetscValidPointer(label, 3); 7754c58f1c22SToby Isaac while (next) { 7755c58f1c22SToby Isaac if (l == n) { 7756c58f1c22SToby Isaac *label = next->label; 7757c58f1c22SToby Isaac PetscFunctionReturn(0); 7758c58f1c22SToby Isaac } 7759c58f1c22SToby Isaac ++l; 7760c58f1c22SToby Isaac next = next->next; 7761c58f1c22SToby Isaac } 7762c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n); 7763c58f1c22SToby Isaac } 7764c58f1c22SToby Isaac 7765c58f1c22SToby Isaac /*@C 7766c58f1c22SToby Isaac DMAddLabel - Add the label to this mesh 7767c58f1c22SToby Isaac 7768c58f1c22SToby Isaac Not Collective 7769c58f1c22SToby Isaac 7770c58f1c22SToby Isaac Input Parameters: 7771c58f1c22SToby Isaac + dm - The DM object 7772c58f1c22SToby Isaac - label - The DMLabel 7773c58f1c22SToby Isaac 7774c58f1c22SToby Isaac Level: developer 7775c58f1c22SToby Isaac 7776c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7777c58f1c22SToby Isaac @*/ 7778c58f1c22SToby Isaac PetscErrorCode DMAddLabel(DM dm, DMLabel label) 7779c58f1c22SToby Isaac { 77805d80c0bfSVaclav Hapla DMLabelLink l, *p, tmpLabel; 7781c58f1c22SToby Isaac PetscBool hasLabel; 7782d67d17b1SMatthew G. Knepley const char *lname; 77835d80c0bfSVaclav Hapla PetscBool flg; 7784c58f1c22SToby Isaac PetscErrorCode ierr; 7785c58f1c22SToby Isaac 7786c58f1c22SToby Isaac PetscFunctionBegin; 7787c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7788d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 7789d67d17b1SMatthew G. Knepley ierr = DMHasLabel(dm, lname, &hasLabel);CHKERRQ(ierr); 7790d67d17b1SMatthew G. Knepley if (hasLabel) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname); 7791c58f1c22SToby Isaac ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr); 7792c58f1c22SToby Isaac tmpLabel->label = label; 7793c58f1c22SToby Isaac tmpLabel->output = PETSC_TRUE; 77945d80c0bfSVaclav Hapla for (p=&dm->labels; (l=*p); p=&l->next) {} 77955d80c0bfSVaclav Hapla *p = tmpLabel; 779608f633c4SVaclav Hapla ierr = PetscObjectReference((PetscObject)label);CHKERRQ(ierr); 77975d80c0bfSVaclav Hapla ierr = PetscStrcmp(lname, "depth", &flg);CHKERRQ(ierr); 77985d80c0bfSVaclav Hapla if (flg) dm->depthLabel = label; 7799ba2698f1SMatthew G. Knepley ierr = PetscStrcmp(lname, "celltype", &flg);CHKERRQ(ierr); 7800ba2698f1SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 7801c58f1c22SToby Isaac PetscFunctionReturn(0); 7802c58f1c22SToby Isaac } 7803c58f1c22SToby Isaac 7804c58f1c22SToby Isaac /*@C 7805e5472504SVaclav Hapla DMRemoveLabel - Remove the label given by name from this mesh 7806c58f1c22SToby Isaac 7807c58f1c22SToby Isaac Not Collective 7808c58f1c22SToby Isaac 7809c58f1c22SToby Isaac Input Parameters: 7810c58f1c22SToby Isaac + dm - The DM object 7811c58f1c22SToby Isaac - name - The label name 7812c58f1c22SToby Isaac 7813c58f1c22SToby Isaac Output Parameter: 7814c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent 7815c58f1c22SToby Isaac 7816c58f1c22SToby Isaac Level: developer 7817c58f1c22SToby Isaac 7818e5472504SVaclav Hapla Notes: 7819e5472504SVaclav Hapla DMRemoveLabel(dm,name,NULL) removes the label from dm and calls 7820e5472504SVaclav Hapla DMLabelDestroy() on the label. 7821e5472504SVaclav Hapla 7822e5472504SVaclav Hapla DMRemoveLabel(dm,name,&label) removes the label from dm, but it DOES NOT 7823e5472504SVaclav Hapla call DMLabelDestroy(). Instead, the label is returned and the user is 7824e5472504SVaclav Hapla responsible of calling DMLabelDestroy() at some point. 7825e5472504SVaclav Hapla 7826e5472504SVaclav Hapla .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabel(), DMGetLabelValue(), DMSetLabelValue(), DMLabelDestroy(), DMRemoveLabelBySelf() 7827c58f1c22SToby Isaac @*/ 7828c58f1c22SToby Isaac PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label) 7829c58f1c22SToby Isaac { 783095d578d6SVaclav Hapla DMLabelLink link, *pnext; 7831c58f1c22SToby Isaac PetscBool hasLabel; 7832d67d17b1SMatthew G. Knepley const char *lname; 7833c58f1c22SToby Isaac PetscErrorCode ierr; 7834c58f1c22SToby Isaac 7835c58f1c22SToby Isaac PetscFunctionBegin; 7836c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7837e5472504SVaclav Hapla PetscValidCharPointer(name, 2); 7838e5472504SVaclav Hapla if (label) { 7839e5472504SVaclav Hapla PetscValidPointer(label, 3); 7840c58f1c22SToby Isaac *label = NULL; 7841e5472504SVaclav Hapla } 78425d80c0bfSVaclav Hapla for (pnext=&dm->labels; (link=*pnext); pnext=&link->next) { 784395d578d6SVaclav Hapla ierr = PetscObjectGetName((PetscObject) link->label, &lname);CHKERRQ(ierr); 7844d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr); 7845c58f1c22SToby Isaac if (hasLabel) { 784695d578d6SVaclav Hapla *pnext = link->next; /* Remove from list */ 7847c58f1c22SToby Isaac ierr = PetscStrcmp(name, "depth", &hasLabel);CHKERRQ(ierr); 784895d578d6SVaclav Hapla if (hasLabel) dm->depthLabel = NULL; 7849ba2698f1SMatthew G. Knepley ierr = PetscStrcmp(name, "celltype", &hasLabel);CHKERRQ(ierr); 7850ba2698f1SMatthew G. Knepley if (hasLabel) dm->celltypeLabel = NULL; 785195d578d6SVaclav Hapla if (label) *label = link->label; 785295d578d6SVaclav Hapla else {ierr = DMLabelDestroy(&link->label);CHKERRQ(ierr);} 785395d578d6SVaclav Hapla ierr = PetscFree(link);CHKERRQ(ierr); 7854c58f1c22SToby Isaac break; 7855c58f1c22SToby Isaac } 7856c58f1c22SToby Isaac } 7857c58f1c22SToby Isaac PetscFunctionReturn(0); 7858c58f1c22SToby Isaac } 7859c58f1c22SToby Isaac 7860306894acSVaclav Hapla /*@ 7861306894acSVaclav Hapla DMRemoveLabelBySelf - Remove the label from this mesh 7862306894acSVaclav Hapla 7863306894acSVaclav Hapla Not Collective 7864306894acSVaclav Hapla 7865306894acSVaclav Hapla Input Parameters: 7866306894acSVaclav Hapla + dm - The DM object 7867306894acSVaclav Hapla . label - (Optional) The DMLabel to be removed from the DM 7868306894acSVaclav Hapla - failNotFound - Should it fail if the label is not found in the DM? 7869306894acSVaclav Hapla 7870306894acSVaclav Hapla Level: developer 7871306894acSVaclav Hapla 7872306894acSVaclav Hapla Notes: 7873306894acSVaclav Hapla Only exactly the same instance is removed if found, name match is ignored. 7874306894acSVaclav Hapla If the DM has an exclusive reference to the label, it gets destroyed and 7875306894acSVaclav Hapla *label nullified. 7876306894acSVaclav Hapla 7877306894acSVaclav Hapla .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabel() DMGetLabelValue(), DMSetLabelValue(), DMLabelDestroy(), DMRemoveLabel() 7878306894acSVaclav Hapla @*/ 7879306894acSVaclav Hapla PetscErrorCode DMRemoveLabelBySelf(DM dm, DMLabel *label, PetscBool failNotFound) 7880306894acSVaclav Hapla { 788143e45a93SVaclav Hapla DMLabelLink link, *pnext; 7882306894acSVaclav Hapla PetscBool hasLabel = PETSC_FALSE; 7883306894acSVaclav Hapla PetscErrorCode ierr; 7884306894acSVaclav Hapla 7885306894acSVaclav Hapla PetscFunctionBegin; 7886306894acSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7887306894acSVaclav Hapla PetscValidPointer(label, 2); 7888f39a9ae0SVaclav Hapla if (!*label && !failNotFound) PetscFunctionReturn(0); 7889306894acSVaclav Hapla PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 2); 7890306894acSVaclav Hapla PetscValidLogicalCollectiveBool(dm,failNotFound,3); 78915d80c0bfSVaclav Hapla for (pnext=&dm->labels; (link=*pnext); pnext=&link->next) { 789243e45a93SVaclav Hapla if (*label == link->label) { 7893306894acSVaclav Hapla hasLabel = PETSC_TRUE; 789443e45a93SVaclav Hapla *pnext = link->next; /* Remove from list */ 7895306894acSVaclav Hapla if (*label == dm->depthLabel) dm->depthLabel = NULL; 7896ba2698f1SMatthew G. Knepley if (*label == dm->celltypeLabel) dm->celltypeLabel = NULL; 789743e45a93SVaclav Hapla if (((PetscObject) link->label)->refct < 2) *label = NULL; /* nullify if exclusive reference */ 789843e45a93SVaclav Hapla ierr = DMLabelDestroy(&link->label);CHKERRQ(ierr); 789943e45a93SVaclav Hapla ierr = PetscFree(link);CHKERRQ(ierr); 7900306894acSVaclav Hapla break; 7901306894acSVaclav Hapla } 7902306894acSVaclav Hapla } 7903306894acSVaclav Hapla if (!hasLabel && failNotFound) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Given label not found in DM"); 7904306894acSVaclav Hapla PetscFunctionReturn(0); 7905306894acSVaclav Hapla } 7906306894acSVaclav Hapla 7907c58f1c22SToby Isaac /*@C 7908c58f1c22SToby Isaac DMGetLabelOutput - Get the output flag for a given label 7909c58f1c22SToby Isaac 7910c58f1c22SToby Isaac Not Collective 7911c58f1c22SToby Isaac 7912c58f1c22SToby Isaac Input Parameters: 7913c58f1c22SToby Isaac + dm - The DM object 7914c58f1c22SToby Isaac - name - The label name 7915c58f1c22SToby Isaac 7916c58f1c22SToby Isaac Output Parameter: 7917c58f1c22SToby Isaac . output - The flag for output 7918c58f1c22SToby Isaac 7919c58f1c22SToby Isaac Level: developer 7920c58f1c22SToby Isaac 7921c58f1c22SToby Isaac .seealso: DMSetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7922c58f1c22SToby Isaac @*/ 7923c58f1c22SToby Isaac PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output) 7924c58f1c22SToby Isaac { 79255d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7926d67d17b1SMatthew G. Knepley const char *lname; 7927c58f1c22SToby Isaac PetscErrorCode ierr; 7928c58f1c22SToby Isaac 7929c58f1c22SToby Isaac PetscFunctionBegin; 7930c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7931c58f1c22SToby Isaac PetscValidPointer(name, 2); 7932c58f1c22SToby Isaac PetscValidPointer(output, 3); 7933c58f1c22SToby Isaac while (next) { 7934c58f1c22SToby Isaac PetscBool flg; 7935c58f1c22SToby Isaac 7936d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 7937d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr); 7938c58f1c22SToby Isaac if (flg) {*output = next->output; PetscFunctionReturn(0);} 7939c58f1c22SToby Isaac next = next->next; 7940c58f1c22SToby Isaac } 7941c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7942c58f1c22SToby Isaac } 7943c58f1c22SToby Isaac 7944c58f1c22SToby Isaac /*@C 7945c58f1c22SToby Isaac DMSetLabelOutput - Set the output flag for a given label 7946c58f1c22SToby Isaac 7947c58f1c22SToby Isaac Not Collective 7948c58f1c22SToby Isaac 7949c58f1c22SToby Isaac Input Parameters: 7950c58f1c22SToby Isaac + dm - The DM object 7951c58f1c22SToby Isaac . name - The label name 7952c58f1c22SToby Isaac - output - The flag for output 7953c58f1c22SToby Isaac 7954c58f1c22SToby Isaac Level: developer 7955c58f1c22SToby Isaac 7956c58f1c22SToby Isaac .seealso: DMGetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7957c58f1c22SToby Isaac @*/ 7958c58f1c22SToby Isaac PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output) 7959c58f1c22SToby Isaac { 79605d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7961d67d17b1SMatthew G. Knepley const char *lname; 7962c58f1c22SToby Isaac PetscErrorCode ierr; 7963c58f1c22SToby Isaac 7964c58f1c22SToby Isaac PetscFunctionBegin; 7965c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7966534a8f05SLisandro Dalcin PetscValidCharPointer(name, 2); 7967c58f1c22SToby Isaac while (next) { 7968c58f1c22SToby Isaac PetscBool flg; 7969c58f1c22SToby Isaac 7970d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 7971d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr); 7972c58f1c22SToby Isaac if (flg) {next->output = output; PetscFunctionReturn(0);} 7973c58f1c22SToby Isaac next = next->next; 7974c58f1c22SToby Isaac } 7975c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7976c58f1c22SToby Isaac } 7977c58f1c22SToby Isaac 7978c58f1c22SToby Isaac /*@ 7979c58f1c22SToby Isaac DMCopyLabels - Copy labels from one mesh to another with a superset of the points 7980c58f1c22SToby Isaac 7981d083f849SBarry Smith Collective on dmA 7982c58f1c22SToby Isaac 7983c58f1c22SToby Isaac Input Parameter: 79845d80c0bfSVaclav Hapla + dmA - The DM object with initial labels 79852e17dfb7SMatthew G. Knepley . dmB - The DM object with copied labels 79865d80c0bfSVaclav Hapla . mode - Copy labels by pointers (PETSC_OWN_POINTER) or duplicate them (PETSC_COPY_VALUES) 7987ba2698f1SMatthew G. Knepley - all - Copy all labels including "depth", "dim", and "celltype" (PETSC_TRUE) which are otherwise ignored (PETSC_FALSE) 7988c58f1c22SToby Isaac 7989c58f1c22SToby Isaac Level: intermediate 7990c58f1c22SToby Isaac 7991c58f1c22SToby Isaac Note: This is typically used when interpolating or otherwise adding to a mesh 7992c58f1c22SToby Isaac 79935d80c0bfSVaclav Hapla .seealso: DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMGetCoordinateSection(), DMShareLabels() 7994c58f1c22SToby Isaac @*/ 79955d80c0bfSVaclav Hapla PetscErrorCode DMCopyLabels(DM dmA, DM dmB, PetscCopyMode mode, PetscBool all) 7996c58f1c22SToby Isaac { 7997c58f1c22SToby Isaac DMLabel label, labelNew; 7998c58f1c22SToby Isaac const char *name; 7999c58f1c22SToby Isaac PetscBool flg; 80005d80c0bfSVaclav Hapla DMLabelLink link; 80015d80c0bfSVaclav Hapla PetscErrorCode ierr; 8002c58f1c22SToby Isaac 80035d80c0bfSVaclav Hapla PetscFunctionBegin; 80045d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 80055d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 80065d80c0bfSVaclav Hapla PetscValidLogicalCollectiveEnum(dmA, mode,3); 80075d80c0bfSVaclav Hapla PetscValidLogicalCollectiveBool(dmA, all, 4); 80085d80c0bfSVaclav Hapla if (mode==PETSC_USE_POINTER) SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_SUP, "PETSC_USE_POINTER not supported for objects"); 80095d80c0bfSVaclav Hapla if (dmA == dmB) PetscFunctionReturn(0); 80105d80c0bfSVaclav Hapla for (link=dmA->labels; link; link=link->next) { 80115d80c0bfSVaclav Hapla label=link->label; 80125d80c0bfSVaclav Hapla ierr = PetscObjectGetName((PetscObject)label, &name);CHKERRQ(ierr); 80135d80c0bfSVaclav Hapla if (!all) { 8014c58f1c22SToby Isaac ierr = PetscStrcmp(name, "depth", &flg);CHKERRQ(ierr); 8015c58f1c22SToby Isaac if (flg) continue; 80167d5acc75SStefano Zampini ierr = PetscStrcmp(name, "dim", &flg);CHKERRQ(ierr); 80177d5acc75SStefano Zampini if (flg) continue; 8018ba2698f1SMatthew G. Knepley ierr = PetscStrcmp(name, "celltype", &flg);CHKERRQ(ierr); 8019ba2698f1SMatthew G. Knepley if (flg) continue; 80205d80c0bfSVaclav Hapla } 80215d80c0bfSVaclav Hapla if (mode==PETSC_COPY_VALUES) { 8022c58f1c22SToby Isaac ierr = DMLabelDuplicate(label, &labelNew);CHKERRQ(ierr); 80235d80c0bfSVaclav Hapla } else { 80245d80c0bfSVaclav Hapla labelNew = label; 80255d80c0bfSVaclav Hapla } 8026c58f1c22SToby Isaac ierr = DMAddLabel(dmB, labelNew);CHKERRQ(ierr); 80275d80c0bfSVaclav Hapla if (mode==PETSC_COPY_VALUES) {ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr);} 8028c58f1c22SToby Isaac } 8029c58f1c22SToby Isaac PetscFunctionReturn(0); 8030c58f1c22SToby Isaac } 80310fdc7489SMatthew Knepley /* 80320fdc7489SMatthew Knepley Many mesh programs, such as Triangle and TetGen, allow only a single label for each mesh point. Therefore, we would 80330fdc7489SMatthew Knepley like to encode all label IDs using a single, universal label. We can do this by assigning an integer to every 80340fdc7489SMatthew Knepley (label, id) pair in the DM. 80350fdc7489SMatthew Knepley 80360fdc7489SMatthew Knepley However, a mesh point can have multiple labels, so we must separate all these values. We will assign a bit range to 80370fdc7489SMatthew Knepley each label. 80380fdc7489SMatthew Knepley */ 80390fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelCreate(DM dm, DMUniversalLabel *universal) 80400fdc7489SMatthew Knepley { 80410fdc7489SMatthew Knepley DMUniversalLabel ul; 80420fdc7489SMatthew Knepley PetscBool *active; 80430fdc7489SMatthew Knepley PetscInt pStart, pEnd, p, Nl, l, m; 80440fdc7489SMatthew Knepley PetscErrorCode ierr; 80450fdc7489SMatthew Knepley 80460fdc7489SMatthew Knepley PetscFunctionBegin; 80470fdc7489SMatthew Knepley ierr = PetscMalloc1(1, &ul);CHKERRQ(ierr); 80480fdc7489SMatthew Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, "universal", &ul->label);CHKERRQ(ierr); 80490fdc7489SMatthew Knepley ierr = DMGetNumLabels(dm, &Nl);CHKERRQ(ierr); 80500fdc7489SMatthew Knepley ierr = PetscCalloc1(Nl, &active);CHKERRQ(ierr); 80510fdc7489SMatthew Knepley ul->Nl = 0; 80520fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 80530fdc7489SMatthew Knepley PetscBool isdepth, iscelltype; 80540fdc7489SMatthew Knepley const char *name; 80550fdc7489SMatthew Knepley 80560fdc7489SMatthew Knepley ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 80570fdc7489SMatthew Knepley ierr = PetscStrncmp(name, "depth", 6, &isdepth);CHKERRQ(ierr); 80580fdc7489SMatthew Knepley ierr = PetscStrncmp(name, "celltype", 9, &iscelltype);CHKERRQ(ierr); 80590fdc7489SMatthew Knepley active[l] = !(isdepth || iscelltype) ? PETSC_TRUE : PETSC_FALSE; 80600fdc7489SMatthew Knepley if (active[l]) ++ul->Nl; 80610fdc7489SMatthew Knepley } 80620fdc7489SMatthew 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); 80630fdc7489SMatthew Knepley ul->Nv = 0; 80640fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 80650fdc7489SMatthew Knepley DMLabel label; 80660fdc7489SMatthew Knepley PetscInt nv; 80670fdc7489SMatthew Knepley const char *name; 80680fdc7489SMatthew Knepley 80690fdc7489SMatthew Knepley if (!active[l]) continue; 80700fdc7489SMatthew Knepley ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 80710fdc7489SMatthew Knepley ierr = DMGetLabelByNum(dm, l, &label);CHKERRQ(ierr); 80720fdc7489SMatthew Knepley ierr = DMLabelGetNumValues(label, &nv);CHKERRQ(ierr); 80730fdc7489SMatthew Knepley ierr = PetscStrallocpy(name, &ul->names[m]);CHKERRQ(ierr); 80740fdc7489SMatthew Knepley ul->indices[m] = l; 80750fdc7489SMatthew Knepley ul->Nv += nv; 80760fdc7489SMatthew Knepley ul->offsets[m+1] = nv; 80770fdc7489SMatthew Knepley ul->bits[m+1] = PetscCeilReal(PetscLog2Real(nv+1)); 80780fdc7489SMatthew Knepley ++m; 80790fdc7489SMatthew Knepley } 80800fdc7489SMatthew Knepley for (l = 1; l <= ul->Nl; ++l) { 80810fdc7489SMatthew Knepley ul->offsets[l] = ul->offsets[l-1] + ul->offsets[l]; 80820fdc7489SMatthew Knepley ul->bits[l] = ul->bits[l-1] + ul->bits[l]; 80830fdc7489SMatthew Knepley } 80840fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 80850fdc7489SMatthew Knepley PetscInt b; 80860fdc7489SMatthew Knepley 80870fdc7489SMatthew Knepley ul->masks[l] = 0; 80880fdc7489SMatthew Knepley for (b = ul->bits[l]; b < ul->bits[l+1]; ++b) ul->masks[l] |= 1 << b; 80890fdc7489SMatthew Knepley } 80900fdc7489SMatthew Knepley ierr = PetscMalloc1(ul->Nv, &ul->values);CHKERRQ(ierr); 80910fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 80920fdc7489SMatthew Knepley DMLabel label; 80930fdc7489SMatthew Knepley IS valueIS; 80940fdc7489SMatthew Knepley const PetscInt *varr; 80950fdc7489SMatthew Knepley PetscInt nv, v; 80960fdc7489SMatthew Knepley 80970fdc7489SMatthew Knepley if (!active[l]) continue; 80980fdc7489SMatthew Knepley ierr = DMGetLabelByNum(dm, l, &label);CHKERRQ(ierr); 80990fdc7489SMatthew Knepley ierr = DMLabelGetNumValues(label, &nv);CHKERRQ(ierr); 81000fdc7489SMatthew Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 81010fdc7489SMatthew Knepley ierr = ISGetIndices(valueIS, &varr);CHKERRQ(ierr); 81020fdc7489SMatthew Knepley for (v = 0; v < nv; ++v) { 81030fdc7489SMatthew Knepley ul->values[ul->offsets[m]+v] = varr[v]; 81040fdc7489SMatthew Knepley } 81050fdc7489SMatthew Knepley ierr = ISRestoreIndices(valueIS, &varr);CHKERRQ(ierr); 81060fdc7489SMatthew Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 81070fdc7489SMatthew Knepley ierr = PetscSortInt(nv, &ul->values[ul->offsets[m]]);CHKERRQ(ierr); 81080fdc7489SMatthew Knepley ++m; 81090fdc7489SMatthew Knepley } 81100fdc7489SMatthew Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 81110fdc7489SMatthew Knepley for (p = pStart; p < pEnd; ++p) { 81120fdc7489SMatthew Knepley PetscInt uval = 0; 81130fdc7489SMatthew Knepley PetscBool marked = PETSC_FALSE; 81140fdc7489SMatthew Knepley 81150fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 81160fdc7489SMatthew Knepley DMLabel label; 81170649b39aSStefano Zampini PetscInt val, defval, loc, nv; 81180fdc7489SMatthew Knepley 81190fdc7489SMatthew Knepley if (!active[l]) continue; 81200fdc7489SMatthew Knepley ierr = DMGetLabelByNum(dm, l, &label);CHKERRQ(ierr); 81210fdc7489SMatthew Knepley ierr = DMLabelGetValue(label, p, &val);CHKERRQ(ierr); 81220fdc7489SMatthew Knepley ierr = DMLabelGetDefaultValue(label, &defval);CHKERRQ(ierr); 81230fdc7489SMatthew Knepley if (val == defval) {++m; continue;} 81240649b39aSStefano Zampini nv = ul->offsets[m+1]-ul->offsets[m]; 81250fdc7489SMatthew Knepley marked = PETSC_TRUE; 81260fdc7489SMatthew Knepley ierr = PetscFindInt(val, nv, &ul->values[ul->offsets[m]], &loc);CHKERRQ(ierr); 81270fdc7489SMatthew Knepley if (loc < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Label value %D not found in compression array", val); 81280fdc7489SMatthew Knepley uval += (loc+1) << ul->bits[m]; 81290fdc7489SMatthew Knepley ++m; 81300fdc7489SMatthew Knepley } 81310fdc7489SMatthew Knepley if (marked) {ierr = DMLabelSetValue(ul->label, p, uval);CHKERRQ(ierr);} 81320fdc7489SMatthew Knepley } 81330fdc7489SMatthew Knepley ierr = PetscFree(active);CHKERRQ(ierr); 81340fdc7489SMatthew Knepley *universal = ul; 81350fdc7489SMatthew Knepley PetscFunctionReturn(0); 81360fdc7489SMatthew Knepley } 81370fdc7489SMatthew Knepley 81380fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelDestroy(DMUniversalLabel *universal) 81390fdc7489SMatthew Knepley { 81400fdc7489SMatthew Knepley PetscInt l; 81410fdc7489SMatthew Knepley PetscErrorCode ierr; 81420fdc7489SMatthew Knepley 81430fdc7489SMatthew Knepley PetscFunctionBegin; 81440fdc7489SMatthew Knepley for (l = 0; l < (*universal)->Nl; ++l) {ierr = PetscFree((*universal)->names[l]);CHKERRQ(ierr);} 81450fdc7489SMatthew Knepley ierr = DMLabelDestroy(&(*universal)->label);CHKERRQ(ierr); 81460fdc7489SMatthew Knepley ierr = PetscFree5((*universal)->names, (*universal)->indices, (*universal)->offsets, (*universal)->bits, (*universal)->masks);CHKERRQ(ierr); 81470fdc7489SMatthew Knepley ierr = PetscFree((*universal)->values);CHKERRQ(ierr); 81480fdc7489SMatthew Knepley ierr = PetscFree(*universal);CHKERRQ(ierr); 81490fdc7489SMatthew Knepley *universal = NULL; 81500fdc7489SMatthew Knepley PetscFunctionReturn(0); 81510fdc7489SMatthew Knepley } 81520fdc7489SMatthew Knepley 81530fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelGetLabel(DMUniversalLabel ul, DMLabel *ulabel) 81540fdc7489SMatthew Knepley { 81550fdc7489SMatthew Knepley PetscFunctionBegin; 81560fdc7489SMatthew Knepley PetscValidPointer(ulabel, 2); 81570fdc7489SMatthew Knepley *ulabel = ul->label; 81580fdc7489SMatthew Knepley PetscFunctionReturn(0); 81590fdc7489SMatthew Knepley } 81600fdc7489SMatthew Knepley 81610fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelCreateLabels(DMUniversalLabel ul, PetscBool preserveOrder, DM dm) 81620fdc7489SMatthew Knepley { 81630fdc7489SMatthew Knepley PetscInt Nl = ul->Nl, l; 81640fdc7489SMatthew Knepley PetscErrorCode ierr; 81650fdc7489SMatthew Knepley 81660fdc7489SMatthew Knepley PetscFunctionBegin; 81670fdc7489SMatthew Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 81680fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 81690fdc7489SMatthew Knepley if (preserveOrder) {ierr = DMCreateLabelAtIndex(dm, ul->indices[l], ul->names[l]);CHKERRQ(ierr);} 81700fdc7489SMatthew Knepley else {ierr = DMCreateLabel(dm, ul->names[l]);CHKERRQ(ierr);} 81710fdc7489SMatthew Knepley } 81720fdc7489SMatthew Knepley if (preserveOrder) { 81730fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 81740fdc7489SMatthew Knepley const char *name; 81750fdc7489SMatthew Knepley PetscBool match; 81760fdc7489SMatthew Knepley 81770fdc7489SMatthew Knepley ierr = DMGetLabelName(dm, ul->indices[l], &name);CHKERRQ(ierr); 81780fdc7489SMatthew Knepley ierr = PetscStrcmp(name, ul->names[l], &match);CHKERRQ(ierr); 81790fdc7489SMatthew 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]); 81800fdc7489SMatthew Knepley } 81810fdc7489SMatthew Knepley } 81820fdc7489SMatthew Knepley PetscFunctionReturn(0); 81830fdc7489SMatthew Knepley } 81840fdc7489SMatthew Knepley 81850fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelSetLabelValue(DMUniversalLabel ul, DM dm, PetscBool useIndex, PetscInt p, PetscInt value) 81860fdc7489SMatthew Knepley { 81870fdc7489SMatthew Knepley PetscInt l; 81880fdc7489SMatthew Knepley PetscErrorCode ierr; 81890fdc7489SMatthew Knepley 81900fdc7489SMatthew Knepley PetscFunctionBegin; 81910fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 81920fdc7489SMatthew Knepley DMLabel label; 81930fdc7489SMatthew Knepley PetscInt lval = (value & ul->masks[l]) >> ul->bits[l]; 81940fdc7489SMatthew Knepley 81950fdc7489SMatthew Knepley if (lval) { 81960fdc7489SMatthew Knepley if (useIndex) {ierr = DMGetLabelByNum(dm, ul->indices[l], &label);CHKERRQ(ierr);} 81970fdc7489SMatthew Knepley else {ierr = DMGetLabel(dm, ul->names[l], &label);CHKERRQ(ierr);} 81980fdc7489SMatthew Knepley ierr = DMLabelSetValue(label, p, ul->values[ul->offsets[l]+lval-1]);CHKERRQ(ierr); 81990fdc7489SMatthew Knepley } 82000fdc7489SMatthew Knepley } 82010fdc7489SMatthew Knepley PetscFunctionReturn(0); 82020fdc7489SMatthew Knepley } 8203a8fb8f29SToby Isaac 8204a8fb8f29SToby Isaac /*@ 8205a8fb8f29SToby Isaac DMGetCoarseDM - Get the coarse mesh from which this was obtained by refinement 8206a8fb8f29SToby Isaac 8207a8fb8f29SToby Isaac Input Parameter: 8208a8fb8f29SToby Isaac . dm - The DM object 8209a8fb8f29SToby Isaac 8210a8fb8f29SToby Isaac Output Parameter: 8211a8fb8f29SToby Isaac . cdm - The coarse DM 8212a8fb8f29SToby Isaac 8213a8fb8f29SToby Isaac Level: intermediate 8214a8fb8f29SToby Isaac 8215a8fb8f29SToby Isaac .seealso: DMSetCoarseDM() 8216a8fb8f29SToby Isaac @*/ 8217a8fb8f29SToby Isaac PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm) 8218a8fb8f29SToby Isaac { 8219a8fb8f29SToby Isaac PetscFunctionBegin; 8220a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8221a8fb8f29SToby Isaac PetscValidPointer(cdm, 2); 8222a8fb8f29SToby Isaac *cdm = dm->coarseMesh; 8223a8fb8f29SToby Isaac PetscFunctionReturn(0); 8224a8fb8f29SToby Isaac } 8225a8fb8f29SToby Isaac 8226a8fb8f29SToby Isaac /*@ 8227a8fb8f29SToby Isaac DMSetCoarseDM - Set the coarse mesh from which this was obtained by refinement 8228a8fb8f29SToby Isaac 8229a8fb8f29SToby Isaac Input Parameters: 8230a8fb8f29SToby Isaac + dm - The DM object 8231a8fb8f29SToby Isaac - cdm - The coarse DM 8232a8fb8f29SToby Isaac 8233a8fb8f29SToby Isaac Level: intermediate 8234a8fb8f29SToby Isaac 8235a8fb8f29SToby Isaac .seealso: DMGetCoarseDM() 8236a8fb8f29SToby Isaac @*/ 8237a8fb8f29SToby Isaac PetscErrorCode DMSetCoarseDM(DM dm, DM cdm) 8238a8fb8f29SToby Isaac { 8239a8fb8f29SToby Isaac PetscErrorCode ierr; 8240a8fb8f29SToby Isaac 8241a8fb8f29SToby Isaac PetscFunctionBegin; 8242a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8243a8fb8f29SToby Isaac if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 8244a8fb8f29SToby Isaac ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr); 8245a8fb8f29SToby Isaac ierr = DMDestroy(&dm->coarseMesh);CHKERRQ(ierr); 8246a8fb8f29SToby Isaac dm->coarseMesh = cdm; 8247a8fb8f29SToby Isaac PetscFunctionReturn(0); 8248a8fb8f29SToby Isaac } 8249a8fb8f29SToby Isaac 825088bdff64SToby Isaac /*@ 825188bdff64SToby Isaac DMGetFineDM - Get the fine mesh from which this was obtained by refinement 825288bdff64SToby Isaac 825388bdff64SToby Isaac Input Parameter: 825488bdff64SToby Isaac . dm - The DM object 825588bdff64SToby Isaac 825688bdff64SToby Isaac Output Parameter: 825788bdff64SToby Isaac . fdm - The fine DM 825888bdff64SToby Isaac 825988bdff64SToby Isaac Level: intermediate 826088bdff64SToby Isaac 826188bdff64SToby Isaac .seealso: DMSetFineDM() 826288bdff64SToby Isaac @*/ 826388bdff64SToby Isaac PetscErrorCode DMGetFineDM(DM dm, DM *fdm) 826488bdff64SToby Isaac { 826588bdff64SToby Isaac PetscFunctionBegin; 826688bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 826788bdff64SToby Isaac PetscValidPointer(fdm, 2); 826888bdff64SToby Isaac *fdm = dm->fineMesh; 826988bdff64SToby Isaac PetscFunctionReturn(0); 827088bdff64SToby Isaac } 827188bdff64SToby Isaac 827288bdff64SToby Isaac /*@ 827388bdff64SToby Isaac DMSetFineDM - Set the fine mesh from which this was obtained by refinement 827488bdff64SToby Isaac 827588bdff64SToby Isaac Input Parameters: 827688bdff64SToby Isaac + dm - The DM object 827788bdff64SToby Isaac - fdm - The fine DM 827888bdff64SToby Isaac 827988bdff64SToby Isaac Level: intermediate 828088bdff64SToby Isaac 828188bdff64SToby Isaac .seealso: DMGetFineDM() 828288bdff64SToby Isaac @*/ 828388bdff64SToby Isaac PetscErrorCode DMSetFineDM(DM dm, DM fdm) 828488bdff64SToby Isaac { 828588bdff64SToby Isaac PetscErrorCode ierr; 828688bdff64SToby Isaac 828788bdff64SToby Isaac PetscFunctionBegin; 828888bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 828988bdff64SToby Isaac if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2); 829088bdff64SToby Isaac ierr = PetscObjectReference((PetscObject)fdm);CHKERRQ(ierr); 829188bdff64SToby Isaac ierr = DMDestroy(&dm->fineMesh);CHKERRQ(ierr); 829288bdff64SToby Isaac dm->fineMesh = fdm; 829388bdff64SToby Isaac PetscFunctionReturn(0); 829488bdff64SToby Isaac } 829588bdff64SToby Isaac 8296a6ba4734SToby Isaac /*=== DMBoundary code ===*/ 8297a6ba4734SToby Isaac 8298a6ba4734SToby Isaac PetscErrorCode DMCopyBoundary(DM dm, DM dmNew) 8299a6ba4734SToby Isaac { 8300e5e52638SMatthew G. Knepley PetscInt d; 8301a6ba4734SToby Isaac PetscErrorCode ierr; 8302a6ba4734SToby Isaac 8303a6ba4734SToby Isaac PetscFunctionBegin; 8304e5e52638SMatthew G. Knepley for (d = 0; d < dm->Nds; ++d) { 830536951cb5SMatthew G. Knepley ierr = PetscDSCopyBoundary(dm->probs[d].ds, PETSC_DETERMINE, NULL, dmNew->probs[d].ds);CHKERRQ(ierr); 8306e5e52638SMatthew G. Knepley } 8307a6ba4734SToby Isaac PetscFunctionReturn(0); 8308a6ba4734SToby Isaac } 8309a6ba4734SToby Isaac 8310a6ba4734SToby Isaac /*@C 8311a6ba4734SToby Isaac DMAddBoundary - Add a boundary condition to the model 8312a6ba4734SToby Isaac 8313783e2ec8SMatthew G. Knepley Collective on dm 8314783e2ec8SMatthew G. Knepley 8315a6ba4734SToby Isaac Input Parameters: 83164c258f51SMatthew G. Knepley + dm - The DM, with a PetscDS that matches the problem being constrained 8317f971fd6bSMatthew G. Knepley . type - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann) 8318a6ba4734SToby Isaac . name - The BC name 8319a6ba4734SToby Isaac . labelname - The label defining constrained points 8320a6ba4734SToby Isaac . field - The field to constrain 8321e8ecbf3fSStefano Zampini . numcomps - The number of constrained field components (0 will constrain all fields) 8322a6ba4734SToby Isaac . comps - An array of constrained component numbers 8323a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 832456cf3b9cSMatthew G. Knepley . bcFunc_t - A pointwise function giving the time deriative of the boundary values, or NULL 8325a6ba4734SToby Isaac . numids - The number of DMLabel ids for constrained points 8326a6ba4734SToby Isaac . ids - An array of ids for constrained points 8327a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 8328a6ba4734SToby Isaac 8329a6ba4734SToby Isaac Options Database Keys: 8330a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 8331a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 8332a6ba4734SToby Isaac 833356cf3b9cSMatthew G. Knepley Note: 833456cf3b9cSMatthew 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: 833556cf3b9cSMatthew G. Knepley 833656cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[]) 833756cf3b9cSMatthew G. Knepley 833856cf3b9cSMatthew G. Knepley If the type is DM_BC_ESSENTIAL_FIELD or other _FIELD value, then the calling sequence is: 833956cf3b9cSMatthew G. Knepley 834056cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux, 834156cf3b9cSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 834256cf3b9cSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 834356cf3b9cSMatthew G. Knepley $ PetscReal time, const PetscReal x[], PetscScalar bcval[]) 834456cf3b9cSMatthew G. Knepley 834556cf3b9cSMatthew G. Knepley + dim - the spatial dimension 834656cf3b9cSMatthew G. Knepley . Nf - the number of fields 834756cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field 834856cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field 834956cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point 835056cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point 835156cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point 835256cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field 835356cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field 835456cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point 835556cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point 835656cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point 835756cf3b9cSMatthew G. Knepley . t - current time 835856cf3b9cSMatthew G. Knepley . x - coordinates of the current point 835956cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters 836056cf3b9cSMatthew G. Knepley . constants - constant parameters 836156cf3b9cSMatthew G. Knepley - bcval - output values at the current point 836256cf3b9cSMatthew G. Knepley 8363a6ba4734SToby Isaac Level: developer 8364a6ba4734SToby Isaac 836556cf3b9cSMatthew G. Knepley .seealso: DMGetBoundary(), PetscDSAddBoundary() 8366a6ba4734SToby Isaac @*/ 836756cf3b9cSMatthew 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) 8368a6ba4734SToby Isaac { 8369e5e52638SMatthew G. Knepley PetscDS ds; 8370a6ba4734SToby Isaac PetscErrorCode ierr; 8371a6ba4734SToby Isaac 8372a6ba4734SToby Isaac PetscFunctionBegin; 8373a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8374783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveEnum(dm, type, 2); 8375783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, field, 5); 8376783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, numcomps, 6); 8377783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, numids, 9); 8378e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 8379783e2ec8SMatthew G. Knepley ierr = DMCompleteBoundaryLabel_Internal(dm, ds, field, PETSC_MAX_INT, labelname);CHKERRQ(ierr); 838056cf3b9cSMatthew G. Knepley ierr = PetscDSAddBoundary(ds, type,name, labelname, field, numcomps, comps, bcFunc, bcFunc_t, numids, ids, ctx);CHKERRQ(ierr); 8381a6ba4734SToby Isaac PetscFunctionReturn(0); 8382a6ba4734SToby Isaac } 8383a6ba4734SToby Isaac 8384a6ba4734SToby Isaac /*@ 8385a6ba4734SToby Isaac DMGetNumBoundary - Get the number of registered BC 8386a6ba4734SToby Isaac 8387a6ba4734SToby Isaac Input Parameters: 8388a6ba4734SToby Isaac . dm - The mesh object 8389a6ba4734SToby Isaac 8390a6ba4734SToby Isaac Output Parameters: 8391a6ba4734SToby Isaac . numBd - The number of BC 8392a6ba4734SToby Isaac 8393a6ba4734SToby Isaac Level: intermediate 8394a6ba4734SToby Isaac 8395a6ba4734SToby Isaac .seealso: DMAddBoundary(), DMGetBoundary() 8396a6ba4734SToby Isaac @*/ 8397a6ba4734SToby Isaac PetscErrorCode DMGetNumBoundary(DM dm, PetscInt *numBd) 8398a6ba4734SToby Isaac { 8399e5e52638SMatthew G. Knepley PetscDS ds; 840058ebd649SToby Isaac PetscErrorCode ierr; 8401a6ba4734SToby Isaac 8402a6ba4734SToby Isaac PetscFunctionBegin; 8403a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8404e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 8405e5e52638SMatthew G. Knepley ierr = PetscDSGetNumBoundary(ds, numBd);CHKERRQ(ierr); 8406a6ba4734SToby Isaac PetscFunctionReturn(0); 8407a6ba4734SToby Isaac } 8408a6ba4734SToby Isaac 8409a6ba4734SToby Isaac /*@C 84101c531cf8SMatthew G. Knepley DMGetBoundary - Get a model boundary condition 8411a6ba4734SToby Isaac 8412a6ba4734SToby Isaac Input Parameters: 8413a6ba4734SToby Isaac + dm - The mesh object 8414a6ba4734SToby Isaac - bd - The BC number 8415a6ba4734SToby Isaac 8416a6ba4734SToby Isaac Output Parameters: 8417f971fd6bSMatthew G. Knepley + type - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann) 8418a6ba4734SToby Isaac . name - The BC name 8419a6ba4734SToby Isaac . labelname - The label defining constrained points 8420a6ba4734SToby Isaac . field - The field to constrain 8421a6ba4734SToby Isaac . numcomps - The number of constrained field components 8422a6ba4734SToby Isaac . comps - An array of constrained component numbers 8423a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 842456cf3b9cSMatthew G. Knepley . bcFunc_t - A pointwise function giving the time derviative of the boundary values 8425a6ba4734SToby Isaac . numids - The number of DMLabel ids for constrained points 8426a6ba4734SToby Isaac . ids - An array of ids for constrained points 8427a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 8428a6ba4734SToby Isaac 8429a6ba4734SToby Isaac Options Database Keys: 8430a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 8431a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 8432a6ba4734SToby Isaac 8433a6ba4734SToby Isaac Level: developer 8434a6ba4734SToby Isaac 8435a6ba4734SToby Isaac .seealso: DMAddBoundary() 8436a6ba4734SToby Isaac @*/ 843756cf3b9cSMatthew 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) 8438a6ba4734SToby Isaac { 8439e5e52638SMatthew G. Knepley PetscDS ds; 844058ebd649SToby Isaac PetscErrorCode ierr; 8441a6ba4734SToby Isaac 8442a6ba4734SToby Isaac PetscFunctionBegin; 8443a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8444e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 844556cf3b9cSMatthew G. Knepley ierr = PetscDSGetBoundary(ds, bd, type, name, labelname, field, numcomps, comps, func, func_t, numids, ids, ctx);CHKERRQ(ierr); 8446a6ba4734SToby Isaac PetscFunctionReturn(0); 8447a6ba4734SToby Isaac } 8448a6ba4734SToby Isaac 8449e6f8dbb6SToby Isaac static PetscErrorCode DMPopulateBoundary(DM dm) 8450e6f8dbb6SToby Isaac { 8451e5e52638SMatthew G. Knepley PetscDS ds; 8452dff059c6SToby Isaac DMBoundary *lastnext; 8453e6f8dbb6SToby Isaac DSBoundary dsbound; 8454e6f8dbb6SToby Isaac PetscErrorCode ierr; 8455e6f8dbb6SToby Isaac 8456e6f8dbb6SToby Isaac PetscFunctionBegin; 8457e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 8458e5e52638SMatthew G. Knepley dsbound = ds->boundary; 845947a1f5adSToby Isaac if (dm->boundary) { 846047a1f5adSToby Isaac DMBoundary next = dm->boundary; 846147a1f5adSToby Isaac 846247a1f5adSToby Isaac /* quick check to see if the PetscDS has changed */ 846347a1f5adSToby Isaac if (next->dsboundary == dsbound) PetscFunctionReturn(0); 846447a1f5adSToby Isaac /* the PetscDS has changed: tear down and rebuild */ 846547a1f5adSToby Isaac while (next) { 846647a1f5adSToby Isaac DMBoundary b = next; 846747a1f5adSToby Isaac 846847a1f5adSToby Isaac next = b->next; 846947a1f5adSToby Isaac ierr = PetscFree(b);CHKERRQ(ierr); 8470a6ba4734SToby Isaac } 847147a1f5adSToby Isaac dm->boundary = NULL; 8472a6ba4734SToby Isaac } 847347a1f5adSToby Isaac 8474dff059c6SToby Isaac lastnext = &(dm->boundary); 8475e6f8dbb6SToby Isaac while (dsbound) { 8476e6f8dbb6SToby Isaac DMBoundary dmbound; 8477e6f8dbb6SToby Isaac 8478e6f8dbb6SToby Isaac ierr = PetscNew(&dmbound);CHKERRQ(ierr); 8479e6f8dbb6SToby Isaac dmbound->dsboundary = dsbound; 8480e6f8dbb6SToby Isaac ierr = DMGetLabel(dm, dsbound->labelname, &(dmbound->label));CHKERRQ(ierr); 8481994fe344SLisandro 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);} 848247a1f5adSToby Isaac /* push on the back instead of the front so that it is in the same order as in the PetscDS */ 8483dff059c6SToby Isaac *lastnext = dmbound; 8484dff059c6SToby Isaac lastnext = &(dmbound->next); 8485dff059c6SToby Isaac dsbound = dsbound->next; 8486a6ba4734SToby Isaac } 8487a6ba4734SToby Isaac PetscFunctionReturn(0); 8488a6ba4734SToby Isaac } 8489a6ba4734SToby Isaac 8490a6ba4734SToby Isaac PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd) 8491a6ba4734SToby Isaac { 8492b95f2879SToby Isaac DMBoundary b; 8493a6ba4734SToby Isaac PetscErrorCode ierr; 8494a6ba4734SToby Isaac 8495a6ba4734SToby Isaac PetscFunctionBegin; 8496a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8497534a8f05SLisandro Dalcin PetscValidBoolPointer(isBd, 3); 8498a6ba4734SToby Isaac *isBd = PETSC_FALSE; 8499e6f8dbb6SToby Isaac ierr = DMPopulateBoundary(dm);CHKERRQ(ierr); 8500b95f2879SToby Isaac b = dm->boundary; 8501a6ba4734SToby Isaac while (b && !(*isBd)) { 8502e6f8dbb6SToby Isaac DMLabel label = b->label; 8503e6f8dbb6SToby Isaac DSBoundary dsb = b->dsboundary; 85043424c85cSToby Isaac 85053424c85cSToby Isaac if (label) { 8506a6ba4734SToby Isaac PetscInt i; 8507a6ba4734SToby Isaac 8508e6f8dbb6SToby Isaac for (i = 0; i < dsb->numids && !(*isBd); ++i) { 8509e6f8dbb6SToby Isaac ierr = DMLabelStratumHasPoint(label, dsb->ids[i], point, isBd);CHKERRQ(ierr); 8510a6ba4734SToby Isaac } 8511a6ba4734SToby Isaac } 8512a6ba4734SToby Isaac b = b->next; 8513a6ba4734SToby Isaac } 8514a6ba4734SToby Isaac PetscFunctionReturn(0); 8515a6ba4734SToby Isaac } 85164d6f44ffSToby Isaac 85174d6f44ffSToby Isaac /*@C 8518a6e0b375SMatthew G. Knepley DMProjectFunction - This projects the given function into the function space provided, putting the coefficients in a global vector. 8519a6e0b375SMatthew G. Knepley 8520a6e0b375SMatthew G. Knepley Collective on DM 85214d6f44ffSToby Isaac 85224d6f44ffSToby Isaac Input Parameters: 85234d6f44ffSToby Isaac + dm - The DM 85240709b2feSToby Isaac . time - The time 85254d6f44ffSToby Isaac . funcs - The coordinate functions to evaluate, one per field 85264d6f44ffSToby Isaac . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 85274d6f44ffSToby Isaac - mode - The insertion mode for values 85284d6f44ffSToby Isaac 85294d6f44ffSToby Isaac Output Parameter: 85304d6f44ffSToby Isaac . X - vector 85314d6f44ffSToby Isaac 85324d6f44ffSToby Isaac Calling sequence of func: 85330709b2feSToby Isaac $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 85344d6f44ffSToby Isaac 85354d6f44ffSToby Isaac + dim - The spatial dimension 85368ec8862eSJed Brown . time - The time at which to sample 85374d6f44ffSToby Isaac . x - The coordinates 85384d6f44ffSToby Isaac . Nf - The number of fields 85394d6f44ffSToby Isaac . u - The output field values 85404d6f44ffSToby Isaac - ctx - optional user-defined function context 85414d6f44ffSToby Isaac 85424d6f44ffSToby Isaac Level: developer 85434d6f44ffSToby Isaac 8544a6e0b375SMatthew G. Knepley .seealso: DMProjectFunctionLocal(), DMProjectFunctionLabel(), DMComputeL2Diff() 85454d6f44ffSToby Isaac @*/ 85460709b2feSToby Isaac PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X) 85474d6f44ffSToby Isaac { 85484d6f44ffSToby Isaac Vec localX; 85494d6f44ffSToby Isaac PetscErrorCode ierr; 85504d6f44ffSToby Isaac 85514d6f44ffSToby Isaac PetscFunctionBegin; 85524d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 85534d6f44ffSToby Isaac ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr); 85540709b2feSToby Isaac ierr = DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr); 85554d6f44ffSToby Isaac ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr); 85564d6f44ffSToby Isaac ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr); 85574d6f44ffSToby Isaac ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr); 85584d6f44ffSToby Isaac PetscFunctionReturn(0); 85594d6f44ffSToby Isaac } 85604d6f44ffSToby Isaac 8561a6e0b375SMatthew G. Knepley /*@C 8562a6e0b375SMatthew G. Knepley DMProjectFunctionLocal - This projects the given function into the function space provided, putting the coefficients in a local vector. 8563a6e0b375SMatthew G. Knepley 8564a6e0b375SMatthew G. Knepley Not collective 8565a6e0b375SMatthew G. Knepley 8566a6e0b375SMatthew G. Knepley Input Parameters: 8567a6e0b375SMatthew G. Knepley + dm - The DM 8568a6e0b375SMatthew G. Knepley . time - The time 8569a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8570a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8571a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8572a6e0b375SMatthew G. Knepley 8573a6e0b375SMatthew G. Knepley Output Parameter: 8574a6e0b375SMatthew G. Knepley . localX - vector 8575a6e0b375SMatthew G. Knepley 8576a6e0b375SMatthew G. Knepley Calling sequence of func: 8577a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 8578a6e0b375SMatthew G. Knepley 8579a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8580a6e0b375SMatthew G. Knepley . x - The coordinates 8581a6e0b375SMatthew G. Knepley . Nf - The number of fields 8582a6e0b375SMatthew G. Knepley . u - The output field values 8583a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8584a6e0b375SMatthew G. Knepley 8585a6e0b375SMatthew G. Knepley Level: developer 8586a6e0b375SMatthew G. Knepley 8587a6e0b375SMatthew G. Knepley .seealso: DMProjectFunction(), DMProjectFunctionLabel(), DMComputeL2Diff() 8588a6e0b375SMatthew G. Knepley @*/ 85890709b2feSToby Isaac PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 85904d6f44ffSToby Isaac { 85914d6f44ffSToby Isaac PetscErrorCode ierr; 85924d6f44ffSToby Isaac 85934d6f44ffSToby Isaac PetscFunctionBegin; 85944d6f44ffSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 85954d6f44ffSToby Isaac PetscValidHeaderSpecific(localX,VEC_CLASSID,5); 85960918c465SMatthew G. Knepley if (!dm->ops->projectfunctionlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLocal",((PetscObject)dm)->type_name); 85970709b2feSToby Isaac ierr = (dm->ops->projectfunctionlocal) (dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr); 85984d6f44ffSToby Isaac PetscFunctionReturn(0); 85994d6f44ffSToby Isaac } 86004d6f44ffSToby Isaac 8601a6e0b375SMatthew G. Knepley /*@C 8602a6e0b375SMatthew 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. 8603a6e0b375SMatthew G. Knepley 8604a6e0b375SMatthew G. Knepley Collective on DM 8605a6e0b375SMatthew G. Knepley 8606a6e0b375SMatthew G. Knepley Input Parameters: 8607a6e0b375SMatthew G. Knepley + dm - The DM 8608a6e0b375SMatthew G. Knepley . time - The time 8609a6e0b375SMatthew G. Knepley . label - The DMLabel selecting the portion of the mesh for projection 8610a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8611a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8612a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8613a6e0b375SMatthew G. Knepley 8614a6e0b375SMatthew G. Knepley Output Parameter: 8615a6e0b375SMatthew G. Knepley . X - vector 8616a6e0b375SMatthew G. Knepley 8617a6e0b375SMatthew G. Knepley Calling sequence of func: 8618a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 8619a6e0b375SMatthew G. Knepley 8620a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8621a6e0b375SMatthew G. Knepley . x - The coordinates 8622a6e0b375SMatthew G. Knepley . Nf - The number of fields 8623a6e0b375SMatthew G. Knepley . u - The output field values 8624a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8625a6e0b375SMatthew G. Knepley 8626a6e0b375SMatthew G. Knepley Level: developer 8627a6e0b375SMatthew G. Knepley 8628a6e0b375SMatthew G. Knepley .seealso: DMProjectFunction(), DMProjectFunctionLocal(), DMProjectFunctionLabelLocal(), DMComputeL2Diff() 8629a6e0b375SMatthew G. Knepley @*/ 86302c53366bSMatthew 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) 86312c53366bSMatthew G. Knepley { 86322c53366bSMatthew G. Knepley Vec localX; 86332c53366bSMatthew G. Knepley PetscErrorCode ierr; 86342c53366bSMatthew G. Knepley 86352c53366bSMatthew G. Knepley PetscFunctionBegin; 86362c53366bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 86372c53366bSMatthew G. Knepley ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr); 86382c53366bSMatthew G. Knepley ierr = DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr); 86392c53366bSMatthew G. Knepley ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr); 86402c53366bSMatthew G. Knepley ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr); 86412c53366bSMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr); 86422c53366bSMatthew G. Knepley PetscFunctionReturn(0); 86432c53366bSMatthew G. Knepley } 86442c53366bSMatthew G. Knepley 8645a6e0b375SMatthew G. Knepley /*@C 8646a6e0b375SMatthew 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. 8647a6e0b375SMatthew G. Knepley 8648a6e0b375SMatthew G. Knepley Not collective 8649a6e0b375SMatthew G. Knepley 8650a6e0b375SMatthew G. Knepley Input Parameters: 8651a6e0b375SMatthew G. Knepley + dm - The DM 8652a6e0b375SMatthew G. Knepley . time - The time 8653a6e0b375SMatthew G. Knepley . label - The DMLabel selecting the portion of the mesh for projection 8654a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8655a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8656a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8657a6e0b375SMatthew G. Knepley 8658a6e0b375SMatthew G. Knepley Output Parameter: 8659a6e0b375SMatthew G. Knepley . localX - vector 8660a6e0b375SMatthew G. Knepley 8661a6e0b375SMatthew G. Knepley Calling sequence of func: 8662a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 8663a6e0b375SMatthew G. Knepley 8664a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8665a6e0b375SMatthew G. Knepley . x - The coordinates 8666a6e0b375SMatthew G. Knepley . Nf - The number of fields 8667a6e0b375SMatthew G. Knepley . u - The output field values 8668a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8669a6e0b375SMatthew G. Knepley 8670a6e0b375SMatthew G. Knepley Level: developer 8671a6e0b375SMatthew G. Knepley 8672a6e0b375SMatthew G. Knepley .seealso: DMProjectFunction(), DMProjectFunctionLocal(), DMProjectFunctionLabel(), DMComputeL2Diff() 8673a6e0b375SMatthew G. Knepley @*/ 86741c531cf8SMatthew 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) 86754d6f44ffSToby Isaac { 86764d6f44ffSToby Isaac PetscErrorCode ierr; 86774d6f44ffSToby Isaac 86784d6f44ffSToby Isaac PetscFunctionBegin; 86794d6f44ffSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 86804d6f44ffSToby Isaac PetscValidHeaderSpecific(localX,VEC_CLASSID,5); 86810918c465SMatthew G. Knepley if (!dm->ops->projectfunctionlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLabelLocal",((PetscObject)dm)->type_name); 86821c531cf8SMatthew G. Knepley ierr = (dm->ops->projectfunctionlabellocal) (dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr); 86834d6f44ffSToby Isaac PetscFunctionReturn(0); 86844d6f44ffSToby Isaac } 86852716604bSToby Isaac 8686a6e0b375SMatthew G. Knepley /*@C 8687a6e0b375SMatthew G. Knepley DMProjectFieldLocal - This projects the given function of the input fields into the function space provided, putting the coefficients in a local vector. 8688a6e0b375SMatthew G. Knepley 8689a6e0b375SMatthew G. Knepley Not collective 8690a6e0b375SMatthew G. Knepley 8691a6e0b375SMatthew G. Knepley Input Parameters: 8692a6e0b375SMatthew G. Knepley + dm - The DM 8693a6e0b375SMatthew G. Knepley . time - The time 8694a6e0b375SMatthew G. Knepley . localU - The input field vector 8695a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8696a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8697a6e0b375SMatthew G. Knepley 8698a6e0b375SMatthew G. Knepley Output Parameter: 8699a6e0b375SMatthew G. Knepley . localX - The output vector 8700a6e0b375SMatthew G. Knepley 8701a6e0b375SMatthew G. Knepley Calling sequence of func: 8702a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8703a6e0b375SMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8704a6e0b375SMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8705a6e0b375SMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8706a6e0b375SMatthew G. Knepley 8707a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8708a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8709a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8710a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8711a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8712a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8713a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8714a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8715a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8716a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8717a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8718a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8719a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8720a6e0b375SMatthew G. Knepley . t - The current time 8721a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8722a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8723a6e0b375SMatthew G. Knepley . constants - The value of each constant 8724a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8725a6e0b375SMatthew G. Knepley 8726a6e0b375SMatthew 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. 8727a6e0b375SMatthew 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 8728a6e0b375SMatthew 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 8729a6e0b375SMatthew 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. 8730a6e0b375SMatthew G. Knepley 8731a6e0b375SMatthew G. Knepley Level: intermediate 8732a6e0b375SMatthew G. Knepley 8733a6e0b375SMatthew G. Knepley .seealso: DMProjectField(), DMProjectFieldLabelLocal(), DMProjectFunction(), DMComputeL2Diff() 8734a6e0b375SMatthew G. Knepley @*/ 87358c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal(DM dm, PetscReal time, Vec localU, 87368c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 87378c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 87388c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8739191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 87408c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 87418c6c5593SMatthew G. Knepley { 87428c6c5593SMatthew G. Knepley PetscErrorCode ierr; 87438c6c5593SMatthew G. Knepley 87448c6c5593SMatthew G. Knepley PetscFunctionBegin; 87458c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 87468c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,3); 87478c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,6); 87480918c465SMatthew G. Knepley if (!dm->ops->projectfieldlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name); 87498c6c5593SMatthew G. Knepley ierr = (dm->ops->projectfieldlocal) (dm, time, localU, funcs, mode, localX);CHKERRQ(ierr); 87508c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 87518c6c5593SMatthew G. Knepley } 87528c6c5593SMatthew G. Knepley 8753a6e0b375SMatthew G. Knepley /*@C 8754a6e0b375SMatthew 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. 8755a6e0b375SMatthew G. Knepley 8756a6e0b375SMatthew G. Knepley Not collective 8757a6e0b375SMatthew G. Knepley 8758a6e0b375SMatthew G. Knepley Input Parameters: 8759a6e0b375SMatthew G. Knepley + dm - The DM 8760a6e0b375SMatthew G. Knepley . time - The time 8761a6e0b375SMatthew G. Knepley . label - The DMLabel marking the portion of the domain to output 8762a6e0b375SMatthew G. Knepley . numIds - The number of label ids to use 8763a6e0b375SMatthew G. Knepley . ids - The label ids to use for marking 8764a6e0b375SMatthew G. Knepley . Nc - The number of components to set in the output, or PETSC_DETERMINE for all components 8765a6e0b375SMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8766a6e0b375SMatthew G. Knepley . localU - The input field vector 8767a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8768a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8769a6e0b375SMatthew G. Knepley 8770a6e0b375SMatthew G. Knepley Output Parameter: 8771a6e0b375SMatthew G. Knepley . localX - The output vector 8772a6e0b375SMatthew G. Knepley 8773a6e0b375SMatthew G. Knepley Calling sequence of func: 8774a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8775a6e0b375SMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8776a6e0b375SMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8777a6e0b375SMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8778a6e0b375SMatthew G. Knepley 8779a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8780a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8781a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8782a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8783a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8784a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8785a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8786a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8787a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8788a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8789a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8790a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8791a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8792a6e0b375SMatthew G. Knepley . t - The current time 8793a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8794a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8795a6e0b375SMatthew G. Knepley . constants - The value of each constant 8796a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8797a6e0b375SMatthew G. Knepley 8798a6e0b375SMatthew 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. 8799a6e0b375SMatthew 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 8800a6e0b375SMatthew 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 8801a6e0b375SMatthew 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. 8802a6e0b375SMatthew G. Knepley 8803a6e0b375SMatthew G. Knepley Level: intermediate 8804a6e0b375SMatthew G. Knepley 8805a6e0b375SMatthew G. Knepley .seealso: DMProjectField(), DMProjectFieldLabelLocal(), DMProjectFunction(), DMComputeL2Diff() 8806a6e0b375SMatthew G. Knepley @*/ 88071c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, 88088c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 88098c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 88108c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8811191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 88128c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 88138c6c5593SMatthew G. Knepley { 88148c6c5593SMatthew G. Knepley PetscErrorCode ierr; 88158c6c5593SMatthew G. Knepley 88168c6c5593SMatthew G. Knepley PetscFunctionBegin; 88178c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 88188c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,6); 88198c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,9); 8820ece3a9fcSMatthew G. Knepley if (!dm->ops->projectfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLabelLocal",((PetscObject)dm)->type_name); 88211c531cf8SMatthew G. Knepley ierr = (dm->ops->projectfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX);CHKERRQ(ierr); 88228c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 88238c6c5593SMatthew G. Knepley } 88248c6c5593SMatthew G. Knepley 88252716604bSToby Isaac /*@C 8826ece3a9fcSMatthew 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. 8827ece3a9fcSMatthew G. Knepley 8828ece3a9fcSMatthew G. Knepley Not collective 8829ece3a9fcSMatthew G. Knepley 8830ece3a9fcSMatthew G. Knepley Input Parameters: 8831ece3a9fcSMatthew G. Knepley + dm - The DM 8832ece3a9fcSMatthew G. Knepley . time - The time 8833ece3a9fcSMatthew G. Knepley . label - The DMLabel marking the portion of the domain boundary to output 8834ece3a9fcSMatthew G. Knepley . numIds - The number of label ids to use 8835ece3a9fcSMatthew G. Knepley . ids - The label ids to use for marking 8836ece3a9fcSMatthew G. Knepley . Nc - The number of components to set in the output, or PETSC_DETERMINE for all components 8837ece3a9fcSMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8838ece3a9fcSMatthew G. Knepley . localU - The input field vector 8839ece3a9fcSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8840ece3a9fcSMatthew G. Knepley - mode - The insertion mode for values 8841ece3a9fcSMatthew G. Knepley 8842ece3a9fcSMatthew G. Knepley Output Parameter: 8843ece3a9fcSMatthew G. Knepley . localX - The output vector 8844ece3a9fcSMatthew G. Knepley 8845ece3a9fcSMatthew G. Knepley Calling sequence of func: 8846ece3a9fcSMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8847ece3a9fcSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8848ece3a9fcSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8849ece3a9fcSMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8850ece3a9fcSMatthew G. Knepley 8851ece3a9fcSMatthew G. Knepley + dim - The spatial dimension 8852ece3a9fcSMatthew G. Knepley . Nf - The number of input fields 8853ece3a9fcSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8854ece3a9fcSMatthew G. Knepley . uOff - The offset of each field in u[] 8855ece3a9fcSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8856ece3a9fcSMatthew G. Knepley . u - The field values at this point in space 8857ece3a9fcSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8858ece3a9fcSMatthew G. Knepley . u_x - The field derivatives at this point in space 8859ece3a9fcSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8860ece3a9fcSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8861ece3a9fcSMatthew G. Knepley . a - The auxiliary field values at this point in space 8862ece3a9fcSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8863ece3a9fcSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8864ece3a9fcSMatthew G. Knepley . t - The current time 8865ece3a9fcSMatthew G. Knepley . x - The coordinates of this point 8866ece3a9fcSMatthew G. Knepley . n - The face normal 8867ece3a9fcSMatthew G. Knepley . numConstants - The number of constants 8868ece3a9fcSMatthew G. Knepley . constants - The value of each constant 8869ece3a9fcSMatthew G. Knepley - f - The value of the function at this point in space 8870ece3a9fcSMatthew G. Knepley 8871ece3a9fcSMatthew G. Knepley Note: 8872ece3a9fcSMatthew 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. 8873ece3a9fcSMatthew 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 8874ece3a9fcSMatthew 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 8875ece3a9fcSMatthew 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. 8876ece3a9fcSMatthew G. Knepley 8877ece3a9fcSMatthew G. Knepley Level: intermediate 8878ece3a9fcSMatthew G. Knepley 8879ece3a9fcSMatthew G. Knepley .seealso: DMProjectField(), DMProjectFieldLabelLocal(), DMProjectFunction(), DMComputeL2Diff() 8880ece3a9fcSMatthew G. Knepley @*/ 8881ece3a9fcSMatthew G. Knepley PetscErrorCode DMProjectBdFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, 8882ece3a9fcSMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 8883ece3a9fcSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8884ece3a9fcSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8885ece3a9fcSMatthew G. Knepley PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 8886ece3a9fcSMatthew G. Knepley InsertMode mode, Vec localX) 8887ece3a9fcSMatthew G. Knepley { 8888ece3a9fcSMatthew G. Knepley PetscErrorCode ierr; 8889ece3a9fcSMatthew G. Knepley 8890ece3a9fcSMatthew G. Knepley PetscFunctionBegin; 8891ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8892ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,6); 8893ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,9); 8894ece3a9fcSMatthew G. Knepley if (!dm->ops->projectbdfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectBdFieldLabelLocal",((PetscObject)dm)->type_name); 8895ece3a9fcSMatthew G. Knepley ierr = (dm->ops->projectbdfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX);CHKERRQ(ierr); 8896ece3a9fcSMatthew G. Knepley PetscFunctionReturn(0); 8897ece3a9fcSMatthew G. Knepley } 8898ece3a9fcSMatthew G. Knepley 8899ece3a9fcSMatthew G. Knepley /*@C 89002716604bSToby Isaac DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h. 89012716604bSToby Isaac 89022716604bSToby Isaac Input Parameters: 89032716604bSToby Isaac + dm - The DM 89040709b2feSToby Isaac . time - The time 89052716604bSToby Isaac . funcs - The functions to evaluate for each field component 89062716604bSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8907574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 89082716604bSToby Isaac 89092716604bSToby Isaac Output Parameter: 89102716604bSToby Isaac . diff - The diff ||u - u_h||_2 89112716604bSToby Isaac 89122716604bSToby Isaac Level: developer 89132716604bSToby Isaac 89141189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff() 89152716604bSToby Isaac @*/ 89160709b2feSToby Isaac PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff) 89172716604bSToby Isaac { 89182716604bSToby Isaac PetscErrorCode ierr; 89192716604bSToby Isaac 89202716604bSToby Isaac PetscFunctionBegin; 89212716604bSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8922b698f381SToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 89230918c465SMatthew G. Knepley if (!dm->ops->computel2diff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2Diff",((PetscObject)dm)->type_name); 89240709b2feSToby Isaac ierr = (dm->ops->computel2diff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr); 89252716604bSToby Isaac PetscFunctionReturn(0); 89262716604bSToby Isaac } 8927b698f381SToby Isaac 8928b698f381SToby Isaac /*@C 8929b698f381SToby Isaac DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h. 8930b698f381SToby Isaac 8931d083f849SBarry Smith Collective on dm 8932d083f849SBarry Smith 8933b698f381SToby Isaac Input Parameters: 8934b698f381SToby Isaac + dm - The DM 8935b698f381SToby Isaac , time - The time 8936b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component 8937b698f381SToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8938574a98acSMatthew G. Knepley . X - The coefficient vector u_h, a global vector 8939b698f381SToby Isaac - n - The vector to project along 8940b698f381SToby Isaac 8941b698f381SToby Isaac Output Parameter: 8942b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2 8943b698f381SToby Isaac 8944b698f381SToby Isaac Level: developer 8945b698f381SToby Isaac 8946b698f381SToby Isaac .seealso: DMProjectFunction(), DMComputeL2Diff() 8947b698f381SToby Isaac @*/ 8948b698f381SToby 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) 8949b698f381SToby Isaac { 8950b698f381SToby Isaac PetscErrorCode ierr; 8951b698f381SToby Isaac 8952b698f381SToby Isaac PetscFunctionBegin; 8953b698f381SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8954b698f381SToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 8955b698f381SToby Isaac if (!dm->ops->computel2gradientdiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2GradientDiff",((PetscObject)dm)->type_name); 8956b698f381SToby Isaac ierr = (dm->ops->computel2gradientdiff)(dm,time,funcs,ctxs,X,n,diff);CHKERRQ(ierr); 8957b698f381SToby Isaac PetscFunctionReturn(0); 8958b698f381SToby Isaac } 8959b698f381SToby Isaac 89602a16baeaSToby Isaac /*@C 89612a16baeaSToby Isaac DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components. 89622a16baeaSToby Isaac 8963d083f849SBarry Smith Collective on dm 8964d083f849SBarry Smith 89652a16baeaSToby Isaac Input Parameters: 89662a16baeaSToby Isaac + dm - The DM 89672a16baeaSToby Isaac . time - The time 89682a16baeaSToby Isaac . funcs - The functions to evaluate for each field component 89692a16baeaSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8970574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 89712a16baeaSToby Isaac 89722a16baeaSToby Isaac Output Parameter: 89732a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2 89742a16baeaSToby Isaac 89752a16baeaSToby Isaac Level: developer 89762a16baeaSToby Isaac 89771189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff() 89782a16baeaSToby Isaac @*/ 89791189c1efSToby Isaac PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[]) 89802a16baeaSToby Isaac { 89812a16baeaSToby Isaac PetscErrorCode ierr; 89822a16baeaSToby Isaac 89832a16baeaSToby Isaac PetscFunctionBegin; 89842a16baeaSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 89852a16baeaSToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 89860918c465SMatthew G. Knepley if (!dm->ops->computel2fielddiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2FieldDiff",((PetscObject)dm)->type_name); 89872a16baeaSToby Isaac ierr = (dm->ops->computel2fielddiff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr); 89882a16baeaSToby Isaac PetscFunctionReturn(0); 89892a16baeaSToby Isaac } 89902a16baeaSToby Isaac 8991df0b854cSToby Isaac /*@C 8992df0b854cSToby Isaac DMAdaptLabel - Adapt a dm based on a label with values interpreted as coarsening and refining flags. Specific implementations of DM maybe have 8993cd3c525cSToby Isaac specialized flags, but all implementations should accept flag values DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN. 8994df0b854cSToby Isaac 8995df0b854cSToby Isaac Collective on dm 8996df0b854cSToby Isaac 8997df0b854cSToby Isaac Input parameters: 8998df0b854cSToby Isaac + dm - the pre-adaptation DM object 8999a1b0c543SToby Isaac - label - label with the flags 9000df0b854cSToby Isaac 9001df0b854cSToby Isaac Output parameters: 90020d1cd5e0SMatthew G. Knepley . dmAdapt - the adapted DM object: may be NULL if an adapted DM could not be produced. 9003df0b854cSToby Isaac 9004df0b854cSToby Isaac Level: intermediate 90050d1cd5e0SMatthew G. Knepley 90060d1cd5e0SMatthew G. Knepley .seealso: DMAdaptMetric(), DMCoarsen(), DMRefine() 9007df0b854cSToby Isaac @*/ 90080d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptLabel(DM dm, DMLabel label, DM *dmAdapt) 9009df0b854cSToby Isaac { 9010df0b854cSToby Isaac PetscErrorCode ierr; 9011df0b854cSToby Isaac 9012df0b854cSToby Isaac PetscFunctionBegin; 9013df0b854cSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9014a1b0c543SToby Isaac PetscValidPointer(label,2); 90150d1cd5e0SMatthew G. Knepley PetscValidPointer(dmAdapt,3); 90160d1cd5e0SMatthew G. Knepley *dmAdapt = NULL; 90176f25b0d8SLisandro Dalcin if (!dm->ops->adaptlabel) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptLabel",((PetscObject)dm)->type_name); 90180d1cd5e0SMatthew G. Knepley ierr = (dm->ops->adaptlabel)(dm, label, dmAdapt);CHKERRQ(ierr); 9019a587d139SMark if (*dmAdapt) { 9020a587d139SMark (*dmAdapt)->prealloc_only = dm->prealloc_only; /* maybe this should go .... */ 9021a587d139SMark ierr = PetscFree((*dmAdapt)->vectype);CHKERRQ(ierr); 9022a587d139SMark ierr = PetscStrallocpy(dm->vectype,(char**)&(*dmAdapt)->vectype);CHKERRQ(ierr); 9023a587d139SMark ierr = PetscFree((*dmAdapt)->mattype);CHKERRQ(ierr); 9024a587d139SMark ierr = PetscStrallocpy(dm->mattype,(char**)&(*dmAdapt)->mattype);CHKERRQ(ierr); 9025a587d139SMark } 90260d1cd5e0SMatthew G. Knepley PetscFunctionReturn(0); 90270d1cd5e0SMatthew G. Knepley } 90280d1cd5e0SMatthew G. Knepley 90290d1cd5e0SMatthew G. Knepley /*@C 90300d1cd5e0SMatthew G. Knepley DMAdaptMetric - Generates a mesh adapted to the specified metric field using the pragmatic library. 90310d1cd5e0SMatthew G. Knepley 90320d1cd5e0SMatthew G. Knepley Input Parameters: 90330d1cd5e0SMatthew G. Knepley + dm - The DM object 90340d1cd5e0SMatthew G. Knepley . metric - The metric to which the mesh is adapted, defined vertex-wise. 90356f25b0d8SLisandro 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_". 90360d1cd5e0SMatthew G. Knepley 90370d1cd5e0SMatthew G. Knepley Output Parameter: 90380d1cd5e0SMatthew G. Knepley . dmAdapt - Pointer to the DM object containing the adapted mesh 90390d1cd5e0SMatthew G. Knepley 90400d1cd5e0SMatthew G. Knepley Note: The label in the adapted mesh will be registered under the name of the input DMLabel object 90410d1cd5e0SMatthew G. Knepley 90420d1cd5e0SMatthew G. Knepley Level: advanced 90430d1cd5e0SMatthew G. Knepley 90440d1cd5e0SMatthew G. Knepley .seealso: DMAdaptLabel(), DMCoarsen(), DMRefine() 90450d1cd5e0SMatthew G. Knepley @*/ 90460d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptMetric(DM dm, Vec metric, DMLabel bdLabel, DM *dmAdapt) 90470d1cd5e0SMatthew G. Knepley { 90480d1cd5e0SMatthew G. Knepley PetscErrorCode ierr; 90490d1cd5e0SMatthew G. Knepley 90500d1cd5e0SMatthew G. Knepley PetscFunctionBegin; 90510d1cd5e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90520d1cd5e0SMatthew G. Knepley PetscValidHeaderSpecific(metric, VEC_CLASSID, 2); 90530d1cd5e0SMatthew G. Knepley if (bdLabel) PetscValidPointer(bdLabel, 3); 90540d1cd5e0SMatthew G. Knepley PetscValidPointer(dmAdapt, 4); 90556f25b0d8SLisandro Dalcin *dmAdapt = NULL; 90566f25b0d8SLisandro Dalcin if (!dm->ops->adaptmetric) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptMetric",((PetscObject)dm)->type_name); 90570d1cd5e0SMatthew G. Knepley ierr = (dm->ops->adaptmetric)(dm, metric, bdLabel, dmAdapt);CHKERRQ(ierr); 9058df0b854cSToby Isaac PetscFunctionReturn(0); 9059df0b854cSToby Isaac } 9060c4088d22SMatthew G. Knepley 9061502a2867SDave May /*@C 9062502a2867SDave May DMGetNeighbors - Gets an array containing the MPI rank of all the processes neighbors 9063502a2867SDave May 9064502a2867SDave May Not Collective 9065502a2867SDave May 9066502a2867SDave May Input Parameter: 9067502a2867SDave May . dm - The DM 9068502a2867SDave May 90690a19bb7dSprj- Output Parameters: 90700a19bb7dSprj- + nranks - the number of neighbours 90710a19bb7dSprj- - ranks - the neighbors ranks 9072502a2867SDave May 9073502a2867SDave May Notes: 9074502a2867SDave May Do not free the array, it is freed when the DM is destroyed. 9075502a2867SDave May 9076502a2867SDave May Level: beginner 9077502a2867SDave May 9078dec1416fSJunchao Zhang .seealso: DMDAGetNeighbors(), PetscSFGetRootRanks() 9079502a2867SDave May @*/ 9080502a2867SDave May PetscErrorCode DMGetNeighbors(DM dm,PetscInt *nranks,const PetscMPIInt *ranks[]) 9081502a2867SDave May { 9082502a2867SDave May PetscErrorCode ierr; 9083502a2867SDave May 9084502a2867SDave May PetscFunctionBegin; 9085502a2867SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 90860918c465SMatthew G. Knepley if (!dm->ops->getneighbors) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMGetNeighbors",((PetscObject)dm)->type_name); 9087502a2867SDave May ierr = (dm->ops->getneighbors)(dm,nranks,ranks);CHKERRQ(ierr); 9088502a2867SDave May PetscFunctionReturn(0); 9089502a2867SDave May } 9090502a2867SDave May 9091531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */ 9092531c7667SBarry Smith 9093531c7667SBarry Smith /* 9094531c7667SBarry Smith Converts the input vector to a ghosted vector and then calls the standard coloring code. 9095531c7667SBarry Smith This has be a different function because it requires DM which is not defined in the Mat library 9096531c7667SBarry Smith */ 9097531c7667SBarry Smith PetscErrorCode MatFDColoringApply_AIJDM(Mat J,MatFDColoring coloring,Vec x1,void *sctx) 9098531c7667SBarry Smith { 9099531c7667SBarry Smith PetscErrorCode ierr; 9100531c7667SBarry Smith 9101531c7667SBarry Smith PetscFunctionBegin; 9102531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 9103531c7667SBarry Smith Vec x1local; 9104531c7667SBarry Smith DM dm; 9105531c7667SBarry Smith ierr = MatGetDM(J,&dm);CHKERRQ(ierr); 9106531c7667SBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_INCOMP,"IS_COLORING_LOCAL requires a DM"); 9107531c7667SBarry Smith ierr = DMGetLocalVector(dm,&x1local);CHKERRQ(ierr); 9108531c7667SBarry Smith ierr = DMGlobalToLocalBegin(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr); 9109531c7667SBarry Smith ierr = DMGlobalToLocalEnd(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr); 9110531c7667SBarry Smith x1 = x1local; 9111531c7667SBarry Smith } 9112531c7667SBarry Smith ierr = MatFDColoringApply_AIJ(J,coloring,x1,sctx);CHKERRQ(ierr); 9113531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 9114531c7667SBarry Smith DM dm; 9115531c7667SBarry Smith ierr = MatGetDM(J,&dm);CHKERRQ(ierr); 9116531c7667SBarry Smith ierr = DMRestoreLocalVector(dm,&x1);CHKERRQ(ierr); 9117531c7667SBarry Smith } 9118531c7667SBarry Smith PetscFunctionReturn(0); 9119531c7667SBarry Smith } 9120531c7667SBarry Smith 9121531c7667SBarry Smith /*@ 9122531c7667SBarry Smith MatFDColoringUseDM - allows a MatFDColoring object to use the DM associated with the matrix to use a IS_COLORING_LOCAL coloring 9123531c7667SBarry Smith 9124531c7667SBarry Smith Input Parameter: 9125531c7667SBarry Smith . coloring - the MatFDColoring object 9126531c7667SBarry Smith 912795452b02SPatrick Sanan Developer Notes: 912895452b02SPatrick Sanan this routine exists because the PETSc Mat library does not know about the DM objects 9129531c7667SBarry Smith 91301b266c99SBarry Smith Level: advanced 91311b266c99SBarry Smith 9132531c7667SBarry Smith .seealso: MatFDColoring, MatFDColoringCreate(), ISColoringType 9133531c7667SBarry Smith @*/ 9134531c7667SBarry Smith PetscErrorCode MatFDColoringUseDM(Mat coloring,MatFDColoring fdcoloring) 9135531c7667SBarry Smith { 9136531c7667SBarry Smith PetscFunctionBegin; 9137531c7667SBarry Smith coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM; 9138531c7667SBarry Smith PetscFunctionReturn(0); 9139531c7667SBarry Smith } 91408320bc6fSPatrick Sanan 91418320bc6fSPatrick Sanan /*@ 91428320bc6fSPatrick Sanan DMGetCompatibility - determine if two DMs are compatible 91438320bc6fSPatrick Sanan 91448320bc6fSPatrick Sanan Collective 91458320bc6fSPatrick Sanan 91468320bc6fSPatrick Sanan Input Parameters: 9147a5bc1bf3SBarry Smith + dm1 - the first DM 91488320bc6fSPatrick Sanan - dm2 - the second DM 91498320bc6fSPatrick Sanan 91508320bc6fSPatrick Sanan Output Parameters: 91518320bc6fSPatrick Sanan + compatible - whether or not the two DMs are compatible 91528320bc6fSPatrick Sanan - set - whether or not the compatible value was set 91538320bc6fSPatrick Sanan 91548320bc6fSPatrick Sanan Notes: 91558320bc6fSPatrick Sanan Two DMs are deemed compatible if they represent the same parallel decomposition 91563d862458SPatrick Sanan of the same topology. This implies that the section (field data) on one 91578320bc6fSPatrick Sanan "makes sense" with respect to the topology and parallel decomposition of the other. 91583d862458SPatrick Sanan Loosely speaking, compatible DMs represent the same domain and parallel 91593d862458SPatrick Sanan decomposition, but hold different data. 91608320bc6fSPatrick Sanan 91618320bc6fSPatrick Sanan Typically, one would confirm compatibility if intending to simultaneously iterate 91628320bc6fSPatrick Sanan over a pair of vectors obtained from different DMs. 91638320bc6fSPatrick Sanan 91648320bc6fSPatrick Sanan For example, two DMDA objects are compatible if they have the same local 91658320bc6fSPatrick Sanan and global sizes and the same stencil width. They can have different numbers 91668320bc6fSPatrick Sanan of degrees of freedom per node. Thus, one could use the node numbering from 91678320bc6fSPatrick Sanan either DM in bounds for a loop over vectors derived from either DM. 91688320bc6fSPatrick Sanan 91698320bc6fSPatrick Sanan Consider the operation of summing data living on a 2-dof DMDA to data living 91708320bc6fSPatrick Sanan on a 1-dof DMDA, which should be compatible, as in the following snippet. 91718320bc6fSPatrick Sanan .vb 91728320bc6fSPatrick Sanan ... 91738320bc6fSPatrick Sanan ierr = DMGetCompatibility(da1,da2,&compatible,&set);CHKERRQ(ierr); 91748320bc6fSPatrick Sanan if (set && compatible) { 91758320bc6fSPatrick Sanan ierr = DMDAVecGetArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr); 91768320bc6fSPatrick Sanan ierr = DMDAVecGetArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr); 91773d862458SPatrick Sanan ierr = DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL);CHKERRQ(ierr); 91788320bc6fSPatrick Sanan for (j=y; j<y+n; ++j) { 91798320bc6fSPatrick Sanan for (i=x; i<x+m, ++i) { 91808320bc6fSPatrick Sanan arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1]; 91818320bc6fSPatrick Sanan } 91828320bc6fSPatrick Sanan } 91838320bc6fSPatrick Sanan ierr = DMDAVecRestoreArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr); 91848320bc6fSPatrick Sanan ierr = DMDAVecRestoreArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr); 91858320bc6fSPatrick Sanan } else { 91868320bc6fSPatrick Sanan SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible"); 91878320bc6fSPatrick Sanan } 91888320bc6fSPatrick Sanan ... 91898320bc6fSPatrick Sanan .ve 91908320bc6fSPatrick Sanan 91918320bc6fSPatrick Sanan Checking compatibility might be expensive for a given implementation of DM, 91928320bc6fSPatrick Sanan or might be impossible to unambiguously confirm or deny. For this reason, 91938320bc6fSPatrick Sanan this function may decline to determine compatibility, and hence users should 91948320bc6fSPatrick Sanan always check the "set" output parameter. 91958320bc6fSPatrick Sanan 91968320bc6fSPatrick Sanan A DM is always compatible with itself. 91978320bc6fSPatrick Sanan 91988320bc6fSPatrick Sanan In the current implementation, DMs which live on "unequal" communicators 91998320bc6fSPatrick Sanan (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed 92008320bc6fSPatrick Sanan incompatible. 92018320bc6fSPatrick Sanan 92028320bc6fSPatrick Sanan This function is labeled "Collective," as information about all subdomains 92038320bc6fSPatrick Sanan is required on each rank. However, in DM implementations which store all this 92048320bc6fSPatrick Sanan information locally, this function may be merely "Logically Collective". 92058320bc6fSPatrick Sanan 92068320bc6fSPatrick Sanan Developer Notes: 92073d862458SPatrick Sanan Compatibility is assumed to be a symmetric concept; DM A is compatible with DM B 92083d862458SPatrick Sanan iff B is compatible with A. Thus, this function checks the implementations 9209a5bc1bf3SBarry Smith of both dm and dmc (if they are of different types), attempting to determine 92108320bc6fSPatrick Sanan compatibility. It is left to DM implementers to ensure that symmetry is 92118320bc6fSPatrick Sanan preserved. The simplest way to do this is, when implementing type-specific 92123d862458SPatrick Sanan logic for this function, is to check for existing logic in the implementation 92133d862458SPatrick Sanan of other DM types and let *set = PETSC_FALSE if found. 92148320bc6fSPatrick Sanan 92158320bc6fSPatrick Sanan Level: advanced 92168320bc6fSPatrick Sanan 92173d862458SPatrick Sanan .seealso: DM, DMDACreateCompatibleDMDA(), DMStagCreateCompatibleDMStag() 92188320bc6fSPatrick Sanan @*/ 92198320bc6fSPatrick Sanan 9220a5bc1bf3SBarry Smith PetscErrorCode DMGetCompatibility(DM dm1,DM dm2,PetscBool *compatible,PetscBool *set) 92218320bc6fSPatrick Sanan { 92228320bc6fSPatrick Sanan PetscErrorCode ierr; 92238320bc6fSPatrick Sanan PetscMPIInt compareResult; 92248320bc6fSPatrick Sanan DMType type,type2; 92258320bc6fSPatrick Sanan PetscBool sameType; 92268320bc6fSPatrick Sanan 92278320bc6fSPatrick Sanan PetscFunctionBegin; 9228a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dm1,DM_CLASSID,1); 92298320bc6fSPatrick Sanan PetscValidHeaderSpecific(dm2,DM_CLASSID,2); 92308320bc6fSPatrick Sanan 92318320bc6fSPatrick Sanan /* Declare a DM compatible with itself */ 9232a5bc1bf3SBarry Smith if (dm1 == dm2) { 92338320bc6fSPatrick Sanan *set = PETSC_TRUE; 92348320bc6fSPatrick Sanan *compatible = PETSC_TRUE; 92358320bc6fSPatrick Sanan PetscFunctionReturn(0); 92368320bc6fSPatrick Sanan } 92378320bc6fSPatrick Sanan 92388320bc6fSPatrick Sanan /* Declare a DM incompatible with a DM that lives on an "unequal" 92398320bc6fSPatrick Sanan communicator. Note that this does not preclude compatibility with 92408320bc6fSPatrick Sanan DMs living on "congruent" or "similar" communicators, but this must be 92418320bc6fSPatrick Sanan determined by the implementation-specific logic */ 9242ffc4695bSBarry Smith ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dm1),PetscObjectComm((PetscObject)dm2),&compareResult);CHKERRMPI(ierr); 92438320bc6fSPatrick Sanan if (compareResult == MPI_UNEQUAL) { 92448320bc6fSPatrick Sanan *set = PETSC_TRUE; 92458320bc6fSPatrick Sanan *compatible = PETSC_FALSE; 92468320bc6fSPatrick Sanan PetscFunctionReturn(0); 92478320bc6fSPatrick Sanan } 92488320bc6fSPatrick Sanan 92498320bc6fSPatrick Sanan /* Pass to the implementation-specific routine, if one exists. */ 9250a5bc1bf3SBarry Smith if (dm1->ops->getcompatibility) { 9251a5bc1bf3SBarry Smith ierr = (*dm1->ops->getcompatibility)(dm1,dm2,compatible,set);CHKERRQ(ierr); 9252b9d85ea2SLisandro Dalcin if (*set) PetscFunctionReturn(0); 92538320bc6fSPatrick Sanan } 92548320bc6fSPatrick Sanan 9255a5bc1bf3SBarry Smith /* If dm1 and dm2 are of different types, then attempt to check compatibility 92568320bc6fSPatrick Sanan with an implementation of this function from dm2 */ 9257a5bc1bf3SBarry Smith ierr = DMGetType(dm1,&type);CHKERRQ(ierr); 92588320bc6fSPatrick Sanan ierr = DMGetType(dm2,&type2);CHKERRQ(ierr); 92598320bc6fSPatrick Sanan ierr = PetscStrcmp(type,type2,&sameType);CHKERRQ(ierr); 92608320bc6fSPatrick Sanan if (!sameType && dm2->ops->getcompatibility) { 9261a5bc1bf3SBarry Smith ierr = (*dm2->ops->getcompatibility)(dm2,dm1,compatible,set);CHKERRQ(ierr); /* Note argument order */ 92628320bc6fSPatrick Sanan } else { 92638320bc6fSPatrick Sanan *set = PETSC_FALSE; 92648320bc6fSPatrick Sanan } 92658320bc6fSPatrick Sanan PetscFunctionReturn(0); 92668320bc6fSPatrick Sanan } 9267c0f0dcc3SMatthew G. Knepley 9268c0f0dcc3SMatthew G. Knepley /*@C 9269c0f0dcc3SMatthew G. Knepley DMMonitorSet - Sets an ADDITIONAL function that is to be used after a solve to monitor discretization performance. 9270c0f0dcc3SMatthew G. Knepley 9271c0f0dcc3SMatthew G. Knepley Logically Collective on DM 9272c0f0dcc3SMatthew G. Knepley 9273c0f0dcc3SMatthew G. Knepley Input Parameters: 9274c0f0dcc3SMatthew G. Knepley + DM - the DM 9275c0f0dcc3SMatthew G. Knepley . f - the monitor function 9276c0f0dcc3SMatthew G. Knepley . mctx - [optional] user-defined context for private data for the monitor routine (use NULL if no context is desired) 9277c0f0dcc3SMatthew G. Knepley - monitordestroy - [optional] routine that frees monitor context (may be NULL) 9278c0f0dcc3SMatthew G. Knepley 9279c0f0dcc3SMatthew G. Knepley Options Database Keys: 9280c0f0dcc3SMatthew G. Knepley - -dm_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to DMMonitorSet(), but 9281c0f0dcc3SMatthew G. Knepley does not cancel those set via the options database. 9282c0f0dcc3SMatthew G. Knepley 9283c0f0dcc3SMatthew G. Knepley Notes: 9284c0f0dcc3SMatthew G. Knepley Several different monitoring routines may be set by calling 9285c0f0dcc3SMatthew G. Knepley DMMonitorSet() multiple times; all will be called in the 9286c0f0dcc3SMatthew G. Knepley order in which they were set. 9287c0f0dcc3SMatthew G. Knepley 9288c0f0dcc3SMatthew G. Knepley Fortran Notes: 9289c0f0dcc3SMatthew G. Knepley Only a single monitor function can be set for each DM object 9290c0f0dcc3SMatthew G. Knepley 9291c0f0dcc3SMatthew G. Knepley Level: intermediate 9292c0f0dcc3SMatthew G. Knepley 9293c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorCancel() 9294c0f0dcc3SMatthew G. Knepley @*/ 9295c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorSet(DM dm, PetscErrorCode (*f)(DM, void *), void *mctx, PetscErrorCode (*monitordestroy)(void**)) 9296c0f0dcc3SMatthew G. Knepley { 9297c0f0dcc3SMatthew G. Knepley PetscInt m; 9298c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9299c0f0dcc3SMatthew G. Knepley 9300c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9301c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9302c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 9303c0f0dcc3SMatthew G. Knepley PetscBool identical; 9304c0f0dcc3SMatthew G. Knepley 9305c0f0dcc3SMatthew G. Knepley ierr = PetscMonitorCompare((PetscErrorCode (*)(void)) f, mctx, monitordestroy, (PetscErrorCode (*)(void)) dm->monitor[m], dm->monitorcontext[m], dm->monitordestroy[m], &identical);CHKERRQ(ierr); 9306c0f0dcc3SMatthew G. Knepley if (identical) PetscFunctionReturn(0); 9307c0f0dcc3SMatthew G. Knepley } 9308c0f0dcc3SMatthew G. Knepley if (dm->numbermonitors >= MAXDMMONITORS) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 9309c0f0dcc3SMatthew G. Knepley dm->monitor[dm->numbermonitors] = f; 9310c0f0dcc3SMatthew G. Knepley dm->monitordestroy[dm->numbermonitors] = monitordestroy; 9311c0f0dcc3SMatthew G. Knepley dm->monitorcontext[dm->numbermonitors++] = (void *) mctx; 9312c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9313c0f0dcc3SMatthew G. Knepley } 9314c0f0dcc3SMatthew G. Knepley 9315c0f0dcc3SMatthew G. Knepley /*@ 9316c0f0dcc3SMatthew G. Knepley DMMonitorCancel - Clears all the monitor functions for a DM object. 9317c0f0dcc3SMatthew G. Knepley 9318c0f0dcc3SMatthew G. Knepley Logically Collective on DM 9319c0f0dcc3SMatthew G. Knepley 9320c0f0dcc3SMatthew G. Knepley Input Parameter: 9321c0f0dcc3SMatthew G. Knepley . dm - the DM 9322c0f0dcc3SMatthew G. Knepley 9323c0f0dcc3SMatthew G. Knepley Options Database Key: 9324c0f0dcc3SMatthew G. Knepley . -dm_monitor_cancel - cancels all monitors that have been hardwired 9325c0f0dcc3SMatthew G. Knepley into a code by calls to DMonitorSet(), but does not cancel those 9326c0f0dcc3SMatthew G. Knepley set via the options database 9327c0f0dcc3SMatthew G. Knepley 9328c0f0dcc3SMatthew G. Knepley Notes: 9329c0f0dcc3SMatthew G. Knepley There is no way to clear one specific monitor from a DM object. 9330c0f0dcc3SMatthew G. Knepley 9331c0f0dcc3SMatthew G. Knepley Level: intermediate 9332c0f0dcc3SMatthew G. Knepley 9333c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorSet() 9334c0f0dcc3SMatthew G. Knepley @*/ 9335c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorCancel(DM dm) 9336c0f0dcc3SMatthew G. Knepley { 9337c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9338c0f0dcc3SMatthew G. Knepley PetscInt m; 9339c0f0dcc3SMatthew G. Knepley 9340c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9341c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9342c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 9343c0f0dcc3SMatthew G. Knepley if (dm->monitordestroy[m]) {ierr = (*dm->monitordestroy[m])(&dm->monitorcontext[m]);CHKERRQ(ierr);} 9344c0f0dcc3SMatthew G. Knepley } 9345c0f0dcc3SMatthew G. Knepley dm->numbermonitors = 0; 9346c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9347c0f0dcc3SMatthew G. Knepley } 9348c0f0dcc3SMatthew G. Knepley 9349c0f0dcc3SMatthew G. Knepley /*@C 9350c0f0dcc3SMatthew G. Knepley DMMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 9351c0f0dcc3SMatthew G. Knepley 9352c0f0dcc3SMatthew G. Knepley Collective on DM 9353c0f0dcc3SMatthew G. Knepley 9354c0f0dcc3SMatthew G. Knepley Input Parameters: 9355c0f0dcc3SMatthew G. Knepley + dm - DM object you wish to monitor 9356c0f0dcc3SMatthew G. Knepley . name - the monitor type one is seeking 9357c0f0dcc3SMatthew G. Knepley . help - message indicating what monitoring is done 9358c0f0dcc3SMatthew G. Knepley . manual - manual page for the monitor 9359c0f0dcc3SMatthew G. Knepley . monitor - the monitor function 9360c0f0dcc3SMatthew 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 9361c0f0dcc3SMatthew G. Knepley 9362c0f0dcc3SMatthew G. Knepley Output Parameter: 9363c0f0dcc3SMatthew G. Knepley . flg - Flag set if the monitor was created 9364c0f0dcc3SMatthew G. Knepley 9365c0f0dcc3SMatthew G. Knepley Level: developer 9366c0f0dcc3SMatthew G. Knepley 9367c0f0dcc3SMatthew G. Knepley .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 9368c0f0dcc3SMatthew G. Knepley PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 9369c0f0dcc3SMatthew G. Knepley PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 9370c0f0dcc3SMatthew G. Knepley PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 9371c0f0dcc3SMatthew G. Knepley PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 9372c0f0dcc3SMatthew G. Knepley PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 9373c0f0dcc3SMatthew G. Knepley PetscOptionsFList(), PetscOptionsEList() 9374c0f0dcc3SMatthew G. Knepley @*/ 9375c0f0dcc3SMatthew 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) 9376c0f0dcc3SMatthew G. Knepley { 9377c0f0dcc3SMatthew G. Knepley PetscViewer viewer; 9378c0f0dcc3SMatthew G. Knepley PetscViewerFormat format; 9379c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9380c0f0dcc3SMatthew G. Knepley 9381c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9382c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9383c0f0dcc3SMatthew G. Knepley ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) dm), ((PetscObject) dm)->options, ((PetscObject) dm)->prefix, name, &viewer, &format, flg);CHKERRQ(ierr); 9384c0f0dcc3SMatthew G. Knepley if (*flg) { 9385c0f0dcc3SMatthew G. Knepley PetscViewerAndFormat *vf; 9386c0f0dcc3SMatthew G. Knepley 9387c0f0dcc3SMatthew G. Knepley ierr = PetscViewerAndFormatCreate(viewer, format, &vf);CHKERRQ(ierr); 9388c0f0dcc3SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) viewer);CHKERRQ(ierr); 9389c0f0dcc3SMatthew G. Knepley if (monitorsetup) {ierr = (*monitorsetup)(dm, vf);CHKERRQ(ierr);} 9390c0f0dcc3SMatthew G. Knepley ierr = DMMonitorSet(dm,(PetscErrorCode (*)(DM, void *)) monitor, vf, (PetscErrorCode (*)(void **)) PetscViewerAndFormatDestroy);CHKERRQ(ierr); 9391c0f0dcc3SMatthew G. Knepley } 9392c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9393c0f0dcc3SMatthew G. Knepley } 9394c0f0dcc3SMatthew G. Knepley 9395c0f0dcc3SMatthew G. Knepley /*@ 9396c0f0dcc3SMatthew G. Knepley DMMonitor - runs the user provided monitor routines, if they exist 9397c0f0dcc3SMatthew G. Knepley 9398c0f0dcc3SMatthew G. Knepley Collective on DM 9399c0f0dcc3SMatthew G. Knepley 9400c0f0dcc3SMatthew G. Knepley Input Parameters: 9401c0f0dcc3SMatthew G. Knepley . dm - The DM 9402c0f0dcc3SMatthew G. Knepley 9403c0f0dcc3SMatthew G. Knepley Level: developer 9404c0f0dcc3SMatthew G. Knepley 9405c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorSet() 9406c0f0dcc3SMatthew G. Knepley @*/ 9407c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitor(DM dm) 9408c0f0dcc3SMatthew G. Knepley { 9409c0f0dcc3SMatthew G. Knepley PetscInt m; 9410c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9411c0f0dcc3SMatthew G. Knepley 9412c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9413c0f0dcc3SMatthew G. Knepley if (!dm) PetscFunctionReturn(0); 9414c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9415c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 9416c0f0dcc3SMatthew G. Knepley ierr = (*dm->monitor[m])(dm, dm->monitorcontext[m]);CHKERRQ(ierr); 9417c0f0dcc3SMatthew G. Knepley } 9418c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9419c0f0dcc3SMatthew G. Knepley } 94202e4af2aeSMatthew G. Knepley 94212e4af2aeSMatthew G. Knepley /*@ 94222e4af2aeSMatthew G. Knepley DMComputeError - Computes the error assuming the user has given exact solution functions 94232e4af2aeSMatthew G. Knepley 94242e4af2aeSMatthew G. Knepley Collective on DM 94252e4af2aeSMatthew G. Knepley 94262e4af2aeSMatthew G. Knepley Input Parameters: 94272e4af2aeSMatthew G. Knepley + dm - The DM 94282e4af2aeSMatthew G. Knepley . sol - The solution vector 94292e4af2aeSMatthew G. Knepley . errors - An array of length Nf, the number of fields, or NULL for no output 9430*99c90e12SSatish Balay - errorVec - A Vec pointer, or NULL for no output 94312e4af2aeSMatthew G. Knepley 94322e4af2aeSMatthew G. Knepley Output Parameters: 94332e4af2aeSMatthew G. Knepley + errors - The error in each field 94342e4af2aeSMatthew G. Knepley - errorVec - Creates a vector to hold the cellwise error 94352e4af2aeSMatthew G. Knepley 94362e4af2aeSMatthew G. Knepley Note: The exact solutions come from the PetscDS object, and the time comes from DMGetOutputSequenceNumber(). 94372e4af2aeSMatthew G. Knepley 94382e4af2aeSMatthew G. Knepley Level: developer 94392e4af2aeSMatthew G. Knepley 94402e4af2aeSMatthew G. Knepley .seealso: DMMonitorSet(), DMGetRegionNumDS(), PetscDSGetExactSolution(), DMGetOutputSequenceNumber() 94412e4af2aeSMatthew G. Knepley @*/ 94422e4af2aeSMatthew G. Knepley PetscErrorCode DMComputeError(DM dm, Vec sol, PetscReal errors[], Vec *errorVec) 94432e4af2aeSMatthew G. Knepley { 94442e4af2aeSMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 94452e4af2aeSMatthew G. Knepley void **ctxs; 94462e4af2aeSMatthew G. Knepley PetscReal time; 94472e4af2aeSMatthew G. Knepley PetscInt Nf, f, Nds, s; 94482e4af2aeSMatthew G. Knepley PetscErrorCode ierr; 94492e4af2aeSMatthew G. Knepley 94502e4af2aeSMatthew G. Knepley PetscFunctionBegin; 94512e4af2aeSMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 94522e4af2aeSMatthew G. Knepley ierr = PetscCalloc2(Nf, &exactSol, Nf, &ctxs);CHKERRQ(ierr); 94532e4af2aeSMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 94542e4af2aeSMatthew G. Knepley for (s = 0; s < Nds; ++s) { 94552e4af2aeSMatthew G. Knepley PetscDS ds; 94562e4af2aeSMatthew G. Knepley DMLabel label; 94572e4af2aeSMatthew G. Knepley IS fieldIS; 94582e4af2aeSMatthew G. Knepley const PetscInt *fields; 94592e4af2aeSMatthew G. Knepley PetscInt dsNf; 94602e4af2aeSMatthew G. Knepley 94612e4af2aeSMatthew G. Knepley ierr = DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds);CHKERRQ(ierr); 94622e4af2aeSMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &dsNf);CHKERRQ(ierr); 94632e4af2aeSMatthew G. Knepley if (fieldIS) {ierr = ISGetIndices(fieldIS, &fields);CHKERRQ(ierr);} 94642e4af2aeSMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 94652e4af2aeSMatthew G. Knepley const PetscInt field = fields[f]; 94662e4af2aeSMatthew G. Knepley ierr = PetscDSGetExactSolution(ds, field, &exactSol[field], &ctxs[field]);CHKERRQ(ierr); 94672e4af2aeSMatthew G. Knepley } 94682e4af2aeSMatthew G. Knepley if (fieldIS) {ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr);} 94692e4af2aeSMatthew G. Knepley } 94702e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 94712e4af2aeSMatthew 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); 94722e4af2aeSMatthew G. Knepley } 94732e4af2aeSMatthew G. Knepley ierr = DMGetOutputSequenceNumber(dm, NULL, &time);CHKERRQ(ierr); 94742e4af2aeSMatthew G. Knepley if (errors) {ierr = DMComputeL2FieldDiff(dm, time, exactSol, ctxs, sol, errors);CHKERRQ(ierr);} 94752e4af2aeSMatthew G. Knepley if (errorVec) { 94762e4af2aeSMatthew G. Knepley DM edm; 94772e4af2aeSMatthew G. Knepley DMPolytopeType ct; 94782e4af2aeSMatthew G. Knepley PetscBool simplex; 94792e4af2aeSMatthew G. Knepley PetscInt dim, cStart, Nf; 94802e4af2aeSMatthew G. Knepley 94812e4af2aeSMatthew G. Knepley ierr = DMClone(dm, &edm);CHKERRQ(ierr); 94822e4af2aeSMatthew G. Knepley ierr = DMGetDimension(edm, &dim);CHKERRQ(ierr); 94832e4af2aeSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, NULL);CHKERRQ(ierr); 94842e4af2aeSMatthew G. Knepley ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 94852e4af2aeSMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 94862e4af2aeSMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 94872e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 94882e4af2aeSMatthew G. Knepley PetscFE fe, efe; 94892e4af2aeSMatthew G. Knepley PetscQuadrature q; 94902e4af2aeSMatthew G. Knepley const char *name; 94912e4af2aeSMatthew G. Knepley 94922e4af2aeSMatthew G. Knepley ierr = DMGetField(dm, f, NULL, (PetscObject *) &fe);CHKERRQ(ierr); 94932e4af2aeSMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, Nf, simplex, 0, PETSC_DETERMINE, &efe);CHKERRQ(ierr); 94942e4af2aeSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) fe, &name);CHKERRQ(ierr); 94952e4af2aeSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) efe, name);CHKERRQ(ierr); 94962e4af2aeSMatthew G. Knepley ierr = PetscFEGetQuadrature(fe, &q);CHKERRQ(ierr); 94972e4af2aeSMatthew G. Knepley ierr = PetscFESetQuadrature(efe, q);CHKERRQ(ierr); 94982e4af2aeSMatthew G. Knepley ierr = DMSetField(edm, f, NULL, (PetscObject) efe);CHKERRQ(ierr); 94992e4af2aeSMatthew G. Knepley ierr = PetscFEDestroy(&efe);CHKERRQ(ierr); 95002e4af2aeSMatthew G. Knepley } 95012e4af2aeSMatthew G. Knepley ierr = DMCreateDS(edm);CHKERRQ(ierr); 95022e4af2aeSMatthew G. Knepley 95032e4af2aeSMatthew G. Knepley ierr = DMCreateGlobalVector(edm, errorVec); 95042e4af2aeSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *errorVec, "Error");CHKERRQ(ierr); 95052e4af2aeSMatthew G. Knepley ierr = DMPlexComputeL2DiffVec(dm, time, exactSol, ctxs, sol, *errorVec);CHKERRQ(ierr); 95062e4af2aeSMatthew G. Knepley ierr = DMDestroy(&edm);CHKERRQ(ierr); 95072e4af2aeSMatthew G. Knepley } 95082e4af2aeSMatthew G. Knepley ierr = PetscFree2(exactSol, ctxs);CHKERRQ(ierr); 95092e4af2aeSMatthew G. Knepley PetscFunctionReturn(0); 95102e4af2aeSMatthew G. Knepley } 9511