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 } 81*45480ffeSMatthew G. Knepley ierr = PetscDSCreate(PETSC_COMM_SELF, &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]; 1777820f2d46SBarry 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); 4058820f2d46SBarry Smith if (gmin) {ierr = MPIU_Allreduce(lmin, gmin, count, MPIU_REAL, MPIU_MIN, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr);} 4059820f2d46SBarry 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 4184*45480ffeSMatthew G. Knepley if (dm->setfromoptionscalled) { 4185*45480ffeSMatthew G. Knepley PetscObject obj = (PetscObject) dm; 4186*45480ffeSMatthew G. Knepley PetscViewer viewer; 4187*45480ffeSMatthew G. Knepley PetscViewerFormat format; 4188*45480ffeSMatthew G. Knepley PetscBool flg; 4189*45480ffeSMatthew G. Knepley 4190*45480ffeSMatthew G. Knepley ierr = PetscOptionsGetViewer(PetscObjectComm(obj), obj->options, obj->prefix, "-dm_petscds_view", &viewer, &format, &flg);CHKERRQ(ierr); 4191*45480ffeSMatthew G. Knepley if (flg) {ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr);} 4192*45480ffeSMatthew G. Knepley for (d = 0; d < dm->Nds; ++d) { 4193*45480ffeSMatthew G. Knepley ierr = PetscDSSetFromOptions(dm->probs[d].ds);CHKERRQ(ierr); 4194*45480ffeSMatthew G. Knepley if (flg) {ierr = PetscDSView(dm->probs[d].ds, viewer);CHKERRQ(ierr);} 4195*45480ffeSMatthew G. Knepley } 4196*45480ffeSMatthew G. Knepley if (flg) { 4197*45480ffeSMatthew G. Knepley ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 4198*45480ffeSMatthew G. Knepley ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 4199*45480ffeSMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4200*45480ffeSMatthew G. Knepley } 4201*45480ffeSMatthew G. Knepley } 42021bb6d2a8SBarry Smith ierr = (*dm->ops->createlocalsection)(dm);CHKERRQ(ierr); 42031bb6d2a8SBarry Smith if (dm->localSection) {ierr = PetscObjectViewFromOptions((PetscObject) dm->localSection, NULL, "-dm_petscsection_view");CHKERRQ(ierr);} 42042f0f8703SMatthew G. Knepley } 42051bb6d2a8SBarry Smith *section = dm->localSection; 420688ed4aceSMatthew G Knepley PetscFunctionReturn(0); 420788ed4aceSMatthew G Knepley } 420888ed4aceSMatthew G Knepley 420988ed4aceSMatthew G Knepley /*@ 42101bb6d2a8SBarry Smith DMSetSection - Set the PetscSection encoding the local data layout for the DM. This is equivalent to DMSetLocalSection(). Deprecated in v3.12 4211061576a5SJed Brown 4212061576a5SJed Brown Input Parameters: 4213061576a5SJed Brown + dm - The DM 4214061576a5SJed Brown - section - The PetscSection 4215061576a5SJed Brown 4216061576a5SJed Brown Level: advanced 4217061576a5SJed Brown 4218061576a5SJed Brown Notes: 4219061576a5SJed Brown Use DMSetLocalSection() in new code. 4220061576a5SJed Brown 4221061576a5SJed Brown Any existing Section will be destroyed 4222061576a5SJed Brown 4223061576a5SJed Brown .seealso: DMSetLocalSection(), DMGetLocalSection(), DMSetGlobalSection() 4224061576a5SJed Brown @*/ 4225061576a5SJed Brown PetscErrorCode DMSetSection(DM dm, PetscSection section) 4226061576a5SJed Brown { 4227061576a5SJed Brown PetscErrorCode ierr; 4228061576a5SJed Brown 4229061576a5SJed Brown PetscFunctionBegin; 4230061576a5SJed Brown ierr = DMSetLocalSection(dm,section);CHKERRQ(ierr); 4231061576a5SJed Brown PetscFunctionReturn(0); 4232061576a5SJed Brown } 4233061576a5SJed Brown 4234061576a5SJed Brown /*@ 4235061576a5SJed Brown DMSetLocalSection - Set the PetscSection encoding the local data layout for the DM. 423688ed4aceSMatthew G Knepley 423788ed4aceSMatthew G Knepley Input Parameters: 423888ed4aceSMatthew G Knepley + dm - The DM 423988ed4aceSMatthew G Knepley - section - The PetscSection 424088ed4aceSMatthew G Knepley 424188ed4aceSMatthew G Knepley Level: intermediate 424288ed4aceSMatthew G Knepley 424388ed4aceSMatthew G Knepley Note: Any existing Section will be destroyed 424488ed4aceSMatthew G Knepley 4245061576a5SJed Brown .seealso: DMGetLocalSection(), DMSetGlobalSection() 424688ed4aceSMatthew G Knepley @*/ 4247061576a5SJed Brown PetscErrorCode DMSetLocalSection(DM dm, PetscSection section) 42480adebc6cSBarry Smith { 4249c473ab19SMatthew G. Knepley PetscInt numFields = 0; 4250af122d2aSMatthew G Knepley PetscInt f; 425188ed4aceSMatthew G Knepley PetscErrorCode ierr; 425288ed4aceSMatthew G Knepley 425388ed4aceSMatthew G Knepley PetscFunctionBegin; 425488ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4255b9d85ea2SLisandro Dalcin if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 42561d799100SJed Brown ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 42571bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&dm->localSection);CHKERRQ(ierr); 42581bb6d2a8SBarry Smith dm->localSection = section; 42591bb6d2a8SBarry Smith if (section) {ierr = PetscSectionGetNumFields(dm->localSection, &numFields);CHKERRQ(ierr);} 4260af122d2aSMatthew G Knepley if (numFields) { 4261af122d2aSMatthew G Knepley ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr); 4262af122d2aSMatthew G Knepley for (f = 0; f < numFields; ++f) { 42630f21e855SMatthew G. Knepley PetscObject disc; 4264af122d2aSMatthew G Knepley const char *name; 4265af122d2aSMatthew G Knepley 42661bb6d2a8SBarry Smith ierr = PetscSectionGetFieldName(dm->localSection, f, &name);CHKERRQ(ierr); 426744a7f3ddSMatthew G. Knepley ierr = DMGetField(dm, f, NULL, &disc);CHKERRQ(ierr); 42680f21e855SMatthew G. Knepley ierr = PetscObjectSetName(disc, name);CHKERRQ(ierr); 4269af122d2aSMatthew G Knepley } 4270af122d2aSMatthew G Knepley } 4271e87a4003SBarry Smith /* The global section will be rebuilt in the next call to DMGetGlobalSection(). */ 42721bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&dm->globalSection);CHKERRQ(ierr); 427388ed4aceSMatthew G Knepley PetscFunctionReturn(0); 427488ed4aceSMatthew G Knepley } 427588ed4aceSMatthew G Knepley 42769435951eSToby Isaac /*@ 4277b7385021SStefano Zampini DMGetDefaultConstraints - Get the PetscSection and Mat that specify the local constraint interpolation. See DMSetDefaultConstraints() for a description of the purpose of constraint interpolation. 42789435951eSToby Isaac 4279e228b242SToby Isaac not collective 4280e228b242SToby Isaac 42819435951eSToby Isaac Input Parameter: 42829435951eSToby Isaac . dm - The DM 42839435951eSToby Isaac 42849435951eSToby Isaac Output Parameter: 42859435951eSToby 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. 42869435951eSToby 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. 42879435951eSToby Isaac 42889435951eSToby Isaac Level: advanced 42899435951eSToby Isaac 42909435951eSToby Isaac Note: This gets borrowed references, so the user should not destroy the PetscSection or the Mat. 42919435951eSToby Isaac 42929435951eSToby Isaac .seealso: DMSetDefaultConstraints() 42939435951eSToby Isaac @*/ 42949435951eSToby Isaac PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat) 42959435951eSToby Isaac { 42969435951eSToby Isaac PetscErrorCode ierr; 42979435951eSToby Isaac 42989435951eSToby Isaac PetscFunctionBegin; 42999435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 43009435951eSToby Isaac if (!dm->defaultConstraintSection && !dm->defaultConstraintMat && dm->ops->createdefaultconstraints) {ierr = (*dm->ops->createdefaultconstraints)(dm);CHKERRQ(ierr);} 430145a75d81SToby Isaac if (section) {*section = dm->defaultConstraintSection;} 430245a75d81SToby Isaac if (mat) {*mat = dm->defaultConstraintMat;} 43039435951eSToby Isaac PetscFunctionReturn(0); 43049435951eSToby Isaac } 43059435951eSToby Isaac 43069435951eSToby Isaac /*@ 4307b7385021SStefano Zampini DMSetDefaultConstraints - Set the PetscSection and Mat that specify the local constraint interpolation. 43089435951eSToby Isaac 43099435951eSToby 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(). 43109435951eSToby Isaac 43119435951eSToby 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. 43129435951eSToby Isaac 4313e228b242SToby Isaac collective on dm 4314e228b242SToby Isaac 43159435951eSToby Isaac Input Parameters: 43169435951eSToby Isaac + dm - The DM 4317e228b242SToby 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). 4318e228b242SToby 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). 43199435951eSToby Isaac 43209435951eSToby Isaac Level: advanced 43219435951eSToby Isaac 43229435951eSToby Isaac Note: This increments the references of the PetscSection and the Mat, so they user can destroy them 43239435951eSToby Isaac 43249435951eSToby Isaac .seealso: DMGetDefaultConstraints() 43259435951eSToby Isaac @*/ 43269435951eSToby Isaac PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat) 43279435951eSToby Isaac { 4328e228b242SToby Isaac PetscMPIInt result; 43299435951eSToby Isaac PetscErrorCode ierr; 43309435951eSToby Isaac 43319435951eSToby Isaac PetscFunctionBegin; 43329435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4333e228b242SToby Isaac if (section) { 4334e228b242SToby Isaac PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 4335ffc4695bSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)section),&result);CHKERRMPI(ierr); 4336f60917d2SBarry Smith if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint section must have local communicator"); 4337e228b242SToby Isaac } 4338e228b242SToby Isaac if (mat) { 4339e228b242SToby Isaac PetscValidHeaderSpecific(mat,MAT_CLASSID,3); 4340ffc4695bSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)mat),&result);CHKERRMPI(ierr); 4341f60917d2SBarry Smith if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint matrix must have local communicator"); 4342e228b242SToby Isaac } 43439435951eSToby Isaac ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 43449435951eSToby Isaac ierr = PetscSectionDestroy(&dm->defaultConstraintSection);CHKERRQ(ierr); 43459435951eSToby Isaac dm->defaultConstraintSection = section; 43469435951eSToby Isaac ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 43479435951eSToby Isaac ierr = MatDestroy(&dm->defaultConstraintMat);CHKERRQ(ierr); 43489435951eSToby Isaac dm->defaultConstraintMat = mat; 43499435951eSToby Isaac PetscFunctionReturn(0); 43509435951eSToby Isaac } 43519435951eSToby Isaac 4352497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 4353507e4973SMatthew G. Knepley /* 4354507e4973SMatthew G. Knepley DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections. 4355507e4973SMatthew G. Knepley 4356507e4973SMatthew G. Knepley Input Parameters: 4357507e4973SMatthew G. Knepley + dm - The DM 4358507e4973SMatthew G. Knepley . localSection - PetscSection describing the local data layout 4359507e4973SMatthew G. Knepley - globalSection - PetscSection describing the global data layout 4360507e4973SMatthew G. Knepley 4361507e4973SMatthew G. Knepley Level: intermediate 4362507e4973SMatthew G. Knepley 43631bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMSetSectionSF() 4364507e4973SMatthew G. Knepley */ 4365f741bcd2SMatthew G. Knepley static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection) 4366507e4973SMatthew G. Knepley { 4367507e4973SMatthew G. Knepley MPI_Comm comm; 4368507e4973SMatthew G. Knepley PetscLayout layout; 4369507e4973SMatthew G. Knepley const PetscInt *ranges; 4370507e4973SMatthew G. Knepley PetscInt pStart, pEnd, p, nroots; 4371507e4973SMatthew G. Knepley PetscMPIInt size, rank; 4372507e4973SMatthew G. Knepley PetscBool valid = PETSC_TRUE, gvalid; 4373507e4973SMatthew G. Knepley PetscErrorCode ierr; 4374507e4973SMatthew G. Knepley 4375507e4973SMatthew G. Knepley PetscFunctionBegin; 4376507e4973SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 4377507e4973SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4378ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 4379ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 4380507e4973SMatthew G. Knepley ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr); 4381507e4973SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr); 4382507e4973SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr); 4383507e4973SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr); 4384507e4973SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr); 4385507e4973SMatthew G. Knepley ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr); 4386507e4973SMatthew G. Knepley ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr); 4387507e4973SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 4388f741bcd2SMatthew G. Knepley PetscInt dof, cdof, off, gdof, gcdof, goff, gsize, d; 4389507e4973SMatthew G. Knepley 4390507e4973SMatthew G. Knepley ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr); 4391507e4973SMatthew G. Knepley ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr); 4392507e4973SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr); 4393507e4973SMatthew G. Knepley ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr); 4394507e4973SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr); 4395507e4973SMatthew G. Knepley ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr); 4396507e4973SMatthew G. Knepley if (!gdof) continue; /* Censored point */ 4397507e4973SMatthew 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;} 4398507e4973SMatthew 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;} 4399507e4973SMatthew G. Knepley if (gdof < 0) { 4400507e4973SMatthew G. Knepley gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof; 4401507e4973SMatthew G. Knepley for (d = 0; d < gsize; ++d) { 4402507e4973SMatthew G. Knepley PetscInt offset = -(goff+1) + d, r; 4403507e4973SMatthew G. Knepley 4404507e4973SMatthew G. Knepley ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr); 4405507e4973SMatthew G. Knepley if (r < 0) r = -(r+2); 4406507e4973SMatthew 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;} 4407507e4973SMatthew G. Knepley } 4408507e4973SMatthew G. Knepley } 4409507e4973SMatthew G. Knepley } 4410507e4973SMatthew G. Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 4411507e4973SMatthew G. Knepley ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr); 4412820f2d46SBarry Smith ierr = MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRMPI(ierr); 4413507e4973SMatthew G. Knepley if (!gvalid) { 4414507e4973SMatthew G. Knepley ierr = DMView(dm, NULL);CHKERRQ(ierr); 4415507e4973SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections"); 4416507e4973SMatthew G. Knepley } 4417507e4973SMatthew G. Knepley PetscFunctionReturn(0); 4418507e4973SMatthew G. Knepley } 4419f741bcd2SMatthew G. Knepley #endif 4420507e4973SMatthew G. Knepley 442188ed4aceSMatthew G Knepley /*@ 4422e87a4003SBarry Smith DMGetGlobalSection - Get the PetscSection encoding the global data layout for the DM. 442388ed4aceSMatthew G Knepley 4424d083f849SBarry Smith Collective on dm 44258b1ab98fSJed Brown 442688ed4aceSMatthew G Knepley Input Parameter: 442788ed4aceSMatthew G Knepley . dm - The DM 442888ed4aceSMatthew G Knepley 442988ed4aceSMatthew G Knepley Output Parameter: 443088ed4aceSMatthew G Knepley . section - The PetscSection 443188ed4aceSMatthew G Knepley 443288ed4aceSMatthew G Knepley Level: intermediate 443388ed4aceSMatthew G Knepley 443488ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSection. 443588ed4aceSMatthew G Knepley 443692fd8e1eSJed Brown .seealso: DMSetLocalSection(), DMGetLocalSection() 443788ed4aceSMatthew G Knepley @*/ 4438e87a4003SBarry Smith PetscErrorCode DMGetGlobalSection(DM dm, PetscSection *section) 44390adebc6cSBarry Smith { 444088ed4aceSMatthew G Knepley PetscErrorCode ierr; 444188ed4aceSMatthew G Knepley 444288ed4aceSMatthew G Knepley PetscFunctionBegin; 444388ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 444488ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 44451bb6d2a8SBarry Smith if (!dm->globalSection) { 4446fd59a867SMatthew G. Knepley PetscSection s; 4447fd59a867SMatthew G. Knepley 444892fd8e1eSJed Brown ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr); 4449fd59a867SMatthew 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"); 445033907cc2SStefano 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"); 44511bb6d2a8SBarry Smith ierr = PetscSectionCreateGlobalSection(s, dm->sf, PETSC_FALSE, PETSC_FALSE, &dm->globalSection);CHKERRQ(ierr); 4452cf06b437SMatthew G. Knepley ierr = PetscLayoutDestroy(&dm->map);CHKERRQ(ierr); 44531bb6d2a8SBarry Smith ierr = PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->globalSection, &dm->map);CHKERRQ(ierr); 44541bb6d2a8SBarry Smith ierr = PetscSectionViewFromOptions(dm->globalSection, NULL, "-global_section_view");CHKERRQ(ierr); 445588ed4aceSMatthew G Knepley } 44561bb6d2a8SBarry Smith *section = dm->globalSection; 445788ed4aceSMatthew G Knepley PetscFunctionReturn(0); 445888ed4aceSMatthew G Knepley } 445988ed4aceSMatthew G Knepley 4460b21d0597SMatthew G Knepley /*@ 4461e87a4003SBarry Smith DMSetGlobalSection - Set the PetscSection encoding the global data layout for the DM. 4462b21d0597SMatthew G Knepley 4463b21d0597SMatthew G Knepley Input Parameters: 4464b21d0597SMatthew G Knepley + dm - The DM 44655080bbdbSMatthew G Knepley - section - The PetscSection, or NULL 4466b21d0597SMatthew G Knepley 4467b21d0597SMatthew G Knepley Level: intermediate 4468b21d0597SMatthew G Knepley 4469b21d0597SMatthew G Knepley Note: Any existing Section will be destroyed 4470b21d0597SMatthew G Knepley 447192fd8e1eSJed Brown .seealso: DMGetGlobalSection(), DMSetLocalSection() 4472b21d0597SMatthew G Knepley @*/ 4473e87a4003SBarry Smith PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section) 44740adebc6cSBarry Smith { 4475b21d0597SMatthew G Knepley PetscErrorCode ierr; 4476b21d0597SMatthew G Knepley 4477b21d0597SMatthew G Knepley PetscFunctionBegin; 4478b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 44795080bbdbSMatthew G Knepley if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 44801d799100SJed Brown ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 44811bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&dm->globalSection);CHKERRQ(ierr); 44821bb6d2a8SBarry Smith dm->globalSection = section; 4483497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 44841bb6d2a8SBarry Smith if (section) {ierr = DMDefaultSectionCheckConsistency_Internal(dm, dm->localSection, section);CHKERRQ(ierr);} 4485507e4973SMatthew G. Knepley #endif 4486b21d0597SMatthew G Knepley PetscFunctionReturn(0); 4487b21d0597SMatthew G Knepley } 4488b21d0597SMatthew G Knepley 448988ed4aceSMatthew G Knepley /*@ 44901bb6d2a8SBarry Smith DMGetSectionSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set, 449188ed4aceSMatthew G Knepley it is created from the default PetscSection layouts in the DM. 449288ed4aceSMatthew G Knepley 449388ed4aceSMatthew G Knepley Input Parameter: 449488ed4aceSMatthew G Knepley . dm - The DM 449588ed4aceSMatthew G Knepley 449688ed4aceSMatthew G Knepley Output Parameter: 449788ed4aceSMatthew G Knepley . sf - The PetscSF 449888ed4aceSMatthew G Knepley 449988ed4aceSMatthew G Knepley Level: intermediate 450088ed4aceSMatthew G Knepley 450188ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSF. 450288ed4aceSMatthew G Knepley 45031bb6d2a8SBarry Smith .seealso: DMSetSectionSF(), DMCreateSectionSF() 450488ed4aceSMatthew G Knepley @*/ 45051bb6d2a8SBarry Smith PetscErrorCode DMGetSectionSF(DM dm, PetscSF *sf) 45060adebc6cSBarry Smith { 450788ed4aceSMatthew G Knepley PetscInt nroots; 450888ed4aceSMatthew G Knepley PetscErrorCode ierr; 450988ed4aceSMatthew G Knepley 451088ed4aceSMatthew G Knepley PetscFunctionBegin; 451188ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 451288ed4aceSMatthew G Knepley PetscValidPointer(sf, 2); 45131bb6d2a8SBarry Smith if (!dm->sectionSF) { 45141bb6d2a8SBarry Smith ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm),&dm->sectionSF);CHKERRQ(ierr); 451533907cc2SStefano Zampini } 45161bb6d2a8SBarry Smith ierr = PetscSFGetGraph(dm->sectionSF, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 451788ed4aceSMatthew G Knepley if (nroots < 0) { 451888ed4aceSMatthew G Knepley PetscSection section, gSection; 451988ed4aceSMatthew G Knepley 452092fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 452131ea6d37SMatthew G Knepley if (section) { 4522e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, &gSection);CHKERRQ(ierr); 45231bb6d2a8SBarry Smith ierr = DMCreateSectionSF(dm, section, gSection);CHKERRQ(ierr); 452431ea6d37SMatthew G Knepley } else { 45250298fd71SBarry Smith *sf = NULL; 452631ea6d37SMatthew G Knepley PetscFunctionReturn(0); 452731ea6d37SMatthew G Knepley } 452888ed4aceSMatthew G Knepley } 45291bb6d2a8SBarry Smith *sf = dm->sectionSF; 453088ed4aceSMatthew G Knepley PetscFunctionReturn(0); 453188ed4aceSMatthew G Knepley } 453288ed4aceSMatthew G Knepley 453388ed4aceSMatthew G Knepley /*@ 45341bb6d2a8SBarry Smith DMSetSectionSF - Set the PetscSF encoding the parallel dof overlap for the DM 453588ed4aceSMatthew G Knepley 453688ed4aceSMatthew G Knepley Input Parameters: 453788ed4aceSMatthew G Knepley + dm - The DM 453888ed4aceSMatthew G Knepley - sf - The PetscSF 453988ed4aceSMatthew G Knepley 454088ed4aceSMatthew G Knepley Level: intermediate 454188ed4aceSMatthew G Knepley 454288ed4aceSMatthew G Knepley Note: Any previous SF is destroyed 454388ed4aceSMatthew G Knepley 45441bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMCreateSectionSF() 454588ed4aceSMatthew G Knepley @*/ 45461bb6d2a8SBarry Smith PetscErrorCode DMSetSectionSF(DM dm, PetscSF sf) 45470adebc6cSBarry Smith { 454888ed4aceSMatthew G Knepley PetscErrorCode ierr; 454988ed4aceSMatthew G Knepley 455088ed4aceSMatthew G Knepley PetscFunctionBegin; 455188ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4552b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 455333907cc2SStefano Zampini ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr); 45541bb6d2a8SBarry Smith ierr = PetscSFDestroy(&dm->sectionSF);CHKERRQ(ierr); 45551bb6d2a8SBarry Smith dm->sectionSF = sf; 455688ed4aceSMatthew G Knepley PetscFunctionReturn(0); 455788ed4aceSMatthew G Knepley } 455888ed4aceSMatthew G Knepley 455988ed4aceSMatthew G Knepley /*@C 45601bb6d2a8SBarry Smith DMCreateSectionSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections 456188ed4aceSMatthew G Knepley describing the data layout. 456288ed4aceSMatthew G Knepley 456388ed4aceSMatthew G Knepley Input Parameters: 456488ed4aceSMatthew G Knepley + dm - The DM 456588ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout 456688ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout 456788ed4aceSMatthew G Knepley 45681bb6d2a8SBarry Smith Notes: One usually uses DMGetSectionSF() to obtain the PetscSF 456988ed4aceSMatthew G Knepley 45701bb6d2a8SBarry Smith Level: developer 45711bb6d2a8SBarry Smith 45721bb6d2a8SBarry Smith Developer Note: Since this routine has for arguments the two sections from the DM and puts the resulting PetscSF 45731bb6d2a8SBarry Smith directly into the DM, perhaps this function should not take the local and global sections as 45741bb6d2a8SBarry Smith input and should just obtain them from the DM? 45751bb6d2a8SBarry Smith 45761bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMSetSectionSF(), DMGetLocalSection(), DMGetGlobalSection() 457788ed4aceSMatthew G Knepley @*/ 45781bb6d2a8SBarry Smith PetscErrorCode DMCreateSectionSF(DM dm, PetscSection localSection, PetscSection globalSection) 457988ed4aceSMatthew G Knepley { 458088ed4aceSMatthew G Knepley PetscErrorCode ierr; 458188ed4aceSMatthew G Knepley 458288ed4aceSMatthew G Knepley PetscFunctionBegin; 458388ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4584b0c7db22SLisandro Dalcin ierr = PetscSFSetGraphSection(dm->sectionSF, localSection, globalSection);CHKERRQ(ierr); 458588ed4aceSMatthew G Knepley PetscFunctionReturn(0); 458688ed4aceSMatthew G Knepley } 4587af122d2aSMatthew G Knepley 4588b21d0597SMatthew G Knepley /*@ 4589b21d0597SMatthew G Knepley DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM. 4590b21d0597SMatthew G Knepley 4591b21d0597SMatthew G Knepley Input Parameter: 4592b21d0597SMatthew G Knepley . dm - The DM 4593b21d0597SMatthew G Knepley 4594b21d0597SMatthew G Knepley Output Parameter: 4595b21d0597SMatthew G Knepley . sf - The PetscSF 4596b21d0597SMatthew G Knepley 4597b21d0597SMatthew G Knepley Level: intermediate 4598b21d0597SMatthew G Knepley 4599b21d0597SMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSF. 4600b21d0597SMatthew G Knepley 46011bb6d2a8SBarry Smith .seealso: DMSetPointSF(), DMGetSectionSF(), DMSetSectionSF(), DMCreateSectionSF() 4602b21d0597SMatthew G Knepley @*/ 46030adebc6cSBarry Smith PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) 46040adebc6cSBarry Smith { 4605b21d0597SMatthew G Knepley PetscFunctionBegin; 4606b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4607b21d0597SMatthew G Knepley PetscValidPointer(sf, 2); 4608b21d0597SMatthew G Knepley *sf = dm->sf; 4609b21d0597SMatthew G Knepley PetscFunctionReturn(0); 4610b21d0597SMatthew G Knepley } 4611b21d0597SMatthew G Knepley 4612057b4bcdSMatthew G Knepley /*@ 4613057b4bcdSMatthew G Knepley DMSetPointSF - Set the PetscSF encoding the parallel section point overlap for the DM. 4614057b4bcdSMatthew G Knepley 4615057b4bcdSMatthew G Knepley Input Parameters: 4616057b4bcdSMatthew G Knepley + dm - The DM 4617057b4bcdSMatthew G Knepley - sf - The PetscSF 4618057b4bcdSMatthew G Knepley 4619057b4bcdSMatthew G Knepley Level: intermediate 4620057b4bcdSMatthew G Knepley 46211bb6d2a8SBarry Smith .seealso: DMGetPointSF(), DMGetSectionSF(), DMSetSectionSF(), DMCreateSectionSF() 4622057b4bcdSMatthew G Knepley @*/ 46230adebc6cSBarry Smith PetscErrorCode DMSetPointSF(DM dm, PetscSF sf) 46240adebc6cSBarry Smith { 4625057b4bcdSMatthew G Knepley PetscErrorCode ierr; 4626057b4bcdSMatthew G Knepley 4627057b4bcdSMatthew G Knepley PetscFunctionBegin; 4628057b4bcdSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4629b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 4630057b4bcdSMatthew G Knepley ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr); 463133907cc2SStefano Zampini ierr = PetscSFDestroy(&dm->sf);CHKERRQ(ierr); 4632057b4bcdSMatthew G Knepley dm->sf = sf; 4633057b4bcdSMatthew G Knepley PetscFunctionReturn(0); 4634057b4bcdSMatthew G Knepley } 4635057b4bcdSMatthew G Knepley 463634aa8a36SMatthew G. Knepley static PetscErrorCode DMSetDefaultAdjacency_Private(DM dm, PetscInt f, PetscObject disc) 463734aa8a36SMatthew G. Knepley { 463834aa8a36SMatthew G. Knepley PetscClassId id; 463934aa8a36SMatthew G. Knepley PetscErrorCode ierr; 464034aa8a36SMatthew G. Knepley 464134aa8a36SMatthew G. Knepley PetscFunctionBegin; 464234aa8a36SMatthew G. Knepley ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr); 464334aa8a36SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 464434aa8a36SMatthew G. Knepley ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr); 464534aa8a36SMatthew G. Knepley } else if (id == PETSCFV_CLASSID) { 464634aa8a36SMatthew G. Knepley ierr = DMSetAdjacency(dm, f, PETSC_TRUE, PETSC_FALSE);CHKERRQ(ierr); 464717c1d62eSMatthew G. Knepley } else { 464817c1d62eSMatthew G. Knepley ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr); 464934aa8a36SMatthew G. Knepley } 465034aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 465134aa8a36SMatthew G. Knepley } 465234aa8a36SMatthew G. Knepley 465344a7f3ddSMatthew G. Knepley static PetscErrorCode DMFieldEnlarge_Static(DM dm, PetscInt NfNew) 465444a7f3ddSMatthew G. Knepley { 465544a7f3ddSMatthew G. Knepley RegionField *tmpr; 465644a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf, f; 465744a7f3ddSMatthew G. Knepley PetscErrorCode ierr; 465844a7f3ddSMatthew G. Knepley 465944a7f3ddSMatthew G. Knepley PetscFunctionBegin; 466044a7f3ddSMatthew G. Knepley if (Nf >= NfNew) PetscFunctionReturn(0); 466144a7f3ddSMatthew G. Knepley ierr = PetscMalloc1(NfNew, &tmpr);CHKERRQ(ierr); 466244a7f3ddSMatthew G. Knepley for (f = 0; f < Nf; ++f) tmpr[f] = dm->fields[f]; 4663e0b68406SMatthew Knepley for (f = Nf; f < NfNew; ++f) {tmpr[f].disc = NULL; tmpr[f].label = NULL; tmpr[f].avoidTensor = PETSC_FALSE;} 466444a7f3ddSMatthew G. Knepley ierr = PetscFree(dm->fields);CHKERRQ(ierr); 466544a7f3ddSMatthew G. Knepley dm->Nf = NfNew; 466644a7f3ddSMatthew G. Knepley dm->fields = tmpr; 466744a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 466844a7f3ddSMatthew G. Knepley } 466944a7f3ddSMatthew G. Knepley 467044a7f3ddSMatthew G. Knepley /*@ 467144a7f3ddSMatthew G. Knepley DMClearFields - Remove all fields from the DM 467244a7f3ddSMatthew G. Knepley 4673d083f849SBarry Smith Logically collective on dm 467444a7f3ddSMatthew G. Knepley 467544a7f3ddSMatthew G. Knepley Input Parameter: 467644a7f3ddSMatthew G. Knepley . dm - The DM 467744a7f3ddSMatthew G. Knepley 467844a7f3ddSMatthew G. Knepley Level: intermediate 467944a7f3ddSMatthew G. Knepley 468044a7f3ddSMatthew G. Knepley .seealso: DMGetNumFields(), DMSetNumFields(), DMSetField() 468144a7f3ddSMatthew G. Knepley @*/ 468244a7f3ddSMatthew G. Knepley PetscErrorCode DMClearFields(DM dm) 468344a7f3ddSMatthew G. Knepley { 468444a7f3ddSMatthew G. Knepley PetscInt f; 468544a7f3ddSMatthew G. Knepley PetscErrorCode ierr; 468644a7f3ddSMatthew G. Knepley 468744a7f3ddSMatthew G. Knepley PetscFunctionBegin; 468844a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 468944a7f3ddSMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 469044a7f3ddSMatthew G. Knepley ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr); 469144a7f3ddSMatthew G. Knepley ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr); 469244a7f3ddSMatthew G. Knepley } 469344a7f3ddSMatthew G. Knepley ierr = PetscFree(dm->fields);CHKERRQ(ierr); 469444a7f3ddSMatthew G. Knepley dm->fields = NULL; 469544a7f3ddSMatthew G. Knepley dm->Nf = 0; 469644a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 469744a7f3ddSMatthew G. Knepley } 469844a7f3ddSMatthew G. Knepley 4699689b5837SMatthew G. Knepley /*@ 4700689b5837SMatthew G. Knepley DMGetNumFields - Get the number of fields in the DM 4701689b5837SMatthew G. Knepley 4702689b5837SMatthew G. Knepley Not collective 4703689b5837SMatthew G. Knepley 4704689b5837SMatthew G. Knepley Input Parameter: 4705689b5837SMatthew G. Knepley . dm - The DM 4706689b5837SMatthew G. Knepley 4707689b5837SMatthew G. Knepley Output Parameter: 4708689b5837SMatthew G. Knepley . Nf - The number of fields 4709689b5837SMatthew G. Knepley 4710689b5837SMatthew G. Knepley Level: intermediate 4711689b5837SMatthew G. Knepley 4712689b5837SMatthew G. Knepley .seealso: DMSetNumFields(), DMSetField() 4713689b5837SMatthew G. Knepley @*/ 47140f21e855SMatthew G. Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields) 47150f21e855SMatthew G. Knepley { 47160f21e855SMatthew G. Knepley PetscFunctionBegin; 47170f21e855SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4718534a8f05SLisandro Dalcin PetscValidIntPointer(numFields, 2); 471944a7f3ddSMatthew G. Knepley *numFields = dm->Nf; 4720af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4721af122d2aSMatthew G Knepley } 4722af122d2aSMatthew G Knepley 4723689b5837SMatthew G. Knepley /*@ 4724689b5837SMatthew G. Knepley DMSetNumFields - Set the number of fields in the DM 4725689b5837SMatthew G. Knepley 4726d083f849SBarry Smith Logically collective on dm 4727689b5837SMatthew G. Knepley 4728689b5837SMatthew G. Knepley Input Parameters: 4729689b5837SMatthew G. Knepley + dm - The DM 4730689b5837SMatthew G. Knepley - Nf - The number of fields 4731689b5837SMatthew G. Knepley 4732689b5837SMatthew G. Knepley Level: intermediate 4733689b5837SMatthew G. Knepley 4734689b5837SMatthew G. Knepley .seealso: DMGetNumFields(), DMSetField() 4735689b5837SMatthew G. Knepley @*/ 4736af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields) 4737af122d2aSMatthew G Knepley { 47380f21e855SMatthew G. Knepley PetscInt Nf, f; 4739af122d2aSMatthew G Knepley PetscErrorCode ierr; 4740af122d2aSMatthew G Knepley 4741af122d2aSMatthew G Knepley PetscFunctionBegin; 4742af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 474344a7f3ddSMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 47440f21e855SMatthew G. Knepley for (f = Nf; f < numFields; ++f) { 47450f21e855SMatthew G. Knepley PetscContainer obj; 47460f21e855SMatthew G. Knepley 47470f21e855SMatthew G. Knepley ierr = PetscContainerCreate(PetscObjectComm((PetscObject) dm), &obj);CHKERRQ(ierr); 474844a7f3ddSMatthew G. Knepley ierr = DMAddField(dm, NULL, (PetscObject) obj);CHKERRQ(ierr); 47490f21e855SMatthew G. Knepley ierr = PetscContainerDestroy(&obj);CHKERRQ(ierr); 4750af122d2aSMatthew G Knepley } 4751af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4752af122d2aSMatthew G Knepley } 4753af122d2aSMatthew G Knepley 4754c1929be8SMatthew G. Knepley /*@ 4755c1929be8SMatthew G. Knepley DMGetField - Return the discretization object for a given DM field 4756c1929be8SMatthew G. Knepley 4757c1929be8SMatthew G. Knepley Not collective 4758c1929be8SMatthew G. Knepley 4759c1929be8SMatthew G. Knepley Input Parameters: 4760c1929be8SMatthew G. Knepley + dm - The DM 4761c1929be8SMatthew G. Knepley - f - The field number 4762c1929be8SMatthew G. Knepley 476344a7f3ddSMatthew G. Knepley Output Parameters: 476444a7f3ddSMatthew G. Knepley + label - The label indicating the support of the field, or NULL for the entire mesh 476544a7f3ddSMatthew G. Knepley - field - The discretization object 4766c1929be8SMatthew G. Knepley 476744a7f3ddSMatthew G. Knepley Level: intermediate 4768c1929be8SMatthew G. Knepley 476944a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMSetField() 4770c1929be8SMatthew G. Knepley @*/ 477144a7f3ddSMatthew G. Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, DMLabel *label, PetscObject *field) 4772af122d2aSMatthew G Knepley { 4773af122d2aSMatthew G Knepley PetscFunctionBegin; 4774af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 477544a7f3ddSMatthew G. Knepley PetscValidPointer(field, 3); 477644a7f3ddSMatthew 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); 477744a7f3ddSMatthew G. Knepley if (label) *label = dm->fields[f].label; 477844a7f3ddSMatthew G. Knepley if (field) *field = dm->fields[f].disc; 4779decb47aaSMatthew G. Knepley PetscFunctionReturn(0); 4780decb47aaSMatthew G. Knepley } 4781decb47aaSMatthew G. Knepley 4782083401c6SMatthew G. Knepley /* Does not clear the DS */ 4783083401c6SMatthew G. Knepley PetscErrorCode DMSetField_Internal(DM dm, PetscInt f, DMLabel label, PetscObject field) 4784083401c6SMatthew G. Knepley { 4785083401c6SMatthew G. Knepley PetscErrorCode ierr; 4786083401c6SMatthew G. Knepley 4787083401c6SMatthew G. Knepley PetscFunctionBegin; 4788083401c6SMatthew G. Knepley ierr = DMFieldEnlarge_Static(dm, f+1);CHKERRQ(ierr); 4789083401c6SMatthew G. Knepley ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr); 4790083401c6SMatthew G. Knepley ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr); 4791083401c6SMatthew G. Knepley dm->fields[f].label = label; 4792083401c6SMatthew G. Knepley dm->fields[f].disc = field; 4793083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 4794083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr); 4795083401c6SMatthew G. Knepley PetscFunctionReturn(0); 4796083401c6SMatthew G. Knepley } 4797083401c6SMatthew G. Knepley 4798c1929be8SMatthew G. Knepley /*@ 4799c1929be8SMatthew G. Knepley DMSetField - Set the discretization object for a given DM field 4800c1929be8SMatthew G. Knepley 4801d083f849SBarry Smith Logically collective on dm 4802c1929be8SMatthew G. Knepley 4803c1929be8SMatthew G. Knepley Input Parameters: 4804c1929be8SMatthew G. Knepley + dm - The DM 4805c1929be8SMatthew G. Knepley . f - The field number 480644a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh 4807c1929be8SMatthew G. Knepley - field - The discretization object 4808c1929be8SMatthew G. Knepley 480944a7f3ddSMatthew G. Knepley Level: intermediate 4810c1929be8SMatthew G. Knepley 481144a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMGetField() 4812c1929be8SMatthew G. Knepley @*/ 481344a7f3ddSMatthew G. Knepley PetscErrorCode DMSetField(DM dm, PetscInt f, DMLabel label, PetscObject field) 4814decb47aaSMatthew G. Knepley { 4815decb47aaSMatthew G. Knepley PetscErrorCode ierr; 4816decb47aaSMatthew G. Knepley 4817decb47aaSMatthew G. Knepley PetscFunctionBegin; 4818decb47aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4819e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 482044a7f3ddSMatthew G. Knepley PetscValidHeader(field, 4); 4821e5e52638SMatthew G. Knepley if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 4822083401c6SMatthew G. Knepley ierr = DMSetField_Internal(dm, f, label, field);CHKERRQ(ierr); 482334aa8a36SMatthew G. Knepley ierr = DMSetDefaultAdjacency_Private(dm, f, field);CHKERRQ(ierr); 48242df9ee95SMatthew G. Knepley ierr = DMClearDS(dm);CHKERRQ(ierr); 482544a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 482644a7f3ddSMatthew G. Knepley } 482744a7f3ddSMatthew G. Knepley 482844a7f3ddSMatthew G. Knepley /*@ 482944a7f3ddSMatthew G. Knepley DMAddField - Add the discretization object for the given DM field 483044a7f3ddSMatthew G. Knepley 4831d083f849SBarry Smith Logically collective on dm 483244a7f3ddSMatthew G. Knepley 483344a7f3ddSMatthew G. Knepley Input Parameters: 483444a7f3ddSMatthew G. Knepley + dm - The DM 483544a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh 483644a7f3ddSMatthew G. Knepley - field - The discretization object 483744a7f3ddSMatthew G. Knepley 483844a7f3ddSMatthew G. Knepley Level: intermediate 483944a7f3ddSMatthew G. Knepley 484044a7f3ddSMatthew G. Knepley .seealso: DMSetField(), DMGetField() 484144a7f3ddSMatthew G. Knepley @*/ 484244a7f3ddSMatthew G. Knepley PetscErrorCode DMAddField(DM dm, DMLabel label, PetscObject field) 484344a7f3ddSMatthew G. Knepley { 484444a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf; 484544a7f3ddSMatthew G. Knepley PetscErrorCode ierr; 484644a7f3ddSMatthew G. Knepley 484744a7f3ddSMatthew G. Knepley PetscFunctionBegin; 484844a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 484944a7f3ddSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 485044a7f3ddSMatthew G. Knepley PetscValidHeader(field, 3); 485144a7f3ddSMatthew G. Knepley ierr = DMFieldEnlarge_Static(dm, Nf+1);CHKERRQ(ierr); 485244a7f3ddSMatthew G. Knepley dm->fields[Nf].label = label; 485344a7f3ddSMatthew G. Knepley dm->fields[Nf].disc = field; 485444a7f3ddSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 485544a7f3ddSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr); 485634aa8a36SMatthew G. Knepley ierr = DMSetDefaultAdjacency_Private(dm, Nf, field);CHKERRQ(ierr); 48572df9ee95SMatthew G. Knepley ierr = DMClearDS(dm);CHKERRQ(ierr); 4858af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4859af122d2aSMatthew G Knepley } 48606636e97aSMatthew G Knepley 4861e5e52638SMatthew G. Knepley /*@ 4862e0b68406SMatthew Knepley DMSetFieldAvoidTensor - Set flag to avoid defining the field on tensor cells 4863e0b68406SMatthew Knepley 4864e0b68406SMatthew Knepley Logically collective on dm 4865e0b68406SMatthew Knepley 4866e0b68406SMatthew Knepley Input Parameters: 4867e0b68406SMatthew Knepley + dm - The DM 4868e0b68406SMatthew Knepley . f - The field index 4869e0b68406SMatthew Knepley - avoidTensor - The flag to avoid defining the field on tensor cells 4870e0b68406SMatthew Knepley 4871e0b68406SMatthew Knepley Level: intermediate 4872e0b68406SMatthew Knepley 4873e0b68406SMatthew Knepley .seealso: DMGetFieldAvoidTensor(), DMSetField(), DMGetField() 4874e0b68406SMatthew Knepley @*/ 4875e0b68406SMatthew Knepley PetscErrorCode DMSetFieldAvoidTensor(DM dm, PetscInt f, PetscBool avoidTensor) 4876e0b68406SMatthew Knepley { 4877e0b68406SMatthew Knepley PetscFunctionBegin; 4878e0b68406SMatthew 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); 4879e0b68406SMatthew Knepley dm->fields[f].avoidTensor = avoidTensor; 4880e0b68406SMatthew Knepley PetscFunctionReturn(0); 4881e0b68406SMatthew Knepley } 4882e0b68406SMatthew Knepley 4883e0b68406SMatthew Knepley /*@ 4884e0b68406SMatthew Knepley DMGetFieldAvoidTensor - Get flag to avoid defining the field on tensor cells 4885e0b68406SMatthew Knepley 4886e0b68406SMatthew Knepley Logically collective on dm 4887e0b68406SMatthew Knepley 4888e0b68406SMatthew Knepley Input Parameters: 4889e0b68406SMatthew Knepley + dm - The DM 4890e0b68406SMatthew Knepley - f - The field index 4891e0b68406SMatthew Knepley 4892e0b68406SMatthew Knepley Output Parameter: 4893e0b68406SMatthew Knepley . avoidTensor - The flag to avoid defining the field on tensor cells 4894e0b68406SMatthew Knepley 4895e0b68406SMatthew Knepley Level: intermediate 4896e0b68406SMatthew Knepley 4897e0b68406SMatthew Knepley .seealso: DMSetFieldAvoidTensor(), DMSetField(), DMGetField() 4898e0b68406SMatthew Knepley @*/ 4899e0b68406SMatthew Knepley PetscErrorCode DMGetFieldAvoidTensor(DM dm, PetscInt f, PetscBool *avoidTensor) 4900e0b68406SMatthew Knepley { 4901e0b68406SMatthew Knepley PetscFunctionBegin; 4902e0b68406SMatthew 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); 4903e0b68406SMatthew Knepley *avoidTensor = dm->fields[f].avoidTensor; 4904e0b68406SMatthew Knepley PetscFunctionReturn(0); 4905e0b68406SMatthew Knepley } 4906e0b68406SMatthew Knepley 4907e0b68406SMatthew Knepley /*@ 4908e5e52638SMatthew G. Knepley DMCopyFields - Copy the discretizations for the DM into another DM 4909e5e52638SMatthew G. Knepley 4910d083f849SBarry Smith Collective on dm 4911e5e52638SMatthew G. Knepley 4912e5e52638SMatthew G. Knepley Input Parameter: 4913e5e52638SMatthew G. Knepley . dm - The DM 4914e5e52638SMatthew G. Knepley 4915e5e52638SMatthew G. Knepley Output Parameter: 4916e5e52638SMatthew G. Knepley . newdm - The DM 4917e5e52638SMatthew G. Knepley 4918e5e52638SMatthew G. Knepley Level: advanced 4919e5e52638SMatthew G. Knepley 4920e5e52638SMatthew G. Knepley .seealso: DMGetField(), DMSetField(), DMAddField(), DMCopyDS(), DMGetDS(), DMGetCellDS() 4921e5e52638SMatthew G. Knepley @*/ 4922e5e52638SMatthew G. Knepley PetscErrorCode DMCopyFields(DM dm, DM newdm) 4923e5e52638SMatthew G. Knepley { 4924e5e52638SMatthew G. Knepley PetscInt Nf, f; 4925e5e52638SMatthew G. Knepley PetscErrorCode ierr; 4926e5e52638SMatthew G. Knepley 4927e5e52638SMatthew G. Knepley PetscFunctionBegin; 4928e5e52638SMatthew G. Knepley if (dm == newdm) PetscFunctionReturn(0); 4929e5e52638SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 4930e5e52638SMatthew G. Knepley ierr = DMClearFields(newdm);CHKERRQ(ierr); 4931e5e52638SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 4932e5e52638SMatthew G. Knepley DMLabel label; 4933e5e52638SMatthew G. Knepley PetscObject field; 493434aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 4935e5e52638SMatthew G. Knepley 4936e5e52638SMatthew G. Knepley ierr = DMGetField(dm, f, &label, &field);CHKERRQ(ierr); 4937e5e52638SMatthew G. Knepley ierr = DMSetField(newdm, f, label, field);CHKERRQ(ierr); 493834aa8a36SMatthew G. Knepley ierr = DMGetAdjacency(dm, f, &useCone, &useClosure);CHKERRQ(ierr); 493934aa8a36SMatthew G. Knepley ierr = DMSetAdjacency(newdm, f, useCone, useClosure);CHKERRQ(ierr); 494034aa8a36SMatthew G. Knepley } 494134aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 494234aa8a36SMatthew G. Knepley } 494334aa8a36SMatthew G. Knepley 494434aa8a36SMatthew G. Knepley /*@ 494534aa8a36SMatthew G. Knepley DMGetAdjacency - Returns the flags for determining variable influence 494634aa8a36SMatthew G. Knepley 494734aa8a36SMatthew G. Knepley Not collective 494834aa8a36SMatthew G. Knepley 494934aa8a36SMatthew G. Knepley Input Parameters: 495034aa8a36SMatthew G. Knepley + dm - The DM object 495134aa8a36SMatthew G. Knepley - f - The field number, or PETSC_DEFAULT for the default adjacency 495234aa8a36SMatthew G. Knepley 495334aa8a36SMatthew G. Knepley Output Parameter: 495434aa8a36SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 495534aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 495634aa8a36SMatthew G. Knepley 495734aa8a36SMatthew G. Knepley Notes: 495834aa8a36SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 495934aa8a36SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 496034aa8a36SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 4961979e053dSMatthew G. Knepley Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 496234aa8a36SMatthew G. Knepley 496334aa8a36SMatthew G. Knepley Level: developer 496434aa8a36SMatthew G. Knepley 496534aa8a36SMatthew G. Knepley .seealso: DMSetAdjacency(), DMGetField(), DMSetField() 496634aa8a36SMatthew G. Knepley @*/ 496734aa8a36SMatthew G. Knepley PetscErrorCode DMGetAdjacency(DM dm, PetscInt f, PetscBool *useCone, PetscBool *useClosure) 496834aa8a36SMatthew G. Knepley { 496934aa8a36SMatthew G. Knepley PetscFunctionBegin; 497034aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4971534a8f05SLisandro Dalcin if (useCone) PetscValidBoolPointer(useCone, 3); 4972534a8f05SLisandro Dalcin if (useClosure) PetscValidBoolPointer(useClosure, 4); 497334aa8a36SMatthew G. Knepley if (f < 0) { 497434aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->adjacency[0]; 497534aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->adjacency[1]; 497634aa8a36SMatthew G. Knepley } else { 497734aa8a36SMatthew G. Knepley PetscInt Nf; 497834aa8a36SMatthew G. Knepley PetscErrorCode ierr; 497934aa8a36SMatthew G. Knepley 498034aa8a36SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 498134aa8a36SMatthew G. Knepley if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf); 498234aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->fields[f].adjacency[0]; 498334aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->fields[f].adjacency[1]; 498434aa8a36SMatthew G. Knepley } 498534aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 498634aa8a36SMatthew G. Knepley } 498734aa8a36SMatthew G. Knepley 498834aa8a36SMatthew G. Knepley /*@ 498934aa8a36SMatthew G. Knepley DMSetAdjacency - Set the flags for determining variable influence 499034aa8a36SMatthew G. Knepley 499134aa8a36SMatthew G. Knepley Not collective 499234aa8a36SMatthew G. Knepley 499334aa8a36SMatthew G. Knepley Input Parameters: 499434aa8a36SMatthew G. Knepley + dm - The DM object 499534aa8a36SMatthew G. Knepley . f - The field number 499634aa8a36SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 499734aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 499834aa8a36SMatthew G. Knepley 499934aa8a36SMatthew G. Knepley Notes: 500034aa8a36SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 500134aa8a36SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 500234aa8a36SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5003979e053dSMatthew G. Knepley Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 500434aa8a36SMatthew G. Knepley 500534aa8a36SMatthew G. Knepley Level: developer 500634aa8a36SMatthew G. Knepley 500734aa8a36SMatthew G. Knepley .seealso: DMGetAdjacency(), DMGetField(), DMSetField() 500834aa8a36SMatthew G. Knepley @*/ 500934aa8a36SMatthew G. Knepley PetscErrorCode DMSetAdjacency(DM dm, PetscInt f, PetscBool useCone, PetscBool useClosure) 501034aa8a36SMatthew G. Knepley { 501134aa8a36SMatthew G. Knepley PetscFunctionBegin; 501234aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 501334aa8a36SMatthew G. Knepley if (f < 0) { 501434aa8a36SMatthew G. Knepley dm->adjacency[0] = useCone; 501534aa8a36SMatthew G. Knepley dm->adjacency[1] = useClosure; 501634aa8a36SMatthew G. Knepley } else { 501734aa8a36SMatthew G. Knepley PetscInt Nf; 501834aa8a36SMatthew G. Knepley PetscErrorCode ierr; 501934aa8a36SMatthew G. Knepley 502034aa8a36SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 502134aa8a36SMatthew G. Knepley if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf); 502234aa8a36SMatthew G. Knepley dm->fields[f].adjacency[0] = useCone; 502334aa8a36SMatthew G. Knepley dm->fields[f].adjacency[1] = useClosure; 5024e5e52638SMatthew G. Knepley } 5025e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5026e5e52638SMatthew G. Knepley } 5027e5e52638SMatthew G. Knepley 5028b0441da4SMatthew G. Knepley /*@ 5029b0441da4SMatthew G. Knepley DMGetBasicAdjacency - Returns the flags for determining variable influence, using either the default or field 0 if it is defined 5030b0441da4SMatthew G. Knepley 5031b0441da4SMatthew G. Knepley Not collective 5032b0441da4SMatthew G. Knepley 5033b0441da4SMatthew G. Knepley Input Parameters: 5034b0441da4SMatthew G. Knepley . dm - The DM object 5035b0441da4SMatthew G. Knepley 5036b0441da4SMatthew G. Knepley Output Parameter: 5037b0441da4SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 5038b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5039b0441da4SMatthew G. Knepley 5040b0441da4SMatthew G. Knepley Notes: 5041b0441da4SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 5042b0441da4SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 5043b0441da4SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5044b0441da4SMatthew G. Knepley 5045b0441da4SMatthew G. Knepley Level: developer 5046b0441da4SMatthew G. Knepley 5047b0441da4SMatthew G. Knepley .seealso: DMSetBasicAdjacency(), DMGetField(), DMSetField() 5048b0441da4SMatthew G. Knepley @*/ 5049b0441da4SMatthew G. Knepley PetscErrorCode DMGetBasicAdjacency(DM dm, PetscBool *useCone, PetscBool *useClosure) 5050b0441da4SMatthew G. Knepley { 5051b0441da4SMatthew G. Knepley PetscInt Nf; 5052b0441da4SMatthew G. Knepley PetscErrorCode ierr; 5053b0441da4SMatthew G. Knepley 5054b0441da4SMatthew G. Knepley PetscFunctionBegin; 5055b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5056534a8f05SLisandro Dalcin if (useCone) PetscValidBoolPointer(useCone, 3); 5057534a8f05SLisandro Dalcin if (useClosure) PetscValidBoolPointer(useClosure, 4); 5058b0441da4SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 5059b0441da4SMatthew G. Knepley if (!Nf) { 5060b0441da4SMatthew G. Knepley ierr = DMGetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr); 5061b0441da4SMatthew G. Knepley } else { 5062b0441da4SMatthew G. Knepley ierr = DMGetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr); 5063b0441da4SMatthew G. Knepley } 5064b0441da4SMatthew G. Knepley PetscFunctionReturn(0); 5065b0441da4SMatthew G. Knepley } 5066b0441da4SMatthew G. Knepley 5067b0441da4SMatthew G. Knepley /*@ 5068b0441da4SMatthew G. Knepley DMSetBasicAdjacency - Set the flags for determining variable influence, using either the default or field 0 if it is defined 5069b0441da4SMatthew G. Knepley 5070b0441da4SMatthew G. Knepley Not collective 5071b0441da4SMatthew G. Knepley 5072b0441da4SMatthew G. Knepley Input Parameters: 5073b0441da4SMatthew G. Knepley + dm - The DM object 5074b0441da4SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 5075b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5076b0441da4SMatthew G. Knepley 5077b0441da4SMatthew G. Knepley Notes: 5078b0441da4SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 5079b0441da4SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 5080b0441da4SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5081b0441da4SMatthew G. Knepley 5082b0441da4SMatthew G. Knepley Level: developer 5083b0441da4SMatthew G. Knepley 5084b0441da4SMatthew G. Knepley .seealso: DMGetBasicAdjacency(), DMGetField(), DMSetField() 5085b0441da4SMatthew G. Knepley @*/ 5086b0441da4SMatthew G. Knepley PetscErrorCode DMSetBasicAdjacency(DM dm, PetscBool useCone, PetscBool useClosure) 5087b0441da4SMatthew G. Knepley { 5088b0441da4SMatthew G. Knepley PetscInt Nf; 5089b0441da4SMatthew G. Knepley PetscErrorCode ierr; 5090b0441da4SMatthew G. Knepley 5091b0441da4SMatthew G. Knepley PetscFunctionBegin; 5092b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5093b0441da4SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 5094b0441da4SMatthew G. Knepley if (!Nf) { 5095b0441da4SMatthew G. Knepley ierr = DMSetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr); 5096b0441da4SMatthew G. Knepley } else { 5097b0441da4SMatthew G. Knepley ierr = DMSetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr); 5098e5e52638SMatthew G. Knepley } 5099e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5100e5e52638SMatthew G. Knepley } 5101e5e52638SMatthew G. Knepley 5102783e2ec8SMatthew G. Knepley /* Complete labels that are being used for FEM BC */ 5103*45480ffeSMatthew G. Knepley static PetscErrorCode DMCompleteBoundaryLabel_Internal(DM dm, PetscDS ds, PetscInt field, PetscInt bdNum, DMLabel label) 5104783e2ec8SMatthew G. Knepley { 5105783e2ec8SMatthew G. Knepley PetscObject obj; 5106783e2ec8SMatthew G. Knepley PetscClassId id; 5107783e2ec8SMatthew G. Knepley PetscInt Nbd, bd; 5108783e2ec8SMatthew G. Knepley PetscBool isFE = PETSC_FALSE; 5109783e2ec8SMatthew G. Knepley PetscBool duplicate = PETSC_FALSE; 5110783e2ec8SMatthew G. Knepley PetscErrorCode ierr; 5111783e2ec8SMatthew G. Knepley 5112783e2ec8SMatthew G. Knepley PetscFunctionBegin; 5113783e2ec8SMatthew G. Knepley ierr = DMGetField(dm, field, NULL, &obj);CHKERRQ(ierr); 5114783e2ec8SMatthew G. Knepley ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 5115783e2ec8SMatthew G. Knepley if (id == PETSCFE_CLASSID) isFE = PETSC_TRUE; 5116783e2ec8SMatthew G. Knepley if (isFE && label) { 5117783e2ec8SMatthew G. Knepley /* Only want to modify label once */ 5118783e2ec8SMatthew G. Knepley ierr = PetscDSGetNumBoundary(ds, &Nbd);CHKERRQ(ierr); 5119783e2ec8SMatthew G. Knepley for (bd = 0; bd < PetscMin(Nbd, bdNum); ++bd) { 5120*45480ffeSMatthew G. Knepley DMLabel l; 5121783e2ec8SMatthew G. Knepley 5122*45480ffeSMatthew G. Knepley ierr = PetscDSGetBoundary(ds, bd, NULL, NULL, NULL, &l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 5123*45480ffeSMatthew G. Knepley duplicate = l == label ? PETSC_TRUE : PETSC_FALSE; 5124783e2ec8SMatthew G. Knepley if (duplicate) break; 5125783e2ec8SMatthew G. Knepley } 5126783e2ec8SMatthew G. Knepley if (!duplicate) { 5127783e2ec8SMatthew G. Knepley DM plex; 5128783e2ec8SMatthew G. Knepley 5129783e2ec8SMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 5130783e2ec8SMatthew G. Knepley if (plex) {ierr = DMPlexLabelComplete(plex, label);CHKERRQ(ierr);} 5131783e2ec8SMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 5132783e2ec8SMatthew G. Knepley } 5133783e2ec8SMatthew G. Knepley } 5134783e2ec8SMatthew G. Knepley PetscFunctionReturn(0); 5135783e2ec8SMatthew G. Knepley } 5136783e2ec8SMatthew G. Knepley 5137e5e52638SMatthew G. Knepley static PetscErrorCode DMDSEnlarge_Static(DM dm, PetscInt NdsNew) 5138e5e52638SMatthew G. Knepley { 5139e5e52638SMatthew G. Knepley DMSpace *tmpd; 5140e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5141e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5142e5e52638SMatthew G. Knepley 5143e5e52638SMatthew G. Knepley PetscFunctionBegin; 5144e5e52638SMatthew G. Knepley if (Nds >= NdsNew) PetscFunctionReturn(0); 5145e5e52638SMatthew G. Knepley ierr = PetscMalloc1(NdsNew, &tmpd);CHKERRQ(ierr); 5146e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) tmpd[s] = dm->probs[s]; 5147b3cf3223SMatthew G. Knepley for (s = Nds; s < NdsNew; ++s) {tmpd[s].ds = NULL; tmpd[s].label = NULL; tmpd[s].fields = NULL;} 5148e5e52638SMatthew G. Knepley ierr = PetscFree(dm->probs);CHKERRQ(ierr); 5149e5e52638SMatthew G. Knepley dm->Nds = NdsNew; 5150e5e52638SMatthew G. Knepley dm->probs = tmpd; 5151e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5152e5e52638SMatthew G. Knepley } 5153e5e52638SMatthew G. Knepley 5154e5e52638SMatthew G. Knepley /*@ 5155e5e52638SMatthew G. Knepley DMGetNumDS - Get the number of discrete systems in the DM 5156e5e52638SMatthew G. Knepley 5157e5e52638SMatthew G. Knepley Not collective 5158e5e52638SMatthew G. Knepley 5159e5e52638SMatthew G. Knepley Input Parameter: 5160e5e52638SMatthew G. Knepley . dm - The DM 5161e5e52638SMatthew G. Knepley 5162e5e52638SMatthew G. Knepley Output Parameter: 5163e5e52638SMatthew G. Knepley . Nds - The number of PetscDS objects 5164e5e52638SMatthew G. Knepley 5165e5e52638SMatthew G. Knepley Level: intermediate 5166e5e52638SMatthew G. Knepley 5167e5e52638SMatthew G. Knepley .seealso: DMGetDS(), DMGetCellDS() 5168e5e52638SMatthew G. Knepley @*/ 5169e5e52638SMatthew G. Knepley PetscErrorCode DMGetNumDS(DM dm, PetscInt *Nds) 5170e5e52638SMatthew G. Knepley { 5171e5e52638SMatthew G. Knepley PetscFunctionBegin; 5172e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5173534a8f05SLisandro Dalcin PetscValidIntPointer(Nds, 2); 5174e5e52638SMatthew G. Knepley *Nds = dm->Nds; 5175e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5176e5e52638SMatthew G. Knepley } 5177e5e52638SMatthew G. Knepley 5178e5e52638SMatthew G. Knepley /*@ 5179e5e52638SMatthew G. Knepley DMClearDS - Remove all discrete systems from the DM 5180e5e52638SMatthew G. Knepley 5181d083f849SBarry Smith Logically collective on dm 5182e5e52638SMatthew G. Knepley 5183e5e52638SMatthew G. Knepley Input Parameter: 5184e5e52638SMatthew G. Knepley . dm - The DM 5185e5e52638SMatthew G. Knepley 5186e5e52638SMatthew G. Knepley Level: intermediate 5187e5e52638SMatthew G. Knepley 5188e5e52638SMatthew G. Knepley .seealso: DMGetNumDS(), DMGetDS(), DMSetField() 5189e5e52638SMatthew G. Knepley @*/ 5190e5e52638SMatthew G. Knepley PetscErrorCode DMClearDS(DM dm) 5191e5e52638SMatthew G. Knepley { 5192e5e52638SMatthew G. Knepley PetscInt s; 5193e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5194e5e52638SMatthew G. Knepley 5195e5e52638SMatthew G. Knepley PetscFunctionBegin; 5196e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5197e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5198e5e52638SMatthew G. Knepley ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr); 5199e5e52638SMatthew G. Knepley ierr = DMLabelDestroy(&dm->probs[s].label);CHKERRQ(ierr); 5200b3cf3223SMatthew G. Knepley ierr = ISDestroy(&dm->probs[s].fields);CHKERRQ(ierr); 5201e5e52638SMatthew G. Knepley } 5202e5e52638SMatthew G. Knepley ierr = PetscFree(dm->probs);CHKERRQ(ierr); 5203e5e52638SMatthew G. Knepley dm->probs = NULL; 5204e5e52638SMatthew G. Knepley dm->Nds = 0; 5205e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5206e5e52638SMatthew G. Knepley } 5207e5e52638SMatthew G. Knepley 5208e5e52638SMatthew G. Knepley /*@ 5209e5e52638SMatthew G. Knepley DMGetDS - Get the default PetscDS 5210e5e52638SMatthew G. Knepley 5211e5e52638SMatthew G. Knepley Not collective 5212e5e52638SMatthew G. Knepley 5213e5e52638SMatthew G. Knepley Input Parameter: 5214e5e52638SMatthew G. Knepley . dm - The DM 5215e5e52638SMatthew G. Knepley 5216e5e52638SMatthew G. Knepley Output Parameter: 5217e5e52638SMatthew G. Knepley . prob - The default PetscDS 5218e5e52638SMatthew G. Knepley 5219e5e52638SMatthew G. Knepley Level: intermediate 5220e5e52638SMatthew G. Knepley 5221e5e52638SMatthew G. Knepley .seealso: DMGetCellDS(), DMGetRegionDS() 5222e5e52638SMatthew G. Knepley @*/ 5223e5e52638SMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *prob) 5224e5e52638SMatthew G. Knepley { 5225b0143b4dSMatthew G. Knepley PetscErrorCode ierr; 5226b0143b4dSMatthew G. Knepley 5227e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5228e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5229e5e52638SMatthew G. Knepley PetscValidPointer(prob, 2); 5230b0143b4dSMatthew G. Knepley if (dm->Nds <= 0) { 5231b0143b4dSMatthew G. Knepley PetscDS ds; 5232b0143b4dSMatthew G. Knepley 5233*45480ffeSMatthew G. Knepley ierr = PetscDSCreate(PETSC_COMM_SELF, &ds);CHKERRQ(ierr); 5234b3cf3223SMatthew G. Knepley ierr = DMSetRegionDS(dm, NULL, NULL, ds);CHKERRQ(ierr); 5235b0143b4dSMatthew G. Knepley ierr = PetscDSDestroy(&ds);CHKERRQ(ierr); 5236b0143b4dSMatthew G. Knepley } 5237b0143b4dSMatthew G. Knepley *prob = dm->probs[0].ds; 5238e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5239e5e52638SMatthew G. Knepley } 5240e5e52638SMatthew G. Knepley 5241e5e52638SMatthew G. Knepley /*@ 5242e5e52638SMatthew G. Knepley DMGetCellDS - Get the PetscDS defined on a given cell 5243e5e52638SMatthew G. Knepley 5244e5e52638SMatthew G. Knepley Not collective 5245e5e52638SMatthew G. Knepley 5246e5e52638SMatthew G. Knepley Input Parameters: 5247e5e52638SMatthew G. Knepley + dm - The DM 5248e5e52638SMatthew G. Knepley - point - Cell for the DS 5249e5e52638SMatthew G. Knepley 5250e5e52638SMatthew G. Knepley Output Parameter: 5251e5e52638SMatthew G. Knepley . prob - The PetscDS defined on the given cell 5252e5e52638SMatthew G. Knepley 5253e5e52638SMatthew G. Knepley Level: developer 5254e5e52638SMatthew G. Knepley 5255b0143b4dSMatthew G. Knepley .seealso: DMGetDS(), DMSetRegionDS() 5256e5e52638SMatthew G. Knepley @*/ 5257e5e52638SMatthew G. Knepley PetscErrorCode DMGetCellDS(DM dm, PetscInt point, PetscDS *prob) 5258e5e52638SMatthew G. Knepley { 5259e5e52638SMatthew G. Knepley PetscDS probDef = NULL; 5260e5e52638SMatthew G. Knepley PetscInt s; 5261e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5262e5e52638SMatthew G. Knepley 5263e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5264e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5265e5e52638SMatthew G. Knepley PetscValidPointer(prob, 3); 5266360cf244SMatthew G. Knepley if (point < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Mesh point cannot be negative: %D", point); 5267e5e52638SMatthew G. Knepley *prob = NULL; 5268e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5269e5e52638SMatthew G. Knepley PetscInt val; 5270e5e52638SMatthew G. Knepley 5271e5e52638SMatthew G. Knepley if (!dm->probs[s].label) {probDef = dm->probs[s].ds;} 5272e5e52638SMatthew G. Knepley else { 5273e5e52638SMatthew G. Knepley ierr = DMLabelGetValue(dm->probs[s].label, point, &val);CHKERRQ(ierr); 5274e5e52638SMatthew G. Knepley if (val >= 0) {*prob = dm->probs[s].ds; break;} 5275e5e52638SMatthew G. Knepley } 5276e5e52638SMatthew G. Knepley } 5277e5e52638SMatthew G. Knepley if (!*prob) *prob = probDef; 5278e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5279e5e52638SMatthew G. Knepley } 5280e5e52638SMatthew G. Knepley 5281e5e52638SMatthew G. Knepley /*@ 5282e5e52638SMatthew G. Knepley DMGetRegionDS - Get the PetscDS for a given mesh region, defined by a DMLabel 5283e5e52638SMatthew G. Knepley 5284e5e52638SMatthew G. Knepley Not collective 5285e5e52638SMatthew G. Knepley 5286e5e52638SMatthew G. Knepley Input Parameters: 5287e5e52638SMatthew G. Knepley + dm - The DM 5288e5e52638SMatthew G. Knepley - label - The DMLabel defining the mesh region, or NULL for the entire mesh 5289e5e52638SMatthew G. Knepley 5290b3cf3223SMatthew G. Knepley Output Parameters: 5291b3cf3223SMatthew G. Knepley + fields - The IS containing the DM field numbers for the fields in this DS, or NULL 5292b3cf3223SMatthew G. Knepley - prob - The PetscDS defined on the given region, or NULL 5293e5e52638SMatthew G. Knepley 5294e5e52638SMatthew G. Knepley Note: If the label is missing, this function returns an error 5295e5e52638SMatthew G. Knepley 5296e5e52638SMatthew G. Knepley Level: advanced 5297e5e52638SMatthew G. Knepley 5298e5e52638SMatthew G. Knepley .seealso: DMGetRegionNumDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS() 5299e5e52638SMatthew G. Knepley @*/ 5300b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionDS(DM dm, DMLabel label, IS *fields, PetscDS *ds) 5301e5e52638SMatthew G. Knepley { 5302e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5303e5e52638SMatthew G. Knepley 5304e5e52638SMatthew G. Knepley PetscFunctionBegin; 5305e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5306e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5307b3cf3223SMatthew G. Knepley if (fields) {PetscValidPointer(fields, 3); *fields = NULL;} 5308b3cf3223SMatthew G. Knepley if (ds) {PetscValidPointer(ds, 4); *ds = NULL;} 5309e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5310b3cf3223SMatthew G. Knepley if (dm->probs[s].label == label) { 5311b3cf3223SMatthew G. Knepley if (fields) *fields = dm->probs[s].fields; 5312b3cf3223SMatthew G. Knepley if (ds) *ds = dm->probs[s].ds; 5313b3cf3223SMatthew G. Knepley PetscFunctionReturn(0); 5314b3cf3223SMatthew G. Knepley } 5315e5e52638SMatthew G. Knepley } 53162df9ee95SMatthew G. Knepley PetscFunctionReturn(0); 5317e5e52638SMatthew G. Knepley } 5318e5e52638SMatthew G. Knepley 5319e5e52638SMatthew G. Knepley /*@ 5320083401c6SMatthew G. Knepley DMSetRegionDS - Set the PetscDS for a given mesh region, defined by a DMLabel 5321083401c6SMatthew G. Knepley 5322083401c6SMatthew G. Knepley Collective on dm 5323083401c6SMatthew G. Knepley 5324083401c6SMatthew G. Knepley Input Parameters: 5325083401c6SMatthew G. Knepley + dm - The DM 5326083401c6SMatthew G. Knepley . label - The DMLabel defining the mesh region, or NULL for the entire mesh 5327083401c6SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL for all fields 5328083401c6SMatthew G. Knepley - prob - The PetscDS defined on the given cell 5329083401c6SMatthew G. Knepley 5330083401c6SMatthew 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, 5331083401c6SMatthew G. Knepley the fields argument is ignored. 5332083401c6SMatthew G. Knepley 5333083401c6SMatthew G. Knepley Level: advanced 5334083401c6SMatthew G. Knepley 5335083401c6SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionNumDS(), DMGetDS(), DMGetCellDS() 5336083401c6SMatthew G. Knepley @*/ 5337083401c6SMatthew G. Knepley PetscErrorCode DMSetRegionDS(DM dm, DMLabel label, IS fields, PetscDS ds) 5338083401c6SMatthew G. Knepley { 5339083401c6SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5340083401c6SMatthew G. Knepley PetscErrorCode ierr; 5341083401c6SMatthew G. Knepley 5342083401c6SMatthew G. Knepley PetscFunctionBegin; 5343083401c6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5344083401c6SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5345083401c6SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 3); 5346083401c6SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5347083401c6SMatthew G. Knepley if (dm->probs[s].label == label) { 5348083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr); 5349083401c6SMatthew G. Knepley dm->probs[s].ds = ds; 5350083401c6SMatthew G. Knepley PetscFunctionReturn(0); 5351083401c6SMatthew G. Knepley } 5352083401c6SMatthew G. Knepley } 5353083401c6SMatthew G. Knepley ierr = DMDSEnlarge_Static(dm, Nds+1);CHKERRQ(ierr); 5354083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 5355083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) fields);CHKERRQ(ierr); 5356083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) ds);CHKERRQ(ierr); 5357083401c6SMatthew G. Knepley if (!label) { 5358083401c6SMatthew G. Knepley /* Put the NULL label at the front, so it is returned as the default */ 5359083401c6SMatthew G. Knepley for (s = Nds-1; s >=0; --s) dm->probs[s+1] = dm->probs[s]; 5360083401c6SMatthew G. Knepley Nds = 0; 5361083401c6SMatthew G. Knepley } 5362083401c6SMatthew G. Knepley dm->probs[Nds].label = label; 5363083401c6SMatthew G. Knepley dm->probs[Nds].fields = fields; 5364083401c6SMatthew G. Knepley dm->probs[Nds].ds = ds; 5365083401c6SMatthew G. Knepley PetscFunctionReturn(0); 5366083401c6SMatthew G. Knepley } 5367083401c6SMatthew G. Knepley 5368083401c6SMatthew G. Knepley /*@ 5369e5e52638SMatthew G. Knepley DMGetRegionNumDS - Get the PetscDS for a given mesh region, defined by the region number 5370e5e52638SMatthew G. Knepley 5371e5e52638SMatthew G. Knepley Not collective 5372e5e52638SMatthew G. Knepley 5373e5e52638SMatthew G. Knepley Input Parameters: 5374e5e52638SMatthew G. Knepley + dm - The DM 5375e5e52638SMatthew G. Knepley - num - The region number, in [0, Nds) 5376e5e52638SMatthew G. Knepley 5377e5e52638SMatthew G. Knepley Output Parameters: 5378b3cf3223SMatthew G. Knepley + label - The region label, or NULL 5379b3cf3223SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL 5380083401c6SMatthew G. Knepley - ds - The PetscDS defined on the given region, or NULL 5381e5e52638SMatthew G. Knepley 5382e5e52638SMatthew G. Knepley Level: advanced 5383e5e52638SMatthew G. Knepley 5384e5e52638SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS() 5385e5e52638SMatthew G. Knepley @*/ 5386b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionNumDS(DM dm, PetscInt num, DMLabel *label, IS *fields, PetscDS *ds) 5387e5e52638SMatthew G. Knepley { 5388e5e52638SMatthew G. Knepley PetscInt Nds; 5389e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5390e5e52638SMatthew G. Knepley 5391e5e52638SMatthew G. Knepley PetscFunctionBegin; 5392e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5393e5e52638SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 5394e5e52638SMatthew 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); 5395e5e52638SMatthew G. Knepley if (label) { 5396e5e52638SMatthew G. Knepley PetscValidPointer(label, 3); 5397e5e52638SMatthew G. Knepley *label = dm->probs[num].label; 5398e5e52638SMatthew G. Knepley } 5399b3cf3223SMatthew G. Knepley if (fields) { 5400b3cf3223SMatthew G. Knepley PetscValidPointer(fields, 4); 5401b3cf3223SMatthew G. Knepley *fields = dm->probs[num].fields; 5402b3cf3223SMatthew G. Knepley } 5403e5e52638SMatthew G. Knepley if (ds) { 5404b3cf3223SMatthew G. Knepley PetscValidPointer(ds, 5); 5405e5e52638SMatthew G. Knepley *ds = dm->probs[num].ds; 5406e5e52638SMatthew G. Knepley } 5407e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5408e5e52638SMatthew G. Knepley } 5409e5e52638SMatthew G. Knepley 5410e5e52638SMatthew G. Knepley /*@ 5411083401c6SMatthew G. Knepley DMSetRegionNumDS - Set the PetscDS for a given mesh region, defined by the region number 5412e5e52638SMatthew G. Knepley 5413083401c6SMatthew G. Knepley Not collective 5414e5e52638SMatthew G. Knepley 5415e5e52638SMatthew G. Knepley Input Parameters: 5416e5e52638SMatthew G. Knepley + dm - The DM 5417083401c6SMatthew G. Knepley . num - The region number, in [0, Nds) 5418083401c6SMatthew G. Knepley . label - The region label, or NULL 5419083401c6SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL to prevent setting 5420083401c6SMatthew G. Knepley - ds - The PetscDS defined on the given region, or NULL to prevent setting 5421e5e52638SMatthew G. Knepley 5422e5e52638SMatthew G. Knepley Level: advanced 5423e5e52638SMatthew G. Knepley 5424083401c6SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS() 5425e5e52638SMatthew G. Knepley @*/ 5426083401c6SMatthew G. Knepley PetscErrorCode DMSetRegionNumDS(DM dm, PetscInt num, DMLabel label, IS fields, PetscDS ds) 5427e5e52638SMatthew G. Knepley { 5428083401c6SMatthew G. Knepley PetscInt Nds; 5429e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5430e5e52638SMatthew G. Knepley 5431e5e52638SMatthew G. Knepley PetscFunctionBegin; 5432e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5433083401c6SMatthew G. Knepley if (label) {PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3);} 5434083401c6SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 5435083401c6SMatthew 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); 5436e5e52638SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 5437083401c6SMatthew G. Knepley ierr = DMLabelDestroy(&dm->probs[num].label);CHKERRQ(ierr); 5438083401c6SMatthew G. Knepley dm->probs[num].label = label; 5439083401c6SMatthew G. Knepley if (fields) { 5440083401c6SMatthew G. Knepley PetscValidHeaderSpecific(fields, IS_CLASSID, 4); 5441b3cf3223SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) fields);CHKERRQ(ierr); 5442083401c6SMatthew G. Knepley ierr = ISDestroy(&dm->probs[num].fields);CHKERRQ(ierr); 5443083401c6SMatthew G. Knepley dm->probs[num].fields = fields; 5444e5e52638SMatthew G. Knepley } 5445083401c6SMatthew G. Knepley if (ds) { 5446083401c6SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 5); 5447083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) ds);CHKERRQ(ierr); 5448083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&dm->probs[num].ds);CHKERRQ(ierr); 5449083401c6SMatthew G. Knepley dm->probs[num].ds = ds; 5450083401c6SMatthew G. Knepley } 5451e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5452e5e52638SMatthew G. Knepley } 5453e5e52638SMatthew G. Knepley 5454e5e52638SMatthew G. Knepley /*@ 54551d3af9e0SMatthew G. Knepley DMFindRegionNum - Find the region number for a given PetscDS, or -1 if it is not found. 54561d3af9e0SMatthew G. Knepley 54571d3af9e0SMatthew G. Knepley Not collective 54581d3af9e0SMatthew G. Knepley 54591d3af9e0SMatthew G. Knepley Input Parameters: 54601d3af9e0SMatthew G. Knepley + dm - The DM 54611d3af9e0SMatthew G. Knepley - ds - The PetscDS defined on the given region 54621d3af9e0SMatthew G. Knepley 54631d3af9e0SMatthew G. Knepley Output Parameter: 54641d3af9e0SMatthew G. Knepley . num - The region number, in [0, Nds), or -1 if not found 54651d3af9e0SMatthew G. Knepley 54661d3af9e0SMatthew G. Knepley Level: advanced 54671d3af9e0SMatthew G. Knepley 54681d3af9e0SMatthew G. Knepley .seealso: DMGetRegionNumDS(), DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS() 54691d3af9e0SMatthew G. Knepley @*/ 54701d3af9e0SMatthew G. Knepley PetscErrorCode DMFindRegionNum(DM dm, PetscDS ds, PetscInt *num) 54711d3af9e0SMatthew G. Knepley { 54721d3af9e0SMatthew G. Knepley PetscInt Nds, n; 54731d3af9e0SMatthew G. Knepley PetscErrorCode ierr; 54741d3af9e0SMatthew G. Knepley 54751d3af9e0SMatthew G. Knepley PetscFunctionBegin; 54761d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 54771d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 2); 54781d3af9e0SMatthew G. Knepley PetscValidPointer(num, 3); 54791d3af9e0SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 54801d3af9e0SMatthew G. Knepley for (n = 0; n < Nds; ++n) if (ds == dm->probs[n].ds) break; 54811d3af9e0SMatthew G. Knepley if (n >= Nds) *num = -1; 54821d3af9e0SMatthew G. Knepley else *num = n; 54831d3af9e0SMatthew G. Knepley PetscFunctionReturn(0); 54841d3af9e0SMatthew G. Knepley } 54851d3af9e0SMatthew G. Knepley 54861d3af9e0SMatthew G. Knepley /*@ 5487e5e52638SMatthew G. Knepley DMCreateDS - Create the discrete systems for the DM based upon the fields added to the DM 5488e5e52638SMatthew G. Knepley 5489d083f849SBarry Smith Collective on dm 5490e5e52638SMatthew G. Knepley 5491e5e52638SMatthew G. Knepley Input Parameter: 5492e5e52638SMatthew G. Knepley . dm - The DM 5493e5e52638SMatthew G. Knepley 5494*45480ffeSMatthew G. Knepley Options Database Keys: 5495*45480ffeSMatthew G. Knepley . -dm_petscds_view - View all the PetscDS objects in this DM 5496*45480ffeSMatthew G. Knepley 5497e5e52638SMatthew G. Knepley Note: If the label has a DS defined, it will be replaced. Otherwise, it will be added to the DM. 5498e5e52638SMatthew G. Knepley 5499e5e52638SMatthew G. Knepley Level: intermediate 5500e5e52638SMatthew G. Knepley 5501e5e52638SMatthew G. Knepley .seealso: DMSetField, DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS() 5502e5e52638SMatthew G. Knepley @*/ 5503e5e52638SMatthew G. Knepley PetscErrorCode DMCreateDS(DM dm) 5504e5e52638SMatthew G. Knepley { 5505e5e52638SMatthew G. Knepley MPI_Comm comm; 5506083401c6SMatthew G. Knepley PetscDS dsDef; 5507083401c6SMatthew G. Knepley DMLabel *labelSet; 5508f9244615SMatthew G. Knepley PetscInt dE, Nf = dm->Nf, f, s, Nl, l, Ndef, k; 5509f9244615SMatthew G. Knepley PetscBool doSetup = PETSC_TRUE, flg; 5510e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5511e5e52638SMatthew G. Knepley 5512e5e52638SMatthew G. Knepley PetscFunctionBegin; 5513e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5514e5e52638SMatthew G. Knepley if (!dm->fields) PetscFunctionReturn(0); 5515e5e52638SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 5516083401c6SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 5517083401c6SMatthew G. Knepley /* Determine how many regions we have */ 5518083401c6SMatthew G. Knepley ierr = PetscMalloc1(Nf, &labelSet);CHKERRQ(ierr); 5519083401c6SMatthew G. Knepley Nl = 0; 5520083401c6SMatthew G. Knepley Ndef = 0; 5521083401c6SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5522083401c6SMatthew G. Knepley DMLabel label = dm->fields[f].label; 5523083401c6SMatthew G. Knepley PetscInt l; 5524083401c6SMatthew G. Knepley 5525083401c6SMatthew G. Knepley if (!label) {++Ndef; continue;} 5526083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) if (label == labelSet[l]) break; 5527083401c6SMatthew G. Knepley if (l < Nl) continue; 5528083401c6SMatthew G. Knepley labelSet[Nl++] = label; 5529083401c6SMatthew G. Knepley } 5530083401c6SMatthew G. Knepley /* Create default DS if there are no labels to intersect with */ 5531083401c6SMatthew G. Knepley ierr = DMGetRegionDS(dm, NULL, NULL, &dsDef);CHKERRQ(ierr); 5532083401c6SMatthew G. Knepley if (!dsDef && Ndef && !Nl) { 5533b3cf3223SMatthew G. Knepley IS fields; 5534b3cf3223SMatthew G. Knepley PetscInt *fld, nf; 5535b3cf3223SMatthew G. Knepley 5536b3cf3223SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) ++nf; 5537083401c6SMatthew G. Knepley if (nf) { 5538b3cf3223SMatthew G. Knepley ierr = PetscMalloc1(nf, &fld);CHKERRQ(ierr); 5539b3cf3223SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) fld[nf++] = f; 554088f0c812SMatthew G. Knepley ierr = ISCreate(PETSC_COMM_SELF, &fields);CHKERRQ(ierr); 554188f0c812SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_");CHKERRQ(ierr); 554288f0c812SMatthew G. Knepley ierr = ISSetType(fields, ISGENERAL);CHKERRQ(ierr); 554388f0c812SMatthew G. Knepley ierr = ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER);CHKERRQ(ierr); 554488f0c812SMatthew G. Knepley 5545*45480ffeSMatthew G. Knepley ierr = PetscDSCreate(PETSC_COMM_SELF, &dsDef);CHKERRQ(ierr); 5546083401c6SMatthew G. Knepley ierr = DMSetRegionDS(dm, NULL, fields, dsDef);CHKERRQ(ierr); 5547083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&dsDef);CHKERRQ(ierr); 5548b3cf3223SMatthew G. Knepley ierr = ISDestroy(&fields);CHKERRQ(ierr); 55492df9ee95SMatthew G. Knepley } 5550083401c6SMatthew G. Knepley } 5551083401c6SMatthew G. Knepley ierr = DMGetRegionDS(dm, NULL, NULL, &dsDef);CHKERRQ(ierr); 5552083401c6SMatthew G. Knepley if (dsDef) {ierr = PetscDSSetCoordinateDimension(dsDef, dE);CHKERRQ(ierr);} 5553083401c6SMatthew G. Knepley /* Intersect labels with default fields */ 5554083401c6SMatthew G. Knepley if (Ndef && Nl) { 55550122748bSMatthew G. Knepley DM plex; 5556083401c6SMatthew G. Knepley DMLabel cellLabel; 5557083401c6SMatthew G. Knepley IS fieldIS, allcellIS, defcellIS = NULL; 5558083401c6SMatthew G. Knepley PetscInt *fields; 5559083401c6SMatthew G. Knepley const PetscInt *cells; 5560083401c6SMatthew G. Knepley PetscInt depth, nf = 0, n, c; 55610122748bSMatthew G. Knepley 55620122748bSMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 55630122748bSMatthew G. Knepley ierr = DMPlexGetDepth(plex, &depth);CHKERRQ(ierr); 5564083401c6SMatthew G. Knepley ierr = DMGetStratumIS(plex, "dim", depth, &allcellIS);CHKERRQ(ierr); 5565083401c6SMatthew G. Knepley if (!allcellIS) {ierr = DMGetStratumIS(plex, "depth", depth, &allcellIS);CHKERRQ(ierr);} 5566083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5567083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5568083401c6SMatthew G. Knepley IS pointIS; 5569083401c6SMatthew G. Knepley 5570083401c6SMatthew G. Knepley ierr = ISDestroy(&defcellIS);CHKERRQ(ierr); 5571083401c6SMatthew G. Knepley ierr = DMLabelGetStratumIS(label, 1, &pointIS);CHKERRQ(ierr); 5572083401c6SMatthew G. Knepley ierr = ISDifference(allcellIS, pointIS, &defcellIS);CHKERRQ(ierr); 5573083401c6SMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 5574083401c6SMatthew G. Knepley } 5575083401c6SMatthew G. Knepley ierr = ISDestroy(&allcellIS);CHKERRQ(ierr); 5576083401c6SMatthew G. Knepley 5577083401c6SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, "defaultCells", &cellLabel);CHKERRQ(ierr); 5578083401c6SMatthew G. Knepley ierr = ISGetLocalSize(defcellIS, &n);CHKERRQ(ierr); 5579083401c6SMatthew G. Knepley ierr = ISGetIndices(defcellIS, &cells);CHKERRQ(ierr); 5580083401c6SMatthew G. Knepley for (c = 0; c < n; ++c) {ierr = DMLabelSetValue(cellLabel, cells[c], 1);CHKERRQ(ierr);} 5581083401c6SMatthew G. Knepley ierr = ISRestoreIndices(defcellIS, &cells);CHKERRQ(ierr); 5582083401c6SMatthew G. Knepley ierr = ISDestroy(&defcellIS);CHKERRQ(ierr); 5583083401c6SMatthew G. Knepley ierr = DMPlexLabelComplete(plex, cellLabel);CHKERRQ(ierr); 5584083401c6SMatthew G. Knepley 5585083401c6SMatthew G. Knepley ierr = PetscMalloc1(Ndef, &fields);CHKERRQ(ierr); 5586083401c6SMatthew G. Knepley for (f = 0; f < Nf; ++f) if (!dm->fields[f].label) fields[nf++] = f; 5587083401c6SMatthew G. Knepley ierr = ISCreate(PETSC_COMM_SELF, &fieldIS);CHKERRQ(ierr); 5588083401c6SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) fieldIS, "dm_fields_");CHKERRQ(ierr); 5589083401c6SMatthew G. Knepley ierr = ISSetType(fieldIS, ISGENERAL);CHKERRQ(ierr); 5590083401c6SMatthew G. Knepley ierr = ISGeneralSetIndices(fieldIS, nf, fields, PETSC_OWN_POINTER);CHKERRQ(ierr); 5591083401c6SMatthew G. Knepley 5592*45480ffeSMatthew G. Knepley ierr = PetscDSCreate(PETSC_COMM_SELF, &dsDef);CHKERRQ(ierr); 5593083401c6SMatthew G. Knepley ierr = DMSetRegionDS(dm, cellLabel, fieldIS, dsDef);CHKERRQ(ierr); 5594083401c6SMatthew G. Knepley ierr = DMLabelDestroy(&cellLabel);CHKERRQ(ierr); 5595083401c6SMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(dsDef, dE);CHKERRQ(ierr); 5596083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&dsDef);CHKERRQ(ierr); 5597083401c6SMatthew G. Knepley ierr = ISDestroy(&fieldIS);CHKERRQ(ierr); 55980122748bSMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 5599083401c6SMatthew G. Knepley } 5600083401c6SMatthew G. Knepley /* Create label DSes 5601083401c6SMatthew G. Knepley - WE ONLY SUPPORT IDENTICAL OR DISJOINT LABELS 5602083401c6SMatthew G. Knepley */ 5603083401c6SMatthew G. Knepley /* TODO Should check that labels are disjoint */ 5604083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5605083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5606083401c6SMatthew G. Knepley PetscDS ds; 5607083401c6SMatthew G. Knepley IS fields; 5608083401c6SMatthew G. Knepley PetscInt *fld, nf; 5609083401c6SMatthew G. Knepley 5610*45480ffeSMatthew G. Knepley ierr = PetscDSCreate(PETSC_COMM_SELF, &ds);CHKERRQ(ierr); 5611083401c6SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (label == dm->fields[f].label || !dm->fields[f].label) ++nf; 5612083401c6SMatthew G. Knepley ierr = PetscMalloc1(nf, &fld);CHKERRQ(ierr); 5613083401c6SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (label == dm->fields[f].label || !dm->fields[f].label) fld[nf++] = f; 5614083401c6SMatthew G. Knepley ierr = ISCreate(PETSC_COMM_SELF, &fields);CHKERRQ(ierr); 5615083401c6SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_");CHKERRQ(ierr); 5616083401c6SMatthew G. Knepley ierr = ISSetType(fields, ISGENERAL);CHKERRQ(ierr); 5617083401c6SMatthew G. Knepley ierr = ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER);CHKERRQ(ierr); 5618083401c6SMatthew G. Knepley ierr = DMSetRegionDS(dm, label, fields, ds);CHKERRQ(ierr); 5619083401c6SMatthew G. Knepley ierr = ISDestroy(&fields);CHKERRQ(ierr); 5620083401c6SMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(ds, dE);CHKERRQ(ierr); 5621083401c6SMatthew G. Knepley { 5622083401c6SMatthew G. Knepley DMPolytopeType ct; 5623083401c6SMatthew G. Knepley PetscInt lStart, lEnd; 5624083401c6SMatthew G. Knepley PetscBool isHybridLocal = PETSC_FALSE, isHybrid; 56250122748bSMatthew G. Knepley 5626e5e52638SMatthew G. Knepley ierr = DMLabelGetBounds(label, &lStart, &lEnd);CHKERRQ(ierr); 5627665f567fSMatthew G. Knepley if (lStart >= 0) { 5628412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, lStart, &ct);CHKERRQ(ierr); 5629412e9a14SMatthew G. Knepley switch (ct) { 5630412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 5631412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 5632412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 5633412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 5634083401c6SMatthew G. Knepley isHybridLocal = PETSC_TRUE;break; 5635083401c6SMatthew G. Knepley default: break; 5636412e9a14SMatthew G. Knepley } 5637665f567fSMatthew G. Knepley } 5638ffc4695bSBarry Smith ierr = MPI_Allreduce(&isHybridLocal, &isHybrid, 1, MPIU_BOOL, MPI_LOR, comm);CHKERRMPI(ierr); 5639083401c6SMatthew G. Knepley ierr = PetscDSSetHybrid(ds, isHybrid);CHKERRQ(ierr); 5640e5e52638SMatthew G. Knepley } 5641083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&ds);CHKERRQ(ierr); 5642e5e52638SMatthew G. Knepley } 5643083401c6SMatthew G. Knepley ierr = PetscFree(labelSet);CHKERRQ(ierr); 5644e5e52638SMatthew G. Knepley /* Set fields in DSes */ 5645083401c6SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5646083401c6SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 5647083401c6SMatthew G. Knepley IS fields = dm->probs[s].fields; 5648083401c6SMatthew G. Knepley const PetscInt *fld; 5649083401c6SMatthew G. Knepley PetscInt nf; 5650e5e52638SMatthew G. Knepley 5651083401c6SMatthew G. Knepley ierr = ISGetLocalSize(fields, &nf);CHKERRQ(ierr); 5652083401c6SMatthew G. Knepley ierr = ISGetIndices(fields, &fld);CHKERRQ(ierr); 5653083401c6SMatthew G. Knepley for (f = 0; f < nf; ++f) { 5654083401c6SMatthew G. Knepley PetscObject disc = dm->fields[fld[f]].disc; 5655083401c6SMatthew G. Knepley PetscBool isHybrid; 5656e5e52638SMatthew G. Knepley PetscClassId id; 5657e5e52638SMatthew G. Knepley 5658083401c6SMatthew G. Knepley ierr = PetscDSGetHybrid(ds, &isHybrid);CHKERRQ(ierr); 5659083401c6SMatthew G. Knepley /* If this is a cohesive cell, then it needs the lower dimensional discretization */ 5660083401c6SMatthew G. Knepley if (isHybrid && f < nf-1) {ierr = PetscFEGetHeightSubspace((PetscFE) disc, 1, (PetscFE *) &disc);CHKERRQ(ierr);} 5661083401c6SMatthew G. Knepley ierr = PetscDSSetDiscretization(ds, f, disc);CHKERRQ(ierr); 5662083401c6SMatthew G. Knepley /* We allow people to have placeholder fields and construct the Section by hand */ 5663e5e52638SMatthew G. Knepley ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr); 5664e5e52638SMatthew G. Knepley if ((id != PETSCFE_CLASSID) && (id != PETSCFV_CLASSID)) doSetup = PETSC_FALSE; 5665e5e52638SMatthew G. Knepley } 5666083401c6SMatthew G. Knepley ierr = ISRestoreIndices(fields, &fld);CHKERRQ(ierr); 5667e5e52638SMatthew G. Knepley } 5668f9244615SMatthew G. Knepley /* Allow k-jet tabulation */ 5669f9244615SMatthew G. Knepley ierr = PetscOptionsGetInt(NULL, ((PetscObject) dm)->prefix, "-dm_ds_jet_degree", &k, &flg);CHKERRQ(ierr); 5670f9244615SMatthew G. Knepley if (flg) { 5671f9244615SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) {ierr = PetscDSSetJetDegree(dm->probs[s].ds, 0, k);CHKERRQ(ierr);} 5672f9244615SMatthew G. Knepley } 5673e5e52638SMatthew G. Knepley /* Setup DSes */ 5674e5e52638SMatthew G. Knepley if (doSetup) { 5675e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) {ierr = PetscDSSetUp(dm->probs[s].ds);CHKERRQ(ierr);} 5676e5e52638SMatthew G. Knepley } 5677e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5678e5e52638SMatthew G. Knepley } 5679e5e52638SMatthew G. Knepley 5680e5e52638SMatthew G. Knepley /*@ 56817f96f943SMatthew G. Knepley DMComputeExactSolution - Compute the exact solution for a given DM, using the PetscDS information. 56827f96f943SMatthew G. Knepley 5683f2cacb80SMatthew G. Knepley Collective on DM 5684f2cacb80SMatthew G. Knepley 56857f96f943SMatthew G. Knepley Input Parameters: 56867f96f943SMatthew G. Knepley + dm - The DM 56877f96f943SMatthew G. Knepley - time - The time 56887f96f943SMatthew G. Knepley 56897f96f943SMatthew G. Knepley Output Parameters: 5690f2cacb80SMatthew G. Knepley + u - The vector will be filled with exact solution values, or NULL 5691f2cacb80SMatthew G. Knepley - u_t - The vector will be filled with the time derivative of exact solution values, or NULL 56927f96f943SMatthew G. Knepley 56937f96f943SMatthew G. Knepley Note: The user must call PetscDSSetExactSolution() beforehand 56947f96f943SMatthew G. Knepley 56957f96f943SMatthew G. Knepley Level: developer 56967f96f943SMatthew G. Knepley 56977f96f943SMatthew G. Knepley .seealso: PetscDSSetExactSolution() 56987f96f943SMatthew G. Knepley @*/ 5699f2cacb80SMatthew G. Knepley PetscErrorCode DMComputeExactSolution(DM dm, PetscReal time, Vec u, Vec u_t) 57007f96f943SMatthew G. Knepley { 57017f96f943SMatthew G. Knepley PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx); 57027f96f943SMatthew G. Knepley void **ectxs; 57037f96f943SMatthew G. Knepley PetscInt Nf, Nds, s; 57047f96f943SMatthew G. Knepley PetscErrorCode ierr; 57057f96f943SMatthew G. Knepley 57067f96f943SMatthew G. Knepley PetscFunctionBegin; 5707f2cacb80SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5708f2cacb80SMatthew G. Knepley if (u) PetscValidHeaderSpecific(u, VEC_CLASSID, 3); 5709f2cacb80SMatthew G. Knepley if (u_t) PetscValidHeaderSpecific(u_t, VEC_CLASSID, 4); 57107f96f943SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 57117f96f943SMatthew G. Knepley ierr = PetscMalloc2(Nf, &exacts, Nf, &ectxs);CHKERRQ(ierr); 57127f96f943SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 57137f96f943SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 57147f96f943SMatthew G. Knepley PetscDS ds; 57157f96f943SMatthew G. Knepley DMLabel label; 57167f96f943SMatthew G. Knepley IS fieldIS; 57177f96f943SMatthew G. Knepley const PetscInt *fields, id = 1; 57187f96f943SMatthew G. Knepley PetscInt dsNf, f; 57197f96f943SMatthew G. Knepley 57207f96f943SMatthew G. Knepley ierr = DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds);CHKERRQ(ierr); 57217f96f943SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &dsNf);CHKERRQ(ierr); 57227f96f943SMatthew G. Knepley ierr = ISGetIndices(fieldIS, &fields);CHKERRQ(ierr); 57237f96f943SMatthew G. Knepley ierr = PetscArrayzero(exacts, Nf);CHKERRQ(ierr); 57247f96f943SMatthew G. Knepley ierr = PetscArrayzero(ectxs, Nf);CHKERRQ(ierr); 5725f2cacb80SMatthew G. Knepley if (u) { 57267f96f943SMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 57277f96f943SMatthew G. Knepley const PetscInt field = fields[f]; 57287f96f943SMatthew G. Knepley ierr = PetscDSGetExactSolution(ds, field, &exacts[field], &ectxs[field]);CHKERRQ(ierr); 57297f96f943SMatthew G. Knepley } 57307f96f943SMatthew G. Knepley ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr); 57317f96f943SMatthew G. Knepley if (label) { 57327f96f943SMatthew G. Knepley ierr = DMProjectFunctionLabel(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, u);CHKERRQ(ierr); 57337f96f943SMatthew G. Knepley } else { 57347f96f943SMatthew G. Knepley ierr = DMProjectFunction(dm, time, exacts, ectxs, INSERT_ALL_VALUES, u);CHKERRQ(ierr); 57357f96f943SMatthew G. Knepley } 57367f96f943SMatthew G. Knepley } 5737f2cacb80SMatthew G. Knepley if (u_t) { 5738f2cacb80SMatthew G. Knepley ierr = PetscArrayzero(exacts, Nf);CHKERRQ(ierr); 5739f2cacb80SMatthew G. Knepley ierr = PetscArrayzero(ectxs, Nf);CHKERRQ(ierr); 5740f2cacb80SMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 5741f2cacb80SMatthew G. Knepley const PetscInt field = fields[f]; 5742f2cacb80SMatthew G. Knepley ierr = PetscDSGetExactSolutionTimeDerivative(ds, field, &exacts[field], &ectxs[field]);CHKERRQ(ierr); 5743f2cacb80SMatthew G. Knepley } 5744f2cacb80SMatthew G. Knepley ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr); 5745f2cacb80SMatthew G. Knepley if (label) { 5746f2cacb80SMatthew G. Knepley ierr = DMProjectFunctionLabel(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, u_t);CHKERRQ(ierr); 5747f2cacb80SMatthew G. Knepley } else { 5748f2cacb80SMatthew G. Knepley ierr = DMProjectFunction(dm, time, exacts, ectxs, INSERT_ALL_VALUES, u_t);CHKERRQ(ierr); 5749f2cacb80SMatthew G. Knepley } 5750f2cacb80SMatthew G. Knepley } 5751f2cacb80SMatthew G. Knepley } 5752f2cacb80SMatthew G. Knepley if (u) { 57537f96f943SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) u, "Exact Solution");CHKERRQ(ierr); 57547f96f943SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) u, "exact_");CHKERRQ(ierr); 5755f2cacb80SMatthew G. Knepley } 5756f2cacb80SMatthew G. Knepley if (u_t) { 5757f2cacb80SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) u, "Exact Solution Time Derivative");CHKERRQ(ierr); 5758f2cacb80SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) u_t, "exact_t_");CHKERRQ(ierr); 5759f2cacb80SMatthew G. Knepley } 57607f96f943SMatthew G. Knepley ierr = PetscFree2(exacts, ectxs);CHKERRQ(ierr); 57617f96f943SMatthew G. Knepley PetscFunctionReturn(0); 57627f96f943SMatthew G. Knepley } 57637f96f943SMatthew G. Knepley 5764*45480ffeSMatthew G. Knepley PetscErrorCode DMTransferDS_Internal(DM dm, DMLabel label, IS fields, PetscDS ds) 5765*45480ffeSMatthew G. Knepley { 5766*45480ffeSMatthew G. Knepley PetscDS dsNew; 5767*45480ffeSMatthew G. Knepley DSBoundary b; 5768*45480ffeSMatthew G. Knepley PetscInt cdim, Nf, f; 5769*45480ffeSMatthew G. Knepley void *ctx; 5770*45480ffeSMatthew G. Knepley PetscErrorCode ierr; 5771*45480ffeSMatthew G. Knepley 5772*45480ffeSMatthew G. Knepley PetscFunctionBegin; 5773*45480ffeSMatthew G. Knepley ierr = PetscDSCreate(PetscObjectComm((PetscObject) ds), &dsNew);CHKERRQ(ierr); 5774*45480ffeSMatthew G. Knepley ierr = PetscDSCopyConstants(ds, dsNew);CHKERRQ(ierr); 5775*45480ffeSMatthew G. Knepley ierr = PetscDSCopyExactSolutions(ds, dsNew);CHKERRQ(ierr); 5776*45480ffeSMatthew G. Knepley ierr = PetscDSSelectDiscretizations(ds, PETSC_DETERMINE, NULL, dsNew);CHKERRQ(ierr); 5777*45480ffeSMatthew G. Knepley ierr = PetscDSCopyEquations(ds, dsNew);CHKERRQ(ierr); 5778*45480ffeSMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 5779*45480ffeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5780*45480ffeSMatthew G. Knepley ierr = PetscDSGetContext(ds, f, &ctx);CHKERRQ(ierr); 5781*45480ffeSMatthew G. Knepley ierr = PetscDSSetContext(dsNew, f, ctx);CHKERRQ(ierr); 5782*45480ffeSMatthew G. Knepley } 5783*45480ffeSMatthew G. Knepley if (Nf) { 5784*45480ffeSMatthew G. Knepley ierr = PetscDSGetCoordinateDimension(ds, &cdim);CHKERRQ(ierr); 5785*45480ffeSMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(dsNew, cdim);CHKERRQ(ierr); 5786*45480ffeSMatthew G. Knepley } 5787*45480ffeSMatthew G. Knepley ierr = PetscDSCopyBoundary(ds, PETSC_DETERMINE, NULL, dsNew);CHKERRQ(ierr); 5788*45480ffeSMatthew G. Knepley for (b = dsNew->boundary; b; b = b->next) { 5789*45480ffeSMatthew G. Knepley ierr = DMGetLabel(dm, b->lname, &b->label);CHKERRQ(ierr); 5790*45480ffeSMatthew G. Knepley /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */ 5791*45480ffeSMatthew G. Knepley //if (!b->label) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Label %s missing in new DM", name); 5792*45480ffeSMatthew G. Knepley } 5793*45480ffeSMatthew G. Knepley 5794*45480ffeSMatthew G. Knepley ierr = DMSetRegionDS(dm, label, fields, dsNew);CHKERRQ(ierr); 5795*45480ffeSMatthew G. Knepley ierr = PetscDSDestroy(&dsNew);CHKERRQ(ierr); 5796*45480ffeSMatthew G. Knepley PetscFunctionReturn(0); 5797*45480ffeSMatthew G. Knepley } 5798*45480ffeSMatthew G. Knepley 57997f96f943SMatthew G. Knepley /*@ 5800e5e52638SMatthew G. Knepley DMCopyDS - Copy the discrete systems for the DM into another DM 5801e5e52638SMatthew G. Knepley 5802d083f849SBarry Smith Collective on dm 5803e5e52638SMatthew G. Knepley 5804e5e52638SMatthew G. Knepley Input Parameter: 5805e5e52638SMatthew G. Knepley . dm - The DM 5806e5e52638SMatthew G. Knepley 5807e5e52638SMatthew G. Knepley Output Parameter: 5808e5e52638SMatthew G. Knepley . newdm - The DM 5809e5e52638SMatthew G. Knepley 5810e5e52638SMatthew G. Knepley Level: advanced 5811e5e52638SMatthew G. Knepley 5812e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS() 5813e5e52638SMatthew G. Knepley @*/ 5814e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDS(DM dm, DM newdm) 5815e5e52638SMatthew G. Knepley { 5816e5e52638SMatthew G. Knepley PetscInt Nds, s; 5817e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5818e5e52638SMatthew G. Knepley 5819e5e52638SMatthew G. Knepley PetscFunctionBegin; 5820e5e52638SMatthew G. Knepley if (dm == newdm) PetscFunctionReturn(0); 5821e5e52638SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 5822e5e52638SMatthew G. Knepley ierr = DMClearDS(newdm);CHKERRQ(ierr); 5823e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5824e5e52638SMatthew G. Knepley DMLabel label; 5825b3cf3223SMatthew G. Knepley IS fields; 5826*45480ffeSMatthew G. Knepley PetscDS ds, newds; 5827783e2ec8SMatthew G. Knepley PetscInt Nbd, bd; 5828e5e52638SMatthew G. Knepley 5829b3cf3223SMatthew G. Knepley ierr = DMGetRegionNumDS(dm, s, &label, &fields, &ds);CHKERRQ(ierr); 5830*45480ffeSMatthew G. Knepley ierr = DMTransferDS_Internal(newdm, label, fields, ds);CHKERRQ(ierr); 5831*45480ffeSMatthew G. Knepley /* Commplete new labels in the new DS */ 5832*45480ffeSMatthew G. Knepley ierr = DMGetRegionDS(newdm, label, NULL, &newds);CHKERRQ(ierr); 5833*45480ffeSMatthew G. Knepley ierr = PetscDSGetNumBoundary(newds, &Nbd);CHKERRQ(ierr); 5834783e2ec8SMatthew G. Knepley for (bd = 0; bd < Nbd; ++bd) { 5835*45480ffeSMatthew G. Knepley DMLabel label; 5836783e2ec8SMatthew G. Knepley PetscInt field; 5837783e2ec8SMatthew G. Knepley 5838*45480ffeSMatthew G. Knepley ierr = PetscDSGetBoundary(newds, bd, NULL, NULL, NULL, &label, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 5839*45480ffeSMatthew G. Knepley ierr = DMCompleteBoundaryLabel_Internal(newdm, newds, field, bd, label);CHKERRQ(ierr); 5840783e2ec8SMatthew G. Knepley } 5841e5e52638SMatthew G. Knepley } 5842e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5843e5e52638SMatthew G. Knepley } 5844e5e52638SMatthew G. Knepley 5845e5e52638SMatthew G. Knepley /*@ 5846e5e52638SMatthew G. Knepley DMCopyDisc - Copy the fields and discrete systems for the DM into another DM 5847e5e52638SMatthew G. Knepley 5848d083f849SBarry Smith Collective on dm 5849e5e52638SMatthew G. Knepley 5850e5e52638SMatthew G. Knepley Input Parameter: 5851e5e52638SMatthew G. Knepley . dm - The DM 5852e5e52638SMatthew G. Knepley 5853e5e52638SMatthew G. Knepley Output Parameter: 5854e5e52638SMatthew G. Knepley . newdm - The DM 5855e5e52638SMatthew G. Knepley 5856e5e52638SMatthew G. Knepley Level: advanced 5857e5e52638SMatthew G. Knepley 5858e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMCopyDS() 5859e5e52638SMatthew G. Knepley @*/ 5860e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDisc(DM dm, DM newdm) 5861e5e52638SMatthew G. Knepley { 5862e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5863e5e52638SMatthew G. Knepley 5864e5e52638SMatthew G. Knepley PetscFunctionBegin; 5865e5e52638SMatthew G. Knepley ierr = DMCopyFields(dm, newdm);CHKERRQ(ierr); 5866e5e52638SMatthew G. Knepley ierr = DMCopyDS(dm, newdm);CHKERRQ(ierr); 5867e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5868e5e52638SMatthew G. Knepley } 5869e5e52638SMatthew G. Knepley 5870b64e0483SPeter Brune PetscErrorCode DMRestrictHook_Coordinates(DM dm,DM dmc,void *ctx) 5871b64e0483SPeter Brune { 5872b64e0483SPeter Brune DM dm_coord,dmc_coord; 5873b64e0483SPeter Brune PetscErrorCode ierr; 5874b64e0483SPeter Brune Vec coords,ccoords; 58756dbf9973SLawrence Mitchell Mat inject; 5876b64e0483SPeter Brune PetscFunctionBegin; 5877b64e0483SPeter Brune ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr); 5878b64e0483SPeter Brune ierr = DMGetCoordinateDM(dmc,&dmc_coord);CHKERRQ(ierr); 5879b64e0483SPeter Brune ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr); 5880b64e0483SPeter Brune ierr = DMGetCoordinates(dmc,&ccoords);CHKERRQ(ierr); 5881b64e0483SPeter Brune if (coords && !ccoords) { 5882b64e0483SPeter Brune ierr = DMCreateGlobalVector(dmc_coord,&ccoords);CHKERRQ(ierr); 58836668ed41SLisandro Dalcin ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr); 58846dbf9973SLawrence Mitchell ierr = DMCreateInjection(dmc_coord,dm_coord,&inject);CHKERRQ(ierr); 58852adcf181SLawrence Mitchell ierr = MatRestrict(inject,coords,ccoords);CHKERRQ(ierr); 58866dbf9973SLawrence Mitchell ierr = MatDestroy(&inject);CHKERRQ(ierr); 5887b64e0483SPeter Brune ierr = DMSetCoordinates(dmc,ccoords);CHKERRQ(ierr); 5888b64e0483SPeter Brune ierr = VecDestroy(&ccoords);CHKERRQ(ierr); 5889b64e0483SPeter Brune } 5890b64e0483SPeter Brune PetscFunctionReturn(0); 5891b64e0483SPeter Brune } 5892b64e0483SPeter Brune 589303dadc2fSPeter Brune static PetscErrorCode DMSubDomainHook_Coordinates(DM dm,DM subdm,void *ctx) 589403dadc2fSPeter Brune { 589503dadc2fSPeter Brune DM dm_coord,subdm_coord; 589603dadc2fSPeter Brune PetscErrorCode ierr; 589703dadc2fSPeter Brune Vec coords,ccoords,clcoords; 589803dadc2fSPeter Brune VecScatter *scat_i,*scat_g; 589903dadc2fSPeter Brune PetscFunctionBegin; 590003dadc2fSPeter Brune ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr); 590103dadc2fSPeter Brune ierr = DMGetCoordinateDM(subdm,&subdm_coord);CHKERRQ(ierr); 590203dadc2fSPeter Brune ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr); 590303dadc2fSPeter Brune ierr = DMGetCoordinates(subdm,&ccoords);CHKERRQ(ierr); 590403dadc2fSPeter Brune if (coords && !ccoords) { 590503dadc2fSPeter Brune ierr = DMCreateGlobalVector(subdm_coord,&ccoords);CHKERRQ(ierr); 59066668ed41SLisandro Dalcin ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr); 590703dadc2fSPeter Brune ierr = DMCreateLocalVector(subdm_coord,&clcoords);CHKERRQ(ierr); 590824640c55SToby Isaac ierr = PetscObjectSetName((PetscObject)clcoords,"coordinates");CHKERRQ(ierr); 590903dadc2fSPeter Brune ierr = DMCreateDomainDecompositionScatters(dm_coord,1,&subdm_coord,NULL,&scat_i,&scat_g);CHKERRQ(ierr); 591003dadc2fSPeter Brune ierr = VecScatterBegin(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 591103dadc2fSPeter Brune ierr = VecScatterEnd(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 59121ed9ada7SJunchao Zhang ierr = VecScatterBegin(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 591303dadc2fSPeter Brune ierr = VecScatterEnd(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 591403dadc2fSPeter Brune ierr = DMSetCoordinates(subdm,ccoords);CHKERRQ(ierr); 591503dadc2fSPeter Brune ierr = DMSetCoordinatesLocal(subdm,clcoords);CHKERRQ(ierr); 591603dadc2fSPeter Brune ierr = VecScatterDestroy(&scat_i[0]);CHKERRQ(ierr); 591703dadc2fSPeter Brune ierr = VecScatterDestroy(&scat_g[0]);CHKERRQ(ierr); 591803dadc2fSPeter Brune ierr = VecDestroy(&ccoords);CHKERRQ(ierr); 591903dadc2fSPeter Brune ierr = VecDestroy(&clcoords);CHKERRQ(ierr); 592003dadc2fSPeter Brune ierr = PetscFree(scat_i);CHKERRQ(ierr); 592103dadc2fSPeter Brune ierr = PetscFree(scat_g);CHKERRQ(ierr); 592203dadc2fSPeter Brune } 592303dadc2fSPeter Brune PetscFunctionReturn(0); 592403dadc2fSPeter Brune } 592503dadc2fSPeter Brune 5926c73cfb54SMatthew G. Knepley /*@ 5927c73cfb54SMatthew G. Knepley DMGetDimension - Return the topological dimension of the DM 5928c73cfb54SMatthew G. Knepley 5929c73cfb54SMatthew G. Knepley Not collective 5930c73cfb54SMatthew G. Knepley 5931c73cfb54SMatthew G. Knepley Input Parameter: 5932c73cfb54SMatthew G. Knepley . dm - The DM 5933c73cfb54SMatthew G. Knepley 5934c73cfb54SMatthew G. Knepley Output Parameter: 5935c73cfb54SMatthew G. Knepley . dim - The topological dimension 5936c73cfb54SMatthew G. Knepley 5937c73cfb54SMatthew G. Knepley Level: beginner 5938c73cfb54SMatthew G. Knepley 5939c73cfb54SMatthew G. Knepley .seealso: DMSetDimension(), DMCreate() 5940c73cfb54SMatthew G. Knepley @*/ 5941c73cfb54SMatthew G. Knepley PetscErrorCode DMGetDimension(DM dm, PetscInt *dim) 5942c73cfb54SMatthew G. Knepley { 5943c73cfb54SMatthew G. Knepley PetscFunctionBegin; 5944c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5945534a8f05SLisandro Dalcin PetscValidIntPointer(dim, 2); 5946c73cfb54SMatthew G. Knepley *dim = dm->dim; 5947c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 5948c73cfb54SMatthew G. Knepley } 5949c73cfb54SMatthew G. Knepley 5950c73cfb54SMatthew G. Knepley /*@ 5951c73cfb54SMatthew G. Knepley DMSetDimension - Set the topological dimension of the DM 5952c73cfb54SMatthew G. Knepley 5953c73cfb54SMatthew G. Knepley Collective on dm 5954c73cfb54SMatthew G. Knepley 5955c73cfb54SMatthew G. Knepley Input Parameters: 5956c73cfb54SMatthew G. Knepley + dm - The DM 5957c73cfb54SMatthew G. Knepley - dim - The topological dimension 5958c73cfb54SMatthew G. Knepley 5959c73cfb54SMatthew G. Knepley Level: beginner 5960c73cfb54SMatthew G. Knepley 5961c73cfb54SMatthew G. Knepley .seealso: DMGetDimension(), DMCreate() 5962c73cfb54SMatthew G. Knepley @*/ 5963c73cfb54SMatthew G. Knepley PetscErrorCode DMSetDimension(DM dm, PetscInt dim) 5964c73cfb54SMatthew G. Knepley { 5965e5e52638SMatthew G. Knepley PetscDS ds; 5966*45480ffeSMatthew G. Knepley PetscInt Nds, n; 5967f17e8794SMatthew G. Knepley PetscErrorCode ierr; 5968f17e8794SMatthew G. Knepley 5969c73cfb54SMatthew G. Knepley PetscFunctionBegin; 5970c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5971c73cfb54SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 5972c73cfb54SMatthew G. Knepley dm->dim = dim; 5973*45480ffeSMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 5974*45480ffeSMatthew G. Knepley for (n = 0; n < Nds; ++n) { 5975*45480ffeSMatthew G. Knepley ierr = DMGetRegionNumDS(dm, n, NULL, NULL, &ds);CHKERRQ(ierr); 5976*45480ffeSMatthew G. Knepley if (ds->dimEmbed < 0) {ierr = PetscDSSetCoordinateDimension(ds, dim);CHKERRQ(ierr);} 5977*45480ffeSMatthew G. Knepley } 5978c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 5979c73cfb54SMatthew G. Knepley } 5980c73cfb54SMatthew G. Knepley 5981793f3fe5SMatthew G. Knepley /*@ 5982793f3fe5SMatthew G. Knepley DMGetDimPoints - Get the half-open interval for all points of a given dimension 5983793f3fe5SMatthew G. Knepley 5984d083f849SBarry Smith Collective on dm 5985793f3fe5SMatthew G. Knepley 5986793f3fe5SMatthew G. Knepley Input Parameters: 5987793f3fe5SMatthew G. Knepley + dm - the DM 5988793f3fe5SMatthew G. Knepley - dim - the dimension 5989793f3fe5SMatthew G. Knepley 5990793f3fe5SMatthew G. Knepley Output Parameters: 5991793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension 5992aa049354SPatrick Sanan - pEnd - The first point following points of the given dimension 5993793f3fe5SMatthew G. Knepley 5994793f3fe5SMatthew G. Knepley Note: 5995793f3fe5SMatthew G. Knepley The points are vertices in the Hasse diagram encoding the topology. This is explained in 5996a8d69d7bSBarry Smith https://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme, 5997793f3fe5SMatthew G. Knepley then the interval is empty. 5998793f3fe5SMatthew G. Knepley 5999793f3fe5SMatthew G. Knepley Level: intermediate 6000793f3fe5SMatthew G. Knepley 6001793f3fe5SMatthew G. Knepley .seealso: DMPLEX, DMPlexGetDepthStratum(), DMPlexGetHeightStratum() 6002793f3fe5SMatthew G. Knepley @*/ 6003793f3fe5SMatthew G. Knepley PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 6004793f3fe5SMatthew G. Knepley { 6005793f3fe5SMatthew G. Knepley PetscInt d; 6006793f3fe5SMatthew G. Knepley PetscErrorCode ierr; 6007793f3fe5SMatthew G. Knepley 6008793f3fe5SMatthew G. Knepley PetscFunctionBegin; 6009793f3fe5SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6010793f3fe5SMatthew G. Knepley ierr = DMGetDimension(dm, &d);CHKERRQ(ierr); 6011793f3fe5SMatthew G. Knepley if ((dim < 0) || (dim > d)) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %d 1", dim, d); 6012b9d85ea2SLisandro Dalcin if (!dm->ops->getdimpoints) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "DM type %s does not implement DMGetDimPoints",((PetscObject)dm)->type_name); 6013793f3fe5SMatthew G. Knepley ierr = (*dm->ops->getdimpoints)(dm, dim, pStart, pEnd);CHKERRQ(ierr); 6014793f3fe5SMatthew G. Knepley PetscFunctionReturn(0); 6015793f3fe5SMatthew G. Knepley } 6016793f3fe5SMatthew G. Knepley 60176636e97aSMatthew G Knepley /*@ 60186636e97aSMatthew G Knepley DMSetCoordinates - Sets into the DM a global vector that holds the coordinates 60196636e97aSMatthew G Knepley 6020d083f849SBarry Smith Collective on dm 60216636e97aSMatthew G Knepley 60226636e97aSMatthew G Knepley Input Parameters: 60236636e97aSMatthew G Knepley + dm - the DM 60246636e97aSMatthew G Knepley - c - coordinate vector 60256636e97aSMatthew G Knepley 60262dd40e9bSPatrick Sanan Notes: 60272dd40e9bSPatrick Sanan The coordinates do include those for ghost points, which are in the local vector. 60282dd40e9bSPatrick Sanan 60292dd40e9bSPatrick Sanan The vector c should be destroyed by the caller. 60306636e97aSMatthew G Knepley 60316636e97aSMatthew G Knepley Level: intermediate 60326636e97aSMatthew G Knepley 603360c22052SBarry Smith .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMDASetUniformCoordinates() 60346636e97aSMatthew G Knepley @*/ 60356636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c) 60366636e97aSMatthew G Knepley { 60376636e97aSMatthew G Knepley PetscErrorCode ierr; 60386636e97aSMatthew G Knepley 60396636e97aSMatthew G Knepley PetscFunctionBegin; 60406636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 60416636e97aSMatthew G Knepley PetscValidHeaderSpecific(c,VEC_CLASSID,2); 60426636e97aSMatthew G Knepley ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr); 60436636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr); 60446636e97aSMatthew G Knepley dm->coordinates = c; 60456636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr); 6046b64e0483SPeter Brune ierr = DMCoarsenHookAdd(dm,DMRestrictHook_Coordinates,NULL,NULL);CHKERRQ(ierr); 604703dadc2fSPeter Brune ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_Coordinates,NULL,NULL);CHKERRQ(ierr); 60486636e97aSMatthew G Knepley PetscFunctionReturn(0); 60496636e97aSMatthew G Knepley } 60506636e97aSMatthew G Knepley 60516636e97aSMatthew G Knepley /*@ 60526636e97aSMatthew G Knepley DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates 60536636e97aSMatthew G Knepley 60547058e716SVaclav Hapla Not collective 60556636e97aSMatthew G Knepley 60566636e97aSMatthew G Knepley Input Parameters: 60576636e97aSMatthew G Knepley + dm - the DM 60586636e97aSMatthew G Knepley - c - coordinate vector 60596636e97aSMatthew G Knepley 60602dd40e9bSPatrick Sanan Notes: 60616636e97aSMatthew G Knepley The coordinates of ghost points can be set using DMSetCoordinates() 60626636e97aSMatthew G Knepley followed by DMGetCoordinatesLocal(). This is intended to enable the 60636636e97aSMatthew G Knepley setting of ghost coordinates outside of the domain. 60646636e97aSMatthew G Knepley 60652dd40e9bSPatrick Sanan The vector c should be destroyed by the caller. 60662dd40e9bSPatrick Sanan 60676636e97aSMatthew G Knepley Level: intermediate 60686636e97aSMatthew G Knepley 60696636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM() 60706636e97aSMatthew G Knepley @*/ 60716636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c) 60726636e97aSMatthew G Knepley { 60736636e97aSMatthew G Knepley PetscErrorCode ierr; 60746636e97aSMatthew G Knepley 60756636e97aSMatthew G Knepley PetscFunctionBegin; 60766636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 60776636e97aSMatthew G Knepley PetscValidHeaderSpecific(c,VEC_CLASSID,2); 60786636e97aSMatthew G Knepley ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr); 60796636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr); 60808865f1eaSKarl Rupp 60816636e97aSMatthew G Knepley dm->coordinatesLocal = c; 60828865f1eaSKarl Rupp 60836636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr); 60846636e97aSMatthew G Knepley PetscFunctionReturn(0); 60856636e97aSMatthew G Knepley } 60866636e97aSMatthew G Knepley 60876636e97aSMatthew G Knepley /*@ 60886636e97aSMatthew G Knepley DMGetCoordinates - Gets a global vector with the coordinates associated with the DM. 60896636e97aSMatthew G Knepley 6090d083f849SBarry Smith Collective on dm 60916636e97aSMatthew G Knepley 60926636e97aSMatthew G Knepley Input Parameter: 60936636e97aSMatthew G Knepley . dm - the DM 60946636e97aSMatthew G Knepley 60956636e97aSMatthew G Knepley Output Parameter: 60966636e97aSMatthew G Knepley . c - global coordinate vector 60976636e97aSMatthew G Knepley 60986636e97aSMatthew G Knepley Note: 609960c22052SBarry Smith This is a borrowed reference, so the user should NOT destroy this vector. When the DM is 610060c22052SBarry Smith destroyed the array will no longer be valid. 61016636e97aSMatthew G Knepley 6102959c7569SPatrick Sanan Each process has only the locally-owned portion of the global coordinates (does NOT have the ghost coordinates). 61036636e97aSMatthew G Knepley 61046636e97aSMatthew G Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 61056636e97aSMatthew G Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 61066636e97aSMatthew G Knepley 61076636e97aSMatthew G Knepley Level: intermediate 61086636e97aSMatthew G Knepley 610960c22052SBarry Smith .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMDASetUniformCoordinates() 61106636e97aSMatthew G Knepley @*/ 61116636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c) 61126636e97aSMatthew G Knepley { 61136636e97aSMatthew G Knepley PetscErrorCode ierr; 61146636e97aSMatthew G Knepley 61156636e97aSMatthew G Knepley PetscFunctionBegin; 61166636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 61176636e97aSMatthew G Knepley PetscValidPointer(c,2); 61181f588964SMatthew G Knepley if (!dm->coordinates && dm->coordinatesLocal) { 61190298fd71SBarry Smith DM cdm = NULL; 61201970a576SMatthew G. Knepley PetscBool localized; 61216636e97aSMatthew G Knepley 61226636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 61236636e97aSMatthew G Knepley ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr); 61241970a576SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 61251970a576SMatthew G. Knepley /* Block size is not correctly set by CreateGlobalVector() if coordinates are localized */ 61261970a576SMatthew G. Knepley if (localized) { 61271970a576SMatthew G. Knepley PetscInt cdim; 61281970a576SMatthew G. Knepley 61291970a576SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 61301970a576SMatthew G. Knepley ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr); 61311970a576SMatthew G. Knepley } 61326636e97aSMatthew G Knepley ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr); 61336636e97aSMatthew G Knepley ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr); 61346636e97aSMatthew G Knepley ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr); 61356636e97aSMatthew G Knepley } 61366636e97aSMatthew G Knepley *c = dm->coordinates; 61376636e97aSMatthew G Knepley PetscFunctionReturn(0); 61386636e97aSMatthew G Knepley } 61396636e97aSMatthew G Knepley 61406636e97aSMatthew G Knepley /*@ 614181e9a530SVaclav Hapla DMGetCoordinatesLocalSetUp - Prepares a local vector of coordinates, so that DMGetCoordinatesLocalNoncollective() can be used as non-collective afterwards. 614281e9a530SVaclav Hapla 6143d083f849SBarry Smith Collective on dm 614481e9a530SVaclav Hapla 614581e9a530SVaclav Hapla Input Parameter: 614681e9a530SVaclav Hapla . dm - the DM 614781e9a530SVaclav Hapla 614881e9a530SVaclav Hapla Level: advanced 614981e9a530SVaclav Hapla 615081e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalNoncollective() 615181e9a530SVaclav Hapla @*/ 615281e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalSetUp(DM dm) 615381e9a530SVaclav Hapla { 615481e9a530SVaclav Hapla PetscErrorCode ierr; 615581e9a530SVaclav Hapla 615681e9a530SVaclav Hapla PetscFunctionBegin; 615781e9a530SVaclav Hapla PetscValidHeaderSpecific(dm,DM_CLASSID,1); 615881e9a530SVaclav Hapla if (!dm->coordinatesLocal && dm->coordinates) { 61591970a576SMatthew G. Knepley DM cdm = NULL; 61601970a576SMatthew G. Knepley PetscBool localized; 61611970a576SMatthew G. Knepley 616281e9a530SVaclav Hapla ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 616381e9a530SVaclav Hapla ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr); 61641970a576SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 61651970a576SMatthew G. Knepley /* Block size is not correctly set by CreateLocalVector() if coordinates are localized */ 61661970a576SMatthew G. Knepley if (localized) { 61671970a576SMatthew G. Knepley PetscInt cdim; 61681970a576SMatthew G. Knepley 61691970a576SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 61701970a576SMatthew G. Knepley ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr); 61711970a576SMatthew G. Knepley } 617281e9a530SVaclav Hapla ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr); 617381e9a530SVaclav Hapla ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr); 617481e9a530SVaclav Hapla ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr); 617581e9a530SVaclav Hapla } 617681e9a530SVaclav Hapla PetscFunctionReturn(0); 617781e9a530SVaclav Hapla } 617881e9a530SVaclav Hapla 617981e9a530SVaclav Hapla /*@ 61806636e97aSMatthew G Knepley DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM. 61816636e97aSMatthew G Knepley 6182d083f849SBarry Smith Collective on dm 61836636e97aSMatthew G Knepley 61846636e97aSMatthew G Knepley Input Parameter: 61856636e97aSMatthew G Knepley . dm - the DM 61866636e97aSMatthew G Knepley 61876636e97aSMatthew G Knepley Output Parameter: 61886636e97aSMatthew G Knepley . c - coordinate vector 61896636e97aSMatthew G Knepley 61906636e97aSMatthew G Knepley Note: 61916636e97aSMatthew G Knepley This is a borrowed reference, so the user should NOT destroy this vector 61926636e97aSMatthew G Knepley 61936636e97aSMatthew G Knepley Each process has the local and ghost coordinates 61946636e97aSMatthew G Knepley 61956636e97aSMatthew G Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 61966636e97aSMatthew G Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 61976636e97aSMatthew G Knepley 61986636e97aSMatthew G Knepley Level: intermediate 61996636e97aSMatthew G Knepley 620081e9a530SVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM(), DMGetCoordinatesLocalNoncollective() 62016636e97aSMatthew G Knepley @*/ 62026636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c) 62036636e97aSMatthew G Knepley { 62046636e97aSMatthew G Knepley PetscErrorCode ierr; 62056636e97aSMatthew G Knepley 62066636e97aSMatthew G Knepley PetscFunctionBegin; 62076636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 62086636e97aSMatthew G Knepley PetscValidPointer(c,2); 620981e9a530SVaclav Hapla ierr = DMGetCoordinatesLocalSetUp(dm);CHKERRQ(ierr); 62106636e97aSMatthew G Knepley *c = dm->coordinatesLocal; 62116636e97aSMatthew G Knepley PetscFunctionReturn(0); 62126636e97aSMatthew G Knepley } 62136636e97aSMatthew G Knepley 621481e9a530SVaclav Hapla /*@ 621581e9a530SVaclav Hapla DMGetCoordinatesLocalNoncollective - Non-collective version of DMGetCoordinatesLocal(). Fails if global coordinates have been set and DMGetCoordinatesLocalSetUp() not called. 621681e9a530SVaclav Hapla 621781e9a530SVaclav Hapla Not collective 621881e9a530SVaclav Hapla 621981e9a530SVaclav Hapla Input Parameter: 622081e9a530SVaclav Hapla . dm - the DM 622181e9a530SVaclav Hapla 622281e9a530SVaclav Hapla Output Parameter: 622381e9a530SVaclav Hapla . c - coordinate vector 622481e9a530SVaclav Hapla 622581e9a530SVaclav Hapla Level: advanced 622681e9a530SVaclav Hapla 622781e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalSetUp(), DMGetCoordinatesLocal(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM() 622881e9a530SVaclav Hapla @*/ 622981e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalNoncollective(DM dm, Vec *c) 623081e9a530SVaclav Hapla { 623181e9a530SVaclav Hapla PetscFunctionBegin; 623281e9a530SVaclav Hapla PetscValidHeaderSpecific(dm,DM_CLASSID,1); 623381e9a530SVaclav Hapla PetscValidPointer(c,2); 623481e9a530SVaclav Hapla if (!dm->coordinatesLocal && dm->coordinates) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called"); 62356636e97aSMatthew G Knepley *c = dm->coordinatesLocal; 62366636e97aSMatthew G Knepley PetscFunctionReturn(0); 62376636e97aSMatthew G Knepley } 62386636e97aSMatthew G Knepley 62392db98f8dSVaclav Hapla /*@ 62402db98f8dSVaclav Hapla DMGetCoordinatesLocalTuple - Gets a local vector with the coordinates of specified points and section describing its layout. 62412db98f8dSVaclav Hapla 62422db98f8dSVaclav Hapla Not collective 62432db98f8dSVaclav Hapla 62442db98f8dSVaclav Hapla Input Parameter: 62452db98f8dSVaclav Hapla + dm - the DM 62462db98f8dSVaclav Hapla - p - the IS of points whose coordinates will be returned 62472db98f8dSVaclav Hapla 62482db98f8dSVaclav Hapla Output Parameter: 62492db98f8dSVaclav Hapla + pCoordSection - the PetscSection describing the layout of pCoord, i.e. each point corresponds to one point in p, and DOFs correspond to coordinates 62502db98f8dSVaclav Hapla - pCoord - the Vec with coordinates of points in p 62512db98f8dSVaclav Hapla 62522db98f8dSVaclav Hapla Note: 62532db98f8dSVaclav Hapla DMGetCoordinatesLocalSetUp() must be called first. This function employs DMGetCoordinatesLocalNoncollective() so it is not collective. 62542db98f8dSVaclav Hapla 62552db98f8dSVaclav Hapla This creates a new vector, so the user SHOULD destroy this vector 62562db98f8dSVaclav Hapla 62572db98f8dSVaclav Hapla Each process has the local and ghost coordinates 62582db98f8dSVaclav Hapla 62592db98f8dSVaclav Hapla For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 62602db98f8dSVaclav Hapla and (x_0,y_0,z_0,x_1,y_1,z_1...) 62612db98f8dSVaclav Hapla 62622db98f8dSVaclav Hapla Level: advanced 62632db98f8dSVaclav Hapla 62642db98f8dSVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinatesLocal(), DMGetCoordinatesLocalNoncollective(), DMGetCoordinatesLocalSetUp(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM() 62652db98f8dSVaclav Hapla @*/ 62662db98f8dSVaclav Hapla PetscErrorCode DMGetCoordinatesLocalTuple(DM dm, IS p, PetscSection *pCoordSection, Vec *pCoord) 62672db98f8dSVaclav Hapla { 62682db98f8dSVaclav Hapla PetscSection cs, newcs; 62692db98f8dSVaclav Hapla Vec coords; 62702db98f8dSVaclav Hapla const PetscScalar *arr; 62712db98f8dSVaclav Hapla PetscScalar *newarr=NULL; 62722db98f8dSVaclav Hapla PetscInt n; 62732db98f8dSVaclav Hapla PetscErrorCode ierr; 62742db98f8dSVaclav Hapla 62752db98f8dSVaclav Hapla PetscFunctionBegin; 62762db98f8dSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 62772db98f8dSVaclav Hapla PetscValidHeaderSpecific(p, IS_CLASSID, 2); 62782db98f8dSVaclav Hapla if (pCoordSection) PetscValidPointer(pCoordSection, 3); 62792db98f8dSVaclav Hapla if (pCoord) PetscValidPointer(pCoord, 4); 62802db98f8dSVaclav Hapla if (!dm->coordinatesLocal) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called or coordinates not set"); 62811bb6d2a8SBarry Smith if (!dm->coordinateDM || !dm->coordinateDM->localSection) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM not supported"); 62821bb6d2a8SBarry Smith cs = dm->coordinateDM->localSection; 62832db98f8dSVaclav Hapla coords = dm->coordinatesLocal; 62842db98f8dSVaclav Hapla ierr = VecGetArrayRead(coords, &arr);CHKERRQ(ierr); 62852db98f8dSVaclav Hapla ierr = PetscSectionExtractDofsFromArray(cs, MPIU_SCALAR, arr, p, &newcs, pCoord ? ((void**)&newarr) : NULL);CHKERRQ(ierr); 62862db98f8dSVaclav Hapla ierr = VecRestoreArrayRead(coords, &arr);CHKERRQ(ierr); 62872db98f8dSVaclav Hapla if (pCoord) { 62882db98f8dSVaclav Hapla ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr); 62892db98f8dSVaclav Hapla /* set array in two steps to mimic PETSC_OWN_POINTER */ 62902db98f8dSVaclav Hapla ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)p), 1, n, NULL, pCoord);CHKERRQ(ierr); 62912db98f8dSVaclav Hapla ierr = VecReplaceArray(*pCoord, newarr);CHKERRQ(ierr); 6292ad9ac99dSVaclav Hapla } else { 6293ad9ac99dSVaclav Hapla ierr = PetscFree(newarr);CHKERRQ(ierr); 62942db98f8dSVaclav Hapla } 6295ad9ac99dSVaclav Hapla if (pCoordSection) {*pCoordSection = newcs;} 6296ad9ac99dSVaclav Hapla else {ierr = PetscSectionDestroy(&newcs);CHKERRQ(ierr);} 62972db98f8dSVaclav Hapla PetscFunctionReturn(0); 62982db98f8dSVaclav Hapla } 62992db98f8dSVaclav Hapla 6300f19dbd58SToby Isaac PetscErrorCode DMGetCoordinateField(DM dm, DMField *field) 6301f19dbd58SToby Isaac { 6302f19dbd58SToby Isaac PetscErrorCode ierr; 6303f19dbd58SToby Isaac 6304f19dbd58SToby Isaac PetscFunctionBegin; 6305f19dbd58SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6306f19dbd58SToby Isaac PetscValidPointer(field,2); 6307f19dbd58SToby Isaac if (!dm->coordinateField) { 6308f19dbd58SToby Isaac if (dm->ops->createcoordinatefield) { 6309f19dbd58SToby Isaac ierr = (*dm->ops->createcoordinatefield)(dm,&dm->coordinateField);CHKERRQ(ierr); 6310f19dbd58SToby Isaac } 6311f19dbd58SToby Isaac } 6312f19dbd58SToby Isaac *field = dm->coordinateField; 6313f19dbd58SToby Isaac PetscFunctionReturn(0); 6314f19dbd58SToby Isaac } 6315f19dbd58SToby Isaac 6316f19dbd58SToby Isaac PetscErrorCode DMSetCoordinateField(DM dm, DMField field) 6317f19dbd58SToby Isaac { 6318f19dbd58SToby Isaac PetscErrorCode ierr; 6319f19dbd58SToby Isaac 6320f19dbd58SToby Isaac PetscFunctionBegin; 6321f19dbd58SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6322f19dbd58SToby Isaac if (field) PetscValidHeaderSpecific(field,DMFIELD_CLASSID,2); 6323c4e6da2cSBarry Smith ierr = PetscObjectReference((PetscObject)field);CHKERRQ(ierr); 6324f19dbd58SToby Isaac ierr = DMFieldDestroy(&dm->coordinateField);CHKERRQ(ierr); 6325f19dbd58SToby Isaac dm->coordinateField = field; 6326f19dbd58SToby Isaac PetscFunctionReturn(0); 6327f19dbd58SToby Isaac } 6328f19dbd58SToby Isaac 63296636e97aSMatthew G Knepley /*@ 63301cfe2091SMatthew G. Knepley DMGetCoordinateDM - Gets the DM that prescribes coordinate layout and scatters between global and local coordinates 63316636e97aSMatthew G Knepley 6332d083f849SBarry Smith Collective on dm 63336636e97aSMatthew G Knepley 63346636e97aSMatthew G Knepley Input Parameter: 63356636e97aSMatthew G Knepley . dm - the DM 63366636e97aSMatthew G Knepley 63376636e97aSMatthew G Knepley Output Parameter: 63386636e97aSMatthew G Knepley . cdm - coordinate DM 63396636e97aSMatthew G Knepley 63406636e97aSMatthew G Knepley Level: intermediate 63416636e97aSMatthew G Knepley 63421cfe2091SMatthew G. Knepley .seealso: DMSetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal() 63436636e97aSMatthew G Knepley @*/ 63446636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm) 63456636e97aSMatthew G Knepley { 63466636e97aSMatthew G Knepley PetscErrorCode ierr; 63476636e97aSMatthew G Knepley 63486636e97aSMatthew G Knepley PetscFunctionBegin; 63496636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 63506636e97aSMatthew G Knepley PetscValidPointer(cdm,2); 63516636e97aSMatthew G Knepley if (!dm->coordinateDM) { 6352308f8a94SToby Isaac DM cdm; 6353308f8a94SToby Isaac 635482f516ccSBarry Smith if (!dm->ops->createcoordinatedm) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unable to create coordinates for this DM"); 6355308f8a94SToby Isaac ierr = (*dm->ops->createcoordinatedm)(dm, &cdm);CHKERRQ(ierr); 6356308f8a94SToby Isaac /* Just in case the DM sets the coordinate DM when creating it (DMP4est can do this, because it may not setup 6357308f8a94SToby Isaac * until the call to CreateCoordinateDM) */ 6358308f8a94SToby Isaac ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr); 6359308f8a94SToby Isaac dm->coordinateDM = cdm; 63606636e97aSMatthew G Knepley } 63616636e97aSMatthew G Knepley *cdm = dm->coordinateDM; 63626636e97aSMatthew G Knepley PetscFunctionReturn(0); 63636636e97aSMatthew G Knepley } 6364e87bb0d3SMatthew G Knepley 63651cfe2091SMatthew G. Knepley /*@ 63661cfe2091SMatthew G. Knepley DMSetCoordinateDM - Sets the DM that prescribes coordinate layout and scatters between global and local coordinates 63671cfe2091SMatthew G. Knepley 6368d083f849SBarry Smith Logically Collective on dm 63691cfe2091SMatthew G. Knepley 63701cfe2091SMatthew G. Knepley Input Parameters: 63711cfe2091SMatthew G. Knepley + dm - the DM 63721cfe2091SMatthew G. Knepley - cdm - coordinate DM 63731cfe2091SMatthew G. Knepley 63741cfe2091SMatthew G. Knepley Level: intermediate 63751cfe2091SMatthew G. Knepley 63761cfe2091SMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal() 63771cfe2091SMatthew G. Knepley @*/ 63781cfe2091SMatthew G. Knepley PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm) 63791cfe2091SMatthew G. Knepley { 63801cfe2091SMatthew G. Knepley PetscErrorCode ierr; 63811cfe2091SMatthew G. Knepley 63821cfe2091SMatthew G. Knepley PetscFunctionBegin; 63831cfe2091SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 63841cfe2091SMatthew G. Knepley PetscValidHeaderSpecific(cdm,DM_CLASSID,2); 6385f26b38b9SToby Isaac ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr); 63861cfe2091SMatthew G. Knepley ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr); 63871cfe2091SMatthew G. Knepley dm->coordinateDM = cdm; 63881cfe2091SMatthew G. Knepley PetscFunctionReturn(0); 63891cfe2091SMatthew G. Knepley } 63901cfe2091SMatthew G. Knepley 639146e270d4SMatthew G. Knepley /*@ 639246e270d4SMatthew G. Knepley DMGetCoordinateDim - Retrieve the dimension of embedding space for coordinate values. 639346e270d4SMatthew G. Knepley 639446e270d4SMatthew G. Knepley Not Collective 639546e270d4SMatthew G. Knepley 639646e270d4SMatthew G. Knepley Input Parameter: 639746e270d4SMatthew G. Knepley . dm - The DM object 639846e270d4SMatthew G. Knepley 639946e270d4SMatthew G. Knepley Output Parameter: 640046e270d4SMatthew G. Knepley . dim - The embedding dimension 640146e270d4SMatthew G. Knepley 640246e270d4SMatthew G. Knepley Level: intermediate 640346e270d4SMatthew G. Knepley 640492fd8e1eSJed Brown .seealso: DMSetCoordinateDim(), DMGetCoordinateSection(), DMGetCoordinateDM(), DMGetLocalSection(), DMSetLocalSection() 640546e270d4SMatthew G. Knepley @*/ 640646e270d4SMatthew G. Knepley PetscErrorCode DMGetCoordinateDim(DM dm, PetscInt *dim) 640746e270d4SMatthew G. Knepley { 640846e270d4SMatthew G. Knepley PetscFunctionBegin; 640946e270d4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6410534a8f05SLisandro Dalcin PetscValidIntPointer(dim, 2); 64119a9a41abSToby Isaac if (dm->dimEmbed == PETSC_DEFAULT) { 64129a9a41abSToby Isaac dm->dimEmbed = dm->dim; 64139a9a41abSToby Isaac } 641446e270d4SMatthew G. Knepley *dim = dm->dimEmbed; 641546e270d4SMatthew G. Knepley PetscFunctionReturn(0); 641646e270d4SMatthew G. Knepley } 641746e270d4SMatthew G. Knepley 641846e270d4SMatthew G. Knepley /*@ 641946e270d4SMatthew G. Knepley DMSetCoordinateDim - Set the dimension of the embedding space for coordinate values. 642046e270d4SMatthew G. Knepley 642146e270d4SMatthew G. Knepley Not Collective 642246e270d4SMatthew G. Knepley 642346e270d4SMatthew G. Knepley Input Parameters: 642446e270d4SMatthew G. Knepley + dm - The DM object 642546e270d4SMatthew G. Knepley - dim - The embedding dimension 642646e270d4SMatthew G. Knepley 642746e270d4SMatthew G. Knepley Level: intermediate 642846e270d4SMatthew G. Knepley 642992fd8e1eSJed Brown .seealso: DMGetCoordinateDim(), DMSetCoordinateSection(), DMGetCoordinateSection(), DMGetLocalSection(), DMSetLocalSection() 643046e270d4SMatthew G. Knepley @*/ 643146e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateDim(DM dm, PetscInt dim) 643246e270d4SMatthew G. Knepley { 6433e5e52638SMatthew G. Knepley PetscDS ds; 6434*45480ffeSMatthew G. Knepley PetscInt Nds, n; 6435f17e8794SMatthew G. Knepley PetscErrorCode ierr; 6436f17e8794SMatthew G. Knepley 643746e270d4SMatthew G. Knepley PetscFunctionBegin; 643846e270d4SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 643946e270d4SMatthew G. Knepley dm->dimEmbed = dim; 6440*45480ffeSMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 6441*45480ffeSMatthew G. Knepley for (n = 0; n < Nds; ++n) { 6442*45480ffeSMatthew G. Knepley ierr = DMGetRegionNumDS(dm, n, NULL, NULL, &ds);CHKERRQ(ierr); 6443e5e52638SMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(ds, dim);CHKERRQ(ierr); 6444*45480ffeSMatthew G. Knepley } 644546e270d4SMatthew G. Knepley PetscFunctionReturn(0); 644646e270d4SMatthew G. Knepley } 644746e270d4SMatthew G. Knepley 6448e8abe2deSMatthew G. Knepley /*@ 6449e8abe2deSMatthew G. Knepley DMGetCoordinateSection - Retrieve the layout of coordinate values over the mesh. 6450e8abe2deSMatthew G. Knepley 6451d083f849SBarry Smith Collective on dm 6452e8abe2deSMatthew G. Knepley 6453e8abe2deSMatthew G. Knepley Input Parameter: 6454e8abe2deSMatthew G. Knepley . dm - The DM object 6455e8abe2deSMatthew G. Knepley 6456e8abe2deSMatthew G. Knepley Output Parameter: 6457e8abe2deSMatthew G. Knepley . section - The PetscSection object 6458e8abe2deSMatthew G. Knepley 6459e8abe2deSMatthew G. Knepley Level: intermediate 6460e8abe2deSMatthew G. Knepley 646192fd8e1eSJed Brown .seealso: DMGetCoordinateDM(), DMGetLocalSection(), DMSetLocalSection() 6462e8abe2deSMatthew G. Knepley @*/ 6463e8abe2deSMatthew G. Knepley PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section) 6464e8abe2deSMatthew G. Knepley { 6465e8abe2deSMatthew G. Knepley DM cdm; 6466e8abe2deSMatthew G. Knepley PetscErrorCode ierr; 6467e8abe2deSMatthew G. Knepley 6468e8abe2deSMatthew G. Knepley PetscFunctionBegin; 6469e8abe2deSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6470e8abe2deSMatthew G. Knepley PetscValidPointer(section, 2); 6471e8abe2deSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 647292fd8e1eSJed Brown ierr = DMGetLocalSection(cdm, section);CHKERRQ(ierr); 6473e8abe2deSMatthew G. Knepley PetscFunctionReturn(0); 6474e8abe2deSMatthew G. Knepley } 6475e8abe2deSMatthew G. Knepley 6476e8abe2deSMatthew G. Knepley /*@ 6477e8abe2deSMatthew G. Knepley DMSetCoordinateSection - Set the layout of coordinate values over the mesh. 6478e8abe2deSMatthew G. Knepley 6479e8abe2deSMatthew G. Knepley Not Collective 6480e8abe2deSMatthew G. Knepley 6481e8abe2deSMatthew G. Knepley Input Parameters: 6482e8abe2deSMatthew G. Knepley + dm - The DM object 648346e270d4SMatthew G. Knepley . dim - The embedding dimension, or PETSC_DETERMINE 6484e8abe2deSMatthew G. Knepley - section - The PetscSection object 6485e8abe2deSMatthew G. Knepley 6486e8abe2deSMatthew G. Knepley Level: intermediate 6487e8abe2deSMatthew G. Knepley 648892fd8e1eSJed Brown .seealso: DMGetCoordinateSection(), DMGetLocalSection(), DMSetLocalSection() 6489e8abe2deSMatthew G. Knepley @*/ 649046e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateSection(DM dm, PetscInt dim, PetscSection section) 6491e8abe2deSMatthew G. Knepley { 6492e8abe2deSMatthew G. Knepley DM cdm; 6493e8abe2deSMatthew G. Knepley PetscErrorCode ierr; 6494e8abe2deSMatthew G. Knepley 6495e8abe2deSMatthew G. Knepley PetscFunctionBegin; 6496e8abe2deSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 649746e270d4SMatthew G. Knepley PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,3); 6498e8abe2deSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 649992fd8e1eSJed Brown ierr = DMSetLocalSection(cdm, section);CHKERRQ(ierr); 650046e270d4SMatthew G. Knepley if (dim == PETSC_DETERMINE) { 65014c1069a6SMatthew G. Knepley PetscInt d = PETSC_DEFAULT; 650246e270d4SMatthew G. Knepley PetscInt pStart, pEnd, vStart, vEnd, v, dd; 650346e270d4SMatthew G. Knepley 650446e270d4SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 650546e270d4SMatthew G. Knepley ierr = DMGetDimPoints(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 650646e270d4SMatthew G. Knepley pStart = PetscMax(vStart, pStart); 650746e270d4SMatthew G. Knepley pEnd = PetscMin(vEnd, pEnd); 650846e270d4SMatthew G. Knepley for (v = pStart; v < pEnd; ++v) { 650946e270d4SMatthew G. Knepley ierr = PetscSectionGetDof(section, v, &dd);CHKERRQ(ierr); 651046e270d4SMatthew G. Knepley if (dd) {d = dd; break;} 651146e270d4SMatthew G. Knepley } 6512ebfe4b0dSMatthew G. Knepley if (d >= 0) {ierr = DMSetCoordinateDim(dm, d);CHKERRQ(ierr);} 651346e270d4SMatthew G. Knepley } 6514e8abe2deSMatthew G. Knepley PetscFunctionReturn(0); 6515e8abe2deSMatthew G. Knepley } 6516e8abe2deSMatthew G. Knepley 6517d864a3eaSLisandro Dalcin /*@ 6518d864a3eaSLisandro Dalcin DMProjectCoordinates - Project coordinates to a different space 6519d864a3eaSLisandro Dalcin 6520d864a3eaSLisandro Dalcin Input Parameters: 6521d864a3eaSLisandro Dalcin + dm - The DM object 6522d864a3eaSLisandro Dalcin - disc - The new coordinate discretization 6523d864a3eaSLisandro Dalcin 6524d864a3eaSLisandro Dalcin Level: intermediate 6525d864a3eaSLisandro Dalcin 6526d864a3eaSLisandro Dalcin .seealso: DMGetCoordinateField() 6527d864a3eaSLisandro Dalcin @*/ 6528d864a3eaSLisandro Dalcin PetscErrorCode DMProjectCoordinates(DM dm, PetscFE disc) 6529d864a3eaSLisandro Dalcin { 6530d864a3eaSLisandro Dalcin PetscObject discOld; 6531d864a3eaSLisandro Dalcin PetscClassId classid; 6532d864a3eaSLisandro Dalcin DM cdmOld,cdmNew; 6533d864a3eaSLisandro Dalcin Vec coordsOld,coordsNew; 6534d864a3eaSLisandro Dalcin Mat matInterp; 6535d864a3eaSLisandro Dalcin PetscErrorCode ierr; 6536d864a3eaSLisandro Dalcin 6537d864a3eaSLisandro Dalcin PetscFunctionBegin; 6538d864a3eaSLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6539d864a3eaSLisandro Dalcin PetscValidHeaderSpecific(disc,PETSCFE_CLASSID,2); 6540d864a3eaSLisandro Dalcin 6541d864a3eaSLisandro Dalcin ierr = DMGetCoordinateDM(dm, &cdmOld);CHKERRQ(ierr); 6542d864a3eaSLisandro Dalcin /* Check current discretization is compatible */ 6543d864a3eaSLisandro Dalcin ierr = DMGetField(cdmOld, 0, NULL, &discOld);CHKERRQ(ierr); 6544d864a3eaSLisandro Dalcin ierr = PetscObjectGetClassId(discOld, &classid);CHKERRQ(ierr); 654529ad44c5SMatthew G. Knepley if (classid != PETSCFE_CLASSID) { 654629ad44c5SMatthew G. Knepley if (classid == PETSC_CONTAINER_CLASSID) { 654729ad44c5SMatthew G. Knepley PetscFE feLinear; 654829ad44c5SMatthew G. Knepley DMPolytopeType ct; 654929ad44c5SMatthew G. Knepley PetscInt dim, dE, cStart; 655029ad44c5SMatthew G. Knepley PetscBool simplex; 655129ad44c5SMatthew G. Knepley 655229ad44c5SMatthew G. Knepley /* Assume linear vertex coordinates */ 655329ad44c5SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 655429ad44c5SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 655529ad44c5SMatthew G. Knepley ierr = DMPlexGetHeightStratum(cdmOld, 0, &cStart, NULL);CHKERRQ(ierr); 655629ad44c5SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 655729ad44c5SMatthew G. Knepley switch (ct) { 655829ad44c5SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 655929ad44c5SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 656029ad44c5SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot autoamtically create coordinate space for prisms"); 656129ad44c5SMatthew G. Knepley default: break; 656229ad44c5SMatthew G. Knepley } 656329ad44c5SMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 656429ad44c5SMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, dE, simplex, 1, -1, &feLinear);CHKERRQ(ierr); 656529ad44c5SMatthew G. Knepley ierr = DMSetField(cdmOld, 0, NULL, (PetscObject) feLinear);CHKERRQ(ierr); 656629ad44c5SMatthew G. Knepley ierr = PetscFEDestroy(&feLinear);CHKERRQ(ierr); 656729ad44c5SMatthew G. Knepley ierr = DMCreateDS(cdmOld);CHKERRQ(ierr); 656829ad44c5SMatthew G. Knepley } else { 656929ad44c5SMatthew G. Knepley const char *discname; 657029ad44c5SMatthew G. Knepley 657129ad44c5SMatthew G. Knepley ierr = PetscObjectGetType(discOld, &discname);CHKERRQ(ierr); 657229ad44c5SMatthew G. Knepley SETERRQ1(PetscObjectComm(discOld), PETSC_ERR_SUP, "Discretization type %s not supported", discname); 657329ad44c5SMatthew G. Knepley } 657429ad44c5SMatthew G. Knepley } 6575d864a3eaSLisandro Dalcin /* Make a fresh clone of the coordinate DM */ 6576d864a3eaSLisandro Dalcin ierr = DMClone(cdmOld, &cdmNew);CHKERRQ(ierr); 6577d864a3eaSLisandro Dalcin ierr = DMSetField(cdmNew, 0, NULL, (PetscObject) disc);CHKERRQ(ierr); 6578d864a3eaSLisandro Dalcin ierr = DMCreateDS(cdmNew);CHKERRQ(ierr); 6579d864a3eaSLisandro Dalcin /* Project the coordinate vector from old to new space */ 6580d864a3eaSLisandro Dalcin ierr = DMGetCoordinates(dm, &coordsOld);CHKERRQ(ierr); 6581d864a3eaSLisandro Dalcin ierr = DMCreateGlobalVector(cdmNew, &coordsNew);CHKERRQ(ierr); 6582d864a3eaSLisandro Dalcin ierr = DMCreateInterpolation(cdmOld, cdmNew, &matInterp, NULL);CHKERRQ(ierr); 6583d864a3eaSLisandro Dalcin ierr = MatInterpolate(matInterp, coordsOld, coordsNew);CHKERRQ(ierr); 6584d864a3eaSLisandro Dalcin ierr = MatDestroy(&matInterp);CHKERRQ(ierr); 6585d864a3eaSLisandro Dalcin /* Set new coordinate structures */ 6586d864a3eaSLisandro Dalcin ierr = DMSetCoordinateField(dm, NULL);CHKERRQ(ierr); 6587d864a3eaSLisandro Dalcin ierr = DMSetCoordinateDM(dm, cdmNew);CHKERRQ(ierr); 6588d864a3eaSLisandro Dalcin ierr = DMSetCoordinates(dm, coordsNew);CHKERRQ(ierr); 6589d864a3eaSLisandro Dalcin ierr = VecDestroy(&coordsNew);CHKERRQ(ierr); 6590d864a3eaSLisandro Dalcin ierr = DMDestroy(&cdmNew);CHKERRQ(ierr); 6591d864a3eaSLisandro Dalcin PetscFunctionReturn(0); 6592d864a3eaSLisandro Dalcin } 6593d864a3eaSLisandro Dalcin 65945dc8c3f7SMatthew G. Knepley /*@C 659590b157c4SStefano Zampini DMGetPeriodicity - Get the description of mesh periodicity 65965dc8c3f7SMatthew G. Knepley 65975dc8c3f7SMatthew G. Knepley Input Parameters: 659890b157c4SStefano Zampini . dm - The DM object 659990b157c4SStefano Zampini 660090b157c4SStefano Zampini Output Parameters: 660190b157c4SStefano Zampini + per - Whether the DM is periodic or not 66025dc8c3f7SMatthew 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 66035dc8c3f7SMatthew G. Knepley . L - If we assume the mesh is a torus, this is the length of each coordinate 66045dc8c3f7SMatthew G. Knepley - bd - This describes the type of periodicity in each topological dimension 66055dc8c3f7SMatthew G. Knepley 66065dc8c3f7SMatthew G. Knepley Level: developer 66075dc8c3f7SMatthew G. Knepley 66085dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity() 66095dc8c3f7SMatthew G. Knepley @*/ 661090b157c4SStefano Zampini PetscErrorCode DMGetPeriodicity(DM dm, PetscBool *per, const PetscReal **maxCell, const PetscReal **L, const DMBoundaryType **bd) 6611c6b900c6SMatthew G. Knepley { 6612c6b900c6SMatthew G. Knepley PetscFunctionBegin; 6613c6b900c6SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 661490b157c4SStefano Zampini if (per) *per = dm->periodic; 6615c6b900c6SMatthew G. Knepley if (L) *L = dm->L; 6616c6b900c6SMatthew G. Knepley if (maxCell) *maxCell = dm->maxCell; 66175dc8c3f7SMatthew G. Knepley if (bd) *bd = dm->bdtype; 6618c6b900c6SMatthew G. Knepley PetscFunctionReturn(0); 6619c6b900c6SMatthew G. Knepley } 6620c6b900c6SMatthew G. Knepley 66215dc8c3f7SMatthew G. Knepley /*@C 66225dc8c3f7SMatthew G. Knepley DMSetPeriodicity - Set the description of mesh periodicity 66235dc8c3f7SMatthew G. Knepley 66245dc8c3f7SMatthew G. Knepley Input Parameters: 66255dc8c3f7SMatthew G. Knepley + dm - The DM object 6626db2bf62eSStefano Zampini . per - Whether the DM is periodic or not. 6627db2bf62eSStefano 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. 66285dc8c3f7SMatthew G. Knepley . L - If we assume the mesh is a torus, this is the length of each coordinate 66295dc8c3f7SMatthew G. Knepley - bd - This describes the type of periodicity in each topological dimension 66305dc8c3f7SMatthew G. Knepley 6631db2bf62eSStefano 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. 6632db2bf62eSStefano Zampini 66335dc8c3f7SMatthew G. Knepley Level: developer 66345dc8c3f7SMatthew G. Knepley 66355dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity() 66365dc8c3f7SMatthew G. Knepley @*/ 663790b157c4SStefano Zampini PetscErrorCode DMSetPeriodicity(DM dm, PetscBool per, const PetscReal maxCell[], const PetscReal L[], const DMBoundaryType bd[]) 6638c6b900c6SMatthew G. Knepley { 6639c6b900c6SMatthew G. Knepley PetscInt dim, d; 6640c6b900c6SMatthew G. Knepley PetscErrorCode ierr; 6641c6b900c6SMatthew G. Knepley 6642c6b900c6SMatthew G. Knepley PetscFunctionBegin; 6643c6b900c6SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 664490b157c4SStefano Zampini PetscValidLogicalCollectiveBool(dm,per,2); 6645412e9a14SMatthew G. Knepley if (maxCell) {PetscValidRealPointer(maxCell,3);} 6646412e9a14SMatthew G. Knepley if (L) {PetscValidRealPointer(L,4);} 6647412e9a14SMatthew G. Knepley if (bd) {PetscValidPointer(bd,5);} 66485dc8c3f7SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 664990b157c4SStefano Zampini if (maxCell) { 6650412e9a14SMatthew G. Knepley if (!dm->maxCell) {ierr = PetscMalloc1(dim, &dm->maxCell);CHKERRQ(ierr);} 6651412e9a14SMatthew G. Knepley for (d = 0; d < dim; ++d) dm->maxCell[d] = maxCell[d]; 6652db2bf62eSStefano Zampini } else { /* remove maxCell information to disable automatic computation of localized vertices */ 6653db2bf62eSStefano Zampini ierr = PetscFree(dm->maxCell);CHKERRQ(ierr); 6654412e9a14SMatthew G. Knepley } 6655db2bf62eSStefano Zampini 6656412e9a14SMatthew G. Knepley if (L) { 6657412e9a14SMatthew G. Knepley if (!dm->L) {ierr = PetscMalloc1(dim, &dm->L);CHKERRQ(ierr);} 6658412e9a14SMatthew G. Knepley for (d = 0; d < dim; ++d) dm->L[d] = L[d]; 6659412e9a14SMatthew G. Knepley } 6660412e9a14SMatthew G. Knepley if (bd) { 6661412e9a14SMatthew G. Knepley if (!dm->bdtype) {ierr = PetscMalloc1(dim, &dm->bdtype);CHKERRQ(ierr);} 6662412e9a14SMatthew G. Knepley for (d = 0; d < dim; ++d) dm->bdtype[d] = bd[d]; 666390b157c4SStefano Zampini } 6664072d7d67SStefano Zampini dm->periodic = per; 6665c6b900c6SMatthew G. Knepley PetscFunctionReturn(0); 6666c6b900c6SMatthew G. Knepley } 6667c6b900c6SMatthew G. Knepley 66682e17dfb7SMatthew G. Knepley /*@ 66692e17dfb7SMatthew 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. 66702e17dfb7SMatthew G. Knepley 66712e17dfb7SMatthew G. Knepley Input Parameters: 66722e17dfb7SMatthew G. Knepley + dm - The DM 667365da65dcSMatthew G. Knepley . in - The input coordinate point (dim numbers) 667465da65dcSMatthew G. Knepley - endpoint - Include the endpoint L_i 66752e17dfb7SMatthew G. Knepley 66762e17dfb7SMatthew G. Knepley Output Parameter: 66772e17dfb7SMatthew G. Knepley . out - The localized coordinate point 66782e17dfb7SMatthew G. Knepley 66792e17dfb7SMatthew G. Knepley Level: developer 66802e17dfb7SMatthew G. Knepley 66812e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate() 66822e17dfb7SMatthew G. Knepley @*/ 668365da65dcSMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate(DM dm, const PetscScalar in[], PetscBool endpoint, PetscScalar out[]) 66842e17dfb7SMatthew G. Knepley { 66852e17dfb7SMatthew G. Knepley PetscInt dim, d; 66862e17dfb7SMatthew G. Knepley PetscErrorCode ierr; 66872e17dfb7SMatthew G. Knepley 66882e17dfb7SMatthew G. Knepley PetscFunctionBegin; 66892e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 66902e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 66912e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 66922e17dfb7SMatthew G. Knepley } else { 669365da65dcSMatthew G. Knepley if (endpoint) { 669465da65dcSMatthew G. Knepley for (d = 0; d < dim; ++d) { 6695da3333bfSMatthew 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)) { 6696da3333bfSMatthew G. Knepley out[d] = in[d] - dm->L[d]*(PetscFloorReal(PetscRealPart(in[d])/dm->L[d]) - 1); 669765da65dcSMatthew G. Knepley } else { 6698da3333bfSMatthew G. Knepley out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]); 669965da65dcSMatthew G. Knepley } 670065da65dcSMatthew G. Knepley } 670165da65dcSMatthew G. Knepley } else { 67022e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 67031118d4bcSLisandro Dalcin out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]); 67042e17dfb7SMatthew G. Knepley } 67052e17dfb7SMatthew G. Knepley } 670665da65dcSMatthew G. Knepley } 67072e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 67082e17dfb7SMatthew G. Knepley } 67092e17dfb7SMatthew G. Knepley 67102e17dfb7SMatthew G. Knepley /* 67112e17dfb7SMatthew 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. 67122e17dfb7SMatthew G. Knepley 67132e17dfb7SMatthew G. Knepley Input Parameters: 67142e17dfb7SMatthew G. Knepley + dm - The DM 67152e17dfb7SMatthew G. Knepley . dim - The spatial dimension 67162e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it 67172e17dfb7SMatthew G. Knepley - in - The input coordinate point (dim numbers) 67182e17dfb7SMatthew G. Knepley 67192e17dfb7SMatthew G. Knepley Output Parameter: 67202e17dfb7SMatthew G. Knepley . out - The localized coordinate point 67212e17dfb7SMatthew G. Knepley 67222e17dfb7SMatthew G. Knepley Level: developer 67232e17dfb7SMatthew G. Knepley 67242e17dfb7SMatthew 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 67252e17dfb7SMatthew G. Knepley 67262e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate() 67272e17dfb7SMatthew G. Knepley */ 67282e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[]) 67292e17dfb7SMatthew G. Knepley { 67302e17dfb7SMatthew G. Knepley PetscInt d; 67312e17dfb7SMatthew G. Knepley 67322e17dfb7SMatthew G. Knepley PetscFunctionBegin; 67332e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 67342e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 67352e17dfb7SMatthew G. Knepley } else { 67362e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 6737908eca10SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) { 67382e17dfb7SMatthew G. Knepley out[d] = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d]; 67392e17dfb7SMatthew G. Knepley } else { 67402e17dfb7SMatthew G. Knepley out[d] = in[d]; 67412e17dfb7SMatthew G. Knepley } 67422e17dfb7SMatthew G. Knepley } 67432e17dfb7SMatthew G. Knepley } 67442e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 67452e17dfb7SMatthew G. Knepley } 6746a5801f52SStefano Zampini 67472e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinateReal_Internal(DM dm, PetscInt dim, const PetscReal anchor[], const PetscReal in[], PetscReal out[]) 67482e17dfb7SMatthew G. Knepley { 67492e17dfb7SMatthew G. Knepley PetscInt d; 67502e17dfb7SMatthew G. Knepley 67512e17dfb7SMatthew G. Knepley PetscFunctionBegin; 67522e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 67532e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 67542e17dfb7SMatthew G. Knepley } else { 67552e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 6756908eca10SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsReal(anchor[d] - in[d]) > dm->maxCell[d])) { 67572e17dfb7SMatthew G. Knepley out[d] = anchor[d] > in[d] ? dm->L[d] + in[d] : in[d] - dm->L[d]; 67582e17dfb7SMatthew G. Knepley } else { 67592e17dfb7SMatthew G. Knepley out[d] = in[d]; 67602e17dfb7SMatthew G. Knepley } 67612e17dfb7SMatthew G. Knepley } 67622e17dfb7SMatthew G. Knepley } 67632e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 67642e17dfb7SMatthew G. Knepley } 67652e17dfb7SMatthew G. Knepley 67662e17dfb7SMatthew G. Knepley /* 67672e17dfb7SMatthew 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. 67682e17dfb7SMatthew G. Knepley 67692e17dfb7SMatthew G. Knepley Input Parameters: 67702e17dfb7SMatthew G. Knepley + dm - The DM 67712e17dfb7SMatthew G. Knepley . dim - The spatial dimension 67722e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it 67732e17dfb7SMatthew G. Knepley . in - The input coordinate delta (dim numbers) 67742e17dfb7SMatthew G. Knepley - out - The input coordinate point (dim numbers) 67752e17dfb7SMatthew G. Knepley 67762e17dfb7SMatthew G. Knepley Output Parameter: 67772e17dfb7SMatthew G. Knepley . out - The localized coordinate in + out 67782e17dfb7SMatthew G. Knepley 67792e17dfb7SMatthew G. Knepley Level: developer 67802e17dfb7SMatthew G. Knepley 67812e17dfb7SMatthew 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 67822e17dfb7SMatthew G. Knepley 67832e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeCoordinate() 67842e17dfb7SMatthew G. Knepley */ 67852e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeAddCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[]) 67862e17dfb7SMatthew G. Knepley { 67872e17dfb7SMatthew G. Knepley PetscInt d; 67882e17dfb7SMatthew G. Knepley 67892e17dfb7SMatthew G. Knepley PetscFunctionBegin; 67902e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 67912e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] += in[d]; 67922e17dfb7SMatthew G. Knepley } else { 67932e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 6794412e9a14SMatthew G. Knepley const PetscReal maxC = dm->maxCell[d]; 6795412e9a14SMatthew G. Knepley 6796412e9a14SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > maxC)) { 6797412e9a14SMatthew G. Knepley const PetscScalar newCoord = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d]; 6798412e9a14SMatthew G. Knepley 6799412e9a14SMatthew G. Knepley if (PetscAbsScalar(newCoord - anchor[d]) > maxC) 6800412e9a14SMatthew 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])); 6801412e9a14SMatthew G. Knepley out[d] += newCoord; 68022e17dfb7SMatthew G. Knepley } else { 68032e17dfb7SMatthew G. Knepley out[d] += in[d]; 68042e17dfb7SMatthew G. Knepley } 68052e17dfb7SMatthew G. Knepley } 68062e17dfb7SMatthew G. Knepley } 68072e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 68082e17dfb7SMatthew G. Knepley } 68092e17dfb7SMatthew G. Knepley 681036447a5eSToby Isaac /*@ 68118f700142SStefano Zampini DMGetCoordinatesLocalizedLocal - Check if the DM coordinates have been localized for cells on this process 68128f700142SStefano Zampini 68138f700142SStefano Zampini Not collective 681436447a5eSToby Isaac 681536447a5eSToby Isaac Input Parameter: 681636447a5eSToby Isaac . dm - The DM 681736447a5eSToby Isaac 681836447a5eSToby Isaac Output Parameter: 681936447a5eSToby Isaac areLocalized - True if localized 682036447a5eSToby Isaac 682136447a5eSToby Isaac Level: developer 682236447a5eSToby Isaac 68238f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMGetCoordinatesLocalized(), DMSetPeriodicity() 682436447a5eSToby Isaac @*/ 68258f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalizedLocal(DM dm,PetscBool *areLocalized) 682636447a5eSToby Isaac { 682736447a5eSToby Isaac DM cdm; 682836447a5eSToby Isaac PetscSection coordSection; 682946a3a80fSLisandro Dalcin PetscInt cStart, cEnd, sStart, sEnd, c, dof; 683046a3a80fSLisandro Dalcin PetscBool isPlex, alreadyLocalized; 683136447a5eSToby Isaac PetscErrorCode ierr; 683236447a5eSToby Isaac 683336447a5eSToby Isaac PetscFunctionBegin; 683436447a5eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6835534a8f05SLisandro Dalcin PetscValidBoolPointer(areLocalized, 2); 68368b09590cSToby Isaac *areLocalized = PETSC_FALSE; 683746a3a80fSLisandro Dalcin 683836447a5eSToby Isaac /* We need some generic way of refering to cells/vertices */ 683936447a5eSToby Isaac ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 684046a3a80fSLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isPlex);CHKERRQ(ierr); 68419f7230bfSMatthew G. Knepley if (!isPlex) PetscFunctionReturn(0); 684246a3a80fSLisandro Dalcin 68439f7230bfSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 684446a3a80fSLisandro Dalcin ierr = DMPlexGetHeightStratum(cdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 684536447a5eSToby Isaac ierr = PetscSectionGetChart(coordSection, &sStart, &sEnd);CHKERRQ(ierr); 684636447a5eSToby Isaac alreadyLocalized = PETSC_FALSE; 684746a3a80fSLisandro Dalcin for (c = cStart; c < cEnd; ++c) { 684846a3a80fSLisandro Dalcin if (c < sStart || c >= sEnd) continue; 684936447a5eSToby Isaac ierr = PetscSectionGetDof(coordSection, c, &dof);CHKERRQ(ierr); 685046a3a80fSLisandro Dalcin if (dof) { alreadyLocalized = PETSC_TRUE; break; } 685136447a5eSToby Isaac } 68528f700142SStefano Zampini *areLocalized = alreadyLocalized; 685336447a5eSToby Isaac PetscFunctionReturn(0); 685436447a5eSToby Isaac } 685536447a5eSToby Isaac 68568f700142SStefano Zampini /*@ 68578f700142SStefano Zampini DMGetCoordinatesLocalized - Check if the DM coordinates have been localized for cells 68588f700142SStefano Zampini 68598f700142SStefano Zampini Collective on dm 68608f700142SStefano Zampini 68618f700142SStefano Zampini Input Parameter: 68628f700142SStefano Zampini . dm - The DM 68638f700142SStefano Zampini 68648f700142SStefano Zampini Output Parameter: 68658f700142SStefano Zampini areLocalized - True if localized 68668f700142SStefano Zampini 68678f700142SStefano Zampini Level: developer 68688f700142SStefano Zampini 68698f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMSetPeriodicity(), DMGetCoordinatesLocalizedLocal() 68708f700142SStefano Zampini @*/ 68718f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalized(DM dm,PetscBool *areLocalized) 68728f700142SStefano Zampini { 68738f700142SStefano Zampini PetscBool localized; 68748f700142SStefano Zampini PetscErrorCode ierr; 68758f700142SStefano Zampini 68768f700142SStefano Zampini PetscFunctionBegin; 68778f700142SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6878534a8f05SLisandro Dalcin PetscValidBoolPointer(areLocalized, 2); 68798f700142SStefano Zampini ierr = DMGetCoordinatesLocalizedLocal(dm,&localized);CHKERRQ(ierr); 6880820f2d46SBarry Smith ierr = MPIU_Allreduce(&localized,areLocalized,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 68818f700142SStefano Zampini PetscFunctionReturn(0); 68828f700142SStefano Zampini } 688336447a5eSToby Isaac 68842e17dfb7SMatthew G. Knepley /*@ 6885492b8470SStefano Zampini DMLocalizeCoordinates - If a mesh is periodic, create local coordinates for cells having periodic faces 68862e17dfb7SMatthew G. Knepley 68878f700142SStefano Zampini Collective on dm 68888f700142SStefano Zampini 68892e17dfb7SMatthew G. Knepley Input Parameter: 68902e17dfb7SMatthew G. Knepley . dm - The DM 68912e17dfb7SMatthew G. Knepley 68922e17dfb7SMatthew G. Knepley Level: developer 68932e17dfb7SMatthew G. Knepley 68948f700142SStefano Zampini .seealso: DMSetPeriodicity(), DMLocalizeCoordinate(), DMLocalizeAddCoordinate() 68952e17dfb7SMatthew G. Knepley @*/ 68962e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinates(DM dm) 68972e17dfb7SMatthew G. Knepley { 68982e17dfb7SMatthew G. Knepley DM cdm; 68992e17dfb7SMatthew G. Knepley PetscSection coordSection, cSection; 69002e17dfb7SMatthew G. Knepley Vec coordinates, cVec; 69013e922f36SToby Isaac PetscScalar *coords, *coords2, *anchor, *localized; 69023e922f36SToby Isaac PetscInt Nc, vStart, vEnd, v, sStart, sEnd, newStart = PETSC_MAX_INT, newEnd = PETSC_MIN_INT, dof, d, off, off2, bs, coordSize; 6903e0ae35bbSToby Isaac PetscBool alreadyLocalized, alreadyLocalizedGlobal; 69043e922f36SToby Isaac PetscInt maxHeight = 0, h; 69053e922f36SToby Isaac PetscInt *pStart = NULL, *pEnd = NULL; 69062e17dfb7SMatthew G. Knepley PetscErrorCode ierr; 69072e17dfb7SMatthew G. Knepley 69082e17dfb7SMatthew G. Knepley PetscFunctionBegin; 69092e17dfb7SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 691092c9c85fSStefano Zampini if (!dm->periodic) PetscFunctionReturn(0); 6911f7cbd40bSStefano Zampini ierr = DMGetCoordinatesLocalized(dm, &alreadyLocalized);CHKERRQ(ierr); 6912f7cbd40bSStefano Zampini if (alreadyLocalized) PetscFunctionReturn(0); 6913f7cbd40bSStefano Zampini 69142e17dfb7SMatthew G. Knepley /* We need some generic way of refering to cells/vertices */ 69152e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 69162e17dfb7SMatthew G. Knepley { 69172e17dfb7SMatthew G. Knepley PetscBool isplex; 69182e17dfb7SMatthew G. Knepley 69192e17dfb7SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isplex);CHKERRQ(ierr); 69202e17dfb7SMatthew G. Knepley if (isplex) { 69212e17dfb7SMatthew G. Knepley ierr = DMPlexGetDepthStratum(cdm, 0, &vStart, &vEnd);CHKERRQ(ierr); 69223e922f36SToby Isaac ierr = DMPlexGetMaxProjectionHeight(cdm,&maxHeight);CHKERRQ(ierr); 692369291d52SBarry Smith ierr = DMGetWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 69243e922f36SToby Isaac pEnd = &pStart[maxHeight + 1]; 69253e922f36SToby Isaac newStart = vStart; 69263e922f36SToby Isaac newEnd = vEnd; 69273e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 69283e922f36SToby Isaac ierr = DMPlexGetHeightStratum(cdm, h, &pStart[h], &pEnd[h]);CHKERRQ(ierr); 69293e922f36SToby Isaac newStart = PetscMin(newStart,pStart[h]); 69303e922f36SToby Isaac newEnd = PetscMax(newEnd,pEnd[h]); 69313e922f36SToby Isaac } 69322e17dfb7SMatthew G. Knepley } else SETERRQ(PetscObjectComm((PetscObject) cdm), PETSC_ERR_ARG_WRONG, "Coordinate localization requires a DMPLEX coordinate DM"); 69332e17dfb7SMatthew G. Knepley } 69342e17dfb7SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 693543eeeb2dSStefano Zampini if (!coordinates) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Missing local coordinates vector"); 69362e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 69373e922f36SToby Isaac ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 6938e0ae35bbSToby Isaac ierr = PetscSectionGetChart(coordSection,&sStart,&sEnd);CHKERRQ(ierr); 69393e922f36SToby Isaac 69402e17dfb7SMatthew G. Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &cSection);CHKERRQ(ierr); 69412e17dfb7SMatthew G. Knepley ierr = PetscSectionSetNumFields(cSection, 1);CHKERRQ(ierr); 69422e17dfb7SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(coordSection, 0, &Nc);CHKERRQ(ierr); 69432e17dfb7SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(cSection, 0, Nc);CHKERRQ(ierr); 69443e922f36SToby Isaac ierr = PetscSectionSetChart(cSection, newStart, newEnd);CHKERRQ(ierr); 69453e922f36SToby Isaac 694669291d52SBarry Smith ierr = DMGetWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 69473e922f36SToby Isaac localized = &anchor[bs]; 69483e922f36SToby Isaac alreadyLocalized = alreadyLocalizedGlobal = PETSC_TRUE; 69493e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 69503e922f36SToby Isaac PetscInt cStart = pStart[h], cEnd = pEnd[h], c; 69513e922f36SToby Isaac 69523e922f36SToby Isaac for (c = cStart; c < cEnd; ++c) { 69533e922f36SToby Isaac PetscScalar *cellCoords = NULL; 69543e922f36SToby Isaac PetscInt b; 69553e922f36SToby Isaac 69563e922f36SToby Isaac if (c < sStart || c >= sEnd) alreadyLocalized = PETSC_FALSE; 69573e922f36SToby Isaac ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 69583e922f36SToby Isaac for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b]; 69593e922f36SToby Isaac for (d = 0; d < dof/bs; ++d) { 69603e922f36SToby Isaac ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], localized);CHKERRQ(ierr); 69613e922f36SToby Isaac for (b = 0; b < bs; b++) { 69623e922f36SToby Isaac if (cellCoords[d*bs + b] != localized[b]) break; 69633e922f36SToby Isaac } 69643e922f36SToby Isaac if (b < bs) break; 69653e922f36SToby Isaac } 69663e922f36SToby Isaac if (d < dof/bs) { 69673e922f36SToby Isaac if (c >= sStart && c < sEnd) { 69683e922f36SToby Isaac PetscInt cdof; 69693e922f36SToby Isaac 69703e922f36SToby Isaac ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 69713e922f36SToby Isaac if (cdof != dof) alreadyLocalized = PETSC_FALSE; 69723e922f36SToby Isaac } 69733e922f36SToby Isaac ierr = PetscSectionSetDof(cSection, c, dof);CHKERRQ(ierr); 69743e922f36SToby Isaac ierr = PetscSectionSetFieldDof(cSection, c, 0, dof);CHKERRQ(ierr); 69753e922f36SToby Isaac } 69763e922f36SToby Isaac ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 69773e922f36SToby Isaac } 69783e922f36SToby Isaac } 6979ffc4695bSBarry Smith ierr = MPI_Allreduce(&alreadyLocalized,&alreadyLocalizedGlobal,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 69803e922f36SToby Isaac if (alreadyLocalizedGlobal) { 698169291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 69823e922f36SToby Isaac ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr); 698369291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 69843e922f36SToby Isaac PetscFunctionReturn(0); 69853e922f36SToby Isaac } 69862e17dfb7SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 69872e17dfb7SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 69882e17dfb7SMatthew G. Knepley ierr = PetscSectionSetDof(cSection, v, dof);CHKERRQ(ierr); 69892e17dfb7SMatthew G. Knepley ierr = PetscSectionSetFieldDof(cSection, v, 0, dof);CHKERRQ(ierr); 69902e17dfb7SMatthew G. Knepley } 69912e17dfb7SMatthew G. Knepley ierr = PetscSectionSetUp(cSection);CHKERRQ(ierr); 69922e17dfb7SMatthew G. Knepley ierr = PetscSectionGetStorageSize(cSection, &coordSize);CHKERRQ(ierr); 6993c2be7e5eSLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &cVec);CHKERRQ(ierr); 69942e17dfb7SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject)cVec,"coordinates");CHKERRQ(ierr); 69952e17dfb7SMatthew G. Knepley ierr = VecSetBlockSize(cVec, bs);CHKERRQ(ierr); 69962e17dfb7SMatthew G. Knepley ierr = VecSetSizes(cVec, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 69972e17dfb7SMatthew G. Knepley ierr = VecSetType(cVec, VECSTANDARD);CHKERRQ(ierr); 6998c2be7e5eSLisandro Dalcin ierr = VecGetArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr); 69992e17dfb7SMatthew G. Knepley ierr = VecGetArray(cVec, &coords2);CHKERRQ(ierr); 70002e17dfb7SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 70012e17dfb7SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 70022e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 70032e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(cSection, v, &off2);CHKERRQ(ierr); 70042e17dfb7SMatthew G. Knepley for (d = 0; d < dof; ++d) coords2[off2+d] = coords[off+d]; 70052e17dfb7SMatthew G. Knepley } 70063e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 70073e922f36SToby Isaac PetscInt cStart = pStart[h], cEnd = pEnd[h], c; 70083e922f36SToby Isaac 70092e17dfb7SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 70102e17dfb7SMatthew G. Knepley PetscScalar *cellCoords = NULL; 70113e922f36SToby Isaac PetscInt b, cdof; 70122e17dfb7SMatthew G. Knepley 70133e922f36SToby Isaac ierr = PetscSectionGetDof(cSection,c,&cdof);CHKERRQ(ierr); 70143e922f36SToby Isaac if (!cdof) continue; 70152e17dfb7SMatthew G. Knepley ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 70162e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(cSection, c, &off2);CHKERRQ(ierr); 70172e17dfb7SMatthew G. Knepley for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b]; 70182e17dfb7SMatthew G. Knepley for (d = 0; d < dof/bs; ++d) {ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], &coords2[off2+d*bs]);CHKERRQ(ierr);} 70192e17dfb7SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 70202e17dfb7SMatthew G. Knepley } 70213e922f36SToby Isaac } 702269291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 702369291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 7024c2be7e5eSLisandro Dalcin ierr = VecRestoreArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr); 70252e17dfb7SMatthew G. Knepley ierr = VecRestoreArray(cVec, &coords2);CHKERRQ(ierr); 70262e17dfb7SMatthew G. Knepley ierr = DMSetCoordinateSection(dm, PETSC_DETERMINE, cSection);CHKERRQ(ierr); 70272e17dfb7SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, cVec);CHKERRQ(ierr); 70282e17dfb7SMatthew G. Knepley ierr = VecDestroy(&cVec);CHKERRQ(ierr); 70292e17dfb7SMatthew G. Knepley ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr); 70302e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 70312e17dfb7SMatthew G. Knepley } 70322e17dfb7SMatthew G. Knepley 7033e87bb0d3SMatthew G Knepley /*@ 70343a93e3b7SToby Isaac DMLocatePoints - Locate the points in v in the mesh and return a PetscSF of the containing cells 7035e87bb0d3SMatthew G Knepley 7036d083f849SBarry Smith Collective on v (see explanation below) 7037e87bb0d3SMatthew G Knepley 7038e87bb0d3SMatthew G Knepley Input Parameters: 7039e87bb0d3SMatthew G Knepley + dm - The DM 70403a93e3b7SToby Isaac . v - The Vec of points 704162a38674SMatthew G. Knepley . ltype - The type of point location, e.g. DM_POINTLOCATION_NONE or DM_POINTLOCATION_NEAREST 70423a93e3b7SToby Isaac - cells - Points to either NULL, or a PetscSF with guesses for which cells contain each point. 7043e87bb0d3SMatthew G Knepley 704461e3bb9bSMatthew G Knepley Output Parameter: 704562a38674SMatthew G. Knepley + v - The Vec of points, which now contains the nearest mesh points to the given points if DM_POINTLOCATION_NEAREST is used 704662a38674SMatthew G. Knepley - cells - The PetscSF containing the ranks and local indices of the containing points. 70473a93e3b7SToby Isaac 7048e87bb0d3SMatthew G Knepley 7049e87bb0d3SMatthew G Knepley Level: developer 705061e3bb9bSMatthew G Knepley 705162a38674SMatthew G. Knepley Notes: 70523a93e3b7SToby Isaac To do a search of the local cells of the mesh, v should have PETSC_COMM_SELF as its communicator. 705362a38674SMatthew G. Knepley To do a search of all the cells in the distributed mesh, v should have the same communicator as dm. 70543a93e3b7SToby Isaac 70553a93e3b7SToby Isaac If *cellSF is NULL on input, a PetscSF will be created. 705662a38674SMatthew G. Knepley If *cellSF is not NULL on input, it should point to an existing PetscSF, whose graph will be used as initial guesses. 70573a93e3b7SToby Isaac 70583a93e3b7SToby Isaac An array that maps each point to its containing cell can be obtained with 70593a93e3b7SToby Isaac 706062a38674SMatthew G. Knepley $ const PetscSFNode *cells; 706162a38674SMatthew G. Knepley $ PetscInt nFound; 7062a6216909SToby Isaac $ const PetscInt *found; 706362a38674SMatthew G. Knepley $ 7064a6216909SToby Isaac $ PetscSFGetGraph(cellSF,NULL,&nFound,&found,&cells); 70653a93e3b7SToby Isaac 70663a93e3b7SToby 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 70673a93e3b7SToby Isaac the index of the cell in its rank's local numbering. 70683a93e3b7SToby Isaac 706962a38674SMatthew G. Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMPointLocationType 707061e3bb9bSMatthew G Knepley @*/ 707162a38674SMatthew G. Knepley PetscErrorCode DMLocatePoints(DM dm, Vec v, DMPointLocationType ltype, PetscSF *cellSF) 7072e87bb0d3SMatthew G Knepley { 7073735aa83eSMatthew G Knepley PetscErrorCode ierr; 7074735aa83eSMatthew G Knepley 7075e87bb0d3SMatthew G Knepley PetscFunctionBegin; 7076e87bb0d3SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7077e87bb0d3SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,2); 7078e0fc9d1bSMatthew G. Knepley PetscValidPointer(cellSF,4); 70793a93e3b7SToby Isaac if (*cellSF) { 70803a93e3b7SToby Isaac PetscMPIInt result; 70813a93e3b7SToby Isaac 7082e0fc9d1bSMatthew G. Knepley PetscValidHeaderSpecific(*cellSF,PETSCSF_CLASSID,4); 7083ffc4695bSBarry Smith ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)v),PetscObjectComm((PetscObject)*cellSF),&result);CHKERRMPI(ierr); 70843a93e3b7SToby 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"); 7085e0fc9d1bSMatthew G. Knepley } else { 70863a93e3b7SToby Isaac ierr = PetscSFCreate(PetscObjectComm((PetscObject)v),cellSF);CHKERRQ(ierr); 70873a93e3b7SToby Isaac } 7088b9d85ea2SLisandro Dalcin if (!dm->ops->locatepoints) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Point location not available for this DM"); 708947a35634SPatrick Farrell ierr = PetscLogEventBegin(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr); 709062a38674SMatthew G. Knepley ierr = (*dm->ops->locatepoints)(dm,v,ltype,*cellSF);CHKERRQ(ierr); 709147a35634SPatrick Farrell ierr = PetscLogEventEnd(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr); 7092e87bb0d3SMatthew G Knepley PetscFunctionReturn(0); 7093e87bb0d3SMatthew G Knepley } 709414f150ffSMatthew G. Knepley 7095f4d763aaSMatthew G. Knepley /*@ 7096f4d763aaSMatthew G. Knepley DMGetOutputDM - Retrieve the DM associated with the layout for output 7097f4d763aaSMatthew G. Knepley 70988f700142SStefano Zampini Collective on dm 70998f700142SStefano Zampini 7100f4d763aaSMatthew G. Knepley Input Parameter: 7101f4d763aaSMatthew G. Knepley . dm - The original DM 7102f4d763aaSMatthew G. Knepley 7103f4d763aaSMatthew G. Knepley Output Parameter: 7104f4d763aaSMatthew G. Knepley . odm - The DM which provides the layout for output 7105f4d763aaSMatthew G. Knepley 7106f4d763aaSMatthew G. Knepley Level: intermediate 7107f4d763aaSMatthew G. Knepley 7108e87a4003SBarry Smith .seealso: VecView(), DMGetGlobalSection() 7109f4d763aaSMatthew G. Knepley @*/ 711014f150ffSMatthew G. Knepley PetscErrorCode DMGetOutputDM(DM dm, DM *odm) 711114f150ffSMatthew G. Knepley { 7112c26acbdeSMatthew G. Knepley PetscSection section; 71132d4e4a49SMatthew G. Knepley PetscBool hasConstraints, ghasConstraints; 711414f150ffSMatthew G. Knepley PetscErrorCode ierr; 711514f150ffSMatthew G. Knepley 711614f150ffSMatthew G. Knepley PetscFunctionBegin; 711714f150ffSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 711814f150ffSMatthew G. Knepley PetscValidPointer(odm,2); 711992fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 7120c26acbdeSMatthew G. Knepley ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr); 7121ffc4695bSBarry Smith ierr = MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 71222d4e4a49SMatthew G. Knepley if (!ghasConstraints) { 7123c26acbdeSMatthew G. Knepley *odm = dm; 7124c26acbdeSMatthew G. Knepley PetscFunctionReturn(0); 7125c26acbdeSMatthew G. Knepley } 712614f150ffSMatthew G. Knepley if (!dm->dmBC) { 7127c26acbdeSMatthew G. Knepley PetscSection newSection, gsection; 712814f150ffSMatthew G. Knepley PetscSF sf; 712914f150ffSMatthew G. Knepley 713014f150ffSMatthew G. Knepley ierr = DMClone(dm, &dm->dmBC);CHKERRQ(ierr); 7131e5e52638SMatthew G. Knepley ierr = DMCopyDisc(dm, dm->dmBC);CHKERRQ(ierr); 713214f150ffSMatthew G. Knepley ierr = PetscSectionClone(section, &newSection);CHKERRQ(ierr); 713392fd8e1eSJed Brown ierr = DMSetLocalSection(dm->dmBC, newSection);CHKERRQ(ierr); 713414f150ffSMatthew G. Knepley ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr); 713514f150ffSMatthew G. Knepley ierr = DMGetPointSF(dm->dmBC, &sf);CHKERRQ(ierr); 713615b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr); 7137e87a4003SBarry Smith ierr = DMSetGlobalSection(dm->dmBC, gsection);CHKERRQ(ierr); 713814f150ffSMatthew G. Knepley ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr); 713914f150ffSMatthew G. Knepley } 714014f150ffSMatthew G. Knepley *odm = dm->dmBC; 714114f150ffSMatthew G. Knepley PetscFunctionReturn(0); 714214f150ffSMatthew G. Knepley } 7143f4d763aaSMatthew G. Knepley 7144f4d763aaSMatthew G. Knepley /*@ 7145cdb7a50dSMatthew G. Knepley DMGetOutputSequenceNumber - Retrieve the sequence number/value for output 7146f4d763aaSMatthew G. Knepley 7147f4d763aaSMatthew G. Knepley Input Parameter: 7148f4d763aaSMatthew G. Knepley . dm - The original DM 7149f4d763aaSMatthew G. Knepley 7150cdb7a50dSMatthew G. Knepley Output Parameters: 7151cdb7a50dSMatthew G. Knepley + num - The output sequence number 7152cdb7a50dSMatthew G. Knepley - val - The output sequence value 7153f4d763aaSMatthew G. Knepley 7154f4d763aaSMatthew G. Knepley Level: intermediate 7155f4d763aaSMatthew G. Knepley 7156f4d763aaSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 7157f4d763aaSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 7158f4d763aaSMatthew G. Knepley 7159f4d763aaSMatthew G. Knepley .seealso: VecView() 7160f4d763aaSMatthew G. Knepley @*/ 7161cdb7a50dSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val) 7162f4d763aaSMatthew G. Knepley { 7163f4d763aaSMatthew G. Knepley PetscFunctionBegin; 7164f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7165534a8f05SLisandro Dalcin if (num) {PetscValidIntPointer(num,2); *num = dm->outputSequenceNum;} 7166534a8f05SLisandro Dalcin if (val) {PetscValidRealPointer(val,3);*val = dm->outputSequenceVal;} 7167f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 7168f4d763aaSMatthew G. Knepley } 7169f4d763aaSMatthew G. Knepley 7170f4d763aaSMatthew G. Knepley /*@ 7171cdb7a50dSMatthew G. Knepley DMSetOutputSequenceNumber - Set the sequence number/value for output 7172f4d763aaSMatthew G. Knepley 7173f4d763aaSMatthew G. Knepley Input Parameters: 7174f4d763aaSMatthew G. Knepley + dm - The original DM 7175cdb7a50dSMatthew G. Knepley . num - The output sequence number 7176cdb7a50dSMatthew G. Knepley - val - The output sequence value 7177f4d763aaSMatthew G. Knepley 7178f4d763aaSMatthew G. Knepley Level: intermediate 7179f4d763aaSMatthew G. Knepley 7180f4d763aaSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 7181f4d763aaSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 7182f4d763aaSMatthew G. Knepley 7183f4d763aaSMatthew G. Knepley .seealso: VecView() 7184f4d763aaSMatthew G. Knepley @*/ 7185cdb7a50dSMatthew G. Knepley PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val) 7186f4d763aaSMatthew G. Knepley { 7187f4d763aaSMatthew G. Knepley PetscFunctionBegin; 7188f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7189f4d763aaSMatthew G. Knepley dm->outputSequenceNum = num; 7190cdb7a50dSMatthew G. Knepley dm->outputSequenceVal = val; 7191cdb7a50dSMatthew G. Knepley PetscFunctionReturn(0); 7192cdb7a50dSMatthew G. Knepley } 7193cdb7a50dSMatthew G. Knepley 7194cdb7a50dSMatthew G. Knepley /*@C 7195cdb7a50dSMatthew G. Knepley DMOutputSequenceLoad - Retrieve the sequence value from a Viewer 7196cdb7a50dSMatthew G. Knepley 7197cdb7a50dSMatthew G. Knepley Input Parameters: 7198cdb7a50dSMatthew G. Knepley + dm - The original DM 7199cdb7a50dSMatthew G. Knepley . name - The sequence name 7200cdb7a50dSMatthew G. Knepley - num - The output sequence number 7201cdb7a50dSMatthew G. Knepley 7202cdb7a50dSMatthew G. Knepley Output Parameter: 7203cdb7a50dSMatthew G. Knepley . val - The output sequence value 7204cdb7a50dSMatthew G. Knepley 7205cdb7a50dSMatthew G. Knepley Level: intermediate 7206cdb7a50dSMatthew G. Knepley 7207cdb7a50dSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 7208cdb7a50dSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 7209cdb7a50dSMatthew G. Knepley 7210cdb7a50dSMatthew G. Knepley .seealso: DMGetOutputSequenceNumber(), DMSetOutputSequenceNumber(), VecView() 7211cdb7a50dSMatthew G. Knepley @*/ 7212cdb7a50dSMatthew G. Knepley PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val) 7213cdb7a50dSMatthew G. Knepley { 7214cdb7a50dSMatthew G. Knepley PetscBool ishdf5; 7215cdb7a50dSMatthew G. Knepley PetscErrorCode ierr; 7216cdb7a50dSMatthew G. Knepley 7217cdb7a50dSMatthew G. Knepley PetscFunctionBegin; 7218cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7219cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 7220534a8f05SLisandro Dalcin PetscValidRealPointer(val,4); 7221cdb7a50dSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 7222cdb7a50dSMatthew G. Knepley if (ishdf5) { 7223cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 7224cdb7a50dSMatthew G. Knepley PetscScalar value; 7225cdb7a50dSMatthew G. Knepley 722639d25373SMatthew G. Knepley ierr = DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer);CHKERRQ(ierr); 72274aeb217fSMatthew G. Knepley *val = PetscRealPart(value); 7228cdb7a50dSMatthew G. Knepley #endif 7229cdb7a50dSMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()"); 7230f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 7231f4d763aaSMatthew G. Knepley } 72328e4ac7eaSMatthew G. Knepley 72338e4ac7eaSMatthew G. Knepley /*@ 72348e4ac7eaSMatthew G. Knepley DMGetUseNatural - Get the flag for creating a mapping to the natural order on distribution 72358e4ac7eaSMatthew G. Knepley 72368e4ac7eaSMatthew G. Knepley Not collective 72378e4ac7eaSMatthew G. Knepley 72388e4ac7eaSMatthew G. Knepley Input Parameter: 72398e4ac7eaSMatthew G. Knepley . dm - The DM 72408e4ac7eaSMatthew G. Knepley 72418e4ac7eaSMatthew G. Knepley Output Parameter: 72428e4ac7eaSMatthew G. Knepley . useNatural - The flag to build the mapping to a natural order during distribution 72438e4ac7eaSMatthew G. Knepley 72448e4ac7eaSMatthew G. Knepley Level: beginner 72458e4ac7eaSMatthew G. Knepley 72468e4ac7eaSMatthew G. Knepley .seealso: DMSetUseNatural(), DMCreate() 72478e4ac7eaSMatthew G. Knepley @*/ 72488e4ac7eaSMatthew G. Knepley PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural) 72498e4ac7eaSMatthew G. Knepley { 72508e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 72518e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7252534a8f05SLisandro Dalcin PetscValidBoolPointer(useNatural, 2); 72538e4ac7eaSMatthew G. Knepley *useNatural = dm->useNatural; 72548e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 72558e4ac7eaSMatthew G. Knepley } 72568e4ac7eaSMatthew G. Knepley 72578e4ac7eaSMatthew G. Knepley /*@ 72585d3b26e6SMatthew G. Knepley DMSetUseNatural - Set the flag for creating a mapping to the natural order after distribution 72598e4ac7eaSMatthew G. Knepley 72608e4ac7eaSMatthew G. Knepley Collective on dm 72618e4ac7eaSMatthew G. Knepley 72628e4ac7eaSMatthew G. Knepley Input Parameters: 72638e4ac7eaSMatthew G. Knepley + dm - The DM 72648e4ac7eaSMatthew G. Knepley - useNatural - The flag to build the mapping to a natural order during distribution 72658e4ac7eaSMatthew G. Knepley 72665d3b26e6SMatthew G. Knepley Note: This also causes the map to be build after DMCreateSubDM() and DMCreateSuperDM() 72675d3b26e6SMatthew G. Knepley 72688e4ac7eaSMatthew G. Knepley Level: beginner 72698e4ac7eaSMatthew G. Knepley 72705d3b26e6SMatthew G. Knepley .seealso: DMGetUseNatural(), DMCreate(), DMPlexDistribute(), DMCreateSubDM(), DMCreateSuperDM() 72718e4ac7eaSMatthew G. Knepley @*/ 72728e4ac7eaSMatthew G. Knepley PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural) 72738e4ac7eaSMatthew G. Knepley { 72748e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 72758e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72768833efb5SBlaise Bourdin PetscValidLogicalCollectiveBool(dm, useNatural, 2); 72778e4ac7eaSMatthew G. Knepley dm->useNatural = useNatural; 72788e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 72798e4ac7eaSMatthew G. Knepley } 7280c58f1c22SToby Isaac 7281c58f1c22SToby Isaac 7282c58f1c22SToby Isaac /*@C 7283c58f1c22SToby Isaac DMCreateLabel - Create a label of the given name if it does not already exist 7284c58f1c22SToby Isaac 7285c58f1c22SToby Isaac Not Collective 7286c58f1c22SToby Isaac 7287c58f1c22SToby Isaac Input Parameters: 7288c58f1c22SToby Isaac + dm - The DM object 7289c58f1c22SToby Isaac - name - The label name 7290c58f1c22SToby Isaac 7291c58f1c22SToby Isaac Level: intermediate 7292c58f1c22SToby Isaac 7293c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7294c58f1c22SToby Isaac @*/ 7295c58f1c22SToby Isaac PetscErrorCode DMCreateLabel(DM dm, const char name[]) 7296c58f1c22SToby Isaac { 72975d80c0bfSVaclav Hapla PetscBool flg; 72985d80c0bfSVaclav Hapla DMLabel label; 7299c58f1c22SToby Isaac PetscErrorCode ierr; 7300c58f1c22SToby Isaac 7301c58f1c22SToby Isaac PetscFunctionBegin; 7302c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7303c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 73045d80c0bfSVaclav Hapla ierr = DMHasLabel(dm, name, &flg);CHKERRQ(ierr); 7305c58f1c22SToby Isaac if (!flg) { 73065d80c0bfSVaclav Hapla ierr = DMLabelCreate(PETSC_COMM_SELF, name, &label);CHKERRQ(ierr); 73075d80c0bfSVaclav Hapla ierr = DMAddLabel(dm, label);CHKERRQ(ierr); 73085d80c0bfSVaclav Hapla ierr = DMLabelDestroy(&label);CHKERRQ(ierr); 7309c58f1c22SToby Isaac } 7310c58f1c22SToby Isaac PetscFunctionReturn(0); 7311c58f1c22SToby Isaac } 7312c58f1c22SToby Isaac 7313c58f1c22SToby Isaac /*@C 73140fdc7489SMatthew Knepley DMCreateLabelAtIndex - Create a label of the given name at the iven index. If it already exists, move it to this index. 73150fdc7489SMatthew Knepley 73160fdc7489SMatthew Knepley Not Collective 73170fdc7489SMatthew Knepley 73180fdc7489SMatthew Knepley Input Parameters: 73190fdc7489SMatthew Knepley + dm - The DM object 73200fdc7489SMatthew Knepley . l - The index for the label 73210fdc7489SMatthew Knepley - name - The label name 73220fdc7489SMatthew Knepley 73230fdc7489SMatthew Knepley Level: intermediate 73240fdc7489SMatthew Knepley 73250fdc7489SMatthew Knepley .seealso: DMCreateLabel(), DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 73260fdc7489SMatthew Knepley @*/ 73270fdc7489SMatthew Knepley PetscErrorCode DMCreateLabelAtIndex(DM dm, PetscInt l, const char name[]) 73280fdc7489SMatthew Knepley { 73290fdc7489SMatthew Knepley DMLabelLink orig, prev = NULL; 73300fdc7489SMatthew Knepley DMLabel label; 73310fdc7489SMatthew Knepley PetscInt Nl, m; 73320fdc7489SMatthew Knepley PetscBool flg, match; 73330fdc7489SMatthew Knepley const char *lname; 73340fdc7489SMatthew Knepley PetscErrorCode ierr; 73350fdc7489SMatthew Knepley 73360fdc7489SMatthew Knepley PetscFunctionBegin; 73370fdc7489SMatthew Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 73380fdc7489SMatthew Knepley PetscValidCharPointer(name, 2); 73390fdc7489SMatthew Knepley ierr = DMHasLabel(dm, name, &flg);CHKERRQ(ierr); 73400fdc7489SMatthew Knepley if (!flg) { 73410fdc7489SMatthew Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, name, &label);CHKERRQ(ierr); 73420fdc7489SMatthew Knepley ierr = DMAddLabel(dm, label);CHKERRQ(ierr); 73430fdc7489SMatthew Knepley ierr = DMLabelDestroy(&label);CHKERRQ(ierr); 73440fdc7489SMatthew Knepley } 73450fdc7489SMatthew Knepley ierr = DMGetNumLabels(dm, &Nl);CHKERRQ(ierr); 73460fdc7489SMatthew Knepley if (l >= Nl) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label index %D must be in [0, %D)", l, Nl); 73470fdc7489SMatthew Knepley for (m = 0, orig = dm->labels; m < Nl; ++m, prev = orig, orig = orig->next) { 73480fdc7489SMatthew Knepley ierr = PetscObjectGetName((PetscObject) orig->label, &lname);CHKERRQ(ierr); 73490fdc7489SMatthew Knepley ierr = PetscStrcmp(name, lname, &match);CHKERRQ(ierr); 73500fdc7489SMatthew Knepley if (match) break; 73510fdc7489SMatthew Knepley } 73520fdc7489SMatthew Knepley if (m == l) PetscFunctionReturn(0); 73530fdc7489SMatthew Knepley if (!m) dm->labels = orig->next; 73540fdc7489SMatthew Knepley else prev->next = orig->next; 73550fdc7489SMatthew Knepley if (!l) { 73560fdc7489SMatthew Knepley orig->next = dm->labels; 73570fdc7489SMatthew Knepley dm->labels = orig; 73580fdc7489SMatthew Knepley } else { 73590fdc7489SMatthew Knepley for (m = 0, prev = dm->labels; m < l-1; ++m, prev = prev->next); 73600fdc7489SMatthew Knepley orig->next = prev->next; 73610fdc7489SMatthew Knepley prev->next = orig; 73620fdc7489SMatthew Knepley } 73630fdc7489SMatthew Knepley PetscFunctionReturn(0); 73640fdc7489SMatthew Knepley } 73650fdc7489SMatthew Knepley 73660fdc7489SMatthew Knepley /*@C 7367c58f1c22SToby Isaac DMGetLabelValue - Get the value in a Sieve Label for the given point, with 0 as the default 7368c58f1c22SToby Isaac 7369c58f1c22SToby Isaac Not Collective 7370c58f1c22SToby Isaac 7371c58f1c22SToby Isaac Input Parameters: 7372c58f1c22SToby Isaac + dm - The DM object 7373c58f1c22SToby Isaac . name - The label name 7374c58f1c22SToby Isaac - point - The mesh point 7375c58f1c22SToby Isaac 7376c58f1c22SToby Isaac Output Parameter: 7377c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label 7378c58f1c22SToby Isaac 7379c58f1c22SToby Isaac Level: beginner 7380c58f1c22SToby Isaac 7381c58f1c22SToby Isaac .seealso: DMLabelGetValue(), DMSetLabelValue(), DMGetStratumIS() 7382c58f1c22SToby Isaac @*/ 7383c58f1c22SToby Isaac PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value) 7384c58f1c22SToby Isaac { 7385c58f1c22SToby Isaac DMLabel label; 7386c58f1c22SToby Isaac PetscErrorCode ierr; 7387c58f1c22SToby Isaac 7388c58f1c22SToby Isaac PetscFunctionBegin; 7389c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7390c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7391c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 739213903a91SSatish Balay if (!label) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name); 7393c58f1c22SToby Isaac ierr = DMLabelGetValue(label, point, value);CHKERRQ(ierr); 7394c58f1c22SToby Isaac PetscFunctionReturn(0); 7395c58f1c22SToby Isaac } 7396c58f1c22SToby Isaac 7397c58f1c22SToby Isaac /*@C 7398c58f1c22SToby Isaac DMSetLabelValue - Add a point to a Sieve Label with given value 7399c58f1c22SToby Isaac 7400c58f1c22SToby Isaac Not Collective 7401c58f1c22SToby Isaac 7402c58f1c22SToby Isaac Input Parameters: 7403c58f1c22SToby Isaac + dm - The DM object 7404c58f1c22SToby Isaac . name - The label name 7405c58f1c22SToby Isaac . point - The mesh point 7406c58f1c22SToby Isaac - value - The label value for this point 7407c58f1c22SToby Isaac 7408c58f1c22SToby Isaac Output Parameter: 7409c58f1c22SToby Isaac 7410c58f1c22SToby Isaac Level: beginner 7411c58f1c22SToby Isaac 7412c58f1c22SToby Isaac .seealso: DMLabelSetValue(), DMGetStratumIS(), DMClearLabelValue() 7413c58f1c22SToby Isaac @*/ 7414c58f1c22SToby Isaac PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 7415c58f1c22SToby Isaac { 7416c58f1c22SToby Isaac DMLabel label; 7417c58f1c22SToby Isaac PetscErrorCode ierr; 7418c58f1c22SToby Isaac 7419c58f1c22SToby Isaac PetscFunctionBegin; 7420c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7421c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7422c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7423c58f1c22SToby Isaac if (!label) { 7424c58f1c22SToby Isaac ierr = DMCreateLabel(dm, name);CHKERRQ(ierr); 7425c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7426c58f1c22SToby Isaac } 7427c58f1c22SToby Isaac ierr = DMLabelSetValue(label, point, value);CHKERRQ(ierr); 7428c58f1c22SToby Isaac PetscFunctionReturn(0); 7429c58f1c22SToby Isaac } 7430c58f1c22SToby Isaac 7431c58f1c22SToby Isaac /*@C 7432c58f1c22SToby Isaac DMClearLabelValue - Remove a point from a Sieve Label with given value 7433c58f1c22SToby Isaac 7434c58f1c22SToby Isaac Not Collective 7435c58f1c22SToby Isaac 7436c58f1c22SToby Isaac Input Parameters: 7437c58f1c22SToby Isaac + dm - The DM object 7438c58f1c22SToby Isaac . name - The label name 7439c58f1c22SToby Isaac . point - The mesh point 7440c58f1c22SToby Isaac - value - The label value for this point 7441c58f1c22SToby Isaac 7442c58f1c22SToby Isaac Output Parameter: 7443c58f1c22SToby Isaac 7444c58f1c22SToby Isaac Level: beginner 7445c58f1c22SToby Isaac 7446c58f1c22SToby Isaac .seealso: DMLabelClearValue(), DMSetLabelValue(), DMGetStratumIS() 7447c58f1c22SToby Isaac @*/ 7448c58f1c22SToby Isaac PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 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 ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7457c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7458c58f1c22SToby Isaac ierr = DMLabelClearValue(label, point, value);CHKERRQ(ierr); 7459c58f1c22SToby Isaac PetscFunctionReturn(0); 7460c58f1c22SToby Isaac } 7461c58f1c22SToby Isaac 7462c58f1c22SToby Isaac /*@C 7463c58f1c22SToby Isaac DMGetLabelSize - Get the number of different integer ids in a Label 7464c58f1c22SToby Isaac 7465c58f1c22SToby Isaac Not Collective 7466c58f1c22SToby Isaac 7467c58f1c22SToby Isaac Input Parameters: 7468c58f1c22SToby Isaac + dm - The DM object 7469c58f1c22SToby Isaac - name - The label name 7470c58f1c22SToby Isaac 7471c58f1c22SToby Isaac Output Parameter: 7472c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist 7473c58f1c22SToby Isaac 7474c58f1c22SToby Isaac Level: beginner 7475c58f1c22SToby Isaac 7476df813f42SMatthew G. Knepley .seealso: DMLabelGetNumValues(), DMSetLabelValue() 7477c58f1c22SToby Isaac @*/ 7478c58f1c22SToby Isaac PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size) 7479c58f1c22SToby Isaac { 7480c58f1c22SToby Isaac DMLabel label; 7481c58f1c22SToby Isaac PetscErrorCode ierr; 7482c58f1c22SToby Isaac 7483c58f1c22SToby Isaac PetscFunctionBegin; 7484c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7485c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7486534a8f05SLisandro Dalcin PetscValidIntPointer(size, 3); 7487c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7488c58f1c22SToby Isaac *size = 0; 7489c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7490c58f1c22SToby Isaac ierr = DMLabelGetNumValues(label, size);CHKERRQ(ierr); 7491c58f1c22SToby Isaac PetscFunctionReturn(0); 7492c58f1c22SToby Isaac } 7493c58f1c22SToby Isaac 7494c58f1c22SToby Isaac /*@C 7495c58f1c22SToby Isaac DMGetLabelIdIS - Get the integer ids in a label 7496c58f1c22SToby Isaac 7497c58f1c22SToby Isaac Not Collective 7498c58f1c22SToby Isaac 7499c58f1c22SToby Isaac Input Parameters: 7500c58f1c22SToby Isaac + mesh - The DM object 7501c58f1c22SToby Isaac - name - The label name 7502c58f1c22SToby Isaac 7503c58f1c22SToby Isaac Output Parameter: 7504c58f1c22SToby Isaac . ids - The integer ids, or NULL if the label does not exist 7505c58f1c22SToby Isaac 7506c58f1c22SToby Isaac Level: beginner 7507c58f1c22SToby Isaac 7508c58f1c22SToby Isaac .seealso: DMLabelGetValueIS(), DMGetLabelSize() 7509c58f1c22SToby Isaac @*/ 7510c58f1c22SToby Isaac PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids) 7511c58f1c22SToby Isaac { 7512c58f1c22SToby Isaac DMLabel label; 7513c58f1c22SToby Isaac PetscErrorCode ierr; 7514c58f1c22SToby Isaac 7515c58f1c22SToby Isaac PetscFunctionBegin; 7516c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7517c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7518c58f1c22SToby Isaac PetscValidPointer(ids, 3); 7519c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7520c58f1c22SToby Isaac *ids = NULL; 7521dab2e251SBlaise Bourdin if (label) { 7522c58f1c22SToby Isaac ierr = DMLabelGetValueIS(label, ids);CHKERRQ(ierr); 7523dab2e251SBlaise Bourdin } else { 7524dab2e251SBlaise Bourdin /* returning an empty IS */ 7525dab2e251SBlaise Bourdin ierr = ISCreateGeneral(PETSC_COMM_SELF,0,NULL,PETSC_USE_POINTER,ids);CHKERRQ(ierr); 7526dab2e251SBlaise Bourdin } 7527c58f1c22SToby Isaac PetscFunctionReturn(0); 7528c58f1c22SToby Isaac } 7529c58f1c22SToby Isaac 7530c58f1c22SToby Isaac /*@C 7531c58f1c22SToby Isaac DMGetStratumSize - Get the number of points in a label stratum 7532c58f1c22SToby Isaac 7533c58f1c22SToby Isaac Not Collective 7534c58f1c22SToby Isaac 7535c58f1c22SToby Isaac Input Parameters: 7536c58f1c22SToby Isaac + dm - The DM object 7537c58f1c22SToby Isaac . name - The label name 7538c58f1c22SToby Isaac - value - The stratum value 7539c58f1c22SToby Isaac 7540c58f1c22SToby Isaac Output Parameter: 7541c58f1c22SToby Isaac . size - The stratum size 7542c58f1c22SToby Isaac 7543c58f1c22SToby Isaac Level: beginner 7544c58f1c22SToby Isaac 7545c58f1c22SToby Isaac .seealso: DMLabelGetStratumSize(), DMGetLabelSize(), DMGetLabelIds() 7546c58f1c22SToby Isaac @*/ 7547c58f1c22SToby Isaac PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size) 7548c58f1c22SToby Isaac { 7549c58f1c22SToby Isaac DMLabel label; 7550c58f1c22SToby Isaac PetscErrorCode ierr; 7551c58f1c22SToby Isaac 7552c58f1c22SToby Isaac PetscFunctionBegin; 7553c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7554c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7555534a8f05SLisandro Dalcin PetscValidIntPointer(size, 4); 7556c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7557c58f1c22SToby Isaac *size = 0; 7558c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7559c58f1c22SToby Isaac ierr = DMLabelGetStratumSize(label, value, size);CHKERRQ(ierr); 7560c58f1c22SToby Isaac PetscFunctionReturn(0); 7561c58f1c22SToby Isaac } 7562c58f1c22SToby Isaac 7563c58f1c22SToby Isaac /*@C 7564c58f1c22SToby Isaac DMGetStratumIS - Get the points in a label stratum 7565c58f1c22SToby Isaac 7566c58f1c22SToby Isaac Not Collective 7567c58f1c22SToby Isaac 7568c58f1c22SToby Isaac Input Parameters: 7569c58f1c22SToby Isaac + dm - The DM object 7570c58f1c22SToby Isaac . name - The label name 7571c58f1c22SToby Isaac - value - The stratum value 7572c58f1c22SToby Isaac 7573c58f1c22SToby Isaac Output Parameter: 7574c58f1c22SToby Isaac . points - The stratum points, or NULL if the label does not exist or does not have that value 7575c58f1c22SToby Isaac 7576c58f1c22SToby Isaac Level: beginner 7577c58f1c22SToby Isaac 7578c58f1c22SToby Isaac .seealso: DMLabelGetStratumIS(), DMGetStratumSize() 7579c58f1c22SToby Isaac @*/ 7580c58f1c22SToby Isaac PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points) 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 PetscValidPointer(points, 4); 7589c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7590c58f1c22SToby Isaac *points = NULL; 7591c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7592c58f1c22SToby Isaac ierr = DMLabelGetStratumIS(label, value, points);CHKERRQ(ierr); 7593c58f1c22SToby Isaac PetscFunctionReturn(0); 7594c58f1c22SToby Isaac } 7595c58f1c22SToby Isaac 75964de306b1SToby Isaac /*@C 75979044fa66SMatthew G. Knepley DMSetStratumIS - Set the points in a label stratum 75984de306b1SToby Isaac 75994de306b1SToby Isaac Not Collective 76004de306b1SToby Isaac 76014de306b1SToby Isaac Input Parameters: 76024de306b1SToby Isaac + dm - The DM object 76034de306b1SToby Isaac . name - The label name 76044de306b1SToby Isaac . value - The stratum value 76054de306b1SToby Isaac - points - The stratum points 76064de306b1SToby Isaac 76074de306b1SToby Isaac Level: beginner 76084de306b1SToby Isaac 76094de306b1SToby Isaac .seealso: DMLabelSetStratumIS(), DMGetStratumSize() 76104de306b1SToby Isaac @*/ 76114de306b1SToby Isaac PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points) 76124de306b1SToby Isaac { 76134de306b1SToby Isaac DMLabel label; 76144de306b1SToby Isaac PetscErrorCode ierr; 76154de306b1SToby Isaac 76164de306b1SToby Isaac PetscFunctionBegin; 76174de306b1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 76184de306b1SToby Isaac PetscValidCharPointer(name, 2); 76194de306b1SToby Isaac PetscValidPointer(points, 4); 76204de306b1SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 76214de306b1SToby Isaac if (!label) PetscFunctionReturn(0); 76224de306b1SToby Isaac ierr = DMLabelSetStratumIS(label, value, points);CHKERRQ(ierr); 76234de306b1SToby Isaac PetscFunctionReturn(0); 76244de306b1SToby Isaac } 76254de306b1SToby Isaac 7626c58f1c22SToby Isaac /*@C 7627c58f1c22SToby Isaac DMClearLabelStratum - Remove all points from a stratum from a Sieve Label 7628c58f1c22SToby Isaac 7629c58f1c22SToby Isaac Not Collective 7630c58f1c22SToby Isaac 7631c58f1c22SToby Isaac Input Parameters: 7632c58f1c22SToby Isaac + dm - The DM object 7633c58f1c22SToby Isaac . name - The label name 7634c58f1c22SToby Isaac - value - The label value for this point 7635c58f1c22SToby Isaac 7636c58f1c22SToby Isaac Output Parameter: 7637c58f1c22SToby Isaac 7638c58f1c22SToby Isaac Level: beginner 7639c58f1c22SToby Isaac 7640c58f1c22SToby Isaac .seealso: DMLabelClearStratum(), DMSetLabelValue(), DMGetStratumIS(), DMClearLabelValue() 7641c58f1c22SToby Isaac @*/ 7642c58f1c22SToby Isaac PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value) 7643c58f1c22SToby Isaac { 7644c58f1c22SToby Isaac DMLabel label; 7645c58f1c22SToby Isaac PetscErrorCode ierr; 7646c58f1c22SToby Isaac 7647c58f1c22SToby Isaac PetscFunctionBegin; 7648c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7649c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7650c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7651c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7652c58f1c22SToby Isaac ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr); 7653c58f1c22SToby Isaac PetscFunctionReturn(0); 7654c58f1c22SToby Isaac } 7655c58f1c22SToby Isaac 7656c58f1c22SToby Isaac /*@ 7657c58f1c22SToby Isaac DMGetNumLabels - Return the number of labels defined by the mesh 7658c58f1c22SToby Isaac 7659c58f1c22SToby Isaac Not Collective 7660c58f1c22SToby Isaac 7661c58f1c22SToby Isaac Input Parameter: 7662c58f1c22SToby Isaac . dm - The DM object 7663c58f1c22SToby Isaac 7664c58f1c22SToby Isaac Output Parameter: 7665c58f1c22SToby Isaac . numLabels - the number of Labels 7666c58f1c22SToby Isaac 7667c58f1c22SToby Isaac Level: intermediate 7668c58f1c22SToby Isaac 7669c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7670c58f1c22SToby Isaac @*/ 7671c58f1c22SToby Isaac PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels) 7672c58f1c22SToby Isaac { 76735d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7674c58f1c22SToby Isaac PetscInt n = 0; 7675c58f1c22SToby Isaac 7676c58f1c22SToby Isaac PetscFunctionBegin; 7677c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7678534a8f05SLisandro Dalcin PetscValidIntPointer(numLabels, 2); 7679c58f1c22SToby Isaac while (next) {++n; next = next->next;} 7680c58f1c22SToby Isaac *numLabels = n; 7681c58f1c22SToby Isaac PetscFunctionReturn(0); 7682c58f1c22SToby Isaac } 7683c58f1c22SToby Isaac 7684c58f1c22SToby Isaac /*@C 7685c58f1c22SToby Isaac DMGetLabelName - Return the name of nth label 7686c58f1c22SToby Isaac 7687c58f1c22SToby Isaac Not Collective 7688c58f1c22SToby Isaac 7689c58f1c22SToby Isaac Input Parameters: 7690c58f1c22SToby Isaac + dm - The DM object 7691c58f1c22SToby Isaac - n - the label number 7692c58f1c22SToby Isaac 7693c58f1c22SToby Isaac Output Parameter: 7694c58f1c22SToby Isaac . name - the label name 7695c58f1c22SToby Isaac 7696c58f1c22SToby Isaac Level: intermediate 7697c58f1c22SToby Isaac 7698c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7699c58f1c22SToby Isaac @*/ 7700c58f1c22SToby Isaac PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name) 7701c58f1c22SToby Isaac { 77025d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7703c58f1c22SToby Isaac PetscInt l = 0; 7704d67d17b1SMatthew G. Knepley PetscErrorCode ierr; 7705c58f1c22SToby Isaac 7706c58f1c22SToby Isaac PetscFunctionBegin; 7707c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7708c58f1c22SToby Isaac PetscValidPointer(name, 3); 7709c58f1c22SToby Isaac while (next) { 7710c58f1c22SToby Isaac if (l == n) { 7711d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, name);CHKERRQ(ierr); 7712c58f1c22SToby Isaac PetscFunctionReturn(0); 7713c58f1c22SToby Isaac } 7714c58f1c22SToby Isaac ++l; 7715c58f1c22SToby Isaac next = next->next; 7716c58f1c22SToby Isaac } 7717c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n); 7718c58f1c22SToby Isaac } 7719c58f1c22SToby Isaac 7720c58f1c22SToby Isaac /*@C 7721c58f1c22SToby Isaac DMHasLabel - Determine whether the mesh has a label of a given name 7722c58f1c22SToby Isaac 7723c58f1c22SToby Isaac Not Collective 7724c58f1c22SToby Isaac 7725c58f1c22SToby Isaac Input Parameters: 7726c58f1c22SToby Isaac + dm - The DM object 7727c58f1c22SToby Isaac - name - The label name 7728c58f1c22SToby Isaac 7729c58f1c22SToby Isaac Output Parameter: 7730c58f1c22SToby Isaac . hasLabel - PETSC_TRUE if the label is present 7731c58f1c22SToby Isaac 7732c58f1c22SToby Isaac Level: intermediate 7733c58f1c22SToby Isaac 7734c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7735c58f1c22SToby Isaac @*/ 7736c58f1c22SToby Isaac PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel) 7737c58f1c22SToby Isaac { 77385d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7739d67d17b1SMatthew G. Knepley const char *lname; 7740c58f1c22SToby Isaac PetscErrorCode ierr; 7741c58f1c22SToby Isaac 7742c58f1c22SToby Isaac PetscFunctionBegin; 7743c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7744c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7745534a8f05SLisandro Dalcin PetscValidBoolPointer(hasLabel, 3); 7746c58f1c22SToby Isaac *hasLabel = PETSC_FALSE; 7747c58f1c22SToby Isaac while (next) { 7748d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 7749d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, hasLabel);CHKERRQ(ierr); 7750c58f1c22SToby Isaac if (*hasLabel) break; 7751c58f1c22SToby Isaac next = next->next; 7752c58f1c22SToby Isaac } 7753c58f1c22SToby Isaac PetscFunctionReturn(0); 7754c58f1c22SToby Isaac } 7755c58f1c22SToby Isaac 7756c58f1c22SToby Isaac /*@C 7757c58f1c22SToby Isaac DMGetLabel - Return the label of a given name, or NULL 7758c58f1c22SToby Isaac 7759c58f1c22SToby Isaac Not Collective 7760c58f1c22SToby Isaac 7761c58f1c22SToby Isaac Input Parameters: 7762c58f1c22SToby Isaac + dm - The DM object 7763c58f1c22SToby Isaac - name - The label name 7764c58f1c22SToby Isaac 7765c58f1c22SToby Isaac Output Parameter: 7766c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent 7767c58f1c22SToby Isaac 77686d7c9049SMatthew G. Knepley Note: Some of the default labels in a DMPlex will be 77696d7c9049SMatthew G. Knepley $ "depth" - Holds the depth (co-dimension) of each mesh point 77706d7c9049SMatthew G. Knepley $ "celltype" - Holds the topological type of each cell 77716d7c9049SMatthew G. Knepley $ "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 77726d7c9049SMatthew G. Knepley $ "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 77736d7c9049SMatthew G. Knepley $ "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 77746d7c9049SMatthew G. Knepley $ "Vertex Sets" - Mirrors the vertex sets defined by GMsh 77756d7c9049SMatthew G. Knepley 7776c58f1c22SToby Isaac Level: intermediate 7777c58f1c22SToby Isaac 77786d7c9049SMatthew G. Knepley .seealso: DMCreateLabel(), DMHasLabel(), DMPlexGetDepthLabel(), DMPlexGetCellType() 7779c58f1c22SToby Isaac @*/ 7780c58f1c22SToby Isaac PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label) 7781c58f1c22SToby Isaac { 77825d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7783c58f1c22SToby Isaac PetscBool hasLabel; 7784d67d17b1SMatthew G. Knepley const char *lname; 7785c58f1c22SToby Isaac PetscErrorCode ierr; 7786c58f1c22SToby Isaac 7787c58f1c22SToby Isaac PetscFunctionBegin; 7788c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7789c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7790c58f1c22SToby Isaac PetscValidPointer(label, 3); 7791c58f1c22SToby Isaac *label = NULL; 7792c58f1c22SToby Isaac while (next) { 7793d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 7794d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr); 7795c58f1c22SToby Isaac if (hasLabel) { 7796c58f1c22SToby Isaac *label = next->label; 7797c58f1c22SToby Isaac break; 7798c58f1c22SToby Isaac } 7799c58f1c22SToby Isaac next = next->next; 7800c58f1c22SToby Isaac } 7801c58f1c22SToby Isaac PetscFunctionReturn(0); 7802c58f1c22SToby Isaac } 7803c58f1c22SToby Isaac 7804c58f1c22SToby Isaac /*@C 7805c58f1c22SToby Isaac DMGetLabelByNum - Return the nth label 7806c58f1c22SToby Isaac 7807c58f1c22SToby Isaac Not Collective 7808c58f1c22SToby Isaac 7809c58f1c22SToby Isaac Input Parameters: 7810c58f1c22SToby Isaac + dm - The DM object 7811c58f1c22SToby Isaac - n - the label number 7812c58f1c22SToby Isaac 7813c58f1c22SToby Isaac Output Parameter: 7814c58f1c22SToby Isaac . label - the label 7815c58f1c22SToby Isaac 7816c58f1c22SToby Isaac Level: intermediate 7817c58f1c22SToby Isaac 7818c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7819c58f1c22SToby Isaac @*/ 7820c58f1c22SToby Isaac PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label) 7821c58f1c22SToby Isaac { 78225d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7823c58f1c22SToby Isaac PetscInt l = 0; 7824c58f1c22SToby Isaac 7825c58f1c22SToby Isaac PetscFunctionBegin; 7826c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7827c58f1c22SToby Isaac PetscValidPointer(label, 3); 7828c58f1c22SToby Isaac while (next) { 7829c58f1c22SToby Isaac if (l == n) { 7830c58f1c22SToby Isaac *label = next->label; 7831c58f1c22SToby Isaac PetscFunctionReturn(0); 7832c58f1c22SToby Isaac } 7833c58f1c22SToby Isaac ++l; 7834c58f1c22SToby Isaac next = next->next; 7835c58f1c22SToby Isaac } 7836c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n); 7837c58f1c22SToby Isaac } 7838c58f1c22SToby Isaac 7839c58f1c22SToby Isaac /*@C 7840c58f1c22SToby Isaac DMAddLabel - Add the label to this mesh 7841c58f1c22SToby Isaac 7842c58f1c22SToby Isaac Not Collective 7843c58f1c22SToby Isaac 7844c58f1c22SToby Isaac Input Parameters: 7845c58f1c22SToby Isaac + dm - The DM object 7846c58f1c22SToby Isaac - label - The DMLabel 7847c58f1c22SToby Isaac 7848c58f1c22SToby Isaac Level: developer 7849c58f1c22SToby Isaac 7850c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7851c58f1c22SToby Isaac @*/ 7852c58f1c22SToby Isaac PetscErrorCode DMAddLabel(DM dm, DMLabel label) 7853c58f1c22SToby Isaac { 78545d80c0bfSVaclav Hapla DMLabelLink l, *p, tmpLabel; 7855c58f1c22SToby Isaac PetscBool hasLabel; 7856d67d17b1SMatthew G. Knepley const char *lname; 78575d80c0bfSVaclav Hapla PetscBool flg; 7858c58f1c22SToby Isaac PetscErrorCode ierr; 7859c58f1c22SToby Isaac 7860c58f1c22SToby Isaac PetscFunctionBegin; 7861c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7862d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 7863d67d17b1SMatthew G. Knepley ierr = DMHasLabel(dm, lname, &hasLabel);CHKERRQ(ierr); 7864d67d17b1SMatthew G. Knepley if (hasLabel) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname); 7865c58f1c22SToby Isaac ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr); 7866c58f1c22SToby Isaac tmpLabel->label = label; 7867c58f1c22SToby Isaac tmpLabel->output = PETSC_TRUE; 78685d80c0bfSVaclav Hapla for (p=&dm->labels; (l=*p); p=&l->next) {} 78695d80c0bfSVaclav Hapla *p = tmpLabel; 787008f633c4SVaclav Hapla ierr = PetscObjectReference((PetscObject)label);CHKERRQ(ierr); 78715d80c0bfSVaclav Hapla ierr = PetscStrcmp(lname, "depth", &flg);CHKERRQ(ierr); 78725d80c0bfSVaclav Hapla if (flg) dm->depthLabel = label; 7873ba2698f1SMatthew G. Knepley ierr = PetscStrcmp(lname, "celltype", &flg);CHKERRQ(ierr); 7874ba2698f1SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 7875c58f1c22SToby Isaac PetscFunctionReturn(0); 7876c58f1c22SToby Isaac } 7877c58f1c22SToby Isaac 7878c58f1c22SToby Isaac /*@C 7879e5472504SVaclav Hapla DMRemoveLabel - Remove the label given by name from this mesh 7880c58f1c22SToby Isaac 7881c58f1c22SToby Isaac Not Collective 7882c58f1c22SToby Isaac 7883c58f1c22SToby Isaac Input Parameters: 7884c58f1c22SToby Isaac + dm - The DM object 7885c58f1c22SToby Isaac - name - The label name 7886c58f1c22SToby Isaac 7887c58f1c22SToby Isaac Output Parameter: 7888c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent 7889c58f1c22SToby Isaac 7890c58f1c22SToby Isaac Level: developer 7891c58f1c22SToby Isaac 7892e5472504SVaclav Hapla Notes: 7893e5472504SVaclav Hapla DMRemoveLabel(dm,name,NULL) removes the label from dm and calls 7894e5472504SVaclav Hapla DMLabelDestroy() on the label. 7895e5472504SVaclav Hapla 7896e5472504SVaclav Hapla DMRemoveLabel(dm,name,&label) removes the label from dm, but it DOES NOT 7897e5472504SVaclav Hapla call DMLabelDestroy(). Instead, the label is returned and the user is 7898e5472504SVaclav Hapla responsible of calling DMLabelDestroy() at some point. 7899e5472504SVaclav Hapla 7900e5472504SVaclav Hapla .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabel(), DMGetLabelValue(), DMSetLabelValue(), DMLabelDestroy(), DMRemoveLabelBySelf() 7901c58f1c22SToby Isaac @*/ 7902c58f1c22SToby Isaac PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label) 7903c58f1c22SToby Isaac { 790495d578d6SVaclav Hapla DMLabelLink link, *pnext; 7905c58f1c22SToby Isaac PetscBool hasLabel; 7906d67d17b1SMatthew G. Knepley const char *lname; 7907c58f1c22SToby Isaac PetscErrorCode ierr; 7908c58f1c22SToby Isaac 7909c58f1c22SToby Isaac PetscFunctionBegin; 7910c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7911e5472504SVaclav Hapla PetscValidCharPointer(name, 2); 7912e5472504SVaclav Hapla if (label) { 7913e5472504SVaclav Hapla PetscValidPointer(label, 3); 7914c58f1c22SToby Isaac *label = NULL; 7915e5472504SVaclav Hapla } 79165d80c0bfSVaclav Hapla for (pnext=&dm->labels; (link=*pnext); pnext=&link->next) { 791795d578d6SVaclav Hapla ierr = PetscObjectGetName((PetscObject) link->label, &lname);CHKERRQ(ierr); 7918d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr); 7919c58f1c22SToby Isaac if (hasLabel) { 792095d578d6SVaclav Hapla *pnext = link->next; /* Remove from list */ 7921c58f1c22SToby Isaac ierr = PetscStrcmp(name, "depth", &hasLabel);CHKERRQ(ierr); 792295d578d6SVaclav Hapla if (hasLabel) dm->depthLabel = NULL; 7923ba2698f1SMatthew G. Knepley ierr = PetscStrcmp(name, "celltype", &hasLabel);CHKERRQ(ierr); 7924ba2698f1SMatthew G. Knepley if (hasLabel) dm->celltypeLabel = NULL; 792595d578d6SVaclav Hapla if (label) *label = link->label; 792695d578d6SVaclav Hapla else {ierr = DMLabelDestroy(&link->label);CHKERRQ(ierr);} 792795d578d6SVaclav Hapla ierr = PetscFree(link);CHKERRQ(ierr); 7928c58f1c22SToby Isaac break; 7929c58f1c22SToby Isaac } 7930c58f1c22SToby Isaac } 7931c58f1c22SToby Isaac PetscFunctionReturn(0); 7932c58f1c22SToby Isaac } 7933c58f1c22SToby Isaac 7934306894acSVaclav Hapla /*@ 7935306894acSVaclav Hapla DMRemoveLabelBySelf - Remove the label from this mesh 7936306894acSVaclav Hapla 7937306894acSVaclav Hapla Not Collective 7938306894acSVaclav Hapla 7939306894acSVaclav Hapla Input Parameters: 7940306894acSVaclav Hapla + dm - The DM object 7941306894acSVaclav Hapla . label - (Optional) The DMLabel to be removed from the DM 7942306894acSVaclav Hapla - failNotFound - Should it fail if the label is not found in the DM? 7943306894acSVaclav Hapla 7944306894acSVaclav Hapla Level: developer 7945306894acSVaclav Hapla 7946306894acSVaclav Hapla Notes: 7947306894acSVaclav Hapla Only exactly the same instance is removed if found, name match is ignored. 7948306894acSVaclav Hapla If the DM has an exclusive reference to the label, it gets destroyed and 7949306894acSVaclav Hapla *label nullified. 7950306894acSVaclav Hapla 7951306894acSVaclav Hapla .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabel() DMGetLabelValue(), DMSetLabelValue(), DMLabelDestroy(), DMRemoveLabel() 7952306894acSVaclav Hapla @*/ 7953306894acSVaclav Hapla PetscErrorCode DMRemoveLabelBySelf(DM dm, DMLabel *label, PetscBool failNotFound) 7954306894acSVaclav Hapla { 795543e45a93SVaclav Hapla DMLabelLink link, *pnext; 7956306894acSVaclav Hapla PetscBool hasLabel = PETSC_FALSE; 7957306894acSVaclav Hapla PetscErrorCode ierr; 7958306894acSVaclav Hapla 7959306894acSVaclav Hapla PetscFunctionBegin; 7960306894acSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7961306894acSVaclav Hapla PetscValidPointer(label, 2); 7962f39a9ae0SVaclav Hapla if (!*label && !failNotFound) PetscFunctionReturn(0); 7963306894acSVaclav Hapla PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 2); 7964306894acSVaclav Hapla PetscValidLogicalCollectiveBool(dm,failNotFound,3); 79655d80c0bfSVaclav Hapla for (pnext=&dm->labels; (link=*pnext); pnext=&link->next) { 796643e45a93SVaclav Hapla if (*label == link->label) { 7967306894acSVaclav Hapla hasLabel = PETSC_TRUE; 796843e45a93SVaclav Hapla *pnext = link->next; /* Remove from list */ 7969306894acSVaclav Hapla if (*label == dm->depthLabel) dm->depthLabel = NULL; 7970ba2698f1SMatthew G. Knepley if (*label == dm->celltypeLabel) dm->celltypeLabel = NULL; 797143e45a93SVaclav Hapla if (((PetscObject) link->label)->refct < 2) *label = NULL; /* nullify if exclusive reference */ 797243e45a93SVaclav Hapla ierr = DMLabelDestroy(&link->label);CHKERRQ(ierr); 797343e45a93SVaclav Hapla ierr = PetscFree(link);CHKERRQ(ierr); 7974306894acSVaclav Hapla break; 7975306894acSVaclav Hapla } 7976306894acSVaclav Hapla } 7977306894acSVaclav Hapla if (!hasLabel && failNotFound) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Given label not found in DM"); 7978306894acSVaclav Hapla PetscFunctionReturn(0); 7979306894acSVaclav Hapla } 7980306894acSVaclav Hapla 7981c58f1c22SToby Isaac /*@C 7982c58f1c22SToby Isaac DMGetLabelOutput - Get the output flag for a given label 7983c58f1c22SToby Isaac 7984c58f1c22SToby Isaac Not Collective 7985c58f1c22SToby Isaac 7986c58f1c22SToby Isaac Input Parameters: 7987c58f1c22SToby Isaac + dm - The DM object 7988c58f1c22SToby Isaac - name - The label name 7989c58f1c22SToby Isaac 7990c58f1c22SToby Isaac Output Parameter: 7991c58f1c22SToby Isaac . output - The flag for output 7992c58f1c22SToby Isaac 7993c58f1c22SToby Isaac Level: developer 7994c58f1c22SToby Isaac 7995c58f1c22SToby Isaac .seealso: DMSetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7996c58f1c22SToby Isaac @*/ 7997c58f1c22SToby Isaac PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output) 7998c58f1c22SToby Isaac { 79995d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 8000d67d17b1SMatthew G. Knepley const char *lname; 8001c58f1c22SToby Isaac PetscErrorCode ierr; 8002c58f1c22SToby Isaac 8003c58f1c22SToby Isaac PetscFunctionBegin; 8004c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8005c58f1c22SToby Isaac PetscValidPointer(name, 2); 8006c58f1c22SToby Isaac PetscValidPointer(output, 3); 8007c58f1c22SToby Isaac while (next) { 8008c58f1c22SToby Isaac PetscBool flg; 8009c58f1c22SToby Isaac 8010d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 8011d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr); 8012c58f1c22SToby Isaac if (flg) {*output = next->output; PetscFunctionReturn(0);} 8013c58f1c22SToby Isaac next = next->next; 8014c58f1c22SToby Isaac } 8015c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 8016c58f1c22SToby Isaac } 8017c58f1c22SToby Isaac 8018c58f1c22SToby Isaac /*@C 8019c58f1c22SToby Isaac DMSetLabelOutput - Set the output flag for a given label 8020c58f1c22SToby Isaac 8021c58f1c22SToby Isaac Not Collective 8022c58f1c22SToby Isaac 8023c58f1c22SToby Isaac Input Parameters: 8024c58f1c22SToby Isaac + dm - The DM object 8025c58f1c22SToby Isaac . name - The label name 8026c58f1c22SToby Isaac - output - The flag for output 8027c58f1c22SToby Isaac 8028c58f1c22SToby Isaac Level: developer 8029c58f1c22SToby Isaac 8030c58f1c22SToby Isaac .seealso: DMGetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 8031c58f1c22SToby Isaac @*/ 8032c58f1c22SToby Isaac PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output) 8033c58f1c22SToby Isaac { 80345d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 8035d67d17b1SMatthew G. Knepley const char *lname; 8036c58f1c22SToby Isaac PetscErrorCode ierr; 8037c58f1c22SToby Isaac 8038c58f1c22SToby Isaac PetscFunctionBegin; 8039c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8040534a8f05SLisandro Dalcin PetscValidCharPointer(name, 2); 8041c58f1c22SToby Isaac while (next) { 8042c58f1c22SToby Isaac PetscBool flg; 8043c58f1c22SToby Isaac 8044d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 8045d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr); 8046c58f1c22SToby Isaac if (flg) {next->output = output; PetscFunctionReturn(0);} 8047c58f1c22SToby Isaac next = next->next; 8048c58f1c22SToby Isaac } 8049c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 8050c58f1c22SToby Isaac } 8051c58f1c22SToby Isaac 8052c58f1c22SToby Isaac /*@ 8053c58f1c22SToby Isaac DMCopyLabels - Copy labels from one mesh to another with a superset of the points 8054c58f1c22SToby Isaac 8055d083f849SBarry Smith Collective on dmA 8056c58f1c22SToby Isaac 8057c58f1c22SToby Isaac Input Parameter: 80585d80c0bfSVaclav Hapla + dmA - The DM object with initial labels 80592e17dfb7SMatthew G. Knepley . dmB - The DM object with copied labels 80605d80c0bfSVaclav Hapla . mode - Copy labels by pointers (PETSC_OWN_POINTER) or duplicate them (PETSC_COPY_VALUES) 8061ba2698f1SMatthew G. Knepley - all - Copy all labels including "depth", "dim", and "celltype" (PETSC_TRUE) which are otherwise ignored (PETSC_FALSE) 8062c58f1c22SToby Isaac 8063c58f1c22SToby Isaac Level: intermediate 8064c58f1c22SToby Isaac 8065c58f1c22SToby Isaac Note: This is typically used when interpolating or otherwise adding to a mesh 8066c58f1c22SToby Isaac 80675d80c0bfSVaclav Hapla .seealso: DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMGetCoordinateSection(), DMShareLabels() 8068c58f1c22SToby Isaac @*/ 80695d80c0bfSVaclav Hapla PetscErrorCode DMCopyLabels(DM dmA, DM dmB, PetscCopyMode mode, PetscBool all) 8070c58f1c22SToby Isaac { 8071c58f1c22SToby Isaac DMLabel label, labelNew; 8072c58f1c22SToby Isaac const char *name; 8073c58f1c22SToby Isaac PetscBool flg; 80745d80c0bfSVaclav Hapla DMLabelLink link; 80755d80c0bfSVaclav Hapla PetscErrorCode ierr; 8076c58f1c22SToby Isaac 80775d80c0bfSVaclav Hapla PetscFunctionBegin; 80785d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 80795d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 80805d80c0bfSVaclav Hapla PetscValidLogicalCollectiveEnum(dmA, mode,3); 80815d80c0bfSVaclav Hapla PetscValidLogicalCollectiveBool(dmA, all, 4); 80825d80c0bfSVaclav Hapla if (mode==PETSC_USE_POINTER) SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_SUP, "PETSC_USE_POINTER not supported for objects"); 80835d80c0bfSVaclav Hapla if (dmA == dmB) PetscFunctionReturn(0); 80845d80c0bfSVaclav Hapla for (link=dmA->labels; link; link=link->next) { 80855d80c0bfSVaclav Hapla label=link->label; 80865d80c0bfSVaclav Hapla ierr = PetscObjectGetName((PetscObject)label, &name);CHKERRQ(ierr); 80875d80c0bfSVaclav Hapla if (!all) { 8088c58f1c22SToby Isaac ierr = PetscStrcmp(name, "depth", &flg);CHKERRQ(ierr); 8089c58f1c22SToby Isaac if (flg) continue; 80907d5acc75SStefano Zampini ierr = PetscStrcmp(name, "dim", &flg);CHKERRQ(ierr); 80917d5acc75SStefano Zampini if (flg) continue; 8092ba2698f1SMatthew G. Knepley ierr = PetscStrcmp(name, "celltype", &flg);CHKERRQ(ierr); 8093ba2698f1SMatthew G. Knepley if (flg) continue; 80945d80c0bfSVaclav Hapla } 80955d80c0bfSVaclav Hapla if (mode==PETSC_COPY_VALUES) { 8096c58f1c22SToby Isaac ierr = DMLabelDuplicate(label, &labelNew);CHKERRQ(ierr); 80975d80c0bfSVaclav Hapla } else { 80985d80c0bfSVaclav Hapla labelNew = label; 80995d80c0bfSVaclav Hapla } 8100c58f1c22SToby Isaac ierr = DMAddLabel(dmB, labelNew);CHKERRQ(ierr); 81015d80c0bfSVaclav Hapla if (mode==PETSC_COPY_VALUES) {ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr);} 8102c58f1c22SToby Isaac } 8103c58f1c22SToby Isaac PetscFunctionReturn(0); 8104c58f1c22SToby Isaac } 81050fdc7489SMatthew Knepley /* 81060fdc7489SMatthew Knepley Many mesh programs, such as Triangle and TetGen, allow only a single label for each mesh point. Therefore, we would 81070fdc7489SMatthew Knepley like to encode all label IDs using a single, universal label. We can do this by assigning an integer to every 81080fdc7489SMatthew Knepley (label, id) pair in the DM. 81090fdc7489SMatthew Knepley 81100fdc7489SMatthew Knepley However, a mesh point can have multiple labels, so we must separate all these values. We will assign a bit range to 81110fdc7489SMatthew Knepley each label. 81120fdc7489SMatthew Knepley */ 81130fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelCreate(DM dm, DMUniversalLabel *universal) 81140fdc7489SMatthew Knepley { 81150fdc7489SMatthew Knepley DMUniversalLabel ul; 81160fdc7489SMatthew Knepley PetscBool *active; 81170fdc7489SMatthew Knepley PetscInt pStart, pEnd, p, Nl, l, m; 81180fdc7489SMatthew Knepley PetscErrorCode ierr; 81190fdc7489SMatthew Knepley 81200fdc7489SMatthew Knepley PetscFunctionBegin; 81210fdc7489SMatthew Knepley ierr = PetscMalloc1(1, &ul);CHKERRQ(ierr); 81220fdc7489SMatthew Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, "universal", &ul->label);CHKERRQ(ierr); 81230fdc7489SMatthew Knepley ierr = DMGetNumLabels(dm, &Nl);CHKERRQ(ierr); 81240fdc7489SMatthew Knepley ierr = PetscCalloc1(Nl, &active);CHKERRQ(ierr); 81250fdc7489SMatthew Knepley ul->Nl = 0; 81260fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 81270fdc7489SMatthew Knepley PetscBool isdepth, iscelltype; 81280fdc7489SMatthew Knepley const char *name; 81290fdc7489SMatthew Knepley 81300fdc7489SMatthew Knepley ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 81310fdc7489SMatthew Knepley ierr = PetscStrncmp(name, "depth", 6, &isdepth);CHKERRQ(ierr); 81320fdc7489SMatthew Knepley ierr = PetscStrncmp(name, "celltype", 9, &iscelltype);CHKERRQ(ierr); 81330fdc7489SMatthew Knepley active[l] = !(isdepth || iscelltype) ? PETSC_TRUE : PETSC_FALSE; 81340fdc7489SMatthew Knepley if (active[l]) ++ul->Nl; 81350fdc7489SMatthew Knepley } 81360fdc7489SMatthew 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); 81370fdc7489SMatthew Knepley ul->Nv = 0; 81380fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 81390fdc7489SMatthew Knepley DMLabel label; 81400fdc7489SMatthew Knepley PetscInt nv; 81410fdc7489SMatthew Knepley const char *name; 81420fdc7489SMatthew Knepley 81430fdc7489SMatthew Knepley if (!active[l]) continue; 81440fdc7489SMatthew Knepley ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 81450fdc7489SMatthew Knepley ierr = DMGetLabelByNum(dm, l, &label);CHKERRQ(ierr); 81460fdc7489SMatthew Knepley ierr = DMLabelGetNumValues(label, &nv);CHKERRQ(ierr); 81470fdc7489SMatthew Knepley ierr = PetscStrallocpy(name, &ul->names[m]);CHKERRQ(ierr); 81480fdc7489SMatthew Knepley ul->indices[m] = l; 81490fdc7489SMatthew Knepley ul->Nv += nv; 81500fdc7489SMatthew Knepley ul->offsets[m+1] = nv; 81510fdc7489SMatthew Knepley ul->bits[m+1] = PetscCeilReal(PetscLog2Real(nv+1)); 81520fdc7489SMatthew Knepley ++m; 81530fdc7489SMatthew Knepley } 81540fdc7489SMatthew Knepley for (l = 1; l <= ul->Nl; ++l) { 81550fdc7489SMatthew Knepley ul->offsets[l] = ul->offsets[l-1] + ul->offsets[l]; 81560fdc7489SMatthew Knepley ul->bits[l] = ul->bits[l-1] + ul->bits[l]; 81570fdc7489SMatthew Knepley } 81580fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 81590fdc7489SMatthew Knepley PetscInt b; 81600fdc7489SMatthew Knepley 81610fdc7489SMatthew Knepley ul->masks[l] = 0; 81620fdc7489SMatthew Knepley for (b = ul->bits[l]; b < ul->bits[l+1]; ++b) ul->masks[l] |= 1 << b; 81630fdc7489SMatthew Knepley } 81640fdc7489SMatthew Knepley ierr = PetscMalloc1(ul->Nv, &ul->values);CHKERRQ(ierr); 81650fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 81660fdc7489SMatthew Knepley DMLabel label; 81670fdc7489SMatthew Knepley IS valueIS; 81680fdc7489SMatthew Knepley const PetscInt *varr; 81690fdc7489SMatthew Knepley PetscInt nv, v; 81700fdc7489SMatthew Knepley 81710fdc7489SMatthew Knepley if (!active[l]) continue; 81720fdc7489SMatthew Knepley ierr = DMGetLabelByNum(dm, l, &label);CHKERRQ(ierr); 81730fdc7489SMatthew Knepley ierr = DMLabelGetNumValues(label, &nv);CHKERRQ(ierr); 81740fdc7489SMatthew Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 81750fdc7489SMatthew Knepley ierr = ISGetIndices(valueIS, &varr);CHKERRQ(ierr); 81760fdc7489SMatthew Knepley for (v = 0; v < nv; ++v) { 81770fdc7489SMatthew Knepley ul->values[ul->offsets[m]+v] = varr[v]; 81780fdc7489SMatthew Knepley } 81790fdc7489SMatthew Knepley ierr = ISRestoreIndices(valueIS, &varr);CHKERRQ(ierr); 81800fdc7489SMatthew Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 81810fdc7489SMatthew Knepley ierr = PetscSortInt(nv, &ul->values[ul->offsets[m]]);CHKERRQ(ierr); 81820fdc7489SMatthew Knepley ++m; 81830fdc7489SMatthew Knepley } 81840fdc7489SMatthew Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 81850fdc7489SMatthew Knepley for (p = pStart; p < pEnd; ++p) { 81860fdc7489SMatthew Knepley PetscInt uval = 0; 81870fdc7489SMatthew Knepley PetscBool marked = PETSC_FALSE; 81880fdc7489SMatthew Knepley 81890fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 81900fdc7489SMatthew Knepley DMLabel label; 81910649b39aSStefano Zampini PetscInt val, defval, loc, nv; 81920fdc7489SMatthew Knepley 81930fdc7489SMatthew Knepley if (!active[l]) continue; 81940fdc7489SMatthew Knepley ierr = DMGetLabelByNum(dm, l, &label);CHKERRQ(ierr); 81950fdc7489SMatthew Knepley ierr = DMLabelGetValue(label, p, &val);CHKERRQ(ierr); 81960fdc7489SMatthew Knepley ierr = DMLabelGetDefaultValue(label, &defval);CHKERRQ(ierr); 81970fdc7489SMatthew Knepley if (val == defval) {++m; continue;} 81980649b39aSStefano Zampini nv = ul->offsets[m+1]-ul->offsets[m]; 81990fdc7489SMatthew Knepley marked = PETSC_TRUE; 82000fdc7489SMatthew Knepley ierr = PetscFindInt(val, nv, &ul->values[ul->offsets[m]], &loc);CHKERRQ(ierr); 82010fdc7489SMatthew Knepley if (loc < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Label value %D not found in compression array", val); 82020fdc7489SMatthew Knepley uval += (loc+1) << ul->bits[m]; 82030fdc7489SMatthew Knepley ++m; 82040fdc7489SMatthew Knepley } 82050fdc7489SMatthew Knepley if (marked) {ierr = DMLabelSetValue(ul->label, p, uval);CHKERRQ(ierr);} 82060fdc7489SMatthew Knepley } 82070fdc7489SMatthew Knepley ierr = PetscFree(active);CHKERRQ(ierr); 82080fdc7489SMatthew Knepley *universal = ul; 82090fdc7489SMatthew Knepley PetscFunctionReturn(0); 82100fdc7489SMatthew Knepley } 82110fdc7489SMatthew Knepley 82120fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelDestroy(DMUniversalLabel *universal) 82130fdc7489SMatthew Knepley { 82140fdc7489SMatthew Knepley PetscInt l; 82150fdc7489SMatthew Knepley PetscErrorCode ierr; 82160fdc7489SMatthew Knepley 82170fdc7489SMatthew Knepley PetscFunctionBegin; 82180fdc7489SMatthew Knepley for (l = 0; l < (*universal)->Nl; ++l) {ierr = PetscFree((*universal)->names[l]);CHKERRQ(ierr);} 82190fdc7489SMatthew Knepley ierr = DMLabelDestroy(&(*universal)->label);CHKERRQ(ierr); 82200fdc7489SMatthew Knepley ierr = PetscFree5((*universal)->names, (*universal)->indices, (*universal)->offsets, (*universal)->bits, (*universal)->masks);CHKERRQ(ierr); 82210fdc7489SMatthew Knepley ierr = PetscFree((*universal)->values);CHKERRQ(ierr); 82220fdc7489SMatthew Knepley ierr = PetscFree(*universal);CHKERRQ(ierr); 82230fdc7489SMatthew Knepley *universal = NULL; 82240fdc7489SMatthew Knepley PetscFunctionReturn(0); 82250fdc7489SMatthew Knepley } 82260fdc7489SMatthew Knepley 82270fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelGetLabel(DMUniversalLabel ul, DMLabel *ulabel) 82280fdc7489SMatthew Knepley { 82290fdc7489SMatthew Knepley PetscFunctionBegin; 82300fdc7489SMatthew Knepley PetscValidPointer(ulabel, 2); 82310fdc7489SMatthew Knepley *ulabel = ul->label; 82320fdc7489SMatthew Knepley PetscFunctionReturn(0); 82330fdc7489SMatthew Knepley } 82340fdc7489SMatthew Knepley 82350fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelCreateLabels(DMUniversalLabel ul, PetscBool preserveOrder, DM dm) 82360fdc7489SMatthew Knepley { 82370fdc7489SMatthew Knepley PetscInt Nl = ul->Nl, l; 82380fdc7489SMatthew Knepley PetscErrorCode ierr; 82390fdc7489SMatthew Knepley 82400fdc7489SMatthew Knepley PetscFunctionBegin; 82410fdc7489SMatthew Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 82420fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 82430fdc7489SMatthew Knepley if (preserveOrder) {ierr = DMCreateLabelAtIndex(dm, ul->indices[l], ul->names[l]);CHKERRQ(ierr);} 82440fdc7489SMatthew Knepley else {ierr = DMCreateLabel(dm, ul->names[l]);CHKERRQ(ierr);} 82450fdc7489SMatthew Knepley } 82460fdc7489SMatthew Knepley if (preserveOrder) { 82470fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 82480fdc7489SMatthew Knepley const char *name; 82490fdc7489SMatthew Knepley PetscBool match; 82500fdc7489SMatthew Knepley 82510fdc7489SMatthew Knepley ierr = DMGetLabelName(dm, ul->indices[l], &name);CHKERRQ(ierr); 82520fdc7489SMatthew Knepley ierr = PetscStrcmp(name, ul->names[l], &match);CHKERRQ(ierr); 82530fdc7489SMatthew 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]); 82540fdc7489SMatthew Knepley } 82550fdc7489SMatthew Knepley } 82560fdc7489SMatthew Knepley PetscFunctionReturn(0); 82570fdc7489SMatthew Knepley } 82580fdc7489SMatthew Knepley 82590fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelSetLabelValue(DMUniversalLabel ul, DM dm, PetscBool useIndex, PetscInt p, PetscInt value) 82600fdc7489SMatthew Knepley { 82610fdc7489SMatthew Knepley PetscInt l; 82620fdc7489SMatthew Knepley PetscErrorCode ierr; 82630fdc7489SMatthew Knepley 82640fdc7489SMatthew Knepley PetscFunctionBegin; 82650fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 82660fdc7489SMatthew Knepley DMLabel label; 82670fdc7489SMatthew Knepley PetscInt lval = (value & ul->masks[l]) >> ul->bits[l]; 82680fdc7489SMatthew Knepley 82690fdc7489SMatthew Knepley if (lval) { 82700fdc7489SMatthew Knepley if (useIndex) {ierr = DMGetLabelByNum(dm, ul->indices[l], &label);CHKERRQ(ierr);} 82710fdc7489SMatthew Knepley else {ierr = DMGetLabel(dm, ul->names[l], &label);CHKERRQ(ierr);} 82720fdc7489SMatthew Knepley ierr = DMLabelSetValue(label, p, ul->values[ul->offsets[l]+lval-1]);CHKERRQ(ierr); 82730fdc7489SMatthew Knepley } 82740fdc7489SMatthew Knepley } 82750fdc7489SMatthew Knepley PetscFunctionReturn(0); 82760fdc7489SMatthew Knepley } 8277a8fb8f29SToby Isaac 8278a8fb8f29SToby Isaac /*@ 8279a8fb8f29SToby Isaac DMGetCoarseDM - Get the coarse mesh from which this was obtained by refinement 8280a8fb8f29SToby Isaac 8281a8fb8f29SToby Isaac Input Parameter: 8282a8fb8f29SToby Isaac . dm - The DM object 8283a8fb8f29SToby Isaac 8284a8fb8f29SToby Isaac Output Parameter: 8285a8fb8f29SToby Isaac . cdm - The coarse DM 8286a8fb8f29SToby Isaac 8287a8fb8f29SToby Isaac Level: intermediate 8288a8fb8f29SToby Isaac 8289a8fb8f29SToby Isaac .seealso: DMSetCoarseDM() 8290a8fb8f29SToby Isaac @*/ 8291a8fb8f29SToby Isaac PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm) 8292a8fb8f29SToby Isaac { 8293a8fb8f29SToby Isaac PetscFunctionBegin; 8294a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8295a8fb8f29SToby Isaac PetscValidPointer(cdm, 2); 8296a8fb8f29SToby Isaac *cdm = dm->coarseMesh; 8297a8fb8f29SToby Isaac PetscFunctionReturn(0); 8298a8fb8f29SToby Isaac } 8299a8fb8f29SToby Isaac 8300a8fb8f29SToby Isaac /*@ 8301a8fb8f29SToby Isaac DMSetCoarseDM - Set the coarse mesh from which this was obtained by refinement 8302a8fb8f29SToby Isaac 8303a8fb8f29SToby Isaac Input Parameters: 8304a8fb8f29SToby Isaac + dm - The DM object 8305a8fb8f29SToby Isaac - cdm - The coarse DM 8306a8fb8f29SToby Isaac 8307a8fb8f29SToby Isaac Level: intermediate 8308a8fb8f29SToby Isaac 8309a8fb8f29SToby Isaac .seealso: DMGetCoarseDM() 8310a8fb8f29SToby Isaac @*/ 8311a8fb8f29SToby Isaac PetscErrorCode DMSetCoarseDM(DM dm, DM cdm) 8312a8fb8f29SToby Isaac { 8313a8fb8f29SToby Isaac PetscErrorCode ierr; 8314a8fb8f29SToby Isaac 8315a8fb8f29SToby Isaac PetscFunctionBegin; 8316a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8317a8fb8f29SToby Isaac if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 8318a8fb8f29SToby Isaac ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr); 8319a8fb8f29SToby Isaac ierr = DMDestroy(&dm->coarseMesh);CHKERRQ(ierr); 8320a8fb8f29SToby Isaac dm->coarseMesh = cdm; 8321a8fb8f29SToby Isaac PetscFunctionReturn(0); 8322a8fb8f29SToby Isaac } 8323a8fb8f29SToby Isaac 832488bdff64SToby Isaac /*@ 832588bdff64SToby Isaac DMGetFineDM - Get the fine mesh from which this was obtained by refinement 832688bdff64SToby Isaac 832788bdff64SToby Isaac Input Parameter: 832888bdff64SToby Isaac . dm - The DM object 832988bdff64SToby Isaac 833088bdff64SToby Isaac Output Parameter: 833188bdff64SToby Isaac . fdm - The fine DM 833288bdff64SToby Isaac 833388bdff64SToby Isaac Level: intermediate 833488bdff64SToby Isaac 833588bdff64SToby Isaac .seealso: DMSetFineDM() 833688bdff64SToby Isaac @*/ 833788bdff64SToby Isaac PetscErrorCode DMGetFineDM(DM dm, DM *fdm) 833888bdff64SToby Isaac { 833988bdff64SToby Isaac PetscFunctionBegin; 834088bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 834188bdff64SToby Isaac PetscValidPointer(fdm, 2); 834288bdff64SToby Isaac *fdm = dm->fineMesh; 834388bdff64SToby Isaac PetscFunctionReturn(0); 834488bdff64SToby Isaac } 834588bdff64SToby Isaac 834688bdff64SToby Isaac /*@ 834788bdff64SToby Isaac DMSetFineDM - Set the fine mesh from which this was obtained by refinement 834888bdff64SToby Isaac 834988bdff64SToby Isaac Input Parameters: 835088bdff64SToby Isaac + dm - The DM object 835188bdff64SToby Isaac - fdm - The fine DM 835288bdff64SToby Isaac 835388bdff64SToby Isaac Level: intermediate 835488bdff64SToby Isaac 835588bdff64SToby Isaac .seealso: DMGetFineDM() 835688bdff64SToby Isaac @*/ 835788bdff64SToby Isaac PetscErrorCode DMSetFineDM(DM dm, DM fdm) 835888bdff64SToby Isaac { 835988bdff64SToby Isaac PetscErrorCode ierr; 836088bdff64SToby Isaac 836188bdff64SToby Isaac PetscFunctionBegin; 836288bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 836388bdff64SToby Isaac if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2); 836488bdff64SToby Isaac ierr = PetscObjectReference((PetscObject)fdm);CHKERRQ(ierr); 836588bdff64SToby Isaac ierr = DMDestroy(&dm->fineMesh);CHKERRQ(ierr); 836688bdff64SToby Isaac dm->fineMesh = fdm; 836788bdff64SToby Isaac PetscFunctionReturn(0); 836888bdff64SToby Isaac } 836988bdff64SToby Isaac 8370a6ba4734SToby Isaac /*=== DMBoundary code ===*/ 8371a6ba4734SToby Isaac 8372a6ba4734SToby Isaac /*@C 8373a6ba4734SToby Isaac DMAddBoundary - Add a boundary condition to the model 8374a6ba4734SToby Isaac 8375783e2ec8SMatthew G. Knepley Collective on dm 8376783e2ec8SMatthew G. Knepley 8377a6ba4734SToby Isaac Input Parameters: 83784c258f51SMatthew G. Knepley + dm - The DM, with a PetscDS that matches the problem being constrained 8379f971fd6bSMatthew G. Knepley . type - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann) 8380a6ba4734SToby Isaac . name - The BC name 8381*45480ffeSMatthew G. Knepley . label - The label defining constrained points 8382*45480ffeSMatthew G. Knepley . Nv - The number of DMLabel values for constrained points 8383*45480ffeSMatthew G. Knepley . values - An array of values for constrained points 8384a6ba4734SToby Isaac . field - The field to constrain 8385*45480ffeSMatthew G. Knepley . Nc - The number of constrained field components (0 will constrain all fields) 8386a6ba4734SToby Isaac . comps - An array of constrained component numbers 8387a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 838856cf3b9cSMatthew G. Knepley . bcFunc_t - A pointwise function giving the time deriative of the boundary values, or NULL 8389a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 8390a6ba4734SToby Isaac 8391*45480ffeSMatthew G. Knepley Output Parameter: 8392*45480ffeSMatthew G. Knepley . bd - (Optional) Boundary number 8393*45480ffeSMatthew G. Knepley 8394a6ba4734SToby Isaac Options Database Keys: 8395a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 8396a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 8397a6ba4734SToby Isaac 839856cf3b9cSMatthew G. Knepley Note: 839956cf3b9cSMatthew 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: 840056cf3b9cSMatthew G. Knepley 840156cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[]) 840256cf3b9cSMatthew G. Knepley 840356cf3b9cSMatthew G. Knepley If the type is DM_BC_ESSENTIAL_FIELD or other _FIELD value, then the calling sequence is: 840456cf3b9cSMatthew G. Knepley 840556cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux, 840656cf3b9cSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 840756cf3b9cSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 840856cf3b9cSMatthew G. Knepley $ PetscReal time, const PetscReal x[], PetscScalar bcval[]) 840956cf3b9cSMatthew G. Knepley 841056cf3b9cSMatthew G. Knepley + dim - the spatial dimension 841156cf3b9cSMatthew G. Knepley . Nf - the number of fields 841256cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field 841356cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field 841456cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point 841556cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point 841656cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point 841756cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field 841856cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field 841956cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point 842056cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point 842156cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point 842256cf3b9cSMatthew G. Knepley . t - current time 842356cf3b9cSMatthew G. Knepley . x - coordinates of the current point 842456cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters 842556cf3b9cSMatthew G. Knepley . constants - constant parameters 842656cf3b9cSMatthew G. Knepley - bcval - output values at the current point 842756cf3b9cSMatthew G. Knepley 8428a6ba4734SToby Isaac Level: developer 8429a6ba4734SToby Isaac 8430*45480ffeSMatthew G. Knepley .seealso: DSGetBoundary(), PetscDSAddBoundary() 8431a6ba4734SToby Isaac @*/ 8432*45480ffeSMatthew G. Knepley PetscErrorCode DMAddBoundary(DM dm, DMBoundaryConditionType type, const char name[], DMLabel label, PetscInt Nv, const PetscInt values[], PetscInt field, PetscInt Nc, const PetscInt comps[], void (*bcFunc)(void), void (*bcFunc_t)(void), void *ctx, PetscInt *bd) 8433a6ba4734SToby Isaac { 8434e5e52638SMatthew G. Knepley PetscDS ds; 8435a6ba4734SToby Isaac PetscErrorCode ierr; 8436a6ba4734SToby Isaac 8437a6ba4734SToby Isaac PetscFunctionBegin; 8438a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8439783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveEnum(dm, type, 2); 8440*45480ffeSMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 8441*45480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nv, 5); 8442*45480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, field, 7); 8443*45480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nc, 8); 8444e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 8445*45480ffeSMatthew G. Knepley ierr = DMCompleteBoundaryLabel_Internal(dm, ds, field, PETSC_MAX_INT, label);CHKERRQ(ierr); 8446*45480ffeSMatthew G. Knepley ierr = PetscDSAddBoundary(ds, type, name, label, Nv, values, field, Nc, comps, bcFunc, bcFunc_t, ctx, bd);CHKERRQ(ierr); 8447a6ba4734SToby Isaac PetscFunctionReturn(0); 8448a6ba4734SToby Isaac } 8449a6ba4734SToby Isaac 8450*45480ffeSMatthew G. Knepley /* TODO Remove this since now the structures are the same */ 8451e6f8dbb6SToby Isaac static PetscErrorCode DMPopulateBoundary(DM dm) 8452e6f8dbb6SToby Isaac { 8453e5e52638SMatthew G. Knepley PetscDS ds; 8454dff059c6SToby Isaac DMBoundary *lastnext; 8455e6f8dbb6SToby Isaac DSBoundary dsbound; 8456e6f8dbb6SToby Isaac PetscErrorCode ierr; 8457e6f8dbb6SToby Isaac 8458e6f8dbb6SToby Isaac PetscFunctionBegin; 8459e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 8460e5e52638SMatthew G. Knepley dsbound = ds->boundary; 846147a1f5adSToby Isaac if (dm->boundary) { 846247a1f5adSToby Isaac DMBoundary next = dm->boundary; 846347a1f5adSToby Isaac 846447a1f5adSToby Isaac /* quick check to see if the PetscDS has changed */ 846547a1f5adSToby Isaac if (next->dsboundary == dsbound) PetscFunctionReturn(0); 846647a1f5adSToby Isaac /* the PetscDS has changed: tear down and rebuild */ 846747a1f5adSToby Isaac while (next) { 846847a1f5adSToby Isaac DMBoundary b = next; 846947a1f5adSToby Isaac 847047a1f5adSToby Isaac next = b->next; 847147a1f5adSToby Isaac ierr = PetscFree(b);CHKERRQ(ierr); 8472a6ba4734SToby Isaac } 847347a1f5adSToby Isaac dm->boundary = NULL; 8474a6ba4734SToby Isaac } 847547a1f5adSToby Isaac 8476dff059c6SToby Isaac lastnext = &(dm->boundary); 8477e6f8dbb6SToby Isaac while (dsbound) { 8478e6f8dbb6SToby Isaac DMBoundary dmbound; 8479e6f8dbb6SToby Isaac 8480e6f8dbb6SToby Isaac ierr = PetscNew(&dmbound);CHKERRQ(ierr); 8481e6f8dbb6SToby Isaac dmbound->dsboundary = dsbound; 8482*45480ffeSMatthew G. Knepley dmbound->label = dsbound->label; 848347a1f5adSToby Isaac /* push on the back instead of the front so that it is in the same order as in the PetscDS */ 8484dff059c6SToby Isaac *lastnext = dmbound; 8485dff059c6SToby Isaac lastnext = &(dmbound->next); 8486dff059c6SToby Isaac dsbound = dsbound->next; 8487a6ba4734SToby Isaac } 8488a6ba4734SToby Isaac PetscFunctionReturn(0); 8489a6ba4734SToby Isaac } 8490a6ba4734SToby Isaac 8491a6ba4734SToby Isaac PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd) 8492a6ba4734SToby Isaac { 8493b95f2879SToby Isaac DMBoundary b; 8494a6ba4734SToby Isaac PetscErrorCode ierr; 8495a6ba4734SToby Isaac 8496a6ba4734SToby Isaac PetscFunctionBegin; 8497a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8498534a8f05SLisandro Dalcin PetscValidBoolPointer(isBd, 3); 8499a6ba4734SToby Isaac *isBd = PETSC_FALSE; 8500e6f8dbb6SToby Isaac ierr = DMPopulateBoundary(dm);CHKERRQ(ierr); 8501b95f2879SToby Isaac b = dm->boundary; 8502a6ba4734SToby Isaac while (b && !(*isBd)) { 8503e6f8dbb6SToby Isaac DMLabel label = b->label; 8504e6f8dbb6SToby Isaac DSBoundary dsb = b->dsboundary; 8505a6ba4734SToby Isaac PetscInt i; 8506a6ba4734SToby Isaac 8507*45480ffeSMatthew G. Knepley if (label) { 8508*45480ffeSMatthew G. Knepley for (i = 0; i < dsb->Nv && !(*isBd); ++i) {ierr = DMLabelStratumHasPoint(label, dsb->values[i], point, isBd);CHKERRQ(ierr);} 8509a6ba4734SToby Isaac } 8510a6ba4734SToby Isaac b = b->next; 8511a6ba4734SToby Isaac } 8512a6ba4734SToby Isaac PetscFunctionReturn(0); 8513a6ba4734SToby Isaac } 85144d6f44ffSToby Isaac 85154d6f44ffSToby Isaac /*@C 8516a6e0b375SMatthew G. Knepley DMProjectFunction - This projects the given function into the function space provided, putting the coefficients in a global vector. 8517a6e0b375SMatthew G. Knepley 8518a6e0b375SMatthew G. Knepley Collective on DM 85194d6f44ffSToby Isaac 85204d6f44ffSToby Isaac Input Parameters: 85214d6f44ffSToby Isaac + dm - The DM 85220709b2feSToby Isaac . time - The time 85234d6f44ffSToby Isaac . funcs - The coordinate functions to evaluate, one per field 85244d6f44ffSToby Isaac . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 85254d6f44ffSToby Isaac - mode - The insertion mode for values 85264d6f44ffSToby Isaac 85274d6f44ffSToby Isaac Output Parameter: 85284d6f44ffSToby Isaac . X - vector 85294d6f44ffSToby Isaac 85304d6f44ffSToby Isaac Calling sequence of func: 85310709b2feSToby Isaac $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 85324d6f44ffSToby Isaac 85334d6f44ffSToby Isaac + dim - The spatial dimension 85348ec8862eSJed Brown . time - The time at which to sample 85354d6f44ffSToby Isaac . x - The coordinates 85364d6f44ffSToby Isaac . Nf - The number of fields 85374d6f44ffSToby Isaac . u - The output field values 85384d6f44ffSToby Isaac - ctx - optional user-defined function context 85394d6f44ffSToby Isaac 85404d6f44ffSToby Isaac Level: developer 85414d6f44ffSToby Isaac 8542a6e0b375SMatthew G. Knepley .seealso: DMProjectFunctionLocal(), DMProjectFunctionLabel(), DMComputeL2Diff() 85434d6f44ffSToby Isaac @*/ 85440709b2feSToby Isaac PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X) 85454d6f44ffSToby Isaac { 85464d6f44ffSToby Isaac Vec localX; 85474d6f44ffSToby Isaac PetscErrorCode ierr; 85484d6f44ffSToby Isaac 85494d6f44ffSToby Isaac PetscFunctionBegin; 85504d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 85514d6f44ffSToby Isaac ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr); 85520709b2feSToby Isaac ierr = DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr); 85534d6f44ffSToby Isaac ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr); 85544d6f44ffSToby Isaac ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr); 85554d6f44ffSToby Isaac ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr); 85564d6f44ffSToby Isaac PetscFunctionReturn(0); 85574d6f44ffSToby Isaac } 85584d6f44ffSToby Isaac 8559a6e0b375SMatthew G. Knepley /*@C 8560a6e0b375SMatthew G. Knepley DMProjectFunctionLocal - This projects the given function into the function space provided, putting the coefficients in a local vector. 8561a6e0b375SMatthew G. Knepley 8562a6e0b375SMatthew G. Knepley Not collective 8563a6e0b375SMatthew G. Knepley 8564a6e0b375SMatthew G. Knepley Input Parameters: 8565a6e0b375SMatthew G. Knepley + dm - The DM 8566a6e0b375SMatthew G. Knepley . time - The time 8567a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8568a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8569a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8570a6e0b375SMatthew G. Knepley 8571a6e0b375SMatthew G. Knepley Output Parameter: 8572a6e0b375SMatthew G. Knepley . localX - vector 8573a6e0b375SMatthew G. Knepley 8574a6e0b375SMatthew G. Knepley Calling sequence of func: 8575a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 8576a6e0b375SMatthew G. Knepley 8577a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8578a6e0b375SMatthew G. Knepley . x - The coordinates 8579a6e0b375SMatthew G. Knepley . Nf - The number of fields 8580a6e0b375SMatthew G. Knepley . u - The output field values 8581a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8582a6e0b375SMatthew G. Knepley 8583a6e0b375SMatthew G. Knepley Level: developer 8584a6e0b375SMatthew G. Knepley 8585a6e0b375SMatthew G. Knepley .seealso: DMProjectFunction(), DMProjectFunctionLabel(), DMComputeL2Diff() 8586a6e0b375SMatthew G. Knepley @*/ 85870709b2feSToby Isaac PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 85884d6f44ffSToby Isaac { 85894d6f44ffSToby Isaac PetscErrorCode ierr; 85904d6f44ffSToby Isaac 85914d6f44ffSToby Isaac PetscFunctionBegin; 85924d6f44ffSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 85934d6f44ffSToby Isaac PetscValidHeaderSpecific(localX,VEC_CLASSID,5); 85940918c465SMatthew G. Knepley if (!dm->ops->projectfunctionlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLocal",((PetscObject)dm)->type_name); 85950709b2feSToby Isaac ierr = (dm->ops->projectfunctionlocal) (dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr); 85964d6f44ffSToby Isaac PetscFunctionReturn(0); 85974d6f44ffSToby Isaac } 85984d6f44ffSToby Isaac 8599a6e0b375SMatthew G. Knepley /*@C 8600a6e0b375SMatthew 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. 8601a6e0b375SMatthew G. Knepley 8602a6e0b375SMatthew G. Knepley Collective on DM 8603a6e0b375SMatthew G. Knepley 8604a6e0b375SMatthew G. Knepley Input Parameters: 8605a6e0b375SMatthew G. Knepley + dm - The DM 8606a6e0b375SMatthew G. Knepley . time - The time 8607a6e0b375SMatthew G. Knepley . label - The DMLabel selecting the portion of the mesh for projection 8608a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8609a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8610a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8611a6e0b375SMatthew G. Knepley 8612a6e0b375SMatthew G. Knepley Output Parameter: 8613a6e0b375SMatthew G. Knepley . X - vector 8614a6e0b375SMatthew G. Knepley 8615a6e0b375SMatthew G. Knepley Calling sequence of func: 8616a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 8617a6e0b375SMatthew G. Knepley 8618a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8619a6e0b375SMatthew G. Knepley . x - The coordinates 8620a6e0b375SMatthew G. Knepley . Nf - The number of fields 8621a6e0b375SMatthew G. Knepley . u - The output field values 8622a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8623a6e0b375SMatthew G. Knepley 8624a6e0b375SMatthew G. Knepley Level: developer 8625a6e0b375SMatthew G. Knepley 8626a6e0b375SMatthew G. Knepley .seealso: DMProjectFunction(), DMProjectFunctionLocal(), DMProjectFunctionLabelLocal(), DMComputeL2Diff() 8627a6e0b375SMatthew G. Knepley @*/ 86282c53366bSMatthew 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) 86292c53366bSMatthew G. Knepley { 86302c53366bSMatthew G. Knepley Vec localX; 86312c53366bSMatthew G. Knepley PetscErrorCode ierr; 86322c53366bSMatthew G. Knepley 86332c53366bSMatthew G. Knepley PetscFunctionBegin; 86342c53366bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 86352c53366bSMatthew G. Knepley ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr); 86362c53366bSMatthew G. Knepley ierr = DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr); 86372c53366bSMatthew G. Knepley ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr); 86382c53366bSMatthew G. Knepley ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr); 86392c53366bSMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr); 86402c53366bSMatthew G. Knepley PetscFunctionReturn(0); 86412c53366bSMatthew G. Knepley } 86422c53366bSMatthew G. Knepley 8643a6e0b375SMatthew G. Knepley /*@C 8644a6e0b375SMatthew 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. 8645a6e0b375SMatthew G. Knepley 8646a6e0b375SMatthew G. Knepley Not collective 8647a6e0b375SMatthew G. Knepley 8648a6e0b375SMatthew G. Knepley Input Parameters: 8649a6e0b375SMatthew G. Knepley + dm - The DM 8650a6e0b375SMatthew G. Knepley . time - The time 8651a6e0b375SMatthew G. Knepley . label - The DMLabel selecting the portion of the mesh for projection 8652a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8653a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8654a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8655a6e0b375SMatthew G. Knepley 8656a6e0b375SMatthew G. Knepley Output Parameter: 8657a6e0b375SMatthew G. Knepley . localX - vector 8658a6e0b375SMatthew G. Knepley 8659a6e0b375SMatthew G. Knepley Calling sequence of func: 8660a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); 8661a6e0b375SMatthew G. Knepley 8662a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8663a6e0b375SMatthew G. Knepley . x - The coordinates 8664a6e0b375SMatthew G. Knepley . Nf - The number of fields 8665a6e0b375SMatthew G. Knepley . u - The output field values 8666a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8667a6e0b375SMatthew G. Knepley 8668a6e0b375SMatthew G. Knepley Level: developer 8669a6e0b375SMatthew G. Knepley 8670a6e0b375SMatthew G. Knepley .seealso: DMProjectFunction(), DMProjectFunctionLocal(), DMProjectFunctionLabel(), DMComputeL2Diff() 8671a6e0b375SMatthew G. Knepley @*/ 86721c531cf8SMatthew 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) 86734d6f44ffSToby Isaac { 86744d6f44ffSToby Isaac PetscErrorCode ierr; 86754d6f44ffSToby Isaac 86764d6f44ffSToby Isaac PetscFunctionBegin; 86774d6f44ffSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 86784d6f44ffSToby Isaac PetscValidHeaderSpecific(localX,VEC_CLASSID,5); 86790918c465SMatthew G. Knepley if (!dm->ops->projectfunctionlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLabelLocal",((PetscObject)dm)->type_name); 86801c531cf8SMatthew G. Knepley ierr = (dm->ops->projectfunctionlabellocal) (dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr); 86814d6f44ffSToby Isaac PetscFunctionReturn(0); 86824d6f44ffSToby Isaac } 86832716604bSToby Isaac 8684a6e0b375SMatthew G. Knepley /*@C 8685a6e0b375SMatthew G. Knepley DMProjectFieldLocal - This projects the given function of the input fields into the function space provided, putting the coefficients in a local vector. 8686a6e0b375SMatthew G. Knepley 8687a6e0b375SMatthew G. Knepley Not collective 8688a6e0b375SMatthew G. Knepley 8689a6e0b375SMatthew G. Knepley Input Parameters: 8690a6e0b375SMatthew G. Knepley + dm - The DM 8691a6e0b375SMatthew G. Knepley . time - The time 8692a6e0b375SMatthew G. Knepley . localU - The input field vector 8693a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8694a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8695a6e0b375SMatthew G. Knepley 8696a6e0b375SMatthew G. Knepley Output Parameter: 8697a6e0b375SMatthew G. Knepley . localX - The output vector 8698a6e0b375SMatthew G. Knepley 8699a6e0b375SMatthew G. Knepley Calling sequence of func: 8700a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8701a6e0b375SMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8702a6e0b375SMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8703a6e0b375SMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8704a6e0b375SMatthew G. Knepley 8705a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8706a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8707a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8708a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8709a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8710a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8711a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8712a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8713a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8714a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8715a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8716a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8717a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8718a6e0b375SMatthew G. Knepley . t - The current time 8719a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8720a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8721a6e0b375SMatthew G. Knepley . constants - The value of each constant 8722a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8723a6e0b375SMatthew G. Knepley 8724a6e0b375SMatthew 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. 8725a6e0b375SMatthew 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 8726a6e0b375SMatthew 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 8727a6e0b375SMatthew 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. 8728a6e0b375SMatthew G. Knepley 8729a6e0b375SMatthew G. Knepley Level: intermediate 8730a6e0b375SMatthew G. Knepley 8731a6e0b375SMatthew G. Knepley .seealso: DMProjectField(), DMProjectFieldLabelLocal(), DMProjectFunction(), DMComputeL2Diff() 8732a6e0b375SMatthew G. Knepley @*/ 87338c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal(DM dm, PetscReal time, Vec localU, 87348c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 87358c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 87368c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8737191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 87388c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 87398c6c5593SMatthew G. Knepley { 87408c6c5593SMatthew G. Knepley PetscErrorCode ierr; 87418c6c5593SMatthew G. Knepley 87428c6c5593SMatthew G. Knepley PetscFunctionBegin; 87438c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 87448c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,3); 87458c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,6); 87460918c465SMatthew G. Knepley if (!dm->ops->projectfieldlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name); 87478c6c5593SMatthew G. Knepley ierr = (dm->ops->projectfieldlocal) (dm, time, localU, funcs, mode, localX);CHKERRQ(ierr); 87488c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 87498c6c5593SMatthew G. Knepley } 87508c6c5593SMatthew G. Knepley 8751a6e0b375SMatthew G. Knepley /*@C 8752a6e0b375SMatthew 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. 8753a6e0b375SMatthew G. Knepley 8754a6e0b375SMatthew G. Knepley Not collective 8755a6e0b375SMatthew G. Knepley 8756a6e0b375SMatthew G. Knepley Input Parameters: 8757a6e0b375SMatthew G. Knepley + dm - The DM 8758a6e0b375SMatthew G. Knepley . time - The time 8759a6e0b375SMatthew G. Knepley . label - The DMLabel marking the portion of the domain to output 8760a6e0b375SMatthew G. Knepley . numIds - The number of label ids to use 8761a6e0b375SMatthew G. Knepley . ids - The label ids to use for marking 8762a6e0b375SMatthew G. Knepley . Nc - The number of components to set in the output, or PETSC_DETERMINE for all components 8763a6e0b375SMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8764a6e0b375SMatthew G. Knepley . localU - The input field vector 8765a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8766a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8767a6e0b375SMatthew G. Knepley 8768a6e0b375SMatthew G. Knepley Output Parameter: 8769a6e0b375SMatthew G. Knepley . localX - The output vector 8770a6e0b375SMatthew G. Knepley 8771a6e0b375SMatthew G. Knepley Calling sequence of func: 8772a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8773a6e0b375SMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8774a6e0b375SMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8775a6e0b375SMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8776a6e0b375SMatthew G. Knepley 8777a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8778a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8779a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8780a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8781a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8782a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8783a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8784a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8785a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8786a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8787a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8788a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8789a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8790a6e0b375SMatthew G. Knepley . t - The current time 8791a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8792a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8793a6e0b375SMatthew G. Knepley . constants - The value of each constant 8794a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8795a6e0b375SMatthew G. Knepley 8796a6e0b375SMatthew 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. 8797a6e0b375SMatthew 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 8798a6e0b375SMatthew 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 8799a6e0b375SMatthew 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. 8800a6e0b375SMatthew G. Knepley 8801a6e0b375SMatthew G. Knepley Level: intermediate 8802a6e0b375SMatthew G. Knepley 8803a6e0b375SMatthew G. Knepley .seealso: DMProjectField(), DMProjectFieldLabelLocal(), DMProjectFunction(), DMComputeL2Diff() 8804a6e0b375SMatthew G. Knepley @*/ 88051c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, 88068c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 88078c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 88088c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8809191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 88108c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 88118c6c5593SMatthew G. Knepley { 88128c6c5593SMatthew G. Knepley PetscErrorCode ierr; 88138c6c5593SMatthew G. Knepley 88148c6c5593SMatthew G. Knepley PetscFunctionBegin; 88158c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 88168c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,6); 88178c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,9); 8818ece3a9fcSMatthew G. Knepley if (!dm->ops->projectfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLabelLocal",((PetscObject)dm)->type_name); 88191c531cf8SMatthew G. Knepley ierr = (dm->ops->projectfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX);CHKERRQ(ierr); 88208c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 88218c6c5593SMatthew G. Knepley } 88228c6c5593SMatthew G. Knepley 88232716604bSToby Isaac /*@C 8824ece3a9fcSMatthew 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. 8825ece3a9fcSMatthew G. Knepley 8826ece3a9fcSMatthew G. Knepley Not collective 8827ece3a9fcSMatthew G. Knepley 8828ece3a9fcSMatthew G. Knepley Input Parameters: 8829ece3a9fcSMatthew G. Knepley + dm - The DM 8830ece3a9fcSMatthew G. Knepley . time - The time 8831ece3a9fcSMatthew G. Knepley . label - The DMLabel marking the portion of the domain boundary to output 8832ece3a9fcSMatthew G. Knepley . numIds - The number of label ids to use 8833ece3a9fcSMatthew G. Knepley . ids - The label ids to use for marking 8834ece3a9fcSMatthew G. Knepley . Nc - The number of components to set in the output, or PETSC_DETERMINE for all components 8835ece3a9fcSMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8836ece3a9fcSMatthew G. Knepley . localU - The input field vector 8837ece3a9fcSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8838ece3a9fcSMatthew G. Knepley - mode - The insertion mode for values 8839ece3a9fcSMatthew G. Knepley 8840ece3a9fcSMatthew G. Knepley Output Parameter: 8841ece3a9fcSMatthew G. Knepley . localX - The output vector 8842ece3a9fcSMatthew G. Knepley 8843ece3a9fcSMatthew G. Knepley Calling sequence of func: 8844ece3a9fcSMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8845ece3a9fcSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8846ece3a9fcSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8847ece3a9fcSMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8848ece3a9fcSMatthew G. Knepley 8849ece3a9fcSMatthew G. Knepley + dim - The spatial dimension 8850ece3a9fcSMatthew G. Knepley . Nf - The number of input fields 8851ece3a9fcSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8852ece3a9fcSMatthew G. Knepley . uOff - The offset of each field in u[] 8853ece3a9fcSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8854ece3a9fcSMatthew G. Knepley . u - The field values at this point in space 8855ece3a9fcSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8856ece3a9fcSMatthew G. Knepley . u_x - The field derivatives at this point in space 8857ece3a9fcSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8858ece3a9fcSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8859ece3a9fcSMatthew G. Knepley . a - The auxiliary field values at this point in space 8860ece3a9fcSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8861ece3a9fcSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8862ece3a9fcSMatthew G. Knepley . t - The current time 8863ece3a9fcSMatthew G. Knepley . x - The coordinates of this point 8864ece3a9fcSMatthew G. Knepley . n - The face normal 8865ece3a9fcSMatthew G. Knepley . numConstants - The number of constants 8866ece3a9fcSMatthew G. Knepley . constants - The value of each constant 8867ece3a9fcSMatthew G. Knepley - f - The value of the function at this point in space 8868ece3a9fcSMatthew G. Knepley 8869ece3a9fcSMatthew G. Knepley Note: 8870ece3a9fcSMatthew 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. 8871ece3a9fcSMatthew 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 8872ece3a9fcSMatthew 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 8873ece3a9fcSMatthew 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. 8874ece3a9fcSMatthew G. Knepley 8875ece3a9fcSMatthew G. Knepley Level: intermediate 8876ece3a9fcSMatthew G. Knepley 8877ece3a9fcSMatthew G. Knepley .seealso: DMProjectField(), DMProjectFieldLabelLocal(), DMProjectFunction(), DMComputeL2Diff() 8878ece3a9fcSMatthew G. Knepley @*/ 8879ece3a9fcSMatthew G. Knepley PetscErrorCode DMProjectBdFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, 8880ece3a9fcSMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 8881ece3a9fcSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8882ece3a9fcSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8883ece3a9fcSMatthew G. Knepley PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 8884ece3a9fcSMatthew G. Knepley InsertMode mode, Vec localX) 8885ece3a9fcSMatthew G. Knepley { 8886ece3a9fcSMatthew G. Knepley PetscErrorCode ierr; 8887ece3a9fcSMatthew G. Knepley 8888ece3a9fcSMatthew G. Knepley PetscFunctionBegin; 8889ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8890ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,6); 8891ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,9); 8892ece3a9fcSMatthew G. Knepley if (!dm->ops->projectbdfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectBdFieldLabelLocal",((PetscObject)dm)->type_name); 8893ece3a9fcSMatthew G. Knepley ierr = (dm->ops->projectbdfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX);CHKERRQ(ierr); 8894ece3a9fcSMatthew G. Knepley PetscFunctionReturn(0); 8895ece3a9fcSMatthew G. Knepley } 8896ece3a9fcSMatthew G. Knepley 8897ece3a9fcSMatthew G. Knepley /*@C 88982716604bSToby Isaac DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h. 88992716604bSToby Isaac 89002716604bSToby Isaac Input Parameters: 89012716604bSToby Isaac + dm - The DM 89020709b2feSToby Isaac . time - The time 89032716604bSToby Isaac . funcs - The functions to evaluate for each field component 89042716604bSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8905574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 89062716604bSToby Isaac 89072716604bSToby Isaac Output Parameter: 89082716604bSToby Isaac . diff - The diff ||u - u_h||_2 89092716604bSToby Isaac 89102716604bSToby Isaac Level: developer 89112716604bSToby Isaac 89121189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff() 89132716604bSToby Isaac @*/ 89140709b2feSToby Isaac PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff) 89152716604bSToby Isaac { 89162716604bSToby Isaac PetscErrorCode ierr; 89172716604bSToby Isaac 89182716604bSToby Isaac PetscFunctionBegin; 89192716604bSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8920b698f381SToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 89210918c465SMatthew G. Knepley if (!dm->ops->computel2diff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2Diff",((PetscObject)dm)->type_name); 89220709b2feSToby Isaac ierr = (dm->ops->computel2diff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr); 89232716604bSToby Isaac PetscFunctionReturn(0); 89242716604bSToby Isaac } 8925b698f381SToby Isaac 8926b698f381SToby Isaac /*@C 8927b698f381SToby Isaac DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h. 8928b698f381SToby Isaac 8929d083f849SBarry Smith Collective on dm 8930d083f849SBarry Smith 8931b698f381SToby Isaac Input Parameters: 8932b698f381SToby Isaac + dm - The DM 8933b698f381SToby Isaac , time - The time 8934b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component 8935b698f381SToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8936574a98acSMatthew G. Knepley . X - The coefficient vector u_h, a global vector 8937b698f381SToby Isaac - n - The vector to project along 8938b698f381SToby Isaac 8939b698f381SToby Isaac Output Parameter: 8940b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2 8941b698f381SToby Isaac 8942b698f381SToby Isaac Level: developer 8943b698f381SToby Isaac 8944b698f381SToby Isaac .seealso: DMProjectFunction(), DMComputeL2Diff() 8945b698f381SToby Isaac @*/ 8946b698f381SToby 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) 8947b698f381SToby Isaac { 8948b698f381SToby Isaac PetscErrorCode ierr; 8949b698f381SToby Isaac 8950b698f381SToby Isaac PetscFunctionBegin; 8951b698f381SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8952b698f381SToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 8953b698f381SToby Isaac if (!dm->ops->computel2gradientdiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2GradientDiff",((PetscObject)dm)->type_name); 8954b698f381SToby Isaac ierr = (dm->ops->computel2gradientdiff)(dm,time,funcs,ctxs,X,n,diff);CHKERRQ(ierr); 8955b698f381SToby Isaac PetscFunctionReturn(0); 8956b698f381SToby Isaac } 8957b698f381SToby Isaac 89582a16baeaSToby Isaac /*@C 89592a16baeaSToby Isaac DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components. 89602a16baeaSToby Isaac 8961d083f849SBarry Smith Collective on dm 8962d083f849SBarry Smith 89632a16baeaSToby Isaac Input Parameters: 89642a16baeaSToby Isaac + dm - The DM 89652a16baeaSToby Isaac . time - The time 89662a16baeaSToby Isaac . funcs - The functions to evaluate for each field component 89672a16baeaSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8968574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 89692a16baeaSToby Isaac 89702a16baeaSToby Isaac Output Parameter: 89712a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2 89722a16baeaSToby Isaac 89732a16baeaSToby Isaac Level: developer 89742a16baeaSToby Isaac 89751189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff() 89762a16baeaSToby Isaac @*/ 89771189c1efSToby Isaac PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[]) 89782a16baeaSToby Isaac { 89792a16baeaSToby Isaac PetscErrorCode ierr; 89802a16baeaSToby Isaac 89812a16baeaSToby Isaac PetscFunctionBegin; 89822a16baeaSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 89832a16baeaSToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 89840918c465SMatthew G. Knepley if (!dm->ops->computel2fielddiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2FieldDiff",((PetscObject)dm)->type_name); 89852a16baeaSToby Isaac ierr = (dm->ops->computel2fielddiff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr); 89862a16baeaSToby Isaac PetscFunctionReturn(0); 89872a16baeaSToby Isaac } 89882a16baeaSToby Isaac 8989df0b854cSToby Isaac /*@C 8990df0b854cSToby Isaac DMAdaptLabel - Adapt a dm based on a label with values interpreted as coarsening and refining flags. Specific implementations of DM maybe have 8991cd3c525cSToby Isaac specialized flags, but all implementations should accept flag values DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN. 8992df0b854cSToby Isaac 8993df0b854cSToby Isaac Collective on dm 8994df0b854cSToby Isaac 8995df0b854cSToby Isaac Input parameters: 8996df0b854cSToby Isaac + dm - the pre-adaptation DM object 8997a1b0c543SToby Isaac - label - label with the flags 8998df0b854cSToby Isaac 8999df0b854cSToby Isaac Output parameters: 90000d1cd5e0SMatthew G. Knepley . dmAdapt - the adapted DM object: may be NULL if an adapted DM could not be produced. 9001df0b854cSToby Isaac 9002df0b854cSToby Isaac Level: intermediate 90030d1cd5e0SMatthew G. Knepley 90040d1cd5e0SMatthew G. Knepley .seealso: DMAdaptMetric(), DMCoarsen(), DMRefine() 9005df0b854cSToby Isaac @*/ 90060d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptLabel(DM dm, DMLabel label, DM *dmAdapt) 9007df0b854cSToby Isaac { 9008df0b854cSToby Isaac PetscErrorCode ierr; 9009df0b854cSToby Isaac 9010df0b854cSToby Isaac PetscFunctionBegin; 9011df0b854cSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9012a1b0c543SToby Isaac PetscValidPointer(label,2); 90130d1cd5e0SMatthew G. Knepley PetscValidPointer(dmAdapt,3); 90140d1cd5e0SMatthew G. Knepley *dmAdapt = NULL; 90156f25b0d8SLisandro Dalcin if (!dm->ops->adaptlabel) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptLabel",((PetscObject)dm)->type_name); 90160d1cd5e0SMatthew G. Knepley ierr = (dm->ops->adaptlabel)(dm, label, dmAdapt);CHKERRQ(ierr); 9017a587d139SMark if (*dmAdapt) { 9018a587d139SMark (*dmAdapt)->prealloc_only = dm->prealloc_only; /* maybe this should go .... */ 9019a587d139SMark ierr = PetscFree((*dmAdapt)->vectype);CHKERRQ(ierr); 9020a587d139SMark ierr = PetscStrallocpy(dm->vectype,(char**)&(*dmAdapt)->vectype);CHKERRQ(ierr); 9021a587d139SMark ierr = PetscFree((*dmAdapt)->mattype);CHKERRQ(ierr); 9022a587d139SMark ierr = PetscStrallocpy(dm->mattype,(char**)&(*dmAdapt)->mattype);CHKERRQ(ierr); 9023a587d139SMark } 90240d1cd5e0SMatthew G. Knepley PetscFunctionReturn(0); 90250d1cd5e0SMatthew G. Knepley } 90260d1cd5e0SMatthew G. Knepley 90270d1cd5e0SMatthew G. Knepley /*@C 90280d1cd5e0SMatthew G. Knepley DMAdaptMetric - Generates a mesh adapted to the specified metric field using the pragmatic library. 90290d1cd5e0SMatthew G. Knepley 90300d1cd5e0SMatthew G. Knepley Input Parameters: 90310d1cd5e0SMatthew G. Knepley + dm - The DM object 90320d1cd5e0SMatthew G. Knepley . metric - The metric to which the mesh is adapted, defined vertex-wise. 90336f25b0d8SLisandro 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_". 90340d1cd5e0SMatthew G. Knepley 90350d1cd5e0SMatthew G. Knepley Output Parameter: 90360d1cd5e0SMatthew G. Knepley . dmAdapt - Pointer to the DM object containing the adapted mesh 90370d1cd5e0SMatthew G. Knepley 90380d1cd5e0SMatthew G. Knepley Note: The label in the adapted mesh will be registered under the name of the input DMLabel object 90390d1cd5e0SMatthew G. Knepley 90400d1cd5e0SMatthew G. Knepley Level: advanced 90410d1cd5e0SMatthew G. Knepley 90420d1cd5e0SMatthew G. Knepley .seealso: DMAdaptLabel(), DMCoarsen(), DMRefine() 90430d1cd5e0SMatthew G. Knepley @*/ 90440d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptMetric(DM dm, Vec metric, DMLabel bdLabel, DM *dmAdapt) 90450d1cd5e0SMatthew G. Knepley { 90460d1cd5e0SMatthew G. Knepley PetscErrorCode ierr; 90470d1cd5e0SMatthew G. Knepley 90480d1cd5e0SMatthew G. Knepley PetscFunctionBegin; 90490d1cd5e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90500d1cd5e0SMatthew G. Knepley PetscValidHeaderSpecific(metric, VEC_CLASSID, 2); 90510d1cd5e0SMatthew G. Knepley if (bdLabel) PetscValidPointer(bdLabel, 3); 90520d1cd5e0SMatthew G. Knepley PetscValidPointer(dmAdapt, 4); 90536f25b0d8SLisandro Dalcin *dmAdapt = NULL; 90546f25b0d8SLisandro Dalcin if (!dm->ops->adaptmetric) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptMetric",((PetscObject)dm)->type_name); 90550d1cd5e0SMatthew G. Knepley ierr = (dm->ops->adaptmetric)(dm, metric, bdLabel, dmAdapt);CHKERRQ(ierr); 9056df0b854cSToby Isaac PetscFunctionReturn(0); 9057df0b854cSToby Isaac } 9058c4088d22SMatthew G. Knepley 9059502a2867SDave May /*@C 9060502a2867SDave May DMGetNeighbors - Gets an array containing the MPI rank of all the processes neighbors 9061502a2867SDave May 9062502a2867SDave May Not Collective 9063502a2867SDave May 9064502a2867SDave May Input Parameter: 9065502a2867SDave May . dm - The DM 9066502a2867SDave May 90670a19bb7dSprj- Output Parameters: 90680a19bb7dSprj- + nranks - the number of neighbours 90690a19bb7dSprj- - ranks - the neighbors ranks 9070502a2867SDave May 9071502a2867SDave May Notes: 9072502a2867SDave May Do not free the array, it is freed when the DM is destroyed. 9073502a2867SDave May 9074502a2867SDave May Level: beginner 9075502a2867SDave May 9076dec1416fSJunchao Zhang .seealso: DMDAGetNeighbors(), PetscSFGetRootRanks() 9077502a2867SDave May @*/ 9078502a2867SDave May PetscErrorCode DMGetNeighbors(DM dm,PetscInt *nranks,const PetscMPIInt *ranks[]) 9079502a2867SDave May { 9080502a2867SDave May PetscErrorCode ierr; 9081502a2867SDave May 9082502a2867SDave May PetscFunctionBegin; 9083502a2867SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 90840918c465SMatthew G. Knepley if (!dm->ops->getneighbors) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMGetNeighbors",((PetscObject)dm)->type_name); 9085502a2867SDave May ierr = (dm->ops->getneighbors)(dm,nranks,ranks);CHKERRQ(ierr); 9086502a2867SDave May PetscFunctionReturn(0); 9087502a2867SDave May } 9088502a2867SDave May 9089531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */ 9090531c7667SBarry Smith 9091531c7667SBarry Smith /* 9092531c7667SBarry Smith Converts the input vector to a ghosted vector and then calls the standard coloring code. 9093531c7667SBarry Smith This has be a different function because it requires DM which is not defined in the Mat library 9094531c7667SBarry Smith */ 9095531c7667SBarry Smith PetscErrorCode MatFDColoringApply_AIJDM(Mat J,MatFDColoring coloring,Vec x1,void *sctx) 9096531c7667SBarry Smith { 9097531c7667SBarry Smith PetscErrorCode ierr; 9098531c7667SBarry Smith 9099531c7667SBarry Smith PetscFunctionBegin; 9100531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 9101531c7667SBarry Smith Vec x1local; 9102531c7667SBarry Smith DM dm; 9103531c7667SBarry Smith ierr = MatGetDM(J,&dm);CHKERRQ(ierr); 9104531c7667SBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_INCOMP,"IS_COLORING_LOCAL requires a DM"); 9105531c7667SBarry Smith ierr = DMGetLocalVector(dm,&x1local);CHKERRQ(ierr); 9106531c7667SBarry Smith ierr = DMGlobalToLocalBegin(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr); 9107531c7667SBarry Smith ierr = DMGlobalToLocalEnd(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr); 9108531c7667SBarry Smith x1 = x1local; 9109531c7667SBarry Smith } 9110531c7667SBarry Smith ierr = MatFDColoringApply_AIJ(J,coloring,x1,sctx);CHKERRQ(ierr); 9111531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 9112531c7667SBarry Smith DM dm; 9113531c7667SBarry Smith ierr = MatGetDM(J,&dm);CHKERRQ(ierr); 9114531c7667SBarry Smith ierr = DMRestoreLocalVector(dm,&x1);CHKERRQ(ierr); 9115531c7667SBarry Smith } 9116531c7667SBarry Smith PetscFunctionReturn(0); 9117531c7667SBarry Smith } 9118531c7667SBarry Smith 9119531c7667SBarry Smith /*@ 9120531c7667SBarry Smith MatFDColoringUseDM - allows a MatFDColoring object to use the DM associated with the matrix to use a IS_COLORING_LOCAL coloring 9121531c7667SBarry Smith 9122531c7667SBarry Smith Input Parameter: 9123531c7667SBarry Smith . coloring - the MatFDColoring object 9124531c7667SBarry Smith 912595452b02SPatrick Sanan Developer Notes: 912695452b02SPatrick Sanan this routine exists because the PETSc Mat library does not know about the DM objects 9127531c7667SBarry Smith 91281b266c99SBarry Smith Level: advanced 91291b266c99SBarry Smith 9130531c7667SBarry Smith .seealso: MatFDColoring, MatFDColoringCreate(), ISColoringType 9131531c7667SBarry Smith @*/ 9132531c7667SBarry Smith PetscErrorCode MatFDColoringUseDM(Mat coloring,MatFDColoring fdcoloring) 9133531c7667SBarry Smith { 9134531c7667SBarry Smith PetscFunctionBegin; 9135531c7667SBarry Smith coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM; 9136531c7667SBarry Smith PetscFunctionReturn(0); 9137531c7667SBarry Smith } 91388320bc6fSPatrick Sanan 91398320bc6fSPatrick Sanan /*@ 91408320bc6fSPatrick Sanan DMGetCompatibility - determine if two DMs are compatible 91418320bc6fSPatrick Sanan 91428320bc6fSPatrick Sanan Collective 91438320bc6fSPatrick Sanan 91448320bc6fSPatrick Sanan Input Parameters: 9145a5bc1bf3SBarry Smith + dm1 - the first DM 91468320bc6fSPatrick Sanan - dm2 - the second DM 91478320bc6fSPatrick Sanan 91488320bc6fSPatrick Sanan Output Parameters: 91498320bc6fSPatrick Sanan + compatible - whether or not the two DMs are compatible 91508320bc6fSPatrick Sanan - set - whether or not the compatible value was set 91518320bc6fSPatrick Sanan 91528320bc6fSPatrick Sanan Notes: 91538320bc6fSPatrick Sanan Two DMs are deemed compatible if they represent the same parallel decomposition 91543d862458SPatrick Sanan of the same topology. This implies that the section (field data) on one 91558320bc6fSPatrick Sanan "makes sense" with respect to the topology and parallel decomposition of the other. 91563d862458SPatrick Sanan Loosely speaking, compatible DMs represent the same domain and parallel 91573d862458SPatrick Sanan decomposition, but hold different data. 91588320bc6fSPatrick Sanan 91598320bc6fSPatrick Sanan Typically, one would confirm compatibility if intending to simultaneously iterate 91608320bc6fSPatrick Sanan over a pair of vectors obtained from different DMs. 91618320bc6fSPatrick Sanan 91628320bc6fSPatrick Sanan For example, two DMDA objects are compatible if they have the same local 91638320bc6fSPatrick Sanan and global sizes and the same stencil width. They can have different numbers 91648320bc6fSPatrick Sanan of degrees of freedom per node. Thus, one could use the node numbering from 91658320bc6fSPatrick Sanan either DM in bounds for a loop over vectors derived from either DM. 91668320bc6fSPatrick Sanan 91678320bc6fSPatrick Sanan Consider the operation of summing data living on a 2-dof DMDA to data living 91688320bc6fSPatrick Sanan on a 1-dof DMDA, which should be compatible, as in the following snippet. 91698320bc6fSPatrick Sanan .vb 91708320bc6fSPatrick Sanan ... 91718320bc6fSPatrick Sanan ierr = DMGetCompatibility(da1,da2,&compatible,&set);CHKERRQ(ierr); 91728320bc6fSPatrick Sanan if (set && compatible) { 91738320bc6fSPatrick Sanan ierr = DMDAVecGetArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr); 91748320bc6fSPatrick Sanan ierr = DMDAVecGetArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr); 91753d862458SPatrick Sanan ierr = DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL);CHKERRQ(ierr); 91768320bc6fSPatrick Sanan for (j=y; j<y+n; ++j) { 91778320bc6fSPatrick Sanan for (i=x; i<x+m, ++i) { 91788320bc6fSPatrick Sanan arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1]; 91798320bc6fSPatrick Sanan } 91808320bc6fSPatrick Sanan } 91818320bc6fSPatrick Sanan ierr = DMDAVecRestoreArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr); 91828320bc6fSPatrick Sanan ierr = DMDAVecRestoreArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr); 91838320bc6fSPatrick Sanan } else { 91848320bc6fSPatrick Sanan SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible"); 91858320bc6fSPatrick Sanan } 91868320bc6fSPatrick Sanan ... 91878320bc6fSPatrick Sanan .ve 91888320bc6fSPatrick Sanan 91898320bc6fSPatrick Sanan Checking compatibility might be expensive for a given implementation of DM, 91908320bc6fSPatrick Sanan or might be impossible to unambiguously confirm or deny. For this reason, 91918320bc6fSPatrick Sanan this function may decline to determine compatibility, and hence users should 91928320bc6fSPatrick Sanan always check the "set" output parameter. 91938320bc6fSPatrick Sanan 91948320bc6fSPatrick Sanan A DM is always compatible with itself. 91958320bc6fSPatrick Sanan 91968320bc6fSPatrick Sanan In the current implementation, DMs which live on "unequal" communicators 91978320bc6fSPatrick Sanan (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed 91988320bc6fSPatrick Sanan incompatible. 91998320bc6fSPatrick Sanan 92008320bc6fSPatrick Sanan This function is labeled "Collective," as information about all subdomains 92018320bc6fSPatrick Sanan is required on each rank. However, in DM implementations which store all this 92028320bc6fSPatrick Sanan information locally, this function may be merely "Logically Collective". 92038320bc6fSPatrick Sanan 92048320bc6fSPatrick Sanan Developer Notes: 92053d862458SPatrick Sanan Compatibility is assumed to be a symmetric concept; DM A is compatible with DM B 92063d862458SPatrick Sanan iff B is compatible with A. Thus, this function checks the implementations 9207a5bc1bf3SBarry Smith of both dm and dmc (if they are of different types), attempting to determine 92088320bc6fSPatrick Sanan compatibility. It is left to DM implementers to ensure that symmetry is 92098320bc6fSPatrick Sanan preserved. The simplest way to do this is, when implementing type-specific 92103d862458SPatrick Sanan logic for this function, is to check for existing logic in the implementation 92113d862458SPatrick Sanan of other DM types and let *set = PETSC_FALSE if found. 92128320bc6fSPatrick Sanan 92138320bc6fSPatrick Sanan Level: advanced 92148320bc6fSPatrick Sanan 92153d862458SPatrick Sanan .seealso: DM, DMDACreateCompatibleDMDA(), DMStagCreateCompatibleDMStag() 92168320bc6fSPatrick Sanan @*/ 92178320bc6fSPatrick Sanan 9218a5bc1bf3SBarry Smith PetscErrorCode DMGetCompatibility(DM dm1,DM dm2,PetscBool *compatible,PetscBool *set) 92198320bc6fSPatrick Sanan { 92208320bc6fSPatrick Sanan PetscErrorCode ierr; 92218320bc6fSPatrick Sanan PetscMPIInt compareResult; 92228320bc6fSPatrick Sanan DMType type,type2; 92238320bc6fSPatrick Sanan PetscBool sameType; 92248320bc6fSPatrick Sanan 92258320bc6fSPatrick Sanan PetscFunctionBegin; 9226a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dm1,DM_CLASSID,1); 92278320bc6fSPatrick Sanan PetscValidHeaderSpecific(dm2,DM_CLASSID,2); 92288320bc6fSPatrick Sanan 92298320bc6fSPatrick Sanan /* Declare a DM compatible with itself */ 9230a5bc1bf3SBarry Smith if (dm1 == dm2) { 92318320bc6fSPatrick Sanan *set = PETSC_TRUE; 92328320bc6fSPatrick Sanan *compatible = PETSC_TRUE; 92338320bc6fSPatrick Sanan PetscFunctionReturn(0); 92348320bc6fSPatrick Sanan } 92358320bc6fSPatrick Sanan 92368320bc6fSPatrick Sanan /* Declare a DM incompatible with a DM that lives on an "unequal" 92378320bc6fSPatrick Sanan communicator. Note that this does not preclude compatibility with 92388320bc6fSPatrick Sanan DMs living on "congruent" or "similar" communicators, but this must be 92398320bc6fSPatrick Sanan determined by the implementation-specific logic */ 9240ffc4695bSBarry Smith ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dm1),PetscObjectComm((PetscObject)dm2),&compareResult);CHKERRMPI(ierr); 92418320bc6fSPatrick Sanan if (compareResult == MPI_UNEQUAL) { 92428320bc6fSPatrick Sanan *set = PETSC_TRUE; 92438320bc6fSPatrick Sanan *compatible = PETSC_FALSE; 92448320bc6fSPatrick Sanan PetscFunctionReturn(0); 92458320bc6fSPatrick Sanan } 92468320bc6fSPatrick Sanan 92478320bc6fSPatrick Sanan /* Pass to the implementation-specific routine, if one exists. */ 9248a5bc1bf3SBarry Smith if (dm1->ops->getcompatibility) { 9249a5bc1bf3SBarry Smith ierr = (*dm1->ops->getcompatibility)(dm1,dm2,compatible,set);CHKERRQ(ierr); 9250b9d85ea2SLisandro Dalcin if (*set) PetscFunctionReturn(0); 92518320bc6fSPatrick Sanan } 92528320bc6fSPatrick Sanan 9253a5bc1bf3SBarry Smith /* If dm1 and dm2 are of different types, then attempt to check compatibility 92548320bc6fSPatrick Sanan with an implementation of this function from dm2 */ 9255a5bc1bf3SBarry Smith ierr = DMGetType(dm1,&type);CHKERRQ(ierr); 92568320bc6fSPatrick Sanan ierr = DMGetType(dm2,&type2);CHKERRQ(ierr); 92578320bc6fSPatrick Sanan ierr = PetscStrcmp(type,type2,&sameType);CHKERRQ(ierr); 92588320bc6fSPatrick Sanan if (!sameType && dm2->ops->getcompatibility) { 9259a5bc1bf3SBarry Smith ierr = (*dm2->ops->getcompatibility)(dm2,dm1,compatible,set);CHKERRQ(ierr); /* Note argument order */ 92608320bc6fSPatrick Sanan } else { 92618320bc6fSPatrick Sanan *set = PETSC_FALSE; 92628320bc6fSPatrick Sanan } 92638320bc6fSPatrick Sanan PetscFunctionReturn(0); 92648320bc6fSPatrick Sanan } 9265c0f0dcc3SMatthew G. Knepley 9266c0f0dcc3SMatthew G. Knepley /*@C 9267c0f0dcc3SMatthew G. Knepley DMMonitorSet - Sets an ADDITIONAL function that is to be used after a solve to monitor discretization performance. 9268c0f0dcc3SMatthew G. Knepley 9269c0f0dcc3SMatthew G. Knepley Logically Collective on DM 9270c0f0dcc3SMatthew G. Knepley 9271c0f0dcc3SMatthew G. Knepley Input Parameters: 9272c0f0dcc3SMatthew G. Knepley + DM - the DM 9273c0f0dcc3SMatthew G. Knepley . f - the monitor function 9274c0f0dcc3SMatthew G. Knepley . mctx - [optional] user-defined context for private data for the monitor routine (use NULL if no context is desired) 9275c0f0dcc3SMatthew G. Knepley - monitordestroy - [optional] routine that frees monitor context (may be NULL) 9276c0f0dcc3SMatthew G. Knepley 9277c0f0dcc3SMatthew G. Knepley Options Database Keys: 9278c0f0dcc3SMatthew G. Knepley - -dm_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to DMMonitorSet(), but 9279c0f0dcc3SMatthew G. Knepley does not cancel those set via the options database. 9280c0f0dcc3SMatthew G. Knepley 9281c0f0dcc3SMatthew G. Knepley Notes: 9282c0f0dcc3SMatthew G. Knepley Several different monitoring routines may be set by calling 9283c0f0dcc3SMatthew G. Knepley DMMonitorSet() multiple times; all will be called in the 9284c0f0dcc3SMatthew G. Knepley order in which they were set. 9285c0f0dcc3SMatthew G. Knepley 9286c0f0dcc3SMatthew G. Knepley Fortran Notes: 9287c0f0dcc3SMatthew G. Knepley Only a single monitor function can be set for each DM object 9288c0f0dcc3SMatthew G. Knepley 9289c0f0dcc3SMatthew G. Knepley Level: intermediate 9290c0f0dcc3SMatthew G. Knepley 9291c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorCancel() 9292c0f0dcc3SMatthew G. Knepley @*/ 9293c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorSet(DM dm, PetscErrorCode (*f)(DM, void *), void *mctx, PetscErrorCode (*monitordestroy)(void**)) 9294c0f0dcc3SMatthew G. Knepley { 9295c0f0dcc3SMatthew G. Knepley PetscInt m; 9296c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9297c0f0dcc3SMatthew G. Knepley 9298c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9299c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9300c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 9301c0f0dcc3SMatthew G. Knepley PetscBool identical; 9302c0f0dcc3SMatthew G. Knepley 9303c0f0dcc3SMatthew G. Knepley ierr = PetscMonitorCompare((PetscErrorCode (*)(void)) f, mctx, monitordestroy, (PetscErrorCode (*)(void)) dm->monitor[m], dm->monitorcontext[m], dm->monitordestroy[m], &identical);CHKERRQ(ierr); 9304c0f0dcc3SMatthew G. Knepley if (identical) PetscFunctionReturn(0); 9305c0f0dcc3SMatthew G. Knepley } 9306c0f0dcc3SMatthew G. Knepley if (dm->numbermonitors >= MAXDMMONITORS) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 9307c0f0dcc3SMatthew G. Knepley dm->monitor[dm->numbermonitors] = f; 9308c0f0dcc3SMatthew G. Knepley dm->monitordestroy[dm->numbermonitors] = monitordestroy; 9309c0f0dcc3SMatthew G. Knepley dm->monitorcontext[dm->numbermonitors++] = (void *) mctx; 9310c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9311c0f0dcc3SMatthew G. Knepley } 9312c0f0dcc3SMatthew G. Knepley 9313c0f0dcc3SMatthew G. Knepley /*@ 9314c0f0dcc3SMatthew G. Knepley DMMonitorCancel - Clears all the monitor functions for a DM object. 9315c0f0dcc3SMatthew G. Knepley 9316c0f0dcc3SMatthew G. Knepley Logically Collective on DM 9317c0f0dcc3SMatthew G. Knepley 9318c0f0dcc3SMatthew G. Knepley Input Parameter: 9319c0f0dcc3SMatthew G. Knepley . dm - the DM 9320c0f0dcc3SMatthew G. Knepley 9321c0f0dcc3SMatthew G. Knepley Options Database Key: 9322c0f0dcc3SMatthew G. Knepley . -dm_monitor_cancel - cancels all monitors that have been hardwired 9323c0f0dcc3SMatthew G. Knepley into a code by calls to DMonitorSet(), but does not cancel those 9324c0f0dcc3SMatthew G. Knepley set via the options database 9325c0f0dcc3SMatthew G. Knepley 9326c0f0dcc3SMatthew G. Knepley Notes: 9327c0f0dcc3SMatthew G. Knepley There is no way to clear one specific monitor from a DM object. 9328c0f0dcc3SMatthew G. Knepley 9329c0f0dcc3SMatthew G. Knepley Level: intermediate 9330c0f0dcc3SMatthew G. Knepley 9331c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorSet() 9332c0f0dcc3SMatthew G. Knepley @*/ 9333c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorCancel(DM dm) 9334c0f0dcc3SMatthew G. Knepley { 9335c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9336c0f0dcc3SMatthew G. Knepley PetscInt m; 9337c0f0dcc3SMatthew G. Knepley 9338c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9339c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9340c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 9341c0f0dcc3SMatthew G. Knepley if (dm->monitordestroy[m]) {ierr = (*dm->monitordestroy[m])(&dm->monitorcontext[m]);CHKERRQ(ierr);} 9342c0f0dcc3SMatthew G. Knepley } 9343c0f0dcc3SMatthew G. Knepley dm->numbermonitors = 0; 9344c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9345c0f0dcc3SMatthew G. Knepley } 9346c0f0dcc3SMatthew G. Knepley 9347c0f0dcc3SMatthew G. Knepley /*@C 9348c0f0dcc3SMatthew G. Knepley DMMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 9349c0f0dcc3SMatthew G. Knepley 9350c0f0dcc3SMatthew G. Knepley Collective on DM 9351c0f0dcc3SMatthew G. Knepley 9352c0f0dcc3SMatthew G. Knepley Input Parameters: 9353c0f0dcc3SMatthew G. Knepley + dm - DM object you wish to monitor 9354c0f0dcc3SMatthew G. Knepley . name - the monitor type one is seeking 9355c0f0dcc3SMatthew G. Knepley . help - message indicating what monitoring is done 9356c0f0dcc3SMatthew G. Knepley . manual - manual page for the monitor 9357c0f0dcc3SMatthew G. Knepley . monitor - the monitor function 9358c0f0dcc3SMatthew 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 9359c0f0dcc3SMatthew G. Knepley 9360c0f0dcc3SMatthew G. Knepley Output Parameter: 9361c0f0dcc3SMatthew G. Knepley . flg - Flag set if the monitor was created 9362c0f0dcc3SMatthew G. Knepley 9363c0f0dcc3SMatthew G. Knepley Level: developer 9364c0f0dcc3SMatthew G. Knepley 9365c0f0dcc3SMatthew G. Knepley .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 9366c0f0dcc3SMatthew G. Knepley PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 9367c0f0dcc3SMatthew G. Knepley PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 9368c0f0dcc3SMatthew G. Knepley PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 9369c0f0dcc3SMatthew G. Knepley PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 9370c0f0dcc3SMatthew G. Knepley PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 9371c0f0dcc3SMatthew G. Knepley PetscOptionsFList(), PetscOptionsEList() 9372c0f0dcc3SMatthew G. Knepley @*/ 9373c0f0dcc3SMatthew 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) 9374c0f0dcc3SMatthew G. Knepley { 9375c0f0dcc3SMatthew G. Knepley PetscViewer viewer; 9376c0f0dcc3SMatthew G. Knepley PetscViewerFormat format; 9377c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9378c0f0dcc3SMatthew G. Knepley 9379c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9380c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9381c0f0dcc3SMatthew G. Knepley ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) dm), ((PetscObject) dm)->options, ((PetscObject) dm)->prefix, name, &viewer, &format, flg);CHKERRQ(ierr); 9382c0f0dcc3SMatthew G. Knepley if (*flg) { 9383c0f0dcc3SMatthew G. Knepley PetscViewerAndFormat *vf; 9384c0f0dcc3SMatthew G. Knepley 9385c0f0dcc3SMatthew G. Knepley ierr = PetscViewerAndFormatCreate(viewer, format, &vf);CHKERRQ(ierr); 9386c0f0dcc3SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) viewer);CHKERRQ(ierr); 9387c0f0dcc3SMatthew G. Knepley if (monitorsetup) {ierr = (*monitorsetup)(dm, vf);CHKERRQ(ierr);} 9388c0f0dcc3SMatthew G. Knepley ierr = DMMonitorSet(dm,(PetscErrorCode (*)(DM, void *)) monitor, vf, (PetscErrorCode (*)(void **)) PetscViewerAndFormatDestroy);CHKERRQ(ierr); 9389c0f0dcc3SMatthew G. Knepley } 9390c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9391c0f0dcc3SMatthew G. Knepley } 9392c0f0dcc3SMatthew G. Knepley 9393c0f0dcc3SMatthew G. Knepley /*@ 9394c0f0dcc3SMatthew G. Knepley DMMonitor - runs the user provided monitor routines, if they exist 9395c0f0dcc3SMatthew G. Knepley 9396c0f0dcc3SMatthew G. Knepley Collective on DM 9397c0f0dcc3SMatthew G. Knepley 9398c0f0dcc3SMatthew G. Knepley Input Parameters: 9399c0f0dcc3SMatthew G. Knepley . dm - The DM 9400c0f0dcc3SMatthew G. Knepley 9401c0f0dcc3SMatthew G. Knepley Level: developer 9402c0f0dcc3SMatthew G. Knepley 9403c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorSet() 9404c0f0dcc3SMatthew G. Knepley @*/ 9405c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitor(DM dm) 9406c0f0dcc3SMatthew G. Knepley { 9407c0f0dcc3SMatthew G. Knepley PetscInt m; 9408c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9409c0f0dcc3SMatthew G. Knepley 9410c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9411c0f0dcc3SMatthew G. Knepley if (!dm) PetscFunctionReturn(0); 9412c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9413c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 9414c0f0dcc3SMatthew G. Knepley ierr = (*dm->monitor[m])(dm, dm->monitorcontext[m]);CHKERRQ(ierr); 9415c0f0dcc3SMatthew G. Knepley } 9416c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9417c0f0dcc3SMatthew G. Knepley } 94182e4af2aeSMatthew G. Knepley 94192e4af2aeSMatthew G. Knepley /*@ 94202e4af2aeSMatthew G. Knepley DMComputeError - Computes the error assuming the user has given exact solution functions 94212e4af2aeSMatthew G. Knepley 94222e4af2aeSMatthew G. Knepley Collective on DM 94232e4af2aeSMatthew G. Knepley 94242e4af2aeSMatthew G. Knepley Input Parameters: 94252e4af2aeSMatthew G. Knepley + dm - The DM 94262e4af2aeSMatthew G. Knepley . sol - The solution vector 94272e4af2aeSMatthew G. Knepley . errors - An array of length Nf, the number of fields, or NULL for no output 942899c90e12SSatish Balay - errorVec - A Vec pointer, or NULL for no output 94292e4af2aeSMatthew G. Knepley 94302e4af2aeSMatthew G. Knepley Output Parameters: 94312e4af2aeSMatthew G. Knepley + errors - The error in each field 94322e4af2aeSMatthew G. Knepley - errorVec - Creates a vector to hold the cellwise error 94332e4af2aeSMatthew G. Knepley 94342e4af2aeSMatthew G. Knepley Note: The exact solutions come from the PetscDS object, and the time comes from DMGetOutputSequenceNumber(). 94352e4af2aeSMatthew G. Knepley 94362e4af2aeSMatthew G. Knepley Level: developer 94372e4af2aeSMatthew G. Knepley 94382e4af2aeSMatthew G. Knepley .seealso: DMMonitorSet(), DMGetRegionNumDS(), PetscDSGetExactSolution(), DMGetOutputSequenceNumber() 94392e4af2aeSMatthew G. Knepley @*/ 94402e4af2aeSMatthew G. Knepley PetscErrorCode DMComputeError(DM dm, Vec sol, PetscReal errors[], Vec *errorVec) 94412e4af2aeSMatthew G. Knepley { 94422e4af2aeSMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 94432e4af2aeSMatthew G. Knepley void **ctxs; 94442e4af2aeSMatthew G. Knepley PetscReal time; 94452e4af2aeSMatthew G. Knepley PetscInt Nf, f, Nds, s; 94462e4af2aeSMatthew G. Knepley PetscErrorCode ierr; 94472e4af2aeSMatthew G. Knepley 94482e4af2aeSMatthew G. Knepley PetscFunctionBegin; 94492e4af2aeSMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 94502e4af2aeSMatthew G. Knepley ierr = PetscCalloc2(Nf, &exactSol, Nf, &ctxs);CHKERRQ(ierr); 94512e4af2aeSMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 94522e4af2aeSMatthew G. Knepley for (s = 0; s < Nds; ++s) { 94532e4af2aeSMatthew G. Knepley PetscDS ds; 94542e4af2aeSMatthew G. Knepley DMLabel label; 94552e4af2aeSMatthew G. Knepley IS fieldIS; 94562e4af2aeSMatthew G. Knepley const PetscInt *fields; 94572e4af2aeSMatthew G. Knepley PetscInt dsNf; 94582e4af2aeSMatthew G. Knepley 94592e4af2aeSMatthew G. Knepley ierr = DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds);CHKERRQ(ierr); 94602e4af2aeSMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &dsNf);CHKERRQ(ierr); 94612e4af2aeSMatthew G. Knepley if (fieldIS) {ierr = ISGetIndices(fieldIS, &fields);CHKERRQ(ierr);} 94622e4af2aeSMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 94632e4af2aeSMatthew G. Knepley const PetscInt field = fields[f]; 94642e4af2aeSMatthew G. Knepley ierr = PetscDSGetExactSolution(ds, field, &exactSol[field], &ctxs[field]);CHKERRQ(ierr); 94652e4af2aeSMatthew G. Knepley } 94662e4af2aeSMatthew G. Knepley if (fieldIS) {ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr);} 94672e4af2aeSMatthew G. Knepley } 94682e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 94692e4af2aeSMatthew 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); 94702e4af2aeSMatthew G. Knepley } 94712e4af2aeSMatthew G. Knepley ierr = DMGetOutputSequenceNumber(dm, NULL, &time);CHKERRQ(ierr); 94722e4af2aeSMatthew G. Knepley if (errors) {ierr = DMComputeL2FieldDiff(dm, time, exactSol, ctxs, sol, errors);CHKERRQ(ierr);} 94732e4af2aeSMatthew G. Knepley if (errorVec) { 94742e4af2aeSMatthew G. Knepley DM edm; 94752e4af2aeSMatthew G. Knepley DMPolytopeType ct; 94762e4af2aeSMatthew G. Knepley PetscBool simplex; 94772e4af2aeSMatthew G. Knepley PetscInt dim, cStart, Nf; 94782e4af2aeSMatthew G. Knepley 94792e4af2aeSMatthew G. Knepley ierr = DMClone(dm, &edm);CHKERRQ(ierr); 94802e4af2aeSMatthew G. Knepley ierr = DMGetDimension(edm, &dim);CHKERRQ(ierr); 94812e4af2aeSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, NULL);CHKERRQ(ierr); 94822e4af2aeSMatthew G. Knepley ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 94832e4af2aeSMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 94842e4af2aeSMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 94852e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 94862e4af2aeSMatthew G. Knepley PetscFE fe, efe; 94872e4af2aeSMatthew G. Knepley PetscQuadrature q; 94882e4af2aeSMatthew G. Knepley const char *name; 94892e4af2aeSMatthew G. Knepley 94902e4af2aeSMatthew G. Knepley ierr = DMGetField(dm, f, NULL, (PetscObject *) &fe);CHKERRQ(ierr); 94912e4af2aeSMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, Nf, simplex, 0, PETSC_DETERMINE, &efe);CHKERRQ(ierr); 94922e4af2aeSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) fe, &name);CHKERRQ(ierr); 94932e4af2aeSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) efe, name);CHKERRQ(ierr); 94942e4af2aeSMatthew G. Knepley ierr = PetscFEGetQuadrature(fe, &q);CHKERRQ(ierr); 94952e4af2aeSMatthew G. Knepley ierr = PetscFESetQuadrature(efe, q);CHKERRQ(ierr); 94962e4af2aeSMatthew G. Knepley ierr = DMSetField(edm, f, NULL, (PetscObject) efe);CHKERRQ(ierr); 94972e4af2aeSMatthew G. Knepley ierr = PetscFEDestroy(&efe);CHKERRQ(ierr); 94982e4af2aeSMatthew G. Knepley } 94992e4af2aeSMatthew G. Knepley ierr = DMCreateDS(edm);CHKERRQ(ierr); 95002e4af2aeSMatthew G. Knepley 95012e4af2aeSMatthew G. Knepley ierr = DMCreateGlobalVector(edm, errorVec); 95022e4af2aeSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *errorVec, "Error");CHKERRQ(ierr); 95032e4af2aeSMatthew G. Knepley ierr = DMPlexComputeL2DiffVec(dm, time, exactSol, ctxs, sol, *errorVec);CHKERRQ(ierr); 95042e4af2aeSMatthew G. Knepley ierr = DMDestroy(&edm);CHKERRQ(ierr); 95052e4af2aeSMatthew G. Knepley } 95062e4af2aeSMatthew G. Knepley ierr = PetscFree2(exactSol, ctxs);CHKERRQ(ierr); 95072e4af2aeSMatthew G. Knepley PetscFunctionReturn(0); 95082e4af2aeSMatthew G. Knepley } 95099a2a23afSMatthew G. Knepley 95109a2a23afSMatthew G. Knepley /*@ 95119a2a23afSMatthew G. Knepley DMGetNumAuxiliaryVec - Get the number of auxiliary vectors associated with this DM 95129a2a23afSMatthew G. Knepley 95139a2a23afSMatthew G. Knepley Not collective 95149a2a23afSMatthew G. Knepley 95159a2a23afSMatthew G. Knepley Input Parameter: 95169a2a23afSMatthew G. Knepley . dm - The DM 95179a2a23afSMatthew G. Knepley 95189a2a23afSMatthew G. Knepley Output Parameter: 95199a2a23afSMatthew G. Knepley . numAux - The nubmer of auxiliary data vectors 95209a2a23afSMatthew G. Knepley 95219a2a23afSMatthew G. Knepley Level: advanced 95229a2a23afSMatthew G. Knepley 95239a2a23afSMatthew G. Knepley .seealso: DMGetAuxiliaryLabels(), DMGetAuxiliaryVec(), DMSetAuxiliaryVec() 95249a2a23afSMatthew G. Knepley @*/ 95259a2a23afSMatthew G. Knepley PetscErrorCode DMGetNumAuxiliaryVec(DM dm, PetscInt *numAux) 95269a2a23afSMatthew G. Knepley { 95279a2a23afSMatthew G. Knepley PetscErrorCode ierr; 95289a2a23afSMatthew G. Knepley 95299a2a23afSMatthew G. Knepley PetscFunctionBegin; 95309a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 95319a2a23afSMatthew G. Knepley ierr = PetscHMapAuxGetSize(dm->auxData, numAux);CHKERRQ(ierr); 95329a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 95339a2a23afSMatthew G. Knepley } 95349a2a23afSMatthew G. Knepley 95359a2a23afSMatthew G. Knepley /*@ 95369a2a23afSMatthew G. Knepley DMGetAuxiliaryVec - Get the auxiliary vector for region specified by the given label and value 95379a2a23afSMatthew G. Knepley 95389a2a23afSMatthew G. Knepley Not collective 95399a2a23afSMatthew G. Knepley 95409a2a23afSMatthew G. Knepley Input Parameters: 95419a2a23afSMatthew G. Knepley + dm - The DM 95429a2a23afSMatthew G. Knepley . label - The DMLabel 95439a2a23afSMatthew G. Knepley - value - The label value indicating the region 95449a2a23afSMatthew G. Knepley 95459a2a23afSMatthew G. Knepley Output Parameter: 95469a2a23afSMatthew G. Knepley . aux - The Vec holding auxiliary field data 95479a2a23afSMatthew G. Knepley 95489a2a23afSMatthew G. Knepley Level: advanced 95499a2a23afSMatthew G. Knepley 95509a2a23afSMatthew G. Knepley .seealso: DMSetAuxiliaryVec(), DMGetNumAuxiliaryVec() 95519a2a23afSMatthew G. Knepley @*/ 95529a2a23afSMatthew G. Knepley PetscErrorCode DMGetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, Vec *aux) 95539a2a23afSMatthew G. Knepley { 95549a2a23afSMatthew G. Knepley PetscHashAuxKey key; 95559a2a23afSMatthew G. Knepley PetscErrorCode ierr; 95569a2a23afSMatthew G. Knepley 95579a2a23afSMatthew G. Knepley PetscFunctionBegin; 95589a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 95599a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 95609a2a23afSMatthew G. Knepley key.label = label; 95619a2a23afSMatthew G. Knepley key.value = value; 95629a2a23afSMatthew G. Knepley ierr = PetscHMapAuxGet(dm->auxData, key, aux);CHKERRQ(ierr); 95639a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 95649a2a23afSMatthew G. Knepley } 95659a2a23afSMatthew G. Knepley 95669a2a23afSMatthew G. Knepley /*@ 95679a2a23afSMatthew G. Knepley DMSetAuxiliaryVec - Set the auxiliary vector for region specified by the given label and value 95689a2a23afSMatthew G. Knepley 95699a2a23afSMatthew G. Knepley Not collective 95709a2a23afSMatthew G. Knepley 95719a2a23afSMatthew G. Knepley Input Parameters: 95729a2a23afSMatthew G. Knepley + dm - The DM 95739a2a23afSMatthew G. Knepley . label - The DMLabel 95749a2a23afSMatthew G. Knepley . value - The label value indicating the region 95759a2a23afSMatthew G. Knepley - aux - The Vec holding auxiliary field data 95769a2a23afSMatthew G. Knepley 95779a2a23afSMatthew G. Knepley Level: advanced 95789a2a23afSMatthew G. Knepley 95799a2a23afSMatthew G. Knepley .seealso: DMGetAuxiliaryVec() 95809a2a23afSMatthew G. Knepley @*/ 95819a2a23afSMatthew G. Knepley PetscErrorCode DMSetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, Vec aux) 95829a2a23afSMatthew G. Knepley { 95839a2a23afSMatthew G. Knepley Vec old; 95849a2a23afSMatthew G. Knepley PetscHashAuxKey key; 95859a2a23afSMatthew G. Knepley PetscErrorCode ierr; 95869a2a23afSMatthew G. Knepley 95879a2a23afSMatthew G. Knepley PetscFunctionBegin; 95889a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 95899a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 95909a2a23afSMatthew G. Knepley key.label = label; 95919a2a23afSMatthew G. Knepley key.value = value; 95929a2a23afSMatthew G. Knepley ierr = PetscHMapAuxGet(dm->auxData, key, &old);CHKERRQ(ierr); 95939a2a23afSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) aux);CHKERRQ(ierr); 95949a2a23afSMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) old);CHKERRQ(ierr); 95959a2a23afSMatthew G. Knepley if (!aux) {ierr = PetscHMapAuxDel(dm->auxData, key);CHKERRQ(ierr);} 95969a2a23afSMatthew G. Knepley else {ierr = PetscHMapAuxSet(dm->auxData, key, aux);CHKERRQ(ierr);} 95979a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 95989a2a23afSMatthew G. Knepley } 95999a2a23afSMatthew G. Knepley 96009a2a23afSMatthew G. Knepley /*@C 96019a2a23afSMatthew G. Knepley DMGetAuxiliaryLabels - Get the labels and values for all auxiliary vectors in this DM 96029a2a23afSMatthew G. Knepley 96039a2a23afSMatthew G. Knepley Not collective 96049a2a23afSMatthew G. Knepley 96059a2a23afSMatthew G. Knepley Input Parameter: 96069a2a23afSMatthew G. Knepley . dm - The DM 96079a2a23afSMatthew G. Knepley 96089a2a23afSMatthew G. Knepley Output Parameters: 96099a2a23afSMatthew G. Knepley + labels - The DMLabels for each Vec 96109a2a23afSMatthew G. Knepley - values - The label values for each Vec 96119a2a23afSMatthew G. Knepley 96129a2a23afSMatthew G. Knepley Note: The arrays passed in must be at least as large as DMGetNumAuxiliaryVec(). 96139a2a23afSMatthew G. Knepley 96149a2a23afSMatthew G. Knepley Level: advanced 96159a2a23afSMatthew G. Knepley 96169a2a23afSMatthew G. Knepley .seealso: DMGetNumAuxiliaryVec(), DMGetAuxiliaryVec(), DMSetAuxiliaryVec() 96179a2a23afSMatthew G. Knepley @*/ 96189a2a23afSMatthew G. Knepley PetscErrorCode DMGetAuxiliaryLabels(DM dm, DMLabel labels[], PetscInt values[]) 96199a2a23afSMatthew G. Knepley { 96209a2a23afSMatthew G. Knepley PetscHashAuxKey *keys; 96219a2a23afSMatthew G. Knepley PetscInt n, i, off = 0; 96229a2a23afSMatthew G. Knepley PetscErrorCode ierr; 96239a2a23afSMatthew G. Knepley 96249a2a23afSMatthew G. Knepley PetscFunctionBegin; 96259a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 96269a2a23afSMatthew G. Knepley PetscValidPointer(labels, 2); 96279a2a23afSMatthew G. Knepley PetscValidPointer(values, 3); 96289a2a23afSMatthew G. Knepley ierr = DMGetNumAuxiliaryVec(dm, &n);CHKERRQ(ierr); 96299a2a23afSMatthew G. Knepley ierr = PetscMalloc1(n, &keys);CHKERRQ(ierr); 96309a2a23afSMatthew G. Knepley ierr = PetscHMapAuxGetKeys(dm->auxData, &off, keys);CHKERRQ(ierr); 96319a2a23afSMatthew G. Knepley for (i = 0; i < n; ++i) {labels[i] = keys[i].label; values[i] = keys[i].value;} 96329a2a23afSMatthew G. Knepley ierr = PetscFree(keys);CHKERRQ(ierr); 96339a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 96349a2a23afSMatthew G. Knepley } 96359a2a23afSMatthew G. Knepley 96369a2a23afSMatthew G. Knepley /*@ 96379a2a23afSMatthew G. Knepley DMCopyAuxiliaryVec - Copy the auxiliary data to a new DM 96389a2a23afSMatthew G. Knepley 96399a2a23afSMatthew G. Knepley Not collective 96409a2a23afSMatthew G. Knepley 96419a2a23afSMatthew G. Knepley Input Parameter: 96429a2a23afSMatthew G. Knepley . dm - The DM 96439a2a23afSMatthew G. Knepley 96449a2a23afSMatthew G. Knepley Output Parameter: 96459a2a23afSMatthew G. Knepley . dmNew - The new DM, now with the same auxiliary data 96469a2a23afSMatthew G. Knepley 96479a2a23afSMatthew G. Knepley Level: advanced 96489a2a23afSMatthew G. Knepley 96499a2a23afSMatthew G. Knepley .seealso: DMGetNumAuxiliaryVec(), DMGetAuxiliaryVec(), DMSetAuxiliaryVec() 96509a2a23afSMatthew G. Knepley @*/ 96519a2a23afSMatthew G. Knepley PetscErrorCode DMCopyAuxiliaryVec(DM dm, DM dmNew) 96529a2a23afSMatthew G. Knepley { 96539a2a23afSMatthew G. Knepley PetscErrorCode ierr; 96549a2a23afSMatthew G. Knepley 96559a2a23afSMatthew G. Knepley PetscFunctionBegin; 96569a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 96579a2a23afSMatthew G. Knepley ierr = PetscHMapAuxDestroy(&dmNew->auxData);CHKERRQ(ierr); 96589a2a23afSMatthew G. Knepley ierr = PetscHMapAuxDuplicate(dm->auxData, &dmNew->auxData);CHKERRQ(ierr); 96599a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 96609a2a23afSMatthew G. Knepley } 9661