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); 849a2a23afSMatthew G. Knepley ierr = PetscHMapAuxCreate(&v->auxData);CHKERRQ(ierr); 8514f150ffSMatthew G. Knepley v->dmBC = NULL; 86a8fb8f29SToby Isaac v->coarseMesh = NULL; 87f4d763aaSMatthew G. Knepley v->outputSequenceNum = -1; 88cdb7a50dSMatthew G. Knepley v->outputSequenceVal = 0.0; 89c0dedaeaSBarry Smith ierr = DMSetVecType(v,VECSTANDARD);CHKERRQ(ierr); 90b412c318SBarry Smith ierr = DMSetMatType(v,MATAIJ);CHKERRQ(ierr); 914a7a4c06SLawrence Mitchell 921411c6eeSJed Brown *dm = v; 93a4121054SBarry Smith PetscFunctionReturn(0); 94a4121054SBarry Smith } 95a4121054SBarry Smith 9638221697SMatthew G. Knepley /*@ 9738221697SMatthew G. Knepley DMClone - Creates a DM object with the same topology as the original. 9838221697SMatthew G. Knepley 99d083f849SBarry Smith Collective 10038221697SMatthew G. Knepley 10138221697SMatthew G. Knepley Input Parameter: 10238221697SMatthew G. Knepley . dm - The original DM object 10338221697SMatthew G. Knepley 10438221697SMatthew G. Knepley Output Parameter: 10538221697SMatthew G. Knepley . newdm - The new DM object 10638221697SMatthew G. Knepley 10738221697SMatthew G. Knepley Level: beginner 10838221697SMatthew G. Knepley 1091cb8cacdSPatrick Sanan Notes: 1101cb8cacdSPatrick Sanan For some DM implementations this is a shallow clone, the result of which may share (referent counted) information with its parent. For example, 1111cb8cacdSPatrick Sanan DMClone() applied to a DMPLEX object will result in a new DMPLEX that shares the topology with the original DMPLEX. It does not 1121cb8cacdSPatrick Sanan share the PetscSection of the original DM. 1131bb6d2a8SBarry Smith 11489706ed2SPatrick Sanan The clone is considered set up iff the original is. 11589706ed2SPatrick Sanan 11692cfd99aSMartin Diehl .seealso: DMDestroy(), DMCreate(), DMSetType(), DMSetLocalSection(), DMSetGlobalSection() 1171bb6d2a8SBarry Smith 11838221697SMatthew G. Knepley @*/ 11938221697SMatthew G. Knepley PetscErrorCode DMClone(DM dm, DM *newdm) 12038221697SMatthew G. Knepley { 12138221697SMatthew G. Knepley PetscSF sf; 12238221697SMatthew G. Knepley Vec coords; 12338221697SMatthew G. Knepley void *ctx; 124a3219837SMatthew G. Knepley PetscInt dim, cdim; 12538221697SMatthew G. Knepley PetscErrorCode ierr; 12638221697SMatthew G. Knepley 12738221697SMatthew G. Knepley PetscFunctionBegin; 12838221697SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 12938221697SMatthew G. Knepley PetscValidPointer(newdm,2); 13038221697SMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject) dm), newdm);CHKERRQ(ierr); 1315d80c0bfSVaclav Hapla ierr = DMCopyLabels(dm, *newdm, PETSC_COPY_VALUES, PETSC_TRUE);CHKERRQ(ierr); 132ddf8437dSMatthew G. Knepley (*newdm)->leveldown = dm->leveldown; 133ddf8437dSMatthew G. Knepley (*newdm)->levelup = dm->levelup; 134c8a6034eSMark (*newdm)->prealloc_only = dm->prealloc_only; 135a587d139SMark ierr = PetscFree((*newdm)->vectype);CHKERRQ(ierr); 136a587d139SMark ierr = PetscStrallocpy(dm->vectype,(char**)&(*newdm)->vectype);CHKERRQ(ierr); 137a587d139SMark ierr = PetscFree((*newdm)->mattype);CHKERRQ(ierr); 138a587d139SMark ierr = PetscStrallocpy(dm->mattype,(char**)&(*newdm)->mattype);CHKERRQ(ierr); 1391de53e9aSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1401de53e9aSMatthew G. Knepley ierr = DMSetDimension(*newdm, dim);CHKERRQ(ierr); 14138221697SMatthew G. Knepley if (dm->ops->clone) { 14238221697SMatthew G. Knepley ierr = (*dm->ops->clone)(dm, newdm);CHKERRQ(ierr); 14338221697SMatthew G. Knepley } 1443f22bcbcSToby Isaac (*newdm)->setupcalled = dm->setupcalled; 14538221697SMatthew G. Knepley ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 14638221697SMatthew G. Knepley ierr = DMSetPointSF(*newdm, sf);CHKERRQ(ierr); 14738221697SMatthew G. Knepley ierr = DMGetApplicationContext(dm, &ctx);CHKERRQ(ierr); 14838221697SMatthew G. Knepley ierr = DMSetApplicationContext(*newdm, ctx);CHKERRQ(ierr); 149be4c1c3eSMatthew G. Knepley if (dm->coordinateDM) { 150be4c1c3eSMatthew G. Knepley DM ncdm; 151be4c1c3eSMatthew G. Knepley PetscSection cs; 1525a0206caSToby Isaac PetscInt pEnd = -1, pEndMax = -1; 153be4c1c3eSMatthew G. Knepley 15492fd8e1eSJed Brown ierr = DMGetLocalSection(dm->coordinateDM, &cs);CHKERRQ(ierr); 155be4c1c3eSMatthew G. Knepley if (cs) {ierr = PetscSectionGetChart(cs, NULL, &pEnd);CHKERRQ(ierr);} 156ffc4695bSBarry Smith ierr = MPI_Allreduce(&pEnd,&pEndMax,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 1575a0206caSToby Isaac if (pEndMax >= 0) { 158be4c1c3eSMatthew G. Knepley ierr = DMClone(dm->coordinateDM, &ncdm);CHKERRQ(ierr); 15983bfc06fSMatthew Knepley ierr = DMCopyDisc(dm->coordinateDM, ncdm);CHKERRQ(ierr); 16092fd8e1eSJed Brown ierr = DMSetLocalSection(ncdm, cs);CHKERRQ(ierr); 161a61e840bSMatthew G. Knepley ierr = DMSetCoordinateDM(*newdm, ncdm);CHKERRQ(ierr); 162be4c1c3eSMatthew G. Knepley ierr = DMDestroy(&ncdm);CHKERRQ(ierr); 163be4c1c3eSMatthew G. Knepley } 164be4c1c3eSMatthew G. Knepley } 165a3219837SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 166a3219837SMatthew G. Knepley ierr = DMSetCoordinateDim(*newdm, cdim);CHKERRQ(ierr); 16738221697SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coords);CHKERRQ(ierr); 16838221697SMatthew G. Knepley if (coords) { 16938221697SMatthew G. Knepley ierr = DMSetCoordinatesLocal(*newdm, coords);CHKERRQ(ierr); 17038221697SMatthew G. Knepley } else { 17138221697SMatthew G. Knepley ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr); 17238221697SMatthew G. Knepley if (coords) {ierr = DMSetCoordinates(*newdm, coords);CHKERRQ(ierr);} 17338221697SMatthew G. Knepley } 17490b157c4SStefano Zampini { 17590b157c4SStefano Zampini PetscBool isper; 176c6b900c6SMatthew G. Knepley const PetscReal *maxCell, *L; 1775dc8c3f7SMatthew G. Knepley const DMBoundaryType *bd; 17890b157c4SStefano Zampini ierr = DMGetPeriodicity(dm, &isper, &maxCell, &L, &bd);CHKERRQ(ierr); 17990b157c4SStefano Zampini ierr = DMSetPeriodicity(*newdm, isper, maxCell, L, bd);CHKERRQ(ierr); 180c6b900c6SMatthew G. Knepley } 18134aa8a36SMatthew G. Knepley { 18234aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 18334aa8a36SMatthew G. Knepley 18434aa8a36SMatthew G. Knepley ierr = DMGetAdjacency(dm, PETSC_DEFAULT, &useCone, &useClosure);CHKERRQ(ierr); 18534aa8a36SMatthew G. Knepley ierr = DMSetAdjacency(*newdm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr); 18634aa8a36SMatthew G. Knepley } 18738221697SMatthew G. Knepley PetscFunctionReturn(0); 18838221697SMatthew G. Knepley } 18938221697SMatthew G. Knepley 1909a42bb27SBarry Smith /*@C 191564755cdSBarry Smith DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector() 1929a42bb27SBarry Smith 193d083f849SBarry Smith Logically Collective on da 1949a42bb27SBarry Smith 1959a42bb27SBarry Smith Input Parameter: 1969a42bb27SBarry Smith + da - initial distributed array 197e9e886b6SKarl Rupp . ctype - the vector type, currently either VECSTANDARD, VECCUDA, or VECVIENNACL 1989a42bb27SBarry Smith 1999a42bb27SBarry Smith Options Database: 200dd85299cSBarry Smith . -dm_vec_type ctype 2019a42bb27SBarry Smith 2029a42bb27SBarry Smith Level: intermediate 2039a42bb27SBarry Smith 204a2a9ebe5SBarry Smith .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType, DMGetVecType(), DMSetMatType(), DMGetMatType() 2059a42bb27SBarry Smith @*/ 20619fd82e9SBarry Smith PetscErrorCode DMSetVecType(DM da,VecType ctype) 2079a42bb27SBarry Smith { 2089a42bb27SBarry Smith PetscErrorCode ierr; 2099a42bb27SBarry Smith 2109a42bb27SBarry Smith PetscFunctionBegin; 2119a42bb27SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 2129a42bb27SBarry Smith ierr = PetscFree(da->vectype);CHKERRQ(ierr); 21319fd82e9SBarry Smith ierr = PetscStrallocpy(ctype,(char**)&da->vectype);CHKERRQ(ierr); 2149a42bb27SBarry Smith PetscFunctionReturn(0); 2159a42bb27SBarry Smith } 2169a42bb27SBarry Smith 217c0dedaeaSBarry Smith /*@C 218c0dedaeaSBarry Smith DMGetVecType - Gets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector() 219c0dedaeaSBarry Smith 220d083f849SBarry Smith Logically Collective on da 221c0dedaeaSBarry Smith 222c0dedaeaSBarry Smith Input Parameter: 223c0dedaeaSBarry Smith . da - initial distributed array 224c0dedaeaSBarry Smith 225c0dedaeaSBarry Smith Output Parameter: 226c0dedaeaSBarry Smith . ctype - the vector type 227c0dedaeaSBarry Smith 228c0dedaeaSBarry Smith Level: intermediate 229c0dedaeaSBarry Smith 230a2a9ebe5SBarry Smith .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType, DMSetMatType(), DMGetMatType(), DMSetVecType() 231c0dedaeaSBarry Smith @*/ 232c0dedaeaSBarry Smith PetscErrorCode DMGetVecType(DM da,VecType *ctype) 233c0dedaeaSBarry Smith { 234c0dedaeaSBarry Smith PetscFunctionBegin; 235c0dedaeaSBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 236c0dedaeaSBarry Smith *ctype = da->vectype; 237c0dedaeaSBarry Smith PetscFunctionReturn(0); 238c0dedaeaSBarry Smith } 239c0dedaeaSBarry Smith 2405f1ad066SMatthew G Knepley /*@ 24134f98d34SBarry Smith VecGetDM - Gets the DM defining the data layout of the vector 2425f1ad066SMatthew G Knepley 2435f1ad066SMatthew G Knepley Not collective 2445f1ad066SMatthew G Knepley 2455f1ad066SMatthew G Knepley Input Parameter: 2465f1ad066SMatthew G Knepley . v - The Vec 2475f1ad066SMatthew G Knepley 2485f1ad066SMatthew G Knepley Output Parameter: 2495f1ad066SMatthew G Knepley . dm - The DM 2505f1ad066SMatthew G Knepley 2515f1ad066SMatthew G Knepley Level: intermediate 2525f1ad066SMatthew G Knepley 2535f1ad066SMatthew G Knepley .seealso: VecSetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType() 2545f1ad066SMatthew G Knepley @*/ 2555f1ad066SMatthew G Knepley PetscErrorCode VecGetDM(Vec v, DM *dm) 2565f1ad066SMatthew G Knepley { 2575f1ad066SMatthew G Knepley PetscErrorCode ierr; 2585f1ad066SMatthew G Knepley 2595f1ad066SMatthew G Knepley PetscFunctionBegin; 2605f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,1); 2615f1ad066SMatthew G Knepley PetscValidPointer(dm,2); 2625f1ad066SMatthew G Knepley ierr = PetscObjectQuery((PetscObject) v, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr); 2635f1ad066SMatthew G Knepley PetscFunctionReturn(0); 2645f1ad066SMatthew G Knepley } 2655f1ad066SMatthew G Knepley 2665f1ad066SMatthew G Knepley /*@ 267d9805387SMatthew G. Knepley VecSetDM - Sets the DM defining the data layout of the vector. 2685f1ad066SMatthew G Knepley 2695f1ad066SMatthew G Knepley Not collective 2705f1ad066SMatthew G Knepley 2715f1ad066SMatthew G Knepley Input Parameters: 2725f1ad066SMatthew G Knepley + v - The Vec 2735f1ad066SMatthew G Knepley - dm - The DM 2745f1ad066SMatthew G Knepley 275d9805387SMatthew 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. 276d9805387SMatthew G. Knepley 2775f1ad066SMatthew G Knepley Level: intermediate 2785f1ad066SMatthew G Knepley 2795f1ad066SMatthew G Knepley .seealso: VecGetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType() 2805f1ad066SMatthew G Knepley @*/ 2815f1ad066SMatthew G Knepley PetscErrorCode VecSetDM(Vec v, DM dm) 2825f1ad066SMatthew G Knepley { 2835f1ad066SMatthew G Knepley PetscErrorCode ierr; 2845f1ad066SMatthew G Knepley 2855f1ad066SMatthew G Knepley PetscFunctionBegin; 2865f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,1); 287d7f50e27SLisandro Dalcin if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2); 2885f1ad066SMatthew G Knepley ierr = PetscObjectCompose((PetscObject) v, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 2895f1ad066SMatthew G Knepley PetscFunctionReturn(0); 2905f1ad066SMatthew G Knepley } 2915f1ad066SMatthew G Knepley 292521d9a4cSLisandro Dalcin /*@C 2938f1509bcSBarry Smith DMSetISColoringType - Sets the type of coloring, global or local, that is created by the DM 2948f1509bcSBarry Smith 295d083f849SBarry Smith Logically Collective on dm 2968f1509bcSBarry Smith 2978f1509bcSBarry Smith Input Parameters: 2988f1509bcSBarry Smith + dm - the DM context 2998f1509bcSBarry Smith - ctype - the matrix type 3008f1509bcSBarry Smith 3018f1509bcSBarry Smith Options Database: 3028f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3038f1509bcSBarry Smith 3048f1509bcSBarry Smith Level: intermediate 3058f1509bcSBarry Smith 3068f1509bcSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(), 3078f1509bcSBarry Smith DMGetISColoringType() 3088f1509bcSBarry Smith @*/ 3098f1509bcSBarry Smith PetscErrorCode DMSetISColoringType(DM dm,ISColoringType ctype) 3108f1509bcSBarry Smith { 3118f1509bcSBarry Smith PetscFunctionBegin; 3128f1509bcSBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3138f1509bcSBarry Smith dm->coloringtype = ctype; 3148f1509bcSBarry Smith PetscFunctionReturn(0); 3158f1509bcSBarry Smith } 3168f1509bcSBarry Smith 3178f1509bcSBarry Smith /*@C 3188f1509bcSBarry Smith DMGetISColoringType - Gets the type of coloring, global or local, that is created by the DM 319521d9a4cSLisandro Dalcin 320d083f849SBarry Smith Logically Collective on dm 321521d9a4cSLisandro Dalcin 322521d9a4cSLisandro Dalcin Input Parameter: 3238f1509bcSBarry Smith . dm - the DM context 3248f1509bcSBarry Smith 3258f1509bcSBarry Smith Output Parameter: 3268f1509bcSBarry Smith . ctype - the matrix type 3278f1509bcSBarry Smith 3288f1509bcSBarry Smith Options Database: 3298f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3308f1509bcSBarry Smith 3318f1509bcSBarry Smith Level: intermediate 3328f1509bcSBarry Smith 3338f1509bcSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(), 3348f1509bcSBarry Smith DMGetISColoringType() 3358f1509bcSBarry Smith @*/ 3368f1509bcSBarry Smith PetscErrorCode DMGetISColoringType(DM dm,ISColoringType *ctype) 3378f1509bcSBarry Smith { 3388f1509bcSBarry Smith PetscFunctionBegin; 3398f1509bcSBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3408f1509bcSBarry Smith *ctype = dm->coloringtype; 3418f1509bcSBarry Smith PetscFunctionReturn(0); 3428f1509bcSBarry Smith } 3438f1509bcSBarry Smith 3448f1509bcSBarry Smith /*@C 3458f1509bcSBarry Smith DMSetMatType - Sets the type of matrix created with DMCreateMatrix() 3468f1509bcSBarry Smith 347d083f849SBarry Smith Logically Collective on dm 3488f1509bcSBarry Smith 3498f1509bcSBarry Smith Input Parameters: 350521d9a4cSLisandro Dalcin + dm - the DM context 351a2b5a043SBarry Smith - ctype - the matrix type 352521d9a4cSLisandro Dalcin 353521d9a4cSLisandro Dalcin Options Database: 354521d9a4cSLisandro Dalcin . -dm_mat_type ctype 355521d9a4cSLisandro Dalcin 356521d9a4cSLisandro Dalcin Level: intermediate 357521d9a4cSLisandro Dalcin 358a2a9ebe5SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(), DMSetMatType(), DMGetMatType() 359521d9a4cSLisandro Dalcin @*/ 36019fd82e9SBarry Smith PetscErrorCode DMSetMatType(DM dm,MatType ctype) 361521d9a4cSLisandro Dalcin { 362521d9a4cSLisandro Dalcin PetscErrorCode ierr; 36388f0584fSBarry Smith 364521d9a4cSLisandro Dalcin PetscFunctionBegin; 365521d9a4cSLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 366521d9a4cSLisandro Dalcin ierr = PetscFree(dm->mattype);CHKERRQ(ierr); 36719fd82e9SBarry Smith ierr = PetscStrallocpy(ctype,(char**)&dm->mattype);CHKERRQ(ierr); 368521d9a4cSLisandro Dalcin PetscFunctionReturn(0); 369521d9a4cSLisandro Dalcin } 370521d9a4cSLisandro Dalcin 371c0dedaeaSBarry Smith /*@C 372c0dedaeaSBarry Smith DMGetMatType - Gets the type of matrix created with DMCreateMatrix() 373c0dedaeaSBarry Smith 374d083f849SBarry Smith Logically Collective on dm 375c0dedaeaSBarry Smith 376c0dedaeaSBarry Smith Input Parameter: 377c0dedaeaSBarry Smith . dm - the DM context 378c0dedaeaSBarry Smith 379c0dedaeaSBarry Smith Output Parameter: 380c0dedaeaSBarry Smith . ctype - the matrix type 381c0dedaeaSBarry Smith 382c0dedaeaSBarry Smith Options Database: 383c0dedaeaSBarry Smith . -dm_mat_type ctype 384c0dedaeaSBarry Smith 385c0dedaeaSBarry Smith Level: intermediate 386c0dedaeaSBarry Smith 387a2a9ebe5SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMSetMatType(), DMSetMatType(), DMGetMatType() 388c0dedaeaSBarry Smith @*/ 389c0dedaeaSBarry Smith PetscErrorCode DMGetMatType(DM dm,MatType *ctype) 390c0dedaeaSBarry Smith { 391c0dedaeaSBarry Smith PetscFunctionBegin; 392c0dedaeaSBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 393c0dedaeaSBarry Smith *ctype = dm->mattype; 394c0dedaeaSBarry Smith PetscFunctionReturn(0); 395c0dedaeaSBarry Smith } 396c0dedaeaSBarry Smith 397c688c046SMatthew G Knepley /*@ 39834f98d34SBarry Smith MatGetDM - Gets the DM defining the data layout of the matrix 399c688c046SMatthew G Knepley 400c688c046SMatthew G Knepley Not collective 401c688c046SMatthew G Knepley 402c688c046SMatthew G Knepley Input Parameter: 403c688c046SMatthew G Knepley . A - The Mat 404c688c046SMatthew G Knepley 405c688c046SMatthew G Knepley Output Parameter: 406c688c046SMatthew G Knepley . dm - The DM 407c688c046SMatthew G Knepley 408c688c046SMatthew G Knepley Level: intermediate 409c688c046SMatthew G Knepley 4108f1509bcSBarry Smith Developer Note: Since the Mat class doesn't know about the DM class the DM object is associated with 4118f1509bcSBarry Smith the Mat through a PetscObjectCompose() operation 4128f1509bcSBarry Smith 413c688c046SMatthew G Knepley .seealso: MatSetDM(), DMCreateMatrix(), DMSetMatType() 414c688c046SMatthew G Knepley @*/ 415c688c046SMatthew G Knepley PetscErrorCode MatGetDM(Mat A, DM *dm) 416c688c046SMatthew G Knepley { 417c688c046SMatthew G Knepley PetscErrorCode ierr; 418c688c046SMatthew G Knepley 419c688c046SMatthew G Knepley PetscFunctionBegin; 420c688c046SMatthew G Knepley PetscValidHeaderSpecific(A,MAT_CLASSID,1); 421c688c046SMatthew G Knepley PetscValidPointer(dm,2); 422c688c046SMatthew G Knepley ierr = PetscObjectQuery((PetscObject) A, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr); 423c688c046SMatthew G Knepley PetscFunctionReturn(0); 424c688c046SMatthew G Knepley } 425c688c046SMatthew G Knepley 426c688c046SMatthew G Knepley /*@ 427c688c046SMatthew G Knepley MatSetDM - Sets the DM defining the data layout of the matrix 428c688c046SMatthew G Knepley 429c688c046SMatthew G Knepley Not collective 430c688c046SMatthew G Knepley 431c688c046SMatthew G Knepley Input Parameters: 432c688c046SMatthew G Knepley + A - The Mat 433c688c046SMatthew G Knepley - dm - The DM 434c688c046SMatthew G Knepley 435c688c046SMatthew G Knepley Level: intermediate 436c688c046SMatthew G Knepley 4378f1509bcSBarry Smith Developer Note: Since the Mat class doesn't know about the DM class the DM object is associated with 4388f1509bcSBarry Smith the Mat through a PetscObjectCompose() operation 4398f1509bcSBarry Smith 4408f1509bcSBarry Smith 441c688c046SMatthew G Knepley .seealso: MatGetDM(), DMCreateMatrix(), DMSetMatType() 442c688c046SMatthew G Knepley @*/ 443c688c046SMatthew G Knepley PetscErrorCode MatSetDM(Mat A, DM dm) 444c688c046SMatthew G Knepley { 445c688c046SMatthew G Knepley PetscErrorCode ierr; 446c688c046SMatthew G Knepley 447c688c046SMatthew G Knepley PetscFunctionBegin; 448c688c046SMatthew G Knepley PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4498865f1eaSKarl Rupp if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2); 450c688c046SMatthew G Knepley ierr = PetscObjectCompose((PetscObject) A, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 451c688c046SMatthew G Knepley PetscFunctionReturn(0); 452c688c046SMatthew G Knepley } 453c688c046SMatthew G Knepley 4549a42bb27SBarry Smith /*@C 4559a42bb27SBarry Smith DMSetOptionsPrefix - Sets the prefix used for searching for all 4566757b960SDave May DM options in the database. 4579a42bb27SBarry Smith 458d083f849SBarry Smith Logically Collective on dm 4599a42bb27SBarry Smith 4609a42bb27SBarry Smith Input Parameter: 4618353ddbbSDave May + da - the DM context 4629a42bb27SBarry Smith - prefix - the prefix to prepend to all option names 4639a42bb27SBarry Smith 4649a42bb27SBarry Smith Notes: 4659a42bb27SBarry Smith A hyphen (-) must NOT be given at the beginning of the prefix name. 4669a42bb27SBarry Smith The first character of all runtime options is AUTOMATICALLY the hyphen. 4679a42bb27SBarry Smith 4689a42bb27SBarry Smith Level: advanced 4699a42bb27SBarry Smith 4709a42bb27SBarry Smith .seealso: DMSetFromOptions() 4719a42bb27SBarry Smith @*/ 4727087cfbeSBarry Smith PetscErrorCode DMSetOptionsPrefix(DM dm,const char prefix[]) 4739a42bb27SBarry Smith { 4749a42bb27SBarry Smith PetscErrorCode ierr; 4759a42bb27SBarry Smith 4769a42bb27SBarry Smith PetscFunctionBegin; 4779a42bb27SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4789a42bb27SBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 479691be533SLawrence Mitchell if (dm->sf) { 480691be533SLawrence Mitchell ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->sf,prefix);CHKERRQ(ierr); 481691be533SLawrence Mitchell } 4821bb6d2a8SBarry Smith if (dm->sectionSF) { 4831bb6d2a8SBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->sectionSF,prefix);CHKERRQ(ierr); 484691be533SLawrence Mitchell } 4859a42bb27SBarry Smith PetscFunctionReturn(0); 4869a42bb27SBarry Smith } 4879a42bb27SBarry Smith 48831697293SDave May /*@C 48931697293SDave May DMAppendOptionsPrefix - Appends to the prefix used for searching for all 49031697293SDave May DM options in the database. 49131697293SDave May 492d083f849SBarry Smith Logically Collective on dm 49331697293SDave May 49431697293SDave May Input Parameters: 49531697293SDave May + dm - the DM context 49631697293SDave May - prefix - the prefix string to prepend to all DM option requests 49731697293SDave May 49831697293SDave May Notes: 49931697293SDave May A hyphen (-) must NOT be given at the beginning of the prefix name. 50031697293SDave May The first character of all runtime options is AUTOMATICALLY the hyphen. 50131697293SDave May 50231697293SDave May Level: advanced 50331697293SDave May 50431697293SDave May .seealso: DMSetOptionsPrefix(), DMGetOptionsPrefix() 50531697293SDave May @*/ 50631697293SDave May PetscErrorCode DMAppendOptionsPrefix(DM dm,const char prefix[]) 50731697293SDave May { 50831697293SDave May PetscErrorCode ierr; 50931697293SDave May 51031697293SDave May PetscFunctionBegin; 51131697293SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 51231697293SDave May ierr = PetscObjectAppendOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 51331697293SDave May PetscFunctionReturn(0); 51431697293SDave May } 51531697293SDave May 51631697293SDave May /*@C 51731697293SDave May DMGetOptionsPrefix - Gets the prefix used for searching for all 51831697293SDave May DM options in the database. 51931697293SDave May 52031697293SDave May Not Collective 52131697293SDave May 52231697293SDave May Input Parameters: 52331697293SDave May . dm - the DM context 52431697293SDave May 52531697293SDave May Output Parameters: 52631697293SDave May . prefix - pointer to the prefix string used is returned 52731697293SDave May 52895452b02SPatrick Sanan Notes: 52995452b02SPatrick Sanan On the fortran side, the user should pass in a string 'prefix' of 53031697293SDave May sufficient length to hold the prefix. 53131697293SDave May 53231697293SDave May Level: advanced 53331697293SDave May 53431697293SDave May .seealso: DMSetOptionsPrefix(), DMAppendOptionsPrefix() 53531697293SDave May @*/ 53631697293SDave May PetscErrorCode DMGetOptionsPrefix(DM dm,const char *prefix[]) 53731697293SDave May { 53831697293SDave May PetscErrorCode ierr; 53931697293SDave May 54031697293SDave May PetscFunctionBegin; 54131697293SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 54231697293SDave May ierr = PetscObjectGetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 54331697293SDave May PetscFunctionReturn(0); 54431697293SDave May } 54531697293SDave May 54688bdff64SToby Isaac static PetscErrorCode DMCountNonCyclicReferences(DM dm, PetscBool recurseCoarse, PetscBool recurseFine, PetscInt *ncrefct) 54788bdff64SToby Isaac { 5486eb26441SStefano Zampini PetscInt refct = ((PetscObject) dm)->refct; 54988bdff64SToby Isaac PetscErrorCode ierr; 55088bdff64SToby Isaac 55188bdff64SToby Isaac PetscFunctionBegin; 552aab5bcd8SJed Brown *ncrefct = 0; 55388bdff64SToby Isaac if (dm->coarseMesh && dm->coarseMesh->fineMesh == dm) { 55488bdff64SToby Isaac refct--; 55588bdff64SToby Isaac if (recurseCoarse) { 55688bdff64SToby Isaac PetscInt coarseCount; 55788bdff64SToby Isaac 55888bdff64SToby Isaac ierr = DMCountNonCyclicReferences(dm->coarseMesh, PETSC_TRUE, PETSC_FALSE,&coarseCount);CHKERRQ(ierr); 55988bdff64SToby Isaac refct += coarseCount; 56088bdff64SToby Isaac } 56188bdff64SToby Isaac } 56288bdff64SToby Isaac if (dm->fineMesh && dm->fineMesh->coarseMesh == dm) { 56388bdff64SToby Isaac refct--; 56488bdff64SToby Isaac if (recurseFine) { 56588bdff64SToby Isaac PetscInt fineCount; 56688bdff64SToby Isaac 56788bdff64SToby Isaac ierr = DMCountNonCyclicReferences(dm->fineMesh, PETSC_FALSE, PETSC_TRUE,&fineCount);CHKERRQ(ierr); 56888bdff64SToby Isaac refct += fineCount; 56988bdff64SToby Isaac } 57088bdff64SToby Isaac } 57188bdff64SToby Isaac *ncrefct = refct; 57288bdff64SToby Isaac PetscFunctionReturn(0); 57388bdff64SToby Isaac } 57488bdff64SToby Isaac 575f4cdcedcSVaclav Hapla PetscErrorCode DMDestroyLabelLinkList_Internal(DM dm) 576354557abSToby Isaac { 5775d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 578354557abSToby Isaac PetscErrorCode ierr; 579354557abSToby Isaac 580354557abSToby Isaac PetscFunctionBegin; 581354557abSToby Isaac /* destroy the labels */ 582354557abSToby Isaac while (next) { 583354557abSToby Isaac DMLabelLink tmp = next->next; 584354557abSToby Isaac 5855d80c0bfSVaclav Hapla if (next->label == dm->depthLabel) dm->depthLabel = NULL; 586ba2698f1SMatthew G. Knepley if (next->label == dm->celltypeLabel) dm->celltypeLabel = NULL; 587354557abSToby Isaac ierr = DMLabelDestroy(&next->label);CHKERRQ(ierr); 588354557abSToby Isaac ierr = PetscFree(next);CHKERRQ(ierr); 589354557abSToby Isaac next = tmp; 590354557abSToby Isaac } 5915d80c0bfSVaclav Hapla dm->labels = NULL; 592354557abSToby Isaac PetscFunctionReturn(0); 593354557abSToby Isaac } 594354557abSToby Isaac 5951fb7b255SJunchao Zhang /*@C 5968472ad0fSDave May DMDestroy - Destroys a vector packer or DM. 59747c6ae99SBarry Smith 598d083f849SBarry Smith Collective on dm 59947c6ae99SBarry Smith 60047c6ae99SBarry Smith Input Parameter: 60147c6ae99SBarry Smith . dm - the DM object to destroy 60247c6ae99SBarry Smith 60347c6ae99SBarry Smith Level: developer 60447c6ae99SBarry Smith 605e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 60647c6ae99SBarry Smith 60747c6ae99SBarry Smith @*/ 608fcfd50ebSBarry Smith PetscErrorCode DMDestroy(DM *dm) 60947c6ae99SBarry Smith { 6106eb26441SStefano Zampini PetscInt cnt; 611dfe15315SJed Brown DMNamedVecLink nlink,nnext; 61247c6ae99SBarry Smith PetscErrorCode ierr; 61347c6ae99SBarry Smith 61447c6ae99SBarry Smith PetscFunctionBegin; 6156bf464f9SBarry Smith if (!*dm) PetscFunctionReturn(0); 6166bf464f9SBarry Smith PetscValidHeaderSpecific((*dm),DM_CLASSID,1); 61787e657c6SBarry Smith 61888bdff64SToby Isaac /* count all non-cyclic references in the doubly-linked list of coarse<->fine meshes */ 61988bdff64SToby Isaac ierr = DMCountNonCyclicReferences(*dm,PETSC_TRUE,PETSC_TRUE,&cnt);CHKERRQ(ierr); 62088bdff64SToby Isaac --((PetscObject)(*dm))->refct; 621ea78f98cSLisandro Dalcin if (--cnt > 0) {*dm = NULL; PetscFunctionReturn(0);} 6226bf464f9SBarry Smith if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0); 6236bf464f9SBarry Smith ((PetscObject)(*dm))->refct = 0; 6246eb26441SStefano Zampini 6256eb26441SStefano Zampini ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr); 6266eb26441SStefano Zampini ierr = DMClearLocalVectors(*dm);CHKERRQ(ierr); 6276eb26441SStefano Zampini 628f490541aSPeter Brune nnext=(*dm)->namedglobal; 6290298fd71SBarry Smith (*dm)->namedglobal = NULL; 630f490541aSPeter Brune for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named vectors */ 6312348bcf4SPeter Brune nnext = nlink->next; 6322348bcf4SPeter 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); 6332348bcf4SPeter Brune ierr = PetscFree(nlink->name);CHKERRQ(ierr); 6342348bcf4SPeter Brune ierr = VecDestroy(&nlink->X);CHKERRQ(ierr); 6352348bcf4SPeter Brune ierr = PetscFree(nlink);CHKERRQ(ierr); 6362348bcf4SPeter Brune } 637f490541aSPeter Brune nnext=(*dm)->namedlocal; 6380298fd71SBarry Smith (*dm)->namedlocal = NULL; 639f490541aSPeter Brune for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named local vectors */ 640f490541aSPeter Brune nnext = nlink->next; 641f490541aSPeter 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); 642f490541aSPeter Brune ierr = PetscFree(nlink->name);CHKERRQ(ierr); 643f490541aSPeter Brune ierr = VecDestroy(&nlink->X);CHKERRQ(ierr); 644f490541aSPeter Brune ierr = PetscFree(nlink);CHKERRQ(ierr); 645f490541aSPeter Brune } 6462348bcf4SPeter Brune 647b17ce1afSJed Brown /* Destroy the list of hooks */ 648c833c3b5SJed Brown { 649c833c3b5SJed Brown DMCoarsenHookLink link,next; 650b17ce1afSJed Brown for (link=(*dm)->coarsenhook; link; link=next) { 651b17ce1afSJed Brown next = link->next; 652b17ce1afSJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 653b17ce1afSJed Brown } 6540298fd71SBarry Smith (*dm)->coarsenhook = NULL; 655c833c3b5SJed Brown } 656c833c3b5SJed Brown { 657c833c3b5SJed Brown DMRefineHookLink link,next; 658c833c3b5SJed Brown for (link=(*dm)->refinehook; link; link=next) { 659c833c3b5SJed Brown next = link->next; 660c833c3b5SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 661c833c3b5SJed Brown } 6620298fd71SBarry Smith (*dm)->refinehook = NULL; 663c833c3b5SJed Brown } 664be081cd6SPeter Brune { 665be081cd6SPeter Brune DMSubDomainHookLink link,next; 666be081cd6SPeter Brune for (link=(*dm)->subdomainhook; link; link=next) { 667be081cd6SPeter Brune next = link->next; 668be081cd6SPeter Brune ierr = PetscFree(link);CHKERRQ(ierr); 669be081cd6SPeter Brune } 6700298fd71SBarry Smith (*dm)->subdomainhook = NULL; 671be081cd6SPeter Brune } 672baf369e7SPeter Brune { 673baf369e7SPeter Brune DMGlobalToLocalHookLink link,next; 674baf369e7SPeter Brune for (link=(*dm)->gtolhook; link; link=next) { 675baf369e7SPeter Brune next = link->next; 676baf369e7SPeter Brune ierr = PetscFree(link);CHKERRQ(ierr); 677baf369e7SPeter Brune } 6780298fd71SBarry Smith (*dm)->gtolhook = NULL; 679baf369e7SPeter Brune } 680d4d07f1eSToby Isaac { 681d4d07f1eSToby Isaac DMLocalToGlobalHookLink link,next; 682d4d07f1eSToby Isaac for (link=(*dm)->ltoghook; link; link=next) { 683d4d07f1eSToby Isaac next = link->next; 684d4d07f1eSToby Isaac ierr = PetscFree(link);CHKERRQ(ierr); 685d4d07f1eSToby Isaac } 686d4d07f1eSToby Isaac (*dm)->ltoghook = NULL; 687d4d07f1eSToby Isaac } 688aa1993deSMatthew G Knepley /* Destroy the work arrays */ 689aa1993deSMatthew G Knepley { 690aa1993deSMatthew G Knepley DMWorkLink link,next; 691aa1993deSMatthew G Knepley if ((*dm)->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Work array still checked out"); 692aa1993deSMatthew G Knepley for (link=(*dm)->workin; link; link=next) { 693aa1993deSMatthew G Knepley next = link->next; 694aa1993deSMatthew G Knepley ierr = PetscFree(link->mem);CHKERRQ(ierr); 695aa1993deSMatthew G Knepley ierr = PetscFree(link);CHKERRQ(ierr); 696aa1993deSMatthew G Knepley } 6970298fd71SBarry Smith (*dm)->workin = NULL; 698aa1993deSMatthew G Knepley } 699c58f1c22SToby Isaac /* destroy the labels */ 700f4cdcedcSVaclav Hapla ierr = DMDestroyLabelLinkList_Internal(*dm);CHKERRQ(ierr); 701f4cdcedcSVaclav Hapla /* destroy the fields */ 702e5e52638SMatthew G. Knepley ierr = DMClearFields(*dm);CHKERRQ(ierr); 703f4cdcedcSVaclav Hapla /* destroy the boundaries */ 704e6f8dbb6SToby Isaac { 705e6f8dbb6SToby Isaac DMBoundary next = (*dm)->boundary; 706e6f8dbb6SToby Isaac while (next) { 707e6f8dbb6SToby Isaac DMBoundary b = next; 708e6f8dbb6SToby Isaac 709e6f8dbb6SToby Isaac next = b->next; 710e6f8dbb6SToby Isaac ierr = PetscFree(b);CHKERRQ(ierr); 711e6f8dbb6SToby Isaac } 712e6f8dbb6SToby Isaac } 713b17ce1afSJed Brown 71452536dc3SBarry Smith ierr = PetscObjectDestroy(&(*dm)->dmksp);CHKERRQ(ierr); 71552536dc3SBarry Smith ierr = PetscObjectDestroy(&(*dm)->dmsnes);CHKERRQ(ierr); 71652536dc3SBarry Smith ierr = PetscObjectDestroy(&(*dm)->dmts);CHKERRQ(ierr); 71752536dc3SBarry Smith 7181a266240SBarry Smith if ((*dm)->ctx && (*dm)->ctxdestroy) { 7191a266240SBarry Smith ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr); 7201a266240SBarry Smith } 72171cd77b2SBarry Smith ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr); 7226bf464f9SBarry Smith ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr); 7236bf464f9SBarry Smith ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr); 724073dac72SJed Brown ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr); 72588ed4aceSMatthew G Knepley 7261bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&(*dm)->localSection);CHKERRQ(ierr); 7271bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&(*dm)->globalSection);CHKERRQ(ierr); 7288b1ab98fSJed Brown ierr = PetscLayoutDestroy(&(*dm)->map);CHKERRQ(ierr); 729fba222abSToby Isaac ierr = PetscSectionDestroy(&(*dm)->defaultConstraintSection);CHKERRQ(ierr); 730fba222abSToby Isaac ierr = MatDestroy(&(*dm)->defaultConstraintMat);CHKERRQ(ierr); 73188ed4aceSMatthew G Knepley ierr = PetscSFDestroy(&(*dm)->sf);CHKERRQ(ierr); 7321bb6d2a8SBarry Smith ierr = PetscSFDestroy(&(*dm)->sectionSF);CHKERRQ(ierr); 733736995cdSBlaise Bourdin if ((*dm)->useNatural) { 734736995cdSBlaise Bourdin if ((*dm)->sfNatural) { 7358e4ac7eaSMatthew G. Knepley ierr = PetscSFDestroy(&(*dm)->sfNatural);CHKERRQ(ierr); 736736995cdSBlaise Bourdin } 737736995cdSBlaise Bourdin ierr = PetscObjectDereference((PetscObject) (*dm)->sfMigration);CHKERRQ(ierr); 738736995cdSBlaise Bourdin } 7399a2a23afSMatthew G. Knepley { 7409a2a23afSMatthew G. Knepley Vec *auxData; 7419a2a23afSMatthew G. Knepley PetscInt n, i, off = 0; 7429a2a23afSMatthew G. Knepley 7439a2a23afSMatthew G. Knepley ierr = PetscHMapAuxGetSize((*dm)->auxData, &n);CHKERRQ(ierr); 7449a2a23afSMatthew G. Knepley ierr = PetscMalloc1(n, &auxData);CHKERRQ(ierr); 7459a2a23afSMatthew G. Knepley ierr = PetscHMapAuxGetVals((*dm)->auxData, &off, auxData);CHKERRQ(ierr); 7469a2a23afSMatthew G. Knepley for (i = 0; i < n; ++i) {ierr = VecDestroy(&auxData[i]);CHKERRQ(ierr);} 7479a2a23afSMatthew G. Knepley ierr = PetscFree(auxData);CHKERRQ(ierr); 7489a2a23afSMatthew G. Knepley ierr = PetscHMapAuxDestroy(&(*dm)->auxData);CHKERRQ(ierr); 7499a2a23afSMatthew G. Knepley } 75088bdff64SToby Isaac if ((*dm)->coarseMesh && (*dm)->coarseMesh->fineMesh == *dm) { 75188bdff64SToby Isaac ierr = DMSetFineDM((*dm)->coarseMesh,NULL);CHKERRQ(ierr); 75288bdff64SToby Isaac } 7536eb26441SStefano Zampini 754a8fb8f29SToby Isaac ierr = DMDestroy(&(*dm)->coarseMesh);CHKERRQ(ierr); 75588bdff64SToby Isaac if ((*dm)->fineMesh && (*dm)->fineMesh->coarseMesh == *dm) { 75688bdff64SToby Isaac ierr = DMSetCoarseDM((*dm)->fineMesh,NULL);CHKERRQ(ierr); 75788bdff64SToby Isaac } 75888bdff64SToby Isaac ierr = DMDestroy(&(*dm)->fineMesh);CHKERRQ(ierr); 759f19dbd58SToby Isaac ierr = DMFieldDestroy(&(*dm)->coordinateField);CHKERRQ(ierr); 7606636e97aSMatthew G Knepley ierr = DMDestroy(&(*dm)->coordinateDM);CHKERRQ(ierr); 7616636e97aSMatthew G Knepley ierr = VecDestroy(&(*dm)->coordinates);CHKERRQ(ierr); 7626636e97aSMatthew G Knepley ierr = VecDestroy(&(*dm)->coordinatesLocal);CHKERRQ(ierr); 763412e9a14SMatthew G. Knepley ierr = PetscFree((*dm)->L);CHKERRQ(ierr); 764412e9a14SMatthew G. Knepley ierr = PetscFree((*dm)->maxCell);CHKERRQ(ierr); 765412e9a14SMatthew G. Knepley ierr = PetscFree((*dm)->bdtype);CHKERRQ(ierr); 766ca3d3a14SMatthew G. Knepley if ((*dm)->transformDestroy) {ierr = (*(*dm)->transformDestroy)(*dm, (*dm)->transformCtx);CHKERRQ(ierr);} 767ca3d3a14SMatthew G. Knepley ierr = DMDestroy(&(*dm)->transformDM);CHKERRQ(ierr); 768ca3d3a14SMatthew G. Knepley ierr = VecDestroy(&(*dm)->transform);CHKERRQ(ierr); 7696636e97aSMatthew G Knepley 770e5e52638SMatthew G. Knepley ierr = DMClearDS(*dm);CHKERRQ(ierr); 77114f150ffSMatthew G. Knepley ierr = DMDestroy(&(*dm)->dmBC);CHKERRQ(ierr); 772e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 773e04113cfSBarry Smith ierr = PetscObjectSAWsViewOff((PetscObject)*dm);CHKERRQ(ierr); 774732e2eb9SMatthew G Knepley 775ed3c66a1SDave May if ((*dm)->ops->destroy) { 7766bf464f9SBarry Smith ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr); 777ed3c66a1SDave May } 778c0f0dcc3SMatthew G. Knepley ierr = DMMonitorCancel(*dm);CHKERRQ(ierr); 779435a35e8SMatthew G Knepley /* We do not destroy (*dm)->data here so that we can reference count backend objects */ 780732e2eb9SMatthew G Knepley ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr); 78147c6ae99SBarry Smith PetscFunctionReturn(0); 78247c6ae99SBarry Smith } 78347c6ae99SBarry Smith 784d7bf68aeSBarry Smith /*@ 785d7bf68aeSBarry Smith DMSetUp - sets up the data structures inside a DM object 786d7bf68aeSBarry Smith 787d083f849SBarry Smith Collective on dm 788d7bf68aeSBarry Smith 789d7bf68aeSBarry Smith Input Parameter: 790d7bf68aeSBarry Smith . dm - the DM object to setup 791d7bf68aeSBarry Smith 792d7bf68aeSBarry Smith Level: developer 793d7bf68aeSBarry Smith 794e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 795d7bf68aeSBarry Smith 796d7bf68aeSBarry Smith @*/ 7977087cfbeSBarry Smith PetscErrorCode DMSetUp(DM dm) 798d7bf68aeSBarry Smith { 799d7bf68aeSBarry Smith PetscErrorCode ierr; 800d7bf68aeSBarry Smith 801d7bf68aeSBarry Smith PetscFunctionBegin; 802171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8038387afaaSJed Brown if (dm->setupcalled) PetscFunctionReturn(0); 804d7bf68aeSBarry Smith if (dm->ops->setup) { 805d7bf68aeSBarry Smith ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr); 806d7bf68aeSBarry Smith } 8078387afaaSJed Brown dm->setupcalled = PETSC_TRUE; 808d7bf68aeSBarry Smith PetscFunctionReturn(0); 809d7bf68aeSBarry Smith } 810d7bf68aeSBarry Smith 811d7bf68aeSBarry Smith /*@ 812d7bf68aeSBarry Smith DMSetFromOptions - sets parameters in a DM from the options database 813d7bf68aeSBarry Smith 814d083f849SBarry Smith Collective on dm 815d7bf68aeSBarry Smith 816d7bf68aeSBarry Smith Input Parameter: 817d7bf68aeSBarry Smith . dm - the DM object to set options for 818d7bf68aeSBarry Smith 819732e2eb9SMatthew G Knepley Options Database: 8204164ae61SDominic Meiser + -dm_preallocate_only - Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros 8214164ae61SDominic Meiser . -dm_vec_type <type> - type of vector to create inside DM 8224164ae61SDominic Meiser . -dm_mat_type <type> - type of matrix to create inside DM 8238f1509bcSBarry Smith - -dm_is_coloring_type - <global or local> 824732e2eb9SMatthew G Knepley 825384a6580SVaclav Hapla DMPLEX Specific Checks 826384a6580SVaclav Hapla + -dm_plex_check_symmetry - Check that the adjacency information in the mesh is symmetric - DMPlexCheckSymmetry() 827384a6580SVaclav Hapla . -dm_plex_check_skeleton - Check that each cell has the correct number of vertices (only for homogeneous simplex or tensor meshes) - DMPlexCheckSkeleton() 828384a6580SVaclav 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() 829384a6580SVaclav Hapla . -dm_plex_check_geometry - Check that cells have positive volume - DMPlexCheckGeometry() 830384a6580SVaclav Hapla . -dm_plex_check_pointsf - Check some necessary conditions for PointSF - DMPlexCheckPointSF() 831384a6580SVaclav Hapla . -dm_plex_check_interface_cones - Check points on inter-partition interfaces have conforming order of cone points - DMPlexCheckInterfaceCones() 832384a6580SVaclav Hapla - -dm_plex_check_all - Perform all the checks above 833d7bf68aeSBarry Smith 83495eb5ee5SVaclav Hapla Level: intermediate 83595eb5ee5SVaclav Hapla 83695eb5ee5SVaclav Hapla .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), 83795eb5ee5SVaclav Hapla DMPlexCheckSymmetry(), DMPlexCheckSkeleton(), DMPlexCheckFaces(), DMPlexCheckGeometry(), DMPlexCheckPointSF(), DMPlexCheckInterfaceCones() 838d7bf68aeSBarry Smith 839d7bf68aeSBarry Smith @*/ 8407087cfbeSBarry Smith PetscErrorCode DMSetFromOptions(DM dm) 841d7bf68aeSBarry Smith { 8427781c08eSBarry Smith char typeName[256]; 843ca266f36SBarry Smith PetscBool flg; 844d7bf68aeSBarry Smith PetscErrorCode ierr; 845d7bf68aeSBarry Smith 846d7bf68aeSBarry Smith PetscFunctionBegin; 847171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 84849be4549SMatthew G. Knepley dm->setfromoptionscalled = PETSC_TRUE; 84949be4549SMatthew G. Knepley if (dm->sf) {ierr = PetscSFSetFromOptions(dm->sf);CHKERRQ(ierr);} 8501bb6d2a8SBarry Smith if (dm->sectionSF) {ierr = PetscSFSetFromOptions(dm->sectionSF);CHKERRQ(ierr);} 8513194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr); 8520298fd71SBarry 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); 853a264d7a6SBarry Smith ierr = PetscOptionsFList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr); 854f9ba7244SBarry Smith if (flg) { 855f9ba7244SBarry Smith ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr); 856f9ba7244SBarry Smith } 857a264d7a6SBarry 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); 858073dac72SJed Brown if (flg) { 859521d9a4cSLisandro Dalcin ierr = DMSetMatType(dm,typeName);CHKERRQ(ierr); 860073dac72SJed Brown } 8618f1509bcSBarry Smith ierr = PetscOptionsEnum("-dm_is_coloring_type","Global or local coloring of Jacobian","DMSetISColoringType",ISColoringTypes,(PetscEnum)dm->coloringtype,(PetscEnum*)&dm->coloringtype,NULL);CHKERRQ(ierr); 862f9ba7244SBarry Smith if (dm->ops->setfromoptions) { 863e55864a3SBarry Smith ierr = (*dm->ops->setfromoptions)(PetscOptionsObject,dm);CHKERRQ(ierr); 864f9ba7244SBarry Smith } 865f9ba7244SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 8660633abcbSJed Brown ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) dm);CHKERRQ(ierr); 86782fcb398SMatthew G Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 868d7bf68aeSBarry Smith PetscFunctionReturn(0); 869d7bf68aeSBarry Smith } 870d7bf68aeSBarry Smith 871fc9bc008SSatish Balay /*@C 872fe2efc57SMark DMViewFromOptions - View from Options 873fe2efc57SMark 874fe2efc57SMark Collective on DM 875fe2efc57SMark 876fe2efc57SMark Input Parameters: 877fe2efc57SMark + dm - the DM object 878736c3998SJose E. Roman . obj - Optional object 879736c3998SJose E. Roman - name - command line option 880fe2efc57SMark 881fe2efc57SMark Level: intermediate 882fe2efc57SMark .seealso: DM, DMView, PetscObjectViewFromOptions(), DMCreate() 883fe2efc57SMark @*/ 884fe2efc57SMark PetscErrorCode DMViewFromOptions(DM dm,PetscObject obj,const char name[]) 885fe2efc57SMark { 886fe2efc57SMark PetscErrorCode ierr; 887fe2efc57SMark 888fe2efc57SMark PetscFunctionBegin; 889fe2efc57SMark PetscValidHeaderSpecific(dm,DM_CLASSID,1); 890fe2efc57SMark ierr = PetscObjectViewFromOptions((PetscObject)dm,obj,name);CHKERRQ(ierr); 891fe2efc57SMark PetscFunctionReturn(0); 892fe2efc57SMark } 893fe2efc57SMark 894fe2efc57SMark /*@C 895224748a4SBarry Smith DMView - Views a DM 89647c6ae99SBarry Smith 897d083f849SBarry Smith Collective on dm 89847c6ae99SBarry Smith 89947c6ae99SBarry Smith Input Parameter: 90047c6ae99SBarry Smith + dm - the DM object to view 90147c6ae99SBarry Smith - v - the viewer 90247c6ae99SBarry Smith 903224748a4SBarry Smith Level: beginner 90447c6ae99SBarry Smith 905e727c939SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 90647c6ae99SBarry Smith 90747c6ae99SBarry Smith @*/ 9087087cfbeSBarry Smith PetscErrorCode DMView(DM dm,PetscViewer v) 90947c6ae99SBarry Smith { 91047c6ae99SBarry Smith PetscErrorCode ierr; 91132c0f0efSBarry Smith PetscBool isbinary; 91276a8abe0SBarry Smith PetscMPIInt size; 91376a8abe0SBarry Smith PetscViewerFormat format; 91447c6ae99SBarry Smith 91547c6ae99SBarry Smith PetscFunctionBegin; 916171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 9173014e516SBarry Smith if (!v) { 918ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)dm),&v);CHKERRQ(ierr); 9193014e516SBarry Smith } 920b1b135c8SBarry Smith PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,2); 92174903a4fSStefano Zampini /* Ideally, we would like to have this test on. 92274903a4fSStefano Zampini However, it currently breaks socket viz via GLVis. 92374903a4fSStefano Zampini During DMView(parallel_mesh,glvis_viewer), each 92474903a4fSStefano Zampini process opens a sequential ASCII socket to visualize 92574903a4fSStefano Zampini the local mesh, and PetscObjectView(dm,local_socket) 92674903a4fSStefano Zampini is internally called inside VecView_GLVis, incurring 92774903a4fSStefano Zampini in an error here */ 92874903a4fSStefano Zampini /* PetscCheckSameComm(dm,1,v,2); */ 9298bfd1ab9SVaclav Hapla ierr = PetscViewerCheckWritable(v);CHKERRQ(ierr); 930b1b135c8SBarry Smith 93176a8abe0SBarry Smith ierr = PetscViewerGetFormat(v,&format);CHKERRQ(ierr); 932ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&size);CHKERRMPI(ierr); 93376a8abe0SBarry Smith if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 93498c3331eSBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)dm,v);CHKERRQ(ierr); 93532c0f0efSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 93632c0f0efSBarry Smith if (isbinary) { 93755849f57SBarry Smith PetscInt classid = DM_FILE_CLASSID; 93832c0f0efSBarry Smith char type[256]; 93932c0f0efSBarry Smith 940f253e43cSLisandro Dalcin ierr = PetscViewerBinaryWrite(v,&classid,1,PETSC_INT);CHKERRQ(ierr); 94132c0f0efSBarry Smith ierr = PetscStrncpy(type,((PetscObject)dm)->type_name,256);CHKERRQ(ierr); 942f253e43cSLisandro Dalcin ierr = PetscViewerBinaryWrite(v,type,256,PETSC_CHAR);CHKERRQ(ierr); 94332c0f0efSBarry Smith } 9440c010503SBarry Smith if (dm->ops->view) { 9450c010503SBarry Smith ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr); 94647c6ae99SBarry Smith } 94747c6ae99SBarry Smith PetscFunctionReturn(0); 94847c6ae99SBarry Smith } 94947c6ae99SBarry Smith 95047c6ae99SBarry Smith /*@ 9518472ad0fSDave May DMCreateGlobalVector - Creates a global vector from a DM object 95247c6ae99SBarry Smith 953d083f849SBarry Smith Collective on dm 95447c6ae99SBarry Smith 95547c6ae99SBarry Smith Input Parameter: 95647c6ae99SBarry Smith . dm - the DM object 95747c6ae99SBarry Smith 95847c6ae99SBarry Smith Output Parameter: 95947c6ae99SBarry Smith . vec - the global vector 96047c6ae99SBarry Smith 961073dac72SJed Brown Level: beginner 96247c6ae99SBarry Smith 963ec075b9fSPatrick Sanan .seealso DMCreateLocalVector(), DMGetGlobalVector(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 96447c6ae99SBarry Smith 96547c6ae99SBarry Smith @*/ 9667087cfbeSBarry Smith PetscErrorCode DMCreateGlobalVector(DM dm,Vec *vec) 96747c6ae99SBarry Smith { 96847c6ae99SBarry Smith PetscErrorCode ierr; 96947c6ae99SBarry Smith 97047c6ae99SBarry Smith PetscFunctionBegin; 971171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 972b9d85ea2SLisandro Dalcin PetscValidPointer(vec,2); 973b9d85ea2SLisandro Dalcin if (!dm->ops->createglobalvector) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateGlobalVector",((PetscObject)dm)->type_name); 97447c6ae99SBarry Smith ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr); 97576bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 976c6b011d8SStefano Zampini DM vdm; 977c6b011d8SStefano Zampini 978c6b011d8SStefano Zampini ierr = VecGetDM(*vec,&vdm);CHKERRQ(ierr); 979c6b011d8SStefano 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); 980c6b011d8SStefano Zampini } 98147c6ae99SBarry Smith PetscFunctionReturn(0); 98247c6ae99SBarry Smith } 98347c6ae99SBarry Smith 98447c6ae99SBarry Smith /*@ 9858472ad0fSDave May DMCreateLocalVector - Creates a local vector from a DM object 98647c6ae99SBarry Smith 98747c6ae99SBarry Smith Not Collective 98847c6ae99SBarry Smith 98947c6ae99SBarry Smith Input Parameter: 99047c6ae99SBarry Smith . dm - the DM object 99147c6ae99SBarry Smith 99247c6ae99SBarry Smith Output Parameter: 99347c6ae99SBarry Smith . vec - the local vector 99447c6ae99SBarry Smith 995073dac72SJed Brown Level: beginner 99647c6ae99SBarry Smith 997ec075b9fSPatrick Sanan .seealso DMCreateGlobalVector(), DMGetLocalVector(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 99847c6ae99SBarry Smith 99947c6ae99SBarry Smith @*/ 10007087cfbeSBarry Smith PetscErrorCode DMCreateLocalVector(DM dm,Vec *vec) 100147c6ae99SBarry Smith { 100247c6ae99SBarry Smith PetscErrorCode ierr; 100347c6ae99SBarry Smith 100447c6ae99SBarry Smith PetscFunctionBegin; 1005171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1006b9d85ea2SLisandro Dalcin PetscValidPointer(vec,2); 1007b9d85ea2SLisandro Dalcin if (!dm->ops->createlocalvector) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateLocalVector",((PetscObject)dm)->type_name); 100847c6ae99SBarry Smith ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr); 100976bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1010c6b011d8SStefano Zampini DM vdm; 1011c6b011d8SStefano Zampini 1012c6b011d8SStefano Zampini ierr = VecGetDM(*vec,&vdm);CHKERRQ(ierr); 1013c6b011d8SStefano 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); 1014c6b011d8SStefano Zampini } 101547c6ae99SBarry Smith PetscFunctionReturn(0); 101647c6ae99SBarry Smith } 101747c6ae99SBarry Smith 10181411c6eeSJed Brown /*@ 10191411c6eeSJed Brown DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM. 10201411c6eeSJed Brown 1021d083f849SBarry Smith Collective on dm 10221411c6eeSJed Brown 10231411c6eeSJed Brown Input Parameter: 10241411c6eeSJed Brown . dm - the DM that provides the mapping 10251411c6eeSJed Brown 10261411c6eeSJed Brown Output Parameter: 10271411c6eeSJed Brown . ltog - the mapping 10281411c6eeSJed Brown 10291411c6eeSJed Brown Level: intermediate 10301411c6eeSJed Brown 10311411c6eeSJed Brown Notes: 10321411c6eeSJed Brown This mapping can then be used by VecSetLocalToGlobalMapping() or 10331411c6eeSJed Brown MatSetLocalToGlobalMapping(). 10341411c6eeSJed Brown 1035fc31e74dSBarry Smith .seealso: DMCreateLocalVector() 10361411c6eeSJed Brown @*/ 10377087cfbeSBarry Smith PetscErrorCode DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog) 10381411c6eeSJed Brown { 10390be3e97aSMatthew G. Knepley PetscInt bs = -1, bsLocal[2], bsMinMax[2]; 10401411c6eeSJed Brown PetscErrorCode ierr; 10411411c6eeSJed Brown 10421411c6eeSJed Brown PetscFunctionBegin; 10431411c6eeSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 10441411c6eeSJed Brown PetscValidPointer(ltog,2); 10451411c6eeSJed Brown if (!dm->ltogmap) { 104637d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 104737d0c07bSMatthew G Knepley 104892fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 104937d0c07bSMatthew G Knepley if (section) { 1050a974ec88SMatthew G. Knepley const PetscInt *cdofs; 105137d0c07bSMatthew G Knepley PetscInt *ltog; 1052ccf3bd66SMatthew G. Knepley PetscInt pStart, pEnd, n, p, k, l; 105337d0c07bSMatthew G Knepley 1054e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 105537d0c07bSMatthew G Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 1056ccf3bd66SMatthew G. Knepley ierr = PetscSectionGetStorageSize(section, &n);CHKERRQ(ierr); 1057ccf3bd66SMatthew G. Knepley ierr = PetscMalloc1(n, <og);CHKERRQ(ierr); /* We want the local+overlap size */ 105837d0c07bSMatthew G Knepley for (p = pStart, l = 0; p < pEnd; ++p) { 1059a974ec88SMatthew G. Knepley PetscInt bdof, cdof, dof, off, c, cind = 0; 106037d0c07bSMatthew G Knepley 106137d0c07bSMatthew G Knepley /* Should probably use constrained dofs */ 106237d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 1063a974ec88SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr); 1064a974ec88SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, p, &cdofs);CHKERRQ(ierr); 106537d0c07bSMatthew G Knepley ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr); 10661a7dc684SMatthew G. Knepley /* If you have dofs, and constraints, and they are unequal, we set the blocksize to 1 */ 10671a7dc684SMatthew G. Knepley bdof = cdof && (dof-cdof) ? 1 : dof; 10681a7dc684SMatthew G. Knepley if (dof) { 1069b190aa46SMatthew G. Knepley if (bs < 0) {bs = bdof;} 1070b190aa46SMatthew G. Knepley else if (bs != bdof) {bs = 1;} 10711a7dc684SMatthew G. Knepley } 107237d0c07bSMatthew G Knepley for (c = 0; c < dof; ++c, ++l) { 1073a974ec88SMatthew G. Knepley if ((cind < cdof) && (c == cdofs[cind])) ltog[l] = off < 0 ? off-c : off+c; 1074a974ec88SMatthew G. Knepley else ltog[l] = (off < 0 ? -(off+1) : off) + c; 107537d0c07bSMatthew G Knepley } 107637d0c07bSMatthew G Knepley } 1077bff27382SMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 10780be3e97aSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 10790be3e97aSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 10800be3e97aSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 10810be3e97aSMatthew G. Knepley else {bs = bsMinMax[0];} 10827591dbb2SMatthew G. Knepley bs = bs < 0 ? 1 : bs; 10837591dbb2SMatthew G. Knepley /* Must reduce indices by blocksize */ 1084ccf3bd66SMatthew G. Knepley if (bs > 1) { 1085ccf3bd66SMatthew G. Knepley for (l = 0, k = 0; l < n; l += bs, ++k) ltog[k] = ltog[l]/bs; 1086ccf3bd66SMatthew G. Knepley n /= bs; 1087ccf3bd66SMatthew G. Knepley } 1088ccf3bd66SMatthew G. Knepley ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, n, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr); 10893bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)dm, (PetscObject)dm->ltogmap);CHKERRQ(ierr); 109037d0c07bSMatthew G Knepley } else { 1091b9d85ea2SLisandro Dalcin if (!dm->ops->getlocaltoglobalmapping) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMGetLocalToGlobalMapping",((PetscObject)dm)->type_name); 1092184d77edSJed Brown ierr = (*dm->ops->getlocaltoglobalmapping)(dm);CHKERRQ(ierr); 10931411c6eeSJed Brown } 109437d0c07bSMatthew G Knepley } 10951411c6eeSJed Brown *ltog = dm->ltogmap; 10961411c6eeSJed Brown PetscFunctionReturn(0); 10971411c6eeSJed Brown } 10981411c6eeSJed Brown 10991411c6eeSJed Brown /*@ 11001411c6eeSJed Brown DMGetBlockSize - Gets the inherent block size associated with a DM 11011411c6eeSJed Brown 11021411c6eeSJed Brown Not Collective 11031411c6eeSJed Brown 11041411c6eeSJed Brown Input Parameter: 11051411c6eeSJed Brown . dm - the DM with block structure 11061411c6eeSJed Brown 11071411c6eeSJed Brown Output Parameter: 11081411c6eeSJed Brown . bs - the block size, 1 implies no exploitable block structure 11091411c6eeSJed Brown 11101411c6eeSJed Brown Level: intermediate 11111411c6eeSJed Brown 1112fc31e74dSBarry Smith .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMapping() 11131411c6eeSJed Brown @*/ 11147087cfbeSBarry Smith PetscErrorCode DMGetBlockSize(DM dm,PetscInt *bs) 11151411c6eeSJed Brown { 11161411c6eeSJed Brown PetscFunctionBegin; 11171411c6eeSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1118534a8f05SLisandro Dalcin PetscValidIntPointer(bs,2); 11191411c6eeSJed 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"); 11201411c6eeSJed Brown *bs = dm->bs; 11211411c6eeSJed Brown PetscFunctionReturn(0); 11221411c6eeSJed Brown } 11231411c6eeSJed Brown 112448eeb7c8SBarry Smith /*@C 11258472ad0fSDave May DMCreateInterpolation - Gets interpolation matrix between two DM objects 112647c6ae99SBarry Smith 1127a5bc1bf3SBarry Smith Collective on dmc 112847c6ae99SBarry Smith 112947c6ae99SBarry Smith Input Parameter: 1130a5bc1bf3SBarry Smith + dmc - the DM object 1131a5bc1bf3SBarry Smith - dmf - the second, finer DM object 113247c6ae99SBarry Smith 113347c6ae99SBarry Smith Output Parameter: 113447c6ae99SBarry Smith + mat - the interpolation 113547c6ae99SBarry Smith - vec - the scaling (optional) 113647c6ae99SBarry Smith 113747c6ae99SBarry Smith Level: developer 113847c6ae99SBarry Smith 113995452b02SPatrick Sanan Notes: 114095452b02SPatrick 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 114185afcc9aSBarry Smith DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation. 1142d52bd9f3SBarry Smith 11431f588964SMatthew G Knepley For DMDA objects you can use this interpolation (more precisely the interpolation from the DMGetCoordinateDM()) to interpolate the mesh coordinate vectors 1144d52bd9f3SBarry Smith EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic. 114585afcc9aSBarry Smith 114685afcc9aSBarry Smith 11472ed6491fSPatrick Sanan .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateRestriction(), DMCreateInterpolationScale() 114847c6ae99SBarry Smith 114947c6ae99SBarry Smith @*/ 1150a5bc1bf3SBarry Smith PetscErrorCode DMCreateInterpolation(DM dmc,DM dmf,Mat *mat,Vec *vec) 115147c6ae99SBarry Smith { 115247c6ae99SBarry Smith PetscErrorCode ierr; 115347c6ae99SBarry Smith 115447c6ae99SBarry Smith PetscFunctionBegin; 1155a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 1156a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf,DM_CLASSID,2); 1157c7d20fa0SStefano Zampini PetscValidPointer(mat,3); 1158a5bc1bf3SBarry Smith if (!dmc->ops->createinterpolation) SETERRQ1(PetscObjectComm((PetscObject)dmc),PETSC_ERR_SUP,"DM type %s does not implement DMCreateInterpolation",((PetscObject)dmc)->type_name); 1159a5bc1bf3SBarry Smith ierr = PetscLogEventBegin(DM_CreateInterpolation,dmc,dmf,0,0);CHKERRQ(ierr); 1160a5bc1bf3SBarry Smith ierr = (*dmc->ops->createinterpolation)(dmc,dmf,mat,vec);CHKERRQ(ierr); 1161a5bc1bf3SBarry Smith ierr = PetscLogEventEnd(DM_CreateInterpolation,dmc,dmf,0,0);CHKERRQ(ierr); 116247c6ae99SBarry Smith PetscFunctionReturn(0); 116347c6ae99SBarry Smith } 116447c6ae99SBarry Smith 11653ad4599aSBarry Smith /*@ 1166d3e313eaSPatrick Sanan DMCreateInterpolationScale - Forms L = 1/(R*1) such that diag(L)*R preserves scale and is thus suitable for state (versus residual) restriction. 11672ed6491fSPatrick Sanan 11682ed6491fSPatrick Sanan Input Parameters: 11692ed6491fSPatrick Sanan + dac - DM that defines a coarse mesh 11702ed6491fSPatrick Sanan . daf - DM that defines a fine mesh 11712ed6491fSPatrick Sanan - mat - the restriction (or interpolation operator) from fine to coarse 11722ed6491fSPatrick Sanan 11732ed6491fSPatrick Sanan Output Parameter: 11742ed6491fSPatrick Sanan . scale - the scaled vector 11752ed6491fSPatrick Sanan 11762ed6491fSPatrick Sanan Level: developer 11772ed6491fSPatrick Sanan 11782ed6491fSPatrick Sanan .seealso: DMCreateInterpolation() 11792ed6491fSPatrick Sanan 11802ed6491fSPatrick Sanan @*/ 11812ed6491fSPatrick Sanan PetscErrorCode DMCreateInterpolationScale(DM dac,DM daf,Mat mat,Vec *scale) 11822ed6491fSPatrick Sanan { 11832ed6491fSPatrick Sanan PetscErrorCode ierr; 11842ed6491fSPatrick Sanan Vec fine; 11852ed6491fSPatrick Sanan PetscScalar one = 1.0; 11862ed6491fSPatrick Sanan 11872ed6491fSPatrick Sanan PetscFunctionBegin; 11882ed6491fSPatrick Sanan ierr = DMCreateGlobalVector(daf,&fine);CHKERRQ(ierr); 11892ed6491fSPatrick Sanan ierr = DMCreateGlobalVector(dac,scale);CHKERRQ(ierr); 11902ed6491fSPatrick Sanan ierr = VecSet(fine,one);CHKERRQ(ierr); 11912ed6491fSPatrick Sanan ierr = MatRestrict(mat,fine,*scale);CHKERRQ(ierr); 11922ed6491fSPatrick Sanan ierr = VecDestroy(&fine);CHKERRQ(ierr); 11932ed6491fSPatrick Sanan ierr = VecReciprocal(*scale);CHKERRQ(ierr); 11942ed6491fSPatrick Sanan PetscFunctionReturn(0); 11952ed6491fSPatrick Sanan } 11962ed6491fSPatrick Sanan 11972ed6491fSPatrick Sanan /*@ 11983ad4599aSBarry Smith DMCreateRestriction - Gets restriction matrix between two DM objects 11993ad4599aSBarry Smith 1200a5bc1bf3SBarry Smith Collective on dmc 12013ad4599aSBarry Smith 12023ad4599aSBarry Smith Input Parameter: 1203a5bc1bf3SBarry Smith + dmc - the DM object 1204a5bc1bf3SBarry Smith - dmf - the second, finer DM object 12053ad4599aSBarry Smith 12063ad4599aSBarry Smith Output Parameter: 12073ad4599aSBarry Smith . mat - the restriction 12083ad4599aSBarry Smith 12093ad4599aSBarry Smith 12103ad4599aSBarry Smith Level: developer 12113ad4599aSBarry Smith 121295452b02SPatrick Sanan Notes: 121395452b02SPatrick 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 12143ad4599aSBarry Smith DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation. 12153ad4599aSBarry Smith 12163ad4599aSBarry Smith 12173ad4599aSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateInterpolation() 12183ad4599aSBarry Smith 12193ad4599aSBarry Smith @*/ 1220a5bc1bf3SBarry Smith PetscErrorCode DMCreateRestriction(DM dmc,DM dmf,Mat *mat) 12213ad4599aSBarry Smith { 12223ad4599aSBarry Smith PetscErrorCode ierr; 12233ad4599aSBarry Smith 12243ad4599aSBarry Smith PetscFunctionBegin; 1225a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 1226a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf,DM_CLASSID,2); 12275a84ad33SLisandro Dalcin PetscValidPointer(mat,3); 1228a5bc1bf3SBarry Smith if (!dmc->ops->createrestriction) SETERRQ1(PetscObjectComm((PetscObject)dmc),PETSC_ERR_SUP,"DM type %s does not implement DMCreateRestriction",((PetscObject)dmc)->type_name); 1229a5bc1bf3SBarry Smith ierr = PetscLogEventBegin(DM_CreateRestriction,dmc,dmf,0,0);CHKERRQ(ierr); 1230a5bc1bf3SBarry Smith ierr = (*dmc->ops->createrestriction)(dmc,dmf,mat);CHKERRQ(ierr); 1231a5bc1bf3SBarry Smith ierr = PetscLogEventEnd(DM_CreateRestriction,dmc,dmf,0,0);CHKERRQ(ierr); 12323ad4599aSBarry Smith PetscFunctionReturn(0); 12333ad4599aSBarry Smith } 12343ad4599aSBarry Smith 123547c6ae99SBarry Smith /*@ 12368472ad0fSDave May DMCreateInjection - Gets injection matrix between two DM objects 123747c6ae99SBarry Smith 1238a5bc1bf3SBarry Smith Collective on dac 123947c6ae99SBarry Smith 124047c6ae99SBarry Smith Input Parameter: 1241a5bc1bf3SBarry Smith + dac - the DM object 1242a5bc1bf3SBarry Smith - daf - the second, finer DM object 124347c6ae99SBarry Smith 124447c6ae99SBarry Smith Output Parameter: 12456dbf9973SLawrence Mitchell . mat - the injection 124647c6ae99SBarry Smith 124747c6ae99SBarry Smith Level: developer 124847c6ae99SBarry Smith 124995452b02SPatrick Sanan Notes: 125095452b02SPatrick 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 125185afcc9aSBarry Smith DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection. 125285afcc9aSBarry Smith 1253e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation() 125447c6ae99SBarry Smith 125547c6ae99SBarry Smith @*/ 1256a5bc1bf3SBarry Smith PetscErrorCode DMCreateInjection(DM dac,DM daf,Mat *mat) 125747c6ae99SBarry Smith { 125847c6ae99SBarry Smith PetscErrorCode ierr; 125947c6ae99SBarry Smith 126047c6ae99SBarry Smith PetscFunctionBegin; 1261a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dac,DM_CLASSID,1); 1262a5bc1bf3SBarry Smith PetscValidHeaderSpecific(daf,DM_CLASSID,2); 12635a84ad33SLisandro Dalcin PetscValidPointer(mat,3); 1264a5bc1bf3SBarry Smith if (!dac->ops->createinjection) SETERRQ1(PetscObjectComm((PetscObject)dac),PETSC_ERR_SUP,"DM type %s does not implement DMCreateInjection",((PetscObject)dac)->type_name); 1265a5bc1bf3SBarry Smith ierr = PetscLogEventBegin(DM_CreateInjection,dac,daf,0,0);CHKERRQ(ierr); 1266a5bc1bf3SBarry Smith ierr = (*dac->ops->createinjection)(dac,daf,mat);CHKERRQ(ierr); 1267a5bc1bf3SBarry Smith ierr = PetscLogEventEnd(DM_CreateInjection,dac,daf,0,0);CHKERRQ(ierr); 126847c6ae99SBarry Smith PetscFunctionReturn(0); 126947c6ae99SBarry Smith } 127047c6ae99SBarry Smith 1271b412c318SBarry Smith /*@ 1272bd041c0cSMatthew G. Knepley DMCreateMassMatrix - Gets mass matrix between two DM objects, M_ij = \int \phi_i \psi_j 1273bd041c0cSMatthew G. Knepley 1274a5bc1bf3SBarry Smith Collective on dac 1275bd041c0cSMatthew G. Knepley 1276bd041c0cSMatthew G. Knepley Input Parameter: 1277a5bc1bf3SBarry Smith + dac - the DM object 1278a5bc1bf3SBarry Smith - daf - the second, finer DM object 1279bd041c0cSMatthew G. Knepley 1280bd041c0cSMatthew G. Knepley Output Parameter: 1281bd041c0cSMatthew G. Knepley . mat - the interpolation 1282bd041c0cSMatthew G. Knepley 1283bd041c0cSMatthew G. Knepley Level: developer 1284bd041c0cSMatthew G. Knepley 1285bd041c0cSMatthew G. Knepley .seealso DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateRestriction(), DMCreateInterpolation(), DMCreateInjection() 1286bd041c0cSMatthew G. Knepley @*/ 1287a5bc1bf3SBarry Smith PetscErrorCode DMCreateMassMatrix(DM dac, DM daf, Mat *mat) 1288bd041c0cSMatthew G. Knepley { 1289bd041c0cSMatthew G. Knepley PetscErrorCode ierr; 1290bd041c0cSMatthew G. Knepley 1291bd041c0cSMatthew G. Knepley PetscFunctionBegin; 1292a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dac, DM_CLASSID, 1); 1293a5bc1bf3SBarry Smith PetscValidHeaderSpecific(daf, DM_CLASSID, 2); 12945a84ad33SLisandro Dalcin PetscValidPointer(mat,3); 1295a5bc1bf3SBarry Smith if (!dac->ops->createmassmatrix) SETERRQ1(PetscObjectComm((PetscObject)dac),PETSC_ERR_SUP,"DM type %s does not implement DMCreateMassMatrix",((PetscObject)dac)->type_name); 1296a5bc1bf3SBarry Smith ierr = (*dac->ops->createmassmatrix)(dac, daf, mat);CHKERRQ(ierr); 1297bd041c0cSMatthew G. Knepley PetscFunctionReturn(0); 1298bd041c0cSMatthew G. Knepley } 1299bd041c0cSMatthew G. Knepley 1300bd041c0cSMatthew G. Knepley /*@ 1301b412c318SBarry Smith DMCreateColoring - Gets coloring for a DM 130247c6ae99SBarry Smith 1303d083f849SBarry Smith Collective on dm 130447c6ae99SBarry Smith 130547c6ae99SBarry Smith Input Parameter: 130647c6ae99SBarry Smith + dm - the DM object 13075bdb020cSBarry Smith - ctype - IS_COLORING_LOCAL or IS_COLORING_GLOBAL 130847c6ae99SBarry Smith 130947c6ae99SBarry Smith Output Parameter: 131047c6ae99SBarry Smith . coloring - the coloring 131147c6ae99SBarry Smith 1312ec5066bdSBarry Smith Notes: 1313ec5066bdSBarry 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 1314ec5066bdSBarry Smith matrix comes from. In general using the mesh produces a more optimal coloring (fewer colors). 1315ec5066bdSBarry Smith 1316ec5066bdSBarry Smith This produces a coloring with the distance of 2, see MatSetColoringDistance() which can be used for efficiently computing Jacobians with MatFDColoringCreate() 1317ec5066bdSBarry Smith 131847c6ae99SBarry Smith Level: developer 131947c6ae99SBarry Smith 1320ec5066bdSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix(), DMSetMatType(), MatColoring, MatFDColoringCreate() 132147c6ae99SBarry Smith 1322aab9d709SJed Brown @*/ 1323b412c318SBarry Smith PetscErrorCode DMCreateColoring(DM dm,ISColoringType ctype,ISColoring *coloring) 132447c6ae99SBarry Smith { 132547c6ae99SBarry Smith PetscErrorCode ierr; 132647c6ae99SBarry Smith 132747c6ae99SBarry Smith PetscFunctionBegin; 1328171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 13295a84ad33SLisandro Dalcin PetscValidPointer(coloring,3); 1330b9d85ea2SLisandro Dalcin if (!dm->ops->getcoloring) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateColoring",((PetscObject)dm)->type_name); 1331b412c318SBarry Smith ierr = (*dm->ops->getcoloring)(dm,ctype,coloring);CHKERRQ(ierr); 133247c6ae99SBarry Smith PetscFunctionReturn(0); 133347c6ae99SBarry Smith } 133447c6ae99SBarry Smith 1335b412c318SBarry Smith /*@ 13368472ad0fSDave May DMCreateMatrix - Gets empty Jacobian for a DM 133747c6ae99SBarry Smith 1338d083f849SBarry Smith Collective on dm 133947c6ae99SBarry Smith 134047c6ae99SBarry Smith Input Parameter: 1341b412c318SBarry Smith . dm - the DM object 134247c6ae99SBarry Smith 134347c6ae99SBarry Smith Output Parameter: 134447c6ae99SBarry Smith . mat - the empty Jacobian 134547c6ae99SBarry Smith 1346073dac72SJed Brown Level: beginner 134747c6ae99SBarry Smith 134895452b02SPatrick Sanan Notes: 134995452b02SPatrick Sanan This properly preallocates the number of nonzeros in the sparse matrix so you 135094013140SBarry Smith do not need to do it yourself. 135194013140SBarry Smith 135294013140SBarry Smith By default it also sets the nonzero structure and puts in the zero entries. To prevent setting 13537889ec69SBarry Smith the nonzero pattern call DMSetMatrixPreallocateOnly() 135494013140SBarry Smith 135594013140SBarry 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 135694013140SBarry Smith internally by PETSc. 135794013140SBarry Smith 135894013140SBarry Smith For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires 1359aa219208SBarry Smith the indices for the global numbering for DMDAs which is complicated. 136094013140SBarry Smith 1361b412c318SBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMSetMatType() 136247c6ae99SBarry Smith 1363aab9d709SJed Brown @*/ 1364b412c318SBarry Smith PetscErrorCode DMCreateMatrix(DM dm,Mat *mat) 136547c6ae99SBarry Smith { 136647c6ae99SBarry Smith PetscErrorCode ierr; 136747c6ae99SBarry Smith 136847c6ae99SBarry Smith PetscFunctionBegin; 1369171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1370c7b7c8a4SJed Brown PetscValidPointer(mat,3); 1371b9d85ea2SLisandro Dalcin if (!dm->ops->creatematrix) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateMatrix",((PetscObject)dm)->type_name); 13725a84ad33SLisandro Dalcin ierr = MatInitializePackage();CHKERRQ(ierr); 1373fdc842d1SBarry Smith ierr = PetscLogEventBegin(DM_CreateMatrix,0,0,0,0);CHKERRQ(ierr); 1374b412c318SBarry Smith ierr = (*dm->ops->creatematrix)(dm,mat);CHKERRQ(ierr); 137576bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1376c6b011d8SStefano Zampini DM mdm; 1377c6b011d8SStefano Zampini 1378c6b011d8SStefano Zampini ierr = MatGetDM(*mat,&mdm);CHKERRQ(ierr); 1379c6b011d8SStefano 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); 1380c6b011d8SStefano Zampini } 1381e571a35bSMatthew G. Knepley /* Handle nullspace and near nullspace */ 1382e5e52638SMatthew G. Knepley if (dm->Nf) { 1383e571a35bSMatthew G. Knepley MatNullSpace nullSpace; 1384649ef022SMatthew Knepley PetscInt Nf, f; 1385e571a35bSMatthew G. Knepley 1386e5e52638SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 1387649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1388649ef022SMatthew Knepley if (dm->nullspaceConstructors[f]) { 1389649ef022SMatthew Knepley ierr = (*dm->nullspaceConstructors[f])(dm, f, f, &nullSpace);CHKERRQ(ierr); 1390e571a35bSMatthew G. Knepley ierr = MatSetNullSpace(*mat, nullSpace);CHKERRQ(ierr); 1391e571a35bSMatthew G. Knepley ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr); 1392649ef022SMatthew Knepley break; 1393e571a35bSMatthew G. Knepley } 1394649ef022SMatthew Knepley } 1395649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1396649ef022SMatthew Knepley if (dm->nearnullspaceConstructors[f]) { 1397649ef022SMatthew Knepley ierr = (*dm->nearnullspaceConstructors[f])(dm, f, f, &nullSpace);CHKERRQ(ierr); 1398e571a35bSMatthew G. Knepley ierr = MatSetNearNullSpace(*mat, nullSpace);CHKERRQ(ierr); 1399e571a35bSMatthew G. Knepley ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr); 1400e571a35bSMatthew G. Knepley } 1401e571a35bSMatthew G. Knepley } 1402e571a35bSMatthew G. Knepley } 1403fdc842d1SBarry Smith ierr = PetscLogEventEnd(DM_CreateMatrix,0,0,0,0);CHKERRQ(ierr); 140447c6ae99SBarry Smith PetscFunctionReturn(0); 140547c6ae99SBarry Smith } 140647c6ae99SBarry Smith 1407732e2eb9SMatthew G Knepley /*@ 1408950540a4SJed Brown DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly 1409732e2eb9SMatthew G Knepley preallocated but the nonzero structure and zero values will not be set. 1410732e2eb9SMatthew G Knepley 1411d083f849SBarry Smith Logically Collective on dm 1412732e2eb9SMatthew G Knepley 1413732e2eb9SMatthew G Knepley Input Parameter: 1414732e2eb9SMatthew G Knepley + dm - the DM 1415732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation 1416732e2eb9SMatthew G Knepley 1417732e2eb9SMatthew G Knepley Level: developer 1418b06ff27eSHong Zhang .seealso DMCreateMatrix(), DMSetMatrixStructureOnly() 1419732e2eb9SMatthew G Knepley @*/ 1420732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only) 1421732e2eb9SMatthew G Knepley { 1422732e2eb9SMatthew G Knepley PetscFunctionBegin; 1423732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1424732e2eb9SMatthew G Knepley dm->prealloc_only = only; 1425732e2eb9SMatthew G Knepley PetscFunctionReturn(0); 1426732e2eb9SMatthew G Knepley } 1427732e2eb9SMatthew G Knepley 1428b06ff27eSHong Zhang /*@ 1429b06ff27eSHong Zhang DMSetMatrixStructureOnly - When DMCreateMatrix() is called, the matrix structure will be created 1430b06ff27eSHong Zhang but the array for values will not be allocated. 1431b06ff27eSHong Zhang 1432d083f849SBarry Smith Logically Collective on dm 1433b06ff27eSHong Zhang 1434b06ff27eSHong Zhang Input Parameter: 1435b06ff27eSHong Zhang + dm - the DM 1436b06ff27eSHong Zhang - only - PETSC_TRUE if only want matrix stucture 1437b06ff27eSHong Zhang 1438b06ff27eSHong Zhang Level: developer 1439b06ff27eSHong Zhang .seealso DMCreateMatrix(), DMSetMatrixPreallocateOnly() 1440b06ff27eSHong Zhang @*/ 1441b06ff27eSHong Zhang PetscErrorCode DMSetMatrixStructureOnly(DM dm, PetscBool only) 1442b06ff27eSHong Zhang { 1443b06ff27eSHong Zhang PetscFunctionBegin; 1444b06ff27eSHong Zhang PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1445b06ff27eSHong Zhang dm->structure_only = only; 1446b06ff27eSHong Zhang PetscFunctionReturn(0); 1447b06ff27eSHong Zhang } 1448b06ff27eSHong Zhang 1449a89ea682SMatthew G Knepley /*@C 1450aa1993deSMatthew G Knepley DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray() 1451a89ea682SMatthew G Knepley 1452a89ea682SMatthew G Knepley Not Collective 1453a89ea682SMatthew G Knepley 1454a89ea682SMatthew G Knepley Input Parameters: 1455a89ea682SMatthew G Knepley + dm - the DM object 1456aa1993deSMatthew G Knepley . count - The minium size 145769291d52SBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, MPIU_INT) 1458a89ea682SMatthew G Knepley 1459a89ea682SMatthew G Knepley Output Parameter: 1460a89ea682SMatthew G Knepley . array - the work array 1461a89ea682SMatthew G Knepley 1462a89ea682SMatthew G Knepley Level: developer 1463a89ea682SMatthew G Knepley 1464a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate() 1465a89ea682SMatthew G Knepley @*/ 146669291d52SBarry Smith PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,MPI_Datatype dtype,void *mem) 1467a89ea682SMatthew G Knepley { 1468a89ea682SMatthew G Knepley PetscErrorCode ierr; 1469aa1993deSMatthew G Knepley DMWorkLink link; 147069291d52SBarry Smith PetscMPIInt dsize; 1471a89ea682SMatthew G Knepley 1472a89ea682SMatthew G Knepley PetscFunctionBegin; 1473a89ea682SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1474aa1993deSMatthew G Knepley PetscValidPointer(mem,4); 1475aa1993deSMatthew G Knepley if (dm->workin) { 1476aa1993deSMatthew G Knepley link = dm->workin; 1477aa1993deSMatthew G Knepley dm->workin = dm->workin->next; 1478aa1993deSMatthew G Knepley } else { 1479b00a9115SJed Brown ierr = PetscNewLog(dm,&link);CHKERRQ(ierr); 1480a89ea682SMatthew G Knepley } 1481ffc4695bSBarry Smith ierr = MPI_Type_size(dtype,&dsize);CHKERRMPI(ierr); 14825056fcd2SBarry Smith if (((size_t)dsize*count) > link->bytes) { 1483aa1993deSMatthew G Knepley ierr = PetscFree(link->mem);CHKERRQ(ierr); 1484854ce69bSBarry Smith ierr = PetscMalloc(dsize*count,&link->mem);CHKERRQ(ierr); 1485854ce69bSBarry Smith link->bytes = dsize*count; 1486aa1993deSMatthew G Knepley } 1487aa1993deSMatthew G Knepley link->next = dm->workout; 1488aa1993deSMatthew G Knepley dm->workout = link; 148900d952a4SJed Brown #if defined(PETSC_HAVE_VALGRIND) 149000d952a4SJed Brown VALGRIND_MAKE_MEM_NOACCESS((char*)link->mem + (size_t)dsize*count, link->bytes - (size_t)dsize*count); 149100d952a4SJed Brown VALGRIND_MAKE_MEM_UNDEFINED(link->mem, (size_t)dsize*count); 149200d952a4SJed Brown #endif 1493aa1993deSMatthew G Knepley *(void**)mem = link->mem; 1494a89ea682SMatthew G Knepley PetscFunctionReturn(0); 1495a89ea682SMatthew G Knepley } 1496a89ea682SMatthew G Knepley 1497aa1993deSMatthew G Knepley /*@C 1498aa1993deSMatthew G Knepley DMRestoreWorkArray - Restores a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray() 1499aa1993deSMatthew G Knepley 1500aa1993deSMatthew G Knepley Not Collective 1501aa1993deSMatthew G Knepley 1502aa1993deSMatthew G Knepley Input Parameters: 1503aa1993deSMatthew G Knepley + dm - the DM object 1504aa1993deSMatthew G Knepley . count - The minium size 150569291d52SBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, MPIU_INT 1506aa1993deSMatthew G Knepley 1507aa1993deSMatthew G Knepley Output Parameter: 1508aa1993deSMatthew G Knepley . array - the work array 1509aa1993deSMatthew G Knepley 1510aa1993deSMatthew G Knepley Level: developer 1511aa1993deSMatthew G Knepley 151295452b02SPatrick Sanan Developer Notes: 151395452b02SPatrick Sanan count and dtype are ignored, they are only needed for DMGetWorkArray() 1514aa1993deSMatthew G Knepley .seealso DMDestroy(), DMCreate() 1515aa1993deSMatthew G Knepley @*/ 151669291d52SBarry Smith PetscErrorCode DMRestoreWorkArray(DM dm,PetscInt count,MPI_Datatype dtype,void *mem) 1517aa1993deSMatthew G Knepley { 1518aa1993deSMatthew G Knepley DMWorkLink *p,link; 1519aa1993deSMatthew G Knepley 1520aa1993deSMatthew G Knepley PetscFunctionBegin; 1521aa1993deSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1522aa1993deSMatthew G Knepley PetscValidPointer(mem,4); 1523aa1993deSMatthew G Knepley for (p=&dm->workout; (link=*p); p=&link->next) { 1524aa1993deSMatthew G Knepley if (link->mem == *(void**)mem) { 1525aa1993deSMatthew G Knepley *p = link->next; 1526aa1993deSMatthew G Knepley link->next = dm->workin; 1527aa1993deSMatthew G Knepley dm->workin = link; 15280298fd71SBarry Smith *(void**)mem = NULL; 1529aa1993deSMatthew G Knepley PetscFunctionReturn(0); 1530aa1993deSMatthew G Knepley } 1531aa1993deSMatthew G Knepley } 1532aa1993deSMatthew G Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out"); 1533aa1993deSMatthew G Knepley } 1534e7c4fc90SDmitry Karpeev 15358cda7954SMatthew G. Knepley /*@C 15368cda7954SMatthew G. Knepley DMSetNullSpaceConstructor - Provide a callback function which constructs the nullspace for a given field 15378cda7954SMatthew G. Knepley 15388cda7954SMatthew G. Knepley Logically collective on DM 15398cda7954SMatthew G. Knepley 15408cda7954SMatthew G. Knepley Input Parameters: 15418cda7954SMatthew G. Knepley + dm - The DM 15428cda7954SMatthew G. Knepley . field - The field number for the nullspace 15438cda7954SMatthew G. Knepley - nullsp - A callback to create the nullspace 15448cda7954SMatthew G. Knepley 15458cda7954SMatthew G. Knepley Notes: 15468cda7954SMatthew G. Knepley The callback is intended to provide nullspaces when function spaces are joined or split, such as in DMCreateSubDM(). The calling sequence is 15478cda7954SMatthew G. Knepley $ PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 15488cda7954SMatthew G. Knepley $ dm - The present DM 15498cda7954SMatthew G. Knepley $ origField - The field number given above, in the original DM 15508cda7954SMatthew G. Knepley $ field - The field number in dm 15518cda7954SMatthew G. Knepley $ nullSpace - The nullspace for the given field 15528cda7954SMatthew G. Knepley 15538cda7954SMatthew G. Knepley This function is currently not available from Fortran. 15548cda7954SMatthew G. Knepley 15558cda7954SMatthew G. Knepley .seealso: DMGetNullSpaceConstructor(), DMSetNearNullSpaceConstructor(), DMGetNearNullSpaceConstructor(), DMCreateSubDM(), DMCreateSuperDM() 15568cda7954SMatthew G. Knepley */ 15578cda7954SMatthew G. Knepley PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1558435a35e8SMatthew G Knepley { 1559435a35e8SMatthew G Knepley PetscFunctionBegin; 1560435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 156182f516ccSBarry Smith if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field); 1562435a35e8SMatthew G Knepley dm->nullspaceConstructors[field] = nullsp; 1563435a35e8SMatthew G Knepley PetscFunctionReturn(0); 1564435a35e8SMatthew G Knepley } 1565435a35e8SMatthew G Knepley 15668cda7954SMatthew G. Knepley /*@C 15678cda7954SMatthew G. Knepley DMGetNullSpaceConstructor - Return the callback function which constructs the nullspace for a given field, or NULL 15688cda7954SMatthew G. Knepley 15698cda7954SMatthew G. Knepley Not collective 15708cda7954SMatthew G. Knepley 15718cda7954SMatthew G. Knepley Input Parameters: 15728cda7954SMatthew G. Knepley + dm - The DM 15738cda7954SMatthew G. Knepley - field - The field number for the nullspace 15748cda7954SMatthew G. Knepley 15758cda7954SMatthew G. Knepley Output Parameter: 15768cda7954SMatthew G. Knepley . nullsp - A callback to create the nullspace 15778cda7954SMatthew G. Knepley 15788cda7954SMatthew G. Knepley Notes: 15798cda7954SMatthew G. Knepley The callback is intended to provide nullspaces when function spaces are joined or split, such as in DMCreateSubDM(). The calling sequence is 15808cda7954SMatthew G. Knepley $ PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 15818cda7954SMatthew G. Knepley $ dm - The present DM 15828cda7954SMatthew G. Knepley $ origField - The field number given above, in the original DM 15838cda7954SMatthew G. Knepley $ field - The field number in dm 15848cda7954SMatthew G. Knepley $ nullSpace - The nullspace for the given field 15858cda7954SMatthew G. Knepley 15868cda7954SMatthew G. Knepley This function is currently not available from Fortran. 15878cda7954SMatthew G. Knepley 15888cda7954SMatthew G. Knepley .seealso: DMSetNullSpaceConstructor(), DMSetNearNullSpaceConstructor(), DMGetNearNullSpaceConstructor(), DMCreateSubDM(), DMCreateSuperDM() 15898cda7954SMatthew G. Knepley */ 15908cda7954SMatthew G. Knepley PetscErrorCode DMGetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 15910a50eb56SMatthew G. Knepley { 15920a50eb56SMatthew G. Knepley PetscFunctionBegin; 15930a50eb56SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1594f9d4088aSMatthew G. Knepley PetscValidPointer(nullsp, 3); 15950a50eb56SMatthew G. Knepley if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field); 15960a50eb56SMatthew G. Knepley *nullsp = dm->nullspaceConstructors[field]; 15970a50eb56SMatthew G. Knepley PetscFunctionReturn(0); 15980a50eb56SMatthew G. Knepley } 15990a50eb56SMatthew G. Knepley 16008cda7954SMatthew G. Knepley /*@C 16018cda7954SMatthew G. Knepley DMSetNearNullSpaceConstructor - Provide a callback function which constructs the near-nullspace for a given field 16028cda7954SMatthew G. Knepley 16038cda7954SMatthew G. Knepley Logically collective on DM 16048cda7954SMatthew G. Knepley 16058cda7954SMatthew G. Knepley Input Parameters: 16068cda7954SMatthew G. Knepley + dm - The DM 16078cda7954SMatthew G. Knepley . field - The field number for the nullspace 16088cda7954SMatthew G. Knepley - nullsp - A callback to create the near-nullspace 16098cda7954SMatthew G. Knepley 16108cda7954SMatthew G. Knepley Notes: 16118cda7954SMatthew G. Knepley The callback is intended to provide nullspaces when function spaces are joined or split, such as in DMCreateSubDM(). The calling sequence is 16128cda7954SMatthew G. Knepley $ PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 16138cda7954SMatthew G. Knepley $ dm - The present DM 16148cda7954SMatthew G. Knepley $ origField - The field number given above, in the original DM 16158cda7954SMatthew G. Knepley $ field - The field number in dm 16168cda7954SMatthew G. Knepley $ nullSpace - The nullspace for the given field 16178cda7954SMatthew G. Knepley 16188cda7954SMatthew G. Knepley This function is currently not available from Fortran. 16198cda7954SMatthew G. Knepley 16208cda7954SMatthew G. Knepley .seealso: DMGetNearNullSpaceConstructor(), DMSetNullSpaceConstructor(), DMGetNullSpaceConstructor(), DMCreateSubDM(), DMCreateSuperDM() 16218cda7954SMatthew G. Knepley */ 16228cda7954SMatthew G. Knepley PetscErrorCode DMSetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1623f9d4088aSMatthew G. Knepley { 1624f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1625f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1626f9d4088aSMatthew G. Knepley if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field); 1627f9d4088aSMatthew G. Knepley dm->nearnullspaceConstructors[field] = nullsp; 1628f9d4088aSMatthew G. Knepley PetscFunctionReturn(0); 1629f9d4088aSMatthew G. Knepley } 1630f9d4088aSMatthew G. Knepley 16318cda7954SMatthew G. Knepley /*@C 16328cda7954SMatthew G. Knepley DMGetNearNullSpaceConstructor - Return the callback function which constructs the near-nullspace for a given field, or NULL 16338cda7954SMatthew G. Knepley 16348cda7954SMatthew G. Knepley Not collective 16358cda7954SMatthew G. Knepley 16368cda7954SMatthew G. Knepley Input Parameters: 16378cda7954SMatthew G. Knepley + dm - The DM 16388cda7954SMatthew G. Knepley - field - The field number for the nullspace 16398cda7954SMatthew G. Knepley 16408cda7954SMatthew G. Knepley Output Parameter: 16418cda7954SMatthew G. Knepley . nullsp - A callback to create the near-nullspace 16428cda7954SMatthew G. Knepley 16438cda7954SMatthew G. Knepley Notes: 16448cda7954SMatthew G. Knepley The callback is intended to provide nullspaces when function spaces are joined or split, such as in DMCreateSubDM(). The calling sequence is 16458cda7954SMatthew G. Knepley $ PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 16468cda7954SMatthew G. Knepley $ dm - The present DM 16478cda7954SMatthew G. Knepley $ origField - The field number given above, in the original DM 16488cda7954SMatthew G. Knepley $ field - The field number in dm 16498cda7954SMatthew G. Knepley $ nullSpace - The nullspace for the given field 16508cda7954SMatthew G. Knepley 16518cda7954SMatthew G. Knepley This function is currently not available from Fortran. 16528cda7954SMatthew G. Knepley 16538cda7954SMatthew G. Knepley .seealso: DMSetNearNullSpaceConstructor(), DMSetNullSpaceConstructor(), DMGetNullSpaceConstructor(), DMCreateSubDM(), DMCreateSuperDM() 16548cda7954SMatthew G. Knepley */ 16558cda7954SMatthew G. Knepley PetscErrorCode DMGetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1656f9d4088aSMatthew G. Knepley { 1657f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1658f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1659f9d4088aSMatthew G. Knepley PetscValidPointer(nullsp, 3); 1660f9d4088aSMatthew G. Knepley if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field); 1661f9d4088aSMatthew G. Knepley *nullsp = dm->nearnullspaceConstructors[field]; 1662f9d4088aSMatthew G. Knepley PetscFunctionReturn(0); 1663f9d4088aSMatthew G. Knepley } 1664f9d4088aSMatthew G. Knepley 16654f3b5142SJed Brown /*@C 16664d343eeaSMatthew G Knepley DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field 16674d343eeaSMatthew G Knepley 16684d343eeaSMatthew G Knepley Not collective 16694d343eeaSMatthew G Knepley 16704d343eeaSMatthew G Knepley Input Parameter: 16714d343eeaSMatthew G Knepley . dm - the DM object 16724d343eeaSMatthew G Knepley 16734d343eeaSMatthew G Knepley Output Parameters: 16740298fd71SBarry Smith + numFields - The number of fields (or NULL if not requested) 16750298fd71SBarry Smith . fieldNames - The name for each field (or NULL if not requested) 16760298fd71SBarry Smith - fields - The global indices for each field (or NULL if not requested) 16774d343eeaSMatthew G Knepley 16784d343eeaSMatthew G Knepley Level: intermediate 16794d343eeaSMatthew G Knepley 168021c9b008SJed Brown Notes: 168121c9b008SJed Brown The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 168221c9b008SJed Brown PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with 168321c9b008SJed Brown PetscFree(). 168421c9b008SJed Brown 16854d343eeaSMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 16864d343eeaSMatthew G Knepley @*/ 168737d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields) 16884d343eeaSMatthew G Knepley { 168937d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 16904d343eeaSMatthew G Knepley PetscErrorCode ierr; 16914d343eeaSMatthew G Knepley 16924d343eeaSMatthew G Knepley PetscFunctionBegin; 16934d343eeaSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 169469ca1f37SDmitry Karpeev if (numFields) { 1695534a8f05SLisandro Dalcin PetscValidIntPointer(numFields,2); 169669ca1f37SDmitry Karpeev *numFields = 0; 169769ca1f37SDmitry Karpeev } 169837d0c07bSMatthew G Knepley if (fieldNames) { 169937d0c07bSMatthew G Knepley PetscValidPointer(fieldNames,3); 17000298fd71SBarry Smith *fieldNames = NULL; 170169ca1f37SDmitry Karpeev } 170269ca1f37SDmitry Karpeev if (fields) { 170369ca1f37SDmitry Karpeev PetscValidPointer(fields,4); 17040298fd71SBarry Smith *fields = NULL; 170569ca1f37SDmitry Karpeev } 170692fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 170737d0c07bSMatthew G Knepley if (section) { 17083a544194SStefano Zampini PetscInt *fieldSizes, *fieldNc, **fieldIndices; 170937d0c07bSMatthew G Knepley PetscInt nF, f, pStart, pEnd, p; 171037d0c07bSMatthew G Knepley 1711e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 171237d0c07bSMatthew G Knepley ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr); 17133a544194SStefano Zampini ierr = PetscMalloc3(nF,&fieldSizes,nF,&fieldNc,nF,&fieldIndices);CHKERRQ(ierr); 171437d0c07bSMatthew G Knepley ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 171537d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 171637d0c07bSMatthew G Knepley fieldSizes[f] = 0; 17173a544194SStefano Zampini ierr = PetscSectionGetFieldComponents(section, f, &fieldNc[f]);CHKERRQ(ierr); 171837d0c07bSMatthew G Knepley } 171937d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 172037d0c07bSMatthew G Knepley PetscInt gdof; 172137d0c07bSMatthew G Knepley 172237d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 172337d0c07bSMatthew G Knepley if (gdof > 0) { 172437d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 17253a544194SStefano Zampini PetscInt fdof, fcdof, fpdof; 172637d0c07bSMatthew G Knepley 172737d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 172837d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 17293a544194SStefano Zampini fpdof = fdof-fcdof; 17303a544194SStefano Zampini if (fpdof && fpdof != fieldNc[f]) { 17313a544194SStefano Zampini /* Layout does not admit a pointwise block size */ 17323a544194SStefano Zampini fieldNc[f] = 1; 17333a544194SStefano Zampini } 17343a544194SStefano Zampini fieldSizes[f] += fpdof; 173537d0c07bSMatthew G Knepley } 173637d0c07bSMatthew G Knepley } 173737d0c07bSMatthew G Knepley } 173837d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 1739785e854fSJed Brown ierr = PetscMalloc1(fieldSizes[f], &fieldIndices[f]);CHKERRQ(ierr); 174037d0c07bSMatthew G Knepley fieldSizes[f] = 0; 174137d0c07bSMatthew G Knepley } 174237d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 174337d0c07bSMatthew G Knepley PetscInt gdof, goff; 174437d0c07bSMatthew G Knepley 174537d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 174637d0c07bSMatthew G Knepley if (gdof > 0) { 174737d0c07bSMatthew G Knepley ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr); 174837d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 174937d0c07bSMatthew G Knepley PetscInt fdof, fcdof, fc; 175037d0c07bSMatthew G Knepley 175137d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 175237d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 175337d0c07bSMatthew G Knepley for (fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) { 175437d0c07bSMatthew G Knepley fieldIndices[f][fieldSizes[f]] = goff++; 175537d0c07bSMatthew G Knepley } 175637d0c07bSMatthew G Knepley } 175737d0c07bSMatthew G Knepley } 175837d0c07bSMatthew G Knepley } 17598865f1eaSKarl Rupp if (numFields) *numFields = nF; 176037d0c07bSMatthew G Knepley if (fieldNames) { 1761785e854fSJed Brown ierr = PetscMalloc1(nF, fieldNames);CHKERRQ(ierr); 176237d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 176337d0c07bSMatthew G Knepley const char *fieldName; 176437d0c07bSMatthew G Knepley 176537d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr); 176637d0c07bSMatthew G Knepley ierr = PetscStrallocpy(fieldName, (char**) &(*fieldNames)[f]);CHKERRQ(ierr); 176737d0c07bSMatthew G Knepley } 176837d0c07bSMatthew G Knepley } 176937d0c07bSMatthew G Knepley if (fields) { 1770785e854fSJed Brown ierr = PetscMalloc1(nF, fields);CHKERRQ(ierr); 177137d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 17723a544194SStefano Zampini PetscInt bs, in[2], out[2]; 17733a544194SStefano Zampini 177482f516ccSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr); 17753a544194SStefano Zampini in[0] = -fieldNc[f]; 17763a544194SStefano Zampini in[1] = fieldNc[f]; 1777*820f2d46SBarry Smith ierr = MPIU_Allreduce(in, out, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 17783a544194SStefano Zampini bs = (-out[0] == out[1]) ? out[1] : 1; 17793a544194SStefano Zampini ierr = ISSetBlockSize((*fields)[f], bs);CHKERRQ(ierr); 178037d0c07bSMatthew G Knepley } 178137d0c07bSMatthew G Knepley } 17823a544194SStefano Zampini ierr = PetscFree3(fieldSizes,fieldNc,fieldIndices);CHKERRQ(ierr); 17838865f1eaSKarl Rupp } else if (dm->ops->createfieldis) { 17848865f1eaSKarl Rupp ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr); 178569ca1f37SDmitry Karpeev } 17864d343eeaSMatthew G Knepley PetscFunctionReturn(0); 17874d343eeaSMatthew G Knepley } 17884d343eeaSMatthew G Knepley 178916621825SDmitry Karpeev 179016621825SDmitry Karpeev /*@C 179116621825SDmitry Karpeev DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems 179216621825SDmitry Karpeev corresponding to different fields: each IS contains the global indices of the dofs of the 179316621825SDmitry Karpeev corresponding field. The optional list of DMs define the DM for each subproblem. 1794e7c4fc90SDmitry Karpeev Generalizes DMCreateFieldIS(). 1795e7c4fc90SDmitry Karpeev 1796e7c4fc90SDmitry Karpeev Not collective 1797e7c4fc90SDmitry Karpeev 1798e7c4fc90SDmitry Karpeev Input Parameter: 1799e7c4fc90SDmitry Karpeev . dm - the DM object 1800e7c4fc90SDmitry Karpeev 1801e7c4fc90SDmitry Karpeev Output Parameters: 18020298fd71SBarry Smith + len - The number of subproblems in the field decomposition (or NULL if not requested) 18030298fd71SBarry Smith . namelist - The name for each field (or NULL if not requested) 18040298fd71SBarry Smith . islist - The global indices for each field (or NULL if not requested) 18050298fd71SBarry Smith - dmlist - The DMs for each field subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined) 1806e7c4fc90SDmitry Karpeev 1807e7c4fc90SDmitry Karpeev Level: intermediate 1808e7c4fc90SDmitry Karpeev 1809e7c4fc90SDmitry Karpeev Notes: 1810e7c4fc90SDmitry Karpeev The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 1811e7c4fc90SDmitry Karpeev PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(), 1812e7c4fc90SDmitry Karpeev and all of the arrays should be freed with PetscFree(). 1813e7c4fc90SDmitry Karpeev 1814e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 1815e7c4fc90SDmitry Karpeev @*/ 181616621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist) 1817e7c4fc90SDmitry Karpeev { 1818e7c4fc90SDmitry Karpeev PetscErrorCode ierr; 1819e7c4fc90SDmitry Karpeev 1820e7c4fc90SDmitry Karpeev PetscFunctionBegin; 1821e7c4fc90SDmitry Karpeev PetscValidHeaderSpecific(dm,DM_CLASSID,1); 18228865f1eaSKarl Rupp if (len) { 1823534a8f05SLisandro Dalcin PetscValidIntPointer(len,2); 18248865f1eaSKarl Rupp *len = 0; 18258865f1eaSKarl Rupp } 18268865f1eaSKarl Rupp if (namelist) { 18278865f1eaSKarl Rupp PetscValidPointer(namelist,3); 1828ea78f98cSLisandro Dalcin *namelist = NULL; 18298865f1eaSKarl Rupp } 18308865f1eaSKarl Rupp if (islist) { 18318865f1eaSKarl Rupp PetscValidPointer(islist,4); 1832ea78f98cSLisandro Dalcin *islist = NULL; 18338865f1eaSKarl Rupp } 18348865f1eaSKarl Rupp if (dmlist) { 18358865f1eaSKarl Rupp PetscValidPointer(dmlist,5); 1836ea78f98cSLisandro Dalcin *dmlist = NULL; 18378865f1eaSKarl Rupp } 1838f3f0edfdSDmitry Karpeev /* 1839f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 1840f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 1841f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 1842f3f0edfdSDmitry Karpeev */ 1843ce94432eSBarry Smith if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 184416621825SDmitry Karpeev if (!dm->ops->createfielddecomposition) { 1845435a35e8SMatthew G Knepley PetscSection section; 1846435a35e8SMatthew G Knepley PetscInt numFields, f; 1847435a35e8SMatthew G Knepley 184892fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 1849435a35e8SMatthew G Knepley if (section) {ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr);} 1850435a35e8SMatthew G Knepley if (section && numFields && dm->ops->createsubdm) { 1851f25d98f1SMatthew G. Knepley if (len) *len = numFields; 185203dc3394SMatthew G. Knepley if (namelist) {ierr = PetscMalloc1(numFields,namelist);CHKERRQ(ierr);} 185303dc3394SMatthew G. Knepley if (islist) {ierr = PetscMalloc1(numFields,islist);CHKERRQ(ierr);} 185403dc3394SMatthew G. Knepley if (dmlist) {ierr = PetscMalloc1(numFields,dmlist);CHKERRQ(ierr);} 1855435a35e8SMatthew G Knepley for (f = 0; f < numFields; ++f) { 1856435a35e8SMatthew G Knepley const char *fieldName; 1857435a35e8SMatthew G Knepley 185803dc3394SMatthew G. Knepley ierr = DMCreateSubDM(dm, 1, &f, islist ? &(*islist)[f] : NULL, dmlist ? &(*dmlist)[f] : NULL);CHKERRQ(ierr); 185903dc3394SMatthew G. Knepley if (namelist) { 1860435a35e8SMatthew G Knepley ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr); 1861435a35e8SMatthew G Knepley ierr = PetscStrallocpy(fieldName, (char**) &(*namelist)[f]);CHKERRQ(ierr); 1862435a35e8SMatthew G Knepley } 186303dc3394SMatthew G. Knepley } 1864435a35e8SMatthew G Knepley } else { 186569ca1f37SDmitry Karpeev ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr); 1866e7c4fc90SDmitry Karpeev /* By default there are no DMs associated with subproblems. */ 18670298fd71SBarry Smith if (dmlist) *dmlist = NULL; 1868e7c4fc90SDmitry Karpeev } 18698865f1eaSKarl Rupp } else { 187016621825SDmitry Karpeev ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist);CHKERRQ(ierr); 187116621825SDmitry Karpeev } 187216621825SDmitry Karpeev PetscFunctionReturn(0); 187316621825SDmitry Karpeev } 187416621825SDmitry Karpeev 1875564cec59SMatthew G. Knepley /*@ 1876435a35e8SMatthew G Knepley DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in. 1877435a35e8SMatthew G Knepley The fields are defined by DMCreateFieldIS(). 1878435a35e8SMatthew G Knepley 1879435a35e8SMatthew G Knepley Not collective 1880435a35e8SMatthew G Knepley 1881435a35e8SMatthew G Knepley Input Parameters: 18822adcc780SMatthew G. Knepley + dm - The DM object 18832adcc780SMatthew G. Knepley . numFields - The number of fields in this subproblem 18842adcc780SMatthew G. Knepley - fields - The field numbers of the selected fields 1885435a35e8SMatthew G Knepley 1886435a35e8SMatthew G Knepley Output Parameters: 18872adcc780SMatthew G. Knepley + is - The global indices for the subproblem 18882adcc780SMatthew G. Knepley - subdm - The DM for the subproblem 1889435a35e8SMatthew G Knepley 18905d3b26e6SMatthew G. Knepley Note: You need to call DMPlexSetMigrationSF() on the original DM if you want the Global-To-Natural map to be automatically constructed 18915d3b26e6SMatthew G. Knepley 1892435a35e8SMatthew G Knepley Level: intermediate 1893435a35e8SMatthew G Knepley 18945d3b26e6SMatthew G. Knepley .seealso DMPlexSetMigrationSF(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 1895435a35e8SMatthew G Knepley @*/ 189637bc7515SMatthew G. Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 1897435a35e8SMatthew G Knepley { 1898435a35e8SMatthew G Knepley PetscErrorCode ierr; 1899435a35e8SMatthew G Knepley 1900435a35e8SMatthew G Knepley PetscFunctionBegin; 1901435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1902435a35e8SMatthew G Knepley PetscValidPointer(fields,3); 19038865f1eaSKarl Rupp if (is) PetscValidPointer(is,4); 19048865f1eaSKarl Rupp if (subdm) PetscValidPointer(subdm,5); 1905b9d85ea2SLisandro Dalcin if (!dm->ops->createsubdm) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateSubDM",((PetscObject)dm)->type_name); 1906435a35e8SMatthew G Knepley ierr = (*dm->ops->createsubdm)(dm, numFields, fields, is, subdm);CHKERRQ(ierr); 1907435a35e8SMatthew G Knepley PetscFunctionReturn(0); 1908435a35e8SMatthew G Knepley } 1909435a35e8SMatthew G Knepley 19102adcc780SMatthew G. Knepley /*@C 19112adcc780SMatthew G. Knepley DMCreateSuperDM - Returns an arrays of ISes and DM encapsulating a superproblem defined by the DMs passed in. 19122adcc780SMatthew G. Knepley 19132adcc780SMatthew G. Knepley Not collective 19142adcc780SMatthew G. Knepley 19152adcc780SMatthew G. Knepley Input Parameter: 19162adcc780SMatthew G. Knepley + dms - The DM objects 19172adcc780SMatthew G. Knepley - len - The number of DMs 19182adcc780SMatthew G. Knepley 19192adcc780SMatthew G. Knepley Output Parameters: 1920a42bd24dSMatthew G. Knepley + is - The global indices for the subproblem, or NULL 19212adcc780SMatthew G. Knepley - superdm - The DM for the superproblem 19222adcc780SMatthew G. Knepley 19235d3b26e6SMatthew G. Knepley Note: You need to call DMPlexSetMigrationSF() on the original DM if you want the Global-To-Natural map to be automatically constructed 19245d3b26e6SMatthew G. Knepley 19252adcc780SMatthew G. Knepley Level: intermediate 19262adcc780SMatthew G. Knepley 19275d3b26e6SMatthew G. Knepley .seealso DMPlexSetMigrationSF(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 19282adcc780SMatthew G. Knepley @*/ 19292adcc780SMatthew G. Knepley PetscErrorCode DMCreateSuperDM(DM dms[], PetscInt len, IS **is, DM *superdm) 19302adcc780SMatthew G. Knepley { 19312adcc780SMatthew G. Knepley PetscInt i; 19322adcc780SMatthew G. Knepley PetscErrorCode ierr; 19332adcc780SMatthew G. Knepley 19342adcc780SMatthew G. Knepley PetscFunctionBegin; 19352adcc780SMatthew G. Knepley PetscValidPointer(dms,1); 19362adcc780SMatthew G. Knepley for (i = 0; i < len; ++i) {PetscValidHeaderSpecific(dms[i],DM_CLASSID,1);} 19372adcc780SMatthew G. Knepley if (is) PetscValidPointer(is,3); 1938a42bd24dSMatthew G. Knepley PetscValidPointer(superdm,4); 19392adcc780SMatthew G. Knepley if (len < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of DMs must be nonnegative: %D", len); 19402adcc780SMatthew G. Knepley if (len) { 1941b9d85ea2SLisandro Dalcin DM dm = dms[0]; 1942b9d85ea2SLisandro Dalcin if (!dm->ops->createsuperdm) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateSuperDM",((PetscObject)dm)->type_name); 1943b9d85ea2SLisandro Dalcin ierr = (*dm->ops->createsuperdm)(dms, len, is, superdm);CHKERRQ(ierr); 19442adcc780SMatthew G. Knepley } 19452adcc780SMatthew G. Knepley PetscFunctionReturn(0); 19462adcc780SMatthew G. Knepley } 19472adcc780SMatthew G. Knepley 194816621825SDmitry Karpeev 194916621825SDmitry Karpeev /*@C 19508d4ac253SDmitry Karpeev DMCreateDomainDecomposition - Returns lists of IS objects defining a decomposition of a problem into subproblems 19518d4ac253SDmitry Karpeev corresponding to restrictions to pairs nested subdomains: each IS contains the global 19528d4ac253SDmitry Karpeev indices of the dofs of the corresponding subdomains. The inner subdomains conceptually 19538d4ac253SDmitry Karpeev define a nonoverlapping covering, while outer subdomains can overlap. 19548d4ac253SDmitry Karpeev The optional list of DMs define the DM for each subproblem. 195516621825SDmitry Karpeev 195616621825SDmitry Karpeev Not collective 195716621825SDmitry Karpeev 195816621825SDmitry Karpeev Input Parameter: 195916621825SDmitry Karpeev . dm - the DM object 196016621825SDmitry Karpeev 196116621825SDmitry Karpeev Output Parameters: 19620298fd71SBarry Smith + len - The number of subproblems in the domain decomposition (or NULL if not requested) 19630298fd71SBarry Smith . namelist - The name for each subdomain (or NULL if not requested) 19640298fd71SBarry Smith . innerislist - The global indices for each inner subdomain (or NULL, if not requested) 19650298fd71SBarry Smith . outerislist - The global indices for each outer subdomain (or NULL, if not requested) 19660298fd71SBarry Smith - dmlist - The DMs for each subdomain subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined) 196716621825SDmitry Karpeev 196816621825SDmitry Karpeev Level: intermediate 196916621825SDmitry Karpeev 197016621825SDmitry Karpeev Notes: 197116621825SDmitry Karpeev The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 197216621825SDmitry Karpeev PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(), 197316621825SDmitry Karpeev and all of the arrays should be freed with PetscFree(). 197416621825SDmitry Karpeev 1975245d9833Sprj- .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldDecomposition() 197616621825SDmitry Karpeev @*/ 19778d4ac253SDmitry Karpeev PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist) 197816621825SDmitry Karpeev { 197916621825SDmitry Karpeev PetscErrorCode ierr; 1980be081cd6SPeter Brune DMSubDomainHookLink link; 1981be081cd6SPeter Brune PetscInt i,l; 198216621825SDmitry Karpeev 198316621825SDmitry Karpeev PetscFunctionBegin; 198416621825SDmitry Karpeev PetscValidHeaderSpecific(dm,DM_CLASSID,1); 198514a18fd3SPeter Brune if (len) {PetscValidPointer(len,2); *len = 0;} 19860298fd71SBarry Smith if (namelist) {PetscValidPointer(namelist,3); *namelist = NULL;} 19870298fd71SBarry Smith if (innerislist) {PetscValidPointer(innerislist,4); *innerislist = NULL;} 19880298fd71SBarry Smith if (outerislist) {PetscValidPointer(outerislist,5); *outerislist = NULL;} 19890298fd71SBarry Smith if (dmlist) {PetscValidPointer(dmlist,6); *dmlist = NULL;} 1990f3f0edfdSDmitry Karpeev /* 1991f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 1992f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 1993f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 1994f3f0edfdSDmitry Karpeev */ 1995ce94432eSBarry Smith if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 199616621825SDmitry Karpeev if (dm->ops->createdomaindecomposition) { 1997be081cd6SPeter Brune ierr = (*dm->ops->createdomaindecomposition)(dm,&l,namelist,innerislist,outerislist,dmlist);CHKERRQ(ierr); 199814a18fd3SPeter Brune /* copy subdomain hooks and context over to the subdomain DMs */ 1999f891f5b9SPatrick Sanan if (dmlist && *dmlist) { 2000be081cd6SPeter Brune for (i = 0; i < l; i++) { 2001be081cd6SPeter Brune for (link=dm->subdomainhook; link; link=link->next) { 2002be081cd6SPeter Brune if (link->ddhook) {ierr = (*link->ddhook)(dm,(*dmlist)[i],link->ctx);CHKERRQ(ierr);} 2003be081cd6SPeter Brune } 2004648262bbSPatrick Sanan if (dm->ctx) (*dmlist)[i]->ctx = dm->ctx; 2005e7c4fc90SDmitry Karpeev } 200614a18fd3SPeter Brune } 200714a18fd3SPeter Brune if (len) *len = l; 200814a18fd3SPeter Brune } 2009e30e807fSPeter Brune PetscFunctionReturn(0); 2010e30e807fSPeter Brune } 2011e30e807fSPeter Brune 2012e30e807fSPeter Brune 2013e30e807fSPeter Brune /*@C 2014e30e807fSPeter Brune DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector 2015e30e807fSPeter Brune 2016e30e807fSPeter Brune Not collective 2017e30e807fSPeter Brune 2018e30e807fSPeter Brune Input Parameters: 2019e30e807fSPeter Brune + dm - the DM object 2020e30e807fSPeter Brune . n - the number of subdomain scatters 2021e30e807fSPeter Brune - subdms - the local subdomains 2022e30e807fSPeter Brune 2023e30e807fSPeter Brune Output Parameters: 2024e30e807fSPeter Brune + n - the number of scatters returned 2025e30e807fSPeter Brune . iscat - scatter from global vector to nonoverlapping global vector entries on subdomain 2026e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain 2027e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts) 2028e30e807fSPeter Brune 202995452b02SPatrick Sanan Notes: 203095452b02SPatrick Sanan This is an alternative to the iis and ois arguments in DMCreateDomainDecomposition that allow for the solution 2031e30e807fSPeter Brune of general nonlinear problems with overlapping subdomain methods. While merely having index sets that enable subsets 2032e30e807fSPeter Brune of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of 2033e30e807fSPeter Brune solution and residual data. 2034e30e807fSPeter Brune 2035e30e807fSPeter Brune Level: developer 2036e30e807fSPeter Brune 2037e30e807fSPeter Brune .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 2038e30e807fSPeter Brune @*/ 2039e30e807fSPeter Brune PetscErrorCode DMCreateDomainDecompositionScatters(DM dm,PetscInt n,DM *subdms,VecScatter **iscat,VecScatter **oscat,VecScatter **gscat) 2040e30e807fSPeter Brune { 2041e30e807fSPeter Brune PetscErrorCode ierr; 2042e30e807fSPeter Brune 2043e30e807fSPeter Brune PetscFunctionBegin; 2044e30e807fSPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2045e30e807fSPeter Brune PetscValidPointer(subdms,3); 2046b9d85ea2SLisandro Dalcin if (!dm->ops->createddscatters) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateDomainDecompositionScatters",((PetscObject)dm)->type_name); 2047e30e807fSPeter Brune ierr = (*dm->ops->createddscatters)(dm,n,subdms,iscat,oscat,gscat);CHKERRQ(ierr); 2048e7c4fc90SDmitry Karpeev PetscFunctionReturn(0); 2049e7c4fc90SDmitry Karpeev } 2050e7c4fc90SDmitry Karpeev 205147c6ae99SBarry Smith /*@ 205247c6ae99SBarry Smith DMRefine - Refines a DM object 205347c6ae99SBarry Smith 2054d083f849SBarry Smith Collective on dm 205547c6ae99SBarry Smith 205647c6ae99SBarry Smith Input Parameter: 205747c6ae99SBarry Smith + dm - the DM object 205891d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL) 205947c6ae99SBarry Smith 206047c6ae99SBarry Smith Output Parameter: 20610298fd71SBarry Smith . dmf - the refined DM, or NULL 2062ae0a1c52SMatthew G Knepley 2063412e9a14SMatthew G. Knepley Options Dtabase Keys: 2064412e9a14SMatthew G. Knepley . -dm_plex_cell_refiner <strategy> - chooses the refinement strategy, e.g. regular, tohex 2065412e9a14SMatthew G. Knepley 20660298fd71SBarry Smith Note: If no refinement was done, the return value is NULL 206747c6ae99SBarry Smith 206847c6ae99SBarry Smith Level: developer 206947c6ae99SBarry Smith 2070e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 207147c6ae99SBarry Smith @*/ 20727087cfbeSBarry Smith PetscErrorCode DMRefine(DM dm,MPI_Comm comm,DM *dmf) 207347c6ae99SBarry Smith { 207447c6ae99SBarry Smith PetscErrorCode ierr; 2075c833c3b5SJed Brown DMRefineHookLink link; 207647c6ae99SBarry Smith 207747c6ae99SBarry Smith PetscFunctionBegin; 2078732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2079b9d85ea2SLisandro Dalcin if (!dm->ops->refine) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMRefine",((PetscObject)dm)->type_name); 20801ac00216SMatthew G. Knepley ierr = PetscLogEventBegin(DM_Refine,dm,0,0,0);CHKERRQ(ierr); 208147c6ae99SBarry Smith ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr); 20824057135bSMatthew G Knepley if (*dmf) { 208343842a1eSJed Brown (*dmf)->ops->creatematrix = dm->ops->creatematrix; 20848865f1eaSKarl Rupp 20858cd211a4SJed Brown ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr); 20868865f1eaSKarl Rupp 2087644e2e5bSBarry Smith (*dmf)->ctx = dm->ctx; 20880598a293SJed Brown (*dmf)->leveldown = dm->leveldown; 2089656b349aSBarry Smith (*dmf)->levelup = dm->levelup + 1; 20908865f1eaSKarl Rupp 2091e4b4b23bSJed Brown ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr); 2092c833c3b5SJed Brown for (link=dm->refinehook; link; link=link->next) { 20938865f1eaSKarl Rupp if (link->refinehook) { 20948865f1eaSKarl Rupp ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr); 20958865f1eaSKarl Rupp } 2096c833c3b5SJed Brown } 2097c833c3b5SJed Brown } 20981ac00216SMatthew G. Knepley ierr = PetscLogEventEnd(DM_Refine,dm,0,0,0);CHKERRQ(ierr); 2099c833c3b5SJed Brown PetscFunctionReturn(0); 2100c833c3b5SJed Brown } 2101c833c3b5SJed Brown 2102bb9467b5SJed Brown /*@C 2103c833c3b5SJed Brown DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid 2104c833c3b5SJed Brown 2105c833c3b5SJed Brown Logically Collective 2106c833c3b5SJed Brown 2107c833c3b5SJed Brown Input Arguments: 2108c833c3b5SJed Brown + coarse - nonlinear solver context on which to run a hook when restricting to a coarser level 2109c833c3b5SJed Brown . refinehook - function to run when setting up a coarser level 2110c833c3b5SJed Brown . interphook - function to run to update data on finer levels (once per SNESSolve()) 21110298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2112c833c3b5SJed Brown 2113c833c3b5SJed Brown Calling sequence of refinehook: 2114c833c3b5SJed Brown $ refinehook(DM coarse,DM fine,void *ctx); 2115c833c3b5SJed Brown 2116c833c3b5SJed Brown + coarse - coarse level DM 2117c833c3b5SJed Brown . fine - fine level DM to interpolate problem to 2118c833c3b5SJed Brown - ctx - optional user-defined function context 2119c833c3b5SJed Brown 2120c833c3b5SJed Brown Calling sequence for interphook: 2121c833c3b5SJed Brown $ interphook(DM coarse,Mat interp,DM fine,void *ctx) 2122c833c3b5SJed Brown 2123c833c3b5SJed Brown + coarse - coarse level DM 2124c833c3b5SJed Brown . interp - matrix interpolating a coarse-level solution to the finer grid 2125c833c3b5SJed Brown . fine - fine level DM to update 2126c833c3b5SJed Brown - ctx - optional user-defined function context 2127c833c3b5SJed Brown 2128c833c3b5SJed Brown Level: advanced 2129c833c3b5SJed Brown 2130c833c3b5SJed Brown Notes: 2131c833c3b5SJed Brown This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing 2132c833c3b5SJed Brown 2133c833c3b5SJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 2134c833c3b5SJed Brown 2135bb9467b5SJed Brown This function is currently not available from Fortran. 2136bb9467b5SJed Brown 2137c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 2138c833c3b5SJed Brown @*/ 2139c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx) 2140c833c3b5SJed Brown { 2141c833c3b5SJed Brown PetscErrorCode ierr; 2142c833c3b5SJed Brown DMRefineHookLink link,*p; 2143c833c3b5SJed Brown 2144c833c3b5SJed Brown PetscFunctionBegin; 2145c833c3b5SJed Brown PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 21463d8e3701SJed Brown for (p=&coarse->refinehook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */ 21473d8e3701SJed Brown if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) PetscFunctionReturn(0); 21483d8e3701SJed Brown } 214995dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 2150c833c3b5SJed Brown link->refinehook = refinehook; 2151c833c3b5SJed Brown link->interphook = interphook; 2152c833c3b5SJed Brown link->ctx = ctx; 21530298fd71SBarry Smith link->next = NULL; 2154c833c3b5SJed Brown *p = link; 2155c833c3b5SJed Brown PetscFunctionReturn(0); 2156c833c3b5SJed Brown } 2157c833c3b5SJed Brown 21583d8e3701SJed Brown /*@C 21593d8e3701SJed Brown DMRefineHookRemove - remove a callback from the list of hooks to be run when interpolating a nonlinear problem to a finer grid 21603d8e3701SJed Brown 21613d8e3701SJed Brown Logically Collective 21623d8e3701SJed Brown 21633d8e3701SJed Brown Input Arguments: 21643d8e3701SJed Brown + coarse - nonlinear solver context on which to run a hook when restricting to a coarser level 21653d8e3701SJed Brown . refinehook - function to run when setting up a coarser level 21663d8e3701SJed Brown . interphook - function to run to update data on finer levels (once per SNESSolve()) 21673d8e3701SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 21683d8e3701SJed Brown 21693d8e3701SJed Brown Level: advanced 21703d8e3701SJed Brown 21713d8e3701SJed Brown Notes: 21723d8e3701SJed Brown This function does nothing if the hook is not in the list. 21733d8e3701SJed Brown 21743d8e3701SJed Brown This function is currently not available from Fortran. 21753d8e3701SJed Brown 21763d8e3701SJed Brown .seealso: DMCoarsenHookRemove(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 21773d8e3701SJed Brown @*/ 21783d8e3701SJed Brown PetscErrorCode DMRefineHookRemove(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx) 21793d8e3701SJed Brown { 21803d8e3701SJed Brown PetscErrorCode ierr; 21813d8e3701SJed Brown DMRefineHookLink link,*p; 21823d8e3701SJed Brown 21833d8e3701SJed Brown PetscFunctionBegin; 21843d8e3701SJed Brown PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 21853d8e3701SJed Brown for (p=&coarse->refinehook; *p; p=&(*p)->next) { /* Search the list of current hooks */ 21863d8e3701SJed Brown if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) { 21873d8e3701SJed Brown link = *p; 21883d8e3701SJed Brown *p = link->next; 21893d8e3701SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 21903d8e3701SJed Brown break; 21913d8e3701SJed Brown } 21923d8e3701SJed Brown } 21933d8e3701SJed Brown PetscFunctionReturn(0); 21943d8e3701SJed Brown } 21953d8e3701SJed Brown 2196c833c3b5SJed Brown /*@ 2197c833c3b5SJed Brown DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd() 2198c833c3b5SJed Brown 2199c833c3b5SJed Brown Collective if any hooks are 2200c833c3b5SJed Brown 2201c833c3b5SJed Brown Input Arguments: 2202c833c3b5SJed Brown + coarse - coarser DM to use as a base 2203e91eccc2SStefano Zampini . interp - interpolation matrix, apply using MatInterpolate() 2204c833c3b5SJed Brown - fine - finer DM to update 2205c833c3b5SJed Brown 2206c833c3b5SJed Brown Level: developer 2207c833c3b5SJed Brown 2208c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate() 2209c833c3b5SJed Brown @*/ 2210c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine) 2211c833c3b5SJed Brown { 2212c833c3b5SJed Brown PetscErrorCode ierr; 2213c833c3b5SJed Brown DMRefineHookLink link; 2214c833c3b5SJed Brown 2215c833c3b5SJed Brown PetscFunctionBegin; 2216c833c3b5SJed Brown for (link=fine->refinehook; link; link=link->next) { 22178865f1eaSKarl Rupp if (link->interphook) { 22188865f1eaSKarl Rupp ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr); 22198865f1eaSKarl Rupp } 22204057135bSMatthew G Knepley } 222147c6ae99SBarry Smith PetscFunctionReturn(0); 222247c6ae99SBarry Smith } 222347c6ae99SBarry Smith 2224eb3f98d2SBarry Smith /*@ 22251f3379b2SToby Isaac DMInterpolateSolution - Interpolates a solution from a coarse mesh to a fine mesh. 22261f3379b2SToby Isaac 22271f3379b2SToby Isaac Collective on DM 22281f3379b2SToby Isaac 22291f3379b2SToby Isaac Input Arguments: 22301f3379b2SToby Isaac + coarse - coarse DM 22311f3379b2SToby Isaac . fine - fine DM 22321f3379b2SToby Isaac . interp - (optional) the matrix computed by DMCreateInterpolation(). Implementations may not need this, but if it 22331f3379b2SToby Isaac is available it can avoid some recomputation. If it is provided, MatInterpolate() will be used if 22341f3379b2SToby Isaac the coarse DM does not have a specialized implementation. 22351f3379b2SToby Isaac - coarseSol - solution on the coarse mesh 22361f3379b2SToby Isaac 22371f3379b2SToby Isaac Output Arguments: 22381f3379b2SToby Isaac . fineSol - the interpolation of coarseSol to the fine mesh 22391f3379b2SToby Isaac 22401f3379b2SToby Isaac Level: developer 22411f3379b2SToby Isaac 22421f3379b2SToby Isaac Note: This function exists because the interpolation of a solution vector between meshes is not always a linear 22431f3379b2SToby Isaac map. For example, if a boundary value problem has an inhomogeneous Dirichlet boundary condition that is compressed 22441f3379b2SToby Isaac out of the solution vector. Or if interpolation is inherently a nonlinear operation, such as a method using 22451f3379b2SToby Isaac slope-limiting reconstruction. 22461f3379b2SToby Isaac 22471f3379b2SToby Isaac .seealso DMInterpolate(), DMCreateInterpolation() 22481f3379b2SToby Isaac @*/ 22491f3379b2SToby Isaac PetscErrorCode DMInterpolateSolution(DM coarse, DM fine, Mat interp, Vec coarseSol, Vec fineSol) 22501f3379b2SToby Isaac { 22511f3379b2SToby Isaac PetscErrorCode (*interpsol)(DM,DM,Mat,Vec,Vec) = NULL; 22521f3379b2SToby Isaac PetscErrorCode ierr; 22531f3379b2SToby Isaac 22541f3379b2SToby Isaac PetscFunctionBegin; 22551f3379b2SToby Isaac PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 22561f3379b2SToby Isaac PetscValidHeaderSpecific(coarse,DM_CLASSID,2); 22571f3379b2SToby Isaac if (interp) PetscValidHeaderSpecific(interp,MAT_CLASSID,3); 22581f3379b2SToby Isaac PetscValidHeaderSpecific(coarseSol,VEC_CLASSID,4); 22591f3379b2SToby Isaac PetscValidHeaderSpecific(fineSol,VEC_CLASSID,5); 22601f3379b2SToby Isaac 22611f3379b2SToby Isaac ierr = PetscObjectQueryFunction((PetscObject)coarse,"DMInterpolateSolution_C", &interpsol);CHKERRQ(ierr); 22621f3379b2SToby Isaac if (interpsol) { 22631f3379b2SToby Isaac ierr = (*interpsol)(coarse, fine, interp, coarseSol, fineSol);CHKERRQ(ierr); 22641f3379b2SToby Isaac } else if (interp) { 22651f3379b2SToby Isaac ierr = MatInterpolate(interp, coarseSol, fineSol);CHKERRQ(ierr); 22661f3379b2SToby Isaac } else SETERRQ1(PetscObjectComm((PetscObject)coarse), PETSC_ERR_SUP, "DM %s does not implement DMInterpolateSolution()", ((PetscObject)coarse)->type_name); 22671f3379b2SToby Isaac PetscFunctionReturn(0); 22681f3379b2SToby Isaac } 22691f3379b2SToby Isaac 22701f3379b2SToby Isaac /*@ 2271aed49f88SRichard Tran Mills DMGetRefineLevel - Gets the number of refinements that have generated this DM. 2272eb3f98d2SBarry Smith 2273eb3f98d2SBarry Smith Not Collective 2274eb3f98d2SBarry Smith 2275eb3f98d2SBarry Smith Input Parameter: 2276eb3f98d2SBarry Smith . dm - the DM object 2277eb3f98d2SBarry Smith 2278eb3f98d2SBarry Smith Output Parameter: 2279eb3f98d2SBarry Smith . level - number of refinements 2280eb3f98d2SBarry Smith 2281eb3f98d2SBarry Smith Level: developer 2282eb3f98d2SBarry Smith 22836a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 2284eb3f98d2SBarry Smith 2285eb3f98d2SBarry Smith @*/ 2286eb3f98d2SBarry Smith PetscErrorCode DMGetRefineLevel(DM dm,PetscInt *level) 2287eb3f98d2SBarry Smith { 2288eb3f98d2SBarry Smith PetscFunctionBegin; 2289eb3f98d2SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2290eb3f98d2SBarry Smith *level = dm->levelup; 2291eb3f98d2SBarry Smith PetscFunctionReturn(0); 2292eb3f98d2SBarry Smith } 2293eb3f98d2SBarry Smith 2294fef3a512SBarry Smith /*@ 2295aed49f88SRichard Tran Mills DMSetRefineLevel - Sets the number of refinements that have generated this DM. 2296fef3a512SBarry Smith 2297fef3a512SBarry Smith Not Collective 2298fef3a512SBarry Smith 2299fef3a512SBarry Smith Input Parameter: 2300fef3a512SBarry Smith + dm - the DM object 2301fef3a512SBarry Smith - level - number of refinements 2302fef3a512SBarry Smith 2303fef3a512SBarry Smith Level: advanced 2304fef3a512SBarry Smith 230595452b02SPatrick Sanan Notes: 230695452b02SPatrick Sanan This value is used by PCMG to determine how many multigrid levels to use 2307fef3a512SBarry Smith 2308fef3a512SBarry Smith .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 2309fef3a512SBarry Smith 2310fef3a512SBarry Smith @*/ 2311fef3a512SBarry Smith PetscErrorCode DMSetRefineLevel(DM dm,PetscInt level) 2312fef3a512SBarry Smith { 2313fef3a512SBarry Smith PetscFunctionBegin; 2314fef3a512SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2315fef3a512SBarry Smith dm->levelup = level; 2316fef3a512SBarry Smith PetscFunctionReturn(0); 2317fef3a512SBarry Smith } 2318fef3a512SBarry Smith 2319ca3d3a14SMatthew G. Knepley PetscErrorCode DMGetBasisTransformDM_Internal(DM dm, DM *tdm) 2320ca3d3a14SMatthew G. Knepley { 2321ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2322ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2323ca3d3a14SMatthew G. Knepley PetscValidPointer(tdm, 2); 2324ca3d3a14SMatthew G. Knepley *tdm = dm->transformDM; 2325ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2326ca3d3a14SMatthew G. Knepley } 2327ca3d3a14SMatthew G. Knepley 2328ca3d3a14SMatthew G. Knepley PetscErrorCode DMGetBasisTransformVec_Internal(DM dm, Vec *tv) 2329ca3d3a14SMatthew G. Knepley { 2330ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2331ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2332ca3d3a14SMatthew G. Knepley PetscValidPointer(tv, 2); 2333ca3d3a14SMatthew G. Knepley *tv = dm->transform; 2334ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2335ca3d3a14SMatthew G. Knepley } 2336ca3d3a14SMatthew G. Knepley 2337ca3d3a14SMatthew G. Knepley /*@ 2338c0f8e1fdSMatthew G. Knepley DMHasBasisTransform - Whether we employ a basis transformation from functions in global vectors to functions in local vectors 2339ca3d3a14SMatthew G. Knepley 2340ca3d3a14SMatthew G. Knepley Input Parameter: 2341ca3d3a14SMatthew G. Knepley . dm - The DM 2342ca3d3a14SMatthew G. Knepley 2343ca3d3a14SMatthew G. Knepley Output Parameter: 2344ca3d3a14SMatthew G. Knepley . flg - PETSC_TRUE if a basis transformation should be done 2345ca3d3a14SMatthew G. Knepley 2346ca3d3a14SMatthew G. Knepley Level: developer 2347ca3d3a14SMatthew G. Knepley 2348436bc73aSJed Brown .seealso: DMPlexGlobalToLocalBasis(), DMPlexLocalToGlobalBasis(), DMPlexCreateBasisRotation() 2349ca3d3a14SMatthew G. Knepley @*/ 2350ca3d3a14SMatthew G. Knepley PetscErrorCode DMHasBasisTransform(DM dm, PetscBool *flg) 2351ca3d3a14SMatthew G. Knepley { 2352ca3d3a14SMatthew G. Knepley Vec tv; 2353ca3d3a14SMatthew G. Knepley PetscErrorCode ierr; 2354ca3d3a14SMatthew G. Knepley 2355ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2356ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2357534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 2358ca3d3a14SMatthew G. Knepley ierr = DMGetBasisTransformVec_Internal(dm, &tv);CHKERRQ(ierr); 2359ca3d3a14SMatthew G. Knepley *flg = tv ? PETSC_TRUE : PETSC_FALSE; 2360ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2361ca3d3a14SMatthew G. Knepley } 2362ca3d3a14SMatthew G. Knepley 2363ca3d3a14SMatthew G. Knepley PetscErrorCode DMConstructBasisTransform_Internal(DM dm) 2364ca3d3a14SMatthew G. Knepley { 2365ca3d3a14SMatthew G. Knepley PetscSection s, ts; 2366ca3d3a14SMatthew G. Knepley PetscScalar *ta; 2367ca3d3a14SMatthew G. Knepley PetscInt cdim, pStart, pEnd, p, Nf, f, Nc, dof; 2368ca3d3a14SMatthew G. Knepley PetscErrorCode ierr; 2369ca3d3a14SMatthew G. Knepley 2370ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2371ca3d3a14SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 237292fd8e1eSJed Brown ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr); 2373ca3d3a14SMatthew G. Knepley ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 2374ca3d3a14SMatthew G. Knepley ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr); 2375ca3d3a14SMatthew G. Knepley ierr = DMClone(dm, &dm->transformDM);CHKERRQ(ierr); 237692fd8e1eSJed Brown ierr = DMGetLocalSection(dm->transformDM, &ts);CHKERRQ(ierr); 2377ca3d3a14SMatthew G. Knepley ierr = PetscSectionSetNumFields(ts, Nf);CHKERRQ(ierr); 2378ca3d3a14SMatthew G. Knepley ierr = PetscSectionSetChart(ts, pStart, pEnd);CHKERRQ(ierr); 2379ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2380ca3d3a14SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(s, f, &Nc);CHKERRQ(ierr); 2381ca3d3a14SMatthew G. Knepley /* We could start to label fields by their transformation properties */ 2382ca3d3a14SMatthew G. Knepley if (Nc != cdim) continue; 2383ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2384ca3d3a14SMatthew G. Knepley ierr = PetscSectionGetFieldDof(s, p, f, &dof);CHKERRQ(ierr); 2385ca3d3a14SMatthew G. Knepley if (!dof) continue; 2386ca3d3a14SMatthew G. Knepley ierr = PetscSectionSetFieldDof(ts, p, f, PetscSqr(cdim));CHKERRQ(ierr); 2387ca3d3a14SMatthew G. Knepley ierr = PetscSectionAddDof(ts, p, PetscSqr(cdim));CHKERRQ(ierr); 2388ca3d3a14SMatthew G. Knepley } 2389ca3d3a14SMatthew G. Knepley } 2390ca3d3a14SMatthew G. Knepley ierr = PetscSectionSetUp(ts);CHKERRQ(ierr); 2391ca3d3a14SMatthew G. Knepley ierr = DMCreateLocalVector(dm->transformDM, &dm->transform);CHKERRQ(ierr); 2392ca3d3a14SMatthew G. Knepley ierr = VecGetArray(dm->transform, &ta);CHKERRQ(ierr); 2393ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2394ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2395ca3d3a14SMatthew G. Knepley ierr = PetscSectionGetFieldDof(ts, p, f, &dof);CHKERRQ(ierr); 2396ca3d3a14SMatthew G. Knepley if (dof) { 2397ca3d3a14SMatthew G. Knepley PetscReal x[3] = {0.0, 0.0, 0.0}; 2398ca3d3a14SMatthew G. Knepley PetscScalar *tva; 2399ca3d3a14SMatthew G. Knepley const PetscScalar *A; 2400ca3d3a14SMatthew G. Knepley 2401ca3d3a14SMatthew G. Knepley /* TODO Get quadrature point for this dual basis vector for coordinate */ 2402ca3d3a14SMatthew G. Knepley ierr = (*dm->transformGetMatrix)(dm, x, PETSC_TRUE, &A, dm->transformCtx);CHKERRQ(ierr); 2403ca3d3a14SMatthew G. Knepley ierr = DMPlexPointLocalFieldRef(dm->transformDM, p, f, ta, (void *) &tva);CHKERRQ(ierr); 2404580bdb30SBarry Smith ierr = PetscArraycpy(tva, A, PetscSqr(cdim));CHKERRQ(ierr); 2405ca3d3a14SMatthew G. Knepley } 2406ca3d3a14SMatthew G. Knepley } 2407ca3d3a14SMatthew G. Knepley } 2408ca3d3a14SMatthew G. Knepley ierr = VecRestoreArray(dm->transform, &ta);CHKERRQ(ierr); 2409ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2410ca3d3a14SMatthew G. Knepley } 2411ca3d3a14SMatthew G. Knepley 2412ca3d3a14SMatthew G. Knepley PetscErrorCode DMCopyTransform(DM dm, DM newdm) 2413ca3d3a14SMatthew G. Knepley { 2414ca3d3a14SMatthew G. Knepley PetscErrorCode ierr; 2415ca3d3a14SMatthew G. Knepley 2416ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2417ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2418ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(newdm, DM_CLASSID, 2); 2419ca3d3a14SMatthew G. Knepley newdm->transformCtx = dm->transformCtx; 2420ca3d3a14SMatthew G. Knepley newdm->transformSetUp = dm->transformSetUp; 2421ca3d3a14SMatthew G. Knepley newdm->transformDestroy = NULL; 2422ca3d3a14SMatthew G. Knepley newdm->transformGetMatrix = dm->transformGetMatrix; 2423ca3d3a14SMatthew G. Knepley if (newdm->transformSetUp) {ierr = DMConstructBasisTransform_Internal(newdm);CHKERRQ(ierr);} 2424ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2425ca3d3a14SMatthew G. Knepley } 2426ca3d3a14SMatthew G. Knepley 2427bb9467b5SJed Brown /*@C 2428baf369e7SPeter Brune DMGlobalToLocalHookAdd - adds a callback to be run when global to local is called 2429baf369e7SPeter Brune 2430baf369e7SPeter Brune Logically Collective 2431baf369e7SPeter Brune 2432baf369e7SPeter Brune Input Arguments: 2433baf369e7SPeter Brune + dm - the DM 2434baf369e7SPeter Brune . beginhook - function to run at the beginning of DMGlobalToLocalBegin() 2435baf369e7SPeter Brune . endhook - function to run after DMGlobalToLocalEnd() has completed 24360298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2437baf369e7SPeter Brune 2438baf369e7SPeter Brune Calling sequence for beginhook: 2439baf369e7SPeter Brune $ beginhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx) 2440baf369e7SPeter Brune 2441baf369e7SPeter Brune + dm - global DM 2442baf369e7SPeter Brune . g - global vector 2443baf369e7SPeter Brune . mode - mode 2444baf369e7SPeter Brune . l - local vector 2445baf369e7SPeter Brune - ctx - optional user-defined function context 2446baf369e7SPeter Brune 2447baf369e7SPeter Brune 2448baf369e7SPeter Brune Calling sequence for endhook: 2449ec4806b8SPeter Brune $ endhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx) 2450baf369e7SPeter Brune 2451baf369e7SPeter Brune + global - global DM 2452baf369e7SPeter Brune - ctx - optional user-defined function context 2453baf369e7SPeter Brune 2454baf369e7SPeter Brune Level: advanced 2455baf369e7SPeter Brune 2456baf369e7SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 2457baf369e7SPeter Brune @*/ 2458baf369e7SPeter Brune PetscErrorCode DMGlobalToLocalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx) 2459baf369e7SPeter Brune { 2460baf369e7SPeter Brune PetscErrorCode ierr; 2461baf369e7SPeter Brune DMGlobalToLocalHookLink link,*p; 2462baf369e7SPeter Brune 2463baf369e7SPeter Brune PetscFunctionBegin; 2464baf369e7SPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2465baf369e7SPeter Brune for (p=&dm->gtolhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 246695dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 2467baf369e7SPeter Brune link->beginhook = beginhook; 2468baf369e7SPeter Brune link->endhook = endhook; 2469baf369e7SPeter Brune link->ctx = ctx; 24700298fd71SBarry Smith link->next = NULL; 2471baf369e7SPeter Brune *p = link; 2472baf369e7SPeter Brune PetscFunctionReturn(0); 2473baf369e7SPeter Brune } 2474baf369e7SPeter Brune 24754c274da1SToby Isaac static PetscErrorCode DMGlobalToLocalHook_Constraints(DM dm, Vec g, InsertMode mode, Vec l, void *ctx) 24764c274da1SToby Isaac { 24774c274da1SToby Isaac Mat cMat; 24784c274da1SToby Isaac Vec cVec; 24794c274da1SToby Isaac PetscSection section, cSec; 24804c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 24814c274da1SToby Isaac PetscErrorCode ierr; 24824c274da1SToby Isaac 24834c274da1SToby Isaac PetscFunctionBegin; 24844c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 24854c274da1SToby Isaac ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr); 24864c274da1SToby Isaac if (cMat && (mode == INSERT_VALUES || mode == INSERT_ALL_VALUES || mode == INSERT_BC_VALUES)) { 24875db9a05bSToby Isaac PetscInt nRows; 24885db9a05bSToby Isaac 24895db9a05bSToby Isaac ierr = MatGetSize(cMat,&nRows,NULL);CHKERRQ(ierr); 24905db9a05bSToby Isaac if (nRows <= 0) PetscFunctionReturn(0); 249192fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 24927711e48fSToby Isaac ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr); 24934c274da1SToby Isaac ierr = MatMult(cMat,l,cVec);CHKERRQ(ierr); 24944c274da1SToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 24954c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 24964c274da1SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 24974c274da1SToby Isaac if (dof) { 24984c274da1SToby Isaac PetscScalar *vals; 24994c274da1SToby Isaac ierr = VecGetValuesSection(cVec,cSec,p,&vals);CHKERRQ(ierr); 25004c274da1SToby Isaac ierr = VecSetValuesSection(l,section,p,vals,INSERT_ALL_VALUES);CHKERRQ(ierr); 25014c274da1SToby Isaac } 25024c274da1SToby Isaac } 25034c274da1SToby Isaac ierr = VecDestroy(&cVec);CHKERRQ(ierr); 25044c274da1SToby Isaac } 25054c274da1SToby Isaac PetscFunctionReturn(0); 25064c274da1SToby Isaac } 25074c274da1SToby Isaac 250847c6ae99SBarry Smith /*@ 250901729b5cSPatrick Sanan DMGlobalToLocal - update local vectors from global vector 251001729b5cSPatrick Sanan 2511d083f849SBarry Smith Neighbor-wise Collective on dm 251201729b5cSPatrick Sanan 251301729b5cSPatrick Sanan Input Parameters: 251401729b5cSPatrick Sanan + dm - the DM object 251501729b5cSPatrick Sanan . g - the global vector 251601729b5cSPatrick Sanan . mode - INSERT_VALUES or ADD_VALUES 251701729b5cSPatrick Sanan - l - the local vector 251801729b5cSPatrick Sanan 251901729b5cSPatrick Sanan Notes: 252001729b5cSPatrick Sanan The communication involved in this update can be overlapped with computation by using 252101729b5cSPatrick Sanan DMGlobalToLocalBegin() and DMGlobalToLocalEnd(). 252201729b5cSPatrick Sanan 252301729b5cSPatrick Sanan Level: beginner 252401729b5cSPatrick Sanan 252501729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd() 252601729b5cSPatrick Sanan 252701729b5cSPatrick Sanan @*/ 252801729b5cSPatrick Sanan PetscErrorCode DMGlobalToLocal(DM dm,Vec g,InsertMode mode,Vec l) 252901729b5cSPatrick Sanan { 253001729b5cSPatrick Sanan PetscErrorCode ierr; 253101729b5cSPatrick Sanan 253201729b5cSPatrick Sanan PetscFunctionBegin; 253301729b5cSPatrick Sanan ierr = DMGlobalToLocalBegin(dm,g,mode,l);CHKERRQ(ierr); 253401729b5cSPatrick Sanan ierr = DMGlobalToLocalEnd(dm,g,mode,l);CHKERRQ(ierr); 253501729b5cSPatrick Sanan PetscFunctionReturn(0); 253601729b5cSPatrick Sanan } 253701729b5cSPatrick Sanan 253801729b5cSPatrick Sanan /*@ 253947c6ae99SBarry Smith DMGlobalToLocalBegin - Begins updating local vectors from global vector 254047c6ae99SBarry Smith 2541d083f849SBarry Smith Neighbor-wise Collective on dm 254247c6ae99SBarry Smith 254347c6ae99SBarry Smith Input Parameters: 254447c6ae99SBarry Smith + dm - the DM object 254547c6ae99SBarry Smith . g - the global vector 254647c6ae99SBarry Smith . mode - INSERT_VALUES or ADD_VALUES 254747c6ae99SBarry Smith - l - the local vector 254847c6ae99SBarry Smith 254901729b5cSPatrick Sanan Level: intermediate 255047c6ae99SBarry Smith 255101729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd() 255247c6ae99SBarry Smith 255347c6ae99SBarry Smith @*/ 25547087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l) 255547c6ae99SBarry Smith { 25567128ae9fSMatthew G Knepley PetscSF sf; 255747c6ae99SBarry Smith PetscErrorCode ierr; 2558baf369e7SPeter Brune DMGlobalToLocalHookLink link; 255947c6ae99SBarry Smith 2560d0295fc0SJunchao Zhang 256147c6ae99SBarry Smith PetscFunctionBegin; 2562171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2563baf369e7SPeter Brune for (link=dm->gtolhook; link; link=link->next) { 25648865f1eaSKarl Rupp if (link->beginhook) { 25658865f1eaSKarl Rupp ierr = (*link->beginhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr); 25668865f1eaSKarl Rupp } 2567baf369e7SPeter Brune } 25681bb6d2a8SBarry Smith ierr = DMGetSectionSF(dm, &sf);CHKERRQ(ierr); 25697128ae9fSMatthew G Knepley if (sf) { 2570ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2571ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2572d0295fc0SJunchao Zhang PetscMemType lmtype,gmtype; 25737128ae9fSMatthew G Knepley 257482f516ccSBarry Smith if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 2575a256111fSJunchao Zhang ierr = VecGetArrayAndMemType(l, &lArray, &lmtype);CHKERRQ(ierr); 2576a256111fSJunchao Zhang ierr = VecGetArrayReadAndMemType(g, &gArray, &gmtype);CHKERRQ(ierr); 2577ad227feaSJunchao Zhang ierr = PetscSFBcastWithMemTypeBegin(sf, MPIU_SCALAR, gmtype, gArray, lmtype, lArray, MPI_REPLACE);CHKERRQ(ierr); 2578a256111fSJunchao Zhang ierr = VecRestoreArrayAndMemType(l, &lArray);CHKERRQ(ierr); 2579a256111fSJunchao Zhang ierr = VecRestoreArrayReadAndMemType(g, &gArray);CHKERRQ(ierr); 25807128ae9fSMatthew G Knepley } else { 258133907cc2SStefano Zampini if (!dm->ops->globaltolocalbegin) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMGlobalToLocalBegin() for type %s",((PetscObject)dm)->type_name); 2582843c4018SMatthew G Knepley ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 25837128ae9fSMatthew G Knepley } 258447c6ae99SBarry Smith PetscFunctionReturn(0); 258547c6ae99SBarry Smith } 258647c6ae99SBarry Smith 258747c6ae99SBarry Smith /*@ 258847c6ae99SBarry Smith DMGlobalToLocalEnd - Ends updating local vectors from global vector 258947c6ae99SBarry Smith 2590d083f849SBarry Smith Neighbor-wise Collective on dm 259147c6ae99SBarry Smith 259247c6ae99SBarry Smith Input Parameters: 259347c6ae99SBarry Smith + dm - the DM object 259447c6ae99SBarry Smith . g - the global vector 259547c6ae99SBarry Smith . mode - INSERT_VALUES or ADD_VALUES 259647c6ae99SBarry Smith - l - the local vector 259747c6ae99SBarry Smith 259801729b5cSPatrick Sanan Level: intermediate 259947c6ae99SBarry Smith 260001729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd() 260147c6ae99SBarry Smith 260247c6ae99SBarry Smith @*/ 26037087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l) 260447c6ae99SBarry Smith { 26057128ae9fSMatthew G Knepley PetscSF sf; 260647c6ae99SBarry Smith PetscErrorCode ierr; 2607ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2608ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2609ca3d3a14SMatthew G. Knepley PetscBool transform; 2610baf369e7SPeter Brune DMGlobalToLocalHookLink link; 2611d0295fc0SJunchao Zhang PetscMemType lmtype,gmtype; 261247c6ae99SBarry Smith 261347c6ae99SBarry Smith PetscFunctionBegin; 2614171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 26151bb6d2a8SBarry Smith ierr = DMGetSectionSF(dm, &sf);CHKERRQ(ierr); 2616ca3d3a14SMatthew G. Knepley ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr); 26177128ae9fSMatthew G Knepley if (sf) { 261882f516ccSBarry Smith if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 26197128ae9fSMatthew G Knepley 2620a256111fSJunchao Zhang ierr = VecGetArrayAndMemType(l, &lArray, &lmtype);CHKERRQ(ierr); 2621a256111fSJunchao Zhang ierr = VecGetArrayReadAndMemType(g, &gArray, &gmtype);CHKERRQ(ierr); 2622ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray,MPI_REPLACE);CHKERRQ(ierr); 2623a256111fSJunchao Zhang ierr = VecRestoreArrayAndMemType(l, &lArray);CHKERRQ(ierr); 2624a256111fSJunchao Zhang ierr = VecRestoreArrayReadAndMemType(g, &gArray);CHKERRQ(ierr); 2625ca3d3a14SMatthew G. Knepley if (transform) {ierr = DMPlexGlobalToLocalBasis(dm, l);CHKERRQ(ierr);} 26267128ae9fSMatthew G Knepley } else { 262733907cc2SStefano Zampini if (!dm->ops->globaltolocalend) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMGlobalToLocalEnd() for type %s",((PetscObject)dm)->type_name); 2628843c4018SMatthew G Knepley ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 26297128ae9fSMatthew G Knepley } 26304c274da1SToby Isaac ierr = DMGlobalToLocalHook_Constraints(dm,g,mode,l,NULL);CHKERRQ(ierr); 2631baf369e7SPeter Brune for (link=dm->gtolhook; link; link=link->next) { 2632baf369e7SPeter Brune if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);} 2633baf369e7SPeter Brune } 263447c6ae99SBarry Smith PetscFunctionReturn(0); 263547c6ae99SBarry Smith } 263647c6ae99SBarry Smith 2637d4d07f1eSToby Isaac /*@C 2638d4d07f1eSToby Isaac DMLocalToGlobalHookAdd - adds a callback to be run when a local to global is called 2639d4d07f1eSToby Isaac 2640d4d07f1eSToby Isaac Logically Collective 2641d4d07f1eSToby Isaac 2642d4d07f1eSToby Isaac Input Arguments: 2643d4d07f1eSToby Isaac + dm - the DM 2644d4d07f1eSToby Isaac . beginhook - function to run at the beginning of DMLocalToGlobalBegin() 2645d4d07f1eSToby Isaac . endhook - function to run after DMLocalToGlobalEnd() has completed 2646d4d07f1eSToby Isaac - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2647d4d07f1eSToby Isaac 2648d4d07f1eSToby Isaac Calling sequence for beginhook: 2649d4d07f1eSToby Isaac $ beginhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx) 2650d4d07f1eSToby Isaac 2651d4d07f1eSToby Isaac + dm - global DM 2652d4d07f1eSToby Isaac . l - local vector 2653d4d07f1eSToby Isaac . mode - mode 2654d4d07f1eSToby Isaac . g - global vector 2655d4d07f1eSToby Isaac - ctx - optional user-defined function context 2656d4d07f1eSToby Isaac 2657d4d07f1eSToby Isaac 2658d4d07f1eSToby Isaac Calling sequence for endhook: 2659d4d07f1eSToby Isaac $ endhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx) 2660d4d07f1eSToby Isaac 2661d4d07f1eSToby Isaac + global - global DM 2662d4d07f1eSToby Isaac . l - local vector 2663d4d07f1eSToby Isaac . mode - mode 2664d4d07f1eSToby Isaac . g - global vector 2665d4d07f1eSToby Isaac - ctx - optional user-defined function context 2666d4d07f1eSToby Isaac 2667d4d07f1eSToby Isaac Level: advanced 2668d4d07f1eSToby Isaac 2669d4d07f1eSToby Isaac .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 2670d4d07f1eSToby Isaac @*/ 2671d4d07f1eSToby Isaac PetscErrorCode DMLocalToGlobalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx) 2672d4d07f1eSToby Isaac { 2673d4d07f1eSToby Isaac PetscErrorCode ierr; 2674d4d07f1eSToby Isaac DMLocalToGlobalHookLink link,*p; 2675d4d07f1eSToby Isaac 2676d4d07f1eSToby Isaac PetscFunctionBegin; 2677d4d07f1eSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2678d4d07f1eSToby Isaac for (p=&dm->ltoghook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 267995dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 2680d4d07f1eSToby Isaac link->beginhook = beginhook; 2681d4d07f1eSToby Isaac link->endhook = endhook; 2682d4d07f1eSToby Isaac link->ctx = ctx; 2683d4d07f1eSToby Isaac link->next = NULL; 2684d4d07f1eSToby Isaac *p = link; 2685d4d07f1eSToby Isaac PetscFunctionReturn(0); 2686d4d07f1eSToby Isaac } 2687d4d07f1eSToby Isaac 26884c274da1SToby Isaac static PetscErrorCode DMLocalToGlobalHook_Constraints(DM dm, Vec l, InsertMode mode, Vec g, void *ctx) 26894c274da1SToby Isaac { 26904c274da1SToby Isaac Mat cMat; 26914c274da1SToby Isaac Vec cVec; 26924c274da1SToby Isaac PetscSection section, cSec; 26934c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 26944c274da1SToby Isaac PetscErrorCode ierr; 26954c274da1SToby Isaac 26964c274da1SToby Isaac PetscFunctionBegin; 26974c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 26984c274da1SToby Isaac ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr); 26994c274da1SToby Isaac if (cMat && (mode == ADD_VALUES || mode == ADD_ALL_VALUES || mode == ADD_BC_VALUES)) { 27005db9a05bSToby Isaac PetscInt nRows; 27015db9a05bSToby Isaac 27025db9a05bSToby Isaac ierr = MatGetSize(cMat,&nRows,NULL);CHKERRQ(ierr); 27035db9a05bSToby Isaac if (nRows <= 0) PetscFunctionReturn(0); 270492fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 27057711e48fSToby Isaac ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr); 27064c274da1SToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 27074c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 27084c274da1SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 27094c274da1SToby Isaac if (dof) { 27104c274da1SToby Isaac PetscInt d; 27114c274da1SToby Isaac PetscScalar *vals; 27124c274da1SToby Isaac ierr = VecGetValuesSection(l,section,p,&vals);CHKERRQ(ierr); 27134c274da1SToby Isaac ierr = VecSetValuesSection(cVec,cSec,p,vals,mode);CHKERRQ(ierr); 27144c274da1SToby Isaac /* for this to be the true transpose, we have to zero the values that 27154c274da1SToby Isaac * we just extracted */ 27164c274da1SToby Isaac for (d = 0; d < dof; d++) { 27174c274da1SToby Isaac vals[d] = 0.; 27184c274da1SToby Isaac } 27194c274da1SToby Isaac } 27204c274da1SToby Isaac } 27214c274da1SToby Isaac ierr = MatMultTransposeAdd(cMat,cVec,l,l);CHKERRQ(ierr); 27224c274da1SToby Isaac ierr = VecDestroy(&cVec);CHKERRQ(ierr); 27234c274da1SToby Isaac } 27244c274da1SToby Isaac PetscFunctionReturn(0); 27254c274da1SToby Isaac } 272601729b5cSPatrick Sanan /*@ 272701729b5cSPatrick Sanan DMLocalToGlobal - updates global vectors from local vectors 272801729b5cSPatrick Sanan 2729d083f849SBarry Smith Neighbor-wise Collective on dm 273001729b5cSPatrick Sanan 273101729b5cSPatrick Sanan Input Parameters: 273201729b5cSPatrick Sanan + dm - the DM object 273301729b5cSPatrick Sanan . l - the local vector 273401729b5cSPatrick 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. 273501729b5cSPatrick Sanan - g - the global vector 273601729b5cSPatrick Sanan 273701729b5cSPatrick Sanan Notes: 273801729b5cSPatrick Sanan The communication involved in this update can be overlapped with computation by using 273901729b5cSPatrick Sanan DMLocalToGlobalBegin() and DMLocalToGlobalEnd(). 274001729b5cSPatrick Sanan 274101729b5cSPatrick Sanan In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation. 274201729b5cSPatrick 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. 274301729b5cSPatrick Sanan 274401729b5cSPatrick Sanan Level: beginner 274501729b5cSPatrick Sanan 274601729b5cSPatrick Sanan .seealso DMLocalToGlobalBegin(), DMLocalToGlobalEnd(), DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin() 274701729b5cSPatrick Sanan 274801729b5cSPatrick Sanan @*/ 274901729b5cSPatrick Sanan PetscErrorCode DMLocalToGlobal(DM dm,Vec l,InsertMode mode,Vec g) 275001729b5cSPatrick Sanan { 275101729b5cSPatrick Sanan PetscErrorCode ierr; 275201729b5cSPatrick Sanan 275301729b5cSPatrick Sanan PetscFunctionBegin; 275401729b5cSPatrick Sanan ierr = DMLocalToGlobalBegin(dm,l,mode,g);CHKERRQ(ierr); 275501729b5cSPatrick Sanan ierr = DMLocalToGlobalEnd(dm,l,mode,g);CHKERRQ(ierr); 275601729b5cSPatrick Sanan PetscFunctionReturn(0); 275701729b5cSPatrick Sanan } 27584c274da1SToby Isaac 275947c6ae99SBarry Smith /*@ 276001729b5cSPatrick Sanan DMLocalToGlobalBegin - begins updating global vectors from local vectors 27619a42bb27SBarry Smith 2762d083f849SBarry Smith Neighbor-wise Collective on dm 27639a42bb27SBarry Smith 27649a42bb27SBarry Smith Input Parameters: 27659a42bb27SBarry Smith + dm - the DM object 2766f6813fd5SJed Brown . l - the local vector 27671eb28f2eSBarry 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. 27681eb28f2eSBarry Smith - g - the global vector 27699a42bb27SBarry Smith 277095452b02SPatrick Sanan Notes: 277195452b02SPatrick Sanan In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation. 277284330215SMatthew 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. 27739a42bb27SBarry Smith 277401729b5cSPatrick Sanan Level: intermediate 27759a42bb27SBarry Smith 277601729b5cSPatrick Sanan .seealso DMLocalToGlobal(), DMLocalToGlobalEnd(), DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin() 27779a42bb27SBarry Smith 27789a42bb27SBarry Smith @*/ 27797087cfbeSBarry Smith PetscErrorCode DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g) 27809a42bb27SBarry Smith { 27817128ae9fSMatthew G Knepley PetscSF sf; 278284330215SMatthew G. Knepley PetscSection s, gs; 2783d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 2784ca3d3a14SMatthew G. Knepley Vec tmpl; 2785ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 2786ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 2787fa88e482SJed Brown PetscBool isInsert, transform, l_inplace = PETSC_FALSE, g_inplace = PETSC_FALSE; 278884330215SMatthew G. Knepley PetscErrorCode ierr; 2789d0295fc0SJunchao Zhang PetscMemType lmtype=PETSC_MEMTYPE_HOST,gmtype=PETSC_MEMTYPE_HOST; 27909a42bb27SBarry Smith 27919a42bb27SBarry Smith PetscFunctionBegin; 2792171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2793d4d07f1eSToby Isaac for (link=dm->ltoghook; link; link=link->next) { 2794d4d07f1eSToby Isaac if (link->beginhook) { 2795d4d07f1eSToby Isaac ierr = (*link->beginhook)(dm,l,mode,g,link->ctx);CHKERRQ(ierr); 2796d4d07f1eSToby Isaac } 2797d4d07f1eSToby Isaac } 27984c274da1SToby Isaac ierr = DMLocalToGlobalHook_Constraints(dm,l,mode,g,NULL);CHKERRQ(ierr); 27991bb6d2a8SBarry Smith ierr = DMGetSectionSF(dm, &sf);CHKERRQ(ierr); 280092fd8e1eSJed Brown ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr); 28017128ae9fSMatthew G Knepley switch (mode) { 28027128ae9fSMatthew G Knepley case INSERT_VALUES: 28037128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 2804304ab55fSMatthew G. Knepley case INSERT_BC_VALUES: 280584330215SMatthew G. Knepley isInsert = PETSC_TRUE; break; 28067128ae9fSMatthew G Knepley case ADD_VALUES: 28077128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 2808304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 280984330215SMatthew G. Knepley isInsert = PETSC_FALSE; break; 28107128ae9fSMatthew G Knepley default: 281182f516ccSBarry Smith SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 28127128ae9fSMatthew G Knepley } 2813ca3d3a14SMatthew G. Knepley if ((sf && !isInsert) || (s && isInsert)) { 2814ca3d3a14SMatthew G. Knepley ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr); 2815ca3d3a14SMatthew G. Knepley if (transform) { 2816ca3d3a14SMatthew G. Knepley ierr = DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr); 2817ca3d3a14SMatthew G. Knepley ierr = VecCopy(l, tmpl);CHKERRQ(ierr); 2818ca3d3a14SMatthew G. Knepley ierr = DMPlexLocalToGlobalBasis(dm, tmpl);CHKERRQ(ierr); 2819ca3d3a14SMatthew G. Knepley ierr = VecGetArrayRead(tmpl, &lArray);CHKERRQ(ierr); 2820fa88e482SJed Brown } else if (isInsert) { 2821ae5cfb4aSMatthew G. Knepley ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr); 2822fa88e482SJed Brown } else { 2823a256111fSJunchao Zhang ierr = VecGetArrayReadAndMemType(l, &lArray, &lmtype);CHKERRQ(ierr); 2824fa88e482SJed Brown l_inplace = PETSC_TRUE; 2825ca3d3a14SMatthew G. Knepley } 2826fa88e482SJed Brown if (s && isInsert) { 28277128ae9fSMatthew G Knepley ierr = VecGetArray(g, &gArray);CHKERRQ(ierr); 2828fa88e482SJed Brown } else { 2829a256111fSJunchao Zhang ierr = VecGetArrayAndMemType(g, &gArray, &gmtype);CHKERRQ(ierr); 2830fa88e482SJed Brown g_inplace = PETSC_TRUE; 2831fa88e482SJed Brown } 2832ca3d3a14SMatthew G. Knepley if (sf && !isInsert) { 2833d0295fc0SJunchao Zhang ierr = PetscSFReduceWithMemTypeBegin(sf, MPIU_SCALAR, lmtype, lArray, gmtype, gArray, MPIU_SUM);CHKERRQ(ierr); 283484330215SMatthew G. Knepley } else if (s && isInsert) { 283584330215SMatthew G. Knepley PetscInt gStart, pStart, pEnd, p; 283684330215SMatthew G. Knepley 2837e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, &gs);CHKERRQ(ierr); 283884330215SMatthew G. Knepley ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 283984330215SMatthew G. Knepley ierr = VecGetOwnershipRange(g, &gStart, NULL);CHKERRQ(ierr); 284084330215SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2841b3b16f48SMatthew G. Knepley PetscInt dof, gdof, cdof, gcdof, off, goff, d, e; 284284330215SMatthew G. Knepley 284384330215SMatthew G. Knepley ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 284403442857SMatthew G. Knepley ierr = PetscSectionGetDof(gs, p, &gdof);CHKERRQ(ierr); 284584330215SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 2846b3b16f48SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(gs, p, &gcdof);CHKERRQ(ierr); 284784330215SMatthew G. Knepley ierr = PetscSectionGetOffset(s, p, &off);CHKERRQ(ierr); 284884330215SMatthew G. Knepley ierr = PetscSectionGetOffset(gs, p, &goff);CHKERRQ(ierr); 2849b3b16f48SMatthew G. Knepley /* Ignore off-process data and points with no global data */ 285003442857SMatthew G. Knepley if (!gdof || goff < 0) continue; 2851b3b16f48SMatthew 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); 2852b3b16f48SMatthew G. Knepley /* If no constraints are enforced in the global vector */ 2853b3b16f48SMatthew G. Knepley if (!gcdof) { 285484330215SMatthew G. Knepley for (d = 0; d < dof; ++d) gArray[goff-gStart+d] = lArray[off+d]; 2855b3b16f48SMatthew G. Knepley /* If constraints are enforced in the global vector */ 2856b3b16f48SMatthew G. Knepley } else if (cdof == gcdof) { 285784330215SMatthew G. Knepley const PetscInt *cdofs; 285884330215SMatthew G. Knepley PetscInt cind = 0; 285984330215SMatthew G. Knepley 286084330215SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(s, p, &cdofs);CHKERRQ(ierr); 2861b3b16f48SMatthew G. Knepley for (d = 0, e = 0; d < dof; ++d) { 286284330215SMatthew G. Knepley if ((cind < cdof) && (d == cdofs[cind])) {++cind; continue;} 2863b3b16f48SMatthew G. Knepley gArray[goff-gStart+e++] = lArray[off+d]; 286484330215SMatthew G. Knepley } 2865b3b16f48SMatthew 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); 286684330215SMatthew G. Knepley } 2867ca3d3a14SMatthew G. Knepley } 2868fa88e482SJed Brown if (g_inplace) { 2869a256111fSJunchao Zhang ierr = VecRestoreArrayAndMemType(g, &gArray);CHKERRQ(ierr); 2870fa88e482SJed Brown } else { 28717128ae9fSMatthew G Knepley ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr); 2872fa88e482SJed Brown } 2873ca3d3a14SMatthew G. Knepley if (transform) { 2874ca3d3a14SMatthew G. Knepley ierr = VecRestoreArrayRead(tmpl, &lArray);CHKERRQ(ierr); 2875ca3d3a14SMatthew G. Knepley ierr = DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr); 2876fa88e482SJed Brown } else if (l_inplace) { 2877a256111fSJunchao Zhang ierr = VecRestoreArrayReadAndMemType(l, &lArray);CHKERRQ(ierr); 2878ca3d3a14SMatthew G. Knepley } else { 2879ca3d3a14SMatthew G. Knepley ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr); 2880ca3d3a14SMatthew G. Knepley } 28817128ae9fSMatthew G Knepley } else { 2882b9d85ea2SLisandro Dalcin if (!dm->ops->localtoglobalbegin) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMLocalToGlobalBegin() for type %s",((PetscObject)dm)->type_name); 2883843c4018SMatthew G Knepley ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr); 28847128ae9fSMatthew G Knepley } 28859a42bb27SBarry Smith PetscFunctionReturn(0); 28869a42bb27SBarry Smith } 28879a42bb27SBarry Smith 28889a42bb27SBarry Smith /*@ 28899a42bb27SBarry Smith DMLocalToGlobalEnd - updates global vectors from local vectors 289047c6ae99SBarry Smith 2891d083f849SBarry Smith Neighbor-wise Collective on dm 289247c6ae99SBarry Smith 289347c6ae99SBarry Smith Input Parameters: 289447c6ae99SBarry Smith + dm - the DM object 2895f6813fd5SJed Brown . l - the local vector 289647c6ae99SBarry Smith . mode - INSERT_VALUES or ADD_VALUES 2897f6813fd5SJed Brown - g - the global vector 289847c6ae99SBarry Smith 289901729b5cSPatrick Sanan Level: intermediate 290047c6ae99SBarry Smith 2901e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd() 290247c6ae99SBarry Smith 290347c6ae99SBarry Smith @*/ 29047087cfbeSBarry Smith PetscErrorCode DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g) 290547c6ae99SBarry Smith { 29067128ae9fSMatthew G Knepley PetscSF sf; 290784330215SMatthew G. Knepley PetscSection s; 2908d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 2909ca3d3a14SMatthew G. Knepley PetscBool isInsert, transform; 291084330215SMatthew G. Knepley PetscErrorCode ierr; 291147c6ae99SBarry Smith 291247c6ae99SBarry Smith PetscFunctionBegin; 2913171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 29141bb6d2a8SBarry Smith ierr = DMGetSectionSF(dm, &sf);CHKERRQ(ierr); 291592fd8e1eSJed Brown ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr); 29167128ae9fSMatthew G Knepley switch (mode) { 29177128ae9fSMatthew G Knepley case INSERT_VALUES: 29187128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 291984330215SMatthew G. Knepley isInsert = PETSC_TRUE; break; 29207128ae9fSMatthew G Knepley case ADD_VALUES: 29217128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 292284330215SMatthew G. Knepley isInsert = PETSC_FALSE; break; 29237128ae9fSMatthew G Knepley default: 292482f516ccSBarry Smith SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 29257128ae9fSMatthew G Knepley } 292684330215SMatthew G. Knepley if (sf && !isInsert) { 2927ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 2928ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 2929ca3d3a14SMatthew G. Knepley Vec tmpl; 293084330215SMatthew G. Knepley 2931ca3d3a14SMatthew G. Knepley ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr); 2932ca3d3a14SMatthew G. Knepley if (transform) { 2933ca3d3a14SMatthew G. Knepley ierr = DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr); 2934ca3d3a14SMatthew G. Knepley ierr = VecGetArrayRead(tmpl, &lArray);CHKERRQ(ierr); 2935ca3d3a14SMatthew G. Knepley } else { 2936a256111fSJunchao Zhang ierr = VecGetArrayReadAndMemType(l, &lArray, NULL);CHKERRQ(ierr); 2937ca3d3a14SMatthew G. Knepley } 2938a256111fSJunchao Zhang ierr = VecGetArrayAndMemType(g, &gArray, NULL);CHKERRQ(ierr); 2939a9b180a6SBarry Smith ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM);CHKERRQ(ierr); 2940ca3d3a14SMatthew G. Knepley if (transform) { 2941ca3d3a14SMatthew G. Knepley ierr = VecRestoreArrayRead(tmpl, &lArray);CHKERRQ(ierr); 2942ca3d3a14SMatthew G. Knepley ierr = DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr); 2943ca3d3a14SMatthew G. Knepley } else { 2944a256111fSJunchao Zhang ierr = VecRestoreArrayReadAndMemType(l, &lArray);CHKERRQ(ierr); 2945ca3d3a14SMatthew G. Knepley } 2946a256111fSJunchao Zhang ierr = VecRestoreArrayAndMemType(g, &gArray);CHKERRQ(ierr); 294784330215SMatthew G. Knepley } else if (s && isInsert) { 29487128ae9fSMatthew G Knepley } else { 2949b9d85ea2SLisandro Dalcin if (!dm->ops->localtoglobalend) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMLocalToGlobalEnd() for type %s",((PetscObject)dm)->type_name); 2950843c4018SMatthew G Knepley ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr); 29517128ae9fSMatthew G Knepley } 2952d4d07f1eSToby Isaac for (link=dm->ltoghook; link; link=link->next) { 2953d4d07f1eSToby Isaac if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);} 2954d4d07f1eSToby Isaac } 295547c6ae99SBarry Smith PetscFunctionReturn(0); 295647c6ae99SBarry Smith } 295747c6ae99SBarry Smith 2958f089877aSRichard Tran Mills /*@ 2959bc0a1609SRichard Tran Mills DMLocalToLocalBegin - Maps from a local vector (including ghost points 2960bc0a1609SRichard Tran Mills that contain irrelevant values) to another local vector where the ghost 2961d78e899eSRichard Tran Mills points in the second are set correctly. Must be followed by DMLocalToLocalEnd(). 2962f089877aSRichard Tran Mills 2963d083f849SBarry Smith Neighbor-wise Collective on dm 2964f089877aSRichard Tran Mills 2965f089877aSRichard Tran Mills Input Parameters: 2966f089877aSRichard Tran Mills + dm - the DM object 2967bc0a1609SRichard Tran Mills . g - the original local vector 2968bc0a1609SRichard Tran Mills - mode - one of INSERT_VALUES or ADD_VALUES 2969f089877aSRichard Tran Mills 2970bc0a1609SRichard Tran Mills Output Parameter: 2971bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 2972f089877aSRichard Tran Mills 2973f089877aSRichard Tran Mills Level: intermediate 2974f089877aSRichard Tran Mills 2975bc0a1609SRichard Tran Mills Notes: 2976bc0a1609SRichard Tran Mills The local vectors used here need not be the same as those 2977bc0a1609SRichard Tran Mills obtained from DMCreateLocalVector(), BUT they 2978bc0a1609SRichard Tran Mills must have the same parallel data layout; they could, for example, be 2979bc0a1609SRichard Tran Mills obtained with VecDuplicate() from the DM originating vectors. 2980bc0a1609SRichard Tran Mills 2981bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalEnd(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 2982f089877aSRichard Tran Mills 2983f089877aSRichard Tran Mills @*/ 2984f089877aSRichard Tran Mills PetscErrorCode DMLocalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l) 2985f089877aSRichard Tran Mills { 2986f089877aSRichard Tran Mills PetscErrorCode ierr; 2987f089877aSRichard Tran Mills 2988f089877aSRichard Tran Mills PetscFunctionBegin; 2989f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2990bb358533SPatrick Sanan if (!dm->ops->localtolocalbegin) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM does not support local to local maps"); 2991f089877aSRichard Tran Mills ierr = (*dm->ops->localtolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 2992f089877aSRichard Tran Mills PetscFunctionReturn(0); 2993f089877aSRichard Tran Mills } 2994f089877aSRichard Tran Mills 2995f089877aSRichard Tran Mills /*@ 2996bc0a1609SRichard Tran Mills DMLocalToLocalEnd - Maps from a local vector (including ghost points 2997bc0a1609SRichard Tran Mills that contain irrelevant values) to another local vector where the ghost 2998d78e899eSRichard Tran Mills points in the second are set correctly. Must be preceded by DMLocalToLocalBegin(). 2999f089877aSRichard Tran Mills 3000d083f849SBarry Smith Neighbor-wise Collective on dm 3001f089877aSRichard Tran Mills 3002f089877aSRichard Tran Mills Input Parameters: 3003bc0a1609SRichard Tran Mills + da - the DM object 3004bc0a1609SRichard Tran Mills . g - the original local vector 3005bc0a1609SRichard Tran Mills - mode - one of INSERT_VALUES or ADD_VALUES 3006f089877aSRichard Tran Mills 3007bc0a1609SRichard Tran Mills Output Parameter: 3008bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 3009f089877aSRichard Tran Mills 3010f089877aSRichard Tran Mills Level: intermediate 3011f089877aSRichard Tran Mills 3012bc0a1609SRichard Tran Mills Notes: 3013bc0a1609SRichard Tran Mills The local vectors used here need not be the same as those 3014bc0a1609SRichard Tran Mills obtained from DMCreateLocalVector(), BUT they 3015bc0a1609SRichard Tran Mills must have the same parallel data layout; they could, for example, be 3016bc0a1609SRichard Tran Mills obtained with VecDuplicate() from the DM originating vectors. 3017bc0a1609SRichard Tran Mills 3018bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalBegin(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 3019f089877aSRichard Tran Mills 3020f089877aSRichard Tran Mills @*/ 3021f089877aSRichard Tran Mills PetscErrorCode DMLocalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l) 3022f089877aSRichard Tran Mills { 3023f089877aSRichard Tran Mills PetscErrorCode ierr; 3024f089877aSRichard Tran Mills 3025f089877aSRichard Tran Mills PetscFunctionBegin; 3026f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3027bb358533SPatrick Sanan if (!dm->ops->localtolocalend) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM does not support local to local maps"); 3028f089877aSRichard Tran Mills ierr = (*dm->ops->localtolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 3029f089877aSRichard Tran Mills PetscFunctionReturn(0); 3030f089877aSRichard Tran Mills } 3031f089877aSRichard Tran Mills 3032f089877aSRichard Tran Mills 303347c6ae99SBarry Smith /*@ 303447c6ae99SBarry Smith DMCoarsen - Coarsens a DM object 303547c6ae99SBarry Smith 3036d083f849SBarry Smith Collective on dm 303747c6ae99SBarry Smith 303847c6ae99SBarry Smith Input Parameter: 303947c6ae99SBarry Smith + dm - the DM object 304091d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL) 304147c6ae99SBarry Smith 304247c6ae99SBarry Smith Output Parameter: 304347c6ae99SBarry Smith . dmc - the coarsened DM 304447c6ae99SBarry Smith 304547c6ae99SBarry Smith Level: developer 304647c6ae99SBarry Smith 3047e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 304847c6ae99SBarry Smith 304947c6ae99SBarry Smith @*/ 30507087cfbeSBarry Smith PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc) 305147c6ae99SBarry Smith { 305247c6ae99SBarry Smith PetscErrorCode ierr; 3053b17ce1afSJed Brown DMCoarsenHookLink link; 305447c6ae99SBarry Smith 305547c6ae99SBarry Smith PetscFunctionBegin; 3056171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3057b9d85ea2SLisandro Dalcin if (!dm->ops->coarsen) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCoarsen",((PetscObject)dm)->type_name); 305847a35634SPatrick Farrell ierr = PetscLogEventBegin(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr); 305947c6ae99SBarry Smith ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr); 3060b9d85ea2SLisandro Dalcin if (*dmc) { 3061a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dm,*dmc);CHKERRQ(ierr); 306243842a1eSJed Brown (*dmc)->ops->creatematrix = dm->ops->creatematrix; 30638cd211a4SJed Brown ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr); 3064644e2e5bSBarry Smith (*dmc)->ctx = dm->ctx; 30650598a293SJed Brown (*dmc)->levelup = dm->levelup; 3066656b349aSBarry Smith (*dmc)->leveldown = dm->leveldown + 1; 3067e4b4b23bSJed Brown ierr = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr); 3068b17ce1afSJed Brown for (link=dm->coarsenhook; link; link=link->next) { 3069b17ce1afSJed Brown if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);} 3070b17ce1afSJed Brown } 3071b9d85ea2SLisandro Dalcin } 307247a35634SPatrick Farrell ierr = PetscLogEventEnd(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr); 3073b9d85ea2SLisandro Dalcin if (!(*dmc)) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "NULL coarse mesh produced"); 3074b17ce1afSJed Brown PetscFunctionReturn(0); 3075b17ce1afSJed Brown } 3076b17ce1afSJed Brown 3077bb9467b5SJed Brown /*@C 3078b17ce1afSJed Brown DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid 3079b17ce1afSJed Brown 3080b17ce1afSJed Brown Logically Collective 3081b17ce1afSJed Brown 3082b17ce1afSJed Brown Input Arguments: 3083b17ce1afSJed Brown + fine - nonlinear solver context on which to run a hook when restricting to a coarser level 3084b17ce1afSJed Brown . coarsenhook - function to run when setting up a coarser level 3085b17ce1afSJed Brown . restricthook - function to run to update data on coarser levels (once per SNESSolve()) 30860298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3087b17ce1afSJed Brown 3088b17ce1afSJed Brown Calling sequence of coarsenhook: 3089b17ce1afSJed Brown $ coarsenhook(DM fine,DM coarse,void *ctx); 3090b17ce1afSJed Brown 3091b17ce1afSJed Brown + fine - fine level DM 3092b17ce1afSJed Brown . coarse - coarse level DM to restrict problem to 3093b17ce1afSJed Brown - ctx - optional user-defined function context 3094b17ce1afSJed Brown 3095b17ce1afSJed Brown Calling sequence for restricthook: 3096c833c3b5SJed Brown $ restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx) 3097b17ce1afSJed Brown 3098b17ce1afSJed Brown + fine - fine level DM 3099b17ce1afSJed Brown . mrestrict - matrix restricting a fine-level solution to the coarse grid 3100c833c3b5SJed Brown . rscale - scaling vector for restriction 3101c833c3b5SJed Brown . inject - matrix restricting by injection 3102b17ce1afSJed Brown . coarse - coarse level DM to update 3103b17ce1afSJed Brown - ctx - optional user-defined function context 3104b17ce1afSJed Brown 3105b17ce1afSJed Brown Level: advanced 3106b17ce1afSJed Brown 3107b17ce1afSJed Brown Notes: 3108b17ce1afSJed Brown This function is only needed if auxiliary data needs to be set up on coarse grids. 3109b17ce1afSJed Brown 3110b17ce1afSJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 3111b17ce1afSJed Brown 3112b17ce1afSJed Brown In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3113b17ce1afSJed Brown extract the finest level information from its context (instead of from the SNES). 3114b17ce1afSJed Brown 3115bb9467b5SJed Brown This function is currently not available from Fortran. 3116bb9467b5SJed Brown 3117dc822a44SJed Brown .seealso: DMCoarsenHookRemove(), DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 3118b17ce1afSJed Brown @*/ 3119b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx) 3120b17ce1afSJed Brown { 3121b17ce1afSJed Brown PetscErrorCode ierr; 3122b17ce1afSJed Brown DMCoarsenHookLink link,*p; 3123b17ce1afSJed Brown 3124b17ce1afSJed Brown PetscFunctionBegin; 3125b17ce1afSJed Brown PetscValidHeaderSpecific(fine,DM_CLASSID,1); 31261e3d8eccSJed Brown for (p=&fine->coarsenhook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */ 31271e3d8eccSJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0); 31281e3d8eccSJed Brown } 312995dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 3130b17ce1afSJed Brown link->coarsenhook = coarsenhook; 3131b17ce1afSJed Brown link->restricthook = restricthook; 3132b17ce1afSJed Brown link->ctx = ctx; 31330298fd71SBarry Smith link->next = NULL; 3134b17ce1afSJed Brown *p = link; 3135b17ce1afSJed Brown PetscFunctionReturn(0); 3136b17ce1afSJed Brown } 3137b17ce1afSJed Brown 3138dc822a44SJed Brown /*@C 3139dc822a44SJed Brown DMCoarsenHookRemove - remove a callback from the list of hooks to be run when restricting a nonlinear problem to the coarse grid 3140dc822a44SJed Brown 3141dc822a44SJed Brown Logically Collective 3142dc822a44SJed Brown 3143dc822a44SJed Brown Input Arguments: 3144dc822a44SJed Brown + fine - nonlinear solver context on which to run a hook when restricting to a coarser level 3145dc822a44SJed Brown . coarsenhook - function to run when setting up a coarser level 3146dc822a44SJed Brown . restricthook - function to run to update data on coarser levels (once per SNESSolve()) 3147dc822a44SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3148dc822a44SJed Brown 3149dc822a44SJed Brown Level: advanced 3150dc822a44SJed Brown 3151dc822a44SJed Brown Notes: 3152dc822a44SJed Brown This function does nothing if the hook is not in the list. 3153dc822a44SJed Brown 3154dc822a44SJed Brown This function is currently not available from Fortran. 3155dc822a44SJed Brown 3156dc822a44SJed Brown .seealso: DMCoarsenHookAdd(), DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 3157dc822a44SJed Brown @*/ 3158dc822a44SJed Brown PetscErrorCode DMCoarsenHookRemove(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx) 3159dc822a44SJed Brown { 3160dc822a44SJed Brown PetscErrorCode ierr; 3161dc822a44SJed Brown DMCoarsenHookLink link,*p; 3162dc822a44SJed Brown 3163dc822a44SJed Brown PetscFunctionBegin; 3164dc822a44SJed Brown PetscValidHeaderSpecific(fine,DM_CLASSID,1); 3165dc822a44SJed Brown for (p=&fine->coarsenhook; *p; p=&(*p)->next) { /* Search the list of current hooks */ 3166dc822a44SJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3167dc822a44SJed Brown link = *p; 3168dc822a44SJed Brown *p = link->next; 3169dc822a44SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 3170dc822a44SJed Brown break; 3171dc822a44SJed Brown } 3172dc822a44SJed Brown } 3173dc822a44SJed Brown PetscFunctionReturn(0); 3174dc822a44SJed Brown } 3175dc822a44SJed Brown 3176dc822a44SJed Brown 3177b17ce1afSJed Brown /*@ 3178b17ce1afSJed Brown DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd() 3179b17ce1afSJed Brown 3180b17ce1afSJed Brown Collective if any hooks are 3181b17ce1afSJed Brown 3182b17ce1afSJed Brown Input Arguments: 3183b17ce1afSJed Brown + fine - finer DM to use as a base 3184b17ce1afSJed Brown . restrct - restriction matrix, apply using MatRestrict() 3185e91eccc2SStefano Zampini . rscale - scaling vector for restriction 3186b17ce1afSJed Brown . inject - injection matrix, also use MatRestrict() 3187e91eccc2SStefano Zampini - coarse - coarser DM to update 3188b17ce1afSJed Brown 3189b17ce1afSJed Brown Level: developer 3190b17ce1afSJed Brown 3191b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict() 3192b17ce1afSJed Brown @*/ 3193b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse) 3194b17ce1afSJed Brown { 3195b17ce1afSJed Brown PetscErrorCode ierr; 3196b17ce1afSJed Brown DMCoarsenHookLink link; 3197b17ce1afSJed Brown 3198b17ce1afSJed Brown PetscFunctionBegin; 3199b17ce1afSJed Brown for (link=fine->coarsenhook; link; link=link->next) { 32008865f1eaSKarl Rupp if (link->restricthook) { 32018865f1eaSKarl Rupp ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr); 32028865f1eaSKarl Rupp } 3203b17ce1afSJed Brown } 320447c6ae99SBarry Smith PetscFunctionReturn(0); 320547c6ae99SBarry Smith } 320647c6ae99SBarry Smith 3207bb9467b5SJed Brown /*@C 3208be081cd6SPeter Brune DMSubDomainHookAdd - adds a callback to be run when restricting a problem to the coarse grid 32095dbd56e3SPeter Brune 3210d083f849SBarry Smith Logically Collective on global 32115dbd56e3SPeter Brune 32125dbd56e3SPeter Brune Input Arguments: 32135dbd56e3SPeter Brune + global - global DM 3214ec4806b8SPeter Brune . ddhook - function to run to pass data to the decomposition DM upon its creation 32155dbd56e3SPeter Brune . restricthook - function to run to update data on block solve (at the beginning of the block solve) 32160298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 32175dbd56e3SPeter Brune 3218ec4806b8SPeter Brune 3219ec4806b8SPeter Brune Calling sequence for ddhook: 3220ec4806b8SPeter Brune $ ddhook(DM global,DM block,void *ctx) 3221ec4806b8SPeter Brune 3222ec4806b8SPeter Brune + global - global DM 3223ec4806b8SPeter Brune . block - block DM 3224ec4806b8SPeter Brune - ctx - optional user-defined function context 3225ec4806b8SPeter Brune 32265dbd56e3SPeter Brune Calling sequence for restricthook: 3227ec4806b8SPeter Brune $ restricthook(DM global,VecScatter out,VecScatter in,DM block,void *ctx) 32285dbd56e3SPeter Brune 32295dbd56e3SPeter Brune + global - global DM 32305dbd56e3SPeter Brune . out - scatter to the outer (with ghost and overlap points) block vector 32315dbd56e3SPeter Brune . in - scatter to block vector values only owned locally 3232ec4806b8SPeter Brune . block - block DM 32335dbd56e3SPeter Brune - ctx - optional user-defined function context 32345dbd56e3SPeter Brune 32355dbd56e3SPeter Brune Level: advanced 32365dbd56e3SPeter Brune 32375dbd56e3SPeter Brune Notes: 3238ec4806b8SPeter Brune This function is only needed if auxiliary data needs to be set up on subdomain DMs. 32395dbd56e3SPeter Brune 32405dbd56e3SPeter Brune If this function is called multiple times, the hooks will be run in the order they are added. 32415dbd56e3SPeter Brune 32425dbd56e3SPeter Brune In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3243ec4806b8SPeter Brune extract the global information from its context (instead of from the SNES). 32445dbd56e3SPeter Brune 3245bb9467b5SJed Brown This function is currently not available from Fortran. 3246bb9467b5SJed Brown 32475dbd56e3SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 32485dbd56e3SPeter Brune @*/ 3249be081cd6SPeter Brune PetscErrorCode DMSubDomainHookAdd(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx) 32505dbd56e3SPeter Brune { 32515dbd56e3SPeter Brune PetscErrorCode ierr; 3252be081cd6SPeter Brune DMSubDomainHookLink link,*p; 32535dbd56e3SPeter Brune 32545dbd56e3SPeter Brune PetscFunctionBegin; 32555dbd56e3SPeter Brune PetscValidHeaderSpecific(global,DM_CLASSID,1); 3256b3a6b972SJed Brown for (p=&global->subdomainhook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */ 3257b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0); 3258b3a6b972SJed Brown } 325995dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 32605dbd56e3SPeter Brune link->restricthook = restricthook; 3261be081cd6SPeter Brune link->ddhook = ddhook; 32625dbd56e3SPeter Brune link->ctx = ctx; 32630298fd71SBarry Smith link->next = NULL; 32645dbd56e3SPeter Brune *p = link; 32655dbd56e3SPeter Brune PetscFunctionReturn(0); 32665dbd56e3SPeter Brune } 32675dbd56e3SPeter Brune 3268b3a6b972SJed Brown /*@C 3269b3a6b972SJed Brown DMSubDomainHookRemove - remove a callback from the list to be run when restricting a problem to the coarse grid 3270b3a6b972SJed Brown 3271b3a6b972SJed Brown Logically Collective 3272b3a6b972SJed Brown 3273b3a6b972SJed Brown Input Arguments: 3274b3a6b972SJed Brown + global - global DM 3275b3a6b972SJed Brown . ddhook - function to run to pass data to the decomposition DM upon its creation 3276b3a6b972SJed Brown . restricthook - function to run to update data on block solve (at the beginning of the block solve) 3277b3a6b972SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3278b3a6b972SJed Brown 3279b3a6b972SJed Brown Level: advanced 3280b3a6b972SJed Brown 3281b3a6b972SJed Brown Notes: 3282b3a6b972SJed Brown 3283b3a6b972SJed Brown This function is currently not available from Fortran. 3284b3a6b972SJed Brown 3285b3a6b972SJed Brown .seealso: DMSubDomainHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 3286b3a6b972SJed Brown @*/ 3287b3a6b972SJed Brown PetscErrorCode DMSubDomainHookRemove(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx) 3288b3a6b972SJed Brown { 3289b3a6b972SJed Brown PetscErrorCode ierr; 3290b3a6b972SJed Brown DMSubDomainHookLink link,*p; 3291b3a6b972SJed Brown 3292b3a6b972SJed Brown PetscFunctionBegin; 3293b3a6b972SJed Brown PetscValidHeaderSpecific(global,DM_CLASSID,1); 3294b3a6b972SJed Brown for (p=&global->subdomainhook; *p; p=&(*p)->next) { /* Search the list of current hooks */ 3295b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3296b3a6b972SJed Brown link = *p; 3297b3a6b972SJed Brown *p = link->next; 3298b3a6b972SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 3299b3a6b972SJed Brown break; 3300b3a6b972SJed Brown } 3301b3a6b972SJed Brown } 3302b3a6b972SJed Brown PetscFunctionReturn(0); 3303b3a6b972SJed Brown } 3304b3a6b972SJed Brown 33055dbd56e3SPeter Brune /*@ 3306be081cd6SPeter Brune DMSubDomainRestrict - restricts user-defined problem data to a block DM by running hooks registered by DMSubDomainHookAdd() 33075dbd56e3SPeter Brune 33085dbd56e3SPeter Brune Collective if any hooks are 33095dbd56e3SPeter Brune 33105dbd56e3SPeter Brune Input Arguments: 33115dbd56e3SPeter Brune + fine - finer DM to use as a base 3312be081cd6SPeter Brune . oscatter - scatter from domain global vector filling subdomain global vector with overlap 3313be081cd6SPeter Brune . gscatter - scatter from domain global vector filling subdomain local vector with ghosts 33145dbd56e3SPeter Brune - coarse - coarer DM to update 33155dbd56e3SPeter Brune 33165dbd56e3SPeter Brune Level: developer 33175dbd56e3SPeter Brune 33185dbd56e3SPeter Brune .seealso: DMCoarsenHookAdd(), MatRestrict() 33195dbd56e3SPeter Brune @*/ 3320be081cd6SPeter Brune PetscErrorCode DMSubDomainRestrict(DM global,VecScatter oscatter,VecScatter gscatter,DM subdm) 33215dbd56e3SPeter Brune { 33225dbd56e3SPeter Brune PetscErrorCode ierr; 3323be081cd6SPeter Brune DMSubDomainHookLink link; 33245dbd56e3SPeter Brune 33255dbd56e3SPeter Brune PetscFunctionBegin; 3326be081cd6SPeter Brune for (link=global->subdomainhook; link; link=link->next) { 33278865f1eaSKarl Rupp if (link->restricthook) { 33288865f1eaSKarl Rupp ierr = (*link->restricthook)(global,oscatter,gscatter,subdm,link->ctx);CHKERRQ(ierr); 33298865f1eaSKarl Rupp } 33305dbd56e3SPeter Brune } 33315dbd56e3SPeter Brune PetscFunctionReturn(0); 33325dbd56e3SPeter Brune } 33335dbd56e3SPeter Brune 33345fe1f584SPeter Brune /*@ 33356a7d9d85SPeter Brune DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM. 33365fe1f584SPeter Brune 33375fe1f584SPeter Brune Not Collective 33385fe1f584SPeter Brune 33395fe1f584SPeter Brune Input Parameter: 33405fe1f584SPeter Brune . dm - the DM object 33415fe1f584SPeter Brune 33425fe1f584SPeter Brune Output Parameter: 33436a7d9d85SPeter Brune . level - number of coarsenings 33445fe1f584SPeter Brune 33455fe1f584SPeter Brune Level: developer 33465fe1f584SPeter Brune 33476a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 33485fe1f584SPeter Brune 33495fe1f584SPeter Brune @*/ 33505fe1f584SPeter Brune PetscErrorCode DMGetCoarsenLevel(DM dm,PetscInt *level) 33515fe1f584SPeter Brune { 33525fe1f584SPeter Brune PetscFunctionBegin; 33535fe1f584SPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3354b9d85ea2SLisandro Dalcin PetscValidIntPointer(level,2); 33555fe1f584SPeter Brune *level = dm->leveldown; 33565fe1f584SPeter Brune PetscFunctionReturn(0); 33575fe1f584SPeter Brune } 33585fe1f584SPeter Brune 33599a64c4a8SMatthew G. Knepley /*@ 33609a64c4a8SMatthew G. Knepley DMSetCoarsenLevel - Sets the number of coarsenings that have generated this DM. 33619a64c4a8SMatthew G. Knepley 33629a64c4a8SMatthew G. Knepley Not Collective 33639a64c4a8SMatthew G. Knepley 33649a64c4a8SMatthew G. Knepley Input Parameters: 33659a64c4a8SMatthew G. Knepley + dm - the DM object 33669a64c4a8SMatthew G. Knepley - level - number of coarsenings 33679a64c4a8SMatthew G. Knepley 33689a64c4a8SMatthew G. Knepley Level: developer 33699a64c4a8SMatthew G. Knepley 33709a64c4a8SMatthew G. Knepley .seealso DMCoarsen(), DMGetCoarsenLevel(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 33719a64c4a8SMatthew G. Knepley @*/ 33729a64c4a8SMatthew G. Knepley PetscErrorCode DMSetCoarsenLevel(DM dm,PetscInt level) 33739a64c4a8SMatthew G. Knepley { 33749a64c4a8SMatthew G. Knepley PetscFunctionBegin; 33759a64c4a8SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 33769a64c4a8SMatthew G. Knepley dm->leveldown = level; 33779a64c4a8SMatthew G. Knepley PetscFunctionReturn(0); 33789a64c4a8SMatthew G. Knepley } 33799a64c4a8SMatthew G. Knepley 33805fe1f584SPeter Brune 33815fe1f584SPeter Brune 338247c6ae99SBarry Smith /*@C 338347c6ae99SBarry Smith DMRefineHierarchy - Refines a DM object, all levels at once 338447c6ae99SBarry Smith 3385d083f849SBarry Smith Collective on dm 338647c6ae99SBarry Smith 338747c6ae99SBarry Smith Input Parameter: 338847c6ae99SBarry Smith + dm - the DM object 338947c6ae99SBarry Smith - nlevels - the number of levels of refinement 339047c6ae99SBarry Smith 339147c6ae99SBarry Smith Output Parameter: 339247c6ae99SBarry Smith . dmf - the refined DM hierarchy 339347c6ae99SBarry Smith 339447c6ae99SBarry Smith Level: developer 339547c6ae99SBarry Smith 3396e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 339747c6ae99SBarry Smith 339847c6ae99SBarry Smith @*/ 33997087cfbeSBarry Smith PetscErrorCode DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[]) 340047c6ae99SBarry Smith { 340147c6ae99SBarry Smith PetscErrorCode ierr; 340247c6ae99SBarry Smith 340347c6ae99SBarry Smith PetscFunctionBegin; 3404171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3405ce94432eSBarry Smith if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 340647c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 3407b9d85ea2SLisandro Dalcin PetscValidPointer(dmf,3); 340847c6ae99SBarry Smith if (dm->ops->refinehierarchy) { 340947c6ae99SBarry Smith ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr); 341047c6ae99SBarry Smith } else if (dm->ops->refine) { 341147c6ae99SBarry Smith PetscInt i; 341247c6ae99SBarry Smith 3413ce94432eSBarry Smith ierr = DMRefine(dm,PetscObjectComm((PetscObject)dm),&dmf[0]);CHKERRQ(ierr); 341447c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 3415ce94432eSBarry Smith ierr = DMRefine(dmf[i-1],PetscObjectComm((PetscObject)dm),&dmf[i]);CHKERRQ(ierr); 341647c6ae99SBarry Smith } 3417ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No RefineHierarchy for this DM yet"); 341847c6ae99SBarry Smith PetscFunctionReturn(0); 341947c6ae99SBarry Smith } 342047c6ae99SBarry Smith 342147c6ae99SBarry Smith /*@C 342247c6ae99SBarry Smith DMCoarsenHierarchy - Coarsens a DM object, all levels at once 342347c6ae99SBarry Smith 3424d083f849SBarry Smith Collective on dm 342547c6ae99SBarry Smith 342647c6ae99SBarry Smith Input Parameter: 342747c6ae99SBarry Smith + dm - the DM object 342847c6ae99SBarry Smith - nlevels - the number of levels of coarsening 342947c6ae99SBarry Smith 343047c6ae99SBarry Smith Output Parameter: 343147c6ae99SBarry Smith . dmc - the coarsened DM hierarchy 343247c6ae99SBarry Smith 343347c6ae99SBarry Smith Level: developer 343447c6ae99SBarry Smith 3435e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 343647c6ae99SBarry Smith 343747c6ae99SBarry Smith @*/ 34387087cfbeSBarry Smith PetscErrorCode DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[]) 343947c6ae99SBarry Smith { 344047c6ae99SBarry Smith PetscErrorCode ierr; 344147c6ae99SBarry Smith 344247c6ae99SBarry Smith PetscFunctionBegin; 3443171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3444ce94432eSBarry Smith if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 344547c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 344647c6ae99SBarry Smith PetscValidPointer(dmc,3); 344747c6ae99SBarry Smith if (dm->ops->coarsenhierarchy) { 344847c6ae99SBarry Smith ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr); 344947c6ae99SBarry Smith } else if (dm->ops->coarsen) { 345047c6ae99SBarry Smith PetscInt i; 345147c6ae99SBarry Smith 3452ce94432eSBarry Smith ierr = DMCoarsen(dm,PetscObjectComm((PetscObject)dm),&dmc[0]);CHKERRQ(ierr); 345347c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 3454ce94432eSBarry Smith ierr = DMCoarsen(dmc[i-1],PetscObjectComm((PetscObject)dm),&dmc[i]);CHKERRQ(ierr); 345547c6ae99SBarry Smith } 3456ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet"); 345747c6ae99SBarry Smith PetscFunctionReturn(0); 345847c6ae99SBarry Smith } 345947c6ae99SBarry Smith 34601a266240SBarry Smith /*@C 34611a266240SBarry Smith DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed 34621a266240SBarry Smith 34631a266240SBarry Smith Not Collective 34641a266240SBarry Smith 34651a266240SBarry Smith Input Parameters: 34661a266240SBarry Smith + dm - the DM object 34671a266240SBarry Smith - destroy - the destroy function 34681a266240SBarry Smith 34691a266240SBarry Smith Level: intermediate 34701a266240SBarry Smith 3471e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 34721a266240SBarry Smith 3473f07f9ceaSJed Brown @*/ 34741a266240SBarry Smith PetscErrorCode DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**)) 34751a266240SBarry Smith { 34761a266240SBarry Smith PetscFunctionBegin; 3477171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 34781a266240SBarry Smith dm->ctxdestroy = destroy; 34791a266240SBarry Smith PetscFunctionReturn(0); 34801a266240SBarry Smith } 34811a266240SBarry Smith 3482b07ff414SBarry Smith /*@ 34831b2093e4SBarry Smith DMSetApplicationContext - Set a user context into a DM object 348447c6ae99SBarry Smith 348547c6ae99SBarry Smith Not Collective 348647c6ae99SBarry Smith 348747c6ae99SBarry Smith Input Parameters: 348847c6ae99SBarry Smith + dm - the DM object 348947c6ae99SBarry Smith - ctx - the user context 349047c6ae99SBarry Smith 349147c6ae99SBarry Smith Level: intermediate 349247c6ae99SBarry Smith 3493e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 349447c6ae99SBarry Smith 349547c6ae99SBarry Smith @*/ 34961b2093e4SBarry Smith PetscErrorCode DMSetApplicationContext(DM dm,void *ctx) 349747c6ae99SBarry Smith { 349847c6ae99SBarry Smith PetscFunctionBegin; 3499171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 350047c6ae99SBarry Smith dm->ctx = ctx; 350147c6ae99SBarry Smith PetscFunctionReturn(0); 350247c6ae99SBarry Smith } 350347c6ae99SBarry Smith 350447c6ae99SBarry Smith /*@ 35051b2093e4SBarry Smith DMGetApplicationContext - Gets a user context from a DM object 350647c6ae99SBarry Smith 350747c6ae99SBarry Smith Not Collective 350847c6ae99SBarry Smith 350947c6ae99SBarry Smith Input Parameter: 351047c6ae99SBarry Smith . dm - the DM object 351147c6ae99SBarry Smith 351247c6ae99SBarry Smith Output Parameter: 351347c6ae99SBarry Smith . ctx - the user context 351447c6ae99SBarry Smith 351547c6ae99SBarry Smith Level: intermediate 351647c6ae99SBarry Smith 3517e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 351847c6ae99SBarry Smith 351947c6ae99SBarry Smith @*/ 35201b2093e4SBarry Smith PetscErrorCode DMGetApplicationContext(DM dm,void *ctx) 352147c6ae99SBarry Smith { 352247c6ae99SBarry Smith PetscFunctionBegin; 3523171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 35241b2093e4SBarry Smith *(void**)ctx = dm->ctx; 352547c6ae99SBarry Smith PetscFunctionReturn(0); 352647c6ae99SBarry Smith } 352747c6ae99SBarry Smith 352808da532bSDmitry Karpeev /*@C 3529df3898eeSBarry Smith DMSetVariableBounds - sets a function to compute the lower and upper bound vectors for SNESVI. 353008da532bSDmitry Karpeev 3531d083f849SBarry Smith Logically Collective on dm 353208da532bSDmitry Karpeev 353308da532bSDmitry Karpeev Input Parameter: 353408da532bSDmitry Karpeev + dm - the DM object 35350298fd71SBarry Smith - f - the function that computes variable bounds used by SNESVI (use NULL to cancel a previous function that was set) 353608da532bSDmitry Karpeev 353708da532bSDmitry Karpeev Level: intermediate 353808da532bSDmitry Karpeev 3539835c3ec7SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), 354008da532bSDmitry Karpeev DMSetJacobian() 354108da532bSDmitry Karpeev 354208da532bSDmitry Karpeev @*/ 354308da532bSDmitry Karpeev PetscErrorCode DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec)) 354408da532bSDmitry Karpeev { 354508da532bSDmitry Karpeev PetscFunctionBegin; 35465a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 354708da532bSDmitry Karpeev dm->ops->computevariablebounds = f; 354808da532bSDmitry Karpeev PetscFunctionReturn(0); 354908da532bSDmitry Karpeev } 355008da532bSDmitry Karpeev 355108da532bSDmitry Karpeev /*@ 355208da532bSDmitry Karpeev DMHasVariableBounds - does the DM object have a variable bounds function? 355308da532bSDmitry Karpeev 355408da532bSDmitry Karpeev Not Collective 355508da532bSDmitry Karpeev 355608da532bSDmitry Karpeev Input Parameter: 355708da532bSDmitry Karpeev . dm - the DM object to destroy 355808da532bSDmitry Karpeev 355908da532bSDmitry Karpeev Output Parameter: 356008da532bSDmitry Karpeev . flg - PETSC_TRUE if the variable bounds function exists 356108da532bSDmitry Karpeev 356208da532bSDmitry Karpeev Level: developer 356308da532bSDmitry Karpeev 356474e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 356508da532bSDmitry Karpeev 356608da532bSDmitry Karpeev @*/ 356708da532bSDmitry Karpeev PetscErrorCode DMHasVariableBounds(DM dm,PetscBool *flg) 356808da532bSDmitry Karpeev { 356908da532bSDmitry Karpeev PetscFunctionBegin; 35705a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3571534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 357208da532bSDmitry Karpeev *flg = (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE; 357308da532bSDmitry Karpeev PetscFunctionReturn(0); 357408da532bSDmitry Karpeev } 357508da532bSDmitry Karpeev 357608da532bSDmitry Karpeev /*@C 357708da532bSDmitry Karpeev DMComputeVariableBounds - compute variable bounds used by SNESVI. 357808da532bSDmitry Karpeev 3579d083f849SBarry Smith Logically Collective on dm 358008da532bSDmitry Karpeev 358108da532bSDmitry Karpeev Input Parameters: 3582907376e6SBarry Smith . dm - the DM object 358308da532bSDmitry Karpeev 358408da532bSDmitry Karpeev Output parameters: 358508da532bSDmitry Karpeev + xl - lower bound 358608da532bSDmitry Karpeev - xu - upper bound 358708da532bSDmitry Karpeev 3588907376e6SBarry Smith Level: advanced 3589907376e6SBarry Smith 359095452b02SPatrick Sanan Notes: 359195452b02SPatrick Sanan This is generally not called by users. It calls the function provided by the user with DMSetVariableBounds() 359208da532bSDmitry Karpeev 359374e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 359408da532bSDmitry Karpeev 359508da532bSDmitry Karpeev @*/ 359608da532bSDmitry Karpeev PetscErrorCode DMComputeVariableBounds(DM dm, Vec xl, Vec xu) 359708da532bSDmitry Karpeev { 359808da532bSDmitry Karpeev PetscErrorCode ierr; 35995fd66863SKarl Rupp 360008da532bSDmitry Karpeev PetscFunctionBegin; 36015a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 360208da532bSDmitry Karpeev PetscValidHeaderSpecific(xl,VEC_CLASSID,2); 36035a84ad33SLisandro Dalcin PetscValidHeaderSpecific(xu,VEC_CLASSID,3); 3604b9d85ea2SLisandro Dalcin if (!dm->ops->computevariablebounds) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeVariableBounds",((PetscObject)dm)->type_name); 360508da532bSDmitry Karpeev ierr = (*dm->ops->computevariablebounds)(dm, xl,xu);CHKERRQ(ierr); 360608da532bSDmitry Karpeev PetscFunctionReturn(0); 360708da532bSDmitry Karpeev } 360808da532bSDmitry Karpeev 3609b0ae01b7SPeter Brune /*@ 3610b0ae01b7SPeter Brune DMHasColoring - does the DM object have a method of providing a coloring? 3611b0ae01b7SPeter Brune 3612b0ae01b7SPeter Brune Not Collective 3613b0ae01b7SPeter Brune 3614b0ae01b7SPeter Brune Input Parameter: 3615b0ae01b7SPeter Brune . dm - the DM object 3616b0ae01b7SPeter Brune 3617b0ae01b7SPeter Brune Output Parameter: 3618b0ae01b7SPeter Brune . flg - PETSC_TRUE if the DM has facilities for DMCreateColoring(). 3619b0ae01b7SPeter Brune 3620b0ae01b7SPeter Brune Level: developer 3621b0ae01b7SPeter Brune 36221565f0a7SPatrick Sanan .seealso DMCreateColoring() 3623b0ae01b7SPeter Brune 3624b0ae01b7SPeter Brune @*/ 3625b0ae01b7SPeter Brune PetscErrorCode DMHasColoring(DM dm,PetscBool *flg) 3626b0ae01b7SPeter Brune { 3627b0ae01b7SPeter Brune PetscFunctionBegin; 36285a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3629534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 3630b0ae01b7SPeter Brune *flg = (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE; 3631b0ae01b7SPeter Brune PetscFunctionReturn(0); 3632b0ae01b7SPeter Brune } 3633b0ae01b7SPeter Brune 36343ad4599aSBarry Smith /*@ 36353ad4599aSBarry Smith DMHasCreateRestriction - does the DM object have a method of providing a restriction? 36363ad4599aSBarry Smith 36373ad4599aSBarry Smith Not Collective 36383ad4599aSBarry Smith 36393ad4599aSBarry Smith Input Parameter: 36403ad4599aSBarry Smith . dm - the DM object 36413ad4599aSBarry Smith 36423ad4599aSBarry Smith Output Parameter: 36433ad4599aSBarry Smith . flg - PETSC_TRUE if the DM has facilities for DMCreateRestriction(). 36443ad4599aSBarry Smith 36453ad4599aSBarry Smith Level: developer 36463ad4599aSBarry Smith 36471565f0a7SPatrick Sanan .seealso DMCreateRestriction() 36483ad4599aSBarry Smith 36493ad4599aSBarry Smith @*/ 36503ad4599aSBarry Smith PetscErrorCode DMHasCreateRestriction(DM dm,PetscBool *flg) 36513ad4599aSBarry Smith { 36523ad4599aSBarry Smith PetscFunctionBegin; 36535a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3654534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 36553ad4599aSBarry Smith *flg = (dm->ops->createrestriction) ? PETSC_TRUE : PETSC_FALSE; 36563ad4599aSBarry Smith PetscFunctionReturn(0); 36573ad4599aSBarry Smith } 36583ad4599aSBarry Smith 3659a7058e45SLawrence Mitchell 3660a7058e45SLawrence Mitchell /*@ 3661a7058e45SLawrence Mitchell DMHasCreateInjection - does the DM object have a method of providing an injection? 3662a7058e45SLawrence Mitchell 3663a7058e45SLawrence Mitchell Not Collective 3664a7058e45SLawrence Mitchell 3665a7058e45SLawrence Mitchell Input Parameter: 3666a7058e45SLawrence Mitchell . dm - the DM object 3667a7058e45SLawrence Mitchell 3668a7058e45SLawrence Mitchell Output Parameter: 3669a7058e45SLawrence Mitchell . flg - PETSC_TRUE if the DM has facilities for DMCreateInjection(). 3670a7058e45SLawrence Mitchell 3671a7058e45SLawrence Mitchell Level: developer 3672a7058e45SLawrence Mitchell 36731565f0a7SPatrick Sanan .seealso DMCreateInjection() 3674a7058e45SLawrence Mitchell 3675a7058e45SLawrence Mitchell @*/ 3676a7058e45SLawrence Mitchell PetscErrorCode DMHasCreateInjection(DM dm,PetscBool *flg) 3677a7058e45SLawrence Mitchell { 36784a7a4c06SLawrence Mitchell PetscErrorCode ierr; 36795a84ad33SLisandro Dalcin 3680a7058e45SLawrence Mitchell PetscFunctionBegin; 36815a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3682534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 36835a84ad33SLisandro Dalcin if (dm->ops->hascreateinjection) { 36844a7a4c06SLawrence Mitchell ierr = (*dm->ops->hascreateinjection)(dm,flg);CHKERRQ(ierr); 36855a84ad33SLisandro Dalcin } else { 36865a84ad33SLisandro Dalcin *flg = (dm->ops->createinjection) ? PETSC_TRUE : PETSC_FALSE; 36875a84ad33SLisandro Dalcin } 3688a7058e45SLawrence Mitchell PetscFunctionReturn(0); 3689a7058e45SLawrence Mitchell } 3690a7058e45SLawrence Mitchell 36910298fd71SBarry Smith PetscFunctionList DMList = NULL; 3692264ace61SBarry Smith PetscBool DMRegisterAllCalled = PETSC_FALSE; 3693264ace61SBarry Smith 3694264ace61SBarry Smith /*@C 3695264ace61SBarry Smith DMSetType - Builds a DM, for a particular DM implementation. 3696264ace61SBarry Smith 3697d083f849SBarry Smith Collective on dm 3698264ace61SBarry Smith 3699264ace61SBarry Smith Input Parameters: 3700264ace61SBarry Smith + dm - The DM object 3701264ace61SBarry Smith - method - The name of the DM type 3702264ace61SBarry Smith 3703264ace61SBarry Smith Options Database Key: 3704264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types 3705264ace61SBarry Smith 3706264ace61SBarry Smith Notes: 3707e1589f56SBarry Smith See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D). 3708264ace61SBarry Smith 3709264ace61SBarry Smith Level: intermediate 3710264ace61SBarry Smith 3711264ace61SBarry Smith .seealso: DMGetType(), DMCreate() 3712264ace61SBarry Smith @*/ 371319fd82e9SBarry Smith PetscErrorCode DMSetType(DM dm, DMType method) 3714264ace61SBarry Smith { 3715264ace61SBarry Smith PetscErrorCode (*r)(DM); 3716264ace61SBarry Smith PetscBool match; 3717264ace61SBarry Smith PetscErrorCode ierr; 3718264ace61SBarry Smith 3719264ace61SBarry Smith PetscFunctionBegin; 3720264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID,1); 3721251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr); 3722264ace61SBarry Smith if (match) PetscFunctionReturn(0); 3723264ace61SBarry Smith 37240f51fdf8SToby Isaac ierr = DMRegisterAll();CHKERRQ(ierr); 37251c9cd337SJed Brown ierr = PetscFunctionListFind(DMList,method,&r);CHKERRQ(ierr); 3726ce94432eSBarry Smith if (!r) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method); 3727264ace61SBarry Smith 3728264ace61SBarry Smith if (dm->ops->destroy) { 3729264ace61SBarry Smith ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr); 3730264ace61SBarry Smith } 3731d57f96a3SLisandro Dalcin ierr = PetscMemzero(dm->ops,sizeof(*dm->ops));CHKERRQ(ierr); 3732264ace61SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr); 3733d57f96a3SLisandro Dalcin ierr = (*r)(dm);CHKERRQ(ierr); 3734264ace61SBarry Smith PetscFunctionReturn(0); 3735264ace61SBarry Smith } 3736264ace61SBarry Smith 3737264ace61SBarry Smith /*@C 3738264ace61SBarry Smith DMGetType - Gets the DM type name (as a string) from the DM. 3739264ace61SBarry Smith 3740264ace61SBarry Smith Not Collective 3741264ace61SBarry Smith 3742264ace61SBarry Smith Input Parameter: 3743264ace61SBarry Smith . dm - The DM 3744264ace61SBarry Smith 3745264ace61SBarry Smith Output Parameter: 3746264ace61SBarry Smith . type - The DM type name 3747264ace61SBarry Smith 3748264ace61SBarry Smith Level: intermediate 3749264ace61SBarry Smith 3750264ace61SBarry Smith .seealso: DMSetType(), DMCreate() 3751264ace61SBarry Smith @*/ 375219fd82e9SBarry Smith PetscErrorCode DMGetType(DM dm, DMType *type) 3753264ace61SBarry Smith { 3754264ace61SBarry Smith PetscErrorCode ierr; 3755264ace61SBarry Smith 3756264ace61SBarry Smith PetscFunctionBegin; 3757264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID,1); 3758c959eef4SJed Brown PetscValidPointer(type,2); 3759607a6623SBarry Smith ierr = DMRegisterAll();CHKERRQ(ierr); 3760264ace61SBarry Smith *type = ((PetscObject)dm)->type_name; 3761264ace61SBarry Smith PetscFunctionReturn(0); 3762264ace61SBarry Smith } 3763264ace61SBarry Smith 376467a56275SMatthew G Knepley /*@C 376567a56275SMatthew G Knepley DMConvert - Converts a DM to another DM, either of the same or different type. 376667a56275SMatthew G Knepley 3767d083f849SBarry Smith Collective on dm 376867a56275SMatthew G Knepley 376967a56275SMatthew G Knepley Input Parameters: 377067a56275SMatthew G Knepley + dm - the DM 377167a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type) 377267a56275SMatthew G Knepley 377367a56275SMatthew G Knepley Output Parameter: 377467a56275SMatthew G Knepley . M - pointer to new DM 377567a56275SMatthew G Knepley 377667a56275SMatthew G Knepley Notes: 377767a56275SMatthew G Knepley Cannot be used to convert a sequential DM to parallel or parallel to sequential, 377867a56275SMatthew G Knepley the MPI communicator of the generated DM is always the same as the communicator 377967a56275SMatthew G Knepley of the input DM. 378067a56275SMatthew G Knepley 378167a56275SMatthew G Knepley Level: intermediate 378267a56275SMatthew G Knepley 378367a56275SMatthew G Knepley .seealso: DMCreate() 378467a56275SMatthew G Knepley @*/ 378519fd82e9SBarry Smith PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M) 378667a56275SMatthew G Knepley { 378767a56275SMatthew G Knepley DM B; 378867a56275SMatthew G Knepley char convname[256]; 3789c067b6caSMatthew G. Knepley PetscBool sametype/*, issame */; 379067a56275SMatthew G Knepley PetscErrorCode ierr; 379167a56275SMatthew G Knepley 379267a56275SMatthew G Knepley PetscFunctionBegin; 379367a56275SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 379467a56275SMatthew G Knepley PetscValidType(dm,1); 379567a56275SMatthew G Knepley PetscValidPointer(M,3); 3796251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr); 3797c067b6caSMatthew G. Knepley /* ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr); */ 3798c067b6caSMatthew G. Knepley if (sametype) { 3799c067b6caSMatthew G. Knepley *M = dm; 3800c067b6caSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr); 3801c067b6caSMatthew G. Knepley PetscFunctionReturn(0); 3802c067b6caSMatthew G. Knepley } else { 38030298fd71SBarry Smith PetscErrorCode (*conv)(DM, DMType, DM*) = NULL; 380467a56275SMatthew G Knepley 380567a56275SMatthew G Knepley /* 380667a56275SMatthew G Knepley Order of precedence: 380767a56275SMatthew G Knepley 1) See if a specialized converter is known to the current DM. 380867a56275SMatthew G Knepley 2) See if a specialized converter is known to the desired DM class. 380967a56275SMatthew G Knepley 3) See if a good general converter is registered for the desired class 381067a56275SMatthew G Knepley 4) See if a good general converter is known for the current matrix. 381167a56275SMatthew G Knepley 5) Use a really basic converter. 381267a56275SMatthew G Knepley */ 381367a56275SMatthew G Knepley 381467a56275SMatthew G Knepley /* 1) See if a specialized converter is known to the current DM and the desired class */ 3815a126751eSBarry Smith ierr = PetscStrncpy(convname,"DMConvert_",sizeof(convname));CHKERRQ(ierr); 3816a126751eSBarry Smith ierr = PetscStrlcat(convname,((PetscObject) dm)->type_name,sizeof(convname));CHKERRQ(ierr); 3817a126751eSBarry Smith ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 3818a126751eSBarry Smith ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 3819a126751eSBarry Smith ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 38200005d66cSJed Brown ierr = PetscObjectQueryFunction((PetscObject)dm,convname,&conv);CHKERRQ(ierr); 382167a56275SMatthew G Knepley if (conv) goto foundconv; 382267a56275SMatthew G Knepley 382367a56275SMatthew G Knepley /* 2) See if a specialized converter is known to the desired DM class. */ 382482f516ccSBarry Smith ierr = DMCreate(PetscObjectComm((PetscObject)dm), &B);CHKERRQ(ierr); 382567a56275SMatthew G Knepley ierr = DMSetType(B, newtype);CHKERRQ(ierr); 3826a126751eSBarry Smith ierr = PetscStrncpy(convname,"DMConvert_",sizeof(convname));CHKERRQ(ierr); 3827a126751eSBarry Smith ierr = PetscStrlcat(convname,((PetscObject) dm)->type_name,sizeof(convname));CHKERRQ(ierr); 3828a126751eSBarry Smith ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 3829a126751eSBarry Smith ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 3830a126751eSBarry Smith ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 38310005d66cSJed Brown ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 383267a56275SMatthew G Knepley if (conv) { 3833fcfd50ebSBarry Smith ierr = DMDestroy(&B);CHKERRQ(ierr); 383467a56275SMatthew G Knepley goto foundconv; 383567a56275SMatthew G Knepley } 383667a56275SMatthew G Knepley 383767a56275SMatthew G Knepley #if 0 383867a56275SMatthew G Knepley /* 3) See if a good general converter is registered for the desired class */ 383967a56275SMatthew G Knepley conv = B->ops->convertfrom; 3840fcfd50ebSBarry Smith ierr = DMDestroy(&B);CHKERRQ(ierr); 384167a56275SMatthew G Knepley if (conv) goto foundconv; 384267a56275SMatthew G Knepley 384367a56275SMatthew G Knepley /* 4) See if a good general converter is known for the current matrix */ 384467a56275SMatthew G Knepley if (dm->ops->convert) { 384567a56275SMatthew G Knepley conv = dm->ops->convert; 384667a56275SMatthew G Knepley } 384767a56275SMatthew G Knepley if (conv) goto foundconv; 384867a56275SMatthew G Knepley #endif 384967a56275SMatthew G Knepley 385067a56275SMatthew G Knepley /* 5) Use a really basic converter. */ 385182f516ccSBarry Smith SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype); 385267a56275SMatthew G Knepley 385367a56275SMatthew G Knepley foundconv: 385467a56275SMatthew G Knepley ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr); 385567a56275SMatthew G Knepley ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr); 385612fa691eSMatthew G. Knepley /* Things that are independent of DM type: We should consult DMClone() here */ 385790b157c4SStefano Zampini { 385890b157c4SStefano Zampini PetscBool isper; 385912fa691eSMatthew G. Knepley const PetscReal *maxCell, *L; 386012fa691eSMatthew G. Knepley const DMBoundaryType *bd; 386190b157c4SStefano Zampini ierr = DMGetPeriodicity(dm, &isper, &maxCell, &L, &bd);CHKERRQ(ierr); 386290b157c4SStefano Zampini ierr = DMSetPeriodicity(*M, isper, maxCell, L, bd);CHKERRQ(ierr); 3863c8a6034eSMark (*M)->prealloc_only = dm->prealloc_only; 3864a587d139SMark ierr = PetscFree((*M)->vectype);CHKERRQ(ierr); 3865a587d139SMark ierr = PetscStrallocpy(dm->vectype,(char**)&(*M)->vectype);CHKERRQ(ierr); 3866a587d139SMark ierr = PetscFree((*M)->mattype);CHKERRQ(ierr); 3867a587d139SMark ierr = PetscStrallocpy(dm->mattype,(char**)&(*M)->mattype);CHKERRQ(ierr); 386812fa691eSMatthew G. Knepley } 386967a56275SMatthew G Knepley ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr); 387067a56275SMatthew G Knepley } 387167a56275SMatthew G Knepley ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr); 387267a56275SMatthew G Knepley PetscFunctionReturn(0); 387367a56275SMatthew G Knepley } 3874264ace61SBarry Smith 3875264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/ 3876264ace61SBarry Smith 3877264ace61SBarry Smith /*@C 38781c84c290SBarry Smith DMRegister - Adds a new DM component implementation 38791c84c290SBarry Smith 38801c84c290SBarry Smith Not Collective 38811c84c290SBarry Smith 38821c84c290SBarry Smith Input Parameters: 38831c84c290SBarry Smith + name - The name of a new user-defined creation routine 38841c84c290SBarry Smith - create_func - The creation routine itself 38851c84c290SBarry Smith 38861c84c290SBarry Smith Notes: 38871c84c290SBarry Smith DMRegister() may be called multiple times to add several user-defined DMs 38881c84c290SBarry Smith 38891c84c290SBarry Smith 38901c84c290SBarry Smith Sample usage: 38911c84c290SBarry Smith .vb 3892bdf89e91SBarry Smith DMRegister("my_da", MyDMCreate); 38931c84c290SBarry Smith .ve 38941c84c290SBarry Smith 38951c84c290SBarry Smith Then, your DM type can be chosen with the procedural interface via 38961c84c290SBarry Smith .vb 38971c84c290SBarry Smith DMCreate(MPI_Comm, DM *); 38981c84c290SBarry Smith DMSetType(DM,"my_da"); 38991c84c290SBarry Smith .ve 39001c84c290SBarry Smith or at runtime via the option 39011c84c290SBarry Smith .vb 39021c84c290SBarry Smith -da_type my_da 39031c84c290SBarry Smith .ve 3904264ace61SBarry Smith 3905264ace61SBarry Smith Level: advanced 39061c84c290SBarry Smith 3907bdf89e91SBarry Smith .seealso: DMRegisterAll(), DMRegisterDestroy() 39081c84c290SBarry Smith 3909264ace61SBarry Smith @*/ 3910bdf89e91SBarry Smith PetscErrorCode DMRegister(const char sname[],PetscErrorCode (*function)(DM)) 3911264ace61SBarry Smith { 3912264ace61SBarry Smith PetscErrorCode ierr; 3913264ace61SBarry Smith 3914264ace61SBarry Smith PetscFunctionBegin; 39151d36bdfdSBarry Smith ierr = DMInitializePackage();CHKERRQ(ierr); 3916a240a19fSJed Brown ierr = PetscFunctionListAdd(&DMList,sname,function);CHKERRQ(ierr); 3917264ace61SBarry Smith PetscFunctionReturn(0); 3918264ace61SBarry Smith } 3919264ace61SBarry Smith 3920b859378eSBarry Smith /*@C 392155849f57SBarry Smith DMLoad - Loads a DM that has been stored in binary with DMView(). 3922b859378eSBarry Smith 3923d083f849SBarry Smith Collective on viewer 3924b859378eSBarry Smith 3925b859378eSBarry Smith Input Parameters: 3926b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or 3927b859378eSBarry Smith some related function before a call to DMLoad(). 3928b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or 3929b859378eSBarry Smith HDF5 file viewer, obtained from PetscViewerHDF5Open() 3930b859378eSBarry Smith 3931b859378eSBarry Smith Level: intermediate 3932b859378eSBarry Smith 3933b859378eSBarry Smith Notes: 393455849f57SBarry Smith The type is determined by the data in the file, any type set into the DM before this call is ignored. 3935b859378eSBarry Smith 3936b859378eSBarry Smith Notes for advanced users: 3937b859378eSBarry Smith Most users should not need to know the details of the binary storage 3938b859378eSBarry Smith format, since DMLoad() and DMView() completely hide these details. 3939b859378eSBarry Smith But for anyone who's interested, the standard binary matrix storage 3940b859378eSBarry Smith format is 3941b859378eSBarry Smith .vb 3942b859378eSBarry Smith has not yet been determined 3943b859378eSBarry Smith .ve 3944b859378eSBarry Smith 3945b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad() 3946b859378eSBarry Smith @*/ 3947b859378eSBarry Smith PetscErrorCode DMLoad(DM newdm, PetscViewer viewer) 3948b859378eSBarry Smith { 39499331c7a4SMatthew G. Knepley PetscBool isbinary, ishdf5; 3950b859378eSBarry Smith PetscErrorCode ierr; 3951b859378eSBarry Smith 3952b859378eSBarry Smith PetscFunctionBegin; 3953b859378eSBarry Smith PetscValidHeaderSpecific(newdm,DM_CLASSID,1); 3954b859378eSBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 3955fb694a9eSVaclav Hapla ierr = PetscViewerCheckReadable(viewer);CHKERRQ(ierr); 395632c0f0efSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 39579331c7a4SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 395858cd63d5SVaclav Hapla ierr = PetscLogEventBegin(DM_Load,viewer,0,0,0);CHKERRQ(ierr); 39599331c7a4SMatthew G. Knepley if (isbinary) { 39609331c7a4SMatthew G. Knepley PetscInt classid; 39619331c7a4SMatthew G. Knepley char type[256]; 3962b859378eSBarry Smith 3963060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr); 39649200755eSBarry Smith if (classid != DM_FILE_CLASSID) SETERRQ1(PetscObjectComm((PetscObject)newdm),PETSC_ERR_ARG_WRONG,"Not DM next in file, classid found %d",(int)classid); 3965060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr); 396632c0f0efSBarry Smith ierr = DMSetType(newdm, type);CHKERRQ(ierr); 39679331c7a4SMatthew G. Knepley if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);} 39689331c7a4SMatthew G. Knepley } else if (ishdf5) { 39699331c7a4SMatthew G. Knepley if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);} 39709331c7a4SMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()"); 397158cd63d5SVaclav Hapla ierr = PetscLogEventEnd(DM_Load,viewer,0,0,0);CHKERRQ(ierr); 3972b859378eSBarry Smith PetscFunctionReturn(0); 3973b859378eSBarry Smith } 3974b859378eSBarry Smith 3975b2e4378dSMatthew G. Knepley /*@ 3976b2e4378dSMatthew G. Knepley DMGetLocalBoundingBox - Returns the bounding box for the piece of the DM on this process. 3977b2e4378dSMatthew G. Knepley 3978b2e4378dSMatthew G. Knepley Not collective 3979b2e4378dSMatthew G. Knepley 3980b2e4378dSMatthew G. Knepley Input Parameter: 3981b2e4378dSMatthew G. Knepley . dm - the DM 3982b2e4378dSMatthew G. Knepley 3983b2e4378dSMatthew G. Knepley Output Parameters: 3984b2e4378dSMatthew G. Knepley + lmin - local minimum coordinates (length coord dim, optional) 3985b2e4378dSMatthew G. Knepley - lmax - local maximim coordinates (length coord dim, optional) 3986b2e4378dSMatthew G. Knepley 3987b2e4378dSMatthew G. Knepley Level: beginner 3988b2e4378dSMatthew G. Knepley 3989b2e4378dSMatthew G. Knepley Note: If the DM is a DMDA and has no coordinates, the index bounds are returned instead. 3990b2e4378dSMatthew G. Knepley 3991b2e4378dSMatthew G. Knepley 3992b2e4378dSMatthew G. Knepley .seealso: DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetBoundingBox() 3993b2e4378dSMatthew G. Knepley @*/ 3994b2e4378dSMatthew G. Knepley PetscErrorCode DMGetLocalBoundingBox(DM dm, PetscReal lmin[], PetscReal lmax[]) 3995b2e4378dSMatthew G. Knepley { 3996b2e4378dSMatthew G. Knepley Vec coords = NULL; 3997b2e4378dSMatthew G. Knepley PetscReal min[3] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MAX_REAL}; 3998b2e4378dSMatthew G. Knepley PetscReal max[3] = {PETSC_MIN_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 3999b2e4378dSMatthew G. Knepley const PetscScalar *local_coords; 4000b2e4378dSMatthew G. Knepley PetscInt N, Ni; 4001b2e4378dSMatthew G. Knepley PetscInt cdim, i, j; 4002b2e4378dSMatthew G. Knepley PetscErrorCode ierr; 4003b2e4378dSMatthew G. Knepley 4004b2e4378dSMatthew G. Knepley PetscFunctionBegin; 4005b2e4378dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4006b2e4378dSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 4007b2e4378dSMatthew G. Knepley ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr); 4008b2e4378dSMatthew G. Knepley if (coords) { 4009b2e4378dSMatthew G. Knepley ierr = VecGetArrayRead(coords, &local_coords);CHKERRQ(ierr); 4010b2e4378dSMatthew G. Knepley ierr = VecGetLocalSize(coords, &N);CHKERRQ(ierr); 4011b2e4378dSMatthew G. Knepley Ni = N/cdim; 4012b2e4378dSMatthew G. Knepley for (i = 0; i < Ni; ++i) { 4013b2e4378dSMatthew G. Knepley for (j = 0; j < 3; ++j) { 4014b2e4378dSMatthew G. Knepley min[j] = j < cdim ? PetscMin(min[j], PetscRealPart(local_coords[i*cdim+j])) : 0; 4015b2e4378dSMatthew G. Knepley max[j] = j < cdim ? PetscMax(max[j], PetscRealPart(local_coords[i*cdim+j])) : 0; 4016b2e4378dSMatthew G. Knepley } 4017b2e4378dSMatthew G. Knepley } 4018b2e4378dSMatthew G. Knepley ierr = VecRestoreArrayRead(coords, &local_coords);CHKERRQ(ierr); 4019b2e4378dSMatthew G. Knepley } else { 4020b2e4378dSMatthew G. Knepley PetscBool isda; 4021b2e4378dSMatthew G. Knepley 4022b2e4378dSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) dm, DMDA, &isda);CHKERRQ(ierr); 4023b2e4378dSMatthew G. Knepley if (isda) {ierr = DMGetLocalBoundingIndices_DMDA(dm, min, max);CHKERRQ(ierr);} 4024b2e4378dSMatthew G. Knepley } 4025b2e4378dSMatthew G. Knepley if (lmin) {ierr = PetscArraycpy(lmin, min, cdim);CHKERRQ(ierr);} 4026b2e4378dSMatthew G. Knepley if (lmax) {ierr = PetscArraycpy(lmax, max, cdim);CHKERRQ(ierr);} 4027b2e4378dSMatthew G. Knepley PetscFunctionReturn(0); 4028b2e4378dSMatthew G. Knepley } 4029b2e4378dSMatthew G. Knepley 4030b2e4378dSMatthew G. Knepley /*@ 4031b2e4378dSMatthew G. Knepley DMGetBoundingBox - Returns the global bounding box for the DM. 4032b2e4378dSMatthew G. Knepley 4033b2e4378dSMatthew G. Knepley Collective 4034b2e4378dSMatthew G. Knepley 4035b2e4378dSMatthew G. Knepley Input Parameter: 4036b2e4378dSMatthew G. Knepley . dm - the DM 4037b2e4378dSMatthew G. Knepley 4038b2e4378dSMatthew G. Knepley Output Parameters: 4039b2e4378dSMatthew G. Knepley + gmin - global minimum coordinates (length coord dim, optional) 4040b2e4378dSMatthew G. Knepley - gmax - global maximim coordinates (length coord dim, optional) 4041b2e4378dSMatthew G. Knepley 4042b2e4378dSMatthew G. Knepley Level: beginner 4043b2e4378dSMatthew G. Knepley 4044b2e4378dSMatthew G. Knepley .seealso: DMGetLocalBoundingBox(), DMGetCoordinates(), DMGetCoordinatesLocal() 4045b2e4378dSMatthew G. Knepley @*/ 4046b2e4378dSMatthew G. Knepley PetscErrorCode DMGetBoundingBox(DM dm, PetscReal gmin[], PetscReal gmax[]) 4047b2e4378dSMatthew G. Knepley { 4048b2e4378dSMatthew G. Knepley PetscReal lmin[3], lmax[3]; 40496ce308c4SMatthew G. Knepley PetscInt cdim; 40506ce308c4SMatthew G. Knepley PetscMPIInt count; 4051b2e4378dSMatthew G. Knepley PetscErrorCode ierr; 4052b2e4378dSMatthew G. Knepley 4053b2e4378dSMatthew G. Knepley PetscFunctionBegin; 4054b2e4378dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4055b2e4378dSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 4056b2e4378dSMatthew G. Knepley ierr = PetscMPIIntCast(cdim, &count);CHKERRQ(ierr); 4057b2e4378dSMatthew G. Knepley ierr = DMGetLocalBoundingBox(dm, lmin, lmax);CHKERRQ(ierr); 4058*820f2d46SBarry Smith if (gmin) {ierr = MPIU_Allreduce(lmin, gmin, count, MPIU_REAL, MPIU_MIN, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr);} 4059*820f2d46SBarry Smith if (gmax) {ierr = MPIU_Allreduce(lmax, gmax, count, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr);} 4060b2e4378dSMatthew G. Knepley PetscFunctionReturn(0); 4061b2e4378dSMatthew G. Knepley } 4062b2e4378dSMatthew G. Knepley 40637da65231SMatthew G Knepley /******************************** FEM Support **********************************/ 40647da65231SMatthew G Knepley 4065a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) 4066a6dfd86eSKarl Rupp { 40671d47ebbbSSatish Balay PetscInt f; 40681b30c384SMatthew G Knepley PetscErrorCode ierr; 40691b30c384SMatthew G Knepley 40707da65231SMatthew G Knepley PetscFunctionBegin; 407174778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr); 40721d47ebbbSSatish Balay for (f = 0; f < len; ++f) { 407357622a8eSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, " | %g |\n", (double)PetscRealPart(x[f]));CHKERRQ(ierr); 40747da65231SMatthew G Knepley } 40757da65231SMatthew G Knepley PetscFunctionReturn(0); 40767da65231SMatthew G Knepley } 40777da65231SMatthew G Knepley 4078a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) 4079a6dfd86eSKarl Rupp { 40801b30c384SMatthew G Knepley PetscInt f, g; 40817da65231SMatthew G Knepley PetscErrorCode ierr; 40827da65231SMatthew G Knepley 40837da65231SMatthew G Knepley PetscFunctionBegin; 408474778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr); 40851d47ebbbSSatish Balay for (f = 0; f < rows; ++f) { 408674778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, " |");CHKERRQ(ierr); 40871d47ebbbSSatish Balay for (g = 0; g < cols; ++g) { 4088e3556bceSMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5g", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr); 40897da65231SMatthew G Knepley } 409074778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr); 40917da65231SMatthew G Knepley } 40927da65231SMatthew G Knepley PetscFunctionReturn(0); 40937da65231SMatthew G Knepley } 4094e7c4fc90SDmitry Karpeev 40956113b454SMatthew G. Knepley PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X) 4096e759306cSMatthew G. Knepley { 40970c5b8624SToby Isaac PetscInt localSize, bs; 40980c5b8624SToby Isaac PetscMPIInt size; 40990c5b8624SToby Isaac Vec x, xglob; 41000c5b8624SToby Isaac const PetscScalar *xarray; 4101e759306cSMatthew G. Knepley PetscErrorCode ierr; 4102e759306cSMatthew G. Knepley 4103e759306cSMatthew G. Knepley PetscFunctionBegin; 4104ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm),&size);CHKERRMPI(ierr); 4105e759306cSMatthew G. Knepley ierr = VecDuplicate(X, &x);CHKERRQ(ierr); 4106e759306cSMatthew G. Knepley ierr = VecCopy(X, x);CHKERRQ(ierr); 41076113b454SMatthew G. Knepley ierr = VecChop(x, tol);CHKERRQ(ierr); 41080c5b8624SToby Isaac ierr = PetscPrintf(PetscObjectComm((PetscObject) dm),"%s:\n",name);CHKERRQ(ierr); 41090c5b8624SToby Isaac if (size > 1) { 41100c5b8624SToby Isaac ierr = VecGetLocalSize(x,&localSize);CHKERRQ(ierr); 41110c5b8624SToby Isaac ierr = VecGetArrayRead(x,&xarray);CHKERRQ(ierr); 41120c5b8624SToby Isaac ierr = VecGetBlockSize(x,&bs);CHKERRQ(ierr); 41130c5b8624SToby Isaac ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject) dm),bs,localSize,PETSC_DETERMINE,xarray,&xglob);CHKERRQ(ierr); 41140c5b8624SToby Isaac } else { 41150c5b8624SToby Isaac xglob = x; 41160c5b8624SToby Isaac } 41170c5b8624SToby Isaac ierr = VecView(xglob,PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject) dm)));CHKERRQ(ierr); 41180c5b8624SToby Isaac if (size > 1) { 41190c5b8624SToby Isaac ierr = VecDestroy(&xglob);CHKERRQ(ierr); 41200c5b8624SToby Isaac ierr = VecRestoreArrayRead(x,&xarray);CHKERRQ(ierr); 41210c5b8624SToby Isaac } 4122e759306cSMatthew G. Knepley ierr = VecDestroy(&x);CHKERRQ(ierr); 4123e759306cSMatthew G. Knepley PetscFunctionReturn(0); 4124e759306cSMatthew G. Knepley } 4125e759306cSMatthew G. Knepley 412688ed4aceSMatthew G Knepley /*@ 41271bb6d2a8SBarry Smith DMGetSection - Get the PetscSection encoding the local data layout for the DM. This is equivalent to DMGetLocalSection(). Deprecated in v3.12 4128061576a5SJed Brown 4129061576a5SJed Brown Input Parameter: 4130061576a5SJed Brown . dm - The DM 4131061576a5SJed Brown 4132061576a5SJed Brown Output Parameter: 4133061576a5SJed Brown . section - The PetscSection 4134061576a5SJed Brown 4135061576a5SJed Brown Options Database Keys: 4136061576a5SJed Brown . -dm_petscsection_view - View the Section created by the DM 4137061576a5SJed Brown 4138061576a5SJed Brown Level: advanced 4139061576a5SJed Brown 4140061576a5SJed Brown Notes: 4141061576a5SJed Brown Use DMGetLocalSection() in new code. 4142061576a5SJed Brown 4143061576a5SJed Brown This gets a borrowed reference, so the user should not destroy this PetscSection. 4144061576a5SJed Brown 4145061576a5SJed Brown .seealso: DMGetLocalSection(), DMSetLocalSection(), DMGetGlobalSection() 4146061576a5SJed Brown @*/ 4147061576a5SJed Brown PetscErrorCode DMGetSection(DM dm, PetscSection *section) 4148061576a5SJed Brown { 4149061576a5SJed Brown PetscErrorCode ierr; 4150061576a5SJed Brown 4151061576a5SJed Brown PetscFunctionBegin; 4152061576a5SJed Brown ierr = DMGetLocalSection(dm,section);CHKERRQ(ierr); 4153061576a5SJed Brown PetscFunctionReturn(0); 4154061576a5SJed Brown } 4155061576a5SJed Brown 4156061576a5SJed Brown /*@ 4157061576a5SJed Brown DMGetLocalSection - Get the PetscSection encoding the local data layout for the DM. 415888ed4aceSMatthew G Knepley 415988ed4aceSMatthew G Knepley Input Parameter: 416088ed4aceSMatthew G Knepley . dm - The DM 416188ed4aceSMatthew G Knepley 416288ed4aceSMatthew G Knepley Output Parameter: 416388ed4aceSMatthew G Knepley . section - The PetscSection 416488ed4aceSMatthew G Knepley 4165e5893cccSMatthew G. Knepley Options Database Keys: 4166e5893cccSMatthew G. Knepley . -dm_petscsection_view - View the Section created by the DM 4167e5893cccSMatthew G. Knepley 416888ed4aceSMatthew G Knepley Level: intermediate 416988ed4aceSMatthew G Knepley 417088ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSection. 417188ed4aceSMatthew G Knepley 4172061576a5SJed Brown .seealso: DMSetLocalSection(), DMGetGlobalSection() 417388ed4aceSMatthew G Knepley @*/ 4174061576a5SJed Brown PetscErrorCode DMGetLocalSection(DM dm, PetscSection *section) 41750adebc6cSBarry Smith { 4176fd59a867SMatthew G. Knepley PetscErrorCode ierr; 4177fd59a867SMatthew G. Knepley 417888ed4aceSMatthew G Knepley PetscFunctionBegin; 417988ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 418088ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 41811bb6d2a8SBarry Smith if (!dm->localSection && dm->ops->createlocalsection) { 4182e5e52638SMatthew G. Knepley PetscInt d; 4183e5e52638SMatthew G. Knepley 4184e5e52638SMatthew G. Knepley if (dm->setfromoptionscalled) for (d = 0; d < dm->Nds; ++d) {ierr = PetscDSSetFromOptions(dm->probs[d].ds);CHKERRQ(ierr);} 41851bb6d2a8SBarry Smith ierr = (*dm->ops->createlocalsection)(dm);CHKERRQ(ierr); 41861bb6d2a8SBarry Smith if (dm->localSection) {ierr = PetscObjectViewFromOptions((PetscObject) dm->localSection, NULL, "-dm_petscsection_view");CHKERRQ(ierr);} 41872f0f8703SMatthew G. Knepley } 41881bb6d2a8SBarry Smith *section = dm->localSection; 418988ed4aceSMatthew G Knepley PetscFunctionReturn(0); 419088ed4aceSMatthew G Knepley } 419188ed4aceSMatthew G Knepley 419288ed4aceSMatthew G Knepley /*@ 41931bb6d2a8SBarry Smith DMSetSection - Set the PetscSection encoding the local data layout for the DM. This is equivalent to DMSetLocalSection(). Deprecated in v3.12 4194061576a5SJed Brown 4195061576a5SJed Brown Input Parameters: 4196061576a5SJed Brown + dm - The DM 4197061576a5SJed Brown - section - The PetscSection 4198061576a5SJed Brown 4199061576a5SJed Brown Level: advanced 4200061576a5SJed Brown 4201061576a5SJed Brown Notes: 4202061576a5SJed Brown Use DMSetLocalSection() in new code. 4203061576a5SJed Brown 4204061576a5SJed Brown Any existing Section will be destroyed 4205061576a5SJed Brown 4206061576a5SJed Brown .seealso: DMSetLocalSection(), DMGetLocalSection(), DMSetGlobalSection() 4207061576a5SJed Brown @*/ 4208061576a5SJed Brown PetscErrorCode DMSetSection(DM dm, PetscSection section) 4209061576a5SJed Brown { 4210061576a5SJed Brown PetscErrorCode ierr; 4211061576a5SJed Brown 4212061576a5SJed Brown PetscFunctionBegin; 4213061576a5SJed Brown ierr = DMSetLocalSection(dm,section);CHKERRQ(ierr); 4214061576a5SJed Brown PetscFunctionReturn(0); 4215061576a5SJed Brown } 4216061576a5SJed Brown 4217061576a5SJed Brown /*@ 4218061576a5SJed Brown DMSetLocalSection - Set the PetscSection encoding the local data layout for the DM. 421988ed4aceSMatthew G Knepley 422088ed4aceSMatthew G Knepley Input Parameters: 422188ed4aceSMatthew G Knepley + dm - The DM 422288ed4aceSMatthew G Knepley - section - The PetscSection 422388ed4aceSMatthew G Knepley 422488ed4aceSMatthew G Knepley Level: intermediate 422588ed4aceSMatthew G Knepley 422688ed4aceSMatthew G Knepley Note: Any existing Section will be destroyed 422788ed4aceSMatthew G Knepley 4228061576a5SJed Brown .seealso: DMGetLocalSection(), DMSetGlobalSection() 422988ed4aceSMatthew G Knepley @*/ 4230061576a5SJed Brown PetscErrorCode DMSetLocalSection(DM dm, PetscSection section) 42310adebc6cSBarry Smith { 4232c473ab19SMatthew G. Knepley PetscInt numFields = 0; 4233af122d2aSMatthew G Knepley PetscInt f; 423488ed4aceSMatthew G Knepley PetscErrorCode ierr; 423588ed4aceSMatthew G Knepley 423688ed4aceSMatthew G Knepley PetscFunctionBegin; 423788ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4238b9d85ea2SLisandro Dalcin if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 42391d799100SJed Brown ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 42401bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&dm->localSection);CHKERRQ(ierr); 42411bb6d2a8SBarry Smith dm->localSection = section; 42421bb6d2a8SBarry Smith if (section) {ierr = PetscSectionGetNumFields(dm->localSection, &numFields);CHKERRQ(ierr);} 4243af122d2aSMatthew G Knepley if (numFields) { 4244af122d2aSMatthew G Knepley ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr); 4245af122d2aSMatthew G Knepley for (f = 0; f < numFields; ++f) { 42460f21e855SMatthew G. Knepley PetscObject disc; 4247af122d2aSMatthew G Knepley const char *name; 4248af122d2aSMatthew G Knepley 42491bb6d2a8SBarry Smith ierr = PetscSectionGetFieldName(dm->localSection, f, &name);CHKERRQ(ierr); 425044a7f3ddSMatthew G. Knepley ierr = DMGetField(dm, f, NULL, &disc);CHKERRQ(ierr); 42510f21e855SMatthew G. Knepley ierr = PetscObjectSetName(disc, name);CHKERRQ(ierr); 4252af122d2aSMatthew G Knepley } 4253af122d2aSMatthew G Knepley } 4254e87a4003SBarry Smith /* The global section will be rebuilt in the next call to DMGetGlobalSection(). */ 42551bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&dm->globalSection);CHKERRQ(ierr); 425688ed4aceSMatthew G Knepley PetscFunctionReturn(0); 425788ed4aceSMatthew G Knepley } 425888ed4aceSMatthew G Knepley 42599435951eSToby Isaac /*@ 4260b7385021SStefano Zampini DMGetDefaultConstraints - Get the PetscSection and Mat that specify the local constraint interpolation. See DMSetDefaultConstraints() for a description of the purpose of constraint interpolation. 42619435951eSToby Isaac 4262e228b242SToby Isaac not collective 4263e228b242SToby Isaac 42649435951eSToby Isaac Input Parameter: 42659435951eSToby Isaac . dm - The DM 42669435951eSToby Isaac 42679435951eSToby Isaac Output Parameter: 42689435951eSToby 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. 42699435951eSToby 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. 42709435951eSToby Isaac 42719435951eSToby Isaac Level: advanced 42729435951eSToby Isaac 42739435951eSToby Isaac Note: This gets borrowed references, so the user should not destroy the PetscSection or the Mat. 42749435951eSToby Isaac 42759435951eSToby Isaac .seealso: DMSetDefaultConstraints() 42769435951eSToby Isaac @*/ 42779435951eSToby Isaac PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat) 42789435951eSToby Isaac { 42799435951eSToby Isaac PetscErrorCode ierr; 42809435951eSToby Isaac 42819435951eSToby Isaac PetscFunctionBegin; 42829435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 42839435951eSToby Isaac if (!dm->defaultConstraintSection && !dm->defaultConstraintMat && dm->ops->createdefaultconstraints) {ierr = (*dm->ops->createdefaultconstraints)(dm);CHKERRQ(ierr);} 428445a75d81SToby Isaac if (section) {*section = dm->defaultConstraintSection;} 428545a75d81SToby Isaac if (mat) {*mat = dm->defaultConstraintMat;} 42869435951eSToby Isaac PetscFunctionReturn(0); 42879435951eSToby Isaac } 42889435951eSToby Isaac 42899435951eSToby Isaac /*@ 4290b7385021SStefano Zampini DMSetDefaultConstraints - Set the PetscSection and Mat that specify the local constraint interpolation. 42919435951eSToby Isaac 42929435951eSToby 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(). 42939435951eSToby Isaac 42949435951eSToby 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. 42959435951eSToby Isaac 4296e228b242SToby Isaac collective on dm 4297e228b242SToby Isaac 42989435951eSToby Isaac Input Parameters: 42999435951eSToby Isaac + dm - The DM 4300e228b242SToby 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). 4301e228b242SToby 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). 43029435951eSToby Isaac 43039435951eSToby Isaac Level: advanced 43049435951eSToby Isaac 43059435951eSToby Isaac Note: This increments the references of the PetscSection and the Mat, so they user can destroy them 43069435951eSToby Isaac 43079435951eSToby Isaac .seealso: DMGetDefaultConstraints() 43089435951eSToby Isaac @*/ 43099435951eSToby Isaac PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat) 43109435951eSToby Isaac { 4311e228b242SToby Isaac PetscMPIInt result; 43129435951eSToby Isaac PetscErrorCode ierr; 43139435951eSToby Isaac 43149435951eSToby Isaac PetscFunctionBegin; 43159435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4316e228b242SToby Isaac if (section) { 4317e228b242SToby Isaac PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 4318ffc4695bSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)section),&result);CHKERRMPI(ierr); 4319f60917d2SBarry Smith if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint section must have local communicator"); 4320e228b242SToby Isaac } 4321e228b242SToby Isaac if (mat) { 4322e228b242SToby Isaac PetscValidHeaderSpecific(mat,MAT_CLASSID,3); 4323ffc4695bSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)mat),&result);CHKERRMPI(ierr); 4324f60917d2SBarry Smith if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint matrix must have local communicator"); 4325e228b242SToby Isaac } 43269435951eSToby Isaac ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 43279435951eSToby Isaac ierr = PetscSectionDestroy(&dm->defaultConstraintSection);CHKERRQ(ierr); 43289435951eSToby Isaac dm->defaultConstraintSection = section; 43299435951eSToby Isaac ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 43309435951eSToby Isaac ierr = MatDestroy(&dm->defaultConstraintMat);CHKERRQ(ierr); 43319435951eSToby Isaac dm->defaultConstraintMat = mat; 43329435951eSToby Isaac PetscFunctionReturn(0); 43339435951eSToby Isaac } 43349435951eSToby Isaac 4335497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 4336507e4973SMatthew G. Knepley /* 4337507e4973SMatthew G. Knepley DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections. 4338507e4973SMatthew G. Knepley 4339507e4973SMatthew G. Knepley Input Parameters: 4340507e4973SMatthew G. Knepley + dm - The DM 4341507e4973SMatthew G. Knepley . localSection - PetscSection describing the local data layout 4342507e4973SMatthew G. Knepley - globalSection - PetscSection describing the global data layout 4343507e4973SMatthew G. Knepley 4344507e4973SMatthew G. Knepley Level: intermediate 4345507e4973SMatthew G. Knepley 43461bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMSetSectionSF() 4347507e4973SMatthew G. Knepley */ 4348f741bcd2SMatthew G. Knepley static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection) 4349507e4973SMatthew G. Knepley { 4350507e4973SMatthew G. Knepley MPI_Comm comm; 4351507e4973SMatthew G. Knepley PetscLayout layout; 4352507e4973SMatthew G. Knepley const PetscInt *ranges; 4353507e4973SMatthew G. Knepley PetscInt pStart, pEnd, p, nroots; 4354507e4973SMatthew G. Knepley PetscMPIInt size, rank; 4355507e4973SMatthew G. Knepley PetscBool valid = PETSC_TRUE, gvalid; 4356507e4973SMatthew G. Knepley PetscErrorCode ierr; 4357507e4973SMatthew G. Knepley 4358507e4973SMatthew G. Knepley PetscFunctionBegin; 4359507e4973SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 4360507e4973SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4361ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 4362ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 4363507e4973SMatthew G. Knepley ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr); 4364507e4973SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr); 4365507e4973SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr); 4366507e4973SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr); 4367507e4973SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr); 4368507e4973SMatthew G. Knepley ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr); 4369507e4973SMatthew G. Knepley ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr); 4370507e4973SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 4371f741bcd2SMatthew G. Knepley PetscInt dof, cdof, off, gdof, gcdof, goff, gsize, d; 4372507e4973SMatthew G. Knepley 4373507e4973SMatthew G. Knepley ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr); 4374507e4973SMatthew G. Knepley ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr); 4375507e4973SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr); 4376507e4973SMatthew G. Knepley ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr); 4377507e4973SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr); 4378507e4973SMatthew G. Knepley ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr); 4379507e4973SMatthew G. Knepley if (!gdof) continue; /* Censored point */ 4380507e4973SMatthew 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;} 4381507e4973SMatthew 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;} 4382507e4973SMatthew G. Knepley if (gdof < 0) { 4383507e4973SMatthew G. Knepley gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof; 4384507e4973SMatthew G. Knepley for (d = 0; d < gsize; ++d) { 4385507e4973SMatthew G. Knepley PetscInt offset = -(goff+1) + d, r; 4386507e4973SMatthew G. Knepley 4387507e4973SMatthew G. Knepley ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr); 4388507e4973SMatthew G. Knepley if (r < 0) r = -(r+2); 4389507e4973SMatthew 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;} 4390507e4973SMatthew G. Knepley } 4391507e4973SMatthew G. Knepley } 4392507e4973SMatthew G. Knepley } 4393507e4973SMatthew G. Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 4394507e4973SMatthew G. Knepley ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr); 4395*820f2d46SBarry Smith ierr = MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRMPI(ierr); 4396507e4973SMatthew G. Knepley if (!gvalid) { 4397507e4973SMatthew G. Knepley ierr = DMView(dm, NULL);CHKERRQ(ierr); 4398507e4973SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections"); 4399507e4973SMatthew G. Knepley } 4400507e4973SMatthew G. Knepley PetscFunctionReturn(0); 4401507e4973SMatthew G. Knepley } 4402f741bcd2SMatthew G. Knepley #endif 4403507e4973SMatthew G. Knepley 440488ed4aceSMatthew G Knepley /*@ 4405e87a4003SBarry Smith DMGetGlobalSection - Get the PetscSection encoding the global data layout for the DM. 440688ed4aceSMatthew G Knepley 4407d083f849SBarry Smith Collective on dm 44088b1ab98fSJed Brown 440988ed4aceSMatthew G Knepley Input Parameter: 441088ed4aceSMatthew G Knepley . dm - The DM 441188ed4aceSMatthew G Knepley 441288ed4aceSMatthew G Knepley Output Parameter: 441388ed4aceSMatthew G Knepley . section - The PetscSection 441488ed4aceSMatthew G Knepley 441588ed4aceSMatthew G Knepley Level: intermediate 441688ed4aceSMatthew G Knepley 441788ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSection. 441888ed4aceSMatthew G Knepley 441992fd8e1eSJed Brown .seealso: DMSetLocalSection(), DMGetLocalSection() 442088ed4aceSMatthew G Knepley @*/ 4421e87a4003SBarry Smith PetscErrorCode DMGetGlobalSection(DM dm, PetscSection *section) 44220adebc6cSBarry Smith { 442388ed4aceSMatthew G Knepley PetscErrorCode ierr; 442488ed4aceSMatthew G Knepley 442588ed4aceSMatthew G Knepley PetscFunctionBegin; 442688ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 442788ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 44281bb6d2a8SBarry Smith if (!dm->globalSection) { 4429fd59a867SMatthew G. Knepley PetscSection s; 4430fd59a867SMatthew G. Knepley 443192fd8e1eSJed Brown ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr); 4432fd59a867SMatthew 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"); 443333907cc2SStefano 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"); 44341bb6d2a8SBarry Smith ierr = PetscSectionCreateGlobalSection(s, dm->sf, PETSC_FALSE, PETSC_FALSE, &dm->globalSection);CHKERRQ(ierr); 4435cf06b437SMatthew G. Knepley ierr = PetscLayoutDestroy(&dm->map);CHKERRQ(ierr); 44361bb6d2a8SBarry Smith ierr = PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->globalSection, &dm->map);CHKERRQ(ierr); 44371bb6d2a8SBarry Smith ierr = PetscSectionViewFromOptions(dm->globalSection, NULL, "-global_section_view");CHKERRQ(ierr); 443888ed4aceSMatthew G Knepley } 44391bb6d2a8SBarry Smith *section = dm->globalSection; 444088ed4aceSMatthew G Knepley PetscFunctionReturn(0); 444188ed4aceSMatthew G Knepley } 444288ed4aceSMatthew G Knepley 4443b21d0597SMatthew G Knepley /*@ 4444e87a4003SBarry Smith DMSetGlobalSection - Set the PetscSection encoding the global data layout for the DM. 4445b21d0597SMatthew G Knepley 4446b21d0597SMatthew G Knepley Input Parameters: 4447b21d0597SMatthew G Knepley + dm - The DM 44485080bbdbSMatthew G Knepley - section - The PetscSection, or NULL 4449b21d0597SMatthew G Knepley 4450b21d0597SMatthew G Knepley Level: intermediate 4451b21d0597SMatthew G Knepley 4452b21d0597SMatthew G Knepley Note: Any existing Section will be destroyed 4453b21d0597SMatthew G Knepley 445492fd8e1eSJed Brown .seealso: DMGetGlobalSection(), DMSetLocalSection() 4455b21d0597SMatthew G Knepley @*/ 4456e87a4003SBarry Smith PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section) 44570adebc6cSBarry Smith { 4458b21d0597SMatthew G Knepley PetscErrorCode ierr; 4459b21d0597SMatthew G Knepley 4460b21d0597SMatthew G Knepley PetscFunctionBegin; 4461b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 44625080bbdbSMatthew G Knepley if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 44631d799100SJed Brown ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 44641bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&dm->globalSection);CHKERRQ(ierr); 44651bb6d2a8SBarry Smith dm->globalSection = section; 4466497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 44671bb6d2a8SBarry Smith if (section) {ierr = DMDefaultSectionCheckConsistency_Internal(dm, dm->localSection, section);CHKERRQ(ierr);} 4468507e4973SMatthew G. Knepley #endif 4469b21d0597SMatthew G Knepley PetscFunctionReturn(0); 4470b21d0597SMatthew G Knepley } 4471b21d0597SMatthew G Knepley 447288ed4aceSMatthew G Knepley /*@ 44731bb6d2a8SBarry Smith DMGetSectionSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set, 447488ed4aceSMatthew G Knepley it is created from the default PetscSection layouts in the DM. 447588ed4aceSMatthew G Knepley 447688ed4aceSMatthew G Knepley Input Parameter: 447788ed4aceSMatthew G Knepley . dm - The DM 447888ed4aceSMatthew G Knepley 447988ed4aceSMatthew G Knepley Output Parameter: 448088ed4aceSMatthew G Knepley . sf - The PetscSF 448188ed4aceSMatthew G Knepley 448288ed4aceSMatthew G Knepley Level: intermediate 448388ed4aceSMatthew G Knepley 448488ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSF. 448588ed4aceSMatthew G Knepley 44861bb6d2a8SBarry Smith .seealso: DMSetSectionSF(), DMCreateSectionSF() 448788ed4aceSMatthew G Knepley @*/ 44881bb6d2a8SBarry Smith PetscErrorCode DMGetSectionSF(DM dm, PetscSF *sf) 44890adebc6cSBarry Smith { 449088ed4aceSMatthew G Knepley PetscInt nroots; 449188ed4aceSMatthew G Knepley PetscErrorCode ierr; 449288ed4aceSMatthew G Knepley 449388ed4aceSMatthew G Knepley PetscFunctionBegin; 449488ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 449588ed4aceSMatthew G Knepley PetscValidPointer(sf, 2); 44961bb6d2a8SBarry Smith if (!dm->sectionSF) { 44971bb6d2a8SBarry Smith ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm),&dm->sectionSF);CHKERRQ(ierr); 449833907cc2SStefano Zampini } 44991bb6d2a8SBarry Smith ierr = PetscSFGetGraph(dm->sectionSF, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 450088ed4aceSMatthew G Knepley if (nroots < 0) { 450188ed4aceSMatthew G Knepley PetscSection section, gSection; 450288ed4aceSMatthew G Knepley 450392fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 450431ea6d37SMatthew G Knepley if (section) { 4505e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, &gSection);CHKERRQ(ierr); 45061bb6d2a8SBarry Smith ierr = DMCreateSectionSF(dm, section, gSection);CHKERRQ(ierr); 450731ea6d37SMatthew G Knepley } else { 45080298fd71SBarry Smith *sf = NULL; 450931ea6d37SMatthew G Knepley PetscFunctionReturn(0); 451031ea6d37SMatthew G Knepley } 451188ed4aceSMatthew G Knepley } 45121bb6d2a8SBarry Smith *sf = dm->sectionSF; 451388ed4aceSMatthew G Knepley PetscFunctionReturn(0); 451488ed4aceSMatthew G Knepley } 451588ed4aceSMatthew G Knepley 451688ed4aceSMatthew G Knepley /*@ 45171bb6d2a8SBarry Smith DMSetSectionSF - Set the PetscSF encoding the parallel dof overlap for the DM 451888ed4aceSMatthew G Knepley 451988ed4aceSMatthew G Knepley Input Parameters: 452088ed4aceSMatthew G Knepley + dm - The DM 452188ed4aceSMatthew G Knepley - sf - The PetscSF 452288ed4aceSMatthew G Knepley 452388ed4aceSMatthew G Knepley Level: intermediate 452488ed4aceSMatthew G Knepley 452588ed4aceSMatthew G Knepley Note: Any previous SF is destroyed 452688ed4aceSMatthew G Knepley 45271bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMCreateSectionSF() 452888ed4aceSMatthew G Knepley @*/ 45291bb6d2a8SBarry Smith PetscErrorCode DMSetSectionSF(DM dm, PetscSF sf) 45300adebc6cSBarry Smith { 453188ed4aceSMatthew G Knepley PetscErrorCode ierr; 453288ed4aceSMatthew G Knepley 453388ed4aceSMatthew G Knepley PetscFunctionBegin; 453488ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4535b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 453633907cc2SStefano Zampini ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr); 45371bb6d2a8SBarry Smith ierr = PetscSFDestroy(&dm->sectionSF);CHKERRQ(ierr); 45381bb6d2a8SBarry Smith dm->sectionSF = sf; 453988ed4aceSMatthew G Knepley PetscFunctionReturn(0); 454088ed4aceSMatthew G Knepley } 454188ed4aceSMatthew G Knepley 454288ed4aceSMatthew G Knepley /*@C 45431bb6d2a8SBarry Smith DMCreateSectionSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections 454488ed4aceSMatthew G Knepley describing the data layout. 454588ed4aceSMatthew G Knepley 454688ed4aceSMatthew G Knepley Input Parameters: 454788ed4aceSMatthew G Knepley + dm - The DM 454888ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout 454988ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout 455088ed4aceSMatthew G Knepley 45511bb6d2a8SBarry Smith Notes: One usually uses DMGetSectionSF() to obtain the PetscSF 455288ed4aceSMatthew G Knepley 45531bb6d2a8SBarry Smith Level: developer 45541bb6d2a8SBarry Smith 45551bb6d2a8SBarry Smith Developer Note: Since this routine has for arguments the two sections from the DM and puts the resulting PetscSF 45561bb6d2a8SBarry Smith directly into the DM, perhaps this function should not take the local and global sections as 45571bb6d2a8SBarry Smith input and should just obtain them from the DM? 45581bb6d2a8SBarry Smith 45591bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMSetSectionSF(), DMGetLocalSection(), DMGetGlobalSection() 456088ed4aceSMatthew G Knepley @*/ 45611bb6d2a8SBarry Smith PetscErrorCode DMCreateSectionSF(DM dm, PetscSection localSection, PetscSection globalSection) 456288ed4aceSMatthew G Knepley { 456388ed4aceSMatthew G Knepley PetscErrorCode ierr; 456488ed4aceSMatthew G Knepley 456588ed4aceSMatthew G Knepley PetscFunctionBegin; 456688ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4567b0c7db22SLisandro Dalcin ierr = PetscSFSetGraphSection(dm->sectionSF, localSection, globalSection);CHKERRQ(ierr); 456888ed4aceSMatthew G Knepley PetscFunctionReturn(0); 456988ed4aceSMatthew G Knepley } 4570af122d2aSMatthew G Knepley 4571b21d0597SMatthew G Knepley /*@ 4572b21d0597SMatthew G Knepley DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM. 4573b21d0597SMatthew G Knepley 4574b21d0597SMatthew G Knepley Input Parameter: 4575b21d0597SMatthew G Knepley . dm - The DM 4576b21d0597SMatthew G Knepley 4577b21d0597SMatthew G Knepley Output Parameter: 4578b21d0597SMatthew G Knepley . sf - The PetscSF 4579b21d0597SMatthew G Knepley 4580b21d0597SMatthew G Knepley Level: intermediate 4581b21d0597SMatthew G Knepley 4582b21d0597SMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSF. 4583b21d0597SMatthew G Knepley 45841bb6d2a8SBarry Smith .seealso: DMSetPointSF(), DMGetSectionSF(), DMSetSectionSF(), DMCreateSectionSF() 4585b21d0597SMatthew G Knepley @*/ 45860adebc6cSBarry Smith PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) 45870adebc6cSBarry Smith { 4588b21d0597SMatthew G Knepley PetscFunctionBegin; 4589b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4590b21d0597SMatthew G Knepley PetscValidPointer(sf, 2); 4591b21d0597SMatthew G Knepley *sf = dm->sf; 4592b21d0597SMatthew G Knepley PetscFunctionReturn(0); 4593b21d0597SMatthew G Knepley } 4594b21d0597SMatthew G Knepley 4595057b4bcdSMatthew G Knepley /*@ 4596057b4bcdSMatthew G Knepley DMSetPointSF - Set the PetscSF encoding the parallel section point overlap for the DM. 4597057b4bcdSMatthew G Knepley 4598057b4bcdSMatthew G Knepley Input Parameters: 4599057b4bcdSMatthew G Knepley + dm - The DM 4600057b4bcdSMatthew G Knepley - sf - The PetscSF 4601057b4bcdSMatthew G Knepley 4602057b4bcdSMatthew G Knepley Level: intermediate 4603057b4bcdSMatthew G Knepley 46041bb6d2a8SBarry Smith .seealso: DMGetPointSF(), DMGetSectionSF(), DMSetSectionSF(), DMCreateSectionSF() 4605057b4bcdSMatthew G Knepley @*/ 46060adebc6cSBarry Smith PetscErrorCode DMSetPointSF(DM dm, PetscSF sf) 46070adebc6cSBarry Smith { 4608057b4bcdSMatthew G Knepley PetscErrorCode ierr; 4609057b4bcdSMatthew G Knepley 4610057b4bcdSMatthew G Knepley PetscFunctionBegin; 4611057b4bcdSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4612b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 4613057b4bcdSMatthew G Knepley ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr); 461433907cc2SStefano Zampini ierr = PetscSFDestroy(&dm->sf);CHKERRQ(ierr); 4615057b4bcdSMatthew G Knepley dm->sf = sf; 4616057b4bcdSMatthew G Knepley PetscFunctionReturn(0); 4617057b4bcdSMatthew G Knepley } 4618057b4bcdSMatthew G Knepley 461934aa8a36SMatthew G. Knepley static PetscErrorCode DMSetDefaultAdjacency_Private(DM dm, PetscInt f, PetscObject disc) 462034aa8a36SMatthew G. Knepley { 462134aa8a36SMatthew G. Knepley PetscClassId id; 462234aa8a36SMatthew G. Knepley PetscErrorCode ierr; 462334aa8a36SMatthew G. Knepley 462434aa8a36SMatthew G. Knepley PetscFunctionBegin; 462534aa8a36SMatthew G. Knepley ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr); 462634aa8a36SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 462734aa8a36SMatthew G. Knepley ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr); 462834aa8a36SMatthew G. Knepley } else if (id == PETSCFV_CLASSID) { 462934aa8a36SMatthew G. Knepley ierr = DMSetAdjacency(dm, f, PETSC_TRUE, PETSC_FALSE);CHKERRQ(ierr); 463017c1d62eSMatthew G. Knepley } else { 463117c1d62eSMatthew G. Knepley ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr); 463234aa8a36SMatthew G. Knepley } 463334aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 463434aa8a36SMatthew G. Knepley } 463534aa8a36SMatthew G. Knepley 463644a7f3ddSMatthew G. Knepley static PetscErrorCode DMFieldEnlarge_Static(DM dm, PetscInt NfNew) 463744a7f3ddSMatthew G. Knepley { 463844a7f3ddSMatthew G. Knepley RegionField *tmpr; 463944a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf, f; 464044a7f3ddSMatthew G. Knepley PetscErrorCode ierr; 464144a7f3ddSMatthew G. Knepley 464244a7f3ddSMatthew G. Knepley PetscFunctionBegin; 464344a7f3ddSMatthew G. Knepley if (Nf >= NfNew) PetscFunctionReturn(0); 464444a7f3ddSMatthew G. Knepley ierr = PetscMalloc1(NfNew, &tmpr);CHKERRQ(ierr); 464544a7f3ddSMatthew G. Knepley for (f = 0; f < Nf; ++f) tmpr[f] = dm->fields[f]; 4646e0b68406SMatthew Knepley for (f = Nf; f < NfNew; ++f) {tmpr[f].disc = NULL; tmpr[f].label = NULL; tmpr[f].avoidTensor = PETSC_FALSE;} 464744a7f3ddSMatthew G. Knepley ierr = PetscFree(dm->fields);CHKERRQ(ierr); 464844a7f3ddSMatthew G. Knepley dm->Nf = NfNew; 464944a7f3ddSMatthew G. Knepley dm->fields = tmpr; 465044a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 465144a7f3ddSMatthew G. Knepley } 465244a7f3ddSMatthew G. Knepley 465344a7f3ddSMatthew G. Knepley /*@ 465444a7f3ddSMatthew G. Knepley DMClearFields - Remove all fields from the DM 465544a7f3ddSMatthew G. Knepley 4656d083f849SBarry Smith Logically collective on dm 465744a7f3ddSMatthew G. Knepley 465844a7f3ddSMatthew G. Knepley Input Parameter: 465944a7f3ddSMatthew G. Knepley . dm - The DM 466044a7f3ddSMatthew G. Knepley 466144a7f3ddSMatthew G. Knepley Level: intermediate 466244a7f3ddSMatthew G. Knepley 466344a7f3ddSMatthew G. Knepley .seealso: DMGetNumFields(), DMSetNumFields(), DMSetField() 466444a7f3ddSMatthew G. Knepley @*/ 466544a7f3ddSMatthew G. Knepley PetscErrorCode DMClearFields(DM dm) 466644a7f3ddSMatthew G. Knepley { 466744a7f3ddSMatthew G. Knepley PetscInt f; 466844a7f3ddSMatthew G. Knepley PetscErrorCode ierr; 466944a7f3ddSMatthew G. Knepley 467044a7f3ddSMatthew G. Knepley PetscFunctionBegin; 467144a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 467244a7f3ddSMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 467344a7f3ddSMatthew G. Knepley ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr); 467444a7f3ddSMatthew G. Knepley ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr); 467544a7f3ddSMatthew G. Knepley } 467644a7f3ddSMatthew G. Knepley ierr = PetscFree(dm->fields);CHKERRQ(ierr); 467744a7f3ddSMatthew G. Knepley dm->fields = NULL; 467844a7f3ddSMatthew G. Knepley dm->Nf = 0; 467944a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 468044a7f3ddSMatthew G. Knepley } 468144a7f3ddSMatthew G. Knepley 4682689b5837SMatthew G. Knepley /*@ 4683689b5837SMatthew G. Knepley DMGetNumFields - Get the number of fields in the DM 4684689b5837SMatthew G. Knepley 4685689b5837SMatthew G. Knepley Not collective 4686689b5837SMatthew G. Knepley 4687689b5837SMatthew G. Knepley Input Parameter: 4688689b5837SMatthew G. Knepley . dm - The DM 4689689b5837SMatthew G. Knepley 4690689b5837SMatthew G. Knepley Output Parameter: 4691689b5837SMatthew G. Knepley . Nf - The number of fields 4692689b5837SMatthew G. Knepley 4693689b5837SMatthew G. Knepley Level: intermediate 4694689b5837SMatthew G. Knepley 4695689b5837SMatthew G. Knepley .seealso: DMSetNumFields(), DMSetField() 4696689b5837SMatthew G. Knepley @*/ 46970f21e855SMatthew G. Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields) 46980f21e855SMatthew G. Knepley { 46990f21e855SMatthew G. Knepley PetscFunctionBegin; 47000f21e855SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4701534a8f05SLisandro Dalcin PetscValidIntPointer(numFields, 2); 470244a7f3ddSMatthew G. Knepley *numFields = dm->Nf; 4703af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4704af122d2aSMatthew G Knepley } 4705af122d2aSMatthew G Knepley 4706689b5837SMatthew G. Knepley /*@ 4707689b5837SMatthew G. Knepley DMSetNumFields - Set the number of fields in the DM 4708689b5837SMatthew G. Knepley 4709d083f849SBarry Smith Logically collective on dm 4710689b5837SMatthew G. Knepley 4711689b5837SMatthew G. Knepley Input Parameters: 4712689b5837SMatthew G. Knepley + dm - The DM 4713689b5837SMatthew G. Knepley - Nf - The number of fields 4714689b5837SMatthew G. Knepley 4715689b5837SMatthew G. Knepley Level: intermediate 4716689b5837SMatthew G. Knepley 4717689b5837SMatthew G. Knepley .seealso: DMGetNumFields(), DMSetField() 4718689b5837SMatthew G. Knepley @*/ 4719af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields) 4720af122d2aSMatthew G Knepley { 47210f21e855SMatthew G. Knepley PetscInt Nf, f; 4722af122d2aSMatthew G Knepley PetscErrorCode ierr; 4723af122d2aSMatthew G Knepley 4724af122d2aSMatthew G Knepley PetscFunctionBegin; 4725af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 472644a7f3ddSMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 47270f21e855SMatthew G. Knepley for (f = Nf; f < numFields; ++f) { 47280f21e855SMatthew G. Knepley PetscContainer obj; 47290f21e855SMatthew G. Knepley 47300f21e855SMatthew G. Knepley ierr = PetscContainerCreate(PetscObjectComm((PetscObject) dm), &obj);CHKERRQ(ierr); 473144a7f3ddSMatthew G. Knepley ierr = DMAddField(dm, NULL, (PetscObject) obj);CHKERRQ(ierr); 47320f21e855SMatthew G. Knepley ierr = PetscContainerDestroy(&obj);CHKERRQ(ierr); 4733af122d2aSMatthew G Knepley } 4734af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4735af122d2aSMatthew G Knepley } 4736af122d2aSMatthew G Knepley 4737c1929be8SMatthew G. Knepley /*@ 4738c1929be8SMatthew G. Knepley DMGetField - Return the discretization object for a given DM field 4739c1929be8SMatthew G. Knepley 4740c1929be8SMatthew G. Knepley Not collective 4741c1929be8SMatthew G. Knepley 4742c1929be8SMatthew G. Knepley Input Parameters: 4743c1929be8SMatthew G. Knepley + dm - The DM 4744c1929be8SMatthew G. Knepley - f - The field number 4745c1929be8SMatthew G. Knepley 474644a7f3ddSMatthew G. Knepley Output Parameters: 474744a7f3ddSMatthew G. Knepley + label - The label indicating the support of the field, or NULL for the entire mesh 474844a7f3ddSMatthew G. Knepley - field - The discretization object 4749c1929be8SMatthew G. Knepley 475044a7f3ddSMatthew G. Knepley Level: intermediate 4751c1929be8SMatthew G. Knepley 475244a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMSetField() 4753c1929be8SMatthew G. Knepley @*/ 475444a7f3ddSMatthew G. Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, DMLabel *label, PetscObject *field) 4755af122d2aSMatthew G Knepley { 4756af122d2aSMatthew G Knepley PetscFunctionBegin; 4757af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 475844a7f3ddSMatthew G. Knepley PetscValidPointer(field, 3); 475944a7f3ddSMatthew 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); 476044a7f3ddSMatthew G. Knepley if (label) *label = dm->fields[f].label; 476144a7f3ddSMatthew G. Knepley if (field) *field = dm->fields[f].disc; 4762decb47aaSMatthew G. Knepley PetscFunctionReturn(0); 4763decb47aaSMatthew G. Knepley } 4764decb47aaSMatthew G. Knepley 4765083401c6SMatthew G. Knepley /* Does not clear the DS */ 4766083401c6SMatthew G. Knepley PetscErrorCode DMSetField_Internal(DM dm, PetscInt f, DMLabel label, PetscObject field) 4767083401c6SMatthew G. Knepley { 4768083401c6SMatthew G. Knepley PetscErrorCode ierr; 4769083401c6SMatthew G. Knepley 4770083401c6SMatthew G. Knepley PetscFunctionBegin; 4771083401c6SMatthew G. Knepley ierr = DMFieldEnlarge_Static(dm, f+1);CHKERRQ(ierr); 4772083401c6SMatthew G. Knepley ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr); 4773083401c6SMatthew G. Knepley ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr); 4774083401c6SMatthew G. Knepley dm->fields[f].label = label; 4775083401c6SMatthew G. Knepley dm->fields[f].disc = field; 4776083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 4777083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr); 4778083401c6SMatthew G. Knepley PetscFunctionReturn(0); 4779083401c6SMatthew G. Knepley } 4780083401c6SMatthew G. Knepley 4781c1929be8SMatthew G. Knepley /*@ 4782c1929be8SMatthew G. Knepley DMSetField - Set the discretization object for a given DM field 4783c1929be8SMatthew G. Knepley 4784d083f849SBarry Smith Logically collective on dm 4785c1929be8SMatthew G. Knepley 4786c1929be8SMatthew G. Knepley Input Parameters: 4787c1929be8SMatthew G. Knepley + dm - The DM 4788c1929be8SMatthew G. Knepley . f - The field number 478944a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh 4790c1929be8SMatthew G. Knepley - field - The discretization object 4791c1929be8SMatthew G. Knepley 479244a7f3ddSMatthew G. Knepley Level: intermediate 4793c1929be8SMatthew G. Knepley 479444a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMGetField() 4795c1929be8SMatthew G. Knepley @*/ 479644a7f3ddSMatthew G. Knepley PetscErrorCode DMSetField(DM dm, PetscInt f, DMLabel label, PetscObject field) 4797decb47aaSMatthew G. Knepley { 4798decb47aaSMatthew G. Knepley PetscErrorCode ierr; 4799decb47aaSMatthew G. Knepley 4800decb47aaSMatthew G. Knepley PetscFunctionBegin; 4801decb47aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4802e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 480344a7f3ddSMatthew G. Knepley PetscValidHeader(field, 4); 4804e5e52638SMatthew G. Knepley if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 4805083401c6SMatthew G. Knepley ierr = DMSetField_Internal(dm, f, label, field);CHKERRQ(ierr); 480634aa8a36SMatthew G. Knepley ierr = DMSetDefaultAdjacency_Private(dm, f, field);CHKERRQ(ierr); 48072df9ee95SMatthew G. Knepley ierr = DMClearDS(dm);CHKERRQ(ierr); 480844a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 480944a7f3ddSMatthew G. Knepley } 481044a7f3ddSMatthew G. Knepley 481144a7f3ddSMatthew G. Knepley /*@ 481244a7f3ddSMatthew G. Knepley DMAddField - Add the discretization object for the given DM field 481344a7f3ddSMatthew G. Knepley 4814d083f849SBarry Smith Logically collective on dm 481544a7f3ddSMatthew G. Knepley 481644a7f3ddSMatthew G. Knepley Input Parameters: 481744a7f3ddSMatthew G. Knepley + dm - The DM 481844a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh 481944a7f3ddSMatthew G. Knepley - field - The discretization object 482044a7f3ddSMatthew G. Knepley 482144a7f3ddSMatthew G. Knepley Level: intermediate 482244a7f3ddSMatthew G. Knepley 482344a7f3ddSMatthew G. Knepley .seealso: DMSetField(), DMGetField() 482444a7f3ddSMatthew G. Knepley @*/ 482544a7f3ddSMatthew G. Knepley PetscErrorCode DMAddField(DM dm, DMLabel label, PetscObject field) 482644a7f3ddSMatthew G. Knepley { 482744a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf; 482844a7f3ddSMatthew G. Knepley PetscErrorCode ierr; 482944a7f3ddSMatthew G. Knepley 483044a7f3ddSMatthew G. Knepley PetscFunctionBegin; 483144a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 483244a7f3ddSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 483344a7f3ddSMatthew G. Knepley PetscValidHeader(field, 3); 483444a7f3ddSMatthew G. Knepley ierr = DMFieldEnlarge_Static(dm, Nf+1);CHKERRQ(ierr); 483544a7f3ddSMatthew G. Knepley dm->fields[Nf].label = label; 483644a7f3ddSMatthew G. Knepley dm->fields[Nf].disc = field; 483744a7f3ddSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 483844a7f3ddSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr); 483934aa8a36SMatthew G. Knepley ierr = DMSetDefaultAdjacency_Private(dm, Nf, field);CHKERRQ(ierr); 48402df9ee95SMatthew G. Knepley ierr = DMClearDS(dm);CHKERRQ(ierr); 4841af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4842af122d2aSMatthew G Knepley } 48436636e97aSMatthew G Knepley 4844e5e52638SMatthew G. Knepley /*@ 4845e0b68406SMatthew Knepley DMSetFieldAvoidTensor - Set flag to avoid defining the field on tensor cells 4846e0b68406SMatthew Knepley 4847e0b68406SMatthew Knepley Logically collective on dm 4848e0b68406SMatthew Knepley 4849e0b68406SMatthew Knepley Input Parameters: 4850e0b68406SMatthew Knepley + dm - The DM 4851e0b68406SMatthew Knepley . f - The field index 4852e0b68406SMatthew Knepley - avoidTensor - The flag to avoid defining the field on tensor cells 4853e0b68406SMatthew Knepley 4854e0b68406SMatthew Knepley Level: intermediate 4855e0b68406SMatthew Knepley 4856e0b68406SMatthew Knepley .seealso: DMGetFieldAvoidTensor(), DMSetField(), DMGetField() 4857e0b68406SMatthew Knepley @*/ 4858e0b68406SMatthew Knepley PetscErrorCode DMSetFieldAvoidTensor(DM dm, PetscInt f, PetscBool avoidTensor) 4859e0b68406SMatthew Knepley { 4860e0b68406SMatthew Knepley PetscFunctionBegin; 4861e0b68406SMatthew 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); 4862e0b68406SMatthew Knepley dm->fields[f].avoidTensor = avoidTensor; 4863e0b68406SMatthew Knepley PetscFunctionReturn(0); 4864e0b68406SMatthew Knepley } 4865e0b68406SMatthew Knepley 4866e0b68406SMatthew Knepley /*@ 4867e0b68406SMatthew Knepley DMGetFieldAvoidTensor - Get flag to avoid defining the field on tensor cells 4868e0b68406SMatthew Knepley 4869e0b68406SMatthew Knepley Logically collective on dm 4870e0b68406SMatthew Knepley 4871e0b68406SMatthew Knepley Input Parameters: 4872e0b68406SMatthew Knepley + dm - The DM 4873e0b68406SMatthew Knepley - f - The field index 4874e0b68406SMatthew Knepley 4875e0b68406SMatthew Knepley Output Parameter: 4876e0b68406SMatthew Knepley . avoidTensor - The flag to avoid defining the field on tensor cells 4877e0b68406SMatthew Knepley 4878e0b68406SMatthew Knepley Level: intermediate 4879e0b68406SMatthew Knepley 4880e0b68406SMatthew Knepley .seealso: DMSetFieldAvoidTensor(), DMSetField(), DMGetField() 4881e0b68406SMatthew Knepley @*/ 4882e0b68406SMatthew Knepley PetscErrorCode DMGetFieldAvoidTensor(DM dm, PetscInt f, PetscBool *avoidTensor) 4883e0b68406SMatthew Knepley { 4884e0b68406SMatthew Knepley PetscFunctionBegin; 4885e0b68406SMatthew 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); 4886e0b68406SMatthew Knepley *avoidTensor = dm->fields[f].avoidTensor; 4887e0b68406SMatthew Knepley PetscFunctionReturn(0); 4888e0b68406SMatthew Knepley } 4889e0b68406SMatthew Knepley 4890e0b68406SMatthew Knepley /*@ 4891e5e52638SMatthew G. Knepley DMCopyFields - Copy the discretizations for the DM into another DM 4892e5e52638SMatthew G. Knepley 4893d083f849SBarry Smith Collective on dm 4894e5e52638SMatthew G. Knepley 4895e5e52638SMatthew G. Knepley Input Parameter: 4896e5e52638SMatthew G. Knepley . dm - The DM 4897e5e52638SMatthew G. Knepley 4898e5e52638SMatthew G. Knepley Output Parameter: 4899e5e52638SMatthew G. Knepley . newdm - The DM 4900e5e52638SMatthew G. Knepley 4901e5e52638SMatthew G. Knepley Level: advanced 4902e5e52638SMatthew G. Knepley 4903e5e52638SMatthew G. Knepley .seealso: DMGetField(), DMSetField(), DMAddField(), DMCopyDS(), DMGetDS(), DMGetCellDS() 4904e5e52638SMatthew G. Knepley @*/ 4905e5e52638SMatthew G. Knepley PetscErrorCode DMCopyFields(DM dm, DM newdm) 4906e5e52638SMatthew G. Knepley { 4907e5e52638SMatthew G. Knepley PetscInt Nf, f; 4908e5e52638SMatthew G. Knepley PetscErrorCode ierr; 4909e5e52638SMatthew G. Knepley 4910e5e52638SMatthew G. Knepley PetscFunctionBegin; 4911e5e52638SMatthew G. Knepley if (dm == newdm) PetscFunctionReturn(0); 4912e5e52638SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 4913e5e52638SMatthew G. Knepley ierr = DMClearFields(newdm);CHKERRQ(ierr); 4914e5e52638SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 4915e5e52638SMatthew G. Knepley DMLabel label; 4916e5e52638SMatthew G. Knepley PetscObject field; 491734aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 4918e5e52638SMatthew G. Knepley 4919e5e52638SMatthew G. Knepley ierr = DMGetField(dm, f, &label, &field);CHKERRQ(ierr); 4920e5e52638SMatthew G. Knepley ierr = DMSetField(newdm, f, label, field);CHKERRQ(ierr); 492134aa8a36SMatthew G. Knepley ierr = DMGetAdjacency(dm, f, &useCone, &useClosure);CHKERRQ(ierr); 492234aa8a36SMatthew G. Knepley ierr = DMSetAdjacency(newdm, f, useCone, useClosure);CHKERRQ(ierr); 492334aa8a36SMatthew G. Knepley } 492434aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 492534aa8a36SMatthew G. Knepley } 492634aa8a36SMatthew G. Knepley 492734aa8a36SMatthew G. Knepley /*@ 492834aa8a36SMatthew G. Knepley DMGetAdjacency - Returns the flags for determining variable influence 492934aa8a36SMatthew G. Knepley 493034aa8a36SMatthew G. Knepley Not collective 493134aa8a36SMatthew G. Knepley 493234aa8a36SMatthew G. Knepley Input Parameters: 493334aa8a36SMatthew G. Knepley + dm - The DM object 493434aa8a36SMatthew G. Knepley - f - The field number, or PETSC_DEFAULT for the default adjacency 493534aa8a36SMatthew G. Knepley 493634aa8a36SMatthew G. Knepley Output Parameter: 493734aa8a36SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 493834aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 493934aa8a36SMatthew G. Knepley 494034aa8a36SMatthew G. Knepley Notes: 494134aa8a36SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 494234aa8a36SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 494334aa8a36SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 4944979e053dSMatthew G. Knepley Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 494534aa8a36SMatthew G. Knepley 494634aa8a36SMatthew G. Knepley Level: developer 494734aa8a36SMatthew G. Knepley 494834aa8a36SMatthew G. Knepley .seealso: DMSetAdjacency(), DMGetField(), DMSetField() 494934aa8a36SMatthew G. Knepley @*/ 495034aa8a36SMatthew G. Knepley PetscErrorCode DMGetAdjacency(DM dm, PetscInt f, PetscBool *useCone, PetscBool *useClosure) 495134aa8a36SMatthew G. Knepley { 495234aa8a36SMatthew G. Knepley PetscFunctionBegin; 495334aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4954534a8f05SLisandro Dalcin if (useCone) PetscValidBoolPointer(useCone, 3); 4955534a8f05SLisandro Dalcin if (useClosure) PetscValidBoolPointer(useClosure, 4); 495634aa8a36SMatthew G. Knepley if (f < 0) { 495734aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->adjacency[0]; 495834aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->adjacency[1]; 495934aa8a36SMatthew G. Knepley } else { 496034aa8a36SMatthew G. Knepley PetscInt Nf; 496134aa8a36SMatthew G. Knepley PetscErrorCode ierr; 496234aa8a36SMatthew G. Knepley 496334aa8a36SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 496434aa8a36SMatthew G. Knepley if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf); 496534aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->fields[f].adjacency[0]; 496634aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->fields[f].adjacency[1]; 496734aa8a36SMatthew G. Knepley } 496834aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 496934aa8a36SMatthew G. Knepley } 497034aa8a36SMatthew G. Knepley 497134aa8a36SMatthew G. Knepley /*@ 497234aa8a36SMatthew G. Knepley DMSetAdjacency - Set the flags for determining variable influence 497334aa8a36SMatthew G. Knepley 497434aa8a36SMatthew G. Knepley Not collective 497534aa8a36SMatthew G. Knepley 497634aa8a36SMatthew G. Knepley Input Parameters: 497734aa8a36SMatthew G. Knepley + dm - The DM object 497834aa8a36SMatthew G. Knepley . f - The field number 497934aa8a36SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 498034aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 498134aa8a36SMatthew G. Knepley 498234aa8a36SMatthew G. Knepley Notes: 498334aa8a36SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 498434aa8a36SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 498534aa8a36SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 4986979e053dSMatthew G. Knepley Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 498734aa8a36SMatthew G. Knepley 498834aa8a36SMatthew G. Knepley Level: developer 498934aa8a36SMatthew G. Knepley 499034aa8a36SMatthew G. Knepley .seealso: DMGetAdjacency(), DMGetField(), DMSetField() 499134aa8a36SMatthew G. Knepley @*/ 499234aa8a36SMatthew G. Knepley PetscErrorCode DMSetAdjacency(DM dm, PetscInt f, PetscBool useCone, PetscBool useClosure) 499334aa8a36SMatthew G. Knepley { 499434aa8a36SMatthew G. Knepley PetscFunctionBegin; 499534aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 499634aa8a36SMatthew G. Knepley if (f < 0) { 499734aa8a36SMatthew G. Knepley dm->adjacency[0] = useCone; 499834aa8a36SMatthew G. Knepley dm->adjacency[1] = useClosure; 499934aa8a36SMatthew G. Knepley } else { 500034aa8a36SMatthew G. Knepley PetscInt Nf; 500134aa8a36SMatthew G. Knepley PetscErrorCode ierr; 500234aa8a36SMatthew G. Knepley 500334aa8a36SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 500434aa8a36SMatthew G. Knepley if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf); 500534aa8a36SMatthew G. Knepley dm->fields[f].adjacency[0] = useCone; 500634aa8a36SMatthew G. Knepley dm->fields[f].adjacency[1] = useClosure; 5007e5e52638SMatthew G. Knepley } 5008e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5009e5e52638SMatthew G. Knepley } 5010e5e52638SMatthew G. Knepley 5011b0441da4SMatthew G. Knepley /*@ 5012b0441da4SMatthew G. Knepley DMGetBasicAdjacency - Returns the flags for determining variable influence, using either the default or field 0 if it is defined 5013b0441da4SMatthew G. Knepley 5014b0441da4SMatthew G. Knepley Not collective 5015b0441da4SMatthew G. Knepley 5016b0441da4SMatthew G. Knepley Input Parameters: 5017b0441da4SMatthew G. Knepley . dm - The DM object 5018b0441da4SMatthew G. Knepley 5019b0441da4SMatthew G. Knepley Output Parameter: 5020b0441da4SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 5021b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5022b0441da4SMatthew G. Knepley 5023b0441da4SMatthew G. Knepley Notes: 5024b0441da4SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 5025b0441da4SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 5026b0441da4SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5027b0441da4SMatthew G. Knepley 5028b0441da4SMatthew G. Knepley Level: developer 5029b0441da4SMatthew G. Knepley 5030b0441da4SMatthew G. Knepley .seealso: DMSetBasicAdjacency(), DMGetField(), DMSetField() 5031b0441da4SMatthew G. Knepley @*/ 5032b0441da4SMatthew G. Knepley PetscErrorCode DMGetBasicAdjacency(DM dm, PetscBool *useCone, PetscBool *useClosure) 5033b0441da4SMatthew G. Knepley { 5034b0441da4SMatthew G. Knepley PetscInt Nf; 5035b0441da4SMatthew G. Knepley PetscErrorCode ierr; 5036b0441da4SMatthew G. Knepley 5037b0441da4SMatthew G. Knepley PetscFunctionBegin; 5038b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5039534a8f05SLisandro Dalcin if (useCone) PetscValidBoolPointer(useCone, 3); 5040534a8f05SLisandro Dalcin if (useClosure) PetscValidBoolPointer(useClosure, 4); 5041b0441da4SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 5042b0441da4SMatthew G. Knepley if (!Nf) { 5043b0441da4SMatthew G. Knepley ierr = DMGetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr); 5044b0441da4SMatthew G. Knepley } else { 5045b0441da4SMatthew G. Knepley ierr = DMGetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr); 5046b0441da4SMatthew G. Knepley } 5047b0441da4SMatthew G. Knepley PetscFunctionReturn(0); 5048b0441da4SMatthew G. Knepley } 5049b0441da4SMatthew G. Knepley 5050b0441da4SMatthew G. Knepley /*@ 5051b0441da4SMatthew G. Knepley DMSetBasicAdjacency - Set the flags for determining variable influence, using either the default or field 0 if it is defined 5052b0441da4SMatthew G. Knepley 5053b0441da4SMatthew G. Knepley Not collective 5054b0441da4SMatthew G. Knepley 5055b0441da4SMatthew G. Knepley Input Parameters: 5056b0441da4SMatthew G. Knepley + dm - The DM object 5057b0441da4SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 5058b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5059b0441da4SMatthew G. Knepley 5060b0441da4SMatthew G. Knepley Notes: 5061b0441da4SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 5062b0441da4SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 5063b0441da4SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5064b0441da4SMatthew G. Knepley 5065b0441da4SMatthew G. Knepley Level: developer 5066b0441da4SMatthew G. Knepley 5067b0441da4SMatthew G. Knepley .seealso: DMGetBasicAdjacency(), DMGetField(), DMSetField() 5068b0441da4SMatthew G. Knepley @*/ 5069b0441da4SMatthew G. Knepley PetscErrorCode DMSetBasicAdjacency(DM dm, PetscBool useCone, PetscBool useClosure) 5070b0441da4SMatthew G. Knepley { 5071b0441da4SMatthew G. Knepley PetscInt Nf; 5072b0441da4SMatthew G. Knepley PetscErrorCode ierr; 5073b0441da4SMatthew G. Knepley 5074b0441da4SMatthew G. Knepley PetscFunctionBegin; 5075b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5076b0441da4SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 5077b0441da4SMatthew G. Knepley if (!Nf) { 5078b0441da4SMatthew G. Knepley ierr = DMSetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr); 5079b0441da4SMatthew G. Knepley } else { 5080b0441da4SMatthew G. Knepley ierr = DMSetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr); 5081e5e52638SMatthew G. Knepley } 5082e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5083e5e52638SMatthew G. Knepley } 5084e5e52638SMatthew G. Knepley 5085783e2ec8SMatthew G. Knepley /* Complete labels that are being used for FEM BC */ 5086783e2ec8SMatthew G. Knepley static PetscErrorCode DMCompleteBoundaryLabel_Internal(DM dm, PetscDS ds, PetscInt field, PetscInt bdNum, const char labelname[]) 5087783e2ec8SMatthew G. Knepley { 5088783e2ec8SMatthew G. Knepley DMLabel label; 5089783e2ec8SMatthew G. Knepley PetscObject obj; 5090783e2ec8SMatthew G. Knepley PetscClassId id; 5091783e2ec8SMatthew G. Knepley PetscInt Nbd, bd; 5092783e2ec8SMatthew G. Knepley PetscBool isFE = PETSC_FALSE; 5093783e2ec8SMatthew G. Knepley PetscBool duplicate = PETSC_FALSE; 5094783e2ec8SMatthew G. Knepley PetscErrorCode ierr; 5095783e2ec8SMatthew G. Knepley 5096783e2ec8SMatthew G. Knepley PetscFunctionBegin; 5097783e2ec8SMatthew G. Knepley ierr = DMGetField(dm, field, NULL, &obj);CHKERRQ(ierr); 5098783e2ec8SMatthew G. Knepley ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 5099783e2ec8SMatthew G. Knepley if (id == PETSCFE_CLASSID) isFE = PETSC_TRUE; 5100783e2ec8SMatthew G. Knepley ierr = DMGetLabel(dm, labelname, &label);CHKERRQ(ierr); 5101783e2ec8SMatthew G. Knepley if (isFE && label) { 5102783e2ec8SMatthew G. Knepley /* Only want to modify label once */ 5103783e2ec8SMatthew G. Knepley ierr = PetscDSGetNumBoundary(ds, &Nbd);CHKERRQ(ierr); 5104783e2ec8SMatthew G. Knepley for (bd = 0; bd < PetscMin(Nbd, bdNum); ++bd) { 5105783e2ec8SMatthew G. Knepley const char *lname; 5106783e2ec8SMatthew G. Knepley 510756cf3b9cSMatthew G. Knepley ierr = PetscDSGetBoundary(ds, bd, NULL, NULL, &lname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 5108783e2ec8SMatthew G. Knepley ierr = PetscStrcmp(lname, labelname, &duplicate);CHKERRQ(ierr); 5109783e2ec8SMatthew G. Knepley if (duplicate) break; 5110783e2ec8SMatthew G. Knepley } 5111783e2ec8SMatthew G. Knepley if (!duplicate) { 5112783e2ec8SMatthew G. Knepley DM plex; 5113783e2ec8SMatthew G. Knepley 5114783e2ec8SMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 5115783e2ec8SMatthew G. Knepley if (plex) {ierr = DMPlexLabelComplete(plex, label);CHKERRQ(ierr);} 5116783e2ec8SMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 5117783e2ec8SMatthew G. Knepley } 5118783e2ec8SMatthew G. Knepley } 5119783e2ec8SMatthew G. Knepley PetscFunctionReturn(0); 5120783e2ec8SMatthew G. Knepley } 5121783e2ec8SMatthew G. Knepley 5122e5e52638SMatthew G. Knepley static PetscErrorCode DMDSEnlarge_Static(DM dm, PetscInt NdsNew) 5123e5e52638SMatthew G. Knepley { 5124e5e52638SMatthew G. Knepley DMSpace *tmpd; 5125e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5126e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5127e5e52638SMatthew G. Knepley 5128e5e52638SMatthew G. Knepley PetscFunctionBegin; 5129e5e52638SMatthew G. Knepley if (Nds >= NdsNew) PetscFunctionReturn(0); 5130e5e52638SMatthew G. Knepley ierr = PetscMalloc1(NdsNew, &tmpd);CHKERRQ(ierr); 5131e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) tmpd[s] = dm->probs[s]; 5132b3cf3223SMatthew G. Knepley for (s = Nds; s < NdsNew; ++s) {tmpd[s].ds = NULL; tmpd[s].label = NULL; tmpd[s].fields = NULL;} 5133e5e52638SMatthew G. Knepley ierr = PetscFree(dm->probs);CHKERRQ(ierr); 5134e5e52638SMatthew G. Knepley dm->Nds = NdsNew; 5135e5e52638SMatthew G. Knepley dm->probs = tmpd; 5136e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5137e5e52638SMatthew G. Knepley } 5138e5e52638SMatthew G. Knepley 5139e5e52638SMatthew G. Knepley /*@ 5140e5e52638SMatthew G. Knepley DMGetNumDS - Get the number of discrete systems in the DM 5141e5e52638SMatthew G. Knepley 5142e5e52638SMatthew G. Knepley Not collective 5143e5e52638SMatthew G. Knepley 5144e5e52638SMatthew G. Knepley Input Parameter: 5145e5e52638SMatthew G. Knepley . dm - The DM 5146e5e52638SMatthew G. Knepley 5147e5e52638SMatthew G. Knepley Output Parameter: 5148e5e52638SMatthew G. Knepley . Nds - The number of PetscDS objects 5149e5e52638SMatthew G. Knepley 5150e5e52638SMatthew G. Knepley Level: intermediate 5151e5e52638SMatthew G. Knepley 5152e5e52638SMatthew G. Knepley .seealso: DMGetDS(), DMGetCellDS() 5153e5e52638SMatthew G. Knepley @*/ 5154e5e52638SMatthew G. Knepley PetscErrorCode DMGetNumDS(DM dm, PetscInt *Nds) 5155e5e52638SMatthew G. Knepley { 5156e5e52638SMatthew G. Knepley PetscFunctionBegin; 5157e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5158534a8f05SLisandro Dalcin PetscValidIntPointer(Nds, 2); 5159e5e52638SMatthew G. Knepley *Nds = dm->Nds; 5160e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5161e5e52638SMatthew G. Knepley } 5162e5e52638SMatthew G. Knepley 5163e5e52638SMatthew G. Knepley /*@ 5164e5e52638SMatthew G. Knepley DMClearDS - Remove all discrete systems from the DM 5165e5e52638SMatthew G. Knepley 5166d083f849SBarry Smith Logically collective on dm 5167e5e52638SMatthew G. Knepley 5168e5e52638SMatthew G. Knepley Input Parameter: 5169e5e52638SMatthew G. Knepley . dm - The DM 5170e5e52638SMatthew G. Knepley 5171e5e52638SMatthew G. Knepley Level: intermediate 5172e5e52638SMatthew G. Knepley 5173e5e52638SMatthew G. Knepley .seealso: DMGetNumDS(), DMGetDS(), DMSetField() 5174e5e52638SMatthew G. Knepley @*/ 5175e5e52638SMatthew G. Knepley PetscErrorCode DMClearDS(DM dm) 5176e5e52638SMatthew G. Knepley { 5177e5e52638SMatthew G. Knepley PetscInt s; 5178e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5179e5e52638SMatthew G. Knepley 5180e5e52638SMatthew G. Knepley PetscFunctionBegin; 5181e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5182e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5183e5e52638SMatthew G. Knepley ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr); 5184e5e52638SMatthew G. Knepley ierr = DMLabelDestroy(&dm->probs[s].label);CHKERRQ(ierr); 5185b3cf3223SMatthew G. Knepley ierr = ISDestroy(&dm->probs[s].fields);CHKERRQ(ierr); 5186e5e52638SMatthew G. Knepley } 5187e5e52638SMatthew G. Knepley ierr = PetscFree(dm->probs);CHKERRQ(ierr); 5188e5e52638SMatthew G. Knepley dm->probs = NULL; 5189e5e52638SMatthew G. Knepley dm->Nds = 0; 5190e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5191e5e52638SMatthew G. Knepley } 5192e5e52638SMatthew G. Knepley 5193e5e52638SMatthew G. Knepley /*@ 5194e5e52638SMatthew G. Knepley DMGetDS - Get the default PetscDS 5195e5e52638SMatthew G. Knepley 5196e5e52638SMatthew G. Knepley Not collective 5197e5e52638SMatthew G. Knepley 5198e5e52638SMatthew G. Knepley Input Parameter: 5199e5e52638SMatthew G. Knepley . dm - The DM 5200e5e52638SMatthew G. Knepley 5201e5e52638SMatthew G. Knepley Output Parameter: 5202e5e52638SMatthew G. Knepley . prob - The default PetscDS 5203e5e52638SMatthew G. Knepley 5204e5e52638SMatthew G. Knepley Level: intermediate 5205e5e52638SMatthew G. Knepley 5206e5e52638SMatthew G. Knepley .seealso: DMGetCellDS(), DMGetRegionDS() 5207e5e52638SMatthew G. Knepley @*/ 5208e5e52638SMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *prob) 5209e5e52638SMatthew G. Knepley { 5210b0143b4dSMatthew G. Knepley PetscErrorCode ierr; 5211b0143b4dSMatthew G. Knepley 5212e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5213e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5214e5e52638SMatthew G. Knepley PetscValidPointer(prob, 2); 5215b0143b4dSMatthew G. Knepley if (dm->Nds <= 0) { 5216b0143b4dSMatthew G. Knepley PetscDS ds; 5217b0143b4dSMatthew G. Knepley 5218b0143b4dSMatthew G. Knepley ierr = PetscDSCreate(PetscObjectComm((PetscObject) dm), &ds);CHKERRQ(ierr); 5219b3cf3223SMatthew G. Knepley ierr = DMSetRegionDS(dm, NULL, NULL, ds);CHKERRQ(ierr); 5220b0143b4dSMatthew G. Knepley ierr = PetscDSDestroy(&ds);CHKERRQ(ierr); 5221b0143b4dSMatthew G. Knepley } 5222b0143b4dSMatthew G. Knepley *prob = dm->probs[0].ds; 5223e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5224e5e52638SMatthew G. Knepley } 5225e5e52638SMatthew G. Knepley 5226e5e52638SMatthew G. Knepley /*@ 5227e5e52638SMatthew G. Knepley DMGetCellDS - Get the PetscDS defined on a given cell 5228e5e52638SMatthew G. Knepley 5229e5e52638SMatthew G. Knepley Not collective 5230e5e52638SMatthew G. Knepley 5231e5e52638SMatthew G. Knepley Input Parameters: 5232e5e52638SMatthew G. Knepley + dm - The DM 5233e5e52638SMatthew G. Knepley - point - Cell for the DS 5234e5e52638SMatthew G. Knepley 5235e5e52638SMatthew G. Knepley Output Parameter: 5236e5e52638SMatthew G. Knepley . prob - The PetscDS defined on the given cell 5237e5e52638SMatthew G. Knepley 5238e5e52638SMatthew G. Knepley Level: developer 5239e5e52638SMatthew G. Knepley 5240b0143b4dSMatthew G. Knepley .seealso: DMGetDS(), DMSetRegionDS() 5241e5e52638SMatthew G. Knepley @*/ 5242e5e52638SMatthew G. Knepley PetscErrorCode DMGetCellDS(DM dm, PetscInt point, PetscDS *prob) 5243e5e52638SMatthew G. Knepley { 5244e5e52638SMatthew G. Knepley PetscDS probDef = NULL; 5245e5e52638SMatthew G. Knepley PetscInt s; 5246e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5247e5e52638SMatthew G. Knepley 5248e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5249e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5250e5e52638SMatthew G. Knepley PetscValidPointer(prob, 3); 5251360cf244SMatthew G. Knepley if (point < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Mesh point cannot be negative: %D", point); 5252e5e52638SMatthew G. Knepley *prob = NULL; 5253e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5254e5e52638SMatthew G. Knepley PetscInt val; 5255e5e52638SMatthew G. Knepley 5256e5e52638SMatthew G. Knepley if (!dm->probs[s].label) {probDef = dm->probs[s].ds;} 5257e5e52638SMatthew G. Knepley else { 5258e5e52638SMatthew G. Knepley ierr = DMLabelGetValue(dm->probs[s].label, point, &val);CHKERRQ(ierr); 5259e5e52638SMatthew G. Knepley if (val >= 0) {*prob = dm->probs[s].ds; break;} 5260e5e52638SMatthew G. Knepley } 5261e5e52638SMatthew G. Knepley } 5262e5e52638SMatthew G. Knepley if (!*prob) *prob = probDef; 5263e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5264e5e52638SMatthew G. Knepley } 5265e5e52638SMatthew G. Knepley 5266e5e52638SMatthew G. Knepley /*@ 5267e5e52638SMatthew G. Knepley DMGetRegionDS - Get the PetscDS for a given mesh region, defined by a DMLabel 5268e5e52638SMatthew G. Knepley 5269e5e52638SMatthew G. Knepley Not collective 5270e5e52638SMatthew G. Knepley 5271e5e52638SMatthew G. Knepley Input Parameters: 5272e5e52638SMatthew G. Knepley + dm - The DM 5273e5e52638SMatthew G. Knepley - label - The DMLabel defining the mesh region, or NULL for the entire mesh 5274e5e52638SMatthew G. Knepley 5275b3cf3223SMatthew G. Knepley Output Parameters: 5276b3cf3223SMatthew G. Knepley + fields - The IS containing the DM field numbers for the fields in this DS, or NULL 5277b3cf3223SMatthew G. Knepley - prob - The PetscDS defined on the given region, or NULL 5278e5e52638SMatthew G. Knepley 5279e5e52638SMatthew G. Knepley Note: If the label is missing, this function returns an error 5280e5e52638SMatthew G. Knepley 5281e5e52638SMatthew G. Knepley Level: advanced 5282e5e52638SMatthew G. Knepley 5283e5e52638SMatthew G. Knepley .seealso: DMGetRegionNumDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS() 5284e5e52638SMatthew G. Knepley @*/ 5285b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionDS(DM dm, DMLabel label, IS *fields, PetscDS *ds) 5286e5e52638SMatthew G. Knepley { 5287e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5288e5e52638SMatthew G. Knepley 5289e5e52638SMatthew G. Knepley PetscFunctionBegin; 5290e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5291e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5292b3cf3223SMatthew G. Knepley if (fields) {PetscValidPointer(fields, 3); *fields = NULL;} 5293b3cf3223SMatthew G. Knepley if (ds) {PetscValidPointer(ds, 4); *ds = NULL;} 5294e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5295b3cf3223SMatthew G. Knepley if (dm->probs[s].label == label) { 5296b3cf3223SMatthew G. Knepley if (fields) *fields = dm->probs[s].fields; 5297b3cf3223SMatthew G. Knepley if (ds) *ds = dm->probs[s].ds; 5298b3cf3223SMatthew G. Knepley PetscFunctionReturn(0); 5299b3cf3223SMatthew G. Knepley } 5300e5e52638SMatthew G. Knepley } 53012df9ee95SMatthew G. Knepley PetscFunctionReturn(0); 5302e5e52638SMatthew G. Knepley } 5303e5e52638SMatthew G. Knepley 5304e5e52638SMatthew G. Knepley /*@ 5305083401c6SMatthew G. Knepley DMSetRegionDS - Set the PetscDS for a given mesh region, defined by a DMLabel 5306083401c6SMatthew G. Knepley 5307083401c6SMatthew G. Knepley Collective on dm 5308083401c6SMatthew G. Knepley 5309083401c6SMatthew G. Knepley Input Parameters: 5310083401c6SMatthew G. Knepley + dm - The DM 5311083401c6SMatthew G. Knepley . label - The DMLabel defining the mesh region, or NULL for the entire mesh 5312083401c6SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL for all fields 5313083401c6SMatthew G. Knepley - prob - The PetscDS defined on the given cell 5314083401c6SMatthew G. Knepley 5315083401c6SMatthew 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, 5316083401c6SMatthew G. Knepley the fields argument is ignored. 5317083401c6SMatthew G. Knepley 5318083401c6SMatthew G. Knepley Level: advanced 5319083401c6SMatthew G. Knepley 5320083401c6SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionNumDS(), DMGetDS(), DMGetCellDS() 5321083401c6SMatthew G. Knepley @*/ 5322083401c6SMatthew G. Knepley PetscErrorCode DMSetRegionDS(DM dm, DMLabel label, IS fields, PetscDS ds) 5323083401c6SMatthew G. Knepley { 5324083401c6SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5325083401c6SMatthew G. Knepley PetscErrorCode ierr; 5326083401c6SMatthew G. Knepley 5327083401c6SMatthew G. Knepley PetscFunctionBegin; 5328083401c6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5329083401c6SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5330083401c6SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 3); 5331083401c6SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5332083401c6SMatthew G. Knepley if (dm->probs[s].label == label) { 5333083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr); 5334083401c6SMatthew G. Knepley dm->probs[s].ds = ds; 5335083401c6SMatthew G. Knepley PetscFunctionReturn(0); 5336083401c6SMatthew G. Knepley } 5337083401c6SMatthew G. Knepley } 5338083401c6SMatthew G. Knepley ierr = DMDSEnlarge_Static(dm, Nds+1);CHKERRQ(ierr); 5339083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 5340083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) fields);CHKERRQ(ierr); 5341083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) ds);CHKERRQ(ierr); 5342083401c6SMatthew G. Knepley if (!label) { 5343083401c6SMatthew G. Knepley /* Put the NULL label at the front, so it is returned as the default */ 5344083401c6SMatthew G. Knepley for (s = Nds-1; s >=0; --s) dm->probs[s+1] = dm->probs[s]; 5345083401c6SMatthew G. Knepley Nds = 0; 5346083401c6SMatthew G. Knepley } 5347083401c6SMatthew G. Knepley dm->probs[Nds].label = label; 5348083401c6SMatthew G. Knepley dm->probs[Nds].fields = fields; 5349083401c6SMatthew G. Knepley dm->probs[Nds].ds = ds; 5350083401c6SMatthew G. Knepley PetscFunctionReturn(0); 5351083401c6SMatthew G. Knepley } 5352083401c6SMatthew G. Knepley 5353083401c6SMatthew G. Knepley /*@ 5354e5e52638SMatthew G. Knepley DMGetRegionNumDS - Get the PetscDS for a given mesh region, defined by the region number 5355e5e52638SMatthew G. Knepley 5356e5e52638SMatthew G. Knepley Not collective 5357e5e52638SMatthew G. Knepley 5358e5e52638SMatthew G. Knepley Input Parameters: 5359e5e52638SMatthew G. Knepley + dm - The DM 5360e5e52638SMatthew G. Knepley - num - The region number, in [0, Nds) 5361e5e52638SMatthew G. Knepley 5362e5e52638SMatthew G. Knepley Output Parameters: 5363b3cf3223SMatthew G. Knepley + label - The region label, or NULL 5364b3cf3223SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL 5365083401c6SMatthew G. Knepley - ds - The PetscDS defined on the given region, or NULL 5366e5e52638SMatthew G. Knepley 5367e5e52638SMatthew G. Knepley Level: advanced 5368e5e52638SMatthew G. Knepley 5369e5e52638SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS() 5370e5e52638SMatthew G. Knepley @*/ 5371b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionNumDS(DM dm, PetscInt num, DMLabel *label, IS *fields, PetscDS *ds) 5372e5e52638SMatthew G. Knepley { 5373e5e52638SMatthew G. Knepley PetscInt Nds; 5374e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5375e5e52638SMatthew G. Knepley 5376e5e52638SMatthew G. Knepley PetscFunctionBegin; 5377e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5378e5e52638SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 5379e5e52638SMatthew 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); 5380e5e52638SMatthew G. Knepley if (label) { 5381e5e52638SMatthew G. Knepley PetscValidPointer(label, 3); 5382e5e52638SMatthew G. Knepley *label = dm->probs[num].label; 5383e5e52638SMatthew G. Knepley } 5384b3cf3223SMatthew G. Knepley if (fields) { 5385b3cf3223SMatthew G. Knepley PetscValidPointer(fields, 4); 5386b3cf3223SMatthew G. Knepley *fields = dm->probs[num].fields; 5387b3cf3223SMatthew G. Knepley } 5388e5e52638SMatthew G. Knepley if (ds) { 5389b3cf3223SMatthew G. Knepley PetscValidPointer(ds, 5); 5390e5e52638SMatthew G. Knepley *ds = dm->probs[num].ds; 5391e5e52638SMatthew G. Knepley } 5392e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5393e5e52638SMatthew G. Knepley } 5394e5e52638SMatthew G. Knepley 5395e5e52638SMatthew G. Knepley /*@ 5396083401c6SMatthew G. Knepley DMSetRegionNumDS - Set the PetscDS for a given mesh region, defined by the region number 5397e5e52638SMatthew G. Knepley 5398083401c6SMatthew G. Knepley Not collective 5399e5e52638SMatthew G. Knepley 5400e5e52638SMatthew G. Knepley Input Parameters: 5401e5e52638SMatthew G. Knepley + dm - The DM 5402083401c6SMatthew G. Knepley . num - The region number, in [0, Nds) 5403083401c6SMatthew G. Knepley . label - The region label, or NULL 5404083401c6SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL to prevent setting 5405083401c6SMatthew G. Knepley - ds - The PetscDS defined on the given region, or NULL to prevent setting 5406e5e52638SMatthew G. Knepley 5407e5e52638SMatthew G. Knepley Level: advanced 5408e5e52638SMatthew G. Knepley 5409083401c6SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS() 5410e5e52638SMatthew G. Knepley @*/ 5411083401c6SMatthew G. Knepley PetscErrorCode DMSetRegionNumDS(DM dm, PetscInt num, DMLabel label, IS fields, PetscDS ds) 5412e5e52638SMatthew G. Knepley { 5413083401c6SMatthew G. Knepley PetscInt Nds; 5414e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5415e5e52638SMatthew G. Knepley 5416e5e52638SMatthew G. Knepley PetscFunctionBegin; 5417e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5418083401c6SMatthew G. Knepley if (label) {PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3);} 5419083401c6SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 5420083401c6SMatthew 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); 5421e5e52638SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 5422083401c6SMatthew G. Knepley ierr = DMLabelDestroy(&dm->probs[num].label);CHKERRQ(ierr); 5423083401c6SMatthew G. Knepley dm->probs[num].label = label; 5424083401c6SMatthew G. Knepley if (fields) { 5425083401c6SMatthew G. Knepley PetscValidHeaderSpecific(fields, IS_CLASSID, 4); 5426b3cf3223SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) fields);CHKERRQ(ierr); 5427083401c6SMatthew G. Knepley ierr = ISDestroy(&dm->probs[num].fields);CHKERRQ(ierr); 5428083401c6SMatthew G. Knepley dm->probs[num].fields = fields; 5429e5e52638SMatthew G. Knepley } 5430083401c6SMatthew G. Knepley if (ds) { 5431083401c6SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 5); 5432083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) ds);CHKERRQ(ierr); 5433083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&dm->probs[num].ds);CHKERRQ(ierr); 5434083401c6SMatthew G. Knepley dm->probs[num].ds = ds; 5435083401c6SMatthew G. Knepley } 5436e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5437e5e52638SMatthew G. Knepley } 5438e5e52638SMatthew G. Knepley 5439e5e52638SMatthew G. Knepley /*@ 54401d3af9e0SMatthew G. Knepley DMFindRegionNum - Find the region number for a given PetscDS, or -1 if it is not found. 54411d3af9e0SMatthew G. Knepley 54421d3af9e0SMatthew G. Knepley Not collective 54431d3af9e0SMatthew G. Knepley 54441d3af9e0SMatthew G. Knepley Input Parameters: 54451d3af9e0SMatthew G. Knepley + dm - The DM 54461d3af9e0SMatthew G. Knepley - ds - The PetscDS defined on the given region 54471d3af9e0SMatthew G. Knepley 54481d3af9e0SMatthew G. Knepley Output Parameter: 54491d3af9e0SMatthew G. Knepley . num - The region number, in [0, Nds), or -1 if not found 54501d3af9e0SMatthew G. Knepley 54511d3af9e0SMatthew G. Knepley Level: advanced 54521d3af9e0SMatthew G. Knepley 54531d3af9e0SMatthew G. Knepley .seealso: DMGetRegionNumDS(), DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS() 54541d3af9e0SMatthew G. Knepley @*/ 54551d3af9e0SMatthew G. Knepley PetscErrorCode DMFindRegionNum(DM dm, PetscDS ds, PetscInt *num) 54561d3af9e0SMatthew G. Knepley { 54571d3af9e0SMatthew G. Knepley PetscInt Nds, n; 54581d3af9e0SMatthew G. Knepley PetscErrorCode ierr; 54591d3af9e0SMatthew G. Knepley 54601d3af9e0SMatthew G. Knepley PetscFunctionBegin; 54611d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 54621d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 2); 54631d3af9e0SMatthew G. Knepley PetscValidPointer(num, 3); 54641d3af9e0SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 54651d3af9e0SMatthew G. Knepley for (n = 0; n < Nds; ++n) if (ds == dm->probs[n].ds) break; 54661d3af9e0SMatthew G. Knepley if (n >= Nds) *num = -1; 54671d3af9e0SMatthew G. Knepley else *num = n; 54681d3af9e0SMatthew G. Knepley PetscFunctionReturn(0); 54691d3af9e0SMatthew G. Knepley } 54701d3af9e0SMatthew G. Knepley 54711d3af9e0SMatthew G. Knepley /*@ 5472e5e52638SMatthew G. Knepley DMCreateDS - Create the discrete systems for the DM based upon the fields added to the DM 5473e5e52638SMatthew G. Knepley 5474d083f849SBarry Smith Collective on dm 5475e5e52638SMatthew G. Knepley 5476e5e52638SMatthew G. Knepley Input Parameter: 5477e5e52638SMatthew G. Knepley . dm - The DM 5478e5e52638SMatthew G. Knepley 5479e5e52638SMatthew G. Knepley Note: If the label has a DS defined, it will be replaced. Otherwise, it will be added to the DM. 5480e5e52638SMatthew G. Knepley 5481e5e52638SMatthew G. Knepley Level: intermediate 5482e5e52638SMatthew G. Knepley 5483e5e52638SMatthew G. Knepley .seealso: DMSetField, DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS() 5484e5e52638SMatthew G. Knepley @*/ 5485e5e52638SMatthew G. Knepley PetscErrorCode DMCreateDS(DM dm) 5486e5e52638SMatthew G. Knepley { 5487e5e52638SMatthew G. Knepley MPI_Comm comm; 5488083401c6SMatthew G. Knepley PetscDS dsDef; 5489083401c6SMatthew G. Knepley DMLabel *labelSet; 5490f9244615SMatthew G. Knepley PetscInt dE, Nf = dm->Nf, f, s, Nl, l, Ndef, k; 5491f9244615SMatthew G. Knepley PetscBool doSetup = PETSC_TRUE, flg; 5492e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5493e5e52638SMatthew G. Knepley 5494e5e52638SMatthew G. Knepley PetscFunctionBegin; 5495e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5496e5e52638SMatthew G. Knepley if (!dm->fields) PetscFunctionReturn(0); 5497e5e52638SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 5498083401c6SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 5499083401c6SMatthew G. Knepley /* Determine how many regions we have */ 5500083401c6SMatthew G. Knepley ierr = PetscMalloc1(Nf, &labelSet);CHKERRQ(ierr); 5501083401c6SMatthew G. Knepley Nl = 0; 5502083401c6SMatthew G. Knepley Ndef = 0; 5503083401c6SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5504083401c6SMatthew G. Knepley DMLabel label = dm->fields[f].label; 5505083401c6SMatthew G. Knepley PetscInt l; 5506083401c6SMatthew G. Knepley 5507083401c6SMatthew G. Knepley if (!label) {++Ndef; continue;} 5508083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) if (label == labelSet[l]) break; 5509083401c6SMatthew G. Knepley if (l < Nl) continue; 5510083401c6SMatthew G. Knepley labelSet[Nl++] = label; 5511083401c6SMatthew G. Knepley } 5512083401c6SMatthew G. Knepley /* Create default DS if there are no labels to intersect with */ 5513083401c6SMatthew G. Knepley ierr = DMGetRegionDS(dm, NULL, NULL, &dsDef);CHKERRQ(ierr); 5514083401c6SMatthew G. Knepley if (!dsDef && Ndef && !Nl) { 5515b3cf3223SMatthew G. Knepley IS fields; 5516b3cf3223SMatthew G. Knepley PetscInt *fld, nf; 5517b3cf3223SMatthew G. Knepley 5518b3cf3223SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) ++nf; 5519083401c6SMatthew G. Knepley if (nf) { 5520b3cf3223SMatthew G. Knepley ierr = PetscMalloc1(nf, &fld);CHKERRQ(ierr); 5521b3cf3223SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) fld[nf++] = f; 552288f0c812SMatthew G. Knepley ierr = ISCreate(PETSC_COMM_SELF, &fields);CHKERRQ(ierr); 552388f0c812SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_");CHKERRQ(ierr); 552488f0c812SMatthew G. Knepley ierr = ISSetType(fields, ISGENERAL);CHKERRQ(ierr); 552588f0c812SMatthew G. Knepley ierr = ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER);CHKERRQ(ierr); 552688f0c812SMatthew G. Knepley 5527083401c6SMatthew G. Knepley ierr = PetscDSCreate(comm, &dsDef);CHKERRQ(ierr); 5528083401c6SMatthew G. Knepley ierr = DMSetRegionDS(dm, NULL, fields, dsDef);CHKERRQ(ierr); 5529083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&dsDef);CHKERRQ(ierr); 5530b3cf3223SMatthew G. Knepley ierr = ISDestroy(&fields);CHKERRQ(ierr); 55312df9ee95SMatthew G. Knepley } 5532083401c6SMatthew G. Knepley } 5533083401c6SMatthew G. Knepley ierr = DMGetRegionDS(dm, NULL, NULL, &dsDef);CHKERRQ(ierr); 5534083401c6SMatthew G. Knepley if (dsDef) {ierr = PetscDSSetCoordinateDimension(dsDef, dE);CHKERRQ(ierr);} 5535083401c6SMatthew G. Knepley /* Intersect labels with default fields */ 5536083401c6SMatthew G. Knepley if (Ndef && Nl) { 55370122748bSMatthew G. Knepley DM plex; 5538083401c6SMatthew G. Knepley DMLabel cellLabel; 5539083401c6SMatthew G. Knepley IS fieldIS, allcellIS, defcellIS = NULL; 5540083401c6SMatthew G. Knepley PetscInt *fields; 5541083401c6SMatthew G. Knepley const PetscInt *cells; 5542083401c6SMatthew G. Knepley PetscInt depth, nf = 0, n, c; 55430122748bSMatthew G. Knepley 55440122748bSMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 55450122748bSMatthew G. Knepley ierr = DMPlexGetDepth(plex, &depth);CHKERRQ(ierr); 5546083401c6SMatthew G. Knepley ierr = DMGetStratumIS(plex, "dim", depth, &allcellIS);CHKERRQ(ierr); 5547083401c6SMatthew G. Knepley if (!allcellIS) {ierr = DMGetStratumIS(plex, "depth", depth, &allcellIS);CHKERRQ(ierr);} 5548083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5549083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5550083401c6SMatthew G. Knepley IS pointIS; 5551083401c6SMatthew G. Knepley 5552083401c6SMatthew G. Knepley ierr = ISDestroy(&defcellIS);CHKERRQ(ierr); 5553083401c6SMatthew G. Knepley ierr = DMLabelGetStratumIS(label, 1, &pointIS);CHKERRQ(ierr); 5554083401c6SMatthew G. Knepley ierr = ISDifference(allcellIS, pointIS, &defcellIS);CHKERRQ(ierr); 5555083401c6SMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 5556083401c6SMatthew G. Knepley } 5557083401c6SMatthew G. Knepley ierr = ISDestroy(&allcellIS);CHKERRQ(ierr); 5558083401c6SMatthew G. Knepley 5559083401c6SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, "defaultCells", &cellLabel);CHKERRQ(ierr); 5560083401c6SMatthew G. Knepley ierr = ISGetLocalSize(defcellIS, &n);CHKERRQ(ierr); 5561083401c6SMatthew G. Knepley ierr = ISGetIndices(defcellIS, &cells);CHKERRQ(ierr); 5562083401c6SMatthew G. Knepley for (c = 0; c < n; ++c) {ierr = DMLabelSetValue(cellLabel, cells[c], 1);CHKERRQ(ierr);} 5563083401c6SMatthew G. Knepley ierr = ISRestoreIndices(defcellIS, &cells);CHKERRQ(ierr); 5564083401c6SMatthew G. Knepley ierr = ISDestroy(&defcellIS);CHKERRQ(ierr); 5565083401c6SMatthew G. Knepley ierr = DMPlexLabelComplete(plex, cellLabel);CHKERRQ(ierr); 5566083401c6SMatthew G. Knepley 5567083401c6SMatthew G. Knepley ierr = PetscMalloc1(Ndef, &fields);CHKERRQ(ierr); 5568083401c6SMatthew G. Knepley for (f = 0; f < Nf; ++f) if (!dm->fields[f].label) fields[nf++] = f; 5569083401c6SMatthew G. Knepley ierr = ISCreate(PETSC_COMM_SELF, &fieldIS);CHKERRQ(ierr); 5570083401c6SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) fieldIS, "dm_fields_");CHKERRQ(ierr); 5571083401c6SMatthew G. Knepley ierr = ISSetType(fieldIS, ISGENERAL);CHKERRQ(ierr); 5572083401c6SMatthew G. Knepley ierr = ISGeneralSetIndices(fieldIS, nf, fields, PETSC_OWN_POINTER);CHKERRQ(ierr); 5573083401c6SMatthew G. Knepley 5574083401c6SMatthew G. Knepley ierr = PetscDSCreate(comm, &dsDef);CHKERRQ(ierr); 5575083401c6SMatthew G. Knepley ierr = DMSetRegionDS(dm, cellLabel, fieldIS, dsDef);CHKERRQ(ierr); 5576083401c6SMatthew G. Knepley ierr = DMLabelDestroy(&cellLabel);CHKERRQ(ierr); 5577083401c6SMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(dsDef, dE);CHKERRQ(ierr); 5578083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&dsDef);CHKERRQ(ierr); 5579083401c6SMatthew G. Knepley ierr = ISDestroy(&fieldIS);CHKERRQ(ierr); 55800122748bSMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 5581083401c6SMatthew G. Knepley } 5582083401c6SMatthew G. Knepley /* Create label DSes 5583083401c6SMatthew G. Knepley - WE ONLY SUPPORT IDENTICAL OR DISJOINT LABELS 5584083401c6SMatthew G. Knepley */ 5585083401c6SMatthew G. Knepley /* TODO Should check that labels are disjoint */ 5586083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5587083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5588083401c6SMatthew G. Knepley PetscDS ds; 5589083401c6SMatthew G. Knepley IS fields; 5590083401c6SMatthew G. Knepley PetscInt *fld, nf; 5591083401c6SMatthew G. Knepley 5592083401c6SMatthew G. Knepley ierr = PetscDSCreate(comm, &ds);CHKERRQ(ierr); 5593083401c6SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (label == dm->fields[f].label || !dm->fields[f].label) ++nf; 5594083401c6SMatthew G. Knepley ierr = PetscMalloc1(nf, &fld);CHKERRQ(ierr); 5595083401c6SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (label == dm->fields[f].label || !dm->fields[f].label) fld[nf++] = f; 5596083401c6SMatthew G. Knepley ierr = ISCreate(PETSC_COMM_SELF, &fields);CHKERRQ(ierr); 5597083401c6SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_");CHKERRQ(ierr); 5598083401c6SMatthew G. Knepley ierr = ISSetType(fields, ISGENERAL);CHKERRQ(ierr); 5599083401c6SMatthew G. Knepley ierr = ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER);CHKERRQ(ierr); 5600083401c6SMatthew G. Knepley ierr = DMSetRegionDS(dm, label, fields, ds);CHKERRQ(ierr); 5601083401c6SMatthew G. Knepley ierr = ISDestroy(&fields);CHKERRQ(ierr); 5602083401c6SMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(ds, dE);CHKERRQ(ierr); 5603083401c6SMatthew G. Knepley { 5604083401c6SMatthew G. Knepley DMPolytopeType ct; 5605083401c6SMatthew G. Knepley PetscInt lStart, lEnd; 5606083401c6SMatthew G. Knepley PetscBool isHybridLocal = PETSC_FALSE, isHybrid; 56070122748bSMatthew G. Knepley 5608e5e52638SMatthew G. Knepley ierr = DMLabelGetBounds(label, &lStart, &lEnd);CHKERRQ(ierr); 5609665f567fSMatthew G. Knepley if (lStart >= 0) { 5610412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, lStart, &ct);CHKERRQ(ierr); 5611412e9a14SMatthew G. Knepley switch (ct) { 5612412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 5613412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 5614412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 5615412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 5616083401c6SMatthew G. Knepley isHybridLocal = PETSC_TRUE;break; 5617083401c6SMatthew G. Knepley default: break; 5618412e9a14SMatthew G. Knepley } 5619665f567fSMatthew G. Knepley } 5620ffc4695bSBarry Smith ierr = MPI_Allreduce(&isHybridLocal, &isHybrid, 1, MPIU_BOOL, MPI_LOR, comm);CHKERRMPI(ierr); 5621083401c6SMatthew G. Knepley ierr = PetscDSSetHybrid(ds, isHybrid);CHKERRQ(ierr); 5622e5e52638SMatthew G. Knepley } 5623083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&ds);CHKERRQ(ierr); 5624e5e52638SMatthew G. Knepley } 5625083401c6SMatthew G. Knepley ierr = PetscFree(labelSet);CHKERRQ(ierr); 5626e5e52638SMatthew G. Knepley /* Set fields in DSes */ 5627083401c6SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5628083401c6SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 5629083401c6SMatthew G. Knepley IS fields = dm->probs[s].fields; 5630083401c6SMatthew G. Knepley const PetscInt *fld; 5631083401c6SMatthew G. Knepley PetscInt nf; 5632e5e52638SMatthew G. Knepley 5633083401c6SMatthew G. Knepley ierr = ISGetLocalSize(fields, &nf);CHKERRQ(ierr); 5634083401c6SMatthew G. Knepley ierr = ISGetIndices(fields, &fld);CHKERRQ(ierr); 5635083401c6SMatthew G. Knepley for (f = 0; f < nf; ++f) { 5636083401c6SMatthew G. Knepley PetscObject disc = dm->fields[fld[f]].disc; 5637083401c6SMatthew G. Knepley PetscBool isHybrid; 5638e5e52638SMatthew G. Knepley PetscClassId id; 5639e5e52638SMatthew G. Knepley 5640083401c6SMatthew G. Knepley ierr = PetscDSGetHybrid(ds, &isHybrid);CHKERRQ(ierr); 5641083401c6SMatthew G. Knepley /* If this is a cohesive cell, then it needs the lower dimensional discretization */ 5642083401c6SMatthew G. Knepley if (isHybrid && f < nf-1) {ierr = PetscFEGetHeightSubspace((PetscFE) disc, 1, (PetscFE *) &disc);CHKERRQ(ierr);} 5643083401c6SMatthew G. Knepley ierr = PetscDSSetDiscretization(ds, f, disc);CHKERRQ(ierr); 5644083401c6SMatthew G. Knepley /* We allow people to have placeholder fields and construct the Section by hand */ 5645e5e52638SMatthew G. Knepley ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr); 5646e5e52638SMatthew G. Knepley if ((id != PETSCFE_CLASSID) && (id != PETSCFV_CLASSID)) doSetup = PETSC_FALSE; 5647e5e52638SMatthew G. Knepley } 5648083401c6SMatthew G. Knepley ierr = ISRestoreIndices(fields, &fld);CHKERRQ(ierr); 5649e5e52638SMatthew G. Knepley } 5650f9244615SMatthew G. Knepley /* Allow k-jet tabulation */ 5651f9244615SMatthew G. Knepley ierr = PetscOptionsGetInt(NULL, ((PetscObject) dm)->prefix, "-dm_ds_jet_degree", &k, &flg);CHKERRQ(ierr); 5652f9244615SMatthew G. Knepley if (flg) { 5653f9244615SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) {ierr = PetscDSSetJetDegree(dm->probs[s].ds, 0, k);CHKERRQ(ierr);} 5654f9244615SMatthew G. Knepley } 5655e5e52638SMatthew G. Knepley /* Setup DSes */ 5656e5e52638SMatthew G. Knepley if (doSetup) { 5657e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) {ierr = PetscDSSetUp(dm->probs[s].ds);CHKERRQ(ierr);} 5658e5e52638SMatthew G. Knepley } 5659e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5660e5e52638SMatthew G. Knepley } 5661e5e52638SMatthew G. Knepley 5662e5e52638SMatthew G. Knepley /*@ 56637f96f943SMatthew G. Knepley DMComputeExactSolution - Compute the exact solution for a given DM, using the PetscDS information. 56647f96f943SMatthew G. Knepley 5665f2cacb80SMatthew G. Knepley Collective on DM 5666f2cacb80SMatthew G. Knepley 56677f96f943SMatthew G. Knepley Input Parameters: 56687f96f943SMatthew G. Knepley + dm - The DM 56697f96f943SMatthew G. Knepley - time - The time 56707f96f943SMatthew G. Knepley 56717f96f943SMatthew G. Knepley Output Parameters: 5672f2cacb80SMatthew G. Knepley + u - The vector will be filled with exact solution values, or NULL 5673f2cacb80SMatthew G. Knepley - u_t - The vector will be filled with the time derivative of exact solution values, or NULL 56747f96f943SMatthew G. Knepley 56757f96f943SMatthew G. Knepley Note: The user must call PetscDSSetExactSolution() beforehand 56767f96f943SMatthew G. Knepley 56777f96f943SMatthew G. Knepley Level: developer 56787f96f943SMatthew G. Knepley 56797f96f943SMatthew G. Knepley .seealso: PetscDSSetExactSolution() 56807f96f943SMatthew G. Knepley @*/ 5681f2cacb80SMatthew G. Knepley PetscErrorCode DMComputeExactSolution(DM dm, PetscReal time, Vec u, Vec u_t) 56827f96f943SMatthew G. Knepley { 56837f96f943SMatthew G. Knepley PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx); 56847f96f943SMatthew G. Knepley void **ectxs; 56857f96f943SMatthew G. Knepley PetscInt Nf, Nds, s; 56867f96f943SMatthew G. Knepley PetscErrorCode ierr; 56877f96f943SMatthew G. Knepley 56887f96f943SMatthew G. Knepley PetscFunctionBegin; 5689f2cacb80SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5690f2cacb80SMatthew G. Knepley if (u) PetscValidHeaderSpecific(u, VEC_CLASSID, 3); 5691f2cacb80SMatthew G. Knepley if (u_t) PetscValidHeaderSpecific(u_t, VEC_CLASSID, 4); 56927f96f943SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 56937f96f943SMatthew G. Knepley ierr = PetscMalloc2(Nf, &exacts, Nf, &ectxs);CHKERRQ(ierr); 56947f96f943SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 56957f96f943SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 56967f96f943SMatthew G. Knepley PetscDS ds; 56977f96f943SMatthew G. Knepley DMLabel label; 56987f96f943SMatthew G. Knepley IS fieldIS; 56997f96f943SMatthew G. Knepley const PetscInt *fields, id = 1; 57007f96f943SMatthew G. Knepley PetscInt dsNf, f; 57017f96f943SMatthew G. Knepley 57027f96f943SMatthew G. Knepley ierr = DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds);CHKERRQ(ierr); 57037f96f943SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &dsNf);CHKERRQ(ierr); 57047f96f943SMatthew G. Knepley ierr = ISGetIndices(fieldIS, &fields);CHKERRQ(ierr); 57057f96f943SMatthew G. Knepley ierr = PetscArrayzero(exacts, Nf);CHKERRQ(ierr); 57067f96f943SMatthew G. Knepley ierr = PetscArrayzero(ectxs, Nf);CHKERRQ(ierr); 5707f2cacb80SMatthew G. Knepley if (u) { 57087f96f943SMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 57097f96f943SMatthew G. Knepley const PetscInt field = fields[f]; 57107f96f943SMatthew G. Knepley ierr = PetscDSGetExactSolution(ds, field, &exacts[field], &ectxs[field]);CHKERRQ(ierr); 57117f96f943SMatthew G. Knepley } 57127f96f943SMatthew G. Knepley ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr); 57137f96f943SMatthew G. Knepley if (label) { 57147f96f943SMatthew G. Knepley ierr = DMProjectFunctionLabel(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, u);CHKERRQ(ierr); 57157f96f943SMatthew G. Knepley } else { 57167f96f943SMatthew G. Knepley ierr = DMProjectFunction(dm, time, exacts, ectxs, INSERT_ALL_VALUES, u);CHKERRQ(ierr); 57177f96f943SMatthew G. Knepley } 57187f96f943SMatthew G. Knepley } 5719f2cacb80SMatthew G. Knepley if (u_t) { 5720f2cacb80SMatthew G. Knepley ierr = PetscArrayzero(exacts, Nf);CHKERRQ(ierr); 5721f2cacb80SMatthew G. Knepley ierr = PetscArrayzero(ectxs, Nf);CHKERRQ(ierr); 5722f2cacb80SMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 5723f2cacb80SMatthew G. Knepley const PetscInt field = fields[f]; 5724f2cacb80SMatthew G. Knepley ierr = PetscDSGetExactSolutionTimeDerivative(ds, field, &exacts[field], &ectxs[field]);CHKERRQ(ierr); 5725f2cacb80SMatthew G. Knepley } 5726f2cacb80SMatthew G. Knepley ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr); 5727f2cacb80SMatthew G. Knepley if (label) { 5728f2cacb80SMatthew G. Knepley ierr = DMProjectFunctionLabel(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, u_t);CHKERRQ(ierr); 5729f2cacb80SMatthew G. Knepley } else { 5730f2cacb80SMatthew G. Knepley ierr = DMProjectFunction(dm, time, exacts, ectxs, INSERT_ALL_VALUES, u_t);CHKERRQ(ierr); 5731f2cacb80SMatthew G. Knepley } 5732f2cacb80SMatthew G. Knepley } 5733f2cacb80SMatthew G. Knepley } 5734f2cacb80SMatthew G. Knepley if (u) { 57357f96f943SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) u, "Exact Solution");CHKERRQ(ierr); 57367f96f943SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) u, "exact_");CHKERRQ(ierr); 5737f2cacb80SMatthew G. Knepley } 5738f2cacb80SMatthew G. Knepley if (u_t) { 5739f2cacb80SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) u, "Exact Solution Time Derivative");CHKERRQ(ierr); 5740f2cacb80SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) u_t, "exact_t_");CHKERRQ(ierr); 5741f2cacb80SMatthew G. Knepley } 57427f96f943SMatthew G. Knepley ierr = PetscFree2(exacts, ectxs);CHKERRQ(ierr); 57437f96f943SMatthew G. Knepley PetscFunctionReturn(0); 57447f96f943SMatthew G. Knepley } 57457f96f943SMatthew G. Knepley 57467f96f943SMatthew G. Knepley /*@ 5747e5e52638SMatthew G. Knepley DMCopyDS - Copy the discrete systems for the DM into another DM 5748e5e52638SMatthew G. Knepley 5749d083f849SBarry Smith Collective on dm 5750e5e52638SMatthew G. Knepley 5751e5e52638SMatthew G. Knepley Input Parameter: 5752e5e52638SMatthew G. Knepley . dm - The DM 5753e5e52638SMatthew G. Knepley 5754e5e52638SMatthew G. Knepley Output Parameter: 5755e5e52638SMatthew G. Knepley . newdm - The DM 5756e5e52638SMatthew G. Knepley 5757e5e52638SMatthew G. Knepley Level: advanced 5758e5e52638SMatthew G. Knepley 5759e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS() 5760e5e52638SMatthew G. Knepley @*/ 5761e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDS(DM dm, DM newdm) 5762e5e52638SMatthew G. Knepley { 5763e5e52638SMatthew G. Knepley PetscInt Nds, s; 5764e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5765e5e52638SMatthew G. Knepley 5766e5e52638SMatthew G. Knepley PetscFunctionBegin; 5767e5e52638SMatthew G. Knepley if (dm == newdm) PetscFunctionReturn(0); 5768e5e52638SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 5769e5e52638SMatthew G. Knepley ierr = DMClearDS(newdm);CHKERRQ(ierr); 5770e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5771e5e52638SMatthew G. Knepley DMLabel label; 5772b3cf3223SMatthew G. Knepley IS fields; 5773e5e52638SMatthew G. Knepley PetscDS ds; 5774783e2ec8SMatthew G. Knepley PetscInt Nbd, bd; 5775e5e52638SMatthew G. Knepley 5776b3cf3223SMatthew G. Knepley ierr = DMGetRegionNumDS(dm, s, &label, &fields, &ds);CHKERRQ(ierr); 5777b3cf3223SMatthew G. Knepley ierr = DMSetRegionDS(newdm, label, fields, ds);CHKERRQ(ierr); 5778783e2ec8SMatthew G. Knepley ierr = PetscDSGetNumBoundary(ds, &Nbd);CHKERRQ(ierr); 5779783e2ec8SMatthew G. Knepley for (bd = 0; bd < Nbd; ++bd) { 5780783e2ec8SMatthew G. Knepley const char *labelname, *name; 5781783e2ec8SMatthew G. Knepley PetscInt field; 5782783e2ec8SMatthew G. Knepley 5783783e2ec8SMatthew G. Knepley /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */ 578456cf3b9cSMatthew G. Knepley ierr = PetscDSGetBoundary(ds, bd, NULL, &name, &labelname, &field, NULL, NULL, NULL, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 5785783e2ec8SMatthew G. Knepley ierr = DMCompleteBoundaryLabel_Internal(newdm, ds, field, bd, labelname);CHKERRQ(ierr); 5786783e2ec8SMatthew G. Knepley } 5787e5e52638SMatthew G. Knepley } 5788e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5789e5e52638SMatthew G. Knepley } 5790e5e52638SMatthew G. Knepley 5791e5e52638SMatthew G. Knepley /*@ 5792e5e52638SMatthew G. Knepley DMCopyDisc - Copy the fields and discrete systems for the DM into another DM 5793e5e52638SMatthew G. Knepley 5794d083f849SBarry Smith Collective on dm 5795e5e52638SMatthew G. Knepley 5796e5e52638SMatthew G. Knepley Input Parameter: 5797e5e52638SMatthew G. Knepley . dm - The DM 5798e5e52638SMatthew G. Knepley 5799e5e52638SMatthew G. Knepley Output Parameter: 5800e5e52638SMatthew G. Knepley . newdm - The DM 5801e5e52638SMatthew G. Knepley 5802e5e52638SMatthew G. Knepley Level: advanced 5803e5e52638SMatthew G. Knepley 5804e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMCopyDS() 5805e5e52638SMatthew G. Knepley @*/ 5806e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDisc(DM dm, DM newdm) 5807e5e52638SMatthew G. Knepley { 5808e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5809e5e52638SMatthew G. Knepley 5810e5e52638SMatthew G. Knepley PetscFunctionBegin; 5811e5e52638SMatthew G. Knepley ierr = DMCopyFields(dm, newdm);CHKERRQ(ierr); 5812e5e52638SMatthew G. Knepley ierr = DMCopyDS(dm, newdm);CHKERRQ(ierr); 5813e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5814e5e52638SMatthew G. Knepley } 5815e5e52638SMatthew G. Knepley 5816b64e0483SPeter Brune PetscErrorCode DMRestrictHook_Coordinates(DM dm,DM dmc,void *ctx) 5817b64e0483SPeter Brune { 5818b64e0483SPeter Brune DM dm_coord,dmc_coord; 5819b64e0483SPeter Brune PetscErrorCode ierr; 5820b64e0483SPeter Brune Vec coords,ccoords; 58216dbf9973SLawrence Mitchell Mat inject; 5822b64e0483SPeter Brune PetscFunctionBegin; 5823b64e0483SPeter Brune ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr); 5824b64e0483SPeter Brune ierr = DMGetCoordinateDM(dmc,&dmc_coord);CHKERRQ(ierr); 5825b64e0483SPeter Brune ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr); 5826b64e0483SPeter Brune ierr = DMGetCoordinates(dmc,&ccoords);CHKERRQ(ierr); 5827b64e0483SPeter Brune if (coords && !ccoords) { 5828b64e0483SPeter Brune ierr = DMCreateGlobalVector(dmc_coord,&ccoords);CHKERRQ(ierr); 58296668ed41SLisandro Dalcin ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr); 58306dbf9973SLawrence Mitchell ierr = DMCreateInjection(dmc_coord,dm_coord,&inject);CHKERRQ(ierr); 58312adcf181SLawrence Mitchell ierr = MatRestrict(inject,coords,ccoords);CHKERRQ(ierr); 58326dbf9973SLawrence Mitchell ierr = MatDestroy(&inject);CHKERRQ(ierr); 5833b64e0483SPeter Brune ierr = DMSetCoordinates(dmc,ccoords);CHKERRQ(ierr); 5834b64e0483SPeter Brune ierr = VecDestroy(&ccoords);CHKERRQ(ierr); 5835b64e0483SPeter Brune } 5836b64e0483SPeter Brune PetscFunctionReturn(0); 5837b64e0483SPeter Brune } 5838b64e0483SPeter Brune 583903dadc2fSPeter Brune static PetscErrorCode DMSubDomainHook_Coordinates(DM dm,DM subdm,void *ctx) 584003dadc2fSPeter Brune { 584103dadc2fSPeter Brune DM dm_coord,subdm_coord; 584203dadc2fSPeter Brune PetscErrorCode ierr; 584303dadc2fSPeter Brune Vec coords,ccoords,clcoords; 584403dadc2fSPeter Brune VecScatter *scat_i,*scat_g; 584503dadc2fSPeter Brune PetscFunctionBegin; 584603dadc2fSPeter Brune ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr); 584703dadc2fSPeter Brune ierr = DMGetCoordinateDM(subdm,&subdm_coord);CHKERRQ(ierr); 584803dadc2fSPeter Brune ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr); 584903dadc2fSPeter Brune ierr = DMGetCoordinates(subdm,&ccoords);CHKERRQ(ierr); 585003dadc2fSPeter Brune if (coords && !ccoords) { 585103dadc2fSPeter Brune ierr = DMCreateGlobalVector(subdm_coord,&ccoords);CHKERRQ(ierr); 58526668ed41SLisandro Dalcin ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr); 585303dadc2fSPeter Brune ierr = DMCreateLocalVector(subdm_coord,&clcoords);CHKERRQ(ierr); 585424640c55SToby Isaac ierr = PetscObjectSetName((PetscObject)clcoords,"coordinates");CHKERRQ(ierr); 585503dadc2fSPeter Brune ierr = DMCreateDomainDecompositionScatters(dm_coord,1,&subdm_coord,NULL,&scat_i,&scat_g);CHKERRQ(ierr); 585603dadc2fSPeter Brune ierr = VecScatterBegin(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 585703dadc2fSPeter Brune ierr = VecScatterEnd(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 58581ed9ada7SJunchao Zhang ierr = VecScatterBegin(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 585903dadc2fSPeter Brune ierr = VecScatterEnd(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 586003dadc2fSPeter Brune ierr = DMSetCoordinates(subdm,ccoords);CHKERRQ(ierr); 586103dadc2fSPeter Brune ierr = DMSetCoordinatesLocal(subdm,clcoords);CHKERRQ(ierr); 586203dadc2fSPeter Brune ierr = VecScatterDestroy(&scat_i[0]);CHKERRQ(ierr); 586303dadc2fSPeter Brune ierr = VecScatterDestroy(&scat_g[0]);CHKERRQ(ierr); 586403dadc2fSPeter Brune ierr = VecDestroy(&ccoords);CHKERRQ(ierr); 586503dadc2fSPeter Brune ierr = VecDestroy(&clcoords);CHKERRQ(ierr); 586603dadc2fSPeter Brune ierr = PetscFree(scat_i);CHKERRQ(ierr); 586703dadc2fSPeter Brune ierr = PetscFree(scat_g);CHKERRQ(ierr); 586803dadc2fSPeter Brune } 586903dadc2fSPeter Brune PetscFunctionReturn(0); 587003dadc2fSPeter Brune } 587103dadc2fSPeter Brune 5872c73cfb54SMatthew G. Knepley /*@ 5873c73cfb54SMatthew G. Knepley DMGetDimension - Return the topological dimension of the DM 5874c73cfb54SMatthew G. Knepley 5875c73cfb54SMatthew G. Knepley Not collective 5876c73cfb54SMatthew G. Knepley 5877c73cfb54SMatthew G. Knepley Input Parameter: 5878c73cfb54SMatthew G. Knepley . dm - The DM 5879c73cfb54SMatthew G. Knepley 5880c73cfb54SMatthew G. Knepley Output Parameter: 5881c73cfb54SMatthew G. Knepley . dim - The topological dimension 5882c73cfb54SMatthew G. Knepley 5883c73cfb54SMatthew G. Knepley Level: beginner 5884c73cfb54SMatthew G. Knepley 5885c73cfb54SMatthew G. Knepley .seealso: DMSetDimension(), DMCreate() 5886c73cfb54SMatthew G. Knepley @*/ 5887c73cfb54SMatthew G. Knepley PetscErrorCode DMGetDimension(DM dm, PetscInt *dim) 5888c73cfb54SMatthew G. Knepley { 5889c73cfb54SMatthew G. Knepley PetscFunctionBegin; 5890c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5891534a8f05SLisandro Dalcin PetscValidIntPointer(dim, 2); 5892c73cfb54SMatthew G. Knepley *dim = dm->dim; 5893c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 5894c73cfb54SMatthew G. Knepley } 5895c73cfb54SMatthew G. Knepley 5896c73cfb54SMatthew G. Knepley /*@ 5897c73cfb54SMatthew G. Knepley DMSetDimension - Set the topological dimension of the DM 5898c73cfb54SMatthew G. Knepley 5899c73cfb54SMatthew G. Knepley Collective on dm 5900c73cfb54SMatthew G. Knepley 5901c73cfb54SMatthew G. Knepley Input Parameters: 5902c73cfb54SMatthew G. Knepley + dm - The DM 5903c73cfb54SMatthew G. Knepley - dim - The topological dimension 5904c73cfb54SMatthew G. Knepley 5905c73cfb54SMatthew G. Knepley Level: beginner 5906c73cfb54SMatthew G. Knepley 5907c73cfb54SMatthew G. Knepley .seealso: DMGetDimension(), DMCreate() 5908c73cfb54SMatthew G. Knepley @*/ 5909c73cfb54SMatthew G. Knepley PetscErrorCode DMSetDimension(DM dm, PetscInt dim) 5910c73cfb54SMatthew G. Knepley { 5911e5e52638SMatthew G. Knepley PetscDS ds; 5912f17e8794SMatthew G. Knepley PetscErrorCode ierr; 5913f17e8794SMatthew G. Knepley 5914c73cfb54SMatthew G. Knepley PetscFunctionBegin; 5915c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5916c73cfb54SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 5917c73cfb54SMatthew G. Knepley dm->dim = dim; 5918e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 5919e5e52638SMatthew G. Knepley if (ds->dimEmbed < 0) {ierr = PetscDSSetCoordinateDimension(ds, dm->dim);CHKERRQ(ierr);} 5920c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 5921c73cfb54SMatthew G. Knepley } 5922c73cfb54SMatthew G. Knepley 5923793f3fe5SMatthew G. Knepley /*@ 5924793f3fe5SMatthew G. Knepley DMGetDimPoints - Get the half-open interval for all points of a given dimension 5925793f3fe5SMatthew G. Knepley 5926d083f849SBarry Smith Collective on dm 5927793f3fe5SMatthew G. Knepley 5928793f3fe5SMatthew G. Knepley Input Parameters: 5929793f3fe5SMatthew G. Knepley + dm - the DM 5930793f3fe5SMatthew G. Knepley - dim - the dimension 5931793f3fe5SMatthew G. Knepley 5932793f3fe5SMatthew G. Knepley Output Parameters: 5933793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension 5934aa049354SPatrick Sanan - pEnd - The first point following points of the given dimension 5935793f3fe5SMatthew G. Knepley 5936793f3fe5SMatthew G. Knepley Note: 5937793f3fe5SMatthew G. Knepley The points are vertices in the Hasse diagram encoding the topology. This is explained in 5938a8d69d7bSBarry Smith https://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme, 5939793f3fe5SMatthew G. Knepley then the interval is empty. 5940793f3fe5SMatthew G. Knepley 5941793f3fe5SMatthew G. Knepley Level: intermediate 5942793f3fe5SMatthew G. Knepley 5943793f3fe5SMatthew G. Knepley .seealso: DMPLEX, DMPlexGetDepthStratum(), DMPlexGetHeightStratum() 5944793f3fe5SMatthew G. Knepley @*/ 5945793f3fe5SMatthew G. Knepley PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 5946793f3fe5SMatthew G. Knepley { 5947793f3fe5SMatthew G. Knepley PetscInt d; 5948793f3fe5SMatthew G. Knepley PetscErrorCode ierr; 5949793f3fe5SMatthew G. Knepley 5950793f3fe5SMatthew G. Knepley PetscFunctionBegin; 5951793f3fe5SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 5952793f3fe5SMatthew G. Knepley ierr = DMGetDimension(dm, &d);CHKERRQ(ierr); 5953793f3fe5SMatthew G. Knepley if ((dim < 0) || (dim > d)) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %d 1", dim, d); 5954b9d85ea2SLisandro Dalcin if (!dm->ops->getdimpoints) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "DM type %s does not implement DMGetDimPoints",((PetscObject)dm)->type_name); 5955793f3fe5SMatthew G. Knepley ierr = (*dm->ops->getdimpoints)(dm, dim, pStart, pEnd);CHKERRQ(ierr); 5956793f3fe5SMatthew G. Knepley PetscFunctionReturn(0); 5957793f3fe5SMatthew G. Knepley } 5958793f3fe5SMatthew G. Knepley 59596636e97aSMatthew G Knepley /*@ 59606636e97aSMatthew G Knepley DMSetCoordinates - Sets into the DM a global vector that holds the coordinates 59616636e97aSMatthew G Knepley 5962d083f849SBarry Smith Collective on dm 59636636e97aSMatthew G Knepley 59646636e97aSMatthew G Knepley Input Parameters: 59656636e97aSMatthew G Knepley + dm - the DM 59666636e97aSMatthew G Knepley - c - coordinate vector 59676636e97aSMatthew G Knepley 59682dd40e9bSPatrick Sanan Notes: 59692dd40e9bSPatrick Sanan The coordinates do include those for ghost points, which are in the local vector. 59702dd40e9bSPatrick Sanan 59712dd40e9bSPatrick Sanan The vector c should be destroyed by the caller. 59726636e97aSMatthew G Knepley 59736636e97aSMatthew G Knepley Level: intermediate 59746636e97aSMatthew G Knepley 597560c22052SBarry Smith .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMDASetUniformCoordinates() 59766636e97aSMatthew G Knepley @*/ 59776636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c) 59786636e97aSMatthew G Knepley { 59796636e97aSMatthew G Knepley PetscErrorCode ierr; 59806636e97aSMatthew G Knepley 59816636e97aSMatthew G Knepley PetscFunctionBegin; 59826636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 59836636e97aSMatthew G Knepley PetscValidHeaderSpecific(c,VEC_CLASSID,2); 59846636e97aSMatthew G Knepley ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr); 59856636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr); 59866636e97aSMatthew G Knepley dm->coordinates = c; 59876636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr); 5988b64e0483SPeter Brune ierr = DMCoarsenHookAdd(dm,DMRestrictHook_Coordinates,NULL,NULL);CHKERRQ(ierr); 598903dadc2fSPeter Brune ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_Coordinates,NULL,NULL);CHKERRQ(ierr); 59906636e97aSMatthew G Knepley PetscFunctionReturn(0); 59916636e97aSMatthew G Knepley } 59926636e97aSMatthew G Knepley 59936636e97aSMatthew G Knepley /*@ 59946636e97aSMatthew G Knepley DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates 59956636e97aSMatthew G Knepley 59967058e716SVaclav Hapla Not collective 59976636e97aSMatthew G Knepley 59986636e97aSMatthew G Knepley Input Parameters: 59996636e97aSMatthew G Knepley + dm - the DM 60006636e97aSMatthew G Knepley - c - coordinate vector 60016636e97aSMatthew G Knepley 60022dd40e9bSPatrick Sanan Notes: 60036636e97aSMatthew G Knepley The coordinates of ghost points can be set using DMSetCoordinates() 60046636e97aSMatthew G Knepley followed by DMGetCoordinatesLocal(). This is intended to enable the 60056636e97aSMatthew G Knepley setting of ghost coordinates outside of the domain. 60066636e97aSMatthew G Knepley 60072dd40e9bSPatrick Sanan The vector c should be destroyed by the caller. 60082dd40e9bSPatrick Sanan 60096636e97aSMatthew G Knepley Level: intermediate 60106636e97aSMatthew G Knepley 60116636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM() 60126636e97aSMatthew G Knepley @*/ 60136636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c) 60146636e97aSMatthew G Knepley { 60156636e97aSMatthew G Knepley PetscErrorCode ierr; 60166636e97aSMatthew G Knepley 60176636e97aSMatthew G Knepley PetscFunctionBegin; 60186636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 60196636e97aSMatthew G Knepley PetscValidHeaderSpecific(c,VEC_CLASSID,2); 60206636e97aSMatthew G Knepley ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr); 60216636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr); 60228865f1eaSKarl Rupp 60236636e97aSMatthew G Knepley dm->coordinatesLocal = c; 60248865f1eaSKarl Rupp 60256636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr); 60266636e97aSMatthew G Knepley PetscFunctionReturn(0); 60276636e97aSMatthew G Knepley } 60286636e97aSMatthew G Knepley 60296636e97aSMatthew G Knepley /*@ 60306636e97aSMatthew G Knepley DMGetCoordinates - Gets a global vector with the coordinates associated with the DM. 60316636e97aSMatthew G Knepley 6032d083f849SBarry Smith Collective on dm 60336636e97aSMatthew G Knepley 60346636e97aSMatthew G Knepley Input Parameter: 60356636e97aSMatthew G Knepley . dm - the DM 60366636e97aSMatthew G Knepley 60376636e97aSMatthew G Knepley Output Parameter: 60386636e97aSMatthew G Knepley . c - global coordinate vector 60396636e97aSMatthew G Knepley 60406636e97aSMatthew G Knepley Note: 604160c22052SBarry Smith This is a borrowed reference, so the user should NOT destroy this vector. When the DM is 604260c22052SBarry Smith destroyed the array will no longer be valid. 60436636e97aSMatthew G Knepley 60446636e97aSMatthew G Knepley Each process has only the local coordinates (does NOT have the ghost coordinates). 60456636e97aSMatthew G Knepley 60466636e97aSMatthew G Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 60476636e97aSMatthew G Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 60486636e97aSMatthew G Knepley 60496636e97aSMatthew G Knepley Level: intermediate 60506636e97aSMatthew G Knepley 605160c22052SBarry Smith .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMDASetUniformCoordinates() 60526636e97aSMatthew G Knepley @*/ 60536636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c) 60546636e97aSMatthew G Knepley { 60556636e97aSMatthew G Knepley PetscErrorCode ierr; 60566636e97aSMatthew G Knepley 60576636e97aSMatthew G Knepley PetscFunctionBegin; 60586636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 60596636e97aSMatthew G Knepley PetscValidPointer(c,2); 60601f588964SMatthew G Knepley if (!dm->coordinates && dm->coordinatesLocal) { 60610298fd71SBarry Smith DM cdm = NULL; 60621970a576SMatthew G. Knepley PetscBool localized; 60636636e97aSMatthew G Knepley 60646636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 60656636e97aSMatthew G Knepley ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr); 60661970a576SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 60671970a576SMatthew G. Knepley /* Block size is not correctly set by CreateGlobalVector() if coordinates are localized */ 60681970a576SMatthew G. Knepley if (localized) { 60691970a576SMatthew G. Knepley PetscInt cdim; 60701970a576SMatthew G. Knepley 60711970a576SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 60721970a576SMatthew G. Knepley ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr); 60731970a576SMatthew G. Knepley } 60746636e97aSMatthew G Knepley ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr); 60756636e97aSMatthew G Knepley ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr); 60766636e97aSMatthew G Knepley ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr); 60776636e97aSMatthew G Knepley } 60786636e97aSMatthew G Knepley *c = dm->coordinates; 60796636e97aSMatthew G Knepley PetscFunctionReturn(0); 60806636e97aSMatthew G Knepley } 60816636e97aSMatthew G Knepley 60826636e97aSMatthew G Knepley /*@ 608381e9a530SVaclav Hapla DMGetCoordinatesLocalSetUp - Prepares a local vector of coordinates, so that DMGetCoordinatesLocalNoncollective() can be used as non-collective afterwards. 608481e9a530SVaclav Hapla 6085d083f849SBarry Smith Collective on dm 608681e9a530SVaclav Hapla 608781e9a530SVaclav Hapla Input Parameter: 608881e9a530SVaclav Hapla . dm - the DM 608981e9a530SVaclav Hapla 609081e9a530SVaclav Hapla Level: advanced 609181e9a530SVaclav Hapla 609281e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalNoncollective() 609381e9a530SVaclav Hapla @*/ 609481e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalSetUp(DM dm) 609581e9a530SVaclav Hapla { 609681e9a530SVaclav Hapla PetscErrorCode ierr; 609781e9a530SVaclav Hapla 609881e9a530SVaclav Hapla PetscFunctionBegin; 609981e9a530SVaclav Hapla PetscValidHeaderSpecific(dm,DM_CLASSID,1); 610081e9a530SVaclav Hapla if (!dm->coordinatesLocal && dm->coordinates) { 61011970a576SMatthew G. Knepley DM cdm = NULL; 61021970a576SMatthew G. Knepley PetscBool localized; 61031970a576SMatthew G. Knepley 610481e9a530SVaclav Hapla ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 610581e9a530SVaclav Hapla ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr); 61061970a576SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 61071970a576SMatthew G. Knepley /* Block size is not correctly set by CreateLocalVector() if coordinates are localized */ 61081970a576SMatthew G. Knepley if (localized) { 61091970a576SMatthew G. Knepley PetscInt cdim; 61101970a576SMatthew G. Knepley 61111970a576SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 61121970a576SMatthew G. Knepley ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr); 61131970a576SMatthew G. Knepley } 611481e9a530SVaclav Hapla ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr); 611581e9a530SVaclav Hapla ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr); 611681e9a530SVaclav Hapla ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr); 611781e9a530SVaclav Hapla } 611881e9a530SVaclav Hapla PetscFunctionReturn(0); 611981e9a530SVaclav Hapla } 612081e9a530SVaclav Hapla 612181e9a530SVaclav Hapla /*@ 61226636e97aSMatthew G Knepley DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM. 61236636e97aSMatthew G Knepley 6124d083f849SBarry Smith Collective on dm 61256636e97aSMatthew G Knepley 61266636e97aSMatthew G Knepley Input Parameter: 61276636e97aSMatthew G Knepley . dm - the DM 61286636e97aSMatthew G Knepley 61296636e97aSMatthew G Knepley Output Parameter: 61306636e97aSMatthew G Knepley . c - coordinate vector 61316636e97aSMatthew G Knepley 61326636e97aSMatthew G Knepley Note: 61336636e97aSMatthew G Knepley This is a borrowed reference, so the user should NOT destroy this vector 61346636e97aSMatthew G Knepley 61356636e97aSMatthew G Knepley Each process has the local and ghost coordinates 61366636e97aSMatthew G Knepley 61376636e97aSMatthew G Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 61386636e97aSMatthew G Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 61396636e97aSMatthew G Knepley 61406636e97aSMatthew G Knepley Level: intermediate 61416636e97aSMatthew G Knepley 614281e9a530SVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM(), DMGetCoordinatesLocalNoncollective() 61436636e97aSMatthew G Knepley @*/ 61446636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c) 61456636e97aSMatthew G Knepley { 61466636e97aSMatthew G Knepley PetscErrorCode ierr; 61476636e97aSMatthew G Knepley 61486636e97aSMatthew G Knepley PetscFunctionBegin; 61496636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 61506636e97aSMatthew G Knepley PetscValidPointer(c,2); 615181e9a530SVaclav Hapla ierr = DMGetCoordinatesLocalSetUp(dm);CHKERRQ(ierr); 61526636e97aSMatthew G Knepley *c = dm->coordinatesLocal; 61536636e97aSMatthew G Knepley PetscFunctionReturn(0); 61546636e97aSMatthew G Knepley } 61556636e97aSMatthew G Knepley 615681e9a530SVaclav Hapla /*@ 615781e9a530SVaclav Hapla DMGetCoordinatesLocalNoncollective - Non-collective version of DMGetCoordinatesLocal(). Fails if global coordinates have been set and DMGetCoordinatesLocalSetUp() not called. 615881e9a530SVaclav Hapla 615981e9a530SVaclav Hapla Not collective 616081e9a530SVaclav Hapla 616181e9a530SVaclav Hapla Input Parameter: 616281e9a530SVaclav Hapla . dm - the DM 616381e9a530SVaclav Hapla 616481e9a530SVaclav Hapla Output Parameter: 616581e9a530SVaclav Hapla . c - coordinate vector 616681e9a530SVaclav Hapla 616781e9a530SVaclav Hapla Level: advanced 616881e9a530SVaclav Hapla 616981e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalSetUp(), DMGetCoordinatesLocal(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM() 617081e9a530SVaclav Hapla @*/ 617181e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalNoncollective(DM dm, Vec *c) 617281e9a530SVaclav Hapla { 617381e9a530SVaclav Hapla PetscFunctionBegin; 617481e9a530SVaclav Hapla PetscValidHeaderSpecific(dm,DM_CLASSID,1); 617581e9a530SVaclav Hapla PetscValidPointer(c,2); 617681e9a530SVaclav Hapla if (!dm->coordinatesLocal && dm->coordinates) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called"); 61776636e97aSMatthew G Knepley *c = dm->coordinatesLocal; 61786636e97aSMatthew G Knepley PetscFunctionReturn(0); 61796636e97aSMatthew G Knepley } 61806636e97aSMatthew G Knepley 61812db98f8dSVaclav Hapla /*@ 61822db98f8dSVaclav Hapla DMGetCoordinatesLocalTuple - Gets a local vector with the coordinates of specified points and section describing its layout. 61832db98f8dSVaclav Hapla 61842db98f8dSVaclav Hapla Not collective 61852db98f8dSVaclav Hapla 61862db98f8dSVaclav Hapla Input Parameter: 61872db98f8dSVaclav Hapla + dm - the DM 61882db98f8dSVaclav Hapla - p - the IS of points whose coordinates will be returned 61892db98f8dSVaclav Hapla 61902db98f8dSVaclav Hapla Output Parameter: 61912db98f8dSVaclav Hapla + pCoordSection - the PetscSection describing the layout of pCoord, i.e. each point corresponds to one point in p, and DOFs correspond to coordinates 61922db98f8dSVaclav Hapla - pCoord - the Vec with coordinates of points in p 61932db98f8dSVaclav Hapla 61942db98f8dSVaclav Hapla Note: 61952db98f8dSVaclav Hapla DMGetCoordinatesLocalSetUp() must be called first. This function employs DMGetCoordinatesLocalNoncollective() so it is not collective. 61962db98f8dSVaclav Hapla 61972db98f8dSVaclav Hapla This creates a new vector, so the user SHOULD destroy this vector 61982db98f8dSVaclav Hapla 61992db98f8dSVaclav Hapla Each process has the local and ghost coordinates 62002db98f8dSVaclav Hapla 62012db98f8dSVaclav Hapla For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 62022db98f8dSVaclav Hapla and (x_0,y_0,z_0,x_1,y_1,z_1...) 62032db98f8dSVaclav Hapla 62042db98f8dSVaclav Hapla Level: advanced 62052db98f8dSVaclav Hapla 62062db98f8dSVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinatesLocal(), DMGetCoordinatesLocalNoncollective(), DMGetCoordinatesLocalSetUp(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM() 62072db98f8dSVaclav Hapla @*/ 62082db98f8dSVaclav Hapla PetscErrorCode DMGetCoordinatesLocalTuple(DM dm, IS p, PetscSection *pCoordSection, Vec *pCoord) 62092db98f8dSVaclav Hapla { 62102db98f8dSVaclav Hapla PetscSection cs, newcs; 62112db98f8dSVaclav Hapla Vec coords; 62122db98f8dSVaclav Hapla const PetscScalar *arr; 62132db98f8dSVaclav Hapla PetscScalar *newarr=NULL; 62142db98f8dSVaclav Hapla PetscInt n; 62152db98f8dSVaclav Hapla PetscErrorCode ierr; 62162db98f8dSVaclav Hapla 62172db98f8dSVaclav Hapla PetscFunctionBegin; 62182db98f8dSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 62192db98f8dSVaclav Hapla PetscValidHeaderSpecific(p, IS_CLASSID, 2); 62202db98f8dSVaclav Hapla if (pCoordSection) PetscValidPointer(pCoordSection, 3); 62212db98f8dSVaclav Hapla if (pCoord) PetscValidPointer(pCoord, 4); 62222db98f8dSVaclav Hapla if (!dm->coordinatesLocal) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called or coordinates not set"); 62231bb6d2a8SBarry Smith if (!dm->coordinateDM || !dm->coordinateDM->localSection) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM not supported"); 62241bb6d2a8SBarry Smith cs = dm->coordinateDM->localSection; 62252db98f8dSVaclav Hapla coords = dm->coordinatesLocal; 62262db98f8dSVaclav Hapla ierr = VecGetArrayRead(coords, &arr);CHKERRQ(ierr); 62272db98f8dSVaclav Hapla ierr = PetscSectionExtractDofsFromArray(cs, MPIU_SCALAR, arr, p, &newcs, pCoord ? ((void**)&newarr) : NULL);CHKERRQ(ierr); 62282db98f8dSVaclav Hapla ierr = VecRestoreArrayRead(coords, &arr);CHKERRQ(ierr); 62292db98f8dSVaclav Hapla if (pCoord) { 62302db98f8dSVaclav Hapla ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr); 62312db98f8dSVaclav Hapla /* set array in two steps to mimic PETSC_OWN_POINTER */ 62322db98f8dSVaclav Hapla ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)p), 1, n, NULL, pCoord);CHKERRQ(ierr); 62332db98f8dSVaclav Hapla ierr = VecReplaceArray(*pCoord, newarr);CHKERRQ(ierr); 6234ad9ac99dSVaclav Hapla } else { 6235ad9ac99dSVaclav Hapla ierr = PetscFree(newarr);CHKERRQ(ierr); 62362db98f8dSVaclav Hapla } 6237ad9ac99dSVaclav Hapla if (pCoordSection) {*pCoordSection = newcs;} 6238ad9ac99dSVaclav Hapla else {ierr = PetscSectionDestroy(&newcs);CHKERRQ(ierr);} 62392db98f8dSVaclav Hapla PetscFunctionReturn(0); 62402db98f8dSVaclav Hapla } 62412db98f8dSVaclav Hapla 6242f19dbd58SToby Isaac PetscErrorCode DMGetCoordinateField(DM dm, DMField *field) 6243f19dbd58SToby Isaac { 6244f19dbd58SToby Isaac PetscErrorCode ierr; 6245f19dbd58SToby Isaac 6246f19dbd58SToby Isaac PetscFunctionBegin; 6247f19dbd58SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6248f19dbd58SToby Isaac PetscValidPointer(field,2); 6249f19dbd58SToby Isaac if (!dm->coordinateField) { 6250f19dbd58SToby Isaac if (dm->ops->createcoordinatefield) { 6251f19dbd58SToby Isaac ierr = (*dm->ops->createcoordinatefield)(dm,&dm->coordinateField);CHKERRQ(ierr); 6252f19dbd58SToby Isaac } 6253f19dbd58SToby Isaac } 6254f19dbd58SToby Isaac *field = dm->coordinateField; 6255f19dbd58SToby Isaac PetscFunctionReturn(0); 6256f19dbd58SToby Isaac } 6257f19dbd58SToby Isaac 6258f19dbd58SToby Isaac PetscErrorCode DMSetCoordinateField(DM dm, DMField field) 6259f19dbd58SToby Isaac { 6260f19dbd58SToby Isaac PetscErrorCode ierr; 6261f19dbd58SToby Isaac 6262f19dbd58SToby Isaac PetscFunctionBegin; 6263f19dbd58SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6264f19dbd58SToby Isaac if (field) PetscValidHeaderSpecific(field,DMFIELD_CLASSID,2); 6265c4e6da2cSBarry Smith ierr = PetscObjectReference((PetscObject)field);CHKERRQ(ierr); 6266f19dbd58SToby Isaac ierr = DMFieldDestroy(&dm->coordinateField);CHKERRQ(ierr); 6267f19dbd58SToby Isaac dm->coordinateField = field; 6268f19dbd58SToby Isaac PetscFunctionReturn(0); 6269f19dbd58SToby Isaac } 6270f19dbd58SToby Isaac 62716636e97aSMatthew G Knepley /*@ 62721cfe2091SMatthew G. Knepley DMGetCoordinateDM - Gets the DM that prescribes coordinate layout and scatters between global and local coordinates 62736636e97aSMatthew G Knepley 6274d083f849SBarry Smith Collective on dm 62756636e97aSMatthew G Knepley 62766636e97aSMatthew G Knepley Input Parameter: 62776636e97aSMatthew G Knepley . dm - the DM 62786636e97aSMatthew G Knepley 62796636e97aSMatthew G Knepley Output Parameter: 62806636e97aSMatthew G Knepley . cdm - coordinate DM 62816636e97aSMatthew G Knepley 62826636e97aSMatthew G Knepley Level: intermediate 62836636e97aSMatthew G Knepley 62841cfe2091SMatthew G. Knepley .seealso: DMSetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal() 62856636e97aSMatthew G Knepley @*/ 62866636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm) 62876636e97aSMatthew G Knepley { 62886636e97aSMatthew G Knepley PetscErrorCode ierr; 62896636e97aSMatthew G Knepley 62906636e97aSMatthew G Knepley PetscFunctionBegin; 62916636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 62926636e97aSMatthew G Knepley PetscValidPointer(cdm,2); 62936636e97aSMatthew G Knepley if (!dm->coordinateDM) { 6294308f8a94SToby Isaac DM cdm; 6295308f8a94SToby Isaac 629682f516ccSBarry Smith if (!dm->ops->createcoordinatedm) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unable to create coordinates for this DM"); 6297308f8a94SToby Isaac ierr = (*dm->ops->createcoordinatedm)(dm, &cdm);CHKERRQ(ierr); 6298308f8a94SToby Isaac /* Just in case the DM sets the coordinate DM when creating it (DMP4est can do this, because it may not setup 6299308f8a94SToby Isaac * until the call to CreateCoordinateDM) */ 6300308f8a94SToby Isaac ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr); 6301308f8a94SToby Isaac dm->coordinateDM = cdm; 63026636e97aSMatthew G Knepley } 63036636e97aSMatthew G Knepley *cdm = dm->coordinateDM; 63046636e97aSMatthew G Knepley PetscFunctionReturn(0); 63056636e97aSMatthew G Knepley } 6306e87bb0d3SMatthew G Knepley 63071cfe2091SMatthew G. Knepley /*@ 63081cfe2091SMatthew G. Knepley DMSetCoordinateDM - Sets the DM that prescribes coordinate layout and scatters between global and local coordinates 63091cfe2091SMatthew G. Knepley 6310d083f849SBarry Smith Logically Collective on dm 63111cfe2091SMatthew G. Knepley 63121cfe2091SMatthew G. Knepley Input Parameters: 63131cfe2091SMatthew G. Knepley + dm - the DM 63141cfe2091SMatthew G. Knepley - cdm - coordinate DM 63151cfe2091SMatthew G. Knepley 63161cfe2091SMatthew G. Knepley Level: intermediate 63171cfe2091SMatthew G. Knepley 63181cfe2091SMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal() 63191cfe2091SMatthew G. Knepley @*/ 63201cfe2091SMatthew G. Knepley PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm) 63211cfe2091SMatthew G. Knepley { 63221cfe2091SMatthew G. Knepley PetscErrorCode ierr; 63231cfe2091SMatthew G. Knepley 63241cfe2091SMatthew G. Knepley PetscFunctionBegin; 63251cfe2091SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 63261cfe2091SMatthew G. Knepley PetscValidHeaderSpecific(cdm,DM_CLASSID,2); 6327f26b38b9SToby Isaac ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr); 63281cfe2091SMatthew G. Knepley ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr); 63291cfe2091SMatthew G. Knepley dm->coordinateDM = cdm; 63301cfe2091SMatthew G. Knepley PetscFunctionReturn(0); 63311cfe2091SMatthew G. Knepley } 63321cfe2091SMatthew G. Knepley 633346e270d4SMatthew G. Knepley /*@ 633446e270d4SMatthew G. Knepley DMGetCoordinateDim - Retrieve the dimension of embedding space for coordinate values. 633546e270d4SMatthew G. Knepley 633646e270d4SMatthew G. Knepley Not Collective 633746e270d4SMatthew G. Knepley 633846e270d4SMatthew G. Knepley Input Parameter: 633946e270d4SMatthew G. Knepley . dm - The DM object 634046e270d4SMatthew G. Knepley 634146e270d4SMatthew G. Knepley Output Parameter: 634246e270d4SMatthew G. Knepley . dim - The embedding dimension 634346e270d4SMatthew G. Knepley 634446e270d4SMatthew G. Knepley Level: intermediate 634546e270d4SMatthew G. Knepley 634692fd8e1eSJed Brown .seealso: DMSetCoordinateDim(), DMGetCoordinateSection(), DMGetCoordinateDM(), DMGetLocalSection(), DMSetLocalSection() 634746e270d4SMatthew G. Knepley @*/ 634846e270d4SMatthew G. Knepley PetscErrorCode DMGetCoordinateDim(DM dm, PetscInt *dim) 634946e270d4SMatthew G. Knepley { 635046e270d4SMatthew G. Knepley PetscFunctionBegin; 635146e270d4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6352534a8f05SLisandro Dalcin PetscValidIntPointer(dim, 2); 63539a9a41abSToby Isaac if (dm->dimEmbed == PETSC_DEFAULT) { 63549a9a41abSToby Isaac dm->dimEmbed = dm->dim; 63559a9a41abSToby Isaac } 635646e270d4SMatthew G. Knepley *dim = dm->dimEmbed; 635746e270d4SMatthew G. Knepley PetscFunctionReturn(0); 635846e270d4SMatthew G. Knepley } 635946e270d4SMatthew G. Knepley 636046e270d4SMatthew G. Knepley /*@ 636146e270d4SMatthew G. Knepley DMSetCoordinateDim - Set the dimension of the embedding space for coordinate values. 636246e270d4SMatthew G. Knepley 636346e270d4SMatthew G. Knepley Not Collective 636446e270d4SMatthew G. Knepley 636546e270d4SMatthew G. Knepley Input Parameters: 636646e270d4SMatthew G. Knepley + dm - The DM object 636746e270d4SMatthew G. Knepley - dim - The embedding dimension 636846e270d4SMatthew G. Knepley 636946e270d4SMatthew G. Knepley Level: intermediate 637046e270d4SMatthew G. Knepley 637192fd8e1eSJed Brown .seealso: DMGetCoordinateDim(), DMSetCoordinateSection(), DMGetCoordinateSection(), DMGetLocalSection(), DMSetLocalSection() 637246e270d4SMatthew G. Knepley @*/ 637346e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateDim(DM dm, PetscInt dim) 637446e270d4SMatthew G. Knepley { 6375e5e52638SMatthew G. Knepley PetscDS ds; 6376f17e8794SMatthew G. Knepley PetscErrorCode ierr; 6377f17e8794SMatthew G. Knepley 637846e270d4SMatthew G. Knepley PetscFunctionBegin; 637946e270d4SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 638046e270d4SMatthew G. Knepley dm->dimEmbed = dim; 6381e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 6382e5e52638SMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(ds, dim);CHKERRQ(ierr); 638346e270d4SMatthew G. Knepley PetscFunctionReturn(0); 638446e270d4SMatthew G. Knepley } 638546e270d4SMatthew G. Knepley 6386e8abe2deSMatthew G. Knepley /*@ 6387e8abe2deSMatthew G. Knepley DMGetCoordinateSection - Retrieve the layout of coordinate values over the mesh. 6388e8abe2deSMatthew G. Knepley 6389d083f849SBarry Smith Collective on dm 6390e8abe2deSMatthew G. Knepley 6391e8abe2deSMatthew G. Knepley Input Parameter: 6392e8abe2deSMatthew G. Knepley . dm - The DM object 6393e8abe2deSMatthew G. Knepley 6394e8abe2deSMatthew G. Knepley Output Parameter: 6395e8abe2deSMatthew G. Knepley . section - The PetscSection object 6396e8abe2deSMatthew G. Knepley 6397e8abe2deSMatthew G. Knepley Level: intermediate 6398e8abe2deSMatthew G. Knepley 639992fd8e1eSJed Brown .seealso: DMGetCoordinateDM(), DMGetLocalSection(), DMSetLocalSection() 6400e8abe2deSMatthew G. Knepley @*/ 6401e8abe2deSMatthew G. Knepley PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section) 6402e8abe2deSMatthew G. Knepley { 6403e8abe2deSMatthew G. Knepley DM cdm; 6404e8abe2deSMatthew G. Knepley PetscErrorCode ierr; 6405e8abe2deSMatthew G. Knepley 6406e8abe2deSMatthew G. Knepley PetscFunctionBegin; 6407e8abe2deSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6408e8abe2deSMatthew G. Knepley PetscValidPointer(section, 2); 6409e8abe2deSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 641092fd8e1eSJed Brown ierr = DMGetLocalSection(cdm, section);CHKERRQ(ierr); 6411e8abe2deSMatthew G. Knepley PetscFunctionReturn(0); 6412e8abe2deSMatthew G. Knepley } 6413e8abe2deSMatthew G. Knepley 6414e8abe2deSMatthew G. Knepley /*@ 6415e8abe2deSMatthew G. Knepley DMSetCoordinateSection - Set the layout of coordinate values over the mesh. 6416e8abe2deSMatthew G. Knepley 6417e8abe2deSMatthew G. Knepley Not Collective 6418e8abe2deSMatthew G. Knepley 6419e8abe2deSMatthew G. Knepley Input Parameters: 6420e8abe2deSMatthew G. Knepley + dm - The DM object 642146e270d4SMatthew G. Knepley . dim - The embedding dimension, or PETSC_DETERMINE 6422e8abe2deSMatthew G. Knepley - section - The PetscSection object 6423e8abe2deSMatthew G. Knepley 6424e8abe2deSMatthew G. Knepley Level: intermediate 6425e8abe2deSMatthew G. Knepley 642692fd8e1eSJed Brown .seealso: DMGetCoordinateSection(), DMGetLocalSection(), DMSetLocalSection() 6427e8abe2deSMatthew G. Knepley @*/ 642846e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateSection(DM dm, PetscInt dim, PetscSection section) 6429e8abe2deSMatthew G. Knepley { 6430e8abe2deSMatthew G. Knepley DM cdm; 6431e8abe2deSMatthew G. Knepley PetscErrorCode ierr; 6432e8abe2deSMatthew G. Knepley 6433e8abe2deSMatthew G. Knepley PetscFunctionBegin; 6434e8abe2deSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 643546e270d4SMatthew G. Knepley PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,3); 6436e8abe2deSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 643792fd8e1eSJed Brown ierr = DMSetLocalSection(cdm, section);CHKERRQ(ierr); 643846e270d4SMatthew G. Knepley if (dim == PETSC_DETERMINE) { 64394c1069a6SMatthew G. Knepley PetscInt d = PETSC_DEFAULT; 644046e270d4SMatthew G. Knepley PetscInt pStart, pEnd, vStart, vEnd, v, dd; 644146e270d4SMatthew G. Knepley 644246e270d4SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 644346e270d4SMatthew G. Knepley ierr = DMGetDimPoints(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 644446e270d4SMatthew G. Knepley pStart = PetscMax(vStart, pStart); 644546e270d4SMatthew G. Knepley pEnd = PetscMin(vEnd, pEnd); 644646e270d4SMatthew G. Knepley for (v = pStart; v < pEnd; ++v) { 644746e270d4SMatthew G. Knepley ierr = PetscSectionGetDof(section, v, &dd);CHKERRQ(ierr); 644846e270d4SMatthew G. Knepley if (dd) {d = dd; break;} 644946e270d4SMatthew G. Knepley } 6450ebfe4b0dSMatthew G. Knepley if (d >= 0) {ierr = DMSetCoordinateDim(dm, d);CHKERRQ(ierr);} 645146e270d4SMatthew G. Knepley } 6452e8abe2deSMatthew G. Knepley PetscFunctionReturn(0); 6453e8abe2deSMatthew G. Knepley } 6454e8abe2deSMatthew G. Knepley 6455d864a3eaSLisandro Dalcin /*@ 6456d864a3eaSLisandro Dalcin DMProjectCoordinates - Project coordinates to a different space 6457d864a3eaSLisandro Dalcin 6458d864a3eaSLisandro Dalcin Input Parameters: 6459d864a3eaSLisandro Dalcin + dm - The DM object 6460d864a3eaSLisandro Dalcin - disc - The new coordinate discretization 6461d864a3eaSLisandro Dalcin 6462d864a3eaSLisandro Dalcin Level: intermediate 6463d864a3eaSLisandro Dalcin 6464d864a3eaSLisandro Dalcin .seealso: DMGetCoordinateField() 6465d864a3eaSLisandro Dalcin @*/ 6466d864a3eaSLisandro Dalcin PetscErrorCode DMProjectCoordinates(DM dm, PetscFE disc) 6467d864a3eaSLisandro Dalcin { 6468d864a3eaSLisandro Dalcin PetscObject discOld; 6469d864a3eaSLisandro Dalcin PetscClassId classid; 6470d864a3eaSLisandro Dalcin DM cdmOld,cdmNew; 6471d864a3eaSLisandro Dalcin Vec coordsOld,coordsNew; 6472d864a3eaSLisandro Dalcin Mat matInterp; 6473d864a3eaSLisandro Dalcin PetscErrorCode ierr; 6474d864a3eaSLisandro Dalcin 6475d864a3eaSLisandro Dalcin PetscFunctionBegin; 6476d864a3eaSLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6477d864a3eaSLisandro Dalcin PetscValidHeaderSpecific(disc,PETSCFE_CLASSID,2); 6478d864a3eaSLisandro Dalcin 6479d864a3eaSLisandro Dalcin ierr = DMGetCoordinateDM(dm, &cdmOld);CHKERRQ(ierr); 6480d864a3eaSLisandro Dalcin /* Check current discretization is compatible */ 6481d864a3eaSLisandro Dalcin ierr = DMGetField(cdmOld, 0, NULL, &discOld);CHKERRQ(ierr); 6482d864a3eaSLisandro Dalcin ierr = PetscObjectGetClassId(discOld, &classid);CHKERRQ(ierr); 648329ad44c5SMatthew G. Knepley if (classid != PETSCFE_CLASSID) { 648429ad44c5SMatthew G. Knepley if (classid == PETSC_CONTAINER_CLASSID) { 648529ad44c5SMatthew G. Knepley PetscFE feLinear; 648629ad44c5SMatthew G. Knepley DMPolytopeType ct; 648729ad44c5SMatthew G. Knepley PetscInt dim, dE, cStart; 648829ad44c5SMatthew G. Knepley PetscBool simplex; 648929ad44c5SMatthew G. Knepley 649029ad44c5SMatthew G. Knepley /* Assume linear vertex coordinates */ 649129ad44c5SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 649229ad44c5SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 649329ad44c5SMatthew G. Knepley ierr = DMPlexGetHeightStratum(cdmOld, 0, &cStart, NULL);CHKERRQ(ierr); 649429ad44c5SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 649529ad44c5SMatthew G. Knepley switch (ct) { 649629ad44c5SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 649729ad44c5SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 649829ad44c5SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot autoamtically create coordinate space for prisms"); 649929ad44c5SMatthew G. Knepley default: break; 650029ad44c5SMatthew G. Knepley } 650129ad44c5SMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 650229ad44c5SMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, dE, simplex, 1, -1, &feLinear);CHKERRQ(ierr); 650329ad44c5SMatthew G. Knepley ierr = DMSetField(cdmOld, 0, NULL, (PetscObject) feLinear);CHKERRQ(ierr); 650429ad44c5SMatthew G. Knepley ierr = PetscFEDestroy(&feLinear);CHKERRQ(ierr); 650529ad44c5SMatthew G. Knepley ierr = DMCreateDS(cdmOld);CHKERRQ(ierr); 650629ad44c5SMatthew G. Knepley } else { 650729ad44c5SMatthew G. Knepley const char *discname; 650829ad44c5SMatthew G. Knepley 650929ad44c5SMatthew G. Knepley ierr = PetscObjectGetType(discOld, &discname);CHKERRQ(ierr); 651029ad44c5SMatthew G. Knepley SETERRQ1(PetscObjectComm(discOld), PETSC_ERR_SUP, "Discretization type %s not supported", discname); 651129ad44c5SMatthew G. Knepley } 651229ad44c5SMatthew G. Knepley } 6513d864a3eaSLisandro Dalcin /* Make a fresh clone of the coordinate DM */ 6514d864a3eaSLisandro Dalcin ierr = DMClone(cdmOld, &cdmNew);CHKERRQ(ierr); 6515d864a3eaSLisandro Dalcin ierr = DMSetField(cdmNew, 0, NULL, (PetscObject) disc);CHKERRQ(ierr); 6516d864a3eaSLisandro Dalcin ierr = DMCreateDS(cdmNew);CHKERRQ(ierr); 6517d864a3eaSLisandro Dalcin /* Project the coordinate vector from old to new space */ 6518d864a3eaSLisandro Dalcin ierr = DMGetCoordinates(dm, &coordsOld);CHKERRQ(ierr); 6519d864a3eaSLisandro Dalcin ierr = DMCreateGlobalVector(cdmNew, &coordsNew);CHKERRQ(ierr); 6520d864a3eaSLisandro Dalcin ierr = DMCreateInterpolation(cdmOld, cdmNew, &matInterp, NULL);CHKERRQ(ierr); 6521d864a3eaSLisandro Dalcin ierr = MatInterpolate(matInterp, coordsOld, coordsNew);CHKERRQ(ierr); 6522d864a3eaSLisandro Dalcin ierr = MatDestroy(&matInterp);CHKERRQ(ierr); 6523d864a3eaSLisandro Dalcin /* Set new coordinate structures */ 6524d864a3eaSLisandro Dalcin ierr = DMSetCoordinateField(dm, NULL);CHKERRQ(ierr); 6525d864a3eaSLisandro Dalcin ierr = DMSetCoordinateDM(dm, cdmNew);CHKERRQ(ierr); 6526d864a3eaSLisandro Dalcin ierr = DMSetCoordinates(dm, coordsNew);CHKERRQ(ierr); 6527d864a3eaSLisandro Dalcin ierr = VecDestroy(&coordsNew);CHKERRQ(ierr); 6528d864a3eaSLisandro Dalcin ierr = DMDestroy(&cdmNew);CHKERRQ(ierr); 6529d864a3eaSLisandro Dalcin PetscFunctionReturn(0); 6530d864a3eaSLisandro Dalcin } 6531d864a3eaSLisandro Dalcin 65325dc8c3f7SMatthew G. Knepley /*@C 653390b157c4SStefano Zampini DMGetPeriodicity - Get the description of mesh periodicity 65345dc8c3f7SMatthew G. Knepley 65355dc8c3f7SMatthew G. Knepley Input Parameters: 653690b157c4SStefano Zampini . dm - The DM object 653790b157c4SStefano Zampini 653890b157c4SStefano Zampini Output Parameters: 653990b157c4SStefano Zampini + per - Whether the DM is periodic or not 65405dc8c3f7SMatthew 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 65415dc8c3f7SMatthew G. Knepley . L - If we assume the mesh is a torus, this is the length of each coordinate 65425dc8c3f7SMatthew G. Knepley - bd - This describes the type of periodicity in each topological dimension 65435dc8c3f7SMatthew G. Knepley 65445dc8c3f7SMatthew G. Knepley Level: developer 65455dc8c3f7SMatthew G. Knepley 65465dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity() 65475dc8c3f7SMatthew G. Knepley @*/ 654890b157c4SStefano Zampini PetscErrorCode DMGetPeriodicity(DM dm, PetscBool *per, const PetscReal **maxCell, const PetscReal **L, const DMBoundaryType **bd) 6549c6b900c6SMatthew G. Knepley { 6550c6b900c6SMatthew G. Knepley PetscFunctionBegin; 6551c6b900c6SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 655290b157c4SStefano Zampini if (per) *per = dm->periodic; 6553c6b900c6SMatthew G. Knepley if (L) *L = dm->L; 6554c6b900c6SMatthew G. Knepley if (maxCell) *maxCell = dm->maxCell; 65555dc8c3f7SMatthew G. Knepley if (bd) *bd = dm->bdtype; 6556c6b900c6SMatthew G. Knepley PetscFunctionReturn(0); 6557c6b900c6SMatthew G. Knepley } 6558c6b900c6SMatthew G. Knepley 65595dc8c3f7SMatthew G. Knepley /*@C 65605dc8c3f7SMatthew G. Knepley DMSetPeriodicity - Set the description of mesh periodicity 65615dc8c3f7SMatthew G. Knepley 65625dc8c3f7SMatthew G. Knepley Input Parameters: 65635dc8c3f7SMatthew G. Knepley + dm - The DM object 6564db2bf62eSStefano Zampini . per - Whether the DM is periodic or not. 6565db2bf62eSStefano 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. 65665dc8c3f7SMatthew G. Knepley . L - If we assume the mesh is a torus, this is the length of each coordinate 65675dc8c3f7SMatthew G. Knepley - bd - This describes the type of periodicity in each topological dimension 65685dc8c3f7SMatthew G. Knepley 6569db2bf62eSStefano 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. 6570db2bf62eSStefano Zampini 65715dc8c3f7SMatthew G. Knepley Level: developer 65725dc8c3f7SMatthew G. Knepley 65735dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity() 65745dc8c3f7SMatthew G. Knepley @*/ 657590b157c4SStefano Zampini PetscErrorCode DMSetPeriodicity(DM dm, PetscBool per, const PetscReal maxCell[], const PetscReal L[], const DMBoundaryType bd[]) 6576c6b900c6SMatthew G. Knepley { 6577c6b900c6SMatthew G. Knepley PetscInt dim, d; 6578c6b900c6SMatthew G. Knepley PetscErrorCode ierr; 6579c6b900c6SMatthew G. Knepley 6580c6b900c6SMatthew G. Knepley PetscFunctionBegin; 6581c6b900c6SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 658290b157c4SStefano Zampini PetscValidLogicalCollectiveBool(dm,per,2); 6583412e9a14SMatthew G. Knepley if (maxCell) {PetscValidRealPointer(maxCell,3);} 6584412e9a14SMatthew G. Knepley if (L) {PetscValidRealPointer(L,4);} 6585412e9a14SMatthew G. Knepley if (bd) {PetscValidPointer(bd,5);} 65865dc8c3f7SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 658790b157c4SStefano Zampini if (maxCell) { 6588412e9a14SMatthew G. Knepley if (!dm->maxCell) {ierr = PetscMalloc1(dim, &dm->maxCell);CHKERRQ(ierr);} 6589412e9a14SMatthew G. Knepley for (d = 0; d < dim; ++d) dm->maxCell[d] = maxCell[d]; 6590db2bf62eSStefano Zampini } else { /* remove maxCell information to disable automatic computation of localized vertices */ 6591db2bf62eSStefano Zampini ierr = PetscFree(dm->maxCell);CHKERRQ(ierr); 6592412e9a14SMatthew G. Knepley } 6593db2bf62eSStefano Zampini 6594412e9a14SMatthew G. Knepley if (L) { 6595412e9a14SMatthew G. Knepley if (!dm->L) {ierr = PetscMalloc1(dim, &dm->L);CHKERRQ(ierr);} 6596412e9a14SMatthew G. Knepley for (d = 0; d < dim; ++d) dm->L[d] = L[d]; 6597412e9a14SMatthew G. Knepley } 6598412e9a14SMatthew G. Knepley if (bd) { 6599412e9a14SMatthew G. Knepley if (!dm->bdtype) {ierr = PetscMalloc1(dim, &dm->bdtype);CHKERRQ(ierr);} 6600412e9a14SMatthew G. Knepley for (d = 0; d < dim; ++d) dm->bdtype[d] = bd[d]; 660190b157c4SStefano Zampini } 6602072d7d67SStefano Zampini dm->periodic = per; 6603c6b900c6SMatthew G. Knepley PetscFunctionReturn(0); 6604c6b900c6SMatthew G. Knepley } 6605c6b900c6SMatthew G. Knepley 66062e17dfb7SMatthew G. Knepley /*@ 66072e17dfb7SMatthew 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. 66082e17dfb7SMatthew G. Knepley 66092e17dfb7SMatthew G. Knepley Input Parameters: 66102e17dfb7SMatthew G. Knepley + dm - The DM 661165da65dcSMatthew G. Knepley . in - The input coordinate point (dim numbers) 661265da65dcSMatthew G. Knepley - endpoint - Include the endpoint L_i 66132e17dfb7SMatthew G. Knepley 66142e17dfb7SMatthew G. Knepley Output Parameter: 66152e17dfb7SMatthew G. Knepley . out - The localized coordinate point 66162e17dfb7SMatthew G. Knepley 66172e17dfb7SMatthew G. Knepley Level: developer 66182e17dfb7SMatthew G. Knepley 66192e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate() 66202e17dfb7SMatthew G. Knepley @*/ 662165da65dcSMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate(DM dm, const PetscScalar in[], PetscBool endpoint, PetscScalar out[]) 66222e17dfb7SMatthew G. Knepley { 66232e17dfb7SMatthew G. Knepley PetscInt dim, d; 66242e17dfb7SMatthew G. Knepley PetscErrorCode ierr; 66252e17dfb7SMatthew G. Knepley 66262e17dfb7SMatthew G. Knepley PetscFunctionBegin; 66272e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 66282e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 66292e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 66302e17dfb7SMatthew G. Knepley } else { 663165da65dcSMatthew G. Knepley if (endpoint) { 663265da65dcSMatthew G. Knepley for (d = 0; d < dim; ++d) { 6633da3333bfSMatthew 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)) { 6634da3333bfSMatthew G. Knepley out[d] = in[d] - dm->L[d]*(PetscFloorReal(PetscRealPart(in[d])/dm->L[d]) - 1); 663565da65dcSMatthew G. Knepley } else { 6636da3333bfSMatthew G. Knepley out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]); 663765da65dcSMatthew G. Knepley } 663865da65dcSMatthew G. Knepley } 663965da65dcSMatthew G. Knepley } else { 66402e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 66411118d4bcSLisandro Dalcin out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]); 66422e17dfb7SMatthew G. Knepley } 66432e17dfb7SMatthew G. Knepley } 664465da65dcSMatthew G. Knepley } 66452e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 66462e17dfb7SMatthew G. Knepley } 66472e17dfb7SMatthew G. Knepley 66482e17dfb7SMatthew G. Knepley /* 66492e17dfb7SMatthew 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. 66502e17dfb7SMatthew G. Knepley 66512e17dfb7SMatthew G. Knepley Input Parameters: 66522e17dfb7SMatthew G. Knepley + dm - The DM 66532e17dfb7SMatthew G. Knepley . dim - The spatial dimension 66542e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it 66552e17dfb7SMatthew G. Knepley - in - The input coordinate point (dim numbers) 66562e17dfb7SMatthew G. Knepley 66572e17dfb7SMatthew G. Knepley Output Parameter: 66582e17dfb7SMatthew G. Knepley . out - The localized coordinate point 66592e17dfb7SMatthew G. Knepley 66602e17dfb7SMatthew G. Knepley Level: developer 66612e17dfb7SMatthew G. Knepley 66622e17dfb7SMatthew 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 66632e17dfb7SMatthew G. Knepley 66642e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate() 66652e17dfb7SMatthew G. Knepley */ 66662e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[]) 66672e17dfb7SMatthew G. Knepley { 66682e17dfb7SMatthew G. Knepley PetscInt d; 66692e17dfb7SMatthew G. Knepley 66702e17dfb7SMatthew G. Knepley PetscFunctionBegin; 66712e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 66722e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 66732e17dfb7SMatthew G. Knepley } else { 66742e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 6675908eca10SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) { 66762e17dfb7SMatthew G. Knepley out[d] = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d]; 66772e17dfb7SMatthew G. Knepley } else { 66782e17dfb7SMatthew G. Knepley out[d] = in[d]; 66792e17dfb7SMatthew G. Knepley } 66802e17dfb7SMatthew G. Knepley } 66812e17dfb7SMatthew G. Knepley } 66822e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 66832e17dfb7SMatthew G. Knepley } 6684a5801f52SStefano Zampini 66852e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinateReal_Internal(DM dm, PetscInt dim, const PetscReal anchor[], const PetscReal in[], PetscReal out[]) 66862e17dfb7SMatthew G. Knepley { 66872e17dfb7SMatthew G. Knepley PetscInt d; 66882e17dfb7SMatthew G. Knepley 66892e17dfb7SMatthew G. Knepley PetscFunctionBegin; 66902e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 66912e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 66922e17dfb7SMatthew G. Knepley } else { 66932e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 6694908eca10SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsReal(anchor[d] - in[d]) > dm->maxCell[d])) { 66952e17dfb7SMatthew G. Knepley out[d] = anchor[d] > in[d] ? dm->L[d] + in[d] : in[d] - dm->L[d]; 66962e17dfb7SMatthew G. Knepley } else { 66972e17dfb7SMatthew G. Knepley out[d] = in[d]; 66982e17dfb7SMatthew G. Knepley } 66992e17dfb7SMatthew G. Knepley } 67002e17dfb7SMatthew G. Knepley } 67012e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 67022e17dfb7SMatthew G. Knepley } 67032e17dfb7SMatthew G. Knepley 67042e17dfb7SMatthew G. Knepley /* 67052e17dfb7SMatthew 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. 67062e17dfb7SMatthew G. Knepley 67072e17dfb7SMatthew G. Knepley Input Parameters: 67082e17dfb7SMatthew G. Knepley + dm - The DM 67092e17dfb7SMatthew G. Knepley . dim - The spatial dimension 67102e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it 67112e17dfb7SMatthew G. Knepley . in - The input coordinate delta (dim numbers) 67122e17dfb7SMatthew G. Knepley - out - The input coordinate point (dim numbers) 67132e17dfb7SMatthew G. Knepley 67142e17dfb7SMatthew G. Knepley Output Parameter: 67152e17dfb7SMatthew G. Knepley . out - The localized coordinate in + out 67162e17dfb7SMatthew G. Knepley 67172e17dfb7SMatthew G. Knepley Level: developer 67182e17dfb7SMatthew G. Knepley 67192e17dfb7SMatthew 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 67202e17dfb7SMatthew G. Knepley 67212e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeCoordinate() 67222e17dfb7SMatthew G. Knepley */ 67232e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeAddCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[]) 67242e17dfb7SMatthew G. Knepley { 67252e17dfb7SMatthew G. Knepley PetscInt d; 67262e17dfb7SMatthew G. Knepley 67272e17dfb7SMatthew G. Knepley PetscFunctionBegin; 67282e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 67292e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] += in[d]; 67302e17dfb7SMatthew G. Knepley } else { 67312e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 6732412e9a14SMatthew G. Knepley const PetscReal maxC = dm->maxCell[d]; 6733412e9a14SMatthew G. Knepley 6734412e9a14SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > maxC)) { 6735412e9a14SMatthew G. Knepley const PetscScalar newCoord = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d]; 6736412e9a14SMatthew G. Knepley 6737412e9a14SMatthew G. Knepley if (PetscAbsScalar(newCoord - anchor[d]) > maxC) 6738412e9a14SMatthew 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])); 6739412e9a14SMatthew G. Knepley out[d] += newCoord; 67402e17dfb7SMatthew G. Knepley } else { 67412e17dfb7SMatthew G. Knepley out[d] += in[d]; 67422e17dfb7SMatthew G. Knepley } 67432e17dfb7SMatthew G. Knepley } 67442e17dfb7SMatthew G. Knepley } 67452e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 67462e17dfb7SMatthew G. Knepley } 67472e17dfb7SMatthew G. Knepley 674836447a5eSToby Isaac /*@ 67498f700142SStefano Zampini DMGetCoordinatesLocalizedLocal - Check if the DM coordinates have been localized for cells on this process 67508f700142SStefano Zampini 67518f700142SStefano Zampini Not collective 675236447a5eSToby Isaac 675336447a5eSToby Isaac Input Parameter: 675436447a5eSToby Isaac . dm - The DM 675536447a5eSToby Isaac 675636447a5eSToby Isaac Output Parameter: 675736447a5eSToby Isaac areLocalized - True if localized 675836447a5eSToby Isaac 675936447a5eSToby Isaac Level: developer 676036447a5eSToby Isaac 67618f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMGetCoordinatesLocalized(), DMSetPeriodicity() 676236447a5eSToby Isaac @*/ 67638f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalizedLocal(DM dm,PetscBool *areLocalized) 676436447a5eSToby Isaac { 676536447a5eSToby Isaac DM cdm; 676636447a5eSToby Isaac PetscSection coordSection; 676746a3a80fSLisandro Dalcin PetscInt cStart, cEnd, sStart, sEnd, c, dof; 676846a3a80fSLisandro Dalcin PetscBool isPlex, alreadyLocalized; 676936447a5eSToby Isaac PetscErrorCode ierr; 677036447a5eSToby Isaac 677136447a5eSToby Isaac PetscFunctionBegin; 677236447a5eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6773534a8f05SLisandro Dalcin PetscValidBoolPointer(areLocalized, 2); 67748b09590cSToby Isaac *areLocalized = PETSC_FALSE; 677546a3a80fSLisandro Dalcin 677636447a5eSToby Isaac /* We need some generic way of refering to cells/vertices */ 677736447a5eSToby Isaac ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 677846a3a80fSLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isPlex);CHKERRQ(ierr); 67799f7230bfSMatthew G. Knepley if (!isPlex) PetscFunctionReturn(0); 678046a3a80fSLisandro Dalcin 67819f7230bfSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 678246a3a80fSLisandro Dalcin ierr = DMPlexGetHeightStratum(cdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 678336447a5eSToby Isaac ierr = PetscSectionGetChart(coordSection, &sStart, &sEnd);CHKERRQ(ierr); 678436447a5eSToby Isaac alreadyLocalized = PETSC_FALSE; 678546a3a80fSLisandro Dalcin for (c = cStart; c < cEnd; ++c) { 678646a3a80fSLisandro Dalcin if (c < sStart || c >= sEnd) continue; 678736447a5eSToby Isaac ierr = PetscSectionGetDof(coordSection, c, &dof);CHKERRQ(ierr); 678846a3a80fSLisandro Dalcin if (dof) { alreadyLocalized = PETSC_TRUE; break; } 678936447a5eSToby Isaac } 67908f700142SStefano Zampini *areLocalized = alreadyLocalized; 679136447a5eSToby Isaac PetscFunctionReturn(0); 679236447a5eSToby Isaac } 679336447a5eSToby Isaac 67948f700142SStefano Zampini /*@ 67958f700142SStefano Zampini DMGetCoordinatesLocalized - Check if the DM coordinates have been localized for cells 67968f700142SStefano Zampini 67978f700142SStefano Zampini Collective on dm 67988f700142SStefano Zampini 67998f700142SStefano Zampini Input Parameter: 68008f700142SStefano Zampini . dm - The DM 68018f700142SStefano Zampini 68028f700142SStefano Zampini Output Parameter: 68038f700142SStefano Zampini areLocalized - True if localized 68048f700142SStefano Zampini 68058f700142SStefano Zampini Level: developer 68068f700142SStefano Zampini 68078f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMSetPeriodicity(), DMGetCoordinatesLocalizedLocal() 68088f700142SStefano Zampini @*/ 68098f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalized(DM dm,PetscBool *areLocalized) 68108f700142SStefano Zampini { 68118f700142SStefano Zampini PetscBool localized; 68128f700142SStefano Zampini PetscErrorCode ierr; 68138f700142SStefano Zampini 68148f700142SStefano Zampini PetscFunctionBegin; 68158f700142SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6816534a8f05SLisandro Dalcin PetscValidBoolPointer(areLocalized, 2); 68178f700142SStefano Zampini ierr = DMGetCoordinatesLocalizedLocal(dm,&localized);CHKERRQ(ierr); 6818*820f2d46SBarry Smith ierr = MPIU_Allreduce(&localized,areLocalized,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 68198f700142SStefano Zampini PetscFunctionReturn(0); 68208f700142SStefano Zampini } 682136447a5eSToby Isaac 68222e17dfb7SMatthew G. Knepley /*@ 6823492b8470SStefano Zampini DMLocalizeCoordinates - If a mesh is periodic, create local coordinates for cells having periodic faces 68242e17dfb7SMatthew G. Knepley 68258f700142SStefano Zampini Collective on dm 68268f700142SStefano Zampini 68272e17dfb7SMatthew G. Knepley Input Parameter: 68282e17dfb7SMatthew G. Knepley . dm - The DM 68292e17dfb7SMatthew G. Knepley 68302e17dfb7SMatthew G. Knepley Level: developer 68312e17dfb7SMatthew G. Knepley 68328f700142SStefano Zampini .seealso: DMSetPeriodicity(), DMLocalizeCoordinate(), DMLocalizeAddCoordinate() 68332e17dfb7SMatthew G. Knepley @*/ 68342e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinates(DM dm) 68352e17dfb7SMatthew G. Knepley { 68362e17dfb7SMatthew G. Knepley DM cdm; 68372e17dfb7SMatthew G. Knepley PetscSection coordSection, cSection; 68382e17dfb7SMatthew G. Knepley Vec coordinates, cVec; 68393e922f36SToby Isaac PetscScalar *coords, *coords2, *anchor, *localized; 68403e922f36SToby Isaac PetscInt Nc, vStart, vEnd, v, sStart, sEnd, newStart = PETSC_MAX_INT, newEnd = PETSC_MIN_INT, dof, d, off, off2, bs, coordSize; 6841e0ae35bbSToby Isaac PetscBool alreadyLocalized, alreadyLocalizedGlobal; 68423e922f36SToby Isaac PetscInt maxHeight = 0, h; 68433e922f36SToby Isaac PetscInt *pStart = NULL, *pEnd = NULL; 68442e17dfb7SMatthew G. Knepley PetscErrorCode ierr; 68452e17dfb7SMatthew G. Knepley 68462e17dfb7SMatthew G. Knepley PetscFunctionBegin; 68472e17dfb7SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 684892c9c85fSStefano Zampini if (!dm->periodic) PetscFunctionReturn(0); 6849f7cbd40bSStefano Zampini ierr = DMGetCoordinatesLocalized(dm, &alreadyLocalized);CHKERRQ(ierr); 6850f7cbd40bSStefano Zampini if (alreadyLocalized) PetscFunctionReturn(0); 6851f7cbd40bSStefano Zampini 68522e17dfb7SMatthew G. Knepley /* We need some generic way of refering to cells/vertices */ 68532e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 68542e17dfb7SMatthew G. Knepley { 68552e17dfb7SMatthew G. Knepley PetscBool isplex; 68562e17dfb7SMatthew G. Knepley 68572e17dfb7SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isplex);CHKERRQ(ierr); 68582e17dfb7SMatthew G. Knepley if (isplex) { 68592e17dfb7SMatthew G. Knepley ierr = DMPlexGetDepthStratum(cdm, 0, &vStart, &vEnd);CHKERRQ(ierr); 68603e922f36SToby Isaac ierr = DMPlexGetMaxProjectionHeight(cdm,&maxHeight);CHKERRQ(ierr); 686169291d52SBarry Smith ierr = DMGetWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 68623e922f36SToby Isaac pEnd = &pStart[maxHeight + 1]; 68633e922f36SToby Isaac newStart = vStart; 68643e922f36SToby Isaac newEnd = vEnd; 68653e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 68663e922f36SToby Isaac ierr = DMPlexGetHeightStratum(cdm, h, &pStart[h], &pEnd[h]);CHKERRQ(ierr); 68673e922f36SToby Isaac newStart = PetscMin(newStart,pStart[h]); 68683e922f36SToby Isaac newEnd = PetscMax(newEnd,pEnd[h]); 68693e922f36SToby Isaac } 68702e17dfb7SMatthew G. Knepley } else SETERRQ(PetscObjectComm((PetscObject) cdm), PETSC_ERR_ARG_WRONG, "Coordinate localization requires a DMPLEX coordinate DM"); 68712e17dfb7SMatthew G. Knepley } 68722e17dfb7SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 687343eeeb2dSStefano Zampini if (!coordinates) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Missing local coordinates vector"); 68742e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 68753e922f36SToby Isaac ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 6876e0ae35bbSToby Isaac ierr = PetscSectionGetChart(coordSection,&sStart,&sEnd);CHKERRQ(ierr); 68773e922f36SToby Isaac 68782e17dfb7SMatthew G. Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &cSection);CHKERRQ(ierr); 68792e17dfb7SMatthew G. Knepley ierr = PetscSectionSetNumFields(cSection, 1);CHKERRQ(ierr); 68802e17dfb7SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(coordSection, 0, &Nc);CHKERRQ(ierr); 68812e17dfb7SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(cSection, 0, Nc);CHKERRQ(ierr); 68823e922f36SToby Isaac ierr = PetscSectionSetChart(cSection, newStart, newEnd);CHKERRQ(ierr); 68833e922f36SToby Isaac 688469291d52SBarry Smith ierr = DMGetWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 68853e922f36SToby Isaac localized = &anchor[bs]; 68863e922f36SToby Isaac alreadyLocalized = alreadyLocalizedGlobal = PETSC_TRUE; 68873e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 68883e922f36SToby Isaac PetscInt cStart = pStart[h], cEnd = pEnd[h], c; 68893e922f36SToby Isaac 68903e922f36SToby Isaac for (c = cStart; c < cEnd; ++c) { 68913e922f36SToby Isaac PetscScalar *cellCoords = NULL; 68923e922f36SToby Isaac PetscInt b; 68933e922f36SToby Isaac 68943e922f36SToby Isaac if (c < sStart || c >= sEnd) alreadyLocalized = PETSC_FALSE; 68953e922f36SToby Isaac ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 68963e922f36SToby Isaac for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b]; 68973e922f36SToby Isaac for (d = 0; d < dof/bs; ++d) { 68983e922f36SToby Isaac ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], localized);CHKERRQ(ierr); 68993e922f36SToby Isaac for (b = 0; b < bs; b++) { 69003e922f36SToby Isaac if (cellCoords[d*bs + b] != localized[b]) break; 69013e922f36SToby Isaac } 69023e922f36SToby Isaac if (b < bs) break; 69033e922f36SToby Isaac } 69043e922f36SToby Isaac if (d < dof/bs) { 69053e922f36SToby Isaac if (c >= sStart && c < sEnd) { 69063e922f36SToby Isaac PetscInt cdof; 69073e922f36SToby Isaac 69083e922f36SToby Isaac ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 69093e922f36SToby Isaac if (cdof != dof) alreadyLocalized = PETSC_FALSE; 69103e922f36SToby Isaac } 69113e922f36SToby Isaac ierr = PetscSectionSetDof(cSection, c, dof);CHKERRQ(ierr); 69123e922f36SToby Isaac ierr = PetscSectionSetFieldDof(cSection, c, 0, dof);CHKERRQ(ierr); 69133e922f36SToby Isaac } 69143e922f36SToby Isaac ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 69153e922f36SToby Isaac } 69163e922f36SToby Isaac } 6917ffc4695bSBarry Smith ierr = MPI_Allreduce(&alreadyLocalized,&alreadyLocalizedGlobal,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 69183e922f36SToby Isaac if (alreadyLocalizedGlobal) { 691969291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 69203e922f36SToby Isaac ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr); 692169291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 69223e922f36SToby Isaac PetscFunctionReturn(0); 69233e922f36SToby Isaac } 69242e17dfb7SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 69252e17dfb7SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 69262e17dfb7SMatthew G. Knepley ierr = PetscSectionSetDof(cSection, v, dof);CHKERRQ(ierr); 69272e17dfb7SMatthew G. Knepley ierr = PetscSectionSetFieldDof(cSection, v, 0, dof);CHKERRQ(ierr); 69282e17dfb7SMatthew G. Knepley } 69292e17dfb7SMatthew G. Knepley ierr = PetscSectionSetUp(cSection);CHKERRQ(ierr); 69302e17dfb7SMatthew G. Knepley ierr = PetscSectionGetStorageSize(cSection, &coordSize);CHKERRQ(ierr); 6931c2be7e5eSLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &cVec);CHKERRQ(ierr); 69322e17dfb7SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject)cVec,"coordinates");CHKERRQ(ierr); 69332e17dfb7SMatthew G. Knepley ierr = VecSetBlockSize(cVec, bs);CHKERRQ(ierr); 69342e17dfb7SMatthew G. Knepley ierr = VecSetSizes(cVec, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 69352e17dfb7SMatthew G. Knepley ierr = VecSetType(cVec, VECSTANDARD);CHKERRQ(ierr); 6936c2be7e5eSLisandro Dalcin ierr = VecGetArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr); 69372e17dfb7SMatthew G. Knepley ierr = VecGetArray(cVec, &coords2);CHKERRQ(ierr); 69382e17dfb7SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 69392e17dfb7SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 69402e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 69412e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(cSection, v, &off2);CHKERRQ(ierr); 69422e17dfb7SMatthew G. Knepley for (d = 0; d < dof; ++d) coords2[off2+d] = coords[off+d]; 69432e17dfb7SMatthew G. Knepley } 69443e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 69453e922f36SToby Isaac PetscInt cStart = pStart[h], cEnd = pEnd[h], c; 69463e922f36SToby Isaac 69472e17dfb7SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 69482e17dfb7SMatthew G. Knepley PetscScalar *cellCoords = NULL; 69493e922f36SToby Isaac PetscInt b, cdof; 69502e17dfb7SMatthew G. Knepley 69513e922f36SToby Isaac ierr = PetscSectionGetDof(cSection,c,&cdof);CHKERRQ(ierr); 69523e922f36SToby Isaac if (!cdof) continue; 69532e17dfb7SMatthew G. Knepley ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 69542e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(cSection, c, &off2);CHKERRQ(ierr); 69552e17dfb7SMatthew G. Knepley for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b]; 69562e17dfb7SMatthew G. Knepley for (d = 0; d < dof/bs; ++d) {ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], &coords2[off2+d*bs]);CHKERRQ(ierr);} 69572e17dfb7SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 69582e17dfb7SMatthew G. Knepley } 69593e922f36SToby Isaac } 696069291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 696169291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 6962c2be7e5eSLisandro Dalcin ierr = VecRestoreArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr); 69632e17dfb7SMatthew G. Knepley ierr = VecRestoreArray(cVec, &coords2);CHKERRQ(ierr); 69642e17dfb7SMatthew G. Knepley ierr = DMSetCoordinateSection(dm, PETSC_DETERMINE, cSection);CHKERRQ(ierr); 69652e17dfb7SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, cVec);CHKERRQ(ierr); 69662e17dfb7SMatthew G. Knepley ierr = VecDestroy(&cVec);CHKERRQ(ierr); 69672e17dfb7SMatthew G. Knepley ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr); 69682e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 69692e17dfb7SMatthew G. Knepley } 69702e17dfb7SMatthew G. Knepley 6971e87bb0d3SMatthew G Knepley /*@ 69723a93e3b7SToby Isaac DMLocatePoints - Locate the points in v in the mesh and return a PetscSF of the containing cells 6973e87bb0d3SMatthew G Knepley 6974d083f849SBarry Smith Collective on v (see explanation below) 6975e87bb0d3SMatthew G Knepley 6976e87bb0d3SMatthew G Knepley Input Parameters: 6977e87bb0d3SMatthew G Knepley + dm - The DM 69783a93e3b7SToby Isaac . v - The Vec of points 697962a38674SMatthew G. Knepley . ltype - The type of point location, e.g. DM_POINTLOCATION_NONE or DM_POINTLOCATION_NEAREST 69803a93e3b7SToby Isaac - cells - Points to either NULL, or a PetscSF with guesses for which cells contain each point. 6981e87bb0d3SMatthew G Knepley 698261e3bb9bSMatthew G Knepley Output Parameter: 698362a38674SMatthew G. Knepley + v - The Vec of points, which now contains the nearest mesh points to the given points if DM_POINTLOCATION_NEAREST is used 698462a38674SMatthew G. Knepley - cells - The PetscSF containing the ranks and local indices of the containing points. 69853a93e3b7SToby Isaac 6986e87bb0d3SMatthew G Knepley 6987e87bb0d3SMatthew G Knepley Level: developer 698861e3bb9bSMatthew G Knepley 698962a38674SMatthew G. Knepley Notes: 69903a93e3b7SToby Isaac To do a search of the local cells of the mesh, v should have PETSC_COMM_SELF as its communicator. 699162a38674SMatthew G. Knepley To do a search of all the cells in the distributed mesh, v should have the same communicator as dm. 69923a93e3b7SToby Isaac 69933a93e3b7SToby Isaac If *cellSF is NULL on input, a PetscSF will be created. 699462a38674SMatthew G. Knepley If *cellSF is not NULL on input, it should point to an existing PetscSF, whose graph will be used as initial guesses. 69953a93e3b7SToby Isaac 69963a93e3b7SToby Isaac An array that maps each point to its containing cell can be obtained with 69973a93e3b7SToby Isaac 699862a38674SMatthew G. Knepley $ const PetscSFNode *cells; 699962a38674SMatthew G. Knepley $ PetscInt nFound; 7000a6216909SToby Isaac $ const PetscInt *found; 700162a38674SMatthew G. Knepley $ 7002a6216909SToby Isaac $ PetscSFGetGraph(cellSF,NULL,&nFound,&found,&cells); 70033a93e3b7SToby Isaac 70043a93e3b7SToby 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 70053a93e3b7SToby Isaac the index of the cell in its rank's local numbering. 70063a93e3b7SToby Isaac 700762a38674SMatthew G. Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMPointLocationType 700861e3bb9bSMatthew G Knepley @*/ 700962a38674SMatthew G. Knepley PetscErrorCode DMLocatePoints(DM dm, Vec v, DMPointLocationType ltype, PetscSF *cellSF) 7010e87bb0d3SMatthew G Knepley { 7011735aa83eSMatthew G Knepley PetscErrorCode ierr; 7012735aa83eSMatthew G Knepley 7013e87bb0d3SMatthew G Knepley PetscFunctionBegin; 7014e87bb0d3SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7015e87bb0d3SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,2); 7016e0fc9d1bSMatthew G. Knepley PetscValidPointer(cellSF,4); 70173a93e3b7SToby Isaac if (*cellSF) { 70183a93e3b7SToby Isaac PetscMPIInt result; 70193a93e3b7SToby Isaac 7020e0fc9d1bSMatthew G. Knepley PetscValidHeaderSpecific(*cellSF,PETSCSF_CLASSID,4); 7021ffc4695bSBarry Smith ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)v),PetscObjectComm((PetscObject)*cellSF),&result);CHKERRMPI(ierr); 70223a93e3b7SToby 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"); 7023e0fc9d1bSMatthew G. Knepley } else { 70243a93e3b7SToby Isaac ierr = PetscSFCreate(PetscObjectComm((PetscObject)v),cellSF);CHKERRQ(ierr); 70253a93e3b7SToby Isaac } 7026b9d85ea2SLisandro Dalcin if (!dm->ops->locatepoints) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Point location not available for this DM"); 702747a35634SPatrick Farrell ierr = PetscLogEventBegin(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr); 702862a38674SMatthew G. Knepley ierr = (*dm->ops->locatepoints)(dm,v,ltype,*cellSF);CHKERRQ(ierr); 702947a35634SPatrick Farrell ierr = PetscLogEventEnd(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr); 7030e87bb0d3SMatthew G Knepley PetscFunctionReturn(0); 7031e87bb0d3SMatthew G Knepley } 703214f150ffSMatthew G. Knepley 7033f4d763aaSMatthew G. Knepley /*@ 7034f4d763aaSMatthew G. Knepley DMGetOutputDM - Retrieve the DM associated with the layout for output 7035f4d763aaSMatthew G. Knepley 70368f700142SStefano Zampini Collective on dm 70378f700142SStefano Zampini 7038f4d763aaSMatthew G. Knepley Input Parameter: 7039f4d763aaSMatthew G. Knepley . dm - The original DM 7040f4d763aaSMatthew G. Knepley 7041f4d763aaSMatthew G. Knepley Output Parameter: 7042f4d763aaSMatthew G. Knepley . odm - The DM which provides the layout for output 7043f4d763aaSMatthew G. Knepley 7044f4d763aaSMatthew G. Knepley Level: intermediate 7045f4d763aaSMatthew G. Knepley 7046e87a4003SBarry Smith .seealso: VecView(), DMGetGlobalSection() 7047f4d763aaSMatthew G. Knepley @*/ 704814f150ffSMatthew G. Knepley PetscErrorCode DMGetOutputDM(DM dm, DM *odm) 704914f150ffSMatthew G. Knepley { 7050c26acbdeSMatthew G. Knepley PetscSection section; 70512d4e4a49SMatthew G. Knepley PetscBool hasConstraints, ghasConstraints; 705214f150ffSMatthew G. Knepley PetscErrorCode ierr; 705314f150ffSMatthew G. Knepley 705414f150ffSMatthew G. Knepley PetscFunctionBegin; 705514f150ffSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 705614f150ffSMatthew G. Knepley PetscValidPointer(odm,2); 705792fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 7058c26acbdeSMatthew G. Knepley ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr); 7059ffc4695bSBarry Smith ierr = MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 70602d4e4a49SMatthew G. Knepley if (!ghasConstraints) { 7061c26acbdeSMatthew G. Knepley *odm = dm; 7062c26acbdeSMatthew G. Knepley PetscFunctionReturn(0); 7063c26acbdeSMatthew G. Knepley } 706414f150ffSMatthew G. Knepley if (!dm->dmBC) { 7065c26acbdeSMatthew G. Knepley PetscSection newSection, gsection; 706614f150ffSMatthew G. Knepley PetscSF sf; 706714f150ffSMatthew G. Knepley 706814f150ffSMatthew G. Knepley ierr = DMClone(dm, &dm->dmBC);CHKERRQ(ierr); 7069e5e52638SMatthew G. Knepley ierr = DMCopyDisc(dm, dm->dmBC);CHKERRQ(ierr); 707014f150ffSMatthew G. Knepley ierr = PetscSectionClone(section, &newSection);CHKERRQ(ierr); 707192fd8e1eSJed Brown ierr = DMSetLocalSection(dm->dmBC, newSection);CHKERRQ(ierr); 707214f150ffSMatthew G. Knepley ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr); 707314f150ffSMatthew G. Knepley ierr = DMGetPointSF(dm->dmBC, &sf);CHKERRQ(ierr); 707415b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr); 7075e87a4003SBarry Smith ierr = DMSetGlobalSection(dm->dmBC, gsection);CHKERRQ(ierr); 707614f150ffSMatthew G. Knepley ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr); 707714f150ffSMatthew G. Knepley } 707814f150ffSMatthew G. Knepley *odm = dm->dmBC; 707914f150ffSMatthew G. Knepley PetscFunctionReturn(0); 708014f150ffSMatthew G. Knepley } 7081f4d763aaSMatthew G. Knepley 7082f4d763aaSMatthew G. Knepley /*@ 7083cdb7a50dSMatthew G. Knepley DMGetOutputSequenceNumber - Retrieve the sequence number/value for output 7084f4d763aaSMatthew G. Knepley 7085f4d763aaSMatthew G. Knepley Input Parameter: 7086f4d763aaSMatthew G. Knepley . dm - The original DM 7087f4d763aaSMatthew G. Knepley 7088cdb7a50dSMatthew G. Knepley Output Parameters: 7089cdb7a50dSMatthew G. Knepley + num - The output sequence number 7090cdb7a50dSMatthew G. Knepley - val - The output sequence value 7091f4d763aaSMatthew G. Knepley 7092f4d763aaSMatthew G. Knepley Level: intermediate 7093f4d763aaSMatthew G. Knepley 7094f4d763aaSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 7095f4d763aaSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 7096f4d763aaSMatthew G. Knepley 7097f4d763aaSMatthew G. Knepley .seealso: VecView() 7098f4d763aaSMatthew G. Knepley @*/ 7099cdb7a50dSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val) 7100f4d763aaSMatthew G. Knepley { 7101f4d763aaSMatthew G. Knepley PetscFunctionBegin; 7102f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7103534a8f05SLisandro Dalcin if (num) {PetscValidIntPointer(num,2); *num = dm->outputSequenceNum;} 7104534a8f05SLisandro Dalcin if (val) {PetscValidRealPointer(val,3);*val = dm->outputSequenceVal;} 7105f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 7106f4d763aaSMatthew G. Knepley } 7107f4d763aaSMatthew G. Knepley 7108f4d763aaSMatthew G. Knepley /*@ 7109cdb7a50dSMatthew G. Knepley DMSetOutputSequenceNumber - Set the sequence number/value for output 7110f4d763aaSMatthew G. Knepley 7111f4d763aaSMatthew G. Knepley Input Parameters: 7112f4d763aaSMatthew G. Knepley + dm - The original DM 7113cdb7a50dSMatthew G. Knepley . num - The output sequence number 7114cdb7a50dSMatthew G. Knepley - val - The output sequence value 7115f4d763aaSMatthew G. Knepley 7116f4d763aaSMatthew G. Knepley Level: intermediate 7117f4d763aaSMatthew G. Knepley 7118f4d763aaSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 7119f4d763aaSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 7120f4d763aaSMatthew G. Knepley 7121f4d763aaSMatthew G. Knepley .seealso: VecView() 7122f4d763aaSMatthew G. Knepley @*/ 7123cdb7a50dSMatthew G. Knepley PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val) 7124f4d763aaSMatthew G. Knepley { 7125f4d763aaSMatthew G. Knepley PetscFunctionBegin; 7126f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7127f4d763aaSMatthew G. Knepley dm->outputSequenceNum = num; 7128cdb7a50dSMatthew G. Knepley dm->outputSequenceVal = val; 7129cdb7a50dSMatthew G. Knepley PetscFunctionReturn(0); 7130cdb7a50dSMatthew G. Knepley } 7131cdb7a50dSMatthew G. Knepley 7132cdb7a50dSMatthew G. Knepley /*@C 7133cdb7a50dSMatthew G. Knepley DMOutputSequenceLoad - Retrieve the sequence value from a Viewer 7134cdb7a50dSMatthew G. Knepley 7135cdb7a50dSMatthew G. Knepley Input Parameters: 7136cdb7a50dSMatthew G. Knepley + dm - The original DM 7137cdb7a50dSMatthew G. Knepley . name - The sequence name 7138cdb7a50dSMatthew G. Knepley - num - The output sequence number 7139cdb7a50dSMatthew G. Knepley 7140cdb7a50dSMatthew G. Knepley Output Parameter: 7141cdb7a50dSMatthew G. Knepley . val - The output sequence value 7142cdb7a50dSMatthew G. Knepley 7143cdb7a50dSMatthew G. Knepley Level: intermediate 7144cdb7a50dSMatthew G. Knepley 7145cdb7a50dSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 7146cdb7a50dSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 7147cdb7a50dSMatthew G. Knepley 7148cdb7a50dSMatthew G. Knepley .seealso: DMGetOutputSequenceNumber(), DMSetOutputSequenceNumber(), VecView() 7149cdb7a50dSMatthew G. Knepley @*/ 7150cdb7a50dSMatthew G. Knepley PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val) 7151cdb7a50dSMatthew G. Knepley { 7152cdb7a50dSMatthew G. Knepley PetscBool ishdf5; 7153cdb7a50dSMatthew G. Knepley PetscErrorCode ierr; 7154cdb7a50dSMatthew G. Knepley 7155cdb7a50dSMatthew G. Knepley PetscFunctionBegin; 7156cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7157cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 7158534a8f05SLisandro Dalcin PetscValidRealPointer(val,4); 7159cdb7a50dSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 7160cdb7a50dSMatthew G. Knepley if (ishdf5) { 7161cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 7162cdb7a50dSMatthew G. Knepley PetscScalar value; 7163cdb7a50dSMatthew G. Knepley 716439d25373SMatthew G. Knepley ierr = DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer);CHKERRQ(ierr); 71654aeb217fSMatthew G. Knepley *val = PetscRealPart(value); 7166cdb7a50dSMatthew G. Knepley #endif 7167cdb7a50dSMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()"); 7168f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 7169f4d763aaSMatthew G. Knepley } 71708e4ac7eaSMatthew G. Knepley 71718e4ac7eaSMatthew G. Knepley /*@ 71728e4ac7eaSMatthew G. Knepley DMGetUseNatural - Get the flag for creating a mapping to the natural order on distribution 71738e4ac7eaSMatthew G. Knepley 71748e4ac7eaSMatthew G. Knepley Not collective 71758e4ac7eaSMatthew G. Knepley 71768e4ac7eaSMatthew G. Knepley Input Parameter: 71778e4ac7eaSMatthew G. Knepley . dm - The DM 71788e4ac7eaSMatthew G. Knepley 71798e4ac7eaSMatthew G. Knepley Output Parameter: 71808e4ac7eaSMatthew G. Knepley . useNatural - The flag to build the mapping to a natural order during distribution 71818e4ac7eaSMatthew G. Knepley 71828e4ac7eaSMatthew G. Knepley Level: beginner 71838e4ac7eaSMatthew G. Knepley 71848e4ac7eaSMatthew G. Knepley .seealso: DMSetUseNatural(), DMCreate() 71858e4ac7eaSMatthew G. Knepley @*/ 71868e4ac7eaSMatthew G. Knepley PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural) 71878e4ac7eaSMatthew G. Knepley { 71888e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 71898e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7190534a8f05SLisandro Dalcin PetscValidBoolPointer(useNatural, 2); 71918e4ac7eaSMatthew G. Knepley *useNatural = dm->useNatural; 71928e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 71938e4ac7eaSMatthew G. Knepley } 71948e4ac7eaSMatthew G. Knepley 71958e4ac7eaSMatthew G. Knepley /*@ 71965d3b26e6SMatthew G. Knepley DMSetUseNatural - Set the flag for creating a mapping to the natural order after distribution 71978e4ac7eaSMatthew G. Knepley 71988e4ac7eaSMatthew G. Knepley Collective on dm 71998e4ac7eaSMatthew G. Knepley 72008e4ac7eaSMatthew G. Knepley Input Parameters: 72018e4ac7eaSMatthew G. Knepley + dm - The DM 72028e4ac7eaSMatthew G. Knepley - useNatural - The flag to build the mapping to a natural order during distribution 72038e4ac7eaSMatthew G. Knepley 72045d3b26e6SMatthew G. Knepley Note: This also causes the map to be build after DMCreateSubDM() and DMCreateSuperDM() 72055d3b26e6SMatthew G. Knepley 72068e4ac7eaSMatthew G. Knepley Level: beginner 72078e4ac7eaSMatthew G. Knepley 72085d3b26e6SMatthew G. Knepley .seealso: DMGetUseNatural(), DMCreate(), DMPlexDistribute(), DMCreateSubDM(), DMCreateSuperDM() 72098e4ac7eaSMatthew G. Knepley @*/ 72108e4ac7eaSMatthew G. Knepley PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural) 72118e4ac7eaSMatthew G. Knepley { 72128e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 72138e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72148833efb5SBlaise Bourdin PetscValidLogicalCollectiveBool(dm, useNatural, 2); 72158e4ac7eaSMatthew G. Knepley dm->useNatural = useNatural; 72168e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 72178e4ac7eaSMatthew G. Knepley } 7218c58f1c22SToby Isaac 7219c58f1c22SToby Isaac 7220c58f1c22SToby Isaac /*@C 7221c58f1c22SToby Isaac DMCreateLabel - Create a label of the given name if it does not already exist 7222c58f1c22SToby Isaac 7223c58f1c22SToby Isaac Not Collective 7224c58f1c22SToby Isaac 7225c58f1c22SToby Isaac Input Parameters: 7226c58f1c22SToby Isaac + dm - The DM object 7227c58f1c22SToby Isaac - name - The label name 7228c58f1c22SToby Isaac 7229c58f1c22SToby Isaac Level: intermediate 7230c58f1c22SToby Isaac 7231c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7232c58f1c22SToby Isaac @*/ 7233c58f1c22SToby Isaac PetscErrorCode DMCreateLabel(DM dm, const char name[]) 7234c58f1c22SToby Isaac { 72355d80c0bfSVaclav Hapla PetscBool flg; 72365d80c0bfSVaclav Hapla DMLabel label; 7237c58f1c22SToby Isaac PetscErrorCode ierr; 7238c58f1c22SToby Isaac 7239c58f1c22SToby Isaac PetscFunctionBegin; 7240c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7241c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 72425d80c0bfSVaclav Hapla ierr = DMHasLabel(dm, name, &flg);CHKERRQ(ierr); 7243c58f1c22SToby Isaac if (!flg) { 72445d80c0bfSVaclav Hapla ierr = DMLabelCreate(PETSC_COMM_SELF, name, &label);CHKERRQ(ierr); 72455d80c0bfSVaclav Hapla ierr = DMAddLabel(dm, label);CHKERRQ(ierr); 72465d80c0bfSVaclav Hapla ierr = DMLabelDestroy(&label);CHKERRQ(ierr); 7247c58f1c22SToby Isaac } 7248c58f1c22SToby Isaac PetscFunctionReturn(0); 7249c58f1c22SToby Isaac } 7250c58f1c22SToby Isaac 7251c58f1c22SToby Isaac /*@C 72520fdc7489SMatthew Knepley DMCreateLabelAtIndex - Create a label of the given name at the iven index. If it already exists, move it to this index. 72530fdc7489SMatthew Knepley 72540fdc7489SMatthew Knepley Not Collective 72550fdc7489SMatthew Knepley 72560fdc7489SMatthew Knepley Input Parameters: 72570fdc7489SMatthew Knepley + dm - The DM object 72580fdc7489SMatthew Knepley . l - The index for the label 72590fdc7489SMatthew Knepley - name - The label name 72600fdc7489SMatthew Knepley 72610fdc7489SMatthew Knepley Level: intermediate 72620fdc7489SMatthew Knepley 72630fdc7489SMatthew Knepley .seealso: DMCreateLabel(), DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 72640fdc7489SMatthew Knepley @*/ 72650fdc7489SMatthew Knepley PetscErrorCode DMCreateLabelAtIndex(DM dm, PetscInt l, const char name[]) 72660fdc7489SMatthew Knepley { 72670fdc7489SMatthew Knepley DMLabelLink orig, prev = NULL; 72680fdc7489SMatthew Knepley DMLabel label; 72690fdc7489SMatthew Knepley PetscInt Nl, m; 72700fdc7489SMatthew Knepley PetscBool flg, match; 72710fdc7489SMatthew Knepley const char *lname; 72720fdc7489SMatthew Knepley PetscErrorCode ierr; 72730fdc7489SMatthew Knepley 72740fdc7489SMatthew Knepley PetscFunctionBegin; 72750fdc7489SMatthew Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72760fdc7489SMatthew Knepley PetscValidCharPointer(name, 2); 72770fdc7489SMatthew Knepley ierr = DMHasLabel(dm, name, &flg);CHKERRQ(ierr); 72780fdc7489SMatthew Knepley if (!flg) { 72790fdc7489SMatthew Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, name, &label);CHKERRQ(ierr); 72800fdc7489SMatthew Knepley ierr = DMAddLabel(dm, label);CHKERRQ(ierr); 72810fdc7489SMatthew Knepley ierr = DMLabelDestroy(&label);CHKERRQ(ierr); 72820fdc7489SMatthew Knepley } 72830fdc7489SMatthew Knepley ierr = DMGetNumLabels(dm, &Nl);CHKERRQ(ierr); 72840fdc7489SMatthew Knepley if (l >= Nl) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label index %D must be in [0, %D)", l, Nl); 72850fdc7489SMatthew Knepley for (m = 0, orig = dm->labels; m < Nl; ++m, prev = orig, orig = orig->next) { 72860fdc7489SMatthew Knepley ierr = PetscObjectGetName((PetscObject) orig->label, &lname);CHKERRQ(ierr); 72870fdc7489SMatthew Knepley ierr = PetscStrcmp(name, lname, &match);CHKERRQ(ierr); 72880fdc7489SMatthew Knepley if (match) break; 72890fdc7489SMatthew Knepley } 72900fdc7489SMatthew Knepley if (m == l) PetscFunctionReturn(0); 72910fdc7489SMatthew Knepley if (!m) dm->labels = orig->next; 72920fdc7489SMatthew Knepley else prev->next = orig->next; 72930fdc7489SMatthew Knepley if (!l) { 72940fdc7489SMatthew Knepley orig->next = dm->labels; 72950fdc7489SMatthew Knepley dm->labels = orig; 72960fdc7489SMatthew Knepley } else { 72970fdc7489SMatthew Knepley for (m = 0, prev = dm->labels; m < l-1; ++m, prev = prev->next); 72980fdc7489SMatthew Knepley orig->next = prev->next; 72990fdc7489SMatthew Knepley prev->next = orig; 73000fdc7489SMatthew Knepley } 73010fdc7489SMatthew Knepley PetscFunctionReturn(0); 73020fdc7489SMatthew Knepley } 73030fdc7489SMatthew Knepley 73040fdc7489SMatthew Knepley /*@C 7305c58f1c22SToby Isaac DMGetLabelValue - Get the value in a Sieve Label for the given point, with 0 as the default 7306c58f1c22SToby Isaac 7307c58f1c22SToby Isaac Not Collective 7308c58f1c22SToby Isaac 7309c58f1c22SToby Isaac Input Parameters: 7310c58f1c22SToby Isaac + dm - The DM object 7311c58f1c22SToby Isaac . name - The label name 7312c58f1c22SToby Isaac - point - The mesh point 7313c58f1c22SToby Isaac 7314c58f1c22SToby Isaac Output Parameter: 7315c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label 7316c58f1c22SToby Isaac 7317c58f1c22SToby Isaac Level: beginner 7318c58f1c22SToby Isaac 7319c58f1c22SToby Isaac .seealso: DMLabelGetValue(), DMSetLabelValue(), DMGetStratumIS() 7320c58f1c22SToby Isaac @*/ 7321c58f1c22SToby Isaac PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value) 7322c58f1c22SToby Isaac { 7323c58f1c22SToby Isaac DMLabel label; 7324c58f1c22SToby Isaac PetscErrorCode ierr; 7325c58f1c22SToby Isaac 7326c58f1c22SToby Isaac PetscFunctionBegin; 7327c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7328c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7329c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 733013903a91SSatish Balay if (!label) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name); 7331c58f1c22SToby Isaac ierr = DMLabelGetValue(label, point, value);CHKERRQ(ierr); 7332c58f1c22SToby Isaac PetscFunctionReturn(0); 7333c58f1c22SToby Isaac } 7334c58f1c22SToby Isaac 7335c58f1c22SToby Isaac /*@C 7336c58f1c22SToby Isaac DMSetLabelValue - Add a point to a Sieve Label with given value 7337c58f1c22SToby Isaac 7338c58f1c22SToby Isaac Not Collective 7339c58f1c22SToby Isaac 7340c58f1c22SToby Isaac Input Parameters: 7341c58f1c22SToby Isaac + dm - The DM object 7342c58f1c22SToby Isaac . name - The label name 7343c58f1c22SToby Isaac . point - The mesh point 7344c58f1c22SToby Isaac - value - The label value for this point 7345c58f1c22SToby Isaac 7346c58f1c22SToby Isaac Output Parameter: 7347c58f1c22SToby Isaac 7348c58f1c22SToby Isaac Level: beginner 7349c58f1c22SToby Isaac 7350c58f1c22SToby Isaac .seealso: DMLabelSetValue(), DMGetStratumIS(), DMClearLabelValue() 7351c58f1c22SToby Isaac @*/ 7352c58f1c22SToby Isaac PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 7353c58f1c22SToby Isaac { 7354c58f1c22SToby Isaac DMLabel label; 7355c58f1c22SToby Isaac PetscErrorCode ierr; 7356c58f1c22SToby Isaac 7357c58f1c22SToby Isaac PetscFunctionBegin; 7358c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7359c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7360c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7361c58f1c22SToby Isaac if (!label) { 7362c58f1c22SToby Isaac ierr = DMCreateLabel(dm, name);CHKERRQ(ierr); 7363c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7364c58f1c22SToby Isaac } 7365c58f1c22SToby Isaac ierr = DMLabelSetValue(label, point, value);CHKERRQ(ierr); 7366c58f1c22SToby Isaac PetscFunctionReturn(0); 7367c58f1c22SToby Isaac } 7368c58f1c22SToby Isaac 7369c58f1c22SToby Isaac /*@C 7370c58f1c22SToby Isaac DMClearLabelValue - Remove a point from a Sieve Label with given value 7371c58f1c22SToby Isaac 7372c58f1c22SToby Isaac Not Collective 7373c58f1c22SToby Isaac 7374c58f1c22SToby Isaac Input Parameters: 7375c58f1c22SToby Isaac + dm - The DM object 7376c58f1c22SToby Isaac . name - The label name 7377c58f1c22SToby Isaac . point - The mesh point 7378c58f1c22SToby Isaac - value - The label value for this point 7379c58f1c22SToby Isaac 7380c58f1c22SToby Isaac Output Parameter: 7381c58f1c22SToby Isaac 7382c58f1c22SToby Isaac Level: beginner 7383c58f1c22SToby Isaac 7384c58f1c22SToby Isaac .seealso: DMLabelClearValue(), DMSetLabelValue(), DMGetStratumIS() 7385c58f1c22SToby Isaac @*/ 7386c58f1c22SToby Isaac PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 7387c58f1c22SToby Isaac { 7388c58f1c22SToby Isaac DMLabel label; 7389c58f1c22SToby Isaac PetscErrorCode ierr; 7390c58f1c22SToby Isaac 7391c58f1c22SToby Isaac PetscFunctionBegin; 7392c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7393c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7394c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7395c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7396c58f1c22SToby Isaac ierr = DMLabelClearValue(label, point, value);CHKERRQ(ierr); 7397c58f1c22SToby Isaac PetscFunctionReturn(0); 7398c58f1c22SToby Isaac } 7399c58f1c22SToby Isaac 7400c58f1c22SToby Isaac /*@C 7401c58f1c22SToby Isaac DMGetLabelSize - Get the number of different integer ids in a Label 7402c58f1c22SToby Isaac 7403c58f1c22SToby Isaac Not Collective 7404c58f1c22SToby Isaac 7405c58f1c22SToby Isaac Input Parameters: 7406c58f1c22SToby Isaac + dm - The DM object 7407c58f1c22SToby Isaac - name - The label name 7408c58f1c22SToby Isaac 7409c58f1c22SToby Isaac Output Parameter: 7410c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist 7411c58f1c22SToby Isaac 7412c58f1c22SToby Isaac Level: beginner 7413c58f1c22SToby Isaac 7414df813f42SMatthew G. Knepley .seealso: DMLabelGetNumValues(), DMSetLabelValue() 7415c58f1c22SToby Isaac @*/ 7416c58f1c22SToby Isaac PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size) 7417c58f1c22SToby Isaac { 7418c58f1c22SToby Isaac DMLabel label; 7419c58f1c22SToby Isaac PetscErrorCode ierr; 7420c58f1c22SToby Isaac 7421c58f1c22SToby Isaac PetscFunctionBegin; 7422c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7423c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7424534a8f05SLisandro Dalcin PetscValidIntPointer(size, 3); 7425c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7426c58f1c22SToby Isaac *size = 0; 7427c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7428c58f1c22SToby Isaac ierr = DMLabelGetNumValues(label, size);CHKERRQ(ierr); 7429c58f1c22SToby Isaac PetscFunctionReturn(0); 7430c58f1c22SToby Isaac } 7431c58f1c22SToby Isaac 7432c58f1c22SToby Isaac /*@C 7433c58f1c22SToby Isaac DMGetLabelIdIS - Get the integer ids in a label 7434c58f1c22SToby Isaac 7435c58f1c22SToby Isaac Not Collective 7436c58f1c22SToby Isaac 7437c58f1c22SToby Isaac Input Parameters: 7438c58f1c22SToby Isaac + mesh - The DM object 7439c58f1c22SToby Isaac - name - The label name 7440c58f1c22SToby Isaac 7441c58f1c22SToby Isaac Output Parameter: 7442c58f1c22SToby Isaac . ids - The integer ids, or NULL if the label does not exist 7443c58f1c22SToby Isaac 7444c58f1c22SToby Isaac Level: beginner 7445c58f1c22SToby Isaac 7446c58f1c22SToby Isaac .seealso: DMLabelGetValueIS(), DMGetLabelSize() 7447c58f1c22SToby Isaac @*/ 7448c58f1c22SToby Isaac PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids) 7449c58f1c22SToby Isaac { 7450c58f1c22SToby Isaac DMLabel label; 7451c58f1c22SToby Isaac PetscErrorCode ierr; 7452c58f1c22SToby Isaac 7453c58f1c22SToby Isaac PetscFunctionBegin; 7454c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7455c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7456c58f1c22SToby Isaac PetscValidPointer(ids, 3); 7457c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7458c58f1c22SToby Isaac *ids = NULL; 7459dab2e251SBlaise Bourdin if (label) { 7460c58f1c22SToby Isaac ierr = DMLabelGetValueIS(label, ids);CHKERRQ(ierr); 7461dab2e251SBlaise Bourdin } else { 7462dab2e251SBlaise Bourdin /* returning an empty IS */ 7463dab2e251SBlaise Bourdin ierr = ISCreateGeneral(PETSC_COMM_SELF,0,NULL,PETSC_USE_POINTER,ids);CHKERRQ(ierr); 7464dab2e251SBlaise Bourdin } 7465c58f1c22SToby Isaac PetscFunctionReturn(0); 7466c58f1c22SToby Isaac } 7467c58f1c22SToby Isaac 7468c58f1c22SToby Isaac /*@C 7469c58f1c22SToby Isaac DMGetStratumSize - Get the number of points in a label stratum 7470c58f1c22SToby Isaac 7471c58f1c22SToby Isaac Not Collective 7472c58f1c22SToby Isaac 7473c58f1c22SToby Isaac Input Parameters: 7474c58f1c22SToby Isaac + dm - The DM object 7475c58f1c22SToby Isaac . name - The label name 7476c58f1c22SToby Isaac - value - The stratum value 7477c58f1c22SToby Isaac 7478c58f1c22SToby Isaac Output Parameter: 7479c58f1c22SToby Isaac . size - The stratum size 7480c58f1c22SToby Isaac 7481c58f1c22SToby Isaac Level: beginner 7482c58f1c22SToby Isaac 7483c58f1c22SToby Isaac .seealso: DMLabelGetStratumSize(), DMGetLabelSize(), DMGetLabelIds() 7484c58f1c22SToby Isaac @*/ 7485c58f1c22SToby Isaac PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size) 7486c58f1c22SToby Isaac { 7487c58f1c22SToby Isaac DMLabel label; 7488c58f1c22SToby Isaac PetscErrorCode ierr; 7489c58f1c22SToby Isaac 7490c58f1c22SToby Isaac PetscFunctionBegin; 7491c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7492c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7493534a8f05SLisandro Dalcin PetscValidIntPointer(size, 4); 7494c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7495c58f1c22SToby Isaac *size = 0; 7496c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7497c58f1c22SToby Isaac ierr = DMLabelGetStratumSize(label, value, size);CHKERRQ(ierr); 7498c58f1c22SToby Isaac PetscFunctionReturn(0); 7499c58f1c22SToby Isaac } 7500c58f1c22SToby Isaac 7501c58f1c22SToby Isaac /*@C 7502c58f1c22SToby Isaac DMGetStratumIS - Get the points in a label stratum 7503c58f1c22SToby Isaac 7504c58f1c22SToby Isaac Not Collective 7505c58f1c22SToby Isaac 7506c58f1c22SToby Isaac Input Parameters: 7507c58f1c22SToby Isaac + dm - The DM object 7508c58f1c22SToby Isaac . name - The label name 7509c58f1c22SToby Isaac - value - The stratum value 7510c58f1c22SToby Isaac 7511c58f1c22SToby Isaac Output Parameter: 7512c58f1c22SToby Isaac . points - The stratum points, or NULL if the label does not exist or does not have that value 7513c58f1c22SToby Isaac 7514c58f1c22SToby Isaac Level: beginner 7515c58f1c22SToby Isaac 7516c58f1c22SToby Isaac .seealso: DMLabelGetStratumIS(), DMGetStratumSize() 7517c58f1c22SToby Isaac @*/ 7518c58f1c22SToby Isaac PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points) 7519c58f1c22SToby Isaac { 7520c58f1c22SToby Isaac DMLabel label; 7521c58f1c22SToby Isaac PetscErrorCode ierr; 7522c58f1c22SToby Isaac 7523c58f1c22SToby Isaac PetscFunctionBegin; 7524c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7525c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7526c58f1c22SToby Isaac PetscValidPointer(points, 4); 7527c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7528c58f1c22SToby Isaac *points = NULL; 7529c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7530c58f1c22SToby Isaac ierr = DMLabelGetStratumIS(label, value, points);CHKERRQ(ierr); 7531c58f1c22SToby Isaac PetscFunctionReturn(0); 7532c58f1c22SToby Isaac } 7533c58f1c22SToby Isaac 75344de306b1SToby Isaac /*@C 75359044fa66SMatthew G. Knepley DMSetStratumIS - Set the points in a label stratum 75364de306b1SToby Isaac 75374de306b1SToby Isaac Not Collective 75384de306b1SToby Isaac 75394de306b1SToby Isaac Input Parameters: 75404de306b1SToby Isaac + dm - The DM object 75414de306b1SToby Isaac . name - The label name 75424de306b1SToby Isaac . value - The stratum value 75434de306b1SToby Isaac - points - The stratum points 75444de306b1SToby Isaac 75454de306b1SToby Isaac Level: beginner 75464de306b1SToby Isaac 75474de306b1SToby Isaac .seealso: DMLabelSetStratumIS(), DMGetStratumSize() 75484de306b1SToby Isaac @*/ 75494de306b1SToby Isaac PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points) 75504de306b1SToby Isaac { 75514de306b1SToby Isaac DMLabel label; 75524de306b1SToby Isaac PetscErrorCode ierr; 75534de306b1SToby Isaac 75544de306b1SToby Isaac PetscFunctionBegin; 75554de306b1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 75564de306b1SToby Isaac PetscValidCharPointer(name, 2); 75574de306b1SToby Isaac PetscValidPointer(points, 4); 75584de306b1SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 75594de306b1SToby Isaac if (!label) PetscFunctionReturn(0); 75604de306b1SToby Isaac ierr = DMLabelSetStratumIS(label, value, points);CHKERRQ(ierr); 75614de306b1SToby Isaac PetscFunctionReturn(0); 75624de306b1SToby Isaac } 75634de306b1SToby Isaac 7564c58f1c22SToby Isaac /*@C 7565c58f1c22SToby Isaac DMClearLabelStratum - Remove all points from a stratum from a Sieve Label 7566c58f1c22SToby Isaac 7567c58f1c22SToby Isaac Not Collective 7568c58f1c22SToby Isaac 7569c58f1c22SToby Isaac Input Parameters: 7570c58f1c22SToby Isaac + dm - The DM object 7571c58f1c22SToby Isaac . name - The label name 7572c58f1c22SToby Isaac - value - The label value for this point 7573c58f1c22SToby Isaac 7574c58f1c22SToby Isaac Output Parameter: 7575c58f1c22SToby Isaac 7576c58f1c22SToby Isaac Level: beginner 7577c58f1c22SToby Isaac 7578c58f1c22SToby Isaac .seealso: DMLabelClearStratum(), DMSetLabelValue(), DMGetStratumIS(), DMClearLabelValue() 7579c58f1c22SToby Isaac @*/ 7580c58f1c22SToby Isaac PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value) 7581c58f1c22SToby Isaac { 7582c58f1c22SToby Isaac DMLabel label; 7583c58f1c22SToby Isaac PetscErrorCode ierr; 7584c58f1c22SToby Isaac 7585c58f1c22SToby Isaac PetscFunctionBegin; 7586c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7587c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7588c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7589c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7590c58f1c22SToby Isaac ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr); 7591c58f1c22SToby Isaac PetscFunctionReturn(0); 7592c58f1c22SToby Isaac } 7593c58f1c22SToby Isaac 7594c58f1c22SToby Isaac /*@ 7595c58f1c22SToby Isaac DMGetNumLabels - Return the number of labels defined by the mesh 7596c58f1c22SToby Isaac 7597c58f1c22SToby Isaac Not Collective 7598c58f1c22SToby Isaac 7599c58f1c22SToby Isaac Input Parameter: 7600c58f1c22SToby Isaac . dm - The DM object 7601c58f1c22SToby Isaac 7602c58f1c22SToby Isaac Output Parameter: 7603c58f1c22SToby Isaac . numLabels - the number of Labels 7604c58f1c22SToby Isaac 7605c58f1c22SToby Isaac Level: intermediate 7606c58f1c22SToby Isaac 7607c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7608c58f1c22SToby Isaac @*/ 7609c58f1c22SToby Isaac PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels) 7610c58f1c22SToby Isaac { 76115d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7612c58f1c22SToby Isaac PetscInt n = 0; 7613c58f1c22SToby Isaac 7614c58f1c22SToby Isaac PetscFunctionBegin; 7615c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7616534a8f05SLisandro Dalcin PetscValidIntPointer(numLabels, 2); 7617c58f1c22SToby Isaac while (next) {++n; next = next->next;} 7618c58f1c22SToby Isaac *numLabels = n; 7619c58f1c22SToby Isaac PetscFunctionReturn(0); 7620c58f1c22SToby Isaac } 7621c58f1c22SToby Isaac 7622c58f1c22SToby Isaac /*@C 7623c58f1c22SToby Isaac DMGetLabelName - Return the name of nth label 7624c58f1c22SToby Isaac 7625c58f1c22SToby Isaac Not Collective 7626c58f1c22SToby Isaac 7627c58f1c22SToby Isaac Input Parameters: 7628c58f1c22SToby Isaac + dm - The DM object 7629c58f1c22SToby Isaac - n - the label number 7630c58f1c22SToby Isaac 7631c58f1c22SToby Isaac Output Parameter: 7632c58f1c22SToby Isaac . name - the label name 7633c58f1c22SToby Isaac 7634c58f1c22SToby Isaac Level: intermediate 7635c58f1c22SToby Isaac 7636c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7637c58f1c22SToby Isaac @*/ 7638c58f1c22SToby Isaac PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name) 7639c58f1c22SToby Isaac { 76405d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7641c58f1c22SToby Isaac PetscInt l = 0; 7642d67d17b1SMatthew G. Knepley PetscErrorCode ierr; 7643c58f1c22SToby Isaac 7644c58f1c22SToby Isaac PetscFunctionBegin; 7645c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7646c58f1c22SToby Isaac PetscValidPointer(name, 3); 7647c58f1c22SToby Isaac while (next) { 7648c58f1c22SToby Isaac if (l == n) { 7649d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, name);CHKERRQ(ierr); 7650c58f1c22SToby Isaac PetscFunctionReturn(0); 7651c58f1c22SToby Isaac } 7652c58f1c22SToby Isaac ++l; 7653c58f1c22SToby Isaac next = next->next; 7654c58f1c22SToby Isaac } 7655c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n); 7656c58f1c22SToby Isaac } 7657c58f1c22SToby Isaac 7658c58f1c22SToby Isaac /*@C 7659c58f1c22SToby Isaac DMHasLabel - Determine whether the mesh has a label of a given name 7660c58f1c22SToby Isaac 7661c58f1c22SToby Isaac Not Collective 7662c58f1c22SToby Isaac 7663c58f1c22SToby Isaac Input Parameters: 7664c58f1c22SToby Isaac + dm - The DM object 7665c58f1c22SToby Isaac - name - The label name 7666c58f1c22SToby Isaac 7667c58f1c22SToby Isaac Output Parameter: 7668c58f1c22SToby Isaac . hasLabel - PETSC_TRUE if the label is present 7669c58f1c22SToby Isaac 7670c58f1c22SToby Isaac Level: intermediate 7671c58f1c22SToby Isaac 7672c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7673c58f1c22SToby Isaac @*/ 7674c58f1c22SToby Isaac PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel) 7675c58f1c22SToby Isaac { 76765d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7677d67d17b1SMatthew G. Knepley const char *lname; 7678c58f1c22SToby Isaac PetscErrorCode ierr; 7679c58f1c22SToby Isaac 7680c58f1c22SToby Isaac PetscFunctionBegin; 7681c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7682c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7683534a8f05SLisandro Dalcin PetscValidBoolPointer(hasLabel, 3); 7684c58f1c22SToby Isaac *hasLabel = PETSC_FALSE; 7685c58f1c22SToby Isaac while (next) { 7686d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 7687d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, hasLabel);CHKERRQ(ierr); 7688c58f1c22SToby Isaac if (*hasLabel) break; 7689c58f1c22SToby Isaac next = next->next; 7690c58f1c22SToby Isaac } 7691c58f1c22SToby Isaac PetscFunctionReturn(0); 7692c58f1c22SToby Isaac } 7693c58f1c22SToby Isaac 7694c58f1c22SToby Isaac /*@C 7695c58f1c22SToby Isaac DMGetLabel - Return the label of a given name, or NULL 7696c58f1c22SToby Isaac 7697c58f1c22SToby Isaac Not Collective 7698c58f1c22SToby Isaac 7699c58f1c22SToby Isaac Input Parameters: 7700c58f1c22SToby Isaac + dm - The DM object 7701c58f1c22SToby Isaac - name - The label name 7702c58f1c22SToby Isaac 7703c58f1c22SToby Isaac Output Parameter: 7704c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent 7705c58f1c22SToby Isaac 77066d7c9049SMatthew G. Knepley Note: Some of the default labels in a DMPlex will be 77076d7c9049SMatthew G. Knepley $ "depth" - Holds the depth (co-dimension) of each mesh point 77086d7c9049SMatthew G. Knepley $ "celltype" - Holds the topological type of each cell 77096d7c9049SMatthew G. Knepley $ "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 77106d7c9049SMatthew G. Knepley $ "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 77116d7c9049SMatthew G. Knepley $ "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 77126d7c9049SMatthew G. Knepley $ "Vertex Sets" - Mirrors the vertex sets defined by GMsh 77136d7c9049SMatthew G. Knepley 7714c58f1c22SToby Isaac Level: intermediate 7715c58f1c22SToby Isaac 77166d7c9049SMatthew G. Knepley .seealso: DMCreateLabel(), DMHasLabel(), DMPlexGetDepthLabel(), DMPlexGetCellType() 7717c58f1c22SToby Isaac @*/ 7718c58f1c22SToby Isaac PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label) 7719c58f1c22SToby Isaac { 77205d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7721c58f1c22SToby Isaac PetscBool hasLabel; 7722d67d17b1SMatthew G. Knepley const char *lname; 7723c58f1c22SToby Isaac PetscErrorCode ierr; 7724c58f1c22SToby Isaac 7725c58f1c22SToby Isaac PetscFunctionBegin; 7726c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7727c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7728c58f1c22SToby Isaac PetscValidPointer(label, 3); 7729c58f1c22SToby Isaac *label = NULL; 7730c58f1c22SToby Isaac while (next) { 7731d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 7732d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr); 7733c58f1c22SToby Isaac if (hasLabel) { 7734c58f1c22SToby Isaac *label = next->label; 7735c58f1c22SToby Isaac break; 7736c58f1c22SToby Isaac } 7737c58f1c22SToby Isaac next = next->next; 7738c58f1c22SToby Isaac } 7739c58f1c22SToby Isaac PetscFunctionReturn(0); 7740c58f1c22SToby Isaac } 7741c58f1c22SToby Isaac 7742c58f1c22SToby Isaac /*@C 7743c58f1c22SToby Isaac DMGetLabelByNum - Return the nth label 7744c58f1c22SToby Isaac 7745c58f1c22SToby Isaac Not Collective 7746c58f1c22SToby Isaac 7747c58f1c22SToby Isaac Input Parameters: 7748c58f1c22SToby Isaac + dm - The DM object 7749c58f1c22SToby Isaac - n - the label number 7750c58f1c22SToby Isaac 7751c58f1c22SToby Isaac Output Parameter: 7752c58f1c22SToby Isaac . label - the label 7753c58f1c22SToby Isaac 7754c58f1c22SToby Isaac Level: intermediate 7755c58f1c22SToby Isaac 7756c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7757c58f1c22SToby Isaac @*/ 7758c58f1c22SToby Isaac PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label) 7759c58f1c22SToby Isaac { 77605d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7761c58f1c22SToby Isaac PetscInt l = 0; 7762c58f1c22SToby Isaac 7763c58f1c22SToby Isaac PetscFunctionBegin; 7764c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7765c58f1c22SToby Isaac PetscValidPointer(label, 3); 7766c58f1c22SToby Isaac while (next) { 7767c58f1c22SToby Isaac if (l == n) { 7768c58f1c22SToby Isaac *label = next->label; 7769c58f1c22SToby Isaac PetscFunctionReturn(0); 7770c58f1c22SToby Isaac } 7771c58f1c22SToby Isaac ++l; 7772c58f1c22SToby Isaac next = next->next; 7773c58f1c22SToby Isaac } 7774c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n); 7775c58f1c22SToby Isaac } 7776c58f1c22SToby Isaac 7777c58f1c22SToby Isaac /*@C 7778c58f1c22SToby Isaac DMAddLabel - Add the label to this mesh 7779c58f1c22SToby Isaac 7780c58f1c22SToby Isaac Not Collective 7781c58f1c22SToby Isaac 7782c58f1c22SToby Isaac Input Parameters: 7783c58f1c22SToby Isaac + dm - The DM object 7784c58f1c22SToby Isaac - label - The DMLabel 7785c58f1c22SToby Isaac 7786c58f1c22SToby Isaac Level: developer 7787c58f1c22SToby Isaac 7788c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7789c58f1c22SToby Isaac @*/ 7790c58f1c22SToby Isaac PetscErrorCode DMAddLabel(DM dm, DMLabel label) 7791c58f1c22SToby Isaac { 77925d80c0bfSVaclav Hapla DMLabelLink l, *p, tmpLabel; 7793c58f1c22SToby Isaac PetscBool hasLabel; 7794d67d17b1SMatthew G. Knepley const char *lname; 77955d80c0bfSVaclav Hapla PetscBool flg; 7796c58f1c22SToby Isaac PetscErrorCode ierr; 7797c58f1c22SToby Isaac 7798c58f1c22SToby Isaac PetscFunctionBegin; 7799c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7800d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 7801d67d17b1SMatthew G. Knepley ierr = DMHasLabel(dm, lname, &hasLabel);CHKERRQ(ierr); 7802d67d17b1SMatthew G. Knepley if (hasLabel) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname); 7803c58f1c22SToby Isaac ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr); 7804c58f1c22SToby Isaac tmpLabel->label = label; 7805c58f1c22SToby Isaac tmpLabel->output = PETSC_TRUE; 78065d80c0bfSVaclav Hapla for (p=&dm->labels; (l=*p); p=&l->next) {} 78075d80c0bfSVaclav Hapla *p = tmpLabel; 780808f633c4SVaclav Hapla ierr = PetscObjectReference((PetscObject)label);CHKERRQ(ierr); 78095d80c0bfSVaclav Hapla ierr = PetscStrcmp(lname, "depth", &flg);CHKERRQ(ierr); 78105d80c0bfSVaclav Hapla if (flg) dm->depthLabel = label; 7811ba2698f1SMatthew G. Knepley ierr = PetscStrcmp(lname, "celltype", &flg);CHKERRQ(ierr); 7812ba2698f1SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 7813c58f1c22SToby Isaac PetscFunctionReturn(0); 7814c58f1c22SToby Isaac } 7815c58f1c22SToby Isaac 7816c58f1c22SToby Isaac /*@C 7817e5472504SVaclav Hapla DMRemoveLabel - Remove the label given by name from this mesh 7818c58f1c22SToby Isaac 7819c58f1c22SToby Isaac Not Collective 7820c58f1c22SToby Isaac 7821c58f1c22SToby Isaac Input Parameters: 7822c58f1c22SToby Isaac + dm - The DM object 7823c58f1c22SToby Isaac - name - The label name 7824c58f1c22SToby Isaac 7825c58f1c22SToby Isaac Output Parameter: 7826c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent 7827c58f1c22SToby Isaac 7828c58f1c22SToby Isaac Level: developer 7829c58f1c22SToby Isaac 7830e5472504SVaclav Hapla Notes: 7831e5472504SVaclav Hapla DMRemoveLabel(dm,name,NULL) removes the label from dm and calls 7832e5472504SVaclav Hapla DMLabelDestroy() on the label. 7833e5472504SVaclav Hapla 7834e5472504SVaclav Hapla DMRemoveLabel(dm,name,&label) removes the label from dm, but it DOES NOT 7835e5472504SVaclav Hapla call DMLabelDestroy(). Instead, the label is returned and the user is 7836e5472504SVaclav Hapla responsible of calling DMLabelDestroy() at some point. 7837e5472504SVaclav Hapla 7838e5472504SVaclav Hapla .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabel(), DMGetLabelValue(), DMSetLabelValue(), DMLabelDestroy(), DMRemoveLabelBySelf() 7839c58f1c22SToby Isaac @*/ 7840c58f1c22SToby Isaac PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label) 7841c58f1c22SToby Isaac { 784295d578d6SVaclav Hapla DMLabelLink link, *pnext; 7843c58f1c22SToby Isaac PetscBool hasLabel; 7844d67d17b1SMatthew G. Knepley const char *lname; 7845c58f1c22SToby Isaac PetscErrorCode ierr; 7846c58f1c22SToby Isaac 7847c58f1c22SToby Isaac PetscFunctionBegin; 7848c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7849e5472504SVaclav Hapla PetscValidCharPointer(name, 2); 7850e5472504SVaclav Hapla if (label) { 7851e5472504SVaclav Hapla PetscValidPointer(label, 3); 7852c58f1c22SToby Isaac *label = NULL; 7853e5472504SVaclav Hapla } 78545d80c0bfSVaclav Hapla for (pnext=&dm->labels; (link=*pnext); pnext=&link->next) { 785595d578d6SVaclav Hapla ierr = PetscObjectGetName((PetscObject) link->label, &lname);CHKERRQ(ierr); 7856d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr); 7857c58f1c22SToby Isaac if (hasLabel) { 785895d578d6SVaclav Hapla *pnext = link->next; /* Remove from list */ 7859c58f1c22SToby Isaac ierr = PetscStrcmp(name, "depth", &hasLabel);CHKERRQ(ierr); 786095d578d6SVaclav Hapla if (hasLabel) dm->depthLabel = NULL; 7861ba2698f1SMatthew G. Knepley ierr = PetscStrcmp(name, "celltype", &hasLabel);CHKERRQ(ierr); 7862ba2698f1SMatthew G. Knepley if (hasLabel) dm->celltypeLabel = NULL; 786395d578d6SVaclav Hapla if (label) *label = link->label; 786495d578d6SVaclav Hapla else {ierr = DMLabelDestroy(&link->label);CHKERRQ(ierr);} 786595d578d6SVaclav Hapla ierr = PetscFree(link);CHKERRQ(ierr); 7866c58f1c22SToby Isaac break; 7867c58f1c22SToby Isaac } 7868c58f1c22SToby Isaac } 7869c58f1c22SToby Isaac PetscFunctionReturn(0); 7870c58f1c22SToby Isaac } 7871c58f1c22SToby Isaac 7872306894acSVaclav Hapla /*@ 7873306894acSVaclav Hapla DMRemoveLabelBySelf - Remove the label from this mesh 7874306894acSVaclav Hapla 7875306894acSVaclav Hapla Not Collective 7876306894acSVaclav Hapla 7877306894acSVaclav Hapla Input Parameters: 7878306894acSVaclav Hapla + dm - The DM object 7879306894acSVaclav Hapla . label - (Optional) The DMLabel to be removed from the DM 7880306894acSVaclav Hapla - failNotFound - Should it fail if the label is not found in the DM? 7881306894acSVaclav Hapla 7882306894acSVaclav Hapla Level: developer 7883306894acSVaclav Hapla 7884306894acSVaclav Hapla Notes: 7885306894acSVaclav Hapla Only exactly the same instance is removed if found, name match is ignored. 7886306894acSVaclav Hapla If the DM has an exclusive reference to the label, it gets destroyed and 7887306894acSVaclav Hapla *label nullified. 7888306894acSVaclav Hapla 7889306894acSVaclav Hapla .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabel() DMGetLabelValue(), DMSetLabelValue(), DMLabelDestroy(), DMRemoveLabel() 7890306894acSVaclav Hapla @*/ 7891306894acSVaclav Hapla PetscErrorCode DMRemoveLabelBySelf(DM dm, DMLabel *label, PetscBool failNotFound) 7892306894acSVaclav Hapla { 789343e45a93SVaclav Hapla DMLabelLink link, *pnext; 7894306894acSVaclav Hapla PetscBool hasLabel = PETSC_FALSE; 7895306894acSVaclav Hapla PetscErrorCode ierr; 7896306894acSVaclav Hapla 7897306894acSVaclav Hapla PetscFunctionBegin; 7898306894acSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7899306894acSVaclav Hapla PetscValidPointer(label, 2); 7900f39a9ae0SVaclav Hapla if (!*label && !failNotFound) PetscFunctionReturn(0); 7901306894acSVaclav Hapla PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 2); 7902306894acSVaclav Hapla PetscValidLogicalCollectiveBool(dm,failNotFound,3); 79035d80c0bfSVaclav Hapla for (pnext=&dm->labels; (link=*pnext); pnext=&link->next) { 790443e45a93SVaclav Hapla if (*label == link->label) { 7905306894acSVaclav Hapla hasLabel = PETSC_TRUE; 790643e45a93SVaclav Hapla *pnext = link->next; /* Remove from list */ 7907306894acSVaclav Hapla if (*label == dm->depthLabel) dm->depthLabel = NULL; 7908ba2698f1SMatthew G. Knepley if (*label == dm->celltypeLabel) dm->celltypeLabel = NULL; 790943e45a93SVaclav Hapla if (((PetscObject) link->label)->refct < 2) *label = NULL; /* nullify if exclusive reference */ 791043e45a93SVaclav Hapla ierr = DMLabelDestroy(&link->label);CHKERRQ(ierr); 791143e45a93SVaclav Hapla ierr = PetscFree(link);CHKERRQ(ierr); 7912306894acSVaclav Hapla break; 7913306894acSVaclav Hapla } 7914306894acSVaclav Hapla } 7915306894acSVaclav Hapla if (!hasLabel && failNotFound) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Given label not found in DM"); 7916306894acSVaclav Hapla PetscFunctionReturn(0); 7917306894acSVaclav Hapla } 7918306894acSVaclav Hapla 7919c58f1c22SToby Isaac /*@C 7920c58f1c22SToby Isaac DMGetLabelOutput - Get the output flag for a given label 7921c58f1c22SToby Isaac 7922c58f1c22SToby Isaac Not Collective 7923c58f1c22SToby Isaac 7924c58f1c22SToby Isaac Input Parameters: 7925c58f1c22SToby Isaac + dm - The DM object 7926c58f1c22SToby Isaac - name - The label name 7927c58f1c22SToby Isaac 7928c58f1c22SToby Isaac Output Parameter: 7929c58f1c22SToby Isaac . output - The flag for output 7930c58f1c22SToby Isaac 7931c58f1c22SToby Isaac Level: developer 7932c58f1c22SToby Isaac 7933c58f1c22SToby Isaac .seealso: DMSetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7934c58f1c22SToby Isaac @*/ 7935c58f1c22SToby Isaac PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output) 7936c58f1c22SToby Isaac { 79375d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7938d67d17b1SMatthew G. Knepley const char *lname; 7939c58f1c22SToby Isaac PetscErrorCode ierr; 7940c58f1c22SToby Isaac 7941c58f1c22SToby Isaac PetscFunctionBegin; 7942c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7943c58f1c22SToby Isaac PetscValidPointer(name, 2); 7944c58f1c22SToby Isaac PetscValidPointer(output, 3); 7945c58f1c22SToby Isaac while (next) { 7946c58f1c22SToby Isaac PetscBool flg; 7947c58f1c22SToby Isaac 7948d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 7949d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr); 7950c58f1c22SToby Isaac if (flg) {*output = next->output; PetscFunctionReturn(0);} 7951c58f1c22SToby Isaac next = next->next; 7952c58f1c22SToby Isaac } 7953c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7954c58f1c22SToby Isaac } 7955c58f1c22SToby Isaac 7956c58f1c22SToby Isaac /*@C 7957c58f1c22SToby Isaac DMSetLabelOutput - Set the output flag for a given label 7958c58f1c22SToby Isaac 7959c58f1c22SToby Isaac Not Collective 7960c58f1c22SToby Isaac 7961c58f1c22SToby Isaac Input Parameters: 7962c58f1c22SToby Isaac + dm - The DM object 7963c58f1c22SToby Isaac . name - The label name 7964c58f1c22SToby Isaac - output - The flag for output 7965c58f1c22SToby Isaac 7966c58f1c22SToby Isaac Level: developer 7967c58f1c22SToby Isaac 7968c58f1c22SToby Isaac .seealso: DMGetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7969c58f1c22SToby Isaac @*/ 7970c58f1c22SToby Isaac PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output) 7971c58f1c22SToby Isaac { 79725d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7973d67d17b1SMatthew G. Knepley const char *lname; 7974c58f1c22SToby Isaac PetscErrorCode ierr; 7975c58f1c22SToby Isaac 7976c58f1c22SToby Isaac PetscFunctionBegin; 7977c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7978534a8f05SLisandro Dalcin PetscValidCharPointer(name, 2); 7979c58f1c22SToby Isaac while (next) { 7980c58f1c22SToby Isaac PetscBool flg; 7981c58f1c22SToby Isaac 7982d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 7983d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr); 7984c58f1c22SToby Isaac if (flg) {next->output = output; PetscFunctionReturn(0);} 7985c58f1c22SToby Isaac next = next->next; 7986c58f1c22SToby Isaac } 7987c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7988c58f1c22SToby Isaac } 7989c58f1c22SToby Isaac 7990c58f1c22SToby Isaac /*@ 7991c58f1c22SToby Isaac DMCopyLabels - Copy labels from one mesh to another with a superset of the points 7992c58f1c22SToby Isaac 7993d083f849SBarry Smith Collective on dmA 7994c58f1c22SToby Isaac 7995c58f1c22SToby Isaac Input Parameter: 79965d80c0bfSVaclav Hapla + dmA - The DM object with initial labels 79972e17dfb7SMatthew G. Knepley . dmB - The DM object with copied labels 79985d80c0bfSVaclav Hapla . mode - Copy labels by pointers (PETSC_OWN_POINTER) or duplicate them (PETSC_COPY_VALUES) 7999ba2698f1SMatthew G. Knepley - all - Copy all labels including "depth", "dim", and "celltype" (PETSC_TRUE) which are otherwise ignored (PETSC_FALSE) 8000c58f1c22SToby Isaac 8001c58f1c22SToby Isaac Level: intermediate 8002c58f1c22SToby Isaac 8003c58f1c22SToby Isaac Note: This is typically used when interpolating or otherwise adding to a mesh 8004c58f1c22SToby Isaac 80055d80c0bfSVaclav Hapla .seealso: DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMGetCoordinateSection(), DMShareLabels() 8006c58f1c22SToby Isaac @*/ 80075d80c0bfSVaclav Hapla PetscErrorCode DMCopyLabels(DM dmA, DM dmB, PetscCopyMode mode, PetscBool all) 8008c58f1c22SToby Isaac { 8009c58f1c22SToby Isaac DMLabel label, labelNew; 8010c58f1c22SToby Isaac const char *name; 8011c58f1c22SToby Isaac PetscBool flg; 80125d80c0bfSVaclav Hapla DMLabelLink link; 80135d80c0bfSVaclav Hapla PetscErrorCode ierr; 8014c58f1c22SToby Isaac 80155d80c0bfSVaclav Hapla PetscFunctionBegin; 80165d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 80175d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 80185d80c0bfSVaclav Hapla PetscValidLogicalCollectiveEnum(dmA, mode,3); 80195d80c0bfSVaclav Hapla PetscValidLogicalCollectiveBool(dmA, all, 4); 80205d80c0bfSVaclav Hapla if (mode==PETSC_USE_POINTER) SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_SUP, "PETSC_USE_POINTER not supported for objects"); 80215d80c0bfSVaclav Hapla if (dmA == dmB) PetscFunctionReturn(0); 80225d80c0bfSVaclav Hapla for (link=dmA->labels; link; link=link->next) { 80235d80c0bfSVaclav Hapla label=link->label; 80245d80c0bfSVaclav Hapla ierr = PetscObjectGetName((PetscObject)label, &name);CHKERRQ(ierr); 80255d80c0bfSVaclav Hapla if (!all) { 8026c58f1c22SToby Isaac ierr = PetscStrcmp(name, "depth", &flg);CHKERRQ(ierr); 8027c58f1c22SToby Isaac if (flg) continue; 80287d5acc75SStefano Zampini ierr = PetscStrcmp(name, "dim", &flg);CHKERRQ(ierr); 80297d5acc75SStefano Zampini if (flg) continue; 8030ba2698f1SMatthew G. Knepley ierr = PetscStrcmp(name, "celltype", &flg);CHKERRQ(ierr); 8031ba2698f1SMatthew G. Knepley if (flg) continue; 80325d80c0bfSVaclav Hapla } 80335d80c0bfSVaclav Hapla if (mode==PETSC_COPY_VALUES) { 8034c58f1c22SToby Isaac ierr = DMLabelDuplicate(label, &labelNew);CHKERRQ(ierr); 80355d80c0bfSVaclav Hapla } else { 80365d80c0bfSVaclav Hapla labelNew = label; 80375d80c0bfSVaclav Hapla } 8038c58f1c22SToby Isaac ierr = DMAddLabel(dmB, labelNew);CHKERRQ(ierr); 80395d80c0bfSVaclav Hapla if (mode==PETSC_COPY_VALUES) {ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr);} 8040c58f1c22SToby Isaac } 8041c58f1c22SToby Isaac PetscFunctionReturn(0); 8042c58f1c22SToby Isaac } 80430fdc7489SMatthew Knepley /* 80440fdc7489SMatthew Knepley Many mesh programs, such as Triangle and TetGen, allow only a single label for each mesh point. Therefore, we would 80450fdc7489SMatthew Knepley like to encode all label IDs using a single, universal label. We can do this by assigning an integer to every 80460fdc7489SMatthew Knepley (label, id) pair in the DM. 80470fdc7489SMatthew Knepley 80480fdc7489SMatthew Knepley However, a mesh point can have multiple labels, so we must separate all these values. We will assign a bit range to 80490fdc7489SMatthew Knepley each label. 80500fdc7489SMatthew Knepley */ 80510fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelCreate(DM dm, DMUniversalLabel *universal) 80520fdc7489SMatthew Knepley { 80530fdc7489SMatthew Knepley DMUniversalLabel ul; 80540fdc7489SMatthew Knepley PetscBool *active; 80550fdc7489SMatthew Knepley PetscInt pStart, pEnd, p, Nl, l, m; 80560fdc7489SMatthew Knepley PetscErrorCode ierr; 80570fdc7489SMatthew Knepley 80580fdc7489SMatthew Knepley PetscFunctionBegin; 80590fdc7489SMatthew Knepley ierr = PetscMalloc1(1, &ul);CHKERRQ(ierr); 80600fdc7489SMatthew Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, "universal", &ul->label);CHKERRQ(ierr); 80610fdc7489SMatthew Knepley ierr = DMGetNumLabels(dm, &Nl);CHKERRQ(ierr); 80620fdc7489SMatthew Knepley ierr = PetscCalloc1(Nl, &active);CHKERRQ(ierr); 80630fdc7489SMatthew Knepley ul->Nl = 0; 80640fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 80650fdc7489SMatthew Knepley PetscBool isdepth, iscelltype; 80660fdc7489SMatthew Knepley const char *name; 80670fdc7489SMatthew Knepley 80680fdc7489SMatthew Knepley ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 80690fdc7489SMatthew Knepley ierr = PetscStrncmp(name, "depth", 6, &isdepth);CHKERRQ(ierr); 80700fdc7489SMatthew Knepley ierr = PetscStrncmp(name, "celltype", 9, &iscelltype);CHKERRQ(ierr); 80710fdc7489SMatthew Knepley active[l] = !(isdepth || iscelltype) ? PETSC_TRUE : PETSC_FALSE; 80720fdc7489SMatthew Knepley if (active[l]) ++ul->Nl; 80730fdc7489SMatthew Knepley } 80740fdc7489SMatthew 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); 80750fdc7489SMatthew Knepley ul->Nv = 0; 80760fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 80770fdc7489SMatthew Knepley DMLabel label; 80780fdc7489SMatthew Knepley PetscInt nv; 80790fdc7489SMatthew Knepley const char *name; 80800fdc7489SMatthew Knepley 80810fdc7489SMatthew Knepley if (!active[l]) continue; 80820fdc7489SMatthew Knepley ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 80830fdc7489SMatthew Knepley ierr = DMGetLabelByNum(dm, l, &label);CHKERRQ(ierr); 80840fdc7489SMatthew Knepley ierr = DMLabelGetNumValues(label, &nv);CHKERRQ(ierr); 80850fdc7489SMatthew Knepley ierr = PetscStrallocpy(name, &ul->names[m]);CHKERRQ(ierr); 80860fdc7489SMatthew Knepley ul->indices[m] = l; 80870fdc7489SMatthew Knepley ul->Nv += nv; 80880fdc7489SMatthew Knepley ul->offsets[m+1] = nv; 80890fdc7489SMatthew Knepley ul->bits[m+1] = PetscCeilReal(PetscLog2Real(nv+1)); 80900fdc7489SMatthew Knepley ++m; 80910fdc7489SMatthew Knepley } 80920fdc7489SMatthew Knepley for (l = 1; l <= ul->Nl; ++l) { 80930fdc7489SMatthew Knepley ul->offsets[l] = ul->offsets[l-1] + ul->offsets[l]; 80940fdc7489SMatthew Knepley ul->bits[l] = ul->bits[l-1] + ul->bits[l]; 80950fdc7489SMatthew Knepley } 80960fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 80970fdc7489SMatthew Knepley PetscInt b; 80980fdc7489SMatthew Knepley 80990fdc7489SMatthew Knepley ul->masks[l] = 0; 81000fdc7489SMatthew Knepley for (b = ul->bits[l]; b < ul->bits[l+1]; ++b) ul->masks[l] |= 1 << b; 81010fdc7489SMatthew Knepley } 81020fdc7489SMatthew Knepley ierr = PetscMalloc1(ul->Nv, &ul->values);CHKERRQ(ierr); 81030fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 81040fdc7489SMatthew Knepley DMLabel label; 81050fdc7489SMatthew Knepley IS valueIS; 81060fdc7489SMatthew Knepley const PetscInt *varr; 81070fdc7489SMatthew Knepley PetscInt nv, v; 81080fdc7489SMatthew Knepley 81090fdc7489SMatthew Knepley if (!active[l]) continue; 81100fdc7489SMatthew Knepley ierr = DMGetLabelByNum(dm, l, &label);CHKERRQ(ierr); 81110fdc7489SMatthew Knepley ierr = DMLabelGetNumValues(label, &nv);CHKERRQ(ierr); 81120fdc7489SMatthew Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 81130fdc7489SMatthew Knepley ierr = ISGetIndices(valueIS, &varr);CHKERRQ(ierr); 81140fdc7489SMatthew Knepley for (v = 0; v < nv; ++v) { 81150fdc7489SMatthew Knepley ul->values[ul->offsets[m]+v] = varr[v]; 81160fdc7489SMatthew Knepley } 81170fdc7489SMatthew Knepley ierr = ISRestoreIndices(valueIS, &varr);CHKERRQ(ierr); 81180fdc7489SMatthew Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 81190fdc7489SMatthew Knepley ierr = PetscSortInt(nv, &ul->values[ul->offsets[m]]);CHKERRQ(ierr); 81200fdc7489SMatthew Knepley ++m; 81210fdc7489SMatthew Knepley } 81220fdc7489SMatthew Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 81230fdc7489SMatthew Knepley for (p = pStart; p < pEnd; ++p) { 81240fdc7489SMatthew Knepley PetscInt uval = 0; 81250fdc7489SMatthew Knepley PetscBool marked = PETSC_FALSE; 81260fdc7489SMatthew Knepley 81270fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 81280fdc7489SMatthew Knepley DMLabel label; 81290649b39aSStefano Zampini PetscInt val, defval, loc, nv; 81300fdc7489SMatthew Knepley 81310fdc7489SMatthew Knepley if (!active[l]) continue; 81320fdc7489SMatthew Knepley ierr = DMGetLabelByNum(dm, l, &label);CHKERRQ(ierr); 81330fdc7489SMatthew Knepley ierr = DMLabelGetValue(label, p, &val);CHKERRQ(ierr); 81340fdc7489SMatthew Knepley ierr = DMLabelGetDefaultValue(label, &defval);CHKERRQ(ierr); 81350fdc7489SMatthew Knepley if (val == defval) {++m; continue;} 81360649b39aSStefano Zampini nv = ul->offsets[m+1]-ul->offsets[m]; 81370fdc7489SMatthew Knepley marked = PETSC_TRUE; 81380fdc7489SMatthew Knepley ierr = PetscFindInt(val, nv, &ul->values[ul->offsets[m]], &loc);CHKERRQ(ierr); 81390fdc7489SMatthew Knepley if (loc < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Label value %D not found in compression array", val); 81400fdc7489SMatthew Knepley uval += (loc+1) << ul->bits[m]; 81410fdc7489SMatthew Knepley ++m; 81420fdc7489SMatthew Knepley } 81430fdc7489SMatthew Knepley if (marked) {ierr = DMLabelSetValue(ul->label, p, uval);CHKERRQ(ierr);} 81440fdc7489SMatthew Knepley } 81450fdc7489SMatthew Knepley ierr = PetscFree(active);CHKERRQ(ierr); 81460fdc7489SMatthew Knepley *universal = ul; 81470fdc7489SMatthew Knepley PetscFunctionReturn(0); 81480fdc7489SMatthew Knepley } 81490fdc7489SMatthew Knepley 81500fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelDestroy(DMUniversalLabel *universal) 81510fdc7489SMatthew Knepley { 81520fdc7489SMatthew Knepley PetscInt l; 81530fdc7489SMatthew Knepley PetscErrorCode ierr; 81540fdc7489SMatthew Knepley 81550fdc7489SMatthew Knepley PetscFunctionBegin; 81560fdc7489SMatthew Knepley for (l = 0; l < (*universal)->Nl; ++l) {ierr = PetscFree((*universal)->names[l]);CHKERRQ(ierr);} 81570fdc7489SMatthew Knepley ierr = DMLabelDestroy(&(*universal)->label);CHKERRQ(ierr); 81580fdc7489SMatthew Knepley ierr = PetscFree5((*universal)->names, (*universal)->indices, (*universal)->offsets, (*universal)->bits, (*universal)->masks);CHKERRQ(ierr); 81590fdc7489SMatthew Knepley ierr = PetscFree((*universal)->values);CHKERRQ(ierr); 81600fdc7489SMatthew Knepley ierr = PetscFree(*universal);CHKERRQ(ierr); 81610fdc7489SMatthew Knepley *universal = NULL; 81620fdc7489SMatthew Knepley PetscFunctionReturn(0); 81630fdc7489SMatthew Knepley } 81640fdc7489SMatthew Knepley 81650fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelGetLabel(DMUniversalLabel ul, DMLabel *ulabel) 81660fdc7489SMatthew Knepley { 81670fdc7489SMatthew Knepley PetscFunctionBegin; 81680fdc7489SMatthew Knepley PetscValidPointer(ulabel, 2); 81690fdc7489SMatthew Knepley *ulabel = ul->label; 81700fdc7489SMatthew Knepley PetscFunctionReturn(0); 81710fdc7489SMatthew Knepley } 81720fdc7489SMatthew Knepley 81730fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelCreateLabels(DMUniversalLabel ul, PetscBool preserveOrder, DM dm) 81740fdc7489SMatthew Knepley { 81750fdc7489SMatthew Knepley PetscInt Nl = ul->Nl, l; 81760fdc7489SMatthew Knepley PetscErrorCode ierr; 81770fdc7489SMatthew Knepley 81780fdc7489SMatthew Knepley PetscFunctionBegin; 81790fdc7489SMatthew Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 81800fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 81810fdc7489SMatthew Knepley if (preserveOrder) {ierr = DMCreateLabelAtIndex(dm, ul->indices[l], ul->names[l]);CHKERRQ(ierr);} 81820fdc7489SMatthew Knepley else {ierr = DMCreateLabel(dm, ul->names[l]);CHKERRQ(ierr);} 81830fdc7489SMatthew Knepley } 81840fdc7489SMatthew Knepley if (preserveOrder) { 81850fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 81860fdc7489SMatthew Knepley const char *name; 81870fdc7489SMatthew Knepley PetscBool match; 81880fdc7489SMatthew Knepley 81890fdc7489SMatthew Knepley ierr = DMGetLabelName(dm, ul->indices[l], &name);CHKERRQ(ierr); 81900fdc7489SMatthew Knepley ierr = PetscStrcmp(name, ul->names[l], &match);CHKERRQ(ierr); 81910fdc7489SMatthew 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]); 81920fdc7489SMatthew Knepley } 81930fdc7489SMatthew Knepley } 81940fdc7489SMatthew Knepley PetscFunctionReturn(0); 81950fdc7489SMatthew Knepley } 81960fdc7489SMatthew Knepley 81970fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelSetLabelValue(DMUniversalLabel ul, DM dm, PetscBool useIndex, PetscInt p, PetscInt value) 81980fdc7489SMatthew Knepley { 81990fdc7489SMatthew Knepley PetscInt l; 82000fdc7489SMatthew Knepley PetscErrorCode ierr; 82010fdc7489SMatthew Knepley 82020fdc7489SMatthew Knepley PetscFunctionBegin; 82030fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 82040fdc7489SMatthew Knepley DMLabel label; 82050fdc7489SMatthew Knepley PetscInt lval = (value & ul->masks[l]) >> ul->bits[l]; 82060fdc7489SMatthew Knepley 82070fdc7489SMatthew Knepley if (lval) { 82080fdc7489SMatthew Knepley if (useIndex) {ierr = DMGetLabelByNum(dm, ul->indices[l], &label);CHKERRQ(ierr);} 82090fdc7489SMatthew Knepley else {ierr = DMGetLabel(dm, ul->names[l], &label);CHKERRQ(ierr);} 82100fdc7489SMatthew Knepley ierr = DMLabelSetValue(label, p, ul->values[ul->offsets[l]+lval-1]);CHKERRQ(ierr); 82110fdc7489SMatthew Knepley } 82120fdc7489SMatthew Knepley } 82130fdc7489SMatthew Knepley PetscFunctionReturn(0); 82140fdc7489SMatthew Knepley } 8215a8fb8f29SToby Isaac 8216a8fb8f29SToby Isaac /*@ 8217a8fb8f29SToby Isaac DMGetCoarseDM - Get the coarse mesh from which this was obtained by refinement 8218a8fb8f29SToby Isaac 8219a8fb8f29SToby Isaac Input Parameter: 8220a8fb8f29SToby Isaac . dm - The DM object 8221a8fb8f29SToby Isaac 8222a8fb8f29SToby Isaac Output Parameter: 8223a8fb8f29SToby Isaac . cdm - The coarse DM 8224a8fb8f29SToby Isaac 8225a8fb8f29SToby Isaac Level: intermediate 8226a8fb8f29SToby Isaac 8227a8fb8f29SToby Isaac .seealso: DMSetCoarseDM() 8228a8fb8f29SToby Isaac @*/ 8229a8fb8f29SToby Isaac PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm) 8230a8fb8f29SToby Isaac { 8231a8fb8f29SToby Isaac PetscFunctionBegin; 8232a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8233a8fb8f29SToby Isaac PetscValidPointer(cdm, 2); 8234a8fb8f29SToby Isaac *cdm = dm->coarseMesh; 8235a8fb8f29SToby Isaac PetscFunctionReturn(0); 8236a8fb8f29SToby Isaac } 8237a8fb8f29SToby Isaac 8238a8fb8f29SToby Isaac /*@ 8239a8fb8f29SToby Isaac DMSetCoarseDM - Set the coarse mesh from which this was obtained by refinement 8240a8fb8f29SToby Isaac 8241a8fb8f29SToby Isaac Input Parameters: 8242a8fb8f29SToby Isaac + dm - The DM object 8243a8fb8f29SToby Isaac - cdm - The coarse DM 8244a8fb8f29SToby Isaac 8245a8fb8f29SToby Isaac Level: intermediate 8246a8fb8f29SToby Isaac 8247a8fb8f29SToby Isaac .seealso: DMGetCoarseDM() 8248a8fb8f29SToby Isaac @*/ 8249a8fb8f29SToby Isaac PetscErrorCode DMSetCoarseDM(DM dm, DM cdm) 8250a8fb8f29SToby Isaac { 8251a8fb8f29SToby Isaac PetscErrorCode ierr; 8252a8fb8f29SToby Isaac 8253a8fb8f29SToby Isaac PetscFunctionBegin; 8254a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8255a8fb8f29SToby Isaac if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 8256a8fb8f29SToby Isaac ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr); 8257a8fb8f29SToby Isaac ierr = DMDestroy(&dm->coarseMesh);CHKERRQ(ierr); 8258a8fb8f29SToby Isaac dm->coarseMesh = cdm; 8259a8fb8f29SToby Isaac PetscFunctionReturn(0); 8260a8fb8f29SToby Isaac } 8261a8fb8f29SToby Isaac 826288bdff64SToby Isaac /*@ 826388bdff64SToby Isaac DMGetFineDM - Get the fine mesh from which this was obtained by refinement 826488bdff64SToby Isaac 826588bdff64SToby Isaac Input Parameter: 826688bdff64SToby Isaac . dm - The DM object 826788bdff64SToby Isaac 826888bdff64SToby Isaac Output Parameter: 826988bdff64SToby Isaac . fdm - The fine DM 827088bdff64SToby Isaac 827188bdff64SToby Isaac Level: intermediate 827288bdff64SToby Isaac 827388bdff64SToby Isaac .seealso: DMSetFineDM() 827488bdff64SToby Isaac @*/ 827588bdff64SToby Isaac PetscErrorCode DMGetFineDM(DM dm, DM *fdm) 827688bdff64SToby Isaac { 827788bdff64SToby Isaac PetscFunctionBegin; 827888bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 827988bdff64SToby Isaac PetscValidPointer(fdm, 2); 828088bdff64SToby Isaac *fdm = dm->fineMesh; 828188bdff64SToby Isaac PetscFunctionReturn(0); 828288bdff64SToby Isaac } 828388bdff64SToby Isaac 828488bdff64SToby Isaac /*@ 828588bdff64SToby Isaac DMSetFineDM - Set the fine mesh from which this was obtained by refinement 828688bdff64SToby Isaac 828788bdff64SToby Isaac Input Parameters: 828888bdff64SToby Isaac + dm - The DM object 828988bdff64SToby Isaac - fdm - The fine DM 829088bdff64SToby Isaac 829188bdff64SToby Isaac Level: intermediate 829288bdff64SToby Isaac 829388bdff64SToby Isaac .seealso: DMGetFineDM() 829488bdff64SToby Isaac @*/ 829588bdff64SToby Isaac PetscErrorCode DMSetFineDM(DM dm, DM fdm) 829688bdff64SToby Isaac { 829788bdff64SToby Isaac PetscErrorCode ierr; 829888bdff64SToby Isaac 829988bdff64SToby Isaac PetscFunctionBegin; 830088bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 830188bdff64SToby Isaac if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2); 830288bdff64SToby Isaac ierr = PetscObjectReference((PetscObject)fdm);CHKERRQ(ierr); 830388bdff64SToby Isaac ierr = DMDestroy(&dm->fineMesh);CHKERRQ(ierr); 830488bdff64SToby Isaac dm->fineMesh = fdm; 830588bdff64SToby Isaac PetscFunctionReturn(0); 830688bdff64SToby Isaac } 830788bdff64SToby Isaac 8308a6ba4734SToby Isaac /*=== DMBoundary code ===*/ 8309a6ba4734SToby Isaac 8310a6ba4734SToby Isaac PetscErrorCode DMCopyBoundary(DM dm, DM dmNew) 8311a6ba4734SToby Isaac { 8312e5e52638SMatthew G. Knepley PetscInt d; 8313a6ba4734SToby Isaac PetscErrorCode ierr; 8314a6ba4734SToby Isaac 8315a6ba4734SToby Isaac PetscFunctionBegin; 8316e5e52638SMatthew G. Knepley for (d = 0; d < dm->Nds; ++d) { 831736951cb5SMatthew G. Knepley ierr = PetscDSCopyBoundary(dm->probs[d].ds, PETSC_DETERMINE, NULL, dmNew->probs[d].ds);CHKERRQ(ierr); 8318e5e52638SMatthew G. Knepley } 8319a6ba4734SToby Isaac PetscFunctionReturn(0); 8320a6ba4734SToby Isaac } 8321a6ba4734SToby Isaac 8322a6ba4734SToby Isaac /*@C 8323a6ba4734SToby Isaac DMAddBoundary - Add a boundary condition to the model 8324a6ba4734SToby Isaac 8325783e2ec8SMatthew G. Knepley Collective on dm 8326783e2ec8SMatthew G. Knepley 8327a6ba4734SToby Isaac Input Parameters: 83284c258f51SMatthew G. Knepley + dm - The DM, with a PetscDS that matches the problem being constrained 8329f971fd6bSMatthew G. Knepley . type - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann) 8330a6ba4734SToby Isaac . name - The BC name 8331a6ba4734SToby Isaac . labelname - The label defining constrained points 8332a6ba4734SToby Isaac . field - The field to constrain 8333e8ecbf3fSStefano Zampini . numcomps - The number of constrained field components (0 will constrain all fields) 8334a6ba4734SToby Isaac . comps - An array of constrained component numbers 8335a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 833656cf3b9cSMatthew G. Knepley . bcFunc_t - A pointwise function giving the time deriative of the boundary values, or NULL 8337a6ba4734SToby Isaac . numids - The number of DMLabel ids for constrained points 8338a6ba4734SToby Isaac . ids - An array of ids for constrained points 8339a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 8340a6ba4734SToby Isaac 8341a6ba4734SToby Isaac Options Database Keys: 8342a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 8343a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 8344a6ba4734SToby Isaac 834556cf3b9cSMatthew G. Knepley Note: 834656cf3b9cSMatthew 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: 834756cf3b9cSMatthew G. Knepley 834856cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[]) 834956cf3b9cSMatthew G. Knepley 835056cf3b9cSMatthew G. Knepley If the type is DM_BC_ESSENTIAL_FIELD or other _FIELD value, then the calling sequence is: 835156cf3b9cSMatthew G. Knepley 835256cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux, 835356cf3b9cSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 835456cf3b9cSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 835556cf3b9cSMatthew G. Knepley $ PetscReal time, const PetscReal x[], PetscScalar bcval[]) 835656cf3b9cSMatthew G. Knepley 835756cf3b9cSMatthew G. Knepley + dim - the spatial dimension 835856cf3b9cSMatthew G. Knepley . Nf - the number of fields 835956cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field 836056cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field 836156cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point 836256cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point 836356cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point 836456cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field 836556cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field 836656cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point 836756cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point 836856cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point 836956cf3b9cSMatthew G. Knepley . t - current time 837056cf3b9cSMatthew G. Knepley . x - coordinates of the current point 837156cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters 837256cf3b9cSMatthew G. Knepley . constants - constant parameters 837356cf3b9cSMatthew G. Knepley - bcval - output values at the current point 837456cf3b9cSMatthew G. Knepley 8375a6ba4734SToby Isaac Level: developer 8376a6ba4734SToby Isaac 837756cf3b9cSMatthew G. Knepley .seealso: DMGetBoundary(), PetscDSAddBoundary() 8378a6ba4734SToby Isaac @*/ 837956cf3b9cSMatthew 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) 8380a6ba4734SToby Isaac { 8381e5e52638SMatthew G. Knepley PetscDS ds; 8382a6ba4734SToby Isaac PetscErrorCode ierr; 8383a6ba4734SToby Isaac 8384a6ba4734SToby Isaac PetscFunctionBegin; 8385a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8386783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveEnum(dm, type, 2); 8387783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, field, 5); 8388783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, numcomps, 6); 8389783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, numids, 9); 8390e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 8391783e2ec8SMatthew G. Knepley ierr = DMCompleteBoundaryLabel_Internal(dm, ds, field, PETSC_MAX_INT, labelname);CHKERRQ(ierr); 839256cf3b9cSMatthew G. Knepley ierr = PetscDSAddBoundary(ds, type,name, labelname, field, numcomps, comps, bcFunc, bcFunc_t, numids, ids, ctx);CHKERRQ(ierr); 8393a6ba4734SToby Isaac PetscFunctionReturn(0); 8394a6ba4734SToby Isaac } 8395a6ba4734SToby Isaac 8396a6ba4734SToby Isaac /*@ 8397a6ba4734SToby Isaac DMGetNumBoundary - Get the number of registered BC 8398a6ba4734SToby Isaac 8399a6ba4734SToby Isaac Input Parameters: 8400a6ba4734SToby Isaac . dm - The mesh object 8401a6ba4734SToby Isaac 8402a6ba4734SToby Isaac Output Parameters: 8403a6ba4734SToby Isaac . numBd - The number of BC 8404a6ba4734SToby Isaac 8405a6ba4734SToby Isaac Level: intermediate 8406a6ba4734SToby Isaac 8407a6ba4734SToby Isaac .seealso: DMAddBoundary(), DMGetBoundary() 8408a6ba4734SToby Isaac @*/ 8409a6ba4734SToby Isaac PetscErrorCode DMGetNumBoundary(DM dm, PetscInt *numBd) 8410a6ba4734SToby Isaac { 8411e5e52638SMatthew G. Knepley PetscDS ds; 841258ebd649SToby Isaac PetscErrorCode ierr; 8413a6ba4734SToby Isaac 8414a6ba4734SToby Isaac PetscFunctionBegin; 8415a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8416e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 8417e5e52638SMatthew G. Knepley ierr = PetscDSGetNumBoundary(ds, numBd);CHKERRQ(ierr); 8418a6ba4734SToby Isaac PetscFunctionReturn(0); 8419a6ba4734SToby Isaac } 8420a6ba4734SToby Isaac 8421a6ba4734SToby Isaac /*@C 84221c531cf8SMatthew G. Knepley DMGetBoundary - Get a model boundary condition 8423a6ba4734SToby Isaac 8424a6ba4734SToby Isaac Input Parameters: 8425a6ba4734SToby Isaac + dm - The mesh object 8426a6ba4734SToby Isaac - bd - The BC number 8427a6ba4734SToby Isaac 8428a6ba4734SToby Isaac Output Parameters: 8429f971fd6bSMatthew G. Knepley + type - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann) 8430a6ba4734SToby Isaac . name - The BC name 8431a6ba4734SToby Isaac . labelname - The label defining constrained points 8432a6ba4734SToby Isaac . field - The field to constrain 8433a6ba4734SToby Isaac . numcomps - The number of constrained field components 8434a6ba4734SToby Isaac . comps - An array of constrained component numbers 8435a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 843656cf3b9cSMatthew G. Knepley . bcFunc_t - A pointwise function giving the time derviative of the boundary values 8437a6ba4734SToby Isaac . numids - The number of DMLabel ids for constrained points 8438a6ba4734SToby Isaac . ids - An array of ids for constrained points 8439a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 8440a6ba4734SToby Isaac 8441a6ba4734SToby Isaac Options Database Keys: 8442a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 8443a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 8444a6ba4734SToby Isaac 8445a6ba4734SToby Isaac Level: developer 8446a6ba4734SToby Isaac 8447a6ba4734SToby Isaac .seealso: DMAddBoundary() 8448a6ba4734SToby Isaac @*/ 844956cf3b9cSMatthew 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) 8450a6ba4734SToby Isaac { 8451e5e52638SMatthew G. Knepley PetscDS ds; 845258ebd649SToby Isaac PetscErrorCode ierr; 8453a6ba4734SToby Isaac 8454a6ba4734SToby Isaac PetscFunctionBegin; 8455a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8456e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 845756cf3b9cSMatthew G. Knepley ierr = PetscDSGetBoundary(ds, bd, type, name, labelname, field, numcomps, comps, func, func_t, numids, ids, ctx);CHKERRQ(ierr); 8458a6ba4734SToby Isaac PetscFunctionReturn(0); 8459a6ba4734SToby Isaac } 8460a6ba4734SToby Isaac 8461e6f8dbb6SToby Isaac static PetscErrorCode DMPopulateBoundary(DM dm) 8462e6f8dbb6SToby Isaac { 8463e5e52638SMatthew G. Knepley PetscDS ds; 8464dff059c6SToby Isaac DMBoundary *lastnext; 8465e6f8dbb6SToby Isaac DSBoundary dsbound; 8466e6f8dbb6SToby Isaac PetscErrorCode ierr; 8467e6f8dbb6SToby Isaac 8468e6f8dbb6SToby Isaac PetscFunctionBegin; 8469e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 8470e5e52638SMatthew G. Knepley dsbound = ds->boundary; 847147a1f5adSToby Isaac if (dm->boundary) { 847247a1f5adSToby Isaac DMBoundary next = dm->boundary; 847347a1f5adSToby Isaac 847447a1f5adSToby Isaac /* quick check to see if the PetscDS has changed */ 847547a1f5adSToby Isaac if (next->dsboundary == dsbound) PetscFunctionReturn(0); 847647a1f5adSToby Isaac /* the PetscDS has changed: tear down and rebuild */ 847747a1f5adSToby Isaac while (next) { 847847a1f5adSToby Isaac DMBoundary b = next; 847947a1f5adSToby Isaac 848047a1f5adSToby Isaac next = b->next; 848147a1f5adSToby Isaac ierr = PetscFree(b);CHKERRQ(ierr); 8482a6ba4734SToby Isaac } 848347a1f5adSToby Isaac dm->boundary = NULL; 8484a6ba4734SToby Isaac } 848547a1f5adSToby Isaac 8486dff059c6SToby Isaac lastnext = &(dm->boundary); 8487e6f8dbb6SToby Isaac while (dsbound) { 8488e6f8dbb6SToby Isaac DMBoundary dmbound; 8489e6f8dbb6SToby Isaac 8490e6f8dbb6SToby Isaac ierr = PetscNew(&dmbound);CHKERRQ(ierr); 8491e6f8dbb6SToby Isaac dmbound->dsboundary = dsbound; 8492e6f8dbb6SToby Isaac ierr = DMGetLabel(dm, dsbound->labelname, &(dmbound->label));CHKERRQ(ierr); 8493994fe344SLisandro 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);} 849447a1f5adSToby Isaac /* push on the back instead of the front so that it is in the same order as in the PetscDS */ 8495dff059c6SToby Isaac *lastnext = dmbound; 8496dff059c6SToby Isaac lastnext = &(dmbound->next); 8497dff059c6SToby Isaac dsbound = dsbound->next; 8498a6ba4734SToby Isaac } 8499a6ba4734SToby Isaac PetscFunctionReturn(0); 8500a6ba4734SToby Isaac } 8501a6ba4734SToby Isaac 8502a6ba4734SToby Isaac PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd) 8503a6ba4734SToby Isaac { 8504b95f2879SToby Isaac DMBoundary b; 8505a6ba4734SToby Isaac PetscErrorCode ierr; 8506a6ba4734SToby Isaac 8507a6ba4734SToby Isaac PetscFunctionBegin; 8508a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8509534a8f05SLisandro Dalcin PetscValidBoolPointer(isBd, 3); 8510a6ba4734SToby Isaac *isBd = PETSC_FALSE; 8511e6f8dbb6SToby Isaac ierr = DMPopulateBoundary(dm);CHKERRQ(ierr); 8512b95f2879SToby Isaac b = dm->boundary; 8513a6ba4734SToby Isaac while (b && !(*isBd)) { 8514e6f8dbb6SToby Isaac DMLabel label = b->label; 8515e6f8dbb6SToby Isaac DSBoundary dsb = b->dsboundary; 85163424c85cSToby Isaac 85173424c85cSToby Isaac if (label) { 8518a6ba4734SToby Isaac PetscInt i; 8519a6ba4734SToby Isaac 8520e6f8dbb6SToby Isaac for (i = 0; i < dsb->numids && !(*isBd); ++i) { 8521e6f8dbb6SToby Isaac ierr = DMLabelStratumHasPoint(label, dsb->ids[i], point, isBd);CHKERRQ(ierr); 8522a6ba4734SToby Isaac } 8523a6ba4734SToby Isaac } 8524a6ba4734SToby Isaac b = b->next; 8525a6ba4734SToby Isaac } 8526a6ba4734SToby Isaac PetscFunctionReturn(0); 8527a6ba4734SToby Isaac } 85284d6f44ffSToby Isaac 85294d6f44ffSToby Isaac /*@C 8530a6e0b375SMatthew G. Knepley DMProjectFunction - This projects the given function into the function space provided, putting the coefficients in a global vector. 8531a6e0b375SMatthew G. Knepley 8532a6e0b375SMatthew G. Knepley Collective on DM 85334d6f44ffSToby Isaac 85344d6f44ffSToby Isaac Input Parameters: 85354d6f44ffSToby Isaac + dm - The DM 85360709b2feSToby Isaac . time - The time 85374d6f44ffSToby Isaac . funcs - The coordinate functions to evaluate, one per field 85384d6f44ffSToby Isaac . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 85394d6f44ffSToby Isaac - mode - The insertion mode for values 85404d6f44ffSToby Isaac 85414d6f44ffSToby Isaac Output Parameter: 85424d6f44ffSToby Isaac . X - vector 85434d6f44ffSToby Isaac 85444d6f44ffSToby Isaac Calling sequence of func: 85450709b2feSToby Isaac $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 85464d6f44ffSToby Isaac 85474d6f44ffSToby Isaac + dim - The spatial dimension 85488ec8862eSJed Brown . time - The time at which to sample 85494d6f44ffSToby Isaac . x - The coordinates 85504d6f44ffSToby Isaac . Nf - The number of fields 85514d6f44ffSToby Isaac . u - The output field values 85524d6f44ffSToby Isaac - ctx - optional user-defined function context 85534d6f44ffSToby Isaac 85544d6f44ffSToby Isaac Level: developer 85554d6f44ffSToby Isaac 8556a6e0b375SMatthew G. Knepley .seealso: DMProjectFunctionLocal(), DMProjectFunctionLabel(), DMComputeL2Diff() 85574d6f44ffSToby Isaac @*/ 85580709b2feSToby Isaac PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X) 85594d6f44ffSToby Isaac { 85604d6f44ffSToby Isaac Vec localX; 85614d6f44ffSToby Isaac PetscErrorCode ierr; 85624d6f44ffSToby Isaac 85634d6f44ffSToby Isaac PetscFunctionBegin; 85644d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 85654d6f44ffSToby Isaac ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr); 85660709b2feSToby Isaac ierr = DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr); 85674d6f44ffSToby Isaac ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr); 85684d6f44ffSToby Isaac ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr); 85694d6f44ffSToby Isaac ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr); 85704d6f44ffSToby Isaac PetscFunctionReturn(0); 85714d6f44ffSToby Isaac } 85724d6f44ffSToby Isaac 8573a6e0b375SMatthew G. Knepley /*@C 8574a6e0b375SMatthew G. Knepley DMProjectFunctionLocal - This projects the given function into the function space provided, putting the coefficients in a local vector. 8575a6e0b375SMatthew G. Knepley 8576a6e0b375SMatthew G. Knepley Not collective 8577a6e0b375SMatthew G. Knepley 8578a6e0b375SMatthew G. Knepley Input Parameters: 8579a6e0b375SMatthew G. Knepley + dm - The DM 8580a6e0b375SMatthew G. Knepley . time - The time 8581a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8582a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8583a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8584a6e0b375SMatthew G. Knepley 8585a6e0b375SMatthew G. Knepley Output Parameter: 8586a6e0b375SMatthew G. Knepley . localX - vector 8587a6e0b375SMatthew G. Knepley 8588a6e0b375SMatthew G. Knepley Calling sequence of func: 8589a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 8590a6e0b375SMatthew G. Knepley 8591a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8592a6e0b375SMatthew G. Knepley . x - The coordinates 8593a6e0b375SMatthew G. Knepley . Nf - The number of fields 8594a6e0b375SMatthew G. Knepley . u - The output field values 8595a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8596a6e0b375SMatthew G. Knepley 8597a6e0b375SMatthew G. Knepley Level: developer 8598a6e0b375SMatthew G. Knepley 8599a6e0b375SMatthew G. Knepley .seealso: DMProjectFunction(), DMProjectFunctionLabel(), DMComputeL2Diff() 8600a6e0b375SMatthew G. Knepley @*/ 86010709b2feSToby Isaac PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 86024d6f44ffSToby Isaac { 86034d6f44ffSToby Isaac PetscErrorCode ierr; 86044d6f44ffSToby Isaac 86054d6f44ffSToby Isaac PetscFunctionBegin; 86064d6f44ffSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 86074d6f44ffSToby Isaac PetscValidHeaderSpecific(localX,VEC_CLASSID,5); 86080918c465SMatthew G. Knepley if (!dm->ops->projectfunctionlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLocal",((PetscObject)dm)->type_name); 86090709b2feSToby Isaac ierr = (dm->ops->projectfunctionlocal) (dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr); 86104d6f44ffSToby Isaac PetscFunctionReturn(0); 86114d6f44ffSToby Isaac } 86124d6f44ffSToby Isaac 8613a6e0b375SMatthew G. Knepley /*@C 8614a6e0b375SMatthew 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. 8615a6e0b375SMatthew G. Knepley 8616a6e0b375SMatthew G. Knepley Collective on DM 8617a6e0b375SMatthew G. Knepley 8618a6e0b375SMatthew G. Knepley Input Parameters: 8619a6e0b375SMatthew G. Knepley + dm - The DM 8620a6e0b375SMatthew G. Knepley . time - The time 8621a6e0b375SMatthew G. Knepley . label - The DMLabel selecting the portion of the mesh for projection 8622a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8623a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8624a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8625a6e0b375SMatthew G. Knepley 8626a6e0b375SMatthew G. Knepley Output Parameter: 8627a6e0b375SMatthew G. Knepley . X - vector 8628a6e0b375SMatthew G. Knepley 8629a6e0b375SMatthew G. Knepley Calling sequence of func: 8630a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 8631a6e0b375SMatthew G. Knepley 8632a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8633a6e0b375SMatthew G. Knepley . x - The coordinates 8634a6e0b375SMatthew G. Knepley . Nf - The number of fields 8635a6e0b375SMatthew G. Knepley . u - The output field values 8636a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8637a6e0b375SMatthew G. Knepley 8638a6e0b375SMatthew G. Knepley Level: developer 8639a6e0b375SMatthew G. Knepley 8640a6e0b375SMatthew G. Knepley .seealso: DMProjectFunction(), DMProjectFunctionLocal(), DMProjectFunctionLabelLocal(), DMComputeL2Diff() 8641a6e0b375SMatthew G. Knepley @*/ 86422c53366bSMatthew 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) 86432c53366bSMatthew G. Knepley { 86442c53366bSMatthew G. Knepley Vec localX; 86452c53366bSMatthew G. Knepley PetscErrorCode ierr; 86462c53366bSMatthew G. Knepley 86472c53366bSMatthew G. Knepley PetscFunctionBegin; 86482c53366bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 86492c53366bSMatthew G. Knepley ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr); 86502c53366bSMatthew G. Knepley ierr = DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr); 86512c53366bSMatthew G. Knepley ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr); 86522c53366bSMatthew G. Knepley ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr); 86532c53366bSMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr); 86542c53366bSMatthew G. Knepley PetscFunctionReturn(0); 86552c53366bSMatthew G. Knepley } 86562c53366bSMatthew G. Knepley 8657a6e0b375SMatthew G. Knepley /*@C 8658a6e0b375SMatthew 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. 8659a6e0b375SMatthew G. Knepley 8660a6e0b375SMatthew G. Knepley Not collective 8661a6e0b375SMatthew G. Knepley 8662a6e0b375SMatthew G. Knepley Input Parameters: 8663a6e0b375SMatthew G. Knepley + dm - The DM 8664a6e0b375SMatthew G. Knepley . time - The time 8665a6e0b375SMatthew G. Knepley . label - The DMLabel selecting the portion of the mesh for projection 8666a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8667a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8668a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8669a6e0b375SMatthew G. Knepley 8670a6e0b375SMatthew G. Knepley Output Parameter: 8671a6e0b375SMatthew G. Knepley . localX - vector 8672a6e0b375SMatthew G. Knepley 8673a6e0b375SMatthew G. Knepley Calling sequence of func: 8674a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 8675a6e0b375SMatthew G. Knepley 8676a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8677a6e0b375SMatthew G. Knepley . x - The coordinates 8678a6e0b375SMatthew G. Knepley . Nf - The number of fields 8679a6e0b375SMatthew G. Knepley . u - The output field values 8680a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8681a6e0b375SMatthew G. Knepley 8682a6e0b375SMatthew G. Knepley Level: developer 8683a6e0b375SMatthew G. Knepley 8684a6e0b375SMatthew G. Knepley .seealso: DMProjectFunction(), DMProjectFunctionLocal(), DMProjectFunctionLabel(), DMComputeL2Diff() 8685a6e0b375SMatthew G. Knepley @*/ 86861c531cf8SMatthew 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) 86874d6f44ffSToby Isaac { 86884d6f44ffSToby Isaac PetscErrorCode ierr; 86894d6f44ffSToby Isaac 86904d6f44ffSToby Isaac PetscFunctionBegin; 86914d6f44ffSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 86924d6f44ffSToby Isaac PetscValidHeaderSpecific(localX,VEC_CLASSID,5); 86930918c465SMatthew G. Knepley if (!dm->ops->projectfunctionlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLabelLocal",((PetscObject)dm)->type_name); 86941c531cf8SMatthew G. Knepley ierr = (dm->ops->projectfunctionlabellocal) (dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr); 86954d6f44ffSToby Isaac PetscFunctionReturn(0); 86964d6f44ffSToby Isaac } 86972716604bSToby Isaac 8698a6e0b375SMatthew G. Knepley /*@C 8699a6e0b375SMatthew G. Knepley DMProjectFieldLocal - This projects the given function of the input fields into the function space provided, putting the coefficients in a local vector. 8700a6e0b375SMatthew G. Knepley 8701a6e0b375SMatthew G. Knepley Not collective 8702a6e0b375SMatthew G. Knepley 8703a6e0b375SMatthew G. Knepley Input Parameters: 8704a6e0b375SMatthew G. Knepley + dm - The DM 8705a6e0b375SMatthew G. Knepley . time - The time 8706a6e0b375SMatthew G. Knepley . localU - The input field vector 8707a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8708a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8709a6e0b375SMatthew G. Knepley 8710a6e0b375SMatthew G. Knepley Output Parameter: 8711a6e0b375SMatthew G. Knepley . localX - The output vector 8712a6e0b375SMatthew G. Knepley 8713a6e0b375SMatthew G. Knepley Calling sequence of func: 8714a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8715a6e0b375SMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8716a6e0b375SMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8717a6e0b375SMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8718a6e0b375SMatthew G. Knepley 8719a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8720a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8721a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8722a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8723a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8724a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8725a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8726a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8727a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8728a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8729a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8730a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8731a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8732a6e0b375SMatthew G. Knepley . t - The current time 8733a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8734a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8735a6e0b375SMatthew G. Knepley . constants - The value of each constant 8736a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8737a6e0b375SMatthew G. Knepley 8738a6e0b375SMatthew 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. 8739a6e0b375SMatthew 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 8740a6e0b375SMatthew 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 8741a6e0b375SMatthew 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. 8742a6e0b375SMatthew G. Knepley 8743a6e0b375SMatthew G. Knepley Level: intermediate 8744a6e0b375SMatthew G. Knepley 8745a6e0b375SMatthew G. Knepley .seealso: DMProjectField(), DMProjectFieldLabelLocal(), DMProjectFunction(), DMComputeL2Diff() 8746a6e0b375SMatthew G. Knepley @*/ 87478c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal(DM dm, PetscReal time, Vec localU, 87488c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 87498c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 87508c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8751191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 87528c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 87538c6c5593SMatthew G. Knepley { 87548c6c5593SMatthew G. Knepley PetscErrorCode ierr; 87558c6c5593SMatthew G. Knepley 87568c6c5593SMatthew G. Knepley PetscFunctionBegin; 87578c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 87588c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,3); 87598c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,6); 87600918c465SMatthew G. Knepley if (!dm->ops->projectfieldlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name); 87618c6c5593SMatthew G. Knepley ierr = (dm->ops->projectfieldlocal) (dm, time, localU, funcs, mode, localX);CHKERRQ(ierr); 87628c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 87638c6c5593SMatthew G. Knepley } 87648c6c5593SMatthew G. Knepley 8765a6e0b375SMatthew G. Knepley /*@C 8766a6e0b375SMatthew 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. 8767a6e0b375SMatthew G. Knepley 8768a6e0b375SMatthew G. Knepley Not collective 8769a6e0b375SMatthew G. Knepley 8770a6e0b375SMatthew G. Knepley Input Parameters: 8771a6e0b375SMatthew G. Knepley + dm - The DM 8772a6e0b375SMatthew G. Knepley . time - The time 8773a6e0b375SMatthew G. Knepley . label - The DMLabel marking the portion of the domain to output 8774a6e0b375SMatthew G. Knepley . numIds - The number of label ids to use 8775a6e0b375SMatthew G. Knepley . ids - The label ids to use for marking 8776a6e0b375SMatthew G. Knepley . Nc - The number of components to set in the output, or PETSC_DETERMINE for all components 8777a6e0b375SMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8778a6e0b375SMatthew G. Knepley . localU - The input field vector 8779a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8780a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8781a6e0b375SMatthew G. Knepley 8782a6e0b375SMatthew G. Knepley Output Parameter: 8783a6e0b375SMatthew G. Knepley . localX - The output vector 8784a6e0b375SMatthew G. Knepley 8785a6e0b375SMatthew G. Knepley Calling sequence of func: 8786a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8787a6e0b375SMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8788a6e0b375SMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8789a6e0b375SMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8790a6e0b375SMatthew G. Knepley 8791a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8792a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8793a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8794a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8795a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8796a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8797a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8798a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8799a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8800a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8801a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8802a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8803a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8804a6e0b375SMatthew G. Knepley . t - The current time 8805a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8806a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8807a6e0b375SMatthew G. Knepley . constants - The value of each constant 8808a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8809a6e0b375SMatthew G. Knepley 8810a6e0b375SMatthew 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. 8811a6e0b375SMatthew 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 8812a6e0b375SMatthew 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 8813a6e0b375SMatthew 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. 8814a6e0b375SMatthew G. Knepley 8815a6e0b375SMatthew G. Knepley Level: intermediate 8816a6e0b375SMatthew G. Knepley 8817a6e0b375SMatthew G. Knepley .seealso: DMProjectField(), DMProjectFieldLabelLocal(), DMProjectFunction(), DMComputeL2Diff() 8818a6e0b375SMatthew G. Knepley @*/ 88191c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, 88208c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 88218c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 88228c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8823191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 88248c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 88258c6c5593SMatthew G. Knepley { 88268c6c5593SMatthew G. Knepley PetscErrorCode ierr; 88278c6c5593SMatthew G. Knepley 88288c6c5593SMatthew G. Knepley PetscFunctionBegin; 88298c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 88308c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,6); 88318c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,9); 8832ece3a9fcSMatthew G. Knepley if (!dm->ops->projectfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLabelLocal",((PetscObject)dm)->type_name); 88331c531cf8SMatthew G. Knepley ierr = (dm->ops->projectfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX);CHKERRQ(ierr); 88348c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 88358c6c5593SMatthew G. Knepley } 88368c6c5593SMatthew G. Knepley 88372716604bSToby Isaac /*@C 8838ece3a9fcSMatthew 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. 8839ece3a9fcSMatthew G. Knepley 8840ece3a9fcSMatthew G. Knepley Not collective 8841ece3a9fcSMatthew G. Knepley 8842ece3a9fcSMatthew G. Knepley Input Parameters: 8843ece3a9fcSMatthew G. Knepley + dm - The DM 8844ece3a9fcSMatthew G. Knepley . time - The time 8845ece3a9fcSMatthew G. Knepley . label - The DMLabel marking the portion of the domain boundary to output 8846ece3a9fcSMatthew G. Knepley . numIds - The number of label ids to use 8847ece3a9fcSMatthew G. Knepley . ids - The label ids to use for marking 8848ece3a9fcSMatthew G. Knepley . Nc - The number of components to set in the output, or PETSC_DETERMINE for all components 8849ece3a9fcSMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8850ece3a9fcSMatthew G. Knepley . localU - The input field vector 8851ece3a9fcSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8852ece3a9fcSMatthew G. Knepley - mode - The insertion mode for values 8853ece3a9fcSMatthew G. Knepley 8854ece3a9fcSMatthew G. Knepley Output Parameter: 8855ece3a9fcSMatthew G. Knepley . localX - The output vector 8856ece3a9fcSMatthew G. Knepley 8857ece3a9fcSMatthew G. Knepley Calling sequence of func: 8858ece3a9fcSMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8859ece3a9fcSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8860ece3a9fcSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8861ece3a9fcSMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8862ece3a9fcSMatthew G. Knepley 8863ece3a9fcSMatthew G. Knepley + dim - The spatial dimension 8864ece3a9fcSMatthew G. Knepley . Nf - The number of input fields 8865ece3a9fcSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8866ece3a9fcSMatthew G. Knepley . uOff - The offset of each field in u[] 8867ece3a9fcSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8868ece3a9fcSMatthew G. Knepley . u - The field values at this point in space 8869ece3a9fcSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8870ece3a9fcSMatthew G. Knepley . u_x - The field derivatives at this point in space 8871ece3a9fcSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8872ece3a9fcSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8873ece3a9fcSMatthew G. Knepley . a - The auxiliary field values at this point in space 8874ece3a9fcSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8875ece3a9fcSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8876ece3a9fcSMatthew G. Knepley . t - The current time 8877ece3a9fcSMatthew G. Knepley . x - The coordinates of this point 8878ece3a9fcSMatthew G. Knepley . n - The face normal 8879ece3a9fcSMatthew G. Knepley . numConstants - The number of constants 8880ece3a9fcSMatthew G. Knepley . constants - The value of each constant 8881ece3a9fcSMatthew G. Knepley - f - The value of the function at this point in space 8882ece3a9fcSMatthew G. Knepley 8883ece3a9fcSMatthew G. Knepley Note: 8884ece3a9fcSMatthew 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. 8885ece3a9fcSMatthew 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 8886ece3a9fcSMatthew 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 8887ece3a9fcSMatthew 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. 8888ece3a9fcSMatthew G. Knepley 8889ece3a9fcSMatthew G. Knepley Level: intermediate 8890ece3a9fcSMatthew G. Knepley 8891ece3a9fcSMatthew G. Knepley .seealso: DMProjectField(), DMProjectFieldLabelLocal(), DMProjectFunction(), DMComputeL2Diff() 8892ece3a9fcSMatthew G. Knepley @*/ 8893ece3a9fcSMatthew G. Knepley PetscErrorCode DMProjectBdFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, 8894ece3a9fcSMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 8895ece3a9fcSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8896ece3a9fcSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8897ece3a9fcSMatthew G. Knepley PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 8898ece3a9fcSMatthew G. Knepley InsertMode mode, Vec localX) 8899ece3a9fcSMatthew G. Knepley { 8900ece3a9fcSMatthew G. Knepley PetscErrorCode ierr; 8901ece3a9fcSMatthew G. Knepley 8902ece3a9fcSMatthew G. Knepley PetscFunctionBegin; 8903ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8904ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,6); 8905ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,9); 8906ece3a9fcSMatthew G. Knepley if (!dm->ops->projectbdfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectBdFieldLabelLocal",((PetscObject)dm)->type_name); 8907ece3a9fcSMatthew G. Knepley ierr = (dm->ops->projectbdfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX);CHKERRQ(ierr); 8908ece3a9fcSMatthew G. Knepley PetscFunctionReturn(0); 8909ece3a9fcSMatthew G. Knepley } 8910ece3a9fcSMatthew G. Knepley 8911ece3a9fcSMatthew G. Knepley /*@C 89122716604bSToby Isaac DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h. 89132716604bSToby Isaac 89142716604bSToby Isaac Input Parameters: 89152716604bSToby Isaac + dm - The DM 89160709b2feSToby Isaac . time - The time 89172716604bSToby Isaac . funcs - The functions to evaluate for each field component 89182716604bSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8919574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 89202716604bSToby Isaac 89212716604bSToby Isaac Output Parameter: 89222716604bSToby Isaac . diff - The diff ||u - u_h||_2 89232716604bSToby Isaac 89242716604bSToby Isaac Level: developer 89252716604bSToby Isaac 89261189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff() 89272716604bSToby Isaac @*/ 89280709b2feSToby Isaac PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff) 89292716604bSToby Isaac { 89302716604bSToby Isaac PetscErrorCode ierr; 89312716604bSToby Isaac 89322716604bSToby Isaac PetscFunctionBegin; 89332716604bSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8934b698f381SToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 89350918c465SMatthew G. Knepley if (!dm->ops->computel2diff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2Diff",((PetscObject)dm)->type_name); 89360709b2feSToby Isaac ierr = (dm->ops->computel2diff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr); 89372716604bSToby Isaac PetscFunctionReturn(0); 89382716604bSToby Isaac } 8939b698f381SToby Isaac 8940b698f381SToby Isaac /*@C 8941b698f381SToby Isaac DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h. 8942b698f381SToby Isaac 8943d083f849SBarry Smith Collective on dm 8944d083f849SBarry Smith 8945b698f381SToby Isaac Input Parameters: 8946b698f381SToby Isaac + dm - The DM 8947b698f381SToby Isaac , time - The time 8948b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component 8949b698f381SToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8950574a98acSMatthew G. Knepley . X - The coefficient vector u_h, a global vector 8951b698f381SToby Isaac - n - The vector to project along 8952b698f381SToby Isaac 8953b698f381SToby Isaac Output Parameter: 8954b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2 8955b698f381SToby Isaac 8956b698f381SToby Isaac Level: developer 8957b698f381SToby Isaac 8958b698f381SToby Isaac .seealso: DMProjectFunction(), DMComputeL2Diff() 8959b698f381SToby Isaac @*/ 8960b698f381SToby 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) 8961b698f381SToby Isaac { 8962b698f381SToby Isaac PetscErrorCode ierr; 8963b698f381SToby Isaac 8964b698f381SToby Isaac PetscFunctionBegin; 8965b698f381SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8966b698f381SToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 8967b698f381SToby Isaac if (!dm->ops->computel2gradientdiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2GradientDiff",((PetscObject)dm)->type_name); 8968b698f381SToby Isaac ierr = (dm->ops->computel2gradientdiff)(dm,time,funcs,ctxs,X,n,diff);CHKERRQ(ierr); 8969b698f381SToby Isaac PetscFunctionReturn(0); 8970b698f381SToby Isaac } 8971b698f381SToby Isaac 89722a16baeaSToby Isaac /*@C 89732a16baeaSToby Isaac DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components. 89742a16baeaSToby Isaac 8975d083f849SBarry Smith Collective on dm 8976d083f849SBarry Smith 89772a16baeaSToby Isaac Input Parameters: 89782a16baeaSToby Isaac + dm - The DM 89792a16baeaSToby Isaac . time - The time 89802a16baeaSToby Isaac . funcs - The functions to evaluate for each field component 89812a16baeaSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8982574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 89832a16baeaSToby Isaac 89842a16baeaSToby Isaac Output Parameter: 89852a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2 89862a16baeaSToby Isaac 89872a16baeaSToby Isaac Level: developer 89882a16baeaSToby Isaac 89891189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff() 89902a16baeaSToby Isaac @*/ 89911189c1efSToby Isaac PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[]) 89922a16baeaSToby Isaac { 89932a16baeaSToby Isaac PetscErrorCode ierr; 89942a16baeaSToby Isaac 89952a16baeaSToby Isaac PetscFunctionBegin; 89962a16baeaSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 89972a16baeaSToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 89980918c465SMatthew G. Knepley if (!dm->ops->computel2fielddiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2FieldDiff",((PetscObject)dm)->type_name); 89992a16baeaSToby Isaac ierr = (dm->ops->computel2fielddiff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr); 90002a16baeaSToby Isaac PetscFunctionReturn(0); 90012a16baeaSToby Isaac } 90022a16baeaSToby Isaac 9003df0b854cSToby Isaac /*@C 9004df0b854cSToby Isaac DMAdaptLabel - Adapt a dm based on a label with values interpreted as coarsening and refining flags. Specific implementations of DM maybe have 9005cd3c525cSToby Isaac specialized flags, but all implementations should accept flag values DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN. 9006df0b854cSToby Isaac 9007df0b854cSToby Isaac Collective on dm 9008df0b854cSToby Isaac 9009df0b854cSToby Isaac Input parameters: 9010df0b854cSToby Isaac + dm - the pre-adaptation DM object 9011a1b0c543SToby Isaac - label - label with the flags 9012df0b854cSToby Isaac 9013df0b854cSToby Isaac Output parameters: 90140d1cd5e0SMatthew G. Knepley . dmAdapt - the adapted DM object: may be NULL if an adapted DM could not be produced. 9015df0b854cSToby Isaac 9016df0b854cSToby Isaac Level: intermediate 90170d1cd5e0SMatthew G. Knepley 90180d1cd5e0SMatthew G. Knepley .seealso: DMAdaptMetric(), DMCoarsen(), DMRefine() 9019df0b854cSToby Isaac @*/ 90200d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptLabel(DM dm, DMLabel label, DM *dmAdapt) 9021df0b854cSToby Isaac { 9022df0b854cSToby Isaac PetscErrorCode ierr; 9023df0b854cSToby Isaac 9024df0b854cSToby Isaac PetscFunctionBegin; 9025df0b854cSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9026a1b0c543SToby Isaac PetscValidPointer(label,2); 90270d1cd5e0SMatthew G. Knepley PetscValidPointer(dmAdapt,3); 90280d1cd5e0SMatthew G. Knepley *dmAdapt = NULL; 90296f25b0d8SLisandro Dalcin if (!dm->ops->adaptlabel) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptLabel",((PetscObject)dm)->type_name); 90300d1cd5e0SMatthew G. Knepley ierr = (dm->ops->adaptlabel)(dm, label, dmAdapt);CHKERRQ(ierr); 9031a587d139SMark if (*dmAdapt) { 9032a587d139SMark (*dmAdapt)->prealloc_only = dm->prealloc_only; /* maybe this should go .... */ 9033a587d139SMark ierr = PetscFree((*dmAdapt)->vectype);CHKERRQ(ierr); 9034a587d139SMark ierr = PetscStrallocpy(dm->vectype,(char**)&(*dmAdapt)->vectype);CHKERRQ(ierr); 9035a587d139SMark ierr = PetscFree((*dmAdapt)->mattype);CHKERRQ(ierr); 9036a587d139SMark ierr = PetscStrallocpy(dm->mattype,(char**)&(*dmAdapt)->mattype);CHKERRQ(ierr); 9037a587d139SMark } 90380d1cd5e0SMatthew G. Knepley PetscFunctionReturn(0); 90390d1cd5e0SMatthew G. Knepley } 90400d1cd5e0SMatthew G. Knepley 90410d1cd5e0SMatthew G. Knepley /*@C 90420d1cd5e0SMatthew G. Knepley DMAdaptMetric - Generates a mesh adapted to the specified metric field using the pragmatic library. 90430d1cd5e0SMatthew G. Knepley 90440d1cd5e0SMatthew G. Knepley Input Parameters: 90450d1cd5e0SMatthew G. Knepley + dm - The DM object 90460d1cd5e0SMatthew G. Knepley . metric - The metric to which the mesh is adapted, defined vertex-wise. 90476f25b0d8SLisandro 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_". 90480d1cd5e0SMatthew G. Knepley 90490d1cd5e0SMatthew G. Knepley Output Parameter: 90500d1cd5e0SMatthew G. Knepley . dmAdapt - Pointer to the DM object containing the adapted mesh 90510d1cd5e0SMatthew G. Knepley 90520d1cd5e0SMatthew G. Knepley Note: The label in the adapted mesh will be registered under the name of the input DMLabel object 90530d1cd5e0SMatthew G. Knepley 90540d1cd5e0SMatthew G. Knepley Level: advanced 90550d1cd5e0SMatthew G. Knepley 90560d1cd5e0SMatthew G. Knepley .seealso: DMAdaptLabel(), DMCoarsen(), DMRefine() 90570d1cd5e0SMatthew G. Knepley @*/ 90580d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptMetric(DM dm, Vec metric, DMLabel bdLabel, DM *dmAdapt) 90590d1cd5e0SMatthew G. Knepley { 90600d1cd5e0SMatthew G. Knepley PetscErrorCode ierr; 90610d1cd5e0SMatthew G. Knepley 90620d1cd5e0SMatthew G. Knepley PetscFunctionBegin; 90630d1cd5e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90640d1cd5e0SMatthew G. Knepley PetscValidHeaderSpecific(metric, VEC_CLASSID, 2); 90650d1cd5e0SMatthew G. Knepley if (bdLabel) PetscValidPointer(bdLabel, 3); 90660d1cd5e0SMatthew G. Knepley PetscValidPointer(dmAdapt, 4); 90676f25b0d8SLisandro Dalcin *dmAdapt = NULL; 90686f25b0d8SLisandro Dalcin if (!dm->ops->adaptmetric) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptMetric",((PetscObject)dm)->type_name); 90690d1cd5e0SMatthew G. Knepley ierr = (dm->ops->adaptmetric)(dm, metric, bdLabel, dmAdapt);CHKERRQ(ierr); 9070df0b854cSToby Isaac PetscFunctionReturn(0); 9071df0b854cSToby Isaac } 9072c4088d22SMatthew G. Knepley 9073502a2867SDave May /*@C 9074502a2867SDave May DMGetNeighbors - Gets an array containing the MPI rank of all the processes neighbors 9075502a2867SDave May 9076502a2867SDave May Not Collective 9077502a2867SDave May 9078502a2867SDave May Input Parameter: 9079502a2867SDave May . dm - The DM 9080502a2867SDave May 90810a19bb7dSprj- Output Parameters: 90820a19bb7dSprj- + nranks - the number of neighbours 90830a19bb7dSprj- - ranks - the neighbors ranks 9084502a2867SDave May 9085502a2867SDave May Notes: 9086502a2867SDave May Do not free the array, it is freed when the DM is destroyed. 9087502a2867SDave May 9088502a2867SDave May Level: beginner 9089502a2867SDave May 9090dec1416fSJunchao Zhang .seealso: DMDAGetNeighbors(), PetscSFGetRootRanks() 9091502a2867SDave May @*/ 9092502a2867SDave May PetscErrorCode DMGetNeighbors(DM dm,PetscInt *nranks,const PetscMPIInt *ranks[]) 9093502a2867SDave May { 9094502a2867SDave May PetscErrorCode ierr; 9095502a2867SDave May 9096502a2867SDave May PetscFunctionBegin; 9097502a2867SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 90980918c465SMatthew G. Knepley if (!dm->ops->getneighbors) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMGetNeighbors",((PetscObject)dm)->type_name); 9099502a2867SDave May ierr = (dm->ops->getneighbors)(dm,nranks,ranks);CHKERRQ(ierr); 9100502a2867SDave May PetscFunctionReturn(0); 9101502a2867SDave May } 9102502a2867SDave May 9103531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */ 9104531c7667SBarry Smith 9105531c7667SBarry Smith /* 9106531c7667SBarry Smith Converts the input vector to a ghosted vector and then calls the standard coloring code. 9107531c7667SBarry Smith This has be a different function because it requires DM which is not defined in the Mat library 9108531c7667SBarry Smith */ 9109531c7667SBarry Smith PetscErrorCode MatFDColoringApply_AIJDM(Mat J,MatFDColoring coloring,Vec x1,void *sctx) 9110531c7667SBarry Smith { 9111531c7667SBarry Smith PetscErrorCode ierr; 9112531c7667SBarry Smith 9113531c7667SBarry Smith PetscFunctionBegin; 9114531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 9115531c7667SBarry Smith Vec x1local; 9116531c7667SBarry Smith DM dm; 9117531c7667SBarry Smith ierr = MatGetDM(J,&dm);CHKERRQ(ierr); 9118531c7667SBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_INCOMP,"IS_COLORING_LOCAL requires a DM"); 9119531c7667SBarry Smith ierr = DMGetLocalVector(dm,&x1local);CHKERRQ(ierr); 9120531c7667SBarry Smith ierr = DMGlobalToLocalBegin(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr); 9121531c7667SBarry Smith ierr = DMGlobalToLocalEnd(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr); 9122531c7667SBarry Smith x1 = x1local; 9123531c7667SBarry Smith } 9124531c7667SBarry Smith ierr = MatFDColoringApply_AIJ(J,coloring,x1,sctx);CHKERRQ(ierr); 9125531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 9126531c7667SBarry Smith DM dm; 9127531c7667SBarry Smith ierr = MatGetDM(J,&dm);CHKERRQ(ierr); 9128531c7667SBarry Smith ierr = DMRestoreLocalVector(dm,&x1);CHKERRQ(ierr); 9129531c7667SBarry Smith } 9130531c7667SBarry Smith PetscFunctionReturn(0); 9131531c7667SBarry Smith } 9132531c7667SBarry Smith 9133531c7667SBarry Smith /*@ 9134531c7667SBarry Smith MatFDColoringUseDM - allows a MatFDColoring object to use the DM associated with the matrix to use a IS_COLORING_LOCAL coloring 9135531c7667SBarry Smith 9136531c7667SBarry Smith Input Parameter: 9137531c7667SBarry Smith . coloring - the MatFDColoring object 9138531c7667SBarry Smith 913995452b02SPatrick Sanan Developer Notes: 914095452b02SPatrick Sanan this routine exists because the PETSc Mat library does not know about the DM objects 9141531c7667SBarry Smith 91421b266c99SBarry Smith Level: advanced 91431b266c99SBarry Smith 9144531c7667SBarry Smith .seealso: MatFDColoring, MatFDColoringCreate(), ISColoringType 9145531c7667SBarry Smith @*/ 9146531c7667SBarry Smith PetscErrorCode MatFDColoringUseDM(Mat coloring,MatFDColoring fdcoloring) 9147531c7667SBarry Smith { 9148531c7667SBarry Smith PetscFunctionBegin; 9149531c7667SBarry Smith coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM; 9150531c7667SBarry Smith PetscFunctionReturn(0); 9151531c7667SBarry Smith } 91528320bc6fSPatrick Sanan 91538320bc6fSPatrick Sanan /*@ 91548320bc6fSPatrick Sanan DMGetCompatibility - determine if two DMs are compatible 91558320bc6fSPatrick Sanan 91568320bc6fSPatrick Sanan Collective 91578320bc6fSPatrick Sanan 91588320bc6fSPatrick Sanan Input Parameters: 9159a5bc1bf3SBarry Smith + dm1 - the first DM 91608320bc6fSPatrick Sanan - dm2 - the second DM 91618320bc6fSPatrick Sanan 91628320bc6fSPatrick Sanan Output Parameters: 91638320bc6fSPatrick Sanan + compatible - whether or not the two DMs are compatible 91648320bc6fSPatrick Sanan - set - whether or not the compatible value was set 91658320bc6fSPatrick Sanan 91668320bc6fSPatrick Sanan Notes: 91678320bc6fSPatrick Sanan Two DMs are deemed compatible if they represent the same parallel decomposition 91683d862458SPatrick Sanan of the same topology. This implies that the section (field data) on one 91698320bc6fSPatrick Sanan "makes sense" with respect to the topology and parallel decomposition of the other. 91703d862458SPatrick Sanan Loosely speaking, compatible DMs represent the same domain and parallel 91713d862458SPatrick Sanan decomposition, but hold different data. 91728320bc6fSPatrick Sanan 91738320bc6fSPatrick Sanan Typically, one would confirm compatibility if intending to simultaneously iterate 91748320bc6fSPatrick Sanan over a pair of vectors obtained from different DMs. 91758320bc6fSPatrick Sanan 91768320bc6fSPatrick Sanan For example, two DMDA objects are compatible if they have the same local 91778320bc6fSPatrick Sanan and global sizes and the same stencil width. They can have different numbers 91788320bc6fSPatrick Sanan of degrees of freedom per node. Thus, one could use the node numbering from 91798320bc6fSPatrick Sanan either DM in bounds for a loop over vectors derived from either DM. 91808320bc6fSPatrick Sanan 91818320bc6fSPatrick Sanan Consider the operation of summing data living on a 2-dof DMDA to data living 91828320bc6fSPatrick Sanan on a 1-dof DMDA, which should be compatible, as in the following snippet. 91838320bc6fSPatrick Sanan .vb 91848320bc6fSPatrick Sanan ... 91858320bc6fSPatrick Sanan ierr = DMGetCompatibility(da1,da2,&compatible,&set);CHKERRQ(ierr); 91868320bc6fSPatrick Sanan if (set && compatible) { 91878320bc6fSPatrick Sanan ierr = DMDAVecGetArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr); 91888320bc6fSPatrick Sanan ierr = DMDAVecGetArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr); 91893d862458SPatrick Sanan ierr = DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL);CHKERRQ(ierr); 91908320bc6fSPatrick Sanan for (j=y; j<y+n; ++j) { 91918320bc6fSPatrick Sanan for (i=x; i<x+m, ++i) { 91928320bc6fSPatrick Sanan arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1]; 91938320bc6fSPatrick Sanan } 91948320bc6fSPatrick Sanan } 91958320bc6fSPatrick Sanan ierr = DMDAVecRestoreArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr); 91968320bc6fSPatrick Sanan ierr = DMDAVecRestoreArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr); 91978320bc6fSPatrick Sanan } else { 91988320bc6fSPatrick Sanan SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible"); 91998320bc6fSPatrick Sanan } 92008320bc6fSPatrick Sanan ... 92018320bc6fSPatrick Sanan .ve 92028320bc6fSPatrick Sanan 92038320bc6fSPatrick Sanan Checking compatibility might be expensive for a given implementation of DM, 92048320bc6fSPatrick Sanan or might be impossible to unambiguously confirm or deny. For this reason, 92058320bc6fSPatrick Sanan this function may decline to determine compatibility, and hence users should 92068320bc6fSPatrick Sanan always check the "set" output parameter. 92078320bc6fSPatrick Sanan 92088320bc6fSPatrick Sanan A DM is always compatible with itself. 92098320bc6fSPatrick Sanan 92108320bc6fSPatrick Sanan In the current implementation, DMs which live on "unequal" communicators 92118320bc6fSPatrick Sanan (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed 92128320bc6fSPatrick Sanan incompatible. 92138320bc6fSPatrick Sanan 92148320bc6fSPatrick Sanan This function is labeled "Collective," as information about all subdomains 92158320bc6fSPatrick Sanan is required on each rank. However, in DM implementations which store all this 92168320bc6fSPatrick Sanan information locally, this function may be merely "Logically Collective". 92178320bc6fSPatrick Sanan 92188320bc6fSPatrick Sanan Developer Notes: 92193d862458SPatrick Sanan Compatibility is assumed to be a symmetric concept; DM A is compatible with DM B 92203d862458SPatrick Sanan iff B is compatible with A. Thus, this function checks the implementations 9221a5bc1bf3SBarry Smith of both dm and dmc (if they are of different types), attempting to determine 92228320bc6fSPatrick Sanan compatibility. It is left to DM implementers to ensure that symmetry is 92238320bc6fSPatrick Sanan preserved. The simplest way to do this is, when implementing type-specific 92243d862458SPatrick Sanan logic for this function, is to check for existing logic in the implementation 92253d862458SPatrick Sanan of other DM types and let *set = PETSC_FALSE if found. 92268320bc6fSPatrick Sanan 92278320bc6fSPatrick Sanan Level: advanced 92288320bc6fSPatrick Sanan 92293d862458SPatrick Sanan .seealso: DM, DMDACreateCompatibleDMDA(), DMStagCreateCompatibleDMStag() 92308320bc6fSPatrick Sanan @*/ 92318320bc6fSPatrick Sanan 9232a5bc1bf3SBarry Smith PetscErrorCode DMGetCompatibility(DM dm1,DM dm2,PetscBool *compatible,PetscBool *set) 92338320bc6fSPatrick Sanan { 92348320bc6fSPatrick Sanan PetscErrorCode ierr; 92358320bc6fSPatrick Sanan PetscMPIInt compareResult; 92368320bc6fSPatrick Sanan DMType type,type2; 92378320bc6fSPatrick Sanan PetscBool sameType; 92388320bc6fSPatrick Sanan 92398320bc6fSPatrick Sanan PetscFunctionBegin; 9240a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dm1,DM_CLASSID,1); 92418320bc6fSPatrick Sanan PetscValidHeaderSpecific(dm2,DM_CLASSID,2); 92428320bc6fSPatrick Sanan 92438320bc6fSPatrick Sanan /* Declare a DM compatible with itself */ 9244a5bc1bf3SBarry Smith if (dm1 == dm2) { 92458320bc6fSPatrick Sanan *set = PETSC_TRUE; 92468320bc6fSPatrick Sanan *compatible = PETSC_TRUE; 92478320bc6fSPatrick Sanan PetscFunctionReturn(0); 92488320bc6fSPatrick Sanan } 92498320bc6fSPatrick Sanan 92508320bc6fSPatrick Sanan /* Declare a DM incompatible with a DM that lives on an "unequal" 92518320bc6fSPatrick Sanan communicator. Note that this does not preclude compatibility with 92528320bc6fSPatrick Sanan DMs living on "congruent" or "similar" communicators, but this must be 92538320bc6fSPatrick Sanan determined by the implementation-specific logic */ 9254ffc4695bSBarry Smith ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dm1),PetscObjectComm((PetscObject)dm2),&compareResult);CHKERRMPI(ierr); 92558320bc6fSPatrick Sanan if (compareResult == MPI_UNEQUAL) { 92568320bc6fSPatrick Sanan *set = PETSC_TRUE; 92578320bc6fSPatrick Sanan *compatible = PETSC_FALSE; 92588320bc6fSPatrick Sanan PetscFunctionReturn(0); 92598320bc6fSPatrick Sanan } 92608320bc6fSPatrick Sanan 92618320bc6fSPatrick Sanan /* Pass to the implementation-specific routine, if one exists. */ 9262a5bc1bf3SBarry Smith if (dm1->ops->getcompatibility) { 9263a5bc1bf3SBarry Smith ierr = (*dm1->ops->getcompatibility)(dm1,dm2,compatible,set);CHKERRQ(ierr); 9264b9d85ea2SLisandro Dalcin if (*set) PetscFunctionReturn(0); 92658320bc6fSPatrick Sanan } 92668320bc6fSPatrick Sanan 9267a5bc1bf3SBarry Smith /* If dm1 and dm2 are of different types, then attempt to check compatibility 92688320bc6fSPatrick Sanan with an implementation of this function from dm2 */ 9269a5bc1bf3SBarry Smith ierr = DMGetType(dm1,&type);CHKERRQ(ierr); 92708320bc6fSPatrick Sanan ierr = DMGetType(dm2,&type2);CHKERRQ(ierr); 92718320bc6fSPatrick Sanan ierr = PetscStrcmp(type,type2,&sameType);CHKERRQ(ierr); 92728320bc6fSPatrick Sanan if (!sameType && dm2->ops->getcompatibility) { 9273a5bc1bf3SBarry Smith ierr = (*dm2->ops->getcompatibility)(dm2,dm1,compatible,set);CHKERRQ(ierr); /* Note argument order */ 92748320bc6fSPatrick Sanan } else { 92758320bc6fSPatrick Sanan *set = PETSC_FALSE; 92768320bc6fSPatrick Sanan } 92778320bc6fSPatrick Sanan PetscFunctionReturn(0); 92788320bc6fSPatrick Sanan } 9279c0f0dcc3SMatthew G. Knepley 9280c0f0dcc3SMatthew G. Knepley /*@C 9281c0f0dcc3SMatthew G. Knepley DMMonitorSet - Sets an ADDITIONAL function that is to be used after a solve to monitor discretization performance. 9282c0f0dcc3SMatthew G. Knepley 9283c0f0dcc3SMatthew G. Knepley Logically Collective on DM 9284c0f0dcc3SMatthew G. Knepley 9285c0f0dcc3SMatthew G. Knepley Input Parameters: 9286c0f0dcc3SMatthew G. Knepley + DM - the DM 9287c0f0dcc3SMatthew G. Knepley . f - the monitor function 9288c0f0dcc3SMatthew G. Knepley . mctx - [optional] user-defined context for private data for the monitor routine (use NULL if no context is desired) 9289c0f0dcc3SMatthew G. Knepley - monitordestroy - [optional] routine that frees monitor context (may be NULL) 9290c0f0dcc3SMatthew G. Knepley 9291c0f0dcc3SMatthew G. Knepley Options Database Keys: 9292c0f0dcc3SMatthew G. Knepley - -dm_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to DMMonitorSet(), but 9293c0f0dcc3SMatthew G. Knepley does not cancel those set via the options database. 9294c0f0dcc3SMatthew G. Knepley 9295c0f0dcc3SMatthew G. Knepley Notes: 9296c0f0dcc3SMatthew G. Knepley Several different monitoring routines may be set by calling 9297c0f0dcc3SMatthew G. Knepley DMMonitorSet() multiple times; all will be called in the 9298c0f0dcc3SMatthew G. Knepley order in which they were set. 9299c0f0dcc3SMatthew G. Knepley 9300c0f0dcc3SMatthew G. Knepley Fortran Notes: 9301c0f0dcc3SMatthew G. Knepley Only a single monitor function can be set for each DM object 9302c0f0dcc3SMatthew G. Knepley 9303c0f0dcc3SMatthew G. Knepley Level: intermediate 9304c0f0dcc3SMatthew G. Knepley 9305c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorCancel() 9306c0f0dcc3SMatthew G. Knepley @*/ 9307c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorSet(DM dm, PetscErrorCode (*f)(DM, void *), void *mctx, PetscErrorCode (*monitordestroy)(void**)) 9308c0f0dcc3SMatthew G. Knepley { 9309c0f0dcc3SMatthew G. Knepley PetscInt m; 9310c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9311c0f0dcc3SMatthew G. Knepley 9312c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9313c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9314c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 9315c0f0dcc3SMatthew G. Knepley PetscBool identical; 9316c0f0dcc3SMatthew G. Knepley 9317c0f0dcc3SMatthew G. Knepley ierr = PetscMonitorCompare((PetscErrorCode (*)(void)) f, mctx, monitordestroy, (PetscErrorCode (*)(void)) dm->monitor[m], dm->monitorcontext[m], dm->monitordestroy[m], &identical);CHKERRQ(ierr); 9318c0f0dcc3SMatthew G. Knepley if (identical) PetscFunctionReturn(0); 9319c0f0dcc3SMatthew G. Knepley } 9320c0f0dcc3SMatthew G. Knepley if (dm->numbermonitors >= MAXDMMONITORS) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 9321c0f0dcc3SMatthew G. Knepley dm->monitor[dm->numbermonitors] = f; 9322c0f0dcc3SMatthew G. Knepley dm->monitordestroy[dm->numbermonitors] = monitordestroy; 9323c0f0dcc3SMatthew G. Knepley dm->monitorcontext[dm->numbermonitors++] = (void *) mctx; 9324c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9325c0f0dcc3SMatthew G. Knepley } 9326c0f0dcc3SMatthew G. Knepley 9327c0f0dcc3SMatthew G. Knepley /*@ 9328c0f0dcc3SMatthew G. Knepley DMMonitorCancel - Clears all the monitor functions for a DM object. 9329c0f0dcc3SMatthew G. Knepley 9330c0f0dcc3SMatthew G. Knepley Logically Collective on DM 9331c0f0dcc3SMatthew G. Knepley 9332c0f0dcc3SMatthew G. Knepley Input Parameter: 9333c0f0dcc3SMatthew G. Knepley . dm - the DM 9334c0f0dcc3SMatthew G. Knepley 9335c0f0dcc3SMatthew G. Knepley Options Database Key: 9336c0f0dcc3SMatthew G. Knepley . -dm_monitor_cancel - cancels all monitors that have been hardwired 9337c0f0dcc3SMatthew G. Knepley into a code by calls to DMonitorSet(), but does not cancel those 9338c0f0dcc3SMatthew G. Knepley set via the options database 9339c0f0dcc3SMatthew G. Knepley 9340c0f0dcc3SMatthew G. Knepley Notes: 9341c0f0dcc3SMatthew G. Knepley There is no way to clear one specific monitor from a DM object. 9342c0f0dcc3SMatthew G. Knepley 9343c0f0dcc3SMatthew G. Knepley Level: intermediate 9344c0f0dcc3SMatthew G. Knepley 9345c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorSet() 9346c0f0dcc3SMatthew G. Knepley @*/ 9347c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorCancel(DM dm) 9348c0f0dcc3SMatthew G. Knepley { 9349c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9350c0f0dcc3SMatthew G. Knepley PetscInt m; 9351c0f0dcc3SMatthew G. Knepley 9352c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9353c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9354c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 9355c0f0dcc3SMatthew G. Knepley if (dm->monitordestroy[m]) {ierr = (*dm->monitordestroy[m])(&dm->monitorcontext[m]);CHKERRQ(ierr);} 9356c0f0dcc3SMatthew G. Knepley } 9357c0f0dcc3SMatthew G. Knepley dm->numbermonitors = 0; 9358c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9359c0f0dcc3SMatthew G. Knepley } 9360c0f0dcc3SMatthew G. Knepley 9361c0f0dcc3SMatthew G. Knepley /*@C 9362c0f0dcc3SMatthew G. Knepley DMMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 9363c0f0dcc3SMatthew G. Knepley 9364c0f0dcc3SMatthew G. Knepley Collective on DM 9365c0f0dcc3SMatthew G. Knepley 9366c0f0dcc3SMatthew G. Knepley Input Parameters: 9367c0f0dcc3SMatthew G. Knepley + dm - DM object you wish to monitor 9368c0f0dcc3SMatthew G. Knepley . name - the monitor type one is seeking 9369c0f0dcc3SMatthew G. Knepley . help - message indicating what monitoring is done 9370c0f0dcc3SMatthew G. Knepley . manual - manual page for the monitor 9371c0f0dcc3SMatthew G. Knepley . monitor - the monitor function 9372c0f0dcc3SMatthew 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 9373c0f0dcc3SMatthew G. Knepley 9374c0f0dcc3SMatthew G. Knepley Output Parameter: 9375c0f0dcc3SMatthew G. Knepley . flg - Flag set if the monitor was created 9376c0f0dcc3SMatthew G. Knepley 9377c0f0dcc3SMatthew G. Knepley Level: developer 9378c0f0dcc3SMatthew G. Knepley 9379c0f0dcc3SMatthew G. Knepley .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 9380c0f0dcc3SMatthew G. Knepley PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 9381c0f0dcc3SMatthew G. Knepley PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 9382c0f0dcc3SMatthew G. Knepley PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 9383c0f0dcc3SMatthew G. Knepley PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 9384c0f0dcc3SMatthew G. Knepley PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 9385c0f0dcc3SMatthew G. Knepley PetscOptionsFList(), PetscOptionsEList() 9386c0f0dcc3SMatthew G. Knepley @*/ 9387c0f0dcc3SMatthew 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) 9388c0f0dcc3SMatthew G. Knepley { 9389c0f0dcc3SMatthew G. Knepley PetscViewer viewer; 9390c0f0dcc3SMatthew G. Knepley PetscViewerFormat format; 9391c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9392c0f0dcc3SMatthew G. Knepley 9393c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9394c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9395c0f0dcc3SMatthew G. Knepley ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) dm), ((PetscObject) dm)->options, ((PetscObject) dm)->prefix, name, &viewer, &format, flg);CHKERRQ(ierr); 9396c0f0dcc3SMatthew G. Knepley if (*flg) { 9397c0f0dcc3SMatthew G. Knepley PetscViewerAndFormat *vf; 9398c0f0dcc3SMatthew G. Knepley 9399c0f0dcc3SMatthew G. Knepley ierr = PetscViewerAndFormatCreate(viewer, format, &vf);CHKERRQ(ierr); 9400c0f0dcc3SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) viewer);CHKERRQ(ierr); 9401c0f0dcc3SMatthew G. Knepley if (monitorsetup) {ierr = (*monitorsetup)(dm, vf);CHKERRQ(ierr);} 9402c0f0dcc3SMatthew G. Knepley ierr = DMMonitorSet(dm,(PetscErrorCode (*)(DM, void *)) monitor, vf, (PetscErrorCode (*)(void **)) PetscViewerAndFormatDestroy);CHKERRQ(ierr); 9403c0f0dcc3SMatthew G. Knepley } 9404c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9405c0f0dcc3SMatthew G. Knepley } 9406c0f0dcc3SMatthew G. Knepley 9407c0f0dcc3SMatthew G. Knepley /*@ 9408c0f0dcc3SMatthew G. Knepley DMMonitor - runs the user provided monitor routines, if they exist 9409c0f0dcc3SMatthew G. Knepley 9410c0f0dcc3SMatthew G. Knepley Collective on DM 9411c0f0dcc3SMatthew G. Knepley 9412c0f0dcc3SMatthew G. Knepley Input Parameters: 9413c0f0dcc3SMatthew G. Knepley . dm - The DM 9414c0f0dcc3SMatthew G. Knepley 9415c0f0dcc3SMatthew G. Knepley Level: developer 9416c0f0dcc3SMatthew G. Knepley 9417c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorSet() 9418c0f0dcc3SMatthew G. Knepley @*/ 9419c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitor(DM dm) 9420c0f0dcc3SMatthew G. Knepley { 9421c0f0dcc3SMatthew G. Knepley PetscInt m; 9422c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9423c0f0dcc3SMatthew G. Knepley 9424c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9425c0f0dcc3SMatthew G. Knepley if (!dm) PetscFunctionReturn(0); 9426c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9427c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 9428c0f0dcc3SMatthew G. Knepley ierr = (*dm->monitor[m])(dm, dm->monitorcontext[m]);CHKERRQ(ierr); 9429c0f0dcc3SMatthew G. Knepley } 9430c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9431c0f0dcc3SMatthew G. Knepley } 94322e4af2aeSMatthew G. Knepley 94332e4af2aeSMatthew G. Knepley /*@ 94342e4af2aeSMatthew G. Knepley DMComputeError - Computes the error assuming the user has given exact solution functions 94352e4af2aeSMatthew G. Knepley 94362e4af2aeSMatthew G. Knepley Collective on DM 94372e4af2aeSMatthew G. Knepley 94382e4af2aeSMatthew G. Knepley Input Parameters: 94392e4af2aeSMatthew G. Knepley + dm - The DM 94402e4af2aeSMatthew G. Knepley . sol - The solution vector 94412e4af2aeSMatthew G. Knepley . errors - An array of length Nf, the number of fields, or NULL for no output 944299c90e12SSatish Balay - errorVec - A Vec pointer, or NULL for no output 94432e4af2aeSMatthew G. Knepley 94442e4af2aeSMatthew G. Knepley Output Parameters: 94452e4af2aeSMatthew G. Knepley + errors - The error in each field 94462e4af2aeSMatthew G. Knepley - errorVec - Creates a vector to hold the cellwise error 94472e4af2aeSMatthew G. Knepley 94482e4af2aeSMatthew G. Knepley Note: The exact solutions come from the PetscDS object, and the time comes from DMGetOutputSequenceNumber(). 94492e4af2aeSMatthew G. Knepley 94502e4af2aeSMatthew G. Knepley Level: developer 94512e4af2aeSMatthew G. Knepley 94522e4af2aeSMatthew G. Knepley .seealso: DMMonitorSet(), DMGetRegionNumDS(), PetscDSGetExactSolution(), DMGetOutputSequenceNumber() 94532e4af2aeSMatthew G. Knepley @*/ 94542e4af2aeSMatthew G. Knepley PetscErrorCode DMComputeError(DM dm, Vec sol, PetscReal errors[], Vec *errorVec) 94552e4af2aeSMatthew G. Knepley { 94562e4af2aeSMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 94572e4af2aeSMatthew G. Knepley void **ctxs; 94582e4af2aeSMatthew G. Knepley PetscReal time; 94592e4af2aeSMatthew G. Knepley PetscInt Nf, f, Nds, s; 94602e4af2aeSMatthew G. Knepley PetscErrorCode ierr; 94612e4af2aeSMatthew G. Knepley 94622e4af2aeSMatthew G. Knepley PetscFunctionBegin; 94632e4af2aeSMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 94642e4af2aeSMatthew G. Knepley ierr = PetscCalloc2(Nf, &exactSol, Nf, &ctxs);CHKERRQ(ierr); 94652e4af2aeSMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 94662e4af2aeSMatthew G. Knepley for (s = 0; s < Nds; ++s) { 94672e4af2aeSMatthew G. Knepley PetscDS ds; 94682e4af2aeSMatthew G. Knepley DMLabel label; 94692e4af2aeSMatthew G. Knepley IS fieldIS; 94702e4af2aeSMatthew G. Knepley const PetscInt *fields; 94712e4af2aeSMatthew G. Knepley PetscInt dsNf; 94722e4af2aeSMatthew G. Knepley 94732e4af2aeSMatthew G. Knepley ierr = DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds);CHKERRQ(ierr); 94742e4af2aeSMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &dsNf);CHKERRQ(ierr); 94752e4af2aeSMatthew G. Knepley if (fieldIS) {ierr = ISGetIndices(fieldIS, &fields);CHKERRQ(ierr);} 94762e4af2aeSMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 94772e4af2aeSMatthew G. Knepley const PetscInt field = fields[f]; 94782e4af2aeSMatthew G. Knepley ierr = PetscDSGetExactSolution(ds, field, &exactSol[field], &ctxs[field]);CHKERRQ(ierr); 94792e4af2aeSMatthew G. Knepley } 94802e4af2aeSMatthew G. Knepley if (fieldIS) {ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr);} 94812e4af2aeSMatthew G. Knepley } 94822e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 94832e4af2aeSMatthew 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); 94842e4af2aeSMatthew G. Knepley } 94852e4af2aeSMatthew G. Knepley ierr = DMGetOutputSequenceNumber(dm, NULL, &time);CHKERRQ(ierr); 94862e4af2aeSMatthew G. Knepley if (errors) {ierr = DMComputeL2FieldDiff(dm, time, exactSol, ctxs, sol, errors);CHKERRQ(ierr);} 94872e4af2aeSMatthew G. Knepley if (errorVec) { 94882e4af2aeSMatthew G. Knepley DM edm; 94892e4af2aeSMatthew G. Knepley DMPolytopeType ct; 94902e4af2aeSMatthew G. Knepley PetscBool simplex; 94912e4af2aeSMatthew G. Knepley PetscInt dim, cStart, Nf; 94922e4af2aeSMatthew G. Knepley 94932e4af2aeSMatthew G. Knepley ierr = DMClone(dm, &edm);CHKERRQ(ierr); 94942e4af2aeSMatthew G. Knepley ierr = DMGetDimension(edm, &dim);CHKERRQ(ierr); 94952e4af2aeSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, NULL);CHKERRQ(ierr); 94962e4af2aeSMatthew G. Knepley ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 94972e4af2aeSMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 94982e4af2aeSMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 94992e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 95002e4af2aeSMatthew G. Knepley PetscFE fe, efe; 95012e4af2aeSMatthew G. Knepley PetscQuadrature q; 95022e4af2aeSMatthew G. Knepley const char *name; 95032e4af2aeSMatthew G. Knepley 95042e4af2aeSMatthew G. Knepley ierr = DMGetField(dm, f, NULL, (PetscObject *) &fe);CHKERRQ(ierr); 95052e4af2aeSMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, Nf, simplex, 0, PETSC_DETERMINE, &efe);CHKERRQ(ierr); 95062e4af2aeSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) fe, &name);CHKERRQ(ierr); 95072e4af2aeSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) efe, name);CHKERRQ(ierr); 95082e4af2aeSMatthew G. Knepley ierr = PetscFEGetQuadrature(fe, &q);CHKERRQ(ierr); 95092e4af2aeSMatthew G. Knepley ierr = PetscFESetQuadrature(efe, q);CHKERRQ(ierr); 95102e4af2aeSMatthew G. Knepley ierr = DMSetField(edm, f, NULL, (PetscObject) efe);CHKERRQ(ierr); 95112e4af2aeSMatthew G. Knepley ierr = PetscFEDestroy(&efe);CHKERRQ(ierr); 95122e4af2aeSMatthew G. Knepley } 95132e4af2aeSMatthew G. Knepley ierr = DMCreateDS(edm);CHKERRQ(ierr); 95142e4af2aeSMatthew G. Knepley 95152e4af2aeSMatthew G. Knepley ierr = DMCreateGlobalVector(edm, errorVec); 95162e4af2aeSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *errorVec, "Error");CHKERRQ(ierr); 95172e4af2aeSMatthew G. Knepley ierr = DMPlexComputeL2DiffVec(dm, time, exactSol, ctxs, sol, *errorVec);CHKERRQ(ierr); 95182e4af2aeSMatthew G. Knepley ierr = DMDestroy(&edm);CHKERRQ(ierr); 95192e4af2aeSMatthew G. Knepley } 95202e4af2aeSMatthew G. Knepley ierr = PetscFree2(exactSol, ctxs);CHKERRQ(ierr); 95212e4af2aeSMatthew G. Knepley PetscFunctionReturn(0); 95222e4af2aeSMatthew G. Knepley } 95239a2a23afSMatthew G. Knepley 95249a2a23afSMatthew G. Knepley /*@ 95259a2a23afSMatthew G. Knepley DMGetNumAuxiliaryVec - Get the number of auxiliary vectors associated with this DM 95269a2a23afSMatthew G. Knepley 95279a2a23afSMatthew G. Knepley Not collective 95289a2a23afSMatthew G. Knepley 95299a2a23afSMatthew G. Knepley Input Parameter: 95309a2a23afSMatthew G. Knepley . dm - The DM 95319a2a23afSMatthew G. Knepley 95329a2a23afSMatthew G. Knepley Output Parameter: 95339a2a23afSMatthew G. Knepley . numAux - The nubmer of auxiliary data vectors 95349a2a23afSMatthew G. Knepley 95359a2a23afSMatthew G. Knepley Level: advanced 95369a2a23afSMatthew G. Knepley 95379a2a23afSMatthew G. Knepley .seealso: DMGetAuxiliaryLabels(), DMGetAuxiliaryVec(), DMSetAuxiliaryVec() 95389a2a23afSMatthew G. Knepley @*/ 95399a2a23afSMatthew G. Knepley PetscErrorCode DMGetNumAuxiliaryVec(DM dm, PetscInt *numAux) 95409a2a23afSMatthew G. Knepley { 95419a2a23afSMatthew G. Knepley PetscErrorCode ierr; 95429a2a23afSMatthew G. Knepley 95439a2a23afSMatthew G. Knepley PetscFunctionBegin; 95449a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 95459a2a23afSMatthew G. Knepley ierr = PetscHMapAuxGetSize(dm->auxData, numAux);CHKERRQ(ierr); 95469a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 95479a2a23afSMatthew G. Knepley } 95489a2a23afSMatthew G. Knepley 95499a2a23afSMatthew G. Knepley /*@ 95509a2a23afSMatthew G. Knepley DMGetAuxiliaryVec - Get the auxiliary vector for region specified by the given label and value 95519a2a23afSMatthew G. Knepley 95529a2a23afSMatthew G. Knepley Not collective 95539a2a23afSMatthew G. Knepley 95549a2a23afSMatthew G. Knepley Input Parameters: 95559a2a23afSMatthew G. Knepley + dm - The DM 95569a2a23afSMatthew G. Knepley . label - The DMLabel 95579a2a23afSMatthew G. Knepley - value - The label value indicating the region 95589a2a23afSMatthew G. Knepley 95599a2a23afSMatthew G. Knepley Output Parameter: 95609a2a23afSMatthew G. Knepley . aux - The Vec holding auxiliary field data 95619a2a23afSMatthew G. Knepley 95629a2a23afSMatthew G. Knepley Level: advanced 95639a2a23afSMatthew G. Knepley 95649a2a23afSMatthew G. Knepley .seealso: DMSetAuxiliaryVec(), DMGetNumAuxiliaryVec() 95659a2a23afSMatthew G. Knepley @*/ 95669a2a23afSMatthew G. Knepley PetscErrorCode DMGetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, Vec *aux) 95679a2a23afSMatthew G. Knepley { 95689a2a23afSMatthew G. Knepley PetscHashAuxKey key; 95699a2a23afSMatthew G. Knepley PetscErrorCode ierr; 95709a2a23afSMatthew G. Knepley 95719a2a23afSMatthew G. Knepley PetscFunctionBegin; 95729a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 95739a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 95749a2a23afSMatthew G. Knepley key.label = label; 95759a2a23afSMatthew G. Knepley key.value = value; 95769a2a23afSMatthew G. Knepley ierr = PetscHMapAuxGet(dm->auxData, key, aux);CHKERRQ(ierr); 95779a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 95789a2a23afSMatthew G. Knepley } 95799a2a23afSMatthew G. Knepley 95809a2a23afSMatthew G. Knepley /*@ 95819a2a23afSMatthew G. Knepley DMSetAuxiliaryVec - Set the auxiliary vector for region specified by the given label and value 95829a2a23afSMatthew G. Knepley 95839a2a23afSMatthew G. Knepley Not collective 95849a2a23afSMatthew G. Knepley 95859a2a23afSMatthew G. Knepley Input Parameters: 95869a2a23afSMatthew G. Knepley + dm - The DM 95879a2a23afSMatthew G. Knepley . label - The DMLabel 95889a2a23afSMatthew G. Knepley . value - The label value indicating the region 95899a2a23afSMatthew G. Knepley - aux - The Vec holding auxiliary field data 95909a2a23afSMatthew G. Knepley 95919a2a23afSMatthew G. Knepley Level: advanced 95929a2a23afSMatthew G. Knepley 95939a2a23afSMatthew G. Knepley .seealso: DMGetAuxiliaryVec() 95949a2a23afSMatthew G. Knepley @*/ 95959a2a23afSMatthew G. Knepley PetscErrorCode DMSetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, Vec aux) 95969a2a23afSMatthew G. Knepley { 95979a2a23afSMatthew G. Knepley Vec old; 95989a2a23afSMatthew G. Knepley PetscHashAuxKey key; 95999a2a23afSMatthew G. Knepley PetscErrorCode ierr; 96009a2a23afSMatthew G. Knepley 96019a2a23afSMatthew G. Knepley PetscFunctionBegin; 96029a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 96039a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 96049a2a23afSMatthew G. Knepley key.label = label; 96059a2a23afSMatthew G. Knepley key.value = value; 96069a2a23afSMatthew G. Knepley ierr = PetscHMapAuxGet(dm->auxData, key, &old);CHKERRQ(ierr); 96079a2a23afSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) aux);CHKERRQ(ierr); 96089a2a23afSMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) old);CHKERRQ(ierr); 96099a2a23afSMatthew G. Knepley if (!aux) {ierr = PetscHMapAuxDel(dm->auxData, key);CHKERRQ(ierr);} 96109a2a23afSMatthew G. Knepley else {ierr = PetscHMapAuxSet(dm->auxData, key, aux);CHKERRQ(ierr);} 96119a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 96129a2a23afSMatthew G. Knepley } 96139a2a23afSMatthew G. Knepley 96149a2a23afSMatthew G. Knepley /*@C 96159a2a23afSMatthew G. Knepley DMGetAuxiliaryLabels - Get the labels and values for all auxiliary vectors in this DM 96169a2a23afSMatthew G. Knepley 96179a2a23afSMatthew G. Knepley Not collective 96189a2a23afSMatthew G. Knepley 96199a2a23afSMatthew G. Knepley Input Parameter: 96209a2a23afSMatthew G. Knepley . dm - The DM 96219a2a23afSMatthew G. Knepley 96229a2a23afSMatthew G. Knepley Output Parameters: 96239a2a23afSMatthew G. Knepley + labels - The DMLabels for each Vec 96249a2a23afSMatthew G. Knepley - values - The label values for each Vec 96259a2a23afSMatthew G. Knepley 96269a2a23afSMatthew G. Knepley Note: The arrays passed in must be at least as large as DMGetNumAuxiliaryVec(). 96279a2a23afSMatthew G. Knepley 96289a2a23afSMatthew G. Knepley Level: advanced 96299a2a23afSMatthew G. Knepley 96309a2a23afSMatthew G. Knepley .seealso: DMGetNumAuxiliaryVec(), DMGetAuxiliaryVec(), DMSetAuxiliaryVec() 96319a2a23afSMatthew G. Knepley @*/ 96329a2a23afSMatthew G. Knepley PetscErrorCode DMGetAuxiliaryLabels(DM dm, DMLabel labels[], PetscInt values[]) 96339a2a23afSMatthew G. Knepley { 96349a2a23afSMatthew G. Knepley PetscHashAuxKey *keys; 96359a2a23afSMatthew G. Knepley PetscInt n, i, off = 0; 96369a2a23afSMatthew G. Knepley PetscErrorCode ierr; 96379a2a23afSMatthew G. Knepley 96389a2a23afSMatthew G. Knepley PetscFunctionBegin; 96399a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 96409a2a23afSMatthew G. Knepley PetscValidPointer(labels, 2); 96419a2a23afSMatthew G. Knepley PetscValidPointer(values, 3); 96429a2a23afSMatthew G. Knepley ierr = DMGetNumAuxiliaryVec(dm, &n);CHKERRQ(ierr); 96439a2a23afSMatthew G. Knepley ierr = PetscMalloc1(n, &keys);CHKERRQ(ierr); 96449a2a23afSMatthew G. Knepley ierr = PetscHMapAuxGetKeys(dm->auxData, &off, keys);CHKERRQ(ierr); 96459a2a23afSMatthew G. Knepley for (i = 0; i < n; ++i) {labels[i] = keys[i].label; values[i] = keys[i].value;} 96469a2a23afSMatthew G. Knepley ierr = PetscFree(keys);CHKERRQ(ierr); 96479a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 96489a2a23afSMatthew G. Knepley } 96499a2a23afSMatthew G. Knepley 96509a2a23afSMatthew G. Knepley /*@ 96519a2a23afSMatthew G. Knepley DMCopyAuxiliaryVec - Copy the auxiliary data to a new DM 96529a2a23afSMatthew G. Knepley 96539a2a23afSMatthew G. Knepley Not collective 96549a2a23afSMatthew G. Knepley 96559a2a23afSMatthew G. Knepley Input Parameter: 96569a2a23afSMatthew G. Knepley . dm - The DM 96579a2a23afSMatthew G. Knepley 96589a2a23afSMatthew G. Knepley Output Parameter: 96599a2a23afSMatthew G. Knepley . dmNew - The new DM, now with the same auxiliary data 96609a2a23afSMatthew G. Knepley 96619a2a23afSMatthew G. Knepley Level: advanced 96629a2a23afSMatthew G. Knepley 96639a2a23afSMatthew G. Knepley .seealso: DMGetNumAuxiliaryVec(), DMGetAuxiliaryVec(), DMSetAuxiliaryVec() 96649a2a23afSMatthew G. Knepley @*/ 96659a2a23afSMatthew G. Knepley PetscErrorCode DMCopyAuxiliaryVec(DM dm, DM dmNew) 96669a2a23afSMatthew G. Knepley { 96679a2a23afSMatthew G. Knepley PetscErrorCode ierr; 96689a2a23afSMatthew G. Knepley 96699a2a23afSMatthew G. Knepley PetscFunctionBegin; 96709a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 96719a2a23afSMatthew G. Knepley ierr = PetscHMapAuxDestroy(&dmNew->auxData);CHKERRQ(ierr); 96729a2a23afSMatthew G. Knepley ierr = PetscHMapAuxDuplicate(dm->auxData, &dmNew->auxData);CHKERRQ(ierr); 96739a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 96749a2a23afSMatthew G. Knepley } 9675