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 10f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 11f918ec44SMatthew G. Knepley #include <petscfeceed.h> 12f918ec44SMatthew G. Knepley #endif 13f918ec44SMatthew G. Knepley 1400d952a4SJed Brown #if defined(PETSC_HAVE_VALGRIND) 1500d952a4SJed Brown # include <valgrind/memcheck.h> 1600d952a4SJed Brown #endif 1700d952a4SJed Brown 18732e2eb9SMatthew G Knepley PetscClassId DM_CLASSID; 19d67d17b1SMatthew G. Knepley PetscClassId DMLABEL_CLASSID; 20557cf195SMatthew 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; 2167a56275SMatthew G Knepley 22ea78f98cSLisandro Dalcin const char *const DMBoundaryTypes[] = {"NONE","GHOSTED","MIRROR","PERIODIC","TWIST","DMBoundaryType","DM_BOUNDARY_", NULL}; 23d1b3049bSMatthew G. Knepley const char *const DMBoundaryConditionTypes[] = {"INVALID","ESSENTIAL","NATURAL","INVALID","INVALID","ESSENTIAL_FIELD","NATURAL_FIELD","INVALID","INVALID","ESSENTIAL_BD_FIELD","NATURAL_RIEMANN","DMBoundaryConditionType","DM_BC_", NULL}; 24da9060c4SMatthew 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}; 252cbb9b06SVaclav Hapla const char *const DMCopyLabelsModes[] = {"replace","keep","fail","DMCopyLabelsMode","DM_COPY_LABELS_", NULL}; 2660c22052SBarry Smith 27a4121054SBarry Smith /*@ 28de043629SMatthew G Knepley DMCreate - Creates an empty DM object. The type can then be set with DMSetType(). 29a4121054SBarry Smith 30a4121054SBarry Smith If you never call DMSetType() it will generate an 31a4121054SBarry Smith error when you try to use the vector. 32a4121054SBarry Smith 33d083f849SBarry Smith Collective 34a4121054SBarry Smith 35a4121054SBarry Smith Input Parameter: 36a4121054SBarry Smith . comm - The communicator for the DM object 37a4121054SBarry Smith 38a4121054SBarry Smith Output Parameter: 39a4121054SBarry Smith . dm - The DM object 40a4121054SBarry Smith 41a4121054SBarry Smith Level: beginner 42a4121054SBarry Smith 438472ad0fSDave May .seealso: DMSetType(), DMDA, DMSLICED, DMCOMPOSITE, DMPLEX, DMMOAB, DMNETWORK 44a4121054SBarry Smith @*/ 457087cfbeSBarry Smith PetscErrorCode DMCreate(MPI_Comm comm,DM *dm) 46a4121054SBarry Smith { 47a4121054SBarry Smith DM v; 48e5e52638SMatthew G. Knepley PetscDS ds; 49a4121054SBarry Smith PetscErrorCode ierr; 50a4121054SBarry Smith 51a4121054SBarry Smith PetscFunctionBegin; 521411c6eeSJed Brown PetscValidPointer(dm,2); 530298fd71SBarry Smith *dm = NULL; 54607a6623SBarry Smith ierr = DMInitializePackage();CHKERRQ(ierr); 55a4121054SBarry Smith 5673107ff1SLisandro Dalcin ierr = PetscHeaderCreate(v, DM_CLASSID, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView);CHKERRQ(ierr); 57e7c4fc90SDmitry Karpeev 5849be4549SMatthew G. Knepley v->setupcalled = PETSC_FALSE; 5949be4549SMatthew G. Knepley v->setfromoptionscalled = PETSC_FALSE; 600298fd71SBarry Smith v->ltogmap = NULL; 61a4ea9b21SRichard Tran Mills v->bind_below = 0; 621411c6eeSJed Brown v->bs = 1; 63171400e9SBarry Smith v->coloringtype = IS_COLORING_GLOBAL; 6488ed4aceSMatthew G Knepley ierr = PetscSFCreate(comm, &v->sf);CHKERRQ(ierr); 651bb6d2a8SBarry Smith ierr = PetscSFCreate(comm, &v->sectionSF);CHKERRQ(ierr); 66c58f1c22SToby Isaac v->labels = NULL; 6734aa8a36SMatthew G. Knepley v->adjacency[0] = PETSC_FALSE; 6834aa8a36SMatthew G. Knepley v->adjacency[1] = PETSC_TRUE; 69c58f1c22SToby Isaac v->depthLabel = NULL; 70ba2698f1SMatthew G. Knepley v->celltypeLabel = NULL; 711bb6d2a8SBarry Smith v->localSection = NULL; 721bb6d2a8SBarry Smith v->globalSection = NULL; 73fba222abSToby Isaac v->defaultConstraintSection = NULL; 74fba222abSToby Isaac v->defaultConstraintMat = NULL; 75c6b900c6SMatthew G. Knepley v->L = NULL; 76c6b900c6SMatthew G. Knepley v->maxCell = NULL; 775dc8c3f7SMatthew G. Knepley v->bdtype = NULL; 789a9a41abSToby Isaac v->dimEmbed = PETSC_DEFAULT; 7996173672SStefano Zampini v->dim = PETSC_DETERMINE; 80435a35e8SMatthew G Knepley { 81435a35e8SMatthew G Knepley PetscInt i; 82435a35e8SMatthew G Knepley for (i = 0; i < 10; ++i) { 830298fd71SBarry Smith v->nullspaceConstructors[i] = NULL; 84f9d4088aSMatthew G. Knepley v->nearnullspaceConstructors[i] = NULL; 85435a35e8SMatthew G Knepley } 86435a35e8SMatthew G Knepley } 8745480ffeSMatthew G. Knepley ierr = PetscDSCreate(PETSC_COMM_SELF, &ds);CHKERRQ(ierr); 88b3cf3223SMatthew G. Knepley ierr = DMSetRegionDS(v, NULL, NULL, ds);CHKERRQ(ierr); 89e5e52638SMatthew G. Knepley ierr = PetscDSDestroy(&ds);CHKERRQ(ierr); 909a2a23afSMatthew G. Knepley ierr = PetscHMapAuxCreate(&v->auxData);CHKERRQ(ierr); 9114f150ffSMatthew G. Knepley v->dmBC = NULL; 92a8fb8f29SToby Isaac v->coarseMesh = NULL; 93f4d763aaSMatthew G. Knepley v->outputSequenceNum = -1; 94cdb7a50dSMatthew G. Knepley v->outputSequenceVal = 0.0; 95c0dedaeaSBarry Smith ierr = DMSetVecType(v,VECSTANDARD);CHKERRQ(ierr); 96b412c318SBarry Smith ierr = DMSetMatType(v,MATAIJ);CHKERRQ(ierr); 974a7a4c06SLawrence Mitchell 981411c6eeSJed Brown *dm = v; 99a4121054SBarry Smith PetscFunctionReturn(0); 100a4121054SBarry Smith } 101a4121054SBarry Smith 10238221697SMatthew G. Knepley /*@ 10338221697SMatthew G. Knepley DMClone - Creates a DM object with the same topology as the original. 10438221697SMatthew G. Knepley 105d083f849SBarry Smith Collective 10638221697SMatthew G. Knepley 10738221697SMatthew G. Knepley Input Parameter: 10838221697SMatthew G. Knepley . dm - The original DM object 10938221697SMatthew G. Knepley 11038221697SMatthew G. Knepley Output Parameter: 11138221697SMatthew G. Knepley . newdm - The new DM object 11238221697SMatthew G. Knepley 11338221697SMatthew G. Knepley Level: beginner 11438221697SMatthew G. Knepley 1151cb8cacdSPatrick Sanan Notes: 1161cb8cacdSPatrick Sanan For some DM implementations this is a shallow clone, the result of which may share (referent counted) information with its parent. For example, 1171cb8cacdSPatrick Sanan DMClone() applied to a DMPLEX object will result in a new DMPLEX that shares the topology with the original DMPLEX. It does not 1181cb8cacdSPatrick Sanan share the PetscSection of the original DM. 1191bb6d2a8SBarry Smith 12089706ed2SPatrick Sanan The clone is considered set up iff the original is. 12189706ed2SPatrick Sanan 12292cfd99aSMartin Diehl .seealso: DMDestroy(), DMCreate(), DMSetType(), DMSetLocalSection(), DMSetGlobalSection() 1231bb6d2a8SBarry Smith 12438221697SMatthew G. Knepley @*/ 12538221697SMatthew G. Knepley PetscErrorCode DMClone(DM dm, DM *newdm) 12638221697SMatthew G. Knepley { 12738221697SMatthew G. Knepley PetscSF sf; 12838221697SMatthew G. Knepley Vec coords; 12938221697SMatthew G. Knepley void *ctx; 130a3219837SMatthew G. Knepley PetscInt dim, cdim; 13138221697SMatthew G. Knepley PetscErrorCode ierr; 13238221697SMatthew G. Knepley 13338221697SMatthew G. Knepley PetscFunctionBegin; 13438221697SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 13538221697SMatthew G. Knepley PetscValidPointer(newdm,2); 13638221697SMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject) dm), newdm);CHKERRQ(ierr); 1372cbb9b06SVaclav Hapla ierr = DMCopyLabels(dm, *newdm, PETSC_COPY_VALUES, PETSC_TRUE, DM_COPY_LABELS_FAIL);CHKERRQ(ierr); 138ddf8437dSMatthew G. Knepley (*newdm)->leveldown = dm->leveldown; 139ddf8437dSMatthew G. Knepley (*newdm)->levelup = dm->levelup; 140c8a6034eSMark (*newdm)->prealloc_only = dm->prealloc_only; 141a587d139SMark ierr = PetscFree((*newdm)->vectype);CHKERRQ(ierr); 142a587d139SMark ierr = PetscStrallocpy(dm->vectype,(char**)&(*newdm)->vectype);CHKERRQ(ierr); 143a587d139SMark ierr = PetscFree((*newdm)->mattype);CHKERRQ(ierr); 144a587d139SMark ierr = PetscStrallocpy(dm->mattype,(char**)&(*newdm)->mattype);CHKERRQ(ierr); 1451de53e9aSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1461de53e9aSMatthew G. Knepley ierr = DMSetDimension(*newdm, dim);CHKERRQ(ierr); 14738221697SMatthew G. Knepley if (dm->ops->clone) { 14838221697SMatthew G. Knepley ierr = (*dm->ops->clone)(dm, newdm);CHKERRQ(ierr); 14938221697SMatthew G. Knepley } 1503f22bcbcSToby Isaac (*newdm)->setupcalled = dm->setupcalled; 15138221697SMatthew G. Knepley ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 15238221697SMatthew G. Knepley ierr = DMSetPointSF(*newdm, sf);CHKERRQ(ierr); 15338221697SMatthew G. Knepley ierr = DMGetApplicationContext(dm, &ctx);CHKERRQ(ierr); 15438221697SMatthew G. Knepley ierr = DMSetApplicationContext(*newdm, ctx);CHKERRQ(ierr); 155be4c1c3eSMatthew G. Knepley if (dm->coordinateDM) { 156be4c1c3eSMatthew G. Knepley DM ncdm; 157be4c1c3eSMatthew G. Knepley PetscSection cs; 1585a0206caSToby Isaac PetscInt pEnd = -1, pEndMax = -1; 159be4c1c3eSMatthew G. Knepley 16092fd8e1eSJed Brown ierr = DMGetLocalSection(dm->coordinateDM, &cs);CHKERRQ(ierr); 161be4c1c3eSMatthew G. Knepley if (cs) {ierr = PetscSectionGetChart(cs, NULL, &pEnd);CHKERRQ(ierr);} 162ffc4695bSBarry Smith ierr = MPI_Allreduce(&pEnd,&pEndMax,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 1635a0206caSToby Isaac if (pEndMax >= 0) { 164be4c1c3eSMatthew G. Knepley ierr = DMClone(dm->coordinateDM, &ncdm);CHKERRQ(ierr); 16583bfc06fSMatthew Knepley ierr = DMCopyDisc(dm->coordinateDM, ncdm);CHKERRQ(ierr); 16692fd8e1eSJed Brown ierr = DMSetLocalSection(ncdm, cs);CHKERRQ(ierr); 167a61e840bSMatthew G. Knepley ierr = DMSetCoordinateDM(*newdm, ncdm);CHKERRQ(ierr); 168be4c1c3eSMatthew G. Knepley ierr = DMDestroy(&ncdm);CHKERRQ(ierr); 169be4c1c3eSMatthew G. Knepley } 170be4c1c3eSMatthew G. Knepley } 171a3219837SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 172a3219837SMatthew G. Knepley ierr = DMSetCoordinateDim(*newdm, cdim);CHKERRQ(ierr); 17338221697SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coords);CHKERRQ(ierr); 17438221697SMatthew G. Knepley if (coords) { 17538221697SMatthew G. Knepley ierr = DMSetCoordinatesLocal(*newdm, coords);CHKERRQ(ierr); 17638221697SMatthew G. Knepley } else { 17738221697SMatthew G. Knepley ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr); 17838221697SMatthew G. Knepley if (coords) {ierr = DMSetCoordinates(*newdm, coords);CHKERRQ(ierr);} 17938221697SMatthew G. Knepley } 18090b157c4SStefano Zampini { 18190b157c4SStefano Zampini PetscBool isper; 182c6b900c6SMatthew G. Knepley const PetscReal *maxCell, *L; 1835dc8c3f7SMatthew G. Knepley const DMBoundaryType *bd; 18490b157c4SStefano Zampini ierr = DMGetPeriodicity(dm, &isper, &maxCell, &L, &bd);CHKERRQ(ierr); 18590b157c4SStefano Zampini ierr = DMSetPeriodicity(*newdm, isper, maxCell, L, bd);CHKERRQ(ierr); 186c6b900c6SMatthew G. Knepley } 18734aa8a36SMatthew G. Knepley { 18834aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 18934aa8a36SMatthew G. Knepley 19034aa8a36SMatthew G. Knepley ierr = DMGetAdjacency(dm, PETSC_DEFAULT, &useCone, &useClosure);CHKERRQ(ierr); 19134aa8a36SMatthew G. Knepley ierr = DMSetAdjacency(*newdm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr); 19234aa8a36SMatthew G. Knepley } 19338221697SMatthew G. Knepley PetscFunctionReturn(0); 19438221697SMatthew G. Knepley } 19538221697SMatthew G. Knepley 1969a42bb27SBarry Smith /*@C 197564755cdSBarry Smith DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector() 1989a42bb27SBarry Smith 199d083f849SBarry Smith Logically Collective on da 2009a42bb27SBarry Smith 2019a42bb27SBarry Smith Input Parameter: 2029a42bb27SBarry Smith + da - initial distributed array 203e9e886b6SKarl Rupp . ctype - the vector type, currently either VECSTANDARD, VECCUDA, or VECVIENNACL 2049a42bb27SBarry Smith 2059a42bb27SBarry Smith Options Database: 206dd85299cSBarry Smith . -dm_vec_type ctype 2079a42bb27SBarry Smith 2089a42bb27SBarry Smith Level: intermediate 2099a42bb27SBarry Smith 210a2a9ebe5SBarry Smith .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType, DMGetVecType(), DMSetMatType(), DMGetMatType() 2119a42bb27SBarry Smith @*/ 21219fd82e9SBarry Smith PetscErrorCode DMSetVecType(DM da,VecType ctype) 2139a42bb27SBarry Smith { 2149a42bb27SBarry Smith PetscErrorCode ierr; 2159a42bb27SBarry Smith 2169a42bb27SBarry Smith PetscFunctionBegin; 2179a42bb27SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 2189a42bb27SBarry Smith ierr = PetscFree(da->vectype);CHKERRQ(ierr); 21919fd82e9SBarry Smith ierr = PetscStrallocpy(ctype,(char**)&da->vectype);CHKERRQ(ierr); 2209a42bb27SBarry Smith PetscFunctionReturn(0); 2219a42bb27SBarry Smith } 2229a42bb27SBarry Smith 223c0dedaeaSBarry Smith /*@C 224c0dedaeaSBarry Smith DMGetVecType - Gets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector() 225c0dedaeaSBarry Smith 226d083f849SBarry Smith Logically Collective on da 227c0dedaeaSBarry Smith 228c0dedaeaSBarry Smith Input Parameter: 229c0dedaeaSBarry Smith . da - initial distributed array 230c0dedaeaSBarry Smith 231c0dedaeaSBarry Smith Output Parameter: 232c0dedaeaSBarry Smith . ctype - the vector type 233c0dedaeaSBarry Smith 234c0dedaeaSBarry Smith Level: intermediate 235c0dedaeaSBarry Smith 236a2a9ebe5SBarry Smith .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType, DMSetMatType(), DMGetMatType(), DMSetVecType() 237c0dedaeaSBarry Smith @*/ 238c0dedaeaSBarry Smith PetscErrorCode DMGetVecType(DM da,VecType *ctype) 239c0dedaeaSBarry Smith { 240c0dedaeaSBarry Smith PetscFunctionBegin; 241c0dedaeaSBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 242c0dedaeaSBarry Smith *ctype = da->vectype; 243c0dedaeaSBarry Smith PetscFunctionReturn(0); 244c0dedaeaSBarry Smith } 245c0dedaeaSBarry Smith 2465f1ad066SMatthew G Knepley /*@ 24734f98d34SBarry Smith VecGetDM - Gets the DM defining the data layout of the vector 2485f1ad066SMatthew G Knepley 2495f1ad066SMatthew G Knepley Not collective 2505f1ad066SMatthew G Knepley 2515f1ad066SMatthew G Knepley Input Parameter: 2525f1ad066SMatthew G Knepley . v - The Vec 2535f1ad066SMatthew G Knepley 2545f1ad066SMatthew G Knepley Output Parameter: 2555f1ad066SMatthew G Knepley . dm - The DM 2565f1ad066SMatthew G Knepley 2575f1ad066SMatthew G Knepley Level: intermediate 2585f1ad066SMatthew G Knepley 2595f1ad066SMatthew G Knepley .seealso: VecSetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType() 2605f1ad066SMatthew G Knepley @*/ 2615f1ad066SMatthew G Knepley PetscErrorCode VecGetDM(Vec v, DM *dm) 2625f1ad066SMatthew G Knepley { 2635f1ad066SMatthew G Knepley PetscErrorCode ierr; 2645f1ad066SMatthew G Knepley 2655f1ad066SMatthew G Knepley PetscFunctionBegin; 2665f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,1); 2675f1ad066SMatthew G Knepley PetscValidPointer(dm,2); 2685f1ad066SMatthew G Knepley ierr = PetscObjectQuery((PetscObject) v, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr); 2695f1ad066SMatthew G Knepley PetscFunctionReturn(0); 2705f1ad066SMatthew G Knepley } 2715f1ad066SMatthew G Knepley 2725f1ad066SMatthew G Knepley /*@ 273d9805387SMatthew G. Knepley VecSetDM - Sets the DM defining the data layout of the vector. 2745f1ad066SMatthew G Knepley 2755f1ad066SMatthew G Knepley Not collective 2765f1ad066SMatthew G Knepley 2775f1ad066SMatthew G Knepley Input Parameters: 2785f1ad066SMatthew G Knepley + v - The Vec 2795f1ad066SMatthew G Knepley - dm - The DM 2805f1ad066SMatthew G Knepley 281d9805387SMatthew 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. 282d9805387SMatthew G. Knepley 2835f1ad066SMatthew G Knepley Level: intermediate 2845f1ad066SMatthew G Knepley 2855f1ad066SMatthew G Knepley .seealso: VecGetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType() 2865f1ad066SMatthew G Knepley @*/ 2875f1ad066SMatthew G Knepley PetscErrorCode VecSetDM(Vec v, DM dm) 2885f1ad066SMatthew G Knepley { 2895f1ad066SMatthew G Knepley PetscErrorCode ierr; 2905f1ad066SMatthew G Knepley 2915f1ad066SMatthew G Knepley PetscFunctionBegin; 2925f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,1); 293d7f50e27SLisandro Dalcin if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2); 2945f1ad066SMatthew G Knepley ierr = PetscObjectCompose((PetscObject) v, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 2955f1ad066SMatthew G Knepley PetscFunctionReturn(0); 2965f1ad066SMatthew G Knepley } 2975f1ad066SMatthew G Knepley 298521d9a4cSLisandro Dalcin /*@C 2998f1509bcSBarry Smith DMSetISColoringType - Sets the type of coloring, global or local, that is created by the DM 3008f1509bcSBarry Smith 301d083f849SBarry Smith Logically Collective on dm 3028f1509bcSBarry Smith 3038f1509bcSBarry Smith Input Parameters: 3048f1509bcSBarry Smith + dm - the DM context 3058f1509bcSBarry Smith - ctype - the matrix type 3068f1509bcSBarry Smith 3078f1509bcSBarry Smith Options Database: 3088f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3098f1509bcSBarry Smith 3108f1509bcSBarry Smith Level: intermediate 3118f1509bcSBarry Smith 3128f1509bcSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(), 3138f1509bcSBarry Smith DMGetISColoringType() 3148f1509bcSBarry Smith @*/ 3158f1509bcSBarry Smith PetscErrorCode DMSetISColoringType(DM dm,ISColoringType ctype) 3168f1509bcSBarry Smith { 3178f1509bcSBarry Smith PetscFunctionBegin; 3188f1509bcSBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3198f1509bcSBarry Smith dm->coloringtype = ctype; 3208f1509bcSBarry Smith PetscFunctionReturn(0); 3218f1509bcSBarry Smith } 3228f1509bcSBarry Smith 3238f1509bcSBarry Smith /*@C 3248f1509bcSBarry Smith DMGetISColoringType - Gets the type of coloring, global or local, that is created by the DM 325521d9a4cSLisandro Dalcin 326d083f849SBarry Smith Logically Collective on dm 327521d9a4cSLisandro Dalcin 328521d9a4cSLisandro Dalcin Input Parameter: 3298f1509bcSBarry Smith . dm - the DM context 3308f1509bcSBarry Smith 3318f1509bcSBarry Smith Output Parameter: 3328f1509bcSBarry Smith . ctype - the matrix type 3338f1509bcSBarry Smith 3348f1509bcSBarry Smith Options Database: 3358f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3368f1509bcSBarry Smith 3378f1509bcSBarry Smith Level: intermediate 3388f1509bcSBarry Smith 3398f1509bcSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(), 3408f1509bcSBarry Smith DMGetISColoringType() 3418f1509bcSBarry Smith @*/ 3428f1509bcSBarry Smith PetscErrorCode DMGetISColoringType(DM dm,ISColoringType *ctype) 3438f1509bcSBarry Smith { 3448f1509bcSBarry Smith PetscFunctionBegin; 3458f1509bcSBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3468f1509bcSBarry Smith *ctype = dm->coloringtype; 3478f1509bcSBarry Smith PetscFunctionReturn(0); 3488f1509bcSBarry Smith } 3498f1509bcSBarry Smith 3508f1509bcSBarry Smith /*@C 3518f1509bcSBarry Smith DMSetMatType - Sets the type of matrix created with DMCreateMatrix() 3528f1509bcSBarry Smith 353d083f849SBarry Smith Logically Collective on dm 3548f1509bcSBarry Smith 3558f1509bcSBarry Smith Input Parameters: 356521d9a4cSLisandro Dalcin + dm - the DM context 357a2b5a043SBarry Smith - ctype - the matrix type 358521d9a4cSLisandro Dalcin 359521d9a4cSLisandro Dalcin Options Database: 360521d9a4cSLisandro Dalcin . -dm_mat_type ctype 361521d9a4cSLisandro Dalcin 362521d9a4cSLisandro Dalcin Level: intermediate 363521d9a4cSLisandro Dalcin 364a2a9ebe5SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(), DMSetMatType(), DMGetMatType() 365521d9a4cSLisandro Dalcin @*/ 36619fd82e9SBarry Smith PetscErrorCode DMSetMatType(DM dm,MatType ctype) 367521d9a4cSLisandro Dalcin { 368521d9a4cSLisandro Dalcin PetscErrorCode ierr; 36988f0584fSBarry Smith 370521d9a4cSLisandro Dalcin PetscFunctionBegin; 371521d9a4cSLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 372521d9a4cSLisandro Dalcin ierr = PetscFree(dm->mattype);CHKERRQ(ierr); 37319fd82e9SBarry Smith ierr = PetscStrallocpy(ctype,(char**)&dm->mattype);CHKERRQ(ierr); 374521d9a4cSLisandro Dalcin PetscFunctionReturn(0); 375521d9a4cSLisandro Dalcin } 376521d9a4cSLisandro Dalcin 377c0dedaeaSBarry Smith /*@C 378c0dedaeaSBarry Smith DMGetMatType - Gets the type of matrix created with DMCreateMatrix() 379c0dedaeaSBarry Smith 380d083f849SBarry Smith Logically Collective on dm 381c0dedaeaSBarry Smith 382c0dedaeaSBarry Smith Input Parameter: 383c0dedaeaSBarry Smith . dm - the DM context 384c0dedaeaSBarry Smith 385c0dedaeaSBarry Smith Output Parameter: 386c0dedaeaSBarry Smith . ctype - the matrix type 387c0dedaeaSBarry Smith 388c0dedaeaSBarry Smith Options Database: 389c0dedaeaSBarry Smith . -dm_mat_type ctype 390c0dedaeaSBarry Smith 391c0dedaeaSBarry Smith Level: intermediate 392c0dedaeaSBarry Smith 393a2a9ebe5SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMSetMatType(), DMSetMatType(), DMGetMatType() 394c0dedaeaSBarry Smith @*/ 395c0dedaeaSBarry Smith PetscErrorCode DMGetMatType(DM dm,MatType *ctype) 396c0dedaeaSBarry Smith { 397c0dedaeaSBarry Smith PetscFunctionBegin; 398c0dedaeaSBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 399c0dedaeaSBarry Smith *ctype = dm->mattype; 400c0dedaeaSBarry Smith PetscFunctionReturn(0); 401c0dedaeaSBarry Smith } 402c0dedaeaSBarry Smith 403c688c046SMatthew G Knepley /*@ 40434f98d34SBarry Smith MatGetDM - Gets the DM defining the data layout of the matrix 405c688c046SMatthew G Knepley 406c688c046SMatthew G Knepley Not collective 407c688c046SMatthew G Knepley 408c688c046SMatthew G Knepley Input Parameter: 409c688c046SMatthew G Knepley . A - The Mat 410c688c046SMatthew G Knepley 411c688c046SMatthew G Knepley Output Parameter: 412c688c046SMatthew G Knepley . dm - The DM 413c688c046SMatthew G Knepley 414c688c046SMatthew G Knepley Level: intermediate 415c688c046SMatthew G Knepley 4168f1509bcSBarry Smith Developer Note: Since the Mat class doesn't know about the DM class the DM object is associated with 4178f1509bcSBarry Smith the Mat through a PetscObjectCompose() operation 4188f1509bcSBarry Smith 419c688c046SMatthew G Knepley .seealso: MatSetDM(), DMCreateMatrix(), DMSetMatType() 420c688c046SMatthew G Knepley @*/ 421c688c046SMatthew G Knepley PetscErrorCode MatGetDM(Mat A, DM *dm) 422c688c046SMatthew G Knepley { 423c688c046SMatthew G Knepley PetscErrorCode ierr; 424c688c046SMatthew G Knepley 425c688c046SMatthew G Knepley PetscFunctionBegin; 426c688c046SMatthew G Knepley PetscValidHeaderSpecific(A,MAT_CLASSID,1); 427c688c046SMatthew G Knepley PetscValidPointer(dm,2); 428c688c046SMatthew G Knepley ierr = PetscObjectQuery((PetscObject) A, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr); 429c688c046SMatthew G Knepley PetscFunctionReturn(0); 430c688c046SMatthew G Knepley } 431c688c046SMatthew G Knepley 432c688c046SMatthew G Knepley /*@ 433c688c046SMatthew G Knepley MatSetDM - Sets the DM defining the data layout of the matrix 434c688c046SMatthew G Knepley 435c688c046SMatthew G Knepley Not collective 436c688c046SMatthew G Knepley 437c688c046SMatthew G Knepley Input Parameters: 438c688c046SMatthew G Knepley + A - The Mat 439c688c046SMatthew G Knepley - dm - The DM 440c688c046SMatthew G Knepley 441c688c046SMatthew G Knepley Level: intermediate 442c688c046SMatthew G Knepley 4438f1509bcSBarry Smith Developer Note: Since the Mat class doesn't know about the DM class the DM object is associated with 4448f1509bcSBarry Smith the Mat through a PetscObjectCompose() operation 4458f1509bcSBarry Smith 446c688c046SMatthew G Knepley .seealso: MatGetDM(), DMCreateMatrix(), DMSetMatType() 447c688c046SMatthew G Knepley @*/ 448c688c046SMatthew G Knepley PetscErrorCode MatSetDM(Mat A, DM dm) 449c688c046SMatthew G Knepley { 450c688c046SMatthew G Knepley PetscErrorCode ierr; 451c688c046SMatthew G Knepley 452c688c046SMatthew G Knepley PetscFunctionBegin; 453c688c046SMatthew G Knepley PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4548865f1eaSKarl Rupp if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2); 455c688c046SMatthew G Knepley ierr = PetscObjectCompose((PetscObject) A, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 456c688c046SMatthew G Knepley PetscFunctionReturn(0); 457c688c046SMatthew G Knepley } 458c688c046SMatthew G Knepley 4599a42bb27SBarry Smith /*@C 4609a42bb27SBarry Smith DMSetOptionsPrefix - Sets the prefix used for searching for all 4616757b960SDave May DM options in the database. 4629a42bb27SBarry Smith 463d083f849SBarry Smith Logically Collective on dm 4649a42bb27SBarry Smith 465d8d19677SJose E. Roman Input Parameters: 4668353ddbbSDave May + da - the DM context 4679a42bb27SBarry Smith - prefix - the prefix to prepend to all option names 4689a42bb27SBarry Smith 4699a42bb27SBarry Smith Notes: 4709a42bb27SBarry Smith A hyphen (-) must NOT be given at the beginning of the prefix name. 4719a42bb27SBarry Smith The first character of all runtime options is AUTOMATICALLY the hyphen. 4729a42bb27SBarry Smith 4739a42bb27SBarry Smith Level: advanced 4749a42bb27SBarry Smith 4759a42bb27SBarry Smith .seealso: DMSetFromOptions() 4769a42bb27SBarry Smith @*/ 4777087cfbeSBarry Smith PetscErrorCode DMSetOptionsPrefix(DM dm,const char prefix[]) 4789a42bb27SBarry Smith { 4799a42bb27SBarry Smith PetscErrorCode ierr; 4809a42bb27SBarry Smith 4819a42bb27SBarry Smith PetscFunctionBegin; 4829a42bb27SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4839a42bb27SBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 484691be533SLawrence Mitchell if (dm->sf) { 485691be533SLawrence Mitchell ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->sf,prefix);CHKERRQ(ierr); 486691be533SLawrence Mitchell } 4871bb6d2a8SBarry Smith if (dm->sectionSF) { 4881bb6d2a8SBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->sectionSF,prefix);CHKERRQ(ierr); 489691be533SLawrence Mitchell } 4909a42bb27SBarry Smith PetscFunctionReturn(0); 4919a42bb27SBarry Smith } 4929a42bb27SBarry Smith 49331697293SDave May /*@C 49431697293SDave May DMAppendOptionsPrefix - Appends to the prefix used for searching for all 49531697293SDave May DM options in the database. 49631697293SDave May 497d083f849SBarry Smith Logically Collective on dm 49831697293SDave May 49931697293SDave May Input Parameters: 50031697293SDave May + dm - the DM context 50131697293SDave May - prefix - the prefix string to prepend to all DM option requests 50231697293SDave May 50331697293SDave May Notes: 50431697293SDave May A hyphen (-) must NOT be given at the beginning of the prefix name. 50531697293SDave May The first character of all runtime options is AUTOMATICALLY the hyphen. 50631697293SDave May 50731697293SDave May Level: advanced 50831697293SDave May 50931697293SDave May .seealso: DMSetOptionsPrefix(), DMGetOptionsPrefix() 51031697293SDave May @*/ 51131697293SDave May PetscErrorCode DMAppendOptionsPrefix(DM dm,const char prefix[]) 51231697293SDave May { 51331697293SDave May PetscErrorCode ierr; 51431697293SDave May 51531697293SDave May PetscFunctionBegin; 51631697293SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 51731697293SDave May ierr = PetscObjectAppendOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 51831697293SDave May PetscFunctionReturn(0); 51931697293SDave May } 52031697293SDave May 52131697293SDave May /*@C 52231697293SDave May DMGetOptionsPrefix - Gets the prefix used for searching for all 52331697293SDave May DM options in the database. 52431697293SDave May 52531697293SDave May Not Collective 52631697293SDave May 52731697293SDave May Input Parameters: 52831697293SDave May . dm - the DM context 52931697293SDave May 53031697293SDave May Output Parameters: 53131697293SDave May . prefix - pointer to the prefix string used is returned 53231697293SDave May 53395452b02SPatrick Sanan Notes: 53495452b02SPatrick Sanan On the fortran side, the user should pass in a string 'prefix' of 53531697293SDave May sufficient length to hold the prefix. 53631697293SDave May 53731697293SDave May Level: advanced 53831697293SDave May 53931697293SDave May .seealso: DMSetOptionsPrefix(), DMAppendOptionsPrefix() 54031697293SDave May @*/ 54131697293SDave May PetscErrorCode DMGetOptionsPrefix(DM dm,const char *prefix[]) 54231697293SDave May { 54331697293SDave May PetscErrorCode ierr; 54431697293SDave May 54531697293SDave May PetscFunctionBegin; 54631697293SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 54731697293SDave May ierr = PetscObjectGetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 54831697293SDave May PetscFunctionReturn(0); 54931697293SDave May } 55031697293SDave May 55188bdff64SToby Isaac static PetscErrorCode DMCountNonCyclicReferences(DM dm, PetscBool recurseCoarse, PetscBool recurseFine, PetscInt *ncrefct) 55288bdff64SToby Isaac { 5536eb26441SStefano Zampini PetscInt refct = ((PetscObject) dm)->refct; 55488bdff64SToby Isaac PetscErrorCode ierr; 55588bdff64SToby Isaac 55688bdff64SToby Isaac PetscFunctionBegin; 557aab5bcd8SJed Brown *ncrefct = 0; 55888bdff64SToby Isaac if (dm->coarseMesh && dm->coarseMesh->fineMesh == dm) { 55988bdff64SToby Isaac refct--; 56088bdff64SToby Isaac if (recurseCoarse) { 56188bdff64SToby Isaac PetscInt coarseCount; 56288bdff64SToby Isaac 56388bdff64SToby Isaac ierr = DMCountNonCyclicReferences(dm->coarseMesh, PETSC_TRUE, PETSC_FALSE,&coarseCount);CHKERRQ(ierr); 56488bdff64SToby Isaac refct += coarseCount; 56588bdff64SToby Isaac } 56688bdff64SToby Isaac } 56788bdff64SToby Isaac if (dm->fineMesh && dm->fineMesh->coarseMesh == dm) { 56888bdff64SToby Isaac refct--; 56988bdff64SToby Isaac if (recurseFine) { 57088bdff64SToby Isaac PetscInt fineCount; 57188bdff64SToby Isaac 57288bdff64SToby Isaac ierr = DMCountNonCyclicReferences(dm->fineMesh, PETSC_FALSE, PETSC_TRUE,&fineCount);CHKERRQ(ierr); 57388bdff64SToby Isaac refct += fineCount; 57488bdff64SToby Isaac } 57588bdff64SToby Isaac } 57688bdff64SToby Isaac *ncrefct = refct; 57788bdff64SToby Isaac PetscFunctionReturn(0); 57888bdff64SToby Isaac } 57988bdff64SToby Isaac 580f4cdcedcSVaclav Hapla PetscErrorCode DMDestroyLabelLinkList_Internal(DM dm) 581354557abSToby Isaac { 5825d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 583354557abSToby Isaac PetscErrorCode ierr; 584354557abSToby Isaac 585354557abSToby Isaac PetscFunctionBegin; 586354557abSToby Isaac /* destroy the labels */ 587354557abSToby Isaac while (next) { 588354557abSToby Isaac DMLabelLink tmp = next->next; 589354557abSToby Isaac 5905d80c0bfSVaclav Hapla if (next->label == dm->depthLabel) dm->depthLabel = NULL; 591ba2698f1SMatthew G. Knepley if (next->label == dm->celltypeLabel) dm->celltypeLabel = NULL; 592354557abSToby Isaac ierr = DMLabelDestroy(&next->label);CHKERRQ(ierr); 593354557abSToby Isaac ierr = PetscFree(next);CHKERRQ(ierr); 594354557abSToby Isaac next = tmp; 595354557abSToby Isaac } 5965d80c0bfSVaclav Hapla dm->labels = NULL; 597354557abSToby Isaac PetscFunctionReturn(0); 598354557abSToby Isaac } 599354557abSToby Isaac 6001fb7b255SJunchao Zhang /*@C 6018472ad0fSDave May DMDestroy - Destroys a vector packer or DM. 60247c6ae99SBarry Smith 603d083f849SBarry Smith Collective on dm 60447c6ae99SBarry Smith 60547c6ae99SBarry Smith Input Parameter: 60647c6ae99SBarry Smith . dm - the DM object to destroy 60747c6ae99SBarry Smith 60847c6ae99SBarry Smith Level: developer 60947c6ae99SBarry Smith 610e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 61147c6ae99SBarry Smith 61247c6ae99SBarry Smith @*/ 613fcfd50ebSBarry Smith PetscErrorCode DMDestroy(DM *dm) 61447c6ae99SBarry Smith { 6156eb26441SStefano Zampini PetscInt cnt; 616dfe15315SJed Brown DMNamedVecLink nlink,nnext; 61747c6ae99SBarry Smith PetscErrorCode ierr; 61847c6ae99SBarry Smith 61947c6ae99SBarry Smith PetscFunctionBegin; 6206bf464f9SBarry Smith if (!*dm) PetscFunctionReturn(0); 6216bf464f9SBarry Smith PetscValidHeaderSpecific((*dm),DM_CLASSID,1); 62287e657c6SBarry Smith 62388bdff64SToby Isaac /* count all non-cyclic references in the doubly-linked list of coarse<->fine meshes */ 62488bdff64SToby Isaac ierr = DMCountNonCyclicReferences(*dm,PETSC_TRUE,PETSC_TRUE,&cnt);CHKERRQ(ierr); 62588bdff64SToby Isaac --((PetscObject)(*dm))->refct; 626ea78f98cSLisandro Dalcin if (--cnt > 0) {*dm = NULL; PetscFunctionReturn(0);} 6276bf464f9SBarry Smith if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0); 6286bf464f9SBarry Smith ((PetscObject)(*dm))->refct = 0; 6296eb26441SStefano Zampini 6306eb26441SStefano Zampini ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr); 6316eb26441SStefano Zampini ierr = DMClearLocalVectors(*dm);CHKERRQ(ierr); 6326eb26441SStefano Zampini 633f490541aSPeter Brune nnext=(*dm)->namedglobal; 6340298fd71SBarry Smith (*dm)->namedglobal = NULL; 635f490541aSPeter Brune for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named vectors */ 6362348bcf4SPeter Brune nnext = nlink->next; 6372348bcf4SPeter 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); 6382348bcf4SPeter Brune ierr = PetscFree(nlink->name);CHKERRQ(ierr); 6392348bcf4SPeter Brune ierr = VecDestroy(&nlink->X);CHKERRQ(ierr); 6402348bcf4SPeter Brune ierr = PetscFree(nlink);CHKERRQ(ierr); 6412348bcf4SPeter Brune } 642f490541aSPeter Brune nnext=(*dm)->namedlocal; 6430298fd71SBarry Smith (*dm)->namedlocal = NULL; 644f490541aSPeter Brune for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named local vectors */ 645f490541aSPeter Brune nnext = nlink->next; 646f490541aSPeter 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); 647f490541aSPeter Brune ierr = PetscFree(nlink->name);CHKERRQ(ierr); 648f490541aSPeter Brune ierr = VecDestroy(&nlink->X);CHKERRQ(ierr); 649f490541aSPeter Brune ierr = PetscFree(nlink);CHKERRQ(ierr); 650f490541aSPeter Brune } 6512348bcf4SPeter Brune 652b17ce1afSJed Brown /* Destroy the list of hooks */ 653c833c3b5SJed Brown { 654c833c3b5SJed Brown DMCoarsenHookLink link,next; 655b17ce1afSJed Brown for (link=(*dm)->coarsenhook; link; link=next) { 656b17ce1afSJed Brown next = link->next; 657b17ce1afSJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 658b17ce1afSJed Brown } 6590298fd71SBarry Smith (*dm)->coarsenhook = NULL; 660c833c3b5SJed Brown } 661c833c3b5SJed Brown { 662c833c3b5SJed Brown DMRefineHookLink link,next; 663c833c3b5SJed Brown for (link=(*dm)->refinehook; link; link=next) { 664c833c3b5SJed Brown next = link->next; 665c833c3b5SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 666c833c3b5SJed Brown } 6670298fd71SBarry Smith (*dm)->refinehook = NULL; 668c833c3b5SJed Brown } 669be081cd6SPeter Brune { 670be081cd6SPeter Brune DMSubDomainHookLink link,next; 671be081cd6SPeter Brune for (link=(*dm)->subdomainhook; link; link=next) { 672be081cd6SPeter Brune next = link->next; 673be081cd6SPeter Brune ierr = PetscFree(link);CHKERRQ(ierr); 674be081cd6SPeter Brune } 6750298fd71SBarry Smith (*dm)->subdomainhook = NULL; 676be081cd6SPeter Brune } 677baf369e7SPeter Brune { 678baf369e7SPeter Brune DMGlobalToLocalHookLink link,next; 679baf369e7SPeter Brune for (link=(*dm)->gtolhook; link; link=next) { 680baf369e7SPeter Brune next = link->next; 681baf369e7SPeter Brune ierr = PetscFree(link);CHKERRQ(ierr); 682baf369e7SPeter Brune } 6830298fd71SBarry Smith (*dm)->gtolhook = NULL; 684baf369e7SPeter Brune } 685d4d07f1eSToby Isaac { 686d4d07f1eSToby Isaac DMLocalToGlobalHookLink link,next; 687d4d07f1eSToby Isaac for (link=(*dm)->ltoghook; link; link=next) { 688d4d07f1eSToby Isaac next = link->next; 689d4d07f1eSToby Isaac ierr = PetscFree(link);CHKERRQ(ierr); 690d4d07f1eSToby Isaac } 691d4d07f1eSToby Isaac (*dm)->ltoghook = NULL; 692d4d07f1eSToby Isaac } 693aa1993deSMatthew G Knepley /* Destroy the work arrays */ 694aa1993deSMatthew G Knepley { 695aa1993deSMatthew G Knepley DMWorkLink link,next; 696aa1993deSMatthew G Knepley if ((*dm)->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Work array still checked out"); 697aa1993deSMatthew G Knepley for (link=(*dm)->workin; link; link=next) { 698aa1993deSMatthew G Knepley next = link->next; 699aa1993deSMatthew G Knepley ierr = PetscFree(link->mem);CHKERRQ(ierr); 700aa1993deSMatthew G Knepley ierr = PetscFree(link);CHKERRQ(ierr); 701aa1993deSMatthew G Knepley } 7020298fd71SBarry Smith (*dm)->workin = NULL; 703aa1993deSMatthew G Knepley } 704c58f1c22SToby Isaac /* destroy the labels */ 705f4cdcedcSVaclav Hapla ierr = DMDestroyLabelLinkList_Internal(*dm);CHKERRQ(ierr); 706f4cdcedcSVaclav Hapla /* destroy the fields */ 707e5e52638SMatthew G. Knepley ierr = DMClearFields(*dm);CHKERRQ(ierr); 708f4cdcedcSVaclav Hapla /* destroy the boundaries */ 709e6f8dbb6SToby Isaac { 710e6f8dbb6SToby Isaac DMBoundary next = (*dm)->boundary; 711e6f8dbb6SToby Isaac while (next) { 712e6f8dbb6SToby Isaac DMBoundary b = next; 713e6f8dbb6SToby Isaac 714e6f8dbb6SToby Isaac next = b->next; 715e6f8dbb6SToby Isaac ierr = PetscFree(b);CHKERRQ(ierr); 716e6f8dbb6SToby Isaac } 717e6f8dbb6SToby Isaac } 718b17ce1afSJed Brown 71952536dc3SBarry Smith ierr = PetscObjectDestroy(&(*dm)->dmksp);CHKERRQ(ierr); 72052536dc3SBarry Smith ierr = PetscObjectDestroy(&(*dm)->dmsnes);CHKERRQ(ierr); 72152536dc3SBarry Smith ierr = PetscObjectDestroy(&(*dm)->dmts);CHKERRQ(ierr); 72252536dc3SBarry Smith 7231a266240SBarry Smith if ((*dm)->ctx && (*dm)->ctxdestroy) { 7241a266240SBarry Smith ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr); 7251a266240SBarry Smith } 72671cd77b2SBarry Smith ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr); 7276bf464f9SBarry Smith ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr); 7286bf464f9SBarry Smith ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr); 729073dac72SJed Brown ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr); 73088ed4aceSMatthew G Knepley 7311bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&(*dm)->localSection);CHKERRQ(ierr); 7321bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&(*dm)->globalSection);CHKERRQ(ierr); 7338b1ab98fSJed Brown ierr = PetscLayoutDestroy(&(*dm)->map);CHKERRQ(ierr); 734fba222abSToby Isaac ierr = PetscSectionDestroy(&(*dm)->defaultConstraintSection);CHKERRQ(ierr); 735fba222abSToby Isaac ierr = MatDestroy(&(*dm)->defaultConstraintMat);CHKERRQ(ierr); 73688ed4aceSMatthew G Knepley ierr = PetscSFDestroy(&(*dm)->sf);CHKERRQ(ierr); 7371bb6d2a8SBarry Smith ierr = PetscSFDestroy(&(*dm)->sectionSF);CHKERRQ(ierr); 738736995cdSBlaise Bourdin if ((*dm)->useNatural) { 739736995cdSBlaise Bourdin if ((*dm)->sfNatural) { 7408e4ac7eaSMatthew G. Knepley ierr = PetscSFDestroy(&(*dm)->sfNatural);CHKERRQ(ierr); 741736995cdSBlaise Bourdin } 742736995cdSBlaise Bourdin ierr = PetscObjectDereference((PetscObject) (*dm)->sfMigration);CHKERRQ(ierr); 743736995cdSBlaise Bourdin } 7449a2a23afSMatthew G. Knepley { 7459a2a23afSMatthew G. Knepley Vec *auxData; 7469a2a23afSMatthew G. Knepley PetscInt n, i, off = 0; 7479a2a23afSMatthew G. Knepley 7489a2a23afSMatthew G. Knepley ierr = PetscHMapAuxGetSize((*dm)->auxData, &n);CHKERRQ(ierr); 7499a2a23afSMatthew G. Knepley ierr = PetscMalloc1(n, &auxData);CHKERRQ(ierr); 7509a2a23afSMatthew G. Knepley ierr = PetscHMapAuxGetVals((*dm)->auxData, &off, auxData);CHKERRQ(ierr); 7519a2a23afSMatthew G. Knepley for (i = 0; i < n; ++i) {ierr = VecDestroy(&auxData[i]);CHKERRQ(ierr);} 7529a2a23afSMatthew G. Knepley ierr = PetscFree(auxData);CHKERRQ(ierr); 7539a2a23afSMatthew G. Knepley ierr = PetscHMapAuxDestroy(&(*dm)->auxData);CHKERRQ(ierr); 7549a2a23afSMatthew G. Knepley } 75588bdff64SToby Isaac if ((*dm)->coarseMesh && (*dm)->coarseMesh->fineMesh == *dm) { 75688bdff64SToby Isaac ierr = DMSetFineDM((*dm)->coarseMesh,NULL);CHKERRQ(ierr); 75788bdff64SToby Isaac } 7586eb26441SStefano Zampini 759a8fb8f29SToby Isaac ierr = DMDestroy(&(*dm)->coarseMesh);CHKERRQ(ierr); 76088bdff64SToby Isaac if ((*dm)->fineMesh && (*dm)->fineMesh->coarseMesh == *dm) { 76188bdff64SToby Isaac ierr = DMSetCoarseDM((*dm)->fineMesh,NULL);CHKERRQ(ierr); 76288bdff64SToby Isaac } 76388bdff64SToby Isaac ierr = DMDestroy(&(*dm)->fineMesh);CHKERRQ(ierr); 764f19dbd58SToby Isaac ierr = DMFieldDestroy(&(*dm)->coordinateField);CHKERRQ(ierr); 7656636e97aSMatthew G Knepley ierr = DMDestroy(&(*dm)->coordinateDM);CHKERRQ(ierr); 7666636e97aSMatthew G Knepley ierr = VecDestroy(&(*dm)->coordinates);CHKERRQ(ierr); 7676636e97aSMatthew G Knepley ierr = VecDestroy(&(*dm)->coordinatesLocal);CHKERRQ(ierr); 768412e9a14SMatthew G. Knepley ierr = PetscFree((*dm)->L);CHKERRQ(ierr); 769412e9a14SMatthew G. Knepley ierr = PetscFree((*dm)->maxCell);CHKERRQ(ierr); 770412e9a14SMatthew G. Knepley ierr = PetscFree((*dm)->bdtype);CHKERRQ(ierr); 771ca3d3a14SMatthew G. Knepley if ((*dm)->transformDestroy) {ierr = (*(*dm)->transformDestroy)(*dm, (*dm)->transformCtx);CHKERRQ(ierr);} 772ca3d3a14SMatthew G. Knepley ierr = DMDestroy(&(*dm)->transformDM);CHKERRQ(ierr); 773ca3d3a14SMatthew G. Knepley ierr = VecDestroy(&(*dm)->transform);CHKERRQ(ierr); 7746636e97aSMatthew G Knepley 775e5e52638SMatthew G. Knepley ierr = DMClearDS(*dm);CHKERRQ(ierr); 77614f150ffSMatthew G. Knepley ierr = DMDestroy(&(*dm)->dmBC);CHKERRQ(ierr); 777e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 778e04113cfSBarry Smith ierr = PetscObjectSAWsViewOff((PetscObject)*dm);CHKERRQ(ierr); 779732e2eb9SMatthew G Knepley 780ed3c66a1SDave May if ((*dm)->ops->destroy) { 7816bf464f9SBarry Smith ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr); 782ed3c66a1SDave May } 783c0f0dcc3SMatthew G. Knepley ierr = DMMonitorCancel(*dm);CHKERRQ(ierr); 784f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 785f918ec44SMatthew G. Knepley ierr = CeedElemRestrictionDestroy(&(*dm)->ceedERestrict);CHKERRQ(ierr); 786f918ec44SMatthew G. Knepley ierr = CeedDestroy(&(*dm)->ceed);CHKERRQ(ierr); 787f918ec44SMatthew G. Knepley #endif 788435a35e8SMatthew G Knepley /* We do not destroy (*dm)->data here so that we can reference count backend objects */ 789732e2eb9SMatthew G Knepley ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr); 79047c6ae99SBarry Smith PetscFunctionReturn(0); 79147c6ae99SBarry Smith } 79247c6ae99SBarry Smith 793d7bf68aeSBarry Smith /*@ 794d7bf68aeSBarry Smith DMSetUp - sets up the data structures inside a DM object 795d7bf68aeSBarry Smith 796d083f849SBarry Smith Collective on dm 797d7bf68aeSBarry Smith 798d7bf68aeSBarry Smith Input Parameter: 799d7bf68aeSBarry Smith . dm - the DM object to setup 800d7bf68aeSBarry Smith 801d7bf68aeSBarry Smith Level: developer 802d7bf68aeSBarry Smith 803e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 804d7bf68aeSBarry Smith 805d7bf68aeSBarry Smith @*/ 8067087cfbeSBarry Smith PetscErrorCode DMSetUp(DM dm) 807d7bf68aeSBarry Smith { 808d7bf68aeSBarry Smith PetscErrorCode ierr; 809d7bf68aeSBarry Smith 810d7bf68aeSBarry Smith PetscFunctionBegin; 811171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8128387afaaSJed Brown if (dm->setupcalled) PetscFunctionReturn(0); 813d7bf68aeSBarry Smith if (dm->ops->setup) { 814d7bf68aeSBarry Smith ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr); 815d7bf68aeSBarry Smith } 8168387afaaSJed Brown dm->setupcalled = PETSC_TRUE; 817d7bf68aeSBarry Smith PetscFunctionReturn(0); 818d7bf68aeSBarry Smith } 819d7bf68aeSBarry Smith 820d7bf68aeSBarry Smith /*@ 821d7bf68aeSBarry Smith DMSetFromOptions - sets parameters in a DM from the options database 822d7bf68aeSBarry Smith 823d083f849SBarry Smith Collective on dm 824d7bf68aeSBarry Smith 825d7bf68aeSBarry Smith Input Parameter: 826d7bf68aeSBarry Smith . dm - the DM object to set options for 827d7bf68aeSBarry Smith 828732e2eb9SMatthew G Knepley Options Database: 8294164ae61SDominic Meiser + -dm_preallocate_only - Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros 8304164ae61SDominic Meiser . -dm_vec_type <type> - type of vector to create inside DM 8314164ae61SDominic Meiser . -dm_mat_type <type> - type of matrix to create inside DM 832a4ea9b21SRichard Tran Mills . -dm_is_coloring_type - <global or local> 833a4ea9b21SRichard Tran Mills - -dm_bind_below <n> - bind (force execution on CPU) for Vec and Mat objects with local size (number of vector entries or matrix rows) below n; currently only supported for DMDA 834732e2eb9SMatthew G Knepley 8359318fe57SMatthew G. Knepley DMPLEX Specific creation options 8369318fe57SMatthew G. Knepley + -dm_plex_filename <str> - File containing a mesh 8379318fe57SMatthew G. Knepley . -dm_plex_boundary_filename <str> - File containing a mesh boundary 838cd7e8a5eSksagiyam . -dm_plex_name <str> - Name of the mesh in the file 8399318fe57SMatthew G. Knepley . -dm_plex_shape <shape> - The domain shape, such as DM_SHAPE_BOX, DM_SHAPE_SPHERE, etc. 8409318fe57SMatthew G. Knepley . -dm_plex_cell <ct> - Cell shape 8419318fe57SMatthew G. Knepley . -dm_plex_reference_cell_domain <bool> - Use a reference cell domain 8429318fe57SMatthew G. Knepley . -dm_plex_dim <dim> - Set the topological dimension 8439318fe57SMatthew G. Knepley . -dm_plex_simplex <bool> - PETSC_TRUE for simplex elements, PETSC_FALSE for tensor elements 8449318fe57SMatthew G. Knepley . -dm_plex_interpolate <bool> - PETSC_TRUE turns on topological interpolation (creating edges and faces) 8459318fe57SMatthew G. Knepley . -dm_plex_scale <sc> - Scale factor for mesh coordinates 8469318fe57SMatthew G. Knepley . -dm_plex_box_faces <m,n,p> - Number of faces along each dimension 8479318fe57SMatthew G. Knepley . -dm_plex_box_lower <x,y,z> - Specify lower-left-bottom coordinates for the box 8489318fe57SMatthew G. Knepley . -dm_plex_box_upper <x,y,z> - Specify upper-right-top coordinates for the box 8499318fe57SMatthew G. Knepley . -dm_plex_box_bd <bx,by,bz> - Specify the DMBoundaryType for each direction 8509318fe57SMatthew G. Knepley . -dm_plex_sphere_radius <r> - The sphere radius 8519318fe57SMatthew G. Knepley . -dm_plex_ball_radius <r> - Radius of the ball 8529318fe57SMatthew G. Knepley . -dm_plex_cylinder_bd <bz> - Boundary type in the z direction 8539318fe57SMatthew G. Knepley . -dm_plex_cylinder_num_wedges <n> - Number of wedges around the cylinder 854bdf63967SMatthew G. Knepley . -dm_plex_reorder <order> - Reorder the mesh using the specified algorithm 8559318fe57SMatthew G. Knepley . -dm_refine_pre <n> - The number of refinements before distribution 8569318fe57SMatthew G. Knepley . -dm_refine_uniform_pre <bool> - Flag for uniform refinement before distribution 8579318fe57SMatthew G. Knepley . -dm_refine_volume_limit_pre <v> - The maximum cell volume after refinement before distribution 8589318fe57SMatthew G. Knepley . -dm_refine <n> - The number of refinements after distribution 859bdf63967SMatthew G. Knepley . -dm_extrude <l> - Activate extrusion and specify the number of layers to extrude 860d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_thickness <t> - The total thickness of extruded layers 861d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_use_tensor <bool> - Use tensor cells when extruding 862d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_symmetric <bool> - Extrude layers symmetrically about the surface 863d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_normal <n0,...,nd> - Specify the extrusion direction 864d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_thicknesses <t0,...,tl> - Specify thickness of each layer 865909dfd52SMatthew G. Knepley . -dm_plex_create_fv_ghost_cells - Flag to create finite volume ghost cells on the boundary 866909dfd52SMatthew G. Knepley . -dm_plex_fv_ghost_cells_label <name> - Label name for ghost cells boundary 8679318fe57SMatthew G. Knepley . -dm_distribute <bool> - Flag to redistribute a mesh among processes 8689318fe57SMatthew G. Knepley . -dm_distribute_overlap <n> - The size of the overlap halo 8699318fe57SMatthew G. Knepley . -dm_plex_adj_cone <bool> - Set adjacency direction 8709318fe57SMatthew G. Knepley - -dm_plex_adj_closure <bool> - Set adjacency size 8719318fe57SMatthew G. Knepley 872384a6580SVaclav Hapla DMPLEX Specific Checks 873384a6580SVaclav Hapla + -dm_plex_check_symmetry - Check that the adjacency information in the mesh is symmetric - DMPlexCheckSymmetry() 874384a6580SVaclav Hapla . -dm_plex_check_skeleton - Check that each cell has the correct number of vertices (only for homogeneous simplex or tensor meshes) - DMPlexCheckSkeleton() 875384a6580SVaclav 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() 876384a6580SVaclav Hapla . -dm_plex_check_geometry - Check that cells have positive volume - DMPlexCheckGeometry() 877384a6580SVaclav Hapla . -dm_plex_check_pointsf - Check some necessary conditions for PointSF - DMPlexCheckPointSF() 878384a6580SVaclav Hapla . -dm_plex_check_interface_cones - Check points on inter-partition interfaces have conforming order of cone points - DMPlexCheckInterfaceCones() 879384a6580SVaclav Hapla - -dm_plex_check_all - Perform all the checks above 880d7bf68aeSBarry Smith 88195eb5ee5SVaclav Hapla Level: intermediate 88295eb5ee5SVaclav Hapla 88395eb5ee5SVaclav Hapla .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), 88495eb5ee5SVaclav Hapla DMPlexCheckSymmetry(), DMPlexCheckSkeleton(), DMPlexCheckFaces(), DMPlexCheckGeometry(), DMPlexCheckPointSF(), DMPlexCheckInterfaceCones() 885d7bf68aeSBarry Smith 886d7bf68aeSBarry Smith @*/ 8877087cfbeSBarry Smith PetscErrorCode DMSetFromOptions(DM dm) 888d7bf68aeSBarry Smith { 8897781c08eSBarry Smith char typeName[256]; 890ca266f36SBarry Smith PetscBool flg; 891d7bf68aeSBarry Smith PetscErrorCode ierr; 892d7bf68aeSBarry Smith 893d7bf68aeSBarry Smith PetscFunctionBegin; 894171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 89549be4549SMatthew G. Knepley dm->setfromoptionscalled = PETSC_TRUE; 89649be4549SMatthew G. Knepley if (dm->sf) {ierr = PetscSFSetFromOptions(dm->sf);CHKERRQ(ierr);} 8971bb6d2a8SBarry Smith if (dm->sectionSF) {ierr = PetscSFSetFromOptions(dm->sectionSF);CHKERRQ(ierr);} 8983194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr); 8990298fd71SBarry 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); 900a264d7a6SBarry Smith ierr = PetscOptionsFList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr); 901f9ba7244SBarry Smith if (flg) { 902f9ba7244SBarry Smith ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr); 903f9ba7244SBarry Smith } 904a264d7a6SBarry 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); 905073dac72SJed Brown if (flg) { 906521d9a4cSLisandro Dalcin ierr = DMSetMatType(dm,typeName);CHKERRQ(ierr); 907073dac72SJed Brown } 9088f1509bcSBarry Smith ierr = PetscOptionsEnum("-dm_is_coloring_type","Global or local coloring of Jacobian","DMSetISColoringType",ISColoringTypes,(PetscEnum)dm->coloringtype,(PetscEnum*)&dm->coloringtype,NULL);CHKERRQ(ierr); 909a4ea9b21SRichard Tran Mills ierr = PetscOptionsInt("-dm_bind_below","Set the size threshold (in entries) below which the Vec is bound to the CPU","VecBindToCPU",dm->bind_below,&dm->bind_below,&flg);CHKERRQ(ierr); 910f9ba7244SBarry Smith if (dm->ops->setfromoptions) { 911e55864a3SBarry Smith ierr = (*dm->ops->setfromoptions)(PetscOptionsObject,dm);CHKERRQ(ierr); 912f9ba7244SBarry Smith } 913f9ba7244SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 9140633abcbSJed Brown ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) dm);CHKERRQ(ierr); 91582fcb398SMatthew G Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 916d7bf68aeSBarry Smith PetscFunctionReturn(0); 917d7bf68aeSBarry Smith } 918d7bf68aeSBarry Smith 919fc9bc008SSatish Balay /*@C 920fe2efc57SMark DMViewFromOptions - View from Options 921fe2efc57SMark 922fe2efc57SMark Collective on DM 923fe2efc57SMark 924fe2efc57SMark Input Parameters: 925fe2efc57SMark + dm - the DM object 926736c3998SJose E. Roman . obj - Optional object 927736c3998SJose E. Roman - name - command line option 928fe2efc57SMark 929fe2efc57SMark Level: intermediate 930fe2efc57SMark .seealso: DM, DMView, PetscObjectViewFromOptions(), DMCreate() 931fe2efc57SMark @*/ 932fe2efc57SMark PetscErrorCode DMViewFromOptions(DM dm,PetscObject obj,const char name[]) 933fe2efc57SMark { 934fe2efc57SMark PetscErrorCode ierr; 935fe2efc57SMark 936fe2efc57SMark PetscFunctionBegin; 937fe2efc57SMark PetscValidHeaderSpecific(dm,DM_CLASSID,1); 938fe2efc57SMark ierr = PetscObjectViewFromOptions((PetscObject)dm,obj,name);CHKERRQ(ierr); 939fe2efc57SMark PetscFunctionReturn(0); 940fe2efc57SMark } 941fe2efc57SMark 942fe2efc57SMark /*@C 943224748a4SBarry Smith DMView - Views a DM 94447c6ae99SBarry Smith 945d083f849SBarry Smith Collective on dm 94647c6ae99SBarry Smith 947d8d19677SJose E. Roman Input Parameters: 94847c6ae99SBarry Smith + dm - the DM object to view 94947c6ae99SBarry Smith - v - the viewer 95047c6ae99SBarry Smith 951cd7e8a5eSksagiyam Notes: 952cd7e8a5eSksagiyam Using PETSCVIEWERHDF5 type with PETSC_VIEWER_HDF5_PETSC format, one can save multiple DMPlex 953cd7e8a5eSksagiyam meshes in a single HDF5 file. This in turn requires one to name the DMPlex object with PetscObjectSetName() 954cd7e8a5eSksagiyam before saving it with DMView() and before loading it with DMLoad() for identification of the mesh object. 955cd7e8a5eSksagiyam 956224748a4SBarry Smith Level: beginner 95747c6ae99SBarry Smith 958cd7e8a5eSksagiyam .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMLoad(), PetscObjectSetName() 95947c6ae99SBarry Smith 96047c6ae99SBarry Smith @*/ 9617087cfbeSBarry Smith PetscErrorCode DMView(DM dm,PetscViewer v) 96247c6ae99SBarry Smith { 96347c6ae99SBarry Smith PetscErrorCode ierr; 96432c0f0efSBarry Smith PetscBool isbinary; 96576a8abe0SBarry Smith PetscMPIInt size; 96676a8abe0SBarry Smith PetscViewerFormat format; 96747c6ae99SBarry Smith 96847c6ae99SBarry Smith PetscFunctionBegin; 969171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 9703014e516SBarry Smith if (!v) { 971ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)dm),&v);CHKERRQ(ierr); 9723014e516SBarry Smith } 973b1b135c8SBarry Smith PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,2); 97474903a4fSStefano Zampini /* Ideally, we would like to have this test on. 97574903a4fSStefano Zampini However, it currently breaks socket viz via GLVis. 97674903a4fSStefano Zampini During DMView(parallel_mesh,glvis_viewer), each 97774903a4fSStefano Zampini process opens a sequential ASCII socket to visualize 97874903a4fSStefano Zampini the local mesh, and PetscObjectView(dm,local_socket) 97974903a4fSStefano Zampini is internally called inside VecView_GLVis, incurring 98074903a4fSStefano Zampini in an error here */ 98174903a4fSStefano Zampini /* PetscCheckSameComm(dm,1,v,2); */ 9828bfd1ab9SVaclav Hapla ierr = PetscViewerCheckWritable(v);CHKERRQ(ierr); 983b1b135c8SBarry Smith 98476a8abe0SBarry Smith ierr = PetscViewerGetFormat(v,&format);CHKERRQ(ierr); 985ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&size);CHKERRMPI(ierr); 98676a8abe0SBarry Smith if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 98798c3331eSBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)dm,v);CHKERRQ(ierr); 98832c0f0efSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 98932c0f0efSBarry Smith if (isbinary) { 99055849f57SBarry Smith PetscInt classid = DM_FILE_CLASSID; 99132c0f0efSBarry Smith char type[256]; 99232c0f0efSBarry Smith 993f253e43cSLisandro Dalcin ierr = PetscViewerBinaryWrite(v,&classid,1,PETSC_INT);CHKERRQ(ierr); 99432c0f0efSBarry Smith ierr = PetscStrncpy(type,((PetscObject)dm)->type_name,256);CHKERRQ(ierr); 995f253e43cSLisandro Dalcin ierr = PetscViewerBinaryWrite(v,type,256,PETSC_CHAR);CHKERRQ(ierr); 99632c0f0efSBarry Smith } 9970c010503SBarry Smith if (dm->ops->view) { 9980c010503SBarry Smith ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr); 99947c6ae99SBarry Smith } 100047c6ae99SBarry Smith PetscFunctionReturn(0); 100147c6ae99SBarry Smith } 100247c6ae99SBarry Smith 100347c6ae99SBarry Smith /*@ 10048472ad0fSDave May DMCreateGlobalVector - Creates a global vector from a DM object 100547c6ae99SBarry Smith 1006d083f849SBarry Smith Collective on dm 100747c6ae99SBarry Smith 100847c6ae99SBarry Smith Input Parameter: 100947c6ae99SBarry Smith . dm - the DM object 101047c6ae99SBarry Smith 101147c6ae99SBarry Smith Output Parameter: 101247c6ae99SBarry Smith . vec - the global vector 101347c6ae99SBarry Smith 1014073dac72SJed Brown Level: beginner 101547c6ae99SBarry Smith 1016ec075b9fSPatrick Sanan .seealso DMCreateLocalVector(), DMGetGlobalVector(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 101747c6ae99SBarry Smith 101847c6ae99SBarry Smith @*/ 10197087cfbeSBarry Smith PetscErrorCode DMCreateGlobalVector(DM dm,Vec *vec) 102047c6ae99SBarry Smith { 102147c6ae99SBarry Smith PetscErrorCode ierr; 102247c6ae99SBarry Smith 102347c6ae99SBarry Smith PetscFunctionBegin; 1024171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1025b9d85ea2SLisandro Dalcin PetscValidPointer(vec,2); 1026b9d85ea2SLisandro Dalcin if (!dm->ops->createglobalvector) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateGlobalVector",((PetscObject)dm)->type_name); 102747c6ae99SBarry Smith ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr); 102876bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1029c6b011d8SStefano Zampini DM vdm; 1030c6b011d8SStefano Zampini 1031c6b011d8SStefano Zampini ierr = VecGetDM(*vec,&vdm);CHKERRQ(ierr); 1032c6b011d8SStefano 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); 1033c6b011d8SStefano Zampini } 103447c6ae99SBarry Smith PetscFunctionReturn(0); 103547c6ae99SBarry Smith } 103647c6ae99SBarry Smith 103747c6ae99SBarry Smith /*@ 10388472ad0fSDave May DMCreateLocalVector - Creates a local vector from a DM object 103947c6ae99SBarry Smith 104047c6ae99SBarry Smith Not Collective 104147c6ae99SBarry Smith 104247c6ae99SBarry Smith Input Parameter: 104347c6ae99SBarry Smith . dm - the DM object 104447c6ae99SBarry Smith 104547c6ae99SBarry Smith Output Parameter: 104647c6ae99SBarry Smith . vec - the local vector 104747c6ae99SBarry Smith 1048073dac72SJed Brown Level: beginner 104947c6ae99SBarry Smith 1050ec075b9fSPatrick Sanan .seealso DMCreateGlobalVector(), DMGetLocalVector(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 105147c6ae99SBarry Smith 105247c6ae99SBarry Smith @*/ 10537087cfbeSBarry Smith PetscErrorCode DMCreateLocalVector(DM dm,Vec *vec) 105447c6ae99SBarry Smith { 105547c6ae99SBarry Smith PetscErrorCode ierr; 105647c6ae99SBarry Smith 105747c6ae99SBarry Smith PetscFunctionBegin; 1058171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1059b9d85ea2SLisandro Dalcin PetscValidPointer(vec,2); 1060b9d85ea2SLisandro Dalcin if (!dm->ops->createlocalvector) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateLocalVector",((PetscObject)dm)->type_name); 106147c6ae99SBarry Smith ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr); 106276bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1063c6b011d8SStefano Zampini DM vdm; 1064c6b011d8SStefano Zampini 1065c6b011d8SStefano Zampini ierr = VecGetDM(*vec,&vdm);CHKERRQ(ierr); 1066c6b011d8SStefano 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); 1067c6b011d8SStefano Zampini } 106847c6ae99SBarry Smith PetscFunctionReturn(0); 106947c6ae99SBarry Smith } 107047c6ae99SBarry Smith 10711411c6eeSJed Brown /*@ 10721411c6eeSJed Brown DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM. 10731411c6eeSJed Brown 1074d083f849SBarry Smith Collective on dm 10751411c6eeSJed Brown 10761411c6eeSJed Brown Input Parameter: 10771411c6eeSJed Brown . dm - the DM that provides the mapping 10781411c6eeSJed Brown 10791411c6eeSJed Brown Output Parameter: 10801411c6eeSJed Brown . ltog - the mapping 10811411c6eeSJed Brown 10821411c6eeSJed Brown Level: intermediate 10831411c6eeSJed Brown 10841411c6eeSJed Brown Notes: 10851411c6eeSJed Brown This mapping can then be used by VecSetLocalToGlobalMapping() or 10861411c6eeSJed Brown MatSetLocalToGlobalMapping(). 10871411c6eeSJed Brown 1088fc31e74dSBarry Smith .seealso: DMCreateLocalVector() 10891411c6eeSJed Brown @*/ 10907087cfbeSBarry Smith PetscErrorCode DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog) 10911411c6eeSJed Brown { 10920be3e97aSMatthew G. Knepley PetscInt bs = -1, bsLocal[2], bsMinMax[2]; 10931411c6eeSJed Brown PetscErrorCode ierr; 10941411c6eeSJed Brown 10951411c6eeSJed Brown PetscFunctionBegin; 10961411c6eeSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 10971411c6eeSJed Brown PetscValidPointer(ltog,2); 10981411c6eeSJed Brown if (!dm->ltogmap) { 109937d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 110037d0c07bSMatthew G Knepley 110192fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 110237d0c07bSMatthew G Knepley if (section) { 1103a974ec88SMatthew G. Knepley const PetscInt *cdofs; 110437d0c07bSMatthew G Knepley PetscInt *ltog; 1105ccf3bd66SMatthew G. Knepley PetscInt pStart, pEnd, n, p, k, l; 110637d0c07bSMatthew G Knepley 1107e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 110837d0c07bSMatthew G Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 1109ccf3bd66SMatthew G. Knepley ierr = PetscSectionGetStorageSize(section, &n);CHKERRQ(ierr); 1110ccf3bd66SMatthew G. Knepley ierr = PetscMalloc1(n, <og);CHKERRQ(ierr); /* We want the local+overlap size */ 111137d0c07bSMatthew G Knepley for (p = pStart, l = 0; p < pEnd; ++p) { 1112a974ec88SMatthew G. Knepley PetscInt bdof, cdof, dof, off, c, cind = 0; 111337d0c07bSMatthew G Knepley 111437d0c07bSMatthew G Knepley /* Should probably use constrained dofs */ 111537d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 1116a974ec88SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr); 1117a974ec88SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, p, &cdofs);CHKERRQ(ierr); 111837d0c07bSMatthew G Knepley ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr); 11191a7dc684SMatthew G. Knepley /* If you have dofs, and constraints, and they are unequal, we set the blocksize to 1 */ 11201a7dc684SMatthew G. Knepley bdof = cdof && (dof-cdof) ? 1 : dof; 11211a7dc684SMatthew G. Knepley if (dof) { 1122b190aa46SMatthew G. Knepley if (bs < 0) {bs = bdof;} 1123b190aa46SMatthew G. Knepley else if (bs != bdof) {bs = 1;} 11241a7dc684SMatthew G. Knepley } 112537d0c07bSMatthew G Knepley for (c = 0; c < dof; ++c, ++l) { 1126a974ec88SMatthew G. Knepley if ((cind < cdof) && (c == cdofs[cind])) ltog[l] = off < 0 ? off-c : off+c; 1127a974ec88SMatthew G. Knepley else ltog[l] = (off < 0 ? -(off+1) : off) + c; 112837d0c07bSMatthew G Knepley } 112937d0c07bSMatthew G Knepley } 1130bff27382SMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 11310be3e97aSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 11320be3e97aSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 11330be3e97aSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 11340be3e97aSMatthew G. Knepley else {bs = bsMinMax[0];} 11357591dbb2SMatthew G. Knepley bs = bs < 0 ? 1 : bs; 11367591dbb2SMatthew G. Knepley /* Must reduce indices by blocksize */ 1137ccf3bd66SMatthew G. Knepley if (bs > 1) { 1138ccf3bd66SMatthew G. Knepley for (l = 0, k = 0; l < n; l += bs, ++k) ltog[k] = ltog[l]/bs; 1139ccf3bd66SMatthew G. Knepley n /= bs; 1140ccf3bd66SMatthew G. Knepley } 1141ccf3bd66SMatthew G. Knepley ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, n, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr); 11423bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)dm, (PetscObject)dm->ltogmap);CHKERRQ(ierr); 114337d0c07bSMatthew G Knepley } else { 1144b9d85ea2SLisandro Dalcin if (!dm->ops->getlocaltoglobalmapping) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMGetLocalToGlobalMapping",((PetscObject)dm)->type_name); 1145184d77edSJed Brown ierr = (*dm->ops->getlocaltoglobalmapping)(dm);CHKERRQ(ierr); 11461411c6eeSJed Brown } 114737d0c07bSMatthew G Knepley } 11481411c6eeSJed Brown *ltog = dm->ltogmap; 11491411c6eeSJed Brown PetscFunctionReturn(0); 11501411c6eeSJed Brown } 11511411c6eeSJed Brown 11521411c6eeSJed Brown /*@ 11531411c6eeSJed Brown DMGetBlockSize - Gets the inherent block size associated with a DM 11541411c6eeSJed Brown 11551411c6eeSJed Brown Not Collective 11561411c6eeSJed Brown 11571411c6eeSJed Brown Input Parameter: 11581411c6eeSJed Brown . dm - the DM with block structure 11591411c6eeSJed Brown 11601411c6eeSJed Brown Output Parameter: 11611411c6eeSJed Brown . bs - the block size, 1 implies no exploitable block structure 11621411c6eeSJed Brown 11631411c6eeSJed Brown Level: intermediate 11641411c6eeSJed Brown 1165fc31e74dSBarry Smith .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMapping() 11661411c6eeSJed Brown @*/ 11677087cfbeSBarry Smith PetscErrorCode DMGetBlockSize(DM dm,PetscInt *bs) 11681411c6eeSJed Brown { 11691411c6eeSJed Brown PetscFunctionBegin; 11701411c6eeSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1171534a8f05SLisandro Dalcin PetscValidIntPointer(bs,2); 11721411c6eeSJed 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"); 11731411c6eeSJed Brown *bs = dm->bs; 11741411c6eeSJed Brown PetscFunctionReturn(0); 11751411c6eeSJed Brown } 11761411c6eeSJed Brown 117748eeb7c8SBarry Smith /*@C 11788472ad0fSDave May DMCreateInterpolation - Gets interpolation matrix between two DM objects 117947c6ae99SBarry Smith 1180a5bc1bf3SBarry Smith Collective on dmc 118147c6ae99SBarry Smith 1182d8d19677SJose E. Roman Input Parameters: 1183a5bc1bf3SBarry Smith + dmc - the DM object 1184a5bc1bf3SBarry Smith - dmf - the second, finer DM object 118547c6ae99SBarry Smith 1186d8d19677SJose E. Roman Output Parameters: 118747c6ae99SBarry Smith + mat - the interpolation 118847c6ae99SBarry Smith - vec - the scaling (optional) 118947c6ae99SBarry Smith 119047c6ae99SBarry Smith Level: developer 119147c6ae99SBarry Smith 119295452b02SPatrick Sanan Notes: 119395452b02SPatrick 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 119485afcc9aSBarry Smith DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation. 1195d52bd9f3SBarry Smith 11961f588964SMatthew G Knepley For DMDA objects you can use this interpolation (more precisely the interpolation from the DMGetCoordinateDM()) to interpolate the mesh coordinate vectors 1197d52bd9f3SBarry Smith EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic. 119885afcc9aSBarry Smith 11992ed6491fSPatrick Sanan .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateRestriction(), DMCreateInterpolationScale() 120047c6ae99SBarry Smith 120147c6ae99SBarry Smith @*/ 1202a5bc1bf3SBarry Smith PetscErrorCode DMCreateInterpolation(DM dmc,DM dmf,Mat *mat,Vec *vec) 120347c6ae99SBarry Smith { 120447c6ae99SBarry Smith PetscErrorCode ierr; 120547c6ae99SBarry Smith 120647c6ae99SBarry Smith PetscFunctionBegin; 1207a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 1208a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf,DM_CLASSID,2); 1209c7d20fa0SStefano Zampini PetscValidPointer(mat,3); 1210a5bc1bf3SBarry Smith if (!dmc->ops->createinterpolation) SETERRQ1(PetscObjectComm((PetscObject)dmc),PETSC_ERR_SUP,"DM type %s does not implement DMCreateInterpolation",((PetscObject)dmc)->type_name); 1211a5bc1bf3SBarry Smith ierr = PetscLogEventBegin(DM_CreateInterpolation,dmc,dmf,0,0);CHKERRQ(ierr); 1212a5bc1bf3SBarry Smith ierr = (*dmc->ops->createinterpolation)(dmc,dmf,mat,vec);CHKERRQ(ierr); 1213a5bc1bf3SBarry Smith ierr = PetscLogEventEnd(DM_CreateInterpolation,dmc,dmf,0,0);CHKERRQ(ierr); 121447c6ae99SBarry Smith PetscFunctionReturn(0); 121547c6ae99SBarry Smith } 121647c6ae99SBarry Smith 12173ad4599aSBarry Smith /*@ 1218d3e313eaSPatrick Sanan DMCreateInterpolationScale - Forms L = 1/(R*1) such that diag(L)*R preserves scale and is thus suitable for state (versus residual) restriction. 12192ed6491fSPatrick Sanan 12202ed6491fSPatrick Sanan Input Parameters: 12212ed6491fSPatrick Sanan + dac - DM that defines a coarse mesh 12222ed6491fSPatrick Sanan . daf - DM that defines a fine mesh 12232ed6491fSPatrick Sanan - mat - the restriction (or interpolation operator) from fine to coarse 12242ed6491fSPatrick Sanan 12252ed6491fSPatrick Sanan Output Parameter: 12262ed6491fSPatrick Sanan . scale - the scaled vector 12272ed6491fSPatrick Sanan 12282ed6491fSPatrick Sanan Level: developer 12292ed6491fSPatrick Sanan 1230e9c74fd6SRichard Tran Mills Developer Notes: 1231e9c74fd6SRichard Tran Mills If the fine-scale DMDA has the -dm_bind_below option set to true, then DMCreateInterpolationScale() calls MatSetBindingPropagates() 1232e9c74fd6SRichard Tran Mills on the restriction/interpolation operator to set the bindingpropagates flag to true. 1233e9c74fd6SRichard Tran Mills 12342ed6491fSPatrick Sanan .seealso: DMCreateInterpolation() 12352ed6491fSPatrick Sanan 12362ed6491fSPatrick Sanan @*/ 12372ed6491fSPatrick Sanan PetscErrorCode DMCreateInterpolationScale(DM dac,DM daf,Mat mat,Vec *scale) 12382ed6491fSPatrick Sanan { 12392ed6491fSPatrick Sanan PetscErrorCode ierr; 12402ed6491fSPatrick Sanan Vec fine; 12412ed6491fSPatrick Sanan PetscScalar one = 1.0; 12429704db99SRichard Tran Mills #if defined(PETSC_HAVE_CUDA) 1243e9c74fd6SRichard Tran Mills PetscBool bindingpropagates,isbound; 12449704db99SRichard Tran Mills #endif 12452ed6491fSPatrick Sanan 12462ed6491fSPatrick Sanan PetscFunctionBegin; 12472ed6491fSPatrick Sanan ierr = DMCreateGlobalVector(daf,&fine);CHKERRQ(ierr); 12482ed6491fSPatrick Sanan ierr = DMCreateGlobalVector(dac,scale);CHKERRQ(ierr); 12492ed6491fSPatrick Sanan ierr = VecSet(fine,one);CHKERRQ(ierr); 12509704db99SRichard Tran Mills #if defined(PETSC_HAVE_CUDA) 12519704db99SRichard Tran Mills /* If the 'fine' Vec is bound to the CPU, it makes sense to bind 'mat' as well. 12529704db99SRichard Tran Mills * Note that we only do this for the CUDA case, right now, but if we add support for MatMultTranspose() via ViennaCL, 12539704db99SRichard Tran Mills * we'll need to do it for that case, too.*/ 1254e9c74fd6SRichard Tran Mills ierr = VecGetBindingPropagates(fine,&bindingpropagates);CHKERRQ(ierr); 1255e9c74fd6SRichard Tran Mills if (bindingpropagates) { 1256b1538989SRichard Tran Mills ierr = MatSetBindingPropagates(mat,PETSC_TRUE);CHKERRQ(ierr); 1257e9c74fd6SRichard Tran Mills ierr = VecBoundToCPU(fine,&isbound);CHKERRQ(ierr); 1258e9c74fd6SRichard Tran Mills ierr = MatBindToCPU(mat,isbound);CHKERRQ(ierr); 125983aa49f4SRichard Tran Mills } 12609704db99SRichard Tran Mills #endif 12612ed6491fSPatrick Sanan ierr = MatRestrict(mat,fine,*scale);CHKERRQ(ierr); 12622ed6491fSPatrick Sanan ierr = VecDestroy(&fine);CHKERRQ(ierr); 12632ed6491fSPatrick Sanan ierr = VecReciprocal(*scale);CHKERRQ(ierr); 12642ed6491fSPatrick Sanan PetscFunctionReturn(0); 12652ed6491fSPatrick Sanan } 12662ed6491fSPatrick Sanan 12672ed6491fSPatrick Sanan /*@ 12683ad4599aSBarry Smith DMCreateRestriction - Gets restriction matrix between two DM objects 12693ad4599aSBarry Smith 1270a5bc1bf3SBarry Smith Collective on dmc 12713ad4599aSBarry Smith 1272d8d19677SJose E. Roman Input Parameters: 1273a5bc1bf3SBarry Smith + dmc - the DM object 1274a5bc1bf3SBarry Smith - dmf - the second, finer DM object 12753ad4599aSBarry Smith 12763ad4599aSBarry Smith Output Parameter: 12773ad4599aSBarry Smith . mat - the restriction 12783ad4599aSBarry Smith 12793ad4599aSBarry Smith Level: developer 12803ad4599aSBarry Smith 128195452b02SPatrick Sanan Notes: 128295452b02SPatrick 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 12833ad4599aSBarry Smith DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation. 12843ad4599aSBarry Smith 12853ad4599aSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateInterpolation() 12863ad4599aSBarry Smith 12873ad4599aSBarry Smith @*/ 1288a5bc1bf3SBarry Smith PetscErrorCode DMCreateRestriction(DM dmc,DM dmf,Mat *mat) 12893ad4599aSBarry Smith { 12903ad4599aSBarry Smith PetscErrorCode ierr; 12913ad4599aSBarry Smith 12923ad4599aSBarry Smith PetscFunctionBegin; 1293a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 1294a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf,DM_CLASSID,2); 12955a84ad33SLisandro Dalcin PetscValidPointer(mat,3); 1296a5bc1bf3SBarry Smith if (!dmc->ops->createrestriction) SETERRQ1(PetscObjectComm((PetscObject)dmc),PETSC_ERR_SUP,"DM type %s does not implement DMCreateRestriction",((PetscObject)dmc)->type_name); 1297a5bc1bf3SBarry Smith ierr = PetscLogEventBegin(DM_CreateRestriction,dmc,dmf,0,0);CHKERRQ(ierr); 1298a5bc1bf3SBarry Smith ierr = (*dmc->ops->createrestriction)(dmc,dmf,mat);CHKERRQ(ierr); 1299a5bc1bf3SBarry Smith ierr = PetscLogEventEnd(DM_CreateRestriction,dmc,dmf,0,0);CHKERRQ(ierr); 13003ad4599aSBarry Smith PetscFunctionReturn(0); 13013ad4599aSBarry Smith } 13023ad4599aSBarry Smith 130347c6ae99SBarry Smith /*@ 13048472ad0fSDave May DMCreateInjection - Gets injection matrix between two DM objects 130547c6ae99SBarry Smith 1306a5bc1bf3SBarry Smith Collective on dac 130747c6ae99SBarry Smith 1308d8d19677SJose E. Roman Input Parameters: 1309a5bc1bf3SBarry Smith + dac - the DM object 1310a5bc1bf3SBarry Smith - daf - the second, finer DM object 131147c6ae99SBarry Smith 131247c6ae99SBarry Smith Output Parameter: 13136dbf9973SLawrence Mitchell . mat - the injection 131447c6ae99SBarry Smith 131547c6ae99SBarry Smith Level: developer 131647c6ae99SBarry Smith 131795452b02SPatrick Sanan Notes: 131895452b02SPatrick 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 131985afcc9aSBarry Smith DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection. 132085afcc9aSBarry Smith 1321e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation() 132247c6ae99SBarry Smith 132347c6ae99SBarry Smith @*/ 1324a5bc1bf3SBarry Smith PetscErrorCode DMCreateInjection(DM dac,DM daf,Mat *mat) 132547c6ae99SBarry Smith { 132647c6ae99SBarry Smith PetscErrorCode ierr; 132747c6ae99SBarry Smith 132847c6ae99SBarry Smith PetscFunctionBegin; 1329a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dac,DM_CLASSID,1); 1330a5bc1bf3SBarry Smith PetscValidHeaderSpecific(daf,DM_CLASSID,2); 13315a84ad33SLisandro Dalcin PetscValidPointer(mat,3); 1332a5bc1bf3SBarry Smith if (!dac->ops->createinjection) SETERRQ1(PetscObjectComm((PetscObject)dac),PETSC_ERR_SUP,"DM type %s does not implement DMCreateInjection",((PetscObject)dac)->type_name); 1333a5bc1bf3SBarry Smith ierr = PetscLogEventBegin(DM_CreateInjection,dac,daf,0,0);CHKERRQ(ierr); 1334a5bc1bf3SBarry Smith ierr = (*dac->ops->createinjection)(dac,daf,mat);CHKERRQ(ierr); 1335a5bc1bf3SBarry Smith ierr = PetscLogEventEnd(DM_CreateInjection,dac,daf,0,0);CHKERRQ(ierr); 133647c6ae99SBarry Smith PetscFunctionReturn(0); 133747c6ae99SBarry Smith } 133847c6ae99SBarry Smith 1339b412c318SBarry Smith /*@ 1340bd041c0cSMatthew G. Knepley DMCreateMassMatrix - Gets mass matrix between two DM objects, M_ij = \int \phi_i \psi_j 1341bd041c0cSMatthew G. Knepley 1342a5bc1bf3SBarry Smith Collective on dac 1343bd041c0cSMatthew G. Knepley 1344d8d19677SJose E. Roman Input Parameters: 1345*b4937a87SMatthew G. Knepley + dmc - the target DM object 1346*b4937a87SMatthew G. Knepley - dmf - the source DM object 1347bd041c0cSMatthew G. Knepley 1348bd041c0cSMatthew G. Knepley Output Parameter: 1349*b4937a87SMatthew G. Knepley . mat - the mass matrix 1350bd041c0cSMatthew G. Knepley 1351bd041c0cSMatthew G. Knepley Level: developer 1352bd041c0cSMatthew G. Knepley 1353*b4937a87SMatthew G. Knepley .seealso DMCreateMassMatrixLumped(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateRestriction(), DMCreateInterpolation(), DMCreateInjection() 1354bd041c0cSMatthew G. Knepley @*/ 1355*b4937a87SMatthew G. Knepley PetscErrorCode DMCreateMassMatrix(DM dmc, DM dmf, Mat *mat) 1356bd041c0cSMatthew G. Knepley { 1357bd041c0cSMatthew G. Knepley PetscErrorCode ierr; 1358bd041c0cSMatthew G. Knepley 1359bd041c0cSMatthew G. Knepley PetscFunctionBegin; 1360*b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 1361*b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 13625a84ad33SLisandro Dalcin PetscValidPointer(mat,3); 1363*b4937a87SMatthew G. Knepley if (!dmc->ops->createmassmatrix) SETERRQ1(PetscObjectComm((PetscObject)dmc),PETSC_ERR_SUP,"DM type %s does not implement DMCreateMassMatrix",((PetscObject)dmc)->type_name); 1364*b4937a87SMatthew G. Knepley ierr = (*dmc->ops->createmassmatrix)(dmc, dmf, mat);CHKERRQ(ierr); 1365*b4937a87SMatthew G. Knepley PetscFunctionReturn(0); 1366*b4937a87SMatthew G. Knepley } 1367*b4937a87SMatthew G. Knepley 1368*b4937a87SMatthew G. Knepley /*@ 1369*b4937a87SMatthew G. Knepley DMCreateMassMatrixLumped - Gets the lumped mass matrix for a given DM 1370*b4937a87SMatthew G. Knepley 1371*b4937a87SMatthew G. Knepley Collective on dm 1372*b4937a87SMatthew G. Knepley 1373*b4937a87SMatthew G. Knepley Input Parameter: 1374*b4937a87SMatthew G. Knepley . dm - the DM object 1375*b4937a87SMatthew G. Knepley 1376*b4937a87SMatthew G. Knepley Output Parameter: 1377*b4937a87SMatthew G. Knepley . lm - the lumped mass matrix 1378*b4937a87SMatthew G. Knepley 1379*b4937a87SMatthew G. Knepley Level: developer 1380*b4937a87SMatthew G. Knepley 1381*b4937a87SMatthew G. Knepley .seealso DMCreateMassMatrix(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateRestriction(), DMCreateInterpolation(), DMCreateInjection() 1382*b4937a87SMatthew G. Knepley @*/ 1383*b4937a87SMatthew G. Knepley PetscErrorCode DMCreateMassMatrixLumped(DM dm, Vec *lm) 1384*b4937a87SMatthew G. Knepley { 1385*b4937a87SMatthew G. Knepley PetscErrorCode ierr; 1386*b4937a87SMatthew G. Knepley 1387*b4937a87SMatthew G. Knepley PetscFunctionBegin; 1388*b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1389*b4937a87SMatthew G. Knepley PetscValidPointer(lm,2); 1390*b4937a87SMatthew G. Knepley if (!dm->ops->createmassmatrixlumped) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateMassMatrixLumped",((PetscObject)dm)->type_name); 1391*b4937a87SMatthew G. Knepley ierr = (*dm->ops->createmassmatrixlumped)(dm, lm);CHKERRQ(ierr); 1392bd041c0cSMatthew G. Knepley PetscFunctionReturn(0); 1393bd041c0cSMatthew G. Knepley } 1394bd041c0cSMatthew G. Knepley 1395bd041c0cSMatthew G. Knepley /*@ 1396b412c318SBarry Smith DMCreateColoring - Gets coloring for a DM 139747c6ae99SBarry Smith 1398d083f849SBarry Smith Collective on dm 139947c6ae99SBarry Smith 1400d8d19677SJose E. Roman Input Parameters: 140147c6ae99SBarry Smith + dm - the DM object 14025bdb020cSBarry Smith - ctype - IS_COLORING_LOCAL or IS_COLORING_GLOBAL 140347c6ae99SBarry Smith 140447c6ae99SBarry Smith Output Parameter: 140547c6ae99SBarry Smith . coloring - the coloring 140647c6ae99SBarry Smith 1407ec5066bdSBarry Smith Notes: 1408ec5066bdSBarry 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 1409ec5066bdSBarry Smith matrix comes from. In general using the mesh produces a more optimal coloring (fewer colors). 1410ec5066bdSBarry Smith 1411ec5066bdSBarry Smith This produces a coloring with the distance of 2, see MatSetColoringDistance() which can be used for efficiently computing Jacobians with MatFDColoringCreate() 1412ec5066bdSBarry Smith 141347c6ae99SBarry Smith Level: developer 141447c6ae99SBarry Smith 1415ec5066bdSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix(), DMSetMatType(), MatColoring, MatFDColoringCreate() 141647c6ae99SBarry Smith 1417aab9d709SJed Brown @*/ 1418b412c318SBarry Smith PetscErrorCode DMCreateColoring(DM dm,ISColoringType ctype,ISColoring *coloring) 141947c6ae99SBarry Smith { 142047c6ae99SBarry Smith PetscErrorCode ierr; 142147c6ae99SBarry Smith 142247c6ae99SBarry Smith PetscFunctionBegin; 1423171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 14245a84ad33SLisandro Dalcin PetscValidPointer(coloring,3); 1425b9d85ea2SLisandro Dalcin if (!dm->ops->getcoloring) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateColoring",((PetscObject)dm)->type_name); 1426b412c318SBarry Smith ierr = (*dm->ops->getcoloring)(dm,ctype,coloring);CHKERRQ(ierr); 142747c6ae99SBarry Smith PetscFunctionReturn(0); 142847c6ae99SBarry Smith } 142947c6ae99SBarry Smith 1430b412c318SBarry Smith /*@ 14318472ad0fSDave May DMCreateMatrix - Gets empty Jacobian for a DM 143247c6ae99SBarry Smith 1433d083f849SBarry Smith Collective on dm 143447c6ae99SBarry Smith 143547c6ae99SBarry Smith Input Parameter: 1436b412c318SBarry Smith . dm - the DM object 143747c6ae99SBarry Smith 143847c6ae99SBarry Smith Output Parameter: 143947c6ae99SBarry Smith . mat - the empty Jacobian 144047c6ae99SBarry Smith 1441073dac72SJed Brown Level: beginner 144247c6ae99SBarry Smith 1443f27dd7c6SMatthew G. Knepley Options Database Keys: 1444f27dd7c6SMatthew G. Knepley . -dm_preallocate_only - Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros 1445f27dd7c6SMatthew G. Knepley 144695452b02SPatrick Sanan Notes: 144795452b02SPatrick Sanan This properly preallocates the number of nonzeros in the sparse matrix so you 144894013140SBarry Smith do not need to do it yourself. 144994013140SBarry Smith 145094013140SBarry Smith By default it also sets the nonzero structure and puts in the zero entries. To prevent setting 14517889ec69SBarry Smith the nonzero pattern call DMSetMatrixPreallocateOnly() 145294013140SBarry Smith 145394013140SBarry 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 145494013140SBarry Smith internally by PETSc. 145594013140SBarry Smith 145694013140SBarry Smith For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires 1457aa219208SBarry Smith the indices for the global numbering for DMDAs which is complicated. 145894013140SBarry Smith 1459b412c318SBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMSetMatType() 146047c6ae99SBarry Smith 1461aab9d709SJed Brown @*/ 1462b412c318SBarry Smith PetscErrorCode DMCreateMatrix(DM dm,Mat *mat) 146347c6ae99SBarry Smith { 146447c6ae99SBarry Smith PetscErrorCode ierr; 146547c6ae99SBarry Smith 146647c6ae99SBarry Smith PetscFunctionBegin; 1467171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1468064a246eSJacob Faibussowitsch PetscValidPointer(mat,2); 1469b9d85ea2SLisandro Dalcin if (!dm->ops->creatematrix) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateMatrix",((PetscObject)dm)->type_name); 14705a84ad33SLisandro Dalcin ierr = MatInitializePackage();CHKERRQ(ierr); 1471fdc842d1SBarry Smith ierr = PetscLogEventBegin(DM_CreateMatrix,0,0,0,0);CHKERRQ(ierr); 1472b412c318SBarry Smith ierr = (*dm->ops->creatematrix)(dm,mat);CHKERRQ(ierr); 147376bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1474c6b011d8SStefano Zampini DM mdm; 1475c6b011d8SStefano Zampini 1476c6b011d8SStefano Zampini ierr = MatGetDM(*mat,&mdm);CHKERRQ(ierr); 1477c6b011d8SStefano 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); 1478c6b011d8SStefano Zampini } 1479e571a35bSMatthew G. Knepley /* Handle nullspace and near nullspace */ 1480e5e52638SMatthew G. Knepley if (dm->Nf) { 1481e571a35bSMatthew G. Knepley MatNullSpace nullSpace; 1482649ef022SMatthew Knepley PetscInt Nf, f; 1483e571a35bSMatthew G. Knepley 1484e5e52638SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 1485649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1486649ef022SMatthew Knepley if (dm->nullspaceConstructors[f]) { 1487649ef022SMatthew Knepley ierr = (*dm->nullspaceConstructors[f])(dm, f, f, &nullSpace);CHKERRQ(ierr); 1488e571a35bSMatthew G. Knepley ierr = MatSetNullSpace(*mat, nullSpace);CHKERRQ(ierr); 1489e571a35bSMatthew G. Knepley ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr); 1490649ef022SMatthew Knepley break; 1491e571a35bSMatthew G. Knepley } 1492649ef022SMatthew Knepley } 1493649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1494649ef022SMatthew Knepley if (dm->nearnullspaceConstructors[f]) { 1495649ef022SMatthew Knepley ierr = (*dm->nearnullspaceConstructors[f])(dm, f, f, &nullSpace);CHKERRQ(ierr); 1496e571a35bSMatthew G. Knepley ierr = MatSetNearNullSpace(*mat, nullSpace);CHKERRQ(ierr); 1497e571a35bSMatthew G. Knepley ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr); 1498e571a35bSMatthew G. Knepley } 1499e571a35bSMatthew G. Knepley } 1500e571a35bSMatthew G. Knepley } 1501fdc842d1SBarry Smith ierr = PetscLogEventEnd(DM_CreateMatrix,0,0,0,0);CHKERRQ(ierr); 150247c6ae99SBarry Smith PetscFunctionReturn(0); 150347c6ae99SBarry Smith } 150447c6ae99SBarry Smith 1505732e2eb9SMatthew G Knepley /*@ 1506950540a4SJed Brown DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly 1507732e2eb9SMatthew G Knepley preallocated but the nonzero structure and zero values will not be set. 1508732e2eb9SMatthew G Knepley 1509d083f849SBarry Smith Logically Collective on dm 1510732e2eb9SMatthew G Knepley 1511d8d19677SJose E. Roman Input Parameters: 1512732e2eb9SMatthew G Knepley + dm - the DM 1513732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation 1514732e2eb9SMatthew G Knepley 1515732e2eb9SMatthew G Knepley Level: developer 1516f27dd7c6SMatthew G. Knepley 1517f27dd7c6SMatthew G. Knepley Options Database Keys: 1518f27dd7c6SMatthew G. Knepley . -dm_preallocate_only - Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros 1519f27dd7c6SMatthew G. Knepley 1520b06ff27eSHong Zhang .seealso DMCreateMatrix(), DMSetMatrixStructureOnly() 1521732e2eb9SMatthew G Knepley @*/ 1522732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only) 1523732e2eb9SMatthew G Knepley { 1524732e2eb9SMatthew G Knepley PetscFunctionBegin; 1525732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1526732e2eb9SMatthew G Knepley dm->prealloc_only = only; 1527732e2eb9SMatthew G Knepley PetscFunctionReturn(0); 1528732e2eb9SMatthew G Knepley } 1529732e2eb9SMatthew G Knepley 1530b06ff27eSHong Zhang /*@ 1531b06ff27eSHong Zhang DMSetMatrixStructureOnly - When DMCreateMatrix() is called, the matrix structure will be created 1532b06ff27eSHong Zhang but the array for values will not be allocated. 1533b06ff27eSHong Zhang 1534d083f849SBarry Smith Logically Collective on dm 1535b06ff27eSHong Zhang 1536d8d19677SJose E. Roman Input Parameters: 1537b06ff27eSHong Zhang + dm - the DM 1538b06ff27eSHong Zhang - only - PETSC_TRUE if only want matrix stucture 1539b06ff27eSHong Zhang 1540b06ff27eSHong Zhang Level: developer 1541b06ff27eSHong Zhang .seealso DMCreateMatrix(), DMSetMatrixPreallocateOnly() 1542b06ff27eSHong Zhang @*/ 1543b06ff27eSHong Zhang PetscErrorCode DMSetMatrixStructureOnly(DM dm, PetscBool only) 1544b06ff27eSHong Zhang { 1545b06ff27eSHong Zhang PetscFunctionBegin; 1546b06ff27eSHong Zhang PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1547b06ff27eSHong Zhang dm->structure_only = only; 1548b06ff27eSHong Zhang PetscFunctionReturn(0); 1549b06ff27eSHong Zhang } 1550b06ff27eSHong Zhang 1551a89ea682SMatthew G Knepley /*@C 1552aa1993deSMatthew G Knepley DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray() 1553a89ea682SMatthew G Knepley 1554a89ea682SMatthew G Knepley Not Collective 1555a89ea682SMatthew G Knepley 1556a89ea682SMatthew G Knepley Input Parameters: 1557a89ea682SMatthew G Knepley + dm - the DM object 1558a5b23f4aSJose E. Roman . count - The minimum size 155969291d52SBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, MPIU_INT) 1560a89ea682SMatthew G Knepley 1561a89ea682SMatthew G Knepley Output Parameter: 1562a89ea682SMatthew G Knepley . array - the work array 1563a89ea682SMatthew G Knepley 1564a89ea682SMatthew G Knepley Level: developer 1565a89ea682SMatthew G Knepley 1566a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate() 1567a89ea682SMatthew G Knepley @*/ 156869291d52SBarry Smith PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,MPI_Datatype dtype,void *mem) 1569a89ea682SMatthew G Knepley { 1570a89ea682SMatthew G Knepley PetscErrorCode ierr; 1571aa1993deSMatthew G Knepley DMWorkLink link; 157269291d52SBarry Smith PetscMPIInt dsize; 1573a89ea682SMatthew G Knepley 1574a89ea682SMatthew G Knepley PetscFunctionBegin; 1575a89ea682SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1576aa1993deSMatthew G Knepley PetscValidPointer(mem,4); 1577aa1993deSMatthew G Knepley if (dm->workin) { 1578aa1993deSMatthew G Knepley link = dm->workin; 1579aa1993deSMatthew G Knepley dm->workin = dm->workin->next; 1580aa1993deSMatthew G Knepley } else { 1581b00a9115SJed Brown ierr = PetscNewLog(dm,&link);CHKERRQ(ierr); 1582a89ea682SMatthew G Knepley } 1583ffc4695bSBarry Smith ierr = MPI_Type_size(dtype,&dsize);CHKERRMPI(ierr); 15845056fcd2SBarry Smith if (((size_t)dsize*count) > link->bytes) { 1585aa1993deSMatthew G Knepley ierr = PetscFree(link->mem);CHKERRQ(ierr); 1586854ce69bSBarry Smith ierr = PetscMalloc(dsize*count,&link->mem);CHKERRQ(ierr); 1587854ce69bSBarry Smith link->bytes = dsize*count; 1588aa1993deSMatthew G Knepley } 1589aa1993deSMatthew G Knepley link->next = dm->workout; 1590aa1993deSMatthew G Knepley dm->workout = link; 159100d952a4SJed Brown #if defined(PETSC_HAVE_VALGRIND) 159200d952a4SJed Brown VALGRIND_MAKE_MEM_NOACCESS((char*)link->mem + (size_t)dsize*count, link->bytes - (size_t)dsize*count); 159300d952a4SJed Brown VALGRIND_MAKE_MEM_UNDEFINED(link->mem, (size_t)dsize*count); 159400d952a4SJed Brown #endif 1595aa1993deSMatthew G Knepley *(void**)mem = link->mem; 1596a89ea682SMatthew G Knepley PetscFunctionReturn(0); 1597a89ea682SMatthew G Knepley } 1598a89ea682SMatthew G Knepley 1599aa1993deSMatthew G Knepley /*@C 1600aa1993deSMatthew G Knepley DMRestoreWorkArray - Restores a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray() 1601aa1993deSMatthew G Knepley 1602aa1993deSMatthew G Knepley Not Collective 1603aa1993deSMatthew G Knepley 1604aa1993deSMatthew G Knepley Input Parameters: 1605aa1993deSMatthew G Knepley + dm - the DM object 1606a5b23f4aSJose E. Roman . count - The minimum size 160769291d52SBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, MPIU_INT 1608aa1993deSMatthew G Knepley 1609aa1993deSMatthew G Knepley Output Parameter: 1610aa1993deSMatthew G Knepley . array - the work array 1611aa1993deSMatthew G Knepley 1612aa1993deSMatthew G Knepley Level: developer 1613aa1993deSMatthew G Knepley 161495452b02SPatrick Sanan Developer Notes: 161595452b02SPatrick Sanan count and dtype are ignored, they are only needed for DMGetWorkArray() 1616aa1993deSMatthew G Knepley .seealso DMDestroy(), DMCreate() 1617aa1993deSMatthew G Knepley @*/ 161869291d52SBarry Smith PetscErrorCode DMRestoreWorkArray(DM dm,PetscInt count,MPI_Datatype dtype,void *mem) 1619aa1993deSMatthew G Knepley { 1620aa1993deSMatthew G Knepley DMWorkLink *p,link; 1621aa1993deSMatthew G Knepley 1622aa1993deSMatthew G Knepley PetscFunctionBegin; 1623aa1993deSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1624aa1993deSMatthew G Knepley PetscValidPointer(mem,4); 1625aa1993deSMatthew G Knepley for (p=&dm->workout; (link=*p); p=&link->next) { 1626aa1993deSMatthew G Knepley if (link->mem == *(void**)mem) { 1627aa1993deSMatthew G Knepley *p = link->next; 1628aa1993deSMatthew G Knepley link->next = dm->workin; 1629aa1993deSMatthew G Knepley dm->workin = link; 16300298fd71SBarry Smith *(void**)mem = NULL; 1631aa1993deSMatthew G Knepley PetscFunctionReturn(0); 1632aa1993deSMatthew G Knepley } 1633aa1993deSMatthew G Knepley } 1634aa1993deSMatthew G Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out"); 1635aa1993deSMatthew G Knepley } 1636e7c4fc90SDmitry Karpeev 16378cda7954SMatthew G. Knepley /*@C 16388cda7954SMatthew G. Knepley DMSetNullSpaceConstructor - Provide a callback function which constructs the nullspace for a given field 16398cda7954SMatthew G. Knepley 16408cda7954SMatthew G. Knepley Logically collective on DM 16418cda7954SMatthew G. Knepley 16428cda7954SMatthew G. Knepley Input Parameters: 16438cda7954SMatthew G. Knepley + dm - The DM 16448cda7954SMatthew G. Knepley . field - The field number for the nullspace 16458cda7954SMatthew G. Knepley - nullsp - A callback to create the nullspace 16468cda7954SMatthew G. Knepley 16478cda7954SMatthew G. Knepley Notes: 16488cda7954SMatthew G. Knepley The callback is intended to provide nullspaces when function spaces are joined or split, such as in DMCreateSubDM(). The calling sequence is 16498cda7954SMatthew G. Knepley $ PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 16508cda7954SMatthew G. Knepley $ dm - The present DM 16518cda7954SMatthew G. Knepley $ origField - The field number given above, in the original DM 16528cda7954SMatthew G. Knepley $ field - The field number in dm 16538cda7954SMatthew G. Knepley $ nullSpace - The nullspace for the given field 16548cda7954SMatthew G. Knepley 16558cda7954SMatthew G. Knepley This function is currently not available from Fortran. 16568cda7954SMatthew G. Knepley 16578cda7954SMatthew G. Knepley .seealso: DMGetNullSpaceConstructor(), DMSetNearNullSpaceConstructor(), DMGetNearNullSpaceConstructor(), DMCreateSubDM(), DMCreateSuperDM() 16588cda7954SMatthew G. Knepley */ 16598cda7954SMatthew G. Knepley PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1660435a35e8SMatthew G Knepley { 1661435a35e8SMatthew G Knepley PetscFunctionBegin; 1662435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 166382f516ccSBarry Smith if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field); 1664435a35e8SMatthew G Knepley dm->nullspaceConstructors[field] = nullsp; 1665435a35e8SMatthew G Knepley PetscFunctionReturn(0); 1666435a35e8SMatthew G Knepley } 1667435a35e8SMatthew G Knepley 16688cda7954SMatthew G. Knepley /*@C 16698cda7954SMatthew G. Knepley DMGetNullSpaceConstructor - Return the callback function which constructs the nullspace for a given field, or NULL 16708cda7954SMatthew G. Knepley 16718cda7954SMatthew G. Knepley Not collective 16728cda7954SMatthew G. Knepley 16738cda7954SMatthew G. Knepley Input Parameters: 16748cda7954SMatthew G. Knepley + dm - The DM 16758cda7954SMatthew G. Knepley - field - The field number for the nullspace 16768cda7954SMatthew G. Knepley 16778cda7954SMatthew G. Knepley Output Parameter: 16788cda7954SMatthew G. Knepley . nullsp - A callback to create the nullspace 16798cda7954SMatthew G. Knepley 16808cda7954SMatthew G. Knepley Notes: 16818cda7954SMatthew G. Knepley The callback is intended to provide nullspaces when function spaces are joined or split, such as in DMCreateSubDM(). The calling sequence is 16828cda7954SMatthew G. Knepley $ PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 16838cda7954SMatthew G. Knepley $ dm - The present DM 16848cda7954SMatthew G. Knepley $ origField - The field number given above, in the original DM 16858cda7954SMatthew G. Knepley $ field - The field number in dm 16868cda7954SMatthew G. Knepley $ nullSpace - The nullspace for the given field 16878cda7954SMatthew G. Knepley 16888cda7954SMatthew G. Knepley This function is currently not available from Fortran. 16898cda7954SMatthew G. Knepley 16908cda7954SMatthew G. Knepley .seealso: DMSetNullSpaceConstructor(), DMSetNearNullSpaceConstructor(), DMGetNearNullSpaceConstructor(), DMCreateSubDM(), DMCreateSuperDM() 16918cda7954SMatthew G. Knepley */ 16928cda7954SMatthew G. Knepley PetscErrorCode DMGetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 16930a50eb56SMatthew G. Knepley { 16940a50eb56SMatthew G. Knepley PetscFunctionBegin; 16950a50eb56SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1696f9d4088aSMatthew G. Knepley PetscValidPointer(nullsp, 3); 16970a50eb56SMatthew G. Knepley if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field); 16980a50eb56SMatthew G. Knepley *nullsp = dm->nullspaceConstructors[field]; 16990a50eb56SMatthew G. Knepley PetscFunctionReturn(0); 17000a50eb56SMatthew G. Knepley } 17010a50eb56SMatthew G. Knepley 17028cda7954SMatthew G. Knepley /*@C 17038cda7954SMatthew G. Knepley DMSetNearNullSpaceConstructor - Provide a callback function which constructs the near-nullspace for a given field 17048cda7954SMatthew G. Knepley 17058cda7954SMatthew G. Knepley Logically collective on DM 17068cda7954SMatthew G. Knepley 17078cda7954SMatthew G. Knepley Input Parameters: 17088cda7954SMatthew G. Knepley + dm - The DM 17098cda7954SMatthew G. Knepley . field - The field number for the nullspace 17108cda7954SMatthew G. Knepley - nullsp - A callback to create the near-nullspace 17118cda7954SMatthew G. Knepley 17128cda7954SMatthew G. Knepley Notes: 17138cda7954SMatthew G. Knepley The callback is intended to provide nullspaces when function spaces are joined or split, such as in DMCreateSubDM(). The calling sequence is 17148cda7954SMatthew G. Knepley $ PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 17158cda7954SMatthew G. Knepley $ dm - The present DM 17168cda7954SMatthew G. Knepley $ origField - The field number given above, in the original DM 17178cda7954SMatthew G. Knepley $ field - The field number in dm 17188cda7954SMatthew G. Knepley $ nullSpace - The nullspace for the given field 17198cda7954SMatthew G. Knepley 17208cda7954SMatthew G. Knepley This function is currently not available from Fortran. 17218cda7954SMatthew G. Knepley 17228cda7954SMatthew G. Knepley .seealso: DMGetNearNullSpaceConstructor(), DMSetNullSpaceConstructor(), DMGetNullSpaceConstructor(), DMCreateSubDM(), DMCreateSuperDM() 17238cda7954SMatthew G. Knepley */ 17248cda7954SMatthew G. Knepley PetscErrorCode DMSetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1725f9d4088aSMatthew G. Knepley { 1726f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1727f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1728f9d4088aSMatthew G. Knepley if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field); 1729f9d4088aSMatthew G. Knepley dm->nearnullspaceConstructors[field] = nullsp; 1730f9d4088aSMatthew G. Knepley PetscFunctionReturn(0); 1731f9d4088aSMatthew G. Knepley } 1732f9d4088aSMatthew G. Knepley 17338cda7954SMatthew G. Knepley /*@C 17348cda7954SMatthew G. Knepley DMGetNearNullSpaceConstructor - Return the callback function which constructs the near-nullspace for a given field, or NULL 17358cda7954SMatthew G. Knepley 17368cda7954SMatthew G. Knepley Not collective 17378cda7954SMatthew G. Knepley 17388cda7954SMatthew G. Knepley Input Parameters: 17398cda7954SMatthew G. Knepley + dm - The DM 17408cda7954SMatthew G. Knepley - field - The field number for the nullspace 17418cda7954SMatthew G. Knepley 17428cda7954SMatthew G. Knepley Output Parameter: 17438cda7954SMatthew G. Knepley . nullsp - A callback to create the near-nullspace 17448cda7954SMatthew G. Knepley 17458cda7954SMatthew G. Knepley Notes: 17468cda7954SMatthew G. Knepley The callback is intended to provide nullspaces when function spaces are joined or split, such as in DMCreateSubDM(). The calling sequence is 17478cda7954SMatthew G. Knepley $ PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 17488cda7954SMatthew G. Knepley $ dm - The present DM 17498cda7954SMatthew G. Knepley $ origField - The field number given above, in the original DM 17508cda7954SMatthew G. Knepley $ field - The field number in dm 17518cda7954SMatthew G. Knepley $ nullSpace - The nullspace for the given field 17528cda7954SMatthew G. Knepley 17538cda7954SMatthew G. Knepley This function is currently not available from Fortran. 17548cda7954SMatthew G. Knepley 17558cda7954SMatthew G. Knepley .seealso: DMSetNearNullSpaceConstructor(), DMSetNullSpaceConstructor(), DMGetNullSpaceConstructor(), DMCreateSubDM(), DMCreateSuperDM() 17568cda7954SMatthew G. Knepley */ 17578cda7954SMatthew G. Knepley PetscErrorCode DMGetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1758f9d4088aSMatthew G. Knepley { 1759f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1760f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1761f9d4088aSMatthew G. Knepley PetscValidPointer(nullsp, 3); 1762f9d4088aSMatthew G. Knepley if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field); 1763f9d4088aSMatthew G. Knepley *nullsp = dm->nearnullspaceConstructors[field]; 1764f9d4088aSMatthew G. Knepley PetscFunctionReturn(0); 1765f9d4088aSMatthew G. Knepley } 1766f9d4088aSMatthew G. Knepley 17674f3b5142SJed Brown /*@C 17684d343eeaSMatthew G Knepley DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field 17694d343eeaSMatthew G Knepley 17704d343eeaSMatthew G Knepley Not collective 17714d343eeaSMatthew G Knepley 17724d343eeaSMatthew G Knepley Input Parameter: 17734d343eeaSMatthew G Knepley . dm - the DM object 17744d343eeaSMatthew G Knepley 17754d343eeaSMatthew G Knepley Output Parameters: 17760298fd71SBarry Smith + numFields - The number of fields (or NULL if not requested) 17770298fd71SBarry Smith . fieldNames - The name for each field (or NULL if not requested) 17780298fd71SBarry Smith - fields - The global indices for each field (or NULL if not requested) 17794d343eeaSMatthew G Knepley 17804d343eeaSMatthew G Knepley Level: intermediate 17814d343eeaSMatthew G Knepley 178221c9b008SJed Brown Notes: 178321c9b008SJed Brown The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 178421c9b008SJed Brown PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with 178521c9b008SJed Brown PetscFree(). 178621c9b008SJed Brown 17874d343eeaSMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix() 17884d343eeaSMatthew G Knepley @*/ 178937d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields) 17904d343eeaSMatthew G Knepley { 179137d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 17924d343eeaSMatthew G Knepley PetscErrorCode ierr; 17934d343eeaSMatthew G Knepley 17944d343eeaSMatthew G Knepley PetscFunctionBegin; 17954d343eeaSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 179669ca1f37SDmitry Karpeev if (numFields) { 1797534a8f05SLisandro Dalcin PetscValidIntPointer(numFields,2); 179869ca1f37SDmitry Karpeev *numFields = 0; 179969ca1f37SDmitry Karpeev } 180037d0c07bSMatthew G Knepley if (fieldNames) { 180137d0c07bSMatthew G Knepley PetscValidPointer(fieldNames,3); 18020298fd71SBarry Smith *fieldNames = NULL; 180369ca1f37SDmitry Karpeev } 180469ca1f37SDmitry Karpeev if (fields) { 180569ca1f37SDmitry Karpeev PetscValidPointer(fields,4); 18060298fd71SBarry Smith *fields = NULL; 180769ca1f37SDmitry Karpeev } 180892fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 180937d0c07bSMatthew G Knepley if (section) { 18103a544194SStefano Zampini PetscInt *fieldSizes, *fieldNc, **fieldIndices; 181137d0c07bSMatthew G Knepley PetscInt nF, f, pStart, pEnd, p; 181237d0c07bSMatthew G Knepley 1813e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 181437d0c07bSMatthew G Knepley ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr); 18153a544194SStefano Zampini ierr = PetscMalloc3(nF,&fieldSizes,nF,&fieldNc,nF,&fieldIndices);CHKERRQ(ierr); 181637d0c07bSMatthew G Knepley ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 181737d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 181837d0c07bSMatthew G Knepley fieldSizes[f] = 0; 18193a544194SStefano Zampini ierr = PetscSectionGetFieldComponents(section, f, &fieldNc[f]);CHKERRQ(ierr); 182037d0c07bSMatthew G Knepley } 182137d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 182237d0c07bSMatthew G Knepley PetscInt gdof; 182337d0c07bSMatthew G Knepley 182437d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 182537d0c07bSMatthew G Knepley if (gdof > 0) { 182637d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 18273a544194SStefano Zampini PetscInt fdof, fcdof, fpdof; 182837d0c07bSMatthew G Knepley 182937d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 183037d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 18313a544194SStefano Zampini fpdof = fdof-fcdof; 18323a544194SStefano Zampini if (fpdof && fpdof != fieldNc[f]) { 18333a544194SStefano Zampini /* Layout does not admit a pointwise block size */ 18343a544194SStefano Zampini fieldNc[f] = 1; 18353a544194SStefano Zampini } 18363a544194SStefano Zampini fieldSizes[f] += fpdof; 183737d0c07bSMatthew G Knepley } 183837d0c07bSMatthew G Knepley } 183937d0c07bSMatthew G Knepley } 184037d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 1841785e854fSJed Brown ierr = PetscMalloc1(fieldSizes[f], &fieldIndices[f]);CHKERRQ(ierr); 184237d0c07bSMatthew G Knepley fieldSizes[f] = 0; 184337d0c07bSMatthew G Knepley } 184437d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 184537d0c07bSMatthew G Knepley PetscInt gdof, goff; 184637d0c07bSMatthew G Knepley 184737d0c07bSMatthew G Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 184837d0c07bSMatthew G Knepley if (gdof > 0) { 184937d0c07bSMatthew G Knepley ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr); 185037d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 185137d0c07bSMatthew G Knepley PetscInt fdof, fcdof, fc; 185237d0c07bSMatthew G Knepley 185337d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 185437d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 185537d0c07bSMatthew G Knepley for (fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) { 185637d0c07bSMatthew G Knepley fieldIndices[f][fieldSizes[f]] = goff++; 185737d0c07bSMatthew G Knepley } 185837d0c07bSMatthew G Knepley } 185937d0c07bSMatthew G Knepley } 186037d0c07bSMatthew G Knepley } 18618865f1eaSKarl Rupp if (numFields) *numFields = nF; 186237d0c07bSMatthew G Knepley if (fieldNames) { 1863785e854fSJed Brown ierr = PetscMalloc1(nF, fieldNames);CHKERRQ(ierr); 186437d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 186537d0c07bSMatthew G Knepley const char *fieldName; 186637d0c07bSMatthew G Knepley 186737d0c07bSMatthew G Knepley ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr); 186837d0c07bSMatthew G Knepley ierr = PetscStrallocpy(fieldName, (char**) &(*fieldNames)[f]);CHKERRQ(ierr); 186937d0c07bSMatthew G Knepley } 187037d0c07bSMatthew G Knepley } 187137d0c07bSMatthew G Knepley if (fields) { 1872785e854fSJed Brown ierr = PetscMalloc1(nF, fields);CHKERRQ(ierr); 187337d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 18743a544194SStefano Zampini PetscInt bs, in[2], out[2]; 18753a544194SStefano Zampini 187682f516ccSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr); 18773a544194SStefano Zampini in[0] = -fieldNc[f]; 18783a544194SStefano Zampini in[1] = fieldNc[f]; 1879820f2d46SBarry Smith ierr = MPIU_Allreduce(in, out, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 18803a544194SStefano Zampini bs = (-out[0] == out[1]) ? out[1] : 1; 18813a544194SStefano Zampini ierr = ISSetBlockSize((*fields)[f], bs);CHKERRQ(ierr); 188237d0c07bSMatthew G Knepley } 188337d0c07bSMatthew G Knepley } 18843a544194SStefano Zampini ierr = PetscFree3(fieldSizes,fieldNc,fieldIndices);CHKERRQ(ierr); 18858865f1eaSKarl Rupp } else if (dm->ops->createfieldis) { 18868865f1eaSKarl Rupp ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr); 188769ca1f37SDmitry Karpeev } 18884d343eeaSMatthew G Knepley PetscFunctionReturn(0); 18894d343eeaSMatthew G Knepley } 18904d343eeaSMatthew G Knepley 189116621825SDmitry Karpeev /*@C 189216621825SDmitry Karpeev DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems 189316621825SDmitry Karpeev corresponding to different fields: each IS contains the global indices of the dofs of the 189416621825SDmitry Karpeev corresponding field. The optional list of DMs define the DM for each subproblem. 1895e7c4fc90SDmitry Karpeev Generalizes DMCreateFieldIS(). 1896e7c4fc90SDmitry Karpeev 1897e7c4fc90SDmitry Karpeev Not collective 1898e7c4fc90SDmitry Karpeev 1899e7c4fc90SDmitry Karpeev Input Parameter: 1900e7c4fc90SDmitry Karpeev . dm - the DM object 1901e7c4fc90SDmitry Karpeev 1902e7c4fc90SDmitry Karpeev Output Parameters: 19030298fd71SBarry Smith + len - The number of subproblems in the field decomposition (or NULL if not requested) 19040298fd71SBarry Smith . namelist - The name for each field (or NULL if not requested) 19050298fd71SBarry Smith . islist - The global indices for each field (or NULL if not requested) 19060298fd71SBarry Smith - dmlist - The DMs for each field subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined) 1907e7c4fc90SDmitry Karpeev 1908e7c4fc90SDmitry Karpeev Level: intermediate 1909e7c4fc90SDmitry Karpeev 1910e7c4fc90SDmitry Karpeev Notes: 1911e7c4fc90SDmitry Karpeev The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 1912e7c4fc90SDmitry Karpeev PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(), 1913e7c4fc90SDmitry Karpeev and all of the arrays should be freed with PetscFree(). 1914e7c4fc90SDmitry Karpeev 1915e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 1916e7c4fc90SDmitry Karpeev @*/ 191716621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist) 1918e7c4fc90SDmitry Karpeev { 1919e7c4fc90SDmitry Karpeev PetscErrorCode ierr; 1920e7c4fc90SDmitry Karpeev 1921e7c4fc90SDmitry Karpeev PetscFunctionBegin; 1922e7c4fc90SDmitry Karpeev PetscValidHeaderSpecific(dm,DM_CLASSID,1); 19238865f1eaSKarl Rupp if (len) { 1924534a8f05SLisandro Dalcin PetscValidIntPointer(len,2); 19258865f1eaSKarl Rupp *len = 0; 19268865f1eaSKarl Rupp } 19278865f1eaSKarl Rupp if (namelist) { 19288865f1eaSKarl Rupp PetscValidPointer(namelist,3); 1929ea78f98cSLisandro Dalcin *namelist = NULL; 19308865f1eaSKarl Rupp } 19318865f1eaSKarl Rupp if (islist) { 19328865f1eaSKarl Rupp PetscValidPointer(islist,4); 1933ea78f98cSLisandro Dalcin *islist = NULL; 19348865f1eaSKarl Rupp } 19358865f1eaSKarl Rupp if (dmlist) { 19368865f1eaSKarl Rupp PetscValidPointer(dmlist,5); 1937ea78f98cSLisandro Dalcin *dmlist = NULL; 19388865f1eaSKarl Rupp } 1939f3f0edfdSDmitry Karpeev /* 1940f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 1941f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 1942f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 1943f3f0edfdSDmitry Karpeev */ 1944ce94432eSBarry Smith if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 194516621825SDmitry Karpeev if (!dm->ops->createfielddecomposition) { 1946435a35e8SMatthew G Knepley PetscSection section; 1947435a35e8SMatthew G Knepley PetscInt numFields, f; 1948435a35e8SMatthew G Knepley 194992fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 1950435a35e8SMatthew G Knepley if (section) {ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr);} 1951435a35e8SMatthew G Knepley if (section && numFields && dm->ops->createsubdm) { 1952f25d98f1SMatthew G. Knepley if (len) *len = numFields; 195303dc3394SMatthew G. Knepley if (namelist) {ierr = PetscMalloc1(numFields,namelist);CHKERRQ(ierr);} 195403dc3394SMatthew G. Knepley if (islist) {ierr = PetscMalloc1(numFields,islist);CHKERRQ(ierr);} 195503dc3394SMatthew G. Knepley if (dmlist) {ierr = PetscMalloc1(numFields,dmlist);CHKERRQ(ierr);} 1956435a35e8SMatthew G Knepley for (f = 0; f < numFields; ++f) { 1957435a35e8SMatthew G Knepley const char *fieldName; 1958435a35e8SMatthew G Knepley 195903dc3394SMatthew G. Knepley ierr = DMCreateSubDM(dm, 1, &f, islist ? &(*islist)[f] : NULL, dmlist ? &(*dmlist)[f] : NULL);CHKERRQ(ierr); 196003dc3394SMatthew G. Knepley if (namelist) { 1961435a35e8SMatthew G Knepley ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr); 1962435a35e8SMatthew G Knepley ierr = PetscStrallocpy(fieldName, (char**) &(*namelist)[f]);CHKERRQ(ierr); 1963435a35e8SMatthew G Knepley } 196403dc3394SMatthew G. Knepley } 1965435a35e8SMatthew G Knepley } else { 196669ca1f37SDmitry Karpeev ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr); 1967e7c4fc90SDmitry Karpeev /* By default there are no DMs associated with subproblems. */ 19680298fd71SBarry Smith if (dmlist) *dmlist = NULL; 1969e7c4fc90SDmitry Karpeev } 19708865f1eaSKarl Rupp } else { 197116621825SDmitry Karpeev ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist);CHKERRQ(ierr); 197216621825SDmitry Karpeev } 197316621825SDmitry Karpeev PetscFunctionReturn(0); 197416621825SDmitry Karpeev } 197516621825SDmitry Karpeev 1976564cec59SMatthew G. Knepley /*@ 1977435a35e8SMatthew G Knepley DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in. 1978435a35e8SMatthew G Knepley The fields are defined by DMCreateFieldIS(). 1979435a35e8SMatthew G Knepley 1980435a35e8SMatthew G Knepley Not collective 1981435a35e8SMatthew G Knepley 1982435a35e8SMatthew G Knepley Input Parameters: 19832adcc780SMatthew G. Knepley + dm - The DM object 19842adcc780SMatthew G. Knepley . numFields - The number of fields in this subproblem 19852adcc780SMatthew G. Knepley - fields - The field numbers of the selected fields 1986435a35e8SMatthew G Knepley 1987435a35e8SMatthew G Knepley Output Parameters: 19882adcc780SMatthew G. Knepley + is - The global indices for the subproblem 19892adcc780SMatthew G. Knepley - subdm - The DM for the subproblem 1990435a35e8SMatthew G Knepley 19915d3b26e6SMatthew G. Knepley Note: You need to call DMPlexSetMigrationSF() on the original DM if you want the Global-To-Natural map to be automatically constructed 19925d3b26e6SMatthew G. Knepley 1993435a35e8SMatthew G Knepley Level: intermediate 1994435a35e8SMatthew G Knepley 19955d3b26e6SMatthew G. Knepley .seealso DMPlexSetMigrationSF(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 1996435a35e8SMatthew G Knepley @*/ 199737bc7515SMatthew G. Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 1998435a35e8SMatthew G Knepley { 1999435a35e8SMatthew G Knepley PetscErrorCode ierr; 2000435a35e8SMatthew G Knepley 2001435a35e8SMatthew G Knepley PetscFunctionBegin; 2002435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2003435a35e8SMatthew G Knepley PetscValidPointer(fields,3); 20048865f1eaSKarl Rupp if (is) PetscValidPointer(is,4); 20058865f1eaSKarl Rupp if (subdm) PetscValidPointer(subdm,5); 2006b9d85ea2SLisandro Dalcin if (!dm->ops->createsubdm) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateSubDM",((PetscObject)dm)->type_name); 2007435a35e8SMatthew G Knepley ierr = (*dm->ops->createsubdm)(dm, numFields, fields, is, subdm);CHKERRQ(ierr); 2008435a35e8SMatthew G Knepley PetscFunctionReturn(0); 2009435a35e8SMatthew G Knepley } 2010435a35e8SMatthew G Knepley 20112adcc780SMatthew G. Knepley /*@C 20122adcc780SMatthew G. Knepley DMCreateSuperDM - Returns an arrays of ISes and DM encapsulating a superproblem defined by the DMs passed in. 20132adcc780SMatthew G. Knepley 20142adcc780SMatthew G. Knepley Not collective 20152adcc780SMatthew G. Knepley 2016d8d19677SJose E. Roman Input Parameters: 20172adcc780SMatthew G. Knepley + dms - The DM objects 20182adcc780SMatthew G. Knepley - len - The number of DMs 20192adcc780SMatthew G. Knepley 20202adcc780SMatthew G. Knepley Output Parameters: 2021a42bd24dSMatthew G. Knepley + is - The global indices for the subproblem, or NULL 20222adcc780SMatthew G. Knepley - superdm - The DM for the superproblem 20232adcc780SMatthew G. Knepley 20245d3b26e6SMatthew G. Knepley Note: You need to call DMPlexSetMigrationSF() on the original DM if you want the Global-To-Natural map to be automatically constructed 20255d3b26e6SMatthew G. Knepley 20262adcc780SMatthew G. Knepley Level: intermediate 20272adcc780SMatthew G. Knepley 20285d3b26e6SMatthew G. Knepley .seealso DMPlexSetMigrationSF(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 20292adcc780SMatthew G. Knepley @*/ 20302adcc780SMatthew G. Knepley PetscErrorCode DMCreateSuperDM(DM dms[], PetscInt len, IS **is, DM *superdm) 20312adcc780SMatthew G. Knepley { 20322adcc780SMatthew G. Knepley PetscInt i; 20332adcc780SMatthew G. Knepley PetscErrorCode ierr; 20342adcc780SMatthew G. Knepley 20352adcc780SMatthew G. Knepley PetscFunctionBegin; 20362adcc780SMatthew G. Knepley PetscValidPointer(dms,1); 20372adcc780SMatthew G. Knepley for (i = 0; i < len; ++i) {PetscValidHeaderSpecific(dms[i],DM_CLASSID,1);} 20382adcc780SMatthew G. Knepley if (is) PetscValidPointer(is,3); 2039a42bd24dSMatthew G. Knepley PetscValidPointer(superdm,4); 20402adcc780SMatthew G. Knepley if (len < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of DMs must be nonnegative: %D", len); 20412adcc780SMatthew G. Knepley if (len) { 2042b9d85ea2SLisandro Dalcin DM dm = dms[0]; 2043b9d85ea2SLisandro Dalcin if (!dm->ops->createsuperdm) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateSuperDM",((PetscObject)dm)->type_name); 2044b9d85ea2SLisandro Dalcin ierr = (*dm->ops->createsuperdm)(dms, len, is, superdm);CHKERRQ(ierr); 20452adcc780SMatthew G. Knepley } 20462adcc780SMatthew G. Knepley PetscFunctionReturn(0); 20472adcc780SMatthew G. Knepley } 20482adcc780SMatthew G. Knepley 204916621825SDmitry Karpeev /*@C 20508d4ac253SDmitry Karpeev DMCreateDomainDecomposition - Returns lists of IS objects defining a decomposition of a problem into subproblems 20518d4ac253SDmitry Karpeev corresponding to restrictions to pairs nested subdomains: each IS contains the global 20528d4ac253SDmitry Karpeev indices of the dofs of the corresponding subdomains. The inner subdomains conceptually 20538d4ac253SDmitry Karpeev define a nonoverlapping covering, while outer subdomains can overlap. 20548d4ac253SDmitry Karpeev The optional list of DMs define the DM for each subproblem. 205516621825SDmitry Karpeev 205616621825SDmitry Karpeev Not collective 205716621825SDmitry Karpeev 205816621825SDmitry Karpeev Input Parameter: 205916621825SDmitry Karpeev . dm - the DM object 206016621825SDmitry Karpeev 206116621825SDmitry Karpeev Output Parameters: 20620298fd71SBarry Smith + len - The number of subproblems in the domain decomposition (or NULL if not requested) 20630298fd71SBarry Smith . namelist - The name for each subdomain (or NULL if not requested) 20640298fd71SBarry Smith . innerislist - The global indices for each inner subdomain (or NULL, if not requested) 20650298fd71SBarry Smith . outerislist - The global indices for each outer subdomain (or NULL, if not requested) 20660298fd71SBarry Smith - dmlist - The DMs for each subdomain subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined) 206716621825SDmitry Karpeev 206816621825SDmitry Karpeev Level: intermediate 206916621825SDmitry Karpeev 207016621825SDmitry Karpeev Notes: 207116621825SDmitry Karpeev The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 207216621825SDmitry Karpeev PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(), 207316621825SDmitry Karpeev and all of the arrays should be freed with PetscFree(). 207416621825SDmitry Karpeev 2075245d9833Sprj- .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldDecomposition() 207616621825SDmitry Karpeev @*/ 20778d4ac253SDmitry Karpeev PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist) 207816621825SDmitry Karpeev { 207916621825SDmitry Karpeev PetscErrorCode ierr; 2080be081cd6SPeter Brune DMSubDomainHookLink link; 2081be081cd6SPeter Brune PetscInt i,l; 208216621825SDmitry Karpeev 208316621825SDmitry Karpeev PetscFunctionBegin; 208416621825SDmitry Karpeev PetscValidHeaderSpecific(dm,DM_CLASSID,1); 208514a18fd3SPeter Brune if (len) {PetscValidPointer(len,2); *len = 0;} 20860298fd71SBarry Smith if (namelist) {PetscValidPointer(namelist,3); *namelist = NULL;} 20870298fd71SBarry Smith if (innerislist) {PetscValidPointer(innerislist,4); *innerislist = NULL;} 20880298fd71SBarry Smith if (outerislist) {PetscValidPointer(outerislist,5); *outerislist = NULL;} 20890298fd71SBarry Smith if (dmlist) {PetscValidPointer(dmlist,6); *dmlist = NULL;} 2090f3f0edfdSDmitry Karpeev /* 2091f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 2092f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 2093f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 2094f3f0edfdSDmitry Karpeev */ 2095ce94432eSBarry Smith if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 209616621825SDmitry Karpeev if (dm->ops->createdomaindecomposition) { 2097be081cd6SPeter Brune ierr = (*dm->ops->createdomaindecomposition)(dm,&l,namelist,innerislist,outerislist,dmlist);CHKERRQ(ierr); 209814a18fd3SPeter Brune /* copy subdomain hooks and context over to the subdomain DMs */ 2099f891f5b9SPatrick Sanan if (dmlist && *dmlist) { 2100be081cd6SPeter Brune for (i = 0; i < l; i++) { 2101be081cd6SPeter Brune for (link=dm->subdomainhook; link; link=link->next) { 2102be081cd6SPeter Brune if (link->ddhook) {ierr = (*link->ddhook)(dm,(*dmlist)[i],link->ctx);CHKERRQ(ierr);} 2103be081cd6SPeter Brune } 2104648262bbSPatrick Sanan if (dm->ctx) (*dmlist)[i]->ctx = dm->ctx; 2105e7c4fc90SDmitry Karpeev } 210614a18fd3SPeter Brune } 210714a18fd3SPeter Brune if (len) *len = l; 210814a18fd3SPeter Brune } 2109e30e807fSPeter Brune PetscFunctionReturn(0); 2110e30e807fSPeter Brune } 2111e30e807fSPeter Brune 2112e30e807fSPeter Brune /*@C 2113e30e807fSPeter Brune DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector 2114e30e807fSPeter Brune 2115e30e807fSPeter Brune Not collective 2116e30e807fSPeter Brune 2117e30e807fSPeter Brune Input Parameters: 2118e30e807fSPeter Brune + dm - the DM object 2119e30e807fSPeter Brune . n - the number of subdomain scatters 2120e30e807fSPeter Brune - subdms - the local subdomains 2121e30e807fSPeter Brune 2122e30e807fSPeter Brune Output Parameters: 21236b867d5aSJose E. Roman + iscat - scatter from global vector to nonoverlapping global vector entries on subdomain 2124e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain 2125e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts) 2126e30e807fSPeter Brune 212795452b02SPatrick Sanan Notes: 212895452b02SPatrick Sanan This is an alternative to the iis and ois arguments in DMCreateDomainDecomposition that allow for the solution 2129e30e807fSPeter Brune of general nonlinear problems with overlapping subdomain methods. While merely having index sets that enable subsets 2130e30e807fSPeter Brune of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of 2131e30e807fSPeter Brune solution and residual data. 2132e30e807fSPeter Brune 2133e30e807fSPeter Brune Level: developer 2134e30e807fSPeter Brune 2135e30e807fSPeter Brune .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS() 2136e30e807fSPeter Brune @*/ 2137e30e807fSPeter Brune PetscErrorCode DMCreateDomainDecompositionScatters(DM dm,PetscInt n,DM *subdms,VecScatter **iscat,VecScatter **oscat,VecScatter **gscat) 2138e30e807fSPeter Brune { 2139e30e807fSPeter Brune PetscErrorCode ierr; 2140e30e807fSPeter Brune 2141e30e807fSPeter Brune PetscFunctionBegin; 2142e30e807fSPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2143e30e807fSPeter Brune PetscValidPointer(subdms,3); 2144b9d85ea2SLisandro Dalcin if (!dm->ops->createddscatters) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateDomainDecompositionScatters",((PetscObject)dm)->type_name); 2145e30e807fSPeter Brune ierr = (*dm->ops->createddscatters)(dm,n,subdms,iscat,oscat,gscat);CHKERRQ(ierr); 2146e7c4fc90SDmitry Karpeev PetscFunctionReturn(0); 2147e7c4fc90SDmitry Karpeev } 2148e7c4fc90SDmitry Karpeev 214947c6ae99SBarry Smith /*@ 215047c6ae99SBarry Smith DMRefine - Refines a DM object 215147c6ae99SBarry Smith 2152d083f849SBarry Smith Collective on dm 215347c6ae99SBarry Smith 2154d8d19677SJose E. Roman Input Parameters: 215547c6ae99SBarry Smith + dm - the DM object 215691d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL) 215747c6ae99SBarry Smith 215847c6ae99SBarry Smith Output Parameter: 21590298fd71SBarry Smith . dmf - the refined DM, or NULL 2160ae0a1c52SMatthew G Knepley 2161f27dd7c6SMatthew G. Knepley Options Database Keys: 2162412e9a14SMatthew G. Knepley . -dm_plex_cell_refiner <strategy> - chooses the refinement strategy, e.g. regular, tohex 2163412e9a14SMatthew G. Knepley 21640298fd71SBarry Smith Note: If no refinement was done, the return value is NULL 216547c6ae99SBarry Smith 216647c6ae99SBarry Smith Level: developer 216747c6ae99SBarry Smith 2168e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 216947c6ae99SBarry Smith @*/ 21707087cfbeSBarry Smith PetscErrorCode DMRefine(DM dm,MPI_Comm comm,DM *dmf) 217147c6ae99SBarry Smith { 217247c6ae99SBarry Smith PetscErrorCode ierr; 2173c833c3b5SJed Brown DMRefineHookLink link; 217447c6ae99SBarry Smith 217547c6ae99SBarry Smith PetscFunctionBegin; 2176732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2177b9d85ea2SLisandro Dalcin if (!dm->ops->refine) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMRefine",((PetscObject)dm)->type_name); 21781ac00216SMatthew G. Knepley ierr = PetscLogEventBegin(DM_Refine,dm,0,0,0);CHKERRQ(ierr); 217947c6ae99SBarry Smith ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr); 21804057135bSMatthew G Knepley if (*dmf) { 218143842a1eSJed Brown (*dmf)->ops->creatematrix = dm->ops->creatematrix; 21828865f1eaSKarl Rupp 21838cd211a4SJed Brown ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr); 21848865f1eaSKarl Rupp 2185644e2e5bSBarry Smith (*dmf)->ctx = dm->ctx; 21860598a293SJed Brown (*dmf)->leveldown = dm->leveldown; 2187656b349aSBarry Smith (*dmf)->levelup = dm->levelup + 1; 21888865f1eaSKarl Rupp 2189e4b4b23bSJed Brown ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr); 2190c833c3b5SJed Brown for (link=dm->refinehook; link; link=link->next) { 21918865f1eaSKarl Rupp if (link->refinehook) { 21928865f1eaSKarl Rupp ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr); 21938865f1eaSKarl Rupp } 2194c833c3b5SJed Brown } 2195c833c3b5SJed Brown } 21961ac00216SMatthew G. Knepley ierr = PetscLogEventEnd(DM_Refine,dm,0,0,0);CHKERRQ(ierr); 2197c833c3b5SJed Brown PetscFunctionReturn(0); 2198c833c3b5SJed Brown } 2199c833c3b5SJed Brown 2200bb9467b5SJed Brown /*@C 2201c833c3b5SJed Brown DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid 2202c833c3b5SJed Brown 2203c833c3b5SJed Brown Logically Collective 2204c833c3b5SJed Brown 22054165533cSJose E. Roman Input Parameters: 2206c833c3b5SJed Brown + coarse - nonlinear solver context on which to run a hook when restricting to a coarser level 2207c833c3b5SJed Brown . refinehook - function to run when setting up a coarser level 2208c833c3b5SJed Brown . interphook - function to run to update data on finer levels (once per SNESSolve()) 22090298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2210c833c3b5SJed Brown 2211c833c3b5SJed Brown Calling sequence of refinehook: 2212c833c3b5SJed Brown $ refinehook(DM coarse,DM fine,void *ctx); 2213c833c3b5SJed Brown 2214c833c3b5SJed Brown + coarse - coarse level DM 2215c833c3b5SJed Brown . fine - fine level DM to interpolate problem to 2216c833c3b5SJed Brown - ctx - optional user-defined function context 2217c833c3b5SJed Brown 2218c833c3b5SJed Brown Calling sequence for interphook: 2219c833c3b5SJed Brown $ interphook(DM coarse,Mat interp,DM fine,void *ctx) 2220c833c3b5SJed Brown 2221c833c3b5SJed Brown + coarse - coarse level DM 2222c833c3b5SJed Brown . interp - matrix interpolating a coarse-level solution to the finer grid 2223c833c3b5SJed Brown . fine - fine level DM to update 2224c833c3b5SJed Brown - ctx - optional user-defined function context 2225c833c3b5SJed Brown 2226c833c3b5SJed Brown Level: advanced 2227c833c3b5SJed Brown 2228c833c3b5SJed Brown Notes: 2229c833c3b5SJed Brown This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing 2230c833c3b5SJed Brown 2231c833c3b5SJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 2232c833c3b5SJed Brown 2233bb9467b5SJed Brown This function is currently not available from Fortran. 2234bb9467b5SJed Brown 2235c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 2236c833c3b5SJed Brown @*/ 2237c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx) 2238c833c3b5SJed Brown { 2239c833c3b5SJed Brown PetscErrorCode ierr; 2240c833c3b5SJed Brown DMRefineHookLink link,*p; 2241c833c3b5SJed Brown 2242c833c3b5SJed Brown PetscFunctionBegin; 2243c833c3b5SJed Brown PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 22443d8e3701SJed Brown for (p=&coarse->refinehook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */ 22453d8e3701SJed Brown if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) PetscFunctionReturn(0); 22463d8e3701SJed Brown } 224795dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 2248c833c3b5SJed Brown link->refinehook = refinehook; 2249c833c3b5SJed Brown link->interphook = interphook; 2250c833c3b5SJed Brown link->ctx = ctx; 22510298fd71SBarry Smith link->next = NULL; 2252c833c3b5SJed Brown *p = link; 2253c833c3b5SJed Brown PetscFunctionReturn(0); 2254c833c3b5SJed Brown } 2255c833c3b5SJed Brown 22563d8e3701SJed Brown /*@C 22573d8e3701SJed Brown DMRefineHookRemove - remove a callback from the list of hooks to be run when interpolating a nonlinear problem to a finer grid 22583d8e3701SJed Brown 22593d8e3701SJed Brown Logically Collective 22603d8e3701SJed Brown 22614165533cSJose E. Roman Input Parameters: 22623d8e3701SJed Brown + coarse - nonlinear solver context on which to run a hook when restricting to a coarser level 22633d8e3701SJed Brown . refinehook - function to run when setting up a coarser level 22643d8e3701SJed Brown . interphook - function to run to update data on finer levels (once per SNESSolve()) 22653d8e3701SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 22663d8e3701SJed Brown 22673d8e3701SJed Brown Level: advanced 22683d8e3701SJed Brown 22693d8e3701SJed Brown Notes: 22703d8e3701SJed Brown This function does nothing if the hook is not in the list. 22713d8e3701SJed Brown 22723d8e3701SJed Brown This function is currently not available from Fortran. 22733d8e3701SJed Brown 22743d8e3701SJed Brown .seealso: DMCoarsenHookRemove(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 22753d8e3701SJed Brown @*/ 22763d8e3701SJed Brown PetscErrorCode DMRefineHookRemove(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx) 22773d8e3701SJed Brown { 22783d8e3701SJed Brown PetscErrorCode ierr; 22793d8e3701SJed Brown DMRefineHookLink link,*p; 22803d8e3701SJed Brown 22813d8e3701SJed Brown PetscFunctionBegin; 22823d8e3701SJed Brown PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 22833d8e3701SJed Brown for (p=&coarse->refinehook; *p; p=&(*p)->next) { /* Search the list of current hooks */ 22843d8e3701SJed Brown if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) { 22853d8e3701SJed Brown link = *p; 22863d8e3701SJed Brown *p = link->next; 22873d8e3701SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 22883d8e3701SJed Brown break; 22893d8e3701SJed Brown } 22903d8e3701SJed Brown } 22913d8e3701SJed Brown PetscFunctionReturn(0); 22923d8e3701SJed Brown } 22933d8e3701SJed Brown 2294c833c3b5SJed Brown /*@ 2295c833c3b5SJed Brown DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd() 2296c833c3b5SJed Brown 2297c833c3b5SJed Brown Collective if any hooks are 2298c833c3b5SJed Brown 22994165533cSJose E. Roman Input Parameters: 2300c833c3b5SJed Brown + coarse - coarser DM to use as a base 2301e91eccc2SStefano Zampini . interp - interpolation matrix, apply using MatInterpolate() 2302c833c3b5SJed Brown - fine - finer DM to update 2303c833c3b5SJed Brown 2304c833c3b5SJed Brown Level: developer 2305c833c3b5SJed Brown 2306c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate() 2307c833c3b5SJed Brown @*/ 2308c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine) 2309c833c3b5SJed Brown { 2310c833c3b5SJed Brown PetscErrorCode ierr; 2311c833c3b5SJed Brown DMRefineHookLink link; 2312c833c3b5SJed Brown 2313c833c3b5SJed Brown PetscFunctionBegin; 2314c833c3b5SJed Brown for (link=fine->refinehook; link; link=link->next) { 23158865f1eaSKarl Rupp if (link->interphook) { 23168865f1eaSKarl Rupp ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr); 23178865f1eaSKarl Rupp } 23184057135bSMatthew G Knepley } 231947c6ae99SBarry Smith PetscFunctionReturn(0); 232047c6ae99SBarry Smith } 232147c6ae99SBarry Smith 2322eb3f98d2SBarry Smith /*@ 23231f3379b2SToby Isaac DMInterpolateSolution - Interpolates a solution from a coarse mesh to a fine mesh. 23241f3379b2SToby Isaac 23251f3379b2SToby Isaac Collective on DM 23261f3379b2SToby Isaac 23274165533cSJose E. Roman Input Parameters: 23281f3379b2SToby Isaac + coarse - coarse DM 23291f3379b2SToby Isaac . fine - fine DM 23301f3379b2SToby Isaac . interp - (optional) the matrix computed by DMCreateInterpolation(). Implementations may not need this, but if it 23311f3379b2SToby Isaac is available it can avoid some recomputation. If it is provided, MatInterpolate() will be used if 23321f3379b2SToby Isaac the coarse DM does not have a specialized implementation. 23331f3379b2SToby Isaac - coarseSol - solution on the coarse mesh 23341f3379b2SToby Isaac 23354165533cSJose E. Roman Output Parameter: 23361f3379b2SToby Isaac . fineSol - the interpolation of coarseSol to the fine mesh 23371f3379b2SToby Isaac 23381f3379b2SToby Isaac Level: developer 23391f3379b2SToby Isaac 23401f3379b2SToby Isaac Note: This function exists because the interpolation of a solution vector between meshes is not always a linear 23411f3379b2SToby Isaac map. For example, if a boundary value problem has an inhomogeneous Dirichlet boundary condition that is compressed 23421f3379b2SToby Isaac out of the solution vector. Or if interpolation is inherently a nonlinear operation, such as a method using 23431f3379b2SToby Isaac slope-limiting reconstruction. 23441f3379b2SToby Isaac 23451f3379b2SToby Isaac .seealso DMInterpolate(), DMCreateInterpolation() 23461f3379b2SToby Isaac @*/ 23471f3379b2SToby Isaac PetscErrorCode DMInterpolateSolution(DM coarse, DM fine, Mat interp, Vec coarseSol, Vec fineSol) 23481f3379b2SToby Isaac { 23491f3379b2SToby Isaac PetscErrorCode (*interpsol)(DM,DM,Mat,Vec,Vec) = NULL; 23501f3379b2SToby Isaac PetscErrorCode ierr; 23511f3379b2SToby Isaac 23521f3379b2SToby Isaac PetscFunctionBegin; 23531f3379b2SToby Isaac PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 23541f3379b2SToby Isaac if (interp) PetscValidHeaderSpecific(interp,MAT_CLASSID,3); 23551f3379b2SToby Isaac PetscValidHeaderSpecific(coarseSol,VEC_CLASSID,4); 23561f3379b2SToby Isaac PetscValidHeaderSpecific(fineSol,VEC_CLASSID,5); 23571f3379b2SToby Isaac 23581f3379b2SToby Isaac ierr = PetscObjectQueryFunction((PetscObject)coarse,"DMInterpolateSolution_C", &interpsol);CHKERRQ(ierr); 23591f3379b2SToby Isaac if (interpsol) { 23601f3379b2SToby Isaac ierr = (*interpsol)(coarse, fine, interp, coarseSol, fineSol);CHKERRQ(ierr); 23611f3379b2SToby Isaac } else if (interp) { 23621f3379b2SToby Isaac ierr = MatInterpolate(interp, coarseSol, fineSol);CHKERRQ(ierr); 23631f3379b2SToby Isaac } else SETERRQ1(PetscObjectComm((PetscObject)coarse), PETSC_ERR_SUP, "DM %s does not implement DMInterpolateSolution()", ((PetscObject)coarse)->type_name); 23641f3379b2SToby Isaac PetscFunctionReturn(0); 23651f3379b2SToby Isaac } 23661f3379b2SToby Isaac 23671f3379b2SToby Isaac /*@ 2368aed49f88SRichard Tran Mills DMGetRefineLevel - Gets the number of refinements that have generated this DM. 2369eb3f98d2SBarry Smith 2370eb3f98d2SBarry Smith Not Collective 2371eb3f98d2SBarry Smith 2372eb3f98d2SBarry Smith Input Parameter: 2373eb3f98d2SBarry Smith . dm - the DM object 2374eb3f98d2SBarry Smith 2375eb3f98d2SBarry Smith Output Parameter: 2376eb3f98d2SBarry Smith . level - number of refinements 2377eb3f98d2SBarry Smith 2378eb3f98d2SBarry Smith Level: developer 2379eb3f98d2SBarry Smith 23806a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 2381eb3f98d2SBarry Smith 2382eb3f98d2SBarry Smith @*/ 2383eb3f98d2SBarry Smith PetscErrorCode DMGetRefineLevel(DM dm,PetscInt *level) 2384eb3f98d2SBarry Smith { 2385eb3f98d2SBarry Smith PetscFunctionBegin; 2386eb3f98d2SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2387eb3f98d2SBarry Smith *level = dm->levelup; 2388eb3f98d2SBarry Smith PetscFunctionReturn(0); 2389eb3f98d2SBarry Smith } 2390eb3f98d2SBarry Smith 2391fef3a512SBarry Smith /*@ 2392aed49f88SRichard Tran Mills DMSetRefineLevel - Sets the number of refinements that have generated this DM. 2393fef3a512SBarry Smith 2394fef3a512SBarry Smith Not Collective 2395fef3a512SBarry Smith 2396d8d19677SJose E. Roman Input Parameters: 2397fef3a512SBarry Smith + dm - the DM object 2398fef3a512SBarry Smith - level - number of refinements 2399fef3a512SBarry Smith 2400fef3a512SBarry Smith Level: advanced 2401fef3a512SBarry Smith 240295452b02SPatrick Sanan Notes: 240395452b02SPatrick Sanan This value is used by PCMG to determine how many multigrid levels to use 2404fef3a512SBarry Smith 2405fef3a512SBarry Smith .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 2406fef3a512SBarry Smith 2407fef3a512SBarry Smith @*/ 2408fef3a512SBarry Smith PetscErrorCode DMSetRefineLevel(DM dm,PetscInt level) 2409fef3a512SBarry Smith { 2410fef3a512SBarry Smith PetscFunctionBegin; 2411fef3a512SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2412fef3a512SBarry Smith dm->levelup = level; 2413fef3a512SBarry Smith PetscFunctionReturn(0); 2414fef3a512SBarry Smith } 2415fef3a512SBarry Smith 2416d410b0cfSMatthew G. Knepley /*@ 2417d410b0cfSMatthew G. Knepley DMExtrude - Extrude a DM object from a surface 2418d410b0cfSMatthew G. Knepley 2419d410b0cfSMatthew G. Knepley Collective on dm 2420d410b0cfSMatthew G. Knepley 2421d410b0cfSMatthew G. Knepley Input Parameter: 2422d410b0cfSMatthew G. Knepley + dm - the DM object 2423d410b0cfSMatthew G. Knepley - layers - the number of extruded cell layers 2424d410b0cfSMatthew G. Knepley 2425d410b0cfSMatthew G. Knepley Output Parameter: 2426d410b0cfSMatthew G. Knepley . dme - the extruded DM, or NULL 2427d410b0cfSMatthew G. Knepley 2428d410b0cfSMatthew G. Knepley Note: If no extrusion was done, the return value is NULL 2429d410b0cfSMatthew G. Knepley 2430d410b0cfSMatthew G. Knepley Level: developer 2431d410b0cfSMatthew G. Knepley 2432d410b0cfSMatthew G. Knepley .seealso DMRefine(), DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector() 2433d410b0cfSMatthew G. Knepley @*/ 2434d410b0cfSMatthew G. Knepley PetscErrorCode DMExtrude(DM dm, PetscInt layers, DM *dme) 2435d410b0cfSMatthew G. Knepley { 2436d410b0cfSMatthew G. Knepley PetscErrorCode ierr; 2437d410b0cfSMatthew G. Knepley 2438d410b0cfSMatthew G. Knepley PetscFunctionBegin; 2439d410b0cfSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2440d410b0cfSMatthew G. Knepley if (!dm->ops->extrude) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "DM type %s does not implement DMExtrude", ((PetscObject) dm)->type_name); 2441d410b0cfSMatthew G. Knepley ierr = (*dm->ops->extrude)(dm, layers, dme);CHKERRQ(ierr); 2442d410b0cfSMatthew G. Knepley if (*dme) { 2443d410b0cfSMatthew G. Knepley (*dme)->ops->creatematrix = dm->ops->creatematrix; 2444d410b0cfSMatthew G. Knepley ierr = PetscObjectCopyFortranFunctionPointers((PetscObject) dm, (PetscObject) *dme);CHKERRQ(ierr); 2445d410b0cfSMatthew G. Knepley (*dme)->ctx = dm->ctx; 2446d410b0cfSMatthew G. Knepley ierr = DMSetMatType(*dme, dm->mattype);CHKERRQ(ierr); 2447d410b0cfSMatthew G. Knepley } 2448d410b0cfSMatthew G. Knepley PetscFunctionReturn(0); 2449d410b0cfSMatthew G. Knepley } 2450d410b0cfSMatthew G. Knepley 2451ca3d3a14SMatthew G. Knepley PetscErrorCode DMGetBasisTransformDM_Internal(DM dm, DM *tdm) 2452ca3d3a14SMatthew G. Knepley { 2453ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2454ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2455ca3d3a14SMatthew G. Knepley PetscValidPointer(tdm, 2); 2456ca3d3a14SMatthew G. Knepley *tdm = dm->transformDM; 2457ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2458ca3d3a14SMatthew G. Knepley } 2459ca3d3a14SMatthew G. Knepley 2460ca3d3a14SMatthew G. Knepley PetscErrorCode DMGetBasisTransformVec_Internal(DM dm, Vec *tv) 2461ca3d3a14SMatthew G. Knepley { 2462ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2463ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2464ca3d3a14SMatthew G. Knepley PetscValidPointer(tv, 2); 2465ca3d3a14SMatthew G. Knepley *tv = dm->transform; 2466ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2467ca3d3a14SMatthew G. Knepley } 2468ca3d3a14SMatthew G. Knepley 2469ca3d3a14SMatthew G. Knepley /*@ 2470c0f8e1fdSMatthew G. Knepley DMHasBasisTransform - Whether we employ a basis transformation from functions in global vectors to functions in local vectors 2471ca3d3a14SMatthew G. Knepley 2472ca3d3a14SMatthew G. Knepley Input Parameter: 2473ca3d3a14SMatthew G. Knepley . dm - The DM 2474ca3d3a14SMatthew G. Knepley 2475ca3d3a14SMatthew G. Knepley Output Parameter: 2476ca3d3a14SMatthew G. Knepley . flg - PETSC_TRUE if a basis transformation should be done 2477ca3d3a14SMatthew G. Knepley 2478ca3d3a14SMatthew G. Knepley Level: developer 2479ca3d3a14SMatthew G. Knepley 2480436bc73aSJed Brown .seealso: DMPlexGlobalToLocalBasis(), DMPlexLocalToGlobalBasis(), DMPlexCreateBasisRotation() 2481ca3d3a14SMatthew G. Knepley @*/ 2482ca3d3a14SMatthew G. Knepley PetscErrorCode DMHasBasisTransform(DM dm, PetscBool *flg) 2483ca3d3a14SMatthew G. Knepley { 2484ca3d3a14SMatthew G. Knepley Vec tv; 2485ca3d3a14SMatthew G. Knepley PetscErrorCode ierr; 2486ca3d3a14SMatthew G. Knepley 2487ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2488ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2489534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 2490ca3d3a14SMatthew G. Knepley ierr = DMGetBasisTransformVec_Internal(dm, &tv);CHKERRQ(ierr); 2491ca3d3a14SMatthew G. Knepley *flg = tv ? PETSC_TRUE : PETSC_FALSE; 2492ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2493ca3d3a14SMatthew G. Knepley } 2494ca3d3a14SMatthew G. Knepley 2495ca3d3a14SMatthew G. Knepley PetscErrorCode DMConstructBasisTransform_Internal(DM dm) 2496ca3d3a14SMatthew G. Knepley { 2497ca3d3a14SMatthew G. Knepley PetscSection s, ts; 2498ca3d3a14SMatthew G. Knepley PetscScalar *ta; 2499ca3d3a14SMatthew G. Knepley PetscInt cdim, pStart, pEnd, p, Nf, f, Nc, dof; 2500ca3d3a14SMatthew G. Knepley PetscErrorCode ierr; 2501ca3d3a14SMatthew G. Knepley 2502ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2503ca3d3a14SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 250492fd8e1eSJed Brown ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr); 2505ca3d3a14SMatthew G. Knepley ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 2506ca3d3a14SMatthew G. Knepley ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr); 2507ca3d3a14SMatthew G. Knepley ierr = DMClone(dm, &dm->transformDM);CHKERRQ(ierr); 250892fd8e1eSJed Brown ierr = DMGetLocalSection(dm->transformDM, &ts);CHKERRQ(ierr); 2509ca3d3a14SMatthew G. Knepley ierr = PetscSectionSetNumFields(ts, Nf);CHKERRQ(ierr); 2510ca3d3a14SMatthew G. Knepley ierr = PetscSectionSetChart(ts, pStart, pEnd);CHKERRQ(ierr); 2511ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2512ca3d3a14SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(s, f, &Nc);CHKERRQ(ierr); 2513ca3d3a14SMatthew G. Knepley /* We could start to label fields by their transformation properties */ 2514ca3d3a14SMatthew G. Knepley if (Nc != cdim) continue; 2515ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2516ca3d3a14SMatthew G. Knepley ierr = PetscSectionGetFieldDof(s, p, f, &dof);CHKERRQ(ierr); 2517ca3d3a14SMatthew G. Knepley if (!dof) continue; 2518ca3d3a14SMatthew G. Knepley ierr = PetscSectionSetFieldDof(ts, p, f, PetscSqr(cdim));CHKERRQ(ierr); 2519ca3d3a14SMatthew G. Knepley ierr = PetscSectionAddDof(ts, p, PetscSqr(cdim));CHKERRQ(ierr); 2520ca3d3a14SMatthew G. Knepley } 2521ca3d3a14SMatthew G. Knepley } 2522ca3d3a14SMatthew G. Knepley ierr = PetscSectionSetUp(ts);CHKERRQ(ierr); 2523ca3d3a14SMatthew G. Knepley ierr = DMCreateLocalVector(dm->transformDM, &dm->transform);CHKERRQ(ierr); 2524ca3d3a14SMatthew G. Knepley ierr = VecGetArray(dm->transform, &ta);CHKERRQ(ierr); 2525ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2526ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2527ca3d3a14SMatthew G. Knepley ierr = PetscSectionGetFieldDof(ts, p, f, &dof);CHKERRQ(ierr); 2528ca3d3a14SMatthew G. Knepley if (dof) { 2529ca3d3a14SMatthew G. Knepley PetscReal x[3] = {0.0, 0.0, 0.0}; 2530ca3d3a14SMatthew G. Knepley PetscScalar *tva; 2531ca3d3a14SMatthew G. Knepley const PetscScalar *A; 2532ca3d3a14SMatthew G. Knepley 2533ca3d3a14SMatthew G. Knepley /* TODO Get quadrature point for this dual basis vector for coordinate */ 2534ca3d3a14SMatthew G. Knepley ierr = (*dm->transformGetMatrix)(dm, x, PETSC_TRUE, &A, dm->transformCtx);CHKERRQ(ierr); 2535ca3d3a14SMatthew G. Knepley ierr = DMPlexPointLocalFieldRef(dm->transformDM, p, f, ta, (void *) &tva);CHKERRQ(ierr); 2536580bdb30SBarry Smith ierr = PetscArraycpy(tva, A, PetscSqr(cdim));CHKERRQ(ierr); 2537ca3d3a14SMatthew G. Knepley } 2538ca3d3a14SMatthew G. Knepley } 2539ca3d3a14SMatthew G. Knepley } 2540ca3d3a14SMatthew G. Knepley ierr = VecRestoreArray(dm->transform, &ta);CHKERRQ(ierr); 2541ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2542ca3d3a14SMatthew G. Knepley } 2543ca3d3a14SMatthew G. Knepley 2544ca3d3a14SMatthew G. Knepley PetscErrorCode DMCopyTransform(DM dm, DM newdm) 2545ca3d3a14SMatthew G. Knepley { 2546ca3d3a14SMatthew G. Knepley PetscErrorCode ierr; 2547ca3d3a14SMatthew G. Knepley 2548ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2549ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2550ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(newdm, DM_CLASSID, 2); 2551ca3d3a14SMatthew G. Knepley newdm->transformCtx = dm->transformCtx; 2552ca3d3a14SMatthew G. Knepley newdm->transformSetUp = dm->transformSetUp; 2553ca3d3a14SMatthew G. Knepley newdm->transformDestroy = NULL; 2554ca3d3a14SMatthew G. Knepley newdm->transformGetMatrix = dm->transformGetMatrix; 2555ca3d3a14SMatthew G. Knepley if (newdm->transformSetUp) {ierr = DMConstructBasisTransform_Internal(newdm);CHKERRQ(ierr);} 2556ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2557ca3d3a14SMatthew G. Knepley } 2558ca3d3a14SMatthew G. Knepley 2559bb9467b5SJed Brown /*@C 2560baf369e7SPeter Brune DMGlobalToLocalHookAdd - adds a callback to be run when global to local is called 2561baf369e7SPeter Brune 2562baf369e7SPeter Brune Logically Collective 2563baf369e7SPeter Brune 25644165533cSJose E. Roman Input Parameters: 2565baf369e7SPeter Brune + dm - the DM 2566baf369e7SPeter Brune . beginhook - function to run at the beginning of DMGlobalToLocalBegin() 2567baf369e7SPeter Brune . endhook - function to run after DMGlobalToLocalEnd() has completed 25680298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2569baf369e7SPeter Brune 2570baf369e7SPeter Brune Calling sequence for beginhook: 2571baf369e7SPeter Brune $ beginhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx) 2572baf369e7SPeter Brune 2573baf369e7SPeter Brune + dm - global DM 2574baf369e7SPeter Brune . g - global vector 2575baf369e7SPeter Brune . mode - mode 2576baf369e7SPeter Brune . l - local vector 2577baf369e7SPeter Brune - ctx - optional user-defined function context 2578baf369e7SPeter Brune 2579baf369e7SPeter Brune Calling sequence for endhook: 2580ec4806b8SPeter Brune $ endhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx) 2581baf369e7SPeter Brune 2582baf369e7SPeter Brune + global - global DM 2583baf369e7SPeter Brune - ctx - optional user-defined function context 2584baf369e7SPeter Brune 2585baf369e7SPeter Brune Level: advanced 2586baf369e7SPeter Brune 2587baf369e7SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 2588baf369e7SPeter Brune @*/ 2589baf369e7SPeter Brune PetscErrorCode DMGlobalToLocalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx) 2590baf369e7SPeter Brune { 2591baf369e7SPeter Brune PetscErrorCode ierr; 2592baf369e7SPeter Brune DMGlobalToLocalHookLink link,*p; 2593baf369e7SPeter Brune 2594baf369e7SPeter Brune PetscFunctionBegin; 2595baf369e7SPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2596baf369e7SPeter Brune for (p=&dm->gtolhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 259795dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 2598baf369e7SPeter Brune link->beginhook = beginhook; 2599baf369e7SPeter Brune link->endhook = endhook; 2600baf369e7SPeter Brune link->ctx = ctx; 26010298fd71SBarry Smith link->next = NULL; 2602baf369e7SPeter Brune *p = link; 2603baf369e7SPeter Brune PetscFunctionReturn(0); 2604baf369e7SPeter Brune } 2605baf369e7SPeter Brune 26064c274da1SToby Isaac static PetscErrorCode DMGlobalToLocalHook_Constraints(DM dm, Vec g, InsertMode mode, Vec l, void *ctx) 26074c274da1SToby Isaac { 26084c274da1SToby Isaac Mat cMat; 26094c274da1SToby Isaac Vec cVec; 26104c274da1SToby Isaac PetscSection section, cSec; 26114c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 26124c274da1SToby Isaac PetscErrorCode ierr; 26134c274da1SToby Isaac 26144c274da1SToby Isaac PetscFunctionBegin; 26154c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 26164c274da1SToby Isaac ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr); 26174c274da1SToby Isaac if (cMat && (mode == INSERT_VALUES || mode == INSERT_ALL_VALUES || mode == INSERT_BC_VALUES)) { 26185db9a05bSToby Isaac PetscInt nRows; 26195db9a05bSToby Isaac 26205db9a05bSToby Isaac ierr = MatGetSize(cMat,&nRows,NULL);CHKERRQ(ierr); 26215db9a05bSToby Isaac if (nRows <= 0) PetscFunctionReturn(0); 262292fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 26237711e48fSToby Isaac ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr); 26244c274da1SToby Isaac ierr = MatMult(cMat,l,cVec);CHKERRQ(ierr); 26254c274da1SToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 26264c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 26274c274da1SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 26284c274da1SToby Isaac if (dof) { 26294c274da1SToby Isaac PetscScalar *vals; 26304c274da1SToby Isaac ierr = VecGetValuesSection(cVec,cSec,p,&vals);CHKERRQ(ierr); 26314c274da1SToby Isaac ierr = VecSetValuesSection(l,section,p,vals,INSERT_ALL_VALUES);CHKERRQ(ierr); 26324c274da1SToby Isaac } 26334c274da1SToby Isaac } 26344c274da1SToby Isaac ierr = VecDestroy(&cVec);CHKERRQ(ierr); 26354c274da1SToby Isaac } 26364c274da1SToby Isaac PetscFunctionReturn(0); 26374c274da1SToby Isaac } 26384c274da1SToby Isaac 263947c6ae99SBarry Smith /*@ 264001729b5cSPatrick Sanan DMGlobalToLocal - update local vectors from global vector 264101729b5cSPatrick Sanan 2642d083f849SBarry Smith Neighbor-wise Collective on dm 264301729b5cSPatrick Sanan 264401729b5cSPatrick Sanan Input Parameters: 264501729b5cSPatrick Sanan + dm - the DM object 264601729b5cSPatrick Sanan . g - the global vector 264701729b5cSPatrick Sanan . mode - INSERT_VALUES or ADD_VALUES 264801729b5cSPatrick Sanan - l - the local vector 264901729b5cSPatrick Sanan 265001729b5cSPatrick Sanan Notes: 265101729b5cSPatrick Sanan The communication involved in this update can be overlapped with computation by using 265201729b5cSPatrick Sanan DMGlobalToLocalBegin() and DMGlobalToLocalEnd(). 265301729b5cSPatrick Sanan 265401729b5cSPatrick Sanan Level: beginner 265501729b5cSPatrick Sanan 265601729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd() 265701729b5cSPatrick Sanan 265801729b5cSPatrick Sanan @*/ 265901729b5cSPatrick Sanan PetscErrorCode DMGlobalToLocal(DM dm,Vec g,InsertMode mode,Vec l) 266001729b5cSPatrick Sanan { 266101729b5cSPatrick Sanan PetscErrorCode ierr; 266201729b5cSPatrick Sanan 266301729b5cSPatrick Sanan PetscFunctionBegin; 266401729b5cSPatrick Sanan ierr = DMGlobalToLocalBegin(dm,g,mode,l);CHKERRQ(ierr); 266501729b5cSPatrick Sanan ierr = DMGlobalToLocalEnd(dm,g,mode,l);CHKERRQ(ierr); 266601729b5cSPatrick Sanan PetscFunctionReturn(0); 266701729b5cSPatrick Sanan } 266801729b5cSPatrick Sanan 266901729b5cSPatrick Sanan /*@ 267047c6ae99SBarry Smith DMGlobalToLocalBegin - Begins updating local vectors from global vector 267147c6ae99SBarry Smith 2672d083f849SBarry Smith Neighbor-wise Collective on dm 267347c6ae99SBarry Smith 267447c6ae99SBarry Smith Input Parameters: 267547c6ae99SBarry Smith + dm - the DM object 267647c6ae99SBarry Smith . g - the global vector 267747c6ae99SBarry Smith . mode - INSERT_VALUES or ADD_VALUES 267847c6ae99SBarry Smith - l - the local vector 267947c6ae99SBarry Smith 268001729b5cSPatrick Sanan Level: intermediate 268147c6ae99SBarry Smith 268201729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd() 268347c6ae99SBarry Smith 268447c6ae99SBarry Smith @*/ 26857087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l) 268647c6ae99SBarry Smith { 26877128ae9fSMatthew G Knepley PetscSF sf; 268847c6ae99SBarry Smith PetscErrorCode ierr; 2689baf369e7SPeter Brune DMGlobalToLocalHookLink link; 269047c6ae99SBarry Smith 269147c6ae99SBarry Smith PetscFunctionBegin; 2692171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2693baf369e7SPeter Brune for (link=dm->gtolhook; link; link=link->next) { 26948865f1eaSKarl Rupp if (link->beginhook) { 26958865f1eaSKarl Rupp ierr = (*link->beginhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr); 26968865f1eaSKarl Rupp } 2697baf369e7SPeter Brune } 26981bb6d2a8SBarry Smith ierr = DMGetSectionSF(dm, &sf);CHKERRQ(ierr); 26997128ae9fSMatthew G Knepley if (sf) { 2700ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2701ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2702d0295fc0SJunchao Zhang PetscMemType lmtype,gmtype; 27037128ae9fSMatthew G Knepley 270482f516ccSBarry Smith if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 2705a256111fSJunchao Zhang ierr = VecGetArrayAndMemType(l, &lArray, &lmtype);CHKERRQ(ierr); 2706a256111fSJunchao Zhang ierr = VecGetArrayReadAndMemType(g, &gArray, &gmtype);CHKERRQ(ierr); 2707ad227feaSJunchao Zhang ierr = PetscSFBcastWithMemTypeBegin(sf, MPIU_SCALAR, gmtype, gArray, lmtype, lArray, MPI_REPLACE);CHKERRQ(ierr); 2708a256111fSJunchao Zhang ierr = VecRestoreArrayAndMemType(l, &lArray);CHKERRQ(ierr); 2709a256111fSJunchao Zhang ierr = VecRestoreArrayReadAndMemType(g, &gArray);CHKERRQ(ierr); 27107128ae9fSMatthew G Knepley } else { 271133907cc2SStefano Zampini if (!dm->ops->globaltolocalbegin) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMGlobalToLocalBegin() for type %s",((PetscObject)dm)->type_name); 2712843c4018SMatthew G Knepley ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 27137128ae9fSMatthew G Knepley } 271447c6ae99SBarry Smith PetscFunctionReturn(0); 271547c6ae99SBarry Smith } 271647c6ae99SBarry Smith 271747c6ae99SBarry Smith /*@ 271847c6ae99SBarry Smith DMGlobalToLocalEnd - Ends updating local vectors from global vector 271947c6ae99SBarry Smith 2720d083f849SBarry Smith Neighbor-wise Collective on dm 272147c6ae99SBarry Smith 272247c6ae99SBarry Smith Input Parameters: 272347c6ae99SBarry Smith + dm - the DM object 272447c6ae99SBarry Smith . g - the global vector 272547c6ae99SBarry Smith . mode - INSERT_VALUES or ADD_VALUES 272647c6ae99SBarry Smith - l - the local vector 272747c6ae99SBarry Smith 272801729b5cSPatrick Sanan Level: intermediate 272947c6ae99SBarry Smith 273001729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd() 273147c6ae99SBarry Smith 273247c6ae99SBarry Smith @*/ 27337087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l) 273447c6ae99SBarry Smith { 27357128ae9fSMatthew G Knepley PetscSF sf; 273647c6ae99SBarry Smith PetscErrorCode ierr; 2737ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2738ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2739ca3d3a14SMatthew G. Knepley PetscBool transform; 2740baf369e7SPeter Brune DMGlobalToLocalHookLink link; 2741d0295fc0SJunchao Zhang PetscMemType lmtype,gmtype; 274247c6ae99SBarry Smith 274347c6ae99SBarry Smith PetscFunctionBegin; 2744171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 27451bb6d2a8SBarry Smith ierr = DMGetSectionSF(dm, &sf);CHKERRQ(ierr); 2746ca3d3a14SMatthew G. Knepley ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr); 27477128ae9fSMatthew G Knepley if (sf) { 274882f516ccSBarry Smith if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 27497128ae9fSMatthew G Knepley 2750a256111fSJunchao Zhang ierr = VecGetArrayAndMemType(l, &lArray, &lmtype);CHKERRQ(ierr); 2751a256111fSJunchao Zhang ierr = VecGetArrayReadAndMemType(g, &gArray, &gmtype);CHKERRQ(ierr); 2752ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray,MPI_REPLACE);CHKERRQ(ierr); 2753a256111fSJunchao Zhang ierr = VecRestoreArrayAndMemType(l, &lArray);CHKERRQ(ierr); 2754a256111fSJunchao Zhang ierr = VecRestoreArrayReadAndMemType(g, &gArray);CHKERRQ(ierr); 2755ca3d3a14SMatthew G. Knepley if (transform) {ierr = DMPlexGlobalToLocalBasis(dm, l);CHKERRQ(ierr);} 27567128ae9fSMatthew G Knepley } else { 275733907cc2SStefano Zampini if (!dm->ops->globaltolocalend) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMGlobalToLocalEnd() for type %s",((PetscObject)dm)->type_name); 2758843c4018SMatthew G Knepley ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 27597128ae9fSMatthew G Knepley } 27604c274da1SToby Isaac ierr = DMGlobalToLocalHook_Constraints(dm,g,mode,l,NULL);CHKERRQ(ierr); 2761baf369e7SPeter Brune for (link=dm->gtolhook; link; link=link->next) { 2762baf369e7SPeter Brune if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);} 2763baf369e7SPeter Brune } 276447c6ae99SBarry Smith PetscFunctionReturn(0); 276547c6ae99SBarry Smith } 276647c6ae99SBarry Smith 2767d4d07f1eSToby Isaac /*@C 2768d4d07f1eSToby Isaac DMLocalToGlobalHookAdd - adds a callback to be run when a local to global is called 2769d4d07f1eSToby Isaac 2770d4d07f1eSToby Isaac Logically Collective 2771d4d07f1eSToby Isaac 27724165533cSJose E. Roman Input Parameters: 2773d4d07f1eSToby Isaac + dm - the DM 2774d4d07f1eSToby Isaac . beginhook - function to run at the beginning of DMLocalToGlobalBegin() 2775d4d07f1eSToby Isaac . endhook - function to run after DMLocalToGlobalEnd() has completed 2776d4d07f1eSToby Isaac - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2777d4d07f1eSToby Isaac 2778d4d07f1eSToby Isaac Calling sequence for beginhook: 2779d4d07f1eSToby Isaac $ beginhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx) 2780d4d07f1eSToby Isaac 2781d4d07f1eSToby Isaac + dm - global DM 2782d4d07f1eSToby Isaac . l - local vector 2783d4d07f1eSToby Isaac . mode - mode 2784d4d07f1eSToby Isaac . g - global vector 2785d4d07f1eSToby Isaac - ctx - optional user-defined function context 2786d4d07f1eSToby Isaac 2787d4d07f1eSToby Isaac Calling sequence for endhook: 2788d4d07f1eSToby Isaac $ endhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx) 2789d4d07f1eSToby Isaac 2790d4d07f1eSToby Isaac + global - global DM 2791d4d07f1eSToby Isaac . l - local vector 2792d4d07f1eSToby Isaac . mode - mode 2793d4d07f1eSToby Isaac . g - global vector 2794d4d07f1eSToby Isaac - ctx - optional user-defined function context 2795d4d07f1eSToby Isaac 2796d4d07f1eSToby Isaac Level: advanced 2797d4d07f1eSToby Isaac 2798d4d07f1eSToby Isaac .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 2799d4d07f1eSToby Isaac @*/ 2800d4d07f1eSToby Isaac PetscErrorCode DMLocalToGlobalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx) 2801d4d07f1eSToby Isaac { 2802d4d07f1eSToby Isaac PetscErrorCode ierr; 2803d4d07f1eSToby Isaac DMLocalToGlobalHookLink link,*p; 2804d4d07f1eSToby Isaac 2805d4d07f1eSToby Isaac PetscFunctionBegin; 2806d4d07f1eSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2807d4d07f1eSToby Isaac for (p=&dm->ltoghook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 280895dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 2809d4d07f1eSToby Isaac link->beginhook = beginhook; 2810d4d07f1eSToby Isaac link->endhook = endhook; 2811d4d07f1eSToby Isaac link->ctx = ctx; 2812d4d07f1eSToby Isaac link->next = NULL; 2813d4d07f1eSToby Isaac *p = link; 2814d4d07f1eSToby Isaac PetscFunctionReturn(0); 2815d4d07f1eSToby Isaac } 2816d4d07f1eSToby Isaac 28174c274da1SToby Isaac static PetscErrorCode DMLocalToGlobalHook_Constraints(DM dm, Vec l, InsertMode mode, Vec g, void *ctx) 28184c274da1SToby Isaac { 28194c274da1SToby Isaac Mat cMat; 28204c274da1SToby Isaac Vec cVec; 28214c274da1SToby Isaac PetscSection section, cSec; 28224c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 28234c274da1SToby Isaac PetscErrorCode ierr; 28244c274da1SToby Isaac 28254c274da1SToby Isaac PetscFunctionBegin; 28264c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 28274c274da1SToby Isaac ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr); 28284c274da1SToby Isaac if (cMat && (mode == ADD_VALUES || mode == ADD_ALL_VALUES || mode == ADD_BC_VALUES)) { 28295db9a05bSToby Isaac PetscInt nRows; 28305db9a05bSToby Isaac 28315db9a05bSToby Isaac ierr = MatGetSize(cMat,&nRows,NULL);CHKERRQ(ierr); 28325db9a05bSToby Isaac if (nRows <= 0) PetscFunctionReturn(0); 283392fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 28347711e48fSToby Isaac ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr); 28354c274da1SToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 28364c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 28374c274da1SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 28384c274da1SToby Isaac if (dof) { 28394c274da1SToby Isaac PetscInt d; 28404c274da1SToby Isaac PetscScalar *vals; 28414c274da1SToby Isaac ierr = VecGetValuesSection(l,section,p,&vals);CHKERRQ(ierr); 28424c274da1SToby Isaac ierr = VecSetValuesSection(cVec,cSec,p,vals,mode);CHKERRQ(ierr); 28434c274da1SToby Isaac /* for this to be the true transpose, we have to zero the values that 28444c274da1SToby Isaac * we just extracted */ 28454c274da1SToby Isaac for (d = 0; d < dof; d++) { 28464c274da1SToby Isaac vals[d] = 0.; 28474c274da1SToby Isaac } 28484c274da1SToby Isaac } 28494c274da1SToby Isaac } 28504c274da1SToby Isaac ierr = MatMultTransposeAdd(cMat,cVec,l,l);CHKERRQ(ierr); 28514c274da1SToby Isaac ierr = VecDestroy(&cVec);CHKERRQ(ierr); 28524c274da1SToby Isaac } 28534c274da1SToby Isaac PetscFunctionReturn(0); 28544c274da1SToby Isaac } 285501729b5cSPatrick Sanan /*@ 285601729b5cSPatrick Sanan DMLocalToGlobal - updates global vectors from local vectors 285701729b5cSPatrick Sanan 2858d083f849SBarry Smith Neighbor-wise Collective on dm 285901729b5cSPatrick Sanan 286001729b5cSPatrick Sanan Input Parameters: 286101729b5cSPatrick Sanan + dm - the DM object 286201729b5cSPatrick Sanan . l - the local vector 286301729b5cSPatrick 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. 286401729b5cSPatrick Sanan - g - the global vector 286501729b5cSPatrick Sanan 286601729b5cSPatrick Sanan Notes: 286701729b5cSPatrick Sanan The communication involved in this update can be overlapped with computation by using 286801729b5cSPatrick Sanan DMLocalToGlobalBegin() and DMLocalToGlobalEnd(). 286901729b5cSPatrick Sanan 287001729b5cSPatrick Sanan In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation. 287101729b5cSPatrick 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. 287201729b5cSPatrick Sanan 287301729b5cSPatrick Sanan Level: beginner 287401729b5cSPatrick Sanan 287501729b5cSPatrick Sanan .seealso DMLocalToGlobalBegin(), DMLocalToGlobalEnd(), DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin() 287601729b5cSPatrick Sanan 287701729b5cSPatrick Sanan @*/ 287801729b5cSPatrick Sanan PetscErrorCode DMLocalToGlobal(DM dm,Vec l,InsertMode mode,Vec g) 287901729b5cSPatrick Sanan { 288001729b5cSPatrick Sanan PetscErrorCode ierr; 288101729b5cSPatrick Sanan 288201729b5cSPatrick Sanan PetscFunctionBegin; 288301729b5cSPatrick Sanan ierr = DMLocalToGlobalBegin(dm,l,mode,g);CHKERRQ(ierr); 288401729b5cSPatrick Sanan ierr = DMLocalToGlobalEnd(dm,l,mode,g);CHKERRQ(ierr); 288501729b5cSPatrick Sanan PetscFunctionReturn(0); 288601729b5cSPatrick Sanan } 28874c274da1SToby Isaac 288847c6ae99SBarry Smith /*@ 288901729b5cSPatrick Sanan DMLocalToGlobalBegin - begins updating global vectors from local vectors 28909a42bb27SBarry Smith 2891d083f849SBarry Smith Neighbor-wise Collective on dm 28929a42bb27SBarry Smith 28939a42bb27SBarry Smith Input Parameters: 28949a42bb27SBarry Smith + dm - the DM object 2895f6813fd5SJed Brown . l - the local vector 28961eb28f2eSBarry 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. 28971eb28f2eSBarry Smith - g - the global vector 28989a42bb27SBarry Smith 289995452b02SPatrick Sanan Notes: 290095452b02SPatrick Sanan In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation. 290184330215SMatthew 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. 29029a42bb27SBarry Smith 290301729b5cSPatrick Sanan Level: intermediate 29049a42bb27SBarry Smith 290501729b5cSPatrick Sanan .seealso DMLocalToGlobal(), DMLocalToGlobalEnd(), DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin() 29069a42bb27SBarry Smith 29079a42bb27SBarry Smith @*/ 29087087cfbeSBarry Smith PetscErrorCode DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g) 29099a42bb27SBarry Smith { 29107128ae9fSMatthew G Knepley PetscSF sf; 291184330215SMatthew G. Knepley PetscSection s, gs; 2912d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 2913ca3d3a14SMatthew G. Knepley Vec tmpl; 2914ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 2915ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 2916fa88e482SJed Brown PetscBool isInsert, transform, l_inplace = PETSC_FALSE, g_inplace = PETSC_FALSE; 291784330215SMatthew G. Knepley PetscErrorCode ierr; 2918d0295fc0SJunchao Zhang PetscMemType lmtype=PETSC_MEMTYPE_HOST,gmtype=PETSC_MEMTYPE_HOST; 29199a42bb27SBarry Smith 29209a42bb27SBarry Smith PetscFunctionBegin; 2921171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2922d4d07f1eSToby Isaac for (link=dm->ltoghook; link; link=link->next) { 2923d4d07f1eSToby Isaac if (link->beginhook) { 2924d4d07f1eSToby Isaac ierr = (*link->beginhook)(dm,l,mode,g,link->ctx);CHKERRQ(ierr); 2925d4d07f1eSToby Isaac } 2926d4d07f1eSToby Isaac } 29274c274da1SToby Isaac ierr = DMLocalToGlobalHook_Constraints(dm,l,mode,g,NULL);CHKERRQ(ierr); 29281bb6d2a8SBarry Smith ierr = DMGetSectionSF(dm, &sf);CHKERRQ(ierr); 292992fd8e1eSJed Brown ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr); 29307128ae9fSMatthew G Knepley switch (mode) { 29317128ae9fSMatthew G Knepley case INSERT_VALUES: 29327128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 2933304ab55fSMatthew G. Knepley case INSERT_BC_VALUES: 293484330215SMatthew G. Knepley isInsert = PETSC_TRUE; break; 29357128ae9fSMatthew G Knepley case ADD_VALUES: 29367128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 2937304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 293884330215SMatthew G. Knepley isInsert = PETSC_FALSE; break; 29397128ae9fSMatthew G Knepley default: 294082f516ccSBarry Smith SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 29417128ae9fSMatthew G Knepley } 2942ca3d3a14SMatthew G. Knepley if ((sf && !isInsert) || (s && isInsert)) { 2943ca3d3a14SMatthew G. Knepley ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr); 2944ca3d3a14SMatthew G. Knepley if (transform) { 2945ca3d3a14SMatthew G. Knepley ierr = DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr); 2946ca3d3a14SMatthew G. Knepley ierr = VecCopy(l, tmpl);CHKERRQ(ierr); 2947ca3d3a14SMatthew G. Knepley ierr = DMPlexLocalToGlobalBasis(dm, tmpl);CHKERRQ(ierr); 2948ca3d3a14SMatthew G. Knepley ierr = VecGetArrayRead(tmpl, &lArray);CHKERRQ(ierr); 2949fa88e482SJed Brown } else if (isInsert) { 2950ae5cfb4aSMatthew G. Knepley ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr); 2951fa88e482SJed Brown } else { 2952a256111fSJunchao Zhang ierr = VecGetArrayReadAndMemType(l, &lArray, &lmtype);CHKERRQ(ierr); 2953fa88e482SJed Brown l_inplace = PETSC_TRUE; 2954ca3d3a14SMatthew G. Knepley } 2955fa88e482SJed Brown if (s && isInsert) { 29567128ae9fSMatthew G Knepley ierr = VecGetArray(g, &gArray);CHKERRQ(ierr); 2957fa88e482SJed Brown } else { 2958a256111fSJunchao Zhang ierr = VecGetArrayAndMemType(g, &gArray, &gmtype);CHKERRQ(ierr); 2959fa88e482SJed Brown g_inplace = PETSC_TRUE; 2960fa88e482SJed Brown } 2961ca3d3a14SMatthew G. Knepley if (sf && !isInsert) { 2962d0295fc0SJunchao Zhang ierr = PetscSFReduceWithMemTypeBegin(sf, MPIU_SCALAR, lmtype, lArray, gmtype, gArray, MPIU_SUM);CHKERRQ(ierr); 296384330215SMatthew G. Knepley } else if (s && isInsert) { 296484330215SMatthew G. Knepley PetscInt gStart, pStart, pEnd, p; 296584330215SMatthew G. Knepley 2966e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, &gs);CHKERRQ(ierr); 296784330215SMatthew G. Knepley ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 296884330215SMatthew G. Knepley ierr = VecGetOwnershipRange(g, &gStart, NULL);CHKERRQ(ierr); 296984330215SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2970b3b16f48SMatthew G. Knepley PetscInt dof, gdof, cdof, gcdof, off, goff, d, e; 297184330215SMatthew G. Knepley 297284330215SMatthew G. Knepley ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 297303442857SMatthew G. Knepley ierr = PetscSectionGetDof(gs, p, &gdof);CHKERRQ(ierr); 297484330215SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 2975b3b16f48SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(gs, p, &gcdof);CHKERRQ(ierr); 297684330215SMatthew G. Knepley ierr = PetscSectionGetOffset(s, p, &off);CHKERRQ(ierr); 297784330215SMatthew G. Knepley ierr = PetscSectionGetOffset(gs, p, &goff);CHKERRQ(ierr); 2978b3b16f48SMatthew G. Knepley /* Ignore off-process data and points with no global data */ 297903442857SMatthew G. Knepley if (!gdof || goff < 0) continue; 2980b3b16f48SMatthew 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); 2981b3b16f48SMatthew G. Knepley /* If no constraints are enforced in the global vector */ 2982b3b16f48SMatthew G. Knepley if (!gcdof) { 298384330215SMatthew G. Knepley for (d = 0; d < dof; ++d) gArray[goff-gStart+d] = lArray[off+d]; 2984b3b16f48SMatthew G. Knepley /* If constraints are enforced in the global vector */ 2985b3b16f48SMatthew G. Knepley } else if (cdof == gcdof) { 298684330215SMatthew G. Knepley const PetscInt *cdofs; 298784330215SMatthew G. Knepley PetscInt cind = 0; 298884330215SMatthew G. Knepley 298984330215SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(s, p, &cdofs);CHKERRQ(ierr); 2990b3b16f48SMatthew G. Knepley for (d = 0, e = 0; d < dof; ++d) { 299184330215SMatthew G. Knepley if ((cind < cdof) && (d == cdofs[cind])) {++cind; continue;} 2992b3b16f48SMatthew G. Knepley gArray[goff-gStart+e++] = lArray[off+d]; 299384330215SMatthew G. Knepley } 2994b3b16f48SMatthew 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); 299584330215SMatthew G. Knepley } 2996ca3d3a14SMatthew G. Knepley } 2997fa88e482SJed Brown if (g_inplace) { 2998a256111fSJunchao Zhang ierr = VecRestoreArrayAndMemType(g, &gArray);CHKERRQ(ierr); 2999fa88e482SJed Brown } else { 30007128ae9fSMatthew G Knepley ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr); 3001fa88e482SJed Brown } 3002ca3d3a14SMatthew G. Knepley if (transform) { 3003ca3d3a14SMatthew G. Knepley ierr = VecRestoreArrayRead(tmpl, &lArray);CHKERRQ(ierr); 3004ca3d3a14SMatthew G. Knepley ierr = DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr); 3005fa88e482SJed Brown } else if (l_inplace) { 3006a256111fSJunchao Zhang ierr = VecRestoreArrayReadAndMemType(l, &lArray);CHKERRQ(ierr); 3007ca3d3a14SMatthew G. Knepley } else { 3008ca3d3a14SMatthew G. Knepley ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr); 3009ca3d3a14SMatthew G. Knepley } 30107128ae9fSMatthew G Knepley } else { 3011b9d85ea2SLisandro Dalcin if (!dm->ops->localtoglobalbegin) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMLocalToGlobalBegin() for type %s",((PetscObject)dm)->type_name); 3012843c4018SMatthew G Knepley ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr); 30137128ae9fSMatthew G Knepley } 30149a42bb27SBarry Smith PetscFunctionReturn(0); 30159a42bb27SBarry Smith } 30169a42bb27SBarry Smith 30179a42bb27SBarry Smith /*@ 30189a42bb27SBarry Smith DMLocalToGlobalEnd - updates global vectors from local vectors 301947c6ae99SBarry Smith 3020d083f849SBarry Smith Neighbor-wise Collective on dm 302147c6ae99SBarry Smith 302247c6ae99SBarry Smith Input Parameters: 302347c6ae99SBarry Smith + dm - the DM object 3024f6813fd5SJed Brown . l - the local vector 302547c6ae99SBarry Smith . mode - INSERT_VALUES or ADD_VALUES 3026f6813fd5SJed Brown - g - the global vector 302747c6ae99SBarry Smith 302801729b5cSPatrick Sanan Level: intermediate 302947c6ae99SBarry Smith 3030e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd() 303147c6ae99SBarry Smith 303247c6ae99SBarry Smith @*/ 30337087cfbeSBarry Smith PetscErrorCode DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g) 303447c6ae99SBarry Smith { 30357128ae9fSMatthew G Knepley PetscSF sf; 303684330215SMatthew G. Knepley PetscSection s; 3037d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 3038ca3d3a14SMatthew G. Knepley PetscBool isInsert, transform; 303984330215SMatthew G. Knepley PetscErrorCode ierr; 304047c6ae99SBarry Smith 304147c6ae99SBarry Smith PetscFunctionBegin; 3042171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 30431bb6d2a8SBarry Smith ierr = DMGetSectionSF(dm, &sf);CHKERRQ(ierr); 304492fd8e1eSJed Brown ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr); 30457128ae9fSMatthew G Knepley switch (mode) { 30467128ae9fSMatthew G Knepley case INSERT_VALUES: 30477128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 304884330215SMatthew G. Knepley isInsert = PETSC_TRUE; break; 30497128ae9fSMatthew G Knepley case ADD_VALUES: 30507128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 305184330215SMatthew G. Knepley isInsert = PETSC_FALSE; break; 30527128ae9fSMatthew G Knepley default: 305382f516ccSBarry Smith SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode); 30547128ae9fSMatthew G Knepley } 305584330215SMatthew G. Knepley if (sf && !isInsert) { 3056ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 3057ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 3058ca3d3a14SMatthew G. Knepley Vec tmpl; 305984330215SMatthew G. Knepley 3060ca3d3a14SMatthew G. Knepley ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr); 3061ca3d3a14SMatthew G. Knepley if (transform) { 3062ca3d3a14SMatthew G. Knepley ierr = DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr); 3063ca3d3a14SMatthew G. Knepley ierr = VecGetArrayRead(tmpl, &lArray);CHKERRQ(ierr); 3064ca3d3a14SMatthew G. Knepley } else { 3065a256111fSJunchao Zhang ierr = VecGetArrayReadAndMemType(l, &lArray, NULL);CHKERRQ(ierr); 3066ca3d3a14SMatthew G. Knepley } 3067a256111fSJunchao Zhang ierr = VecGetArrayAndMemType(g, &gArray, NULL);CHKERRQ(ierr); 3068a9b180a6SBarry Smith ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM);CHKERRQ(ierr); 3069ca3d3a14SMatthew G. Knepley if (transform) { 3070ca3d3a14SMatthew G. Knepley ierr = VecRestoreArrayRead(tmpl, &lArray);CHKERRQ(ierr); 3071ca3d3a14SMatthew G. Knepley ierr = DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr); 3072ca3d3a14SMatthew G. Knepley } else { 3073a256111fSJunchao Zhang ierr = VecRestoreArrayReadAndMemType(l, &lArray);CHKERRQ(ierr); 3074ca3d3a14SMatthew G. Knepley } 3075a256111fSJunchao Zhang ierr = VecRestoreArrayAndMemType(g, &gArray);CHKERRQ(ierr); 307684330215SMatthew G. Knepley } else if (s && isInsert) { 30777128ae9fSMatthew G Knepley } else { 3078b9d85ea2SLisandro Dalcin if (!dm->ops->localtoglobalend) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMLocalToGlobalEnd() for type %s",((PetscObject)dm)->type_name); 3079843c4018SMatthew G Knepley ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr); 30807128ae9fSMatthew G Knepley } 3081d4d07f1eSToby Isaac for (link=dm->ltoghook; link; link=link->next) { 3082d4d07f1eSToby Isaac if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);} 3083d4d07f1eSToby Isaac } 308447c6ae99SBarry Smith PetscFunctionReturn(0); 308547c6ae99SBarry Smith } 308647c6ae99SBarry Smith 3087f089877aSRichard Tran Mills /*@ 3088bc0a1609SRichard Tran Mills DMLocalToLocalBegin - Maps from a local vector (including ghost points 3089bc0a1609SRichard Tran Mills that contain irrelevant values) to another local vector where the ghost 3090d78e899eSRichard Tran Mills points in the second are set correctly. Must be followed by DMLocalToLocalEnd(). 3091f089877aSRichard Tran Mills 3092d083f849SBarry Smith Neighbor-wise Collective on dm 3093f089877aSRichard Tran Mills 3094f089877aSRichard Tran Mills Input Parameters: 3095f089877aSRichard Tran Mills + dm - the DM object 3096bc0a1609SRichard Tran Mills . g - the original local vector 3097bc0a1609SRichard Tran Mills - mode - one of INSERT_VALUES or ADD_VALUES 3098f089877aSRichard Tran Mills 3099bc0a1609SRichard Tran Mills Output Parameter: 3100bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 3101f089877aSRichard Tran Mills 3102f089877aSRichard Tran Mills Level: intermediate 3103f089877aSRichard Tran Mills 3104bc0a1609SRichard Tran Mills Notes: 3105bc0a1609SRichard Tran Mills The local vectors used here need not be the same as those 3106bc0a1609SRichard Tran Mills obtained from DMCreateLocalVector(), BUT they 3107bc0a1609SRichard Tran Mills must have the same parallel data layout; they could, for example, be 3108bc0a1609SRichard Tran Mills obtained with VecDuplicate() from the DM originating vectors. 3109bc0a1609SRichard Tran Mills 3110bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalEnd(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 3111f089877aSRichard Tran Mills 3112f089877aSRichard Tran Mills @*/ 3113f089877aSRichard Tran Mills PetscErrorCode DMLocalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l) 3114f089877aSRichard Tran Mills { 3115f089877aSRichard Tran Mills PetscErrorCode ierr; 3116f089877aSRichard Tran Mills 3117f089877aSRichard Tran Mills PetscFunctionBegin; 3118f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3119bb358533SPatrick Sanan if (!dm->ops->localtolocalbegin) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM does not support local to local maps"); 3120f089877aSRichard Tran Mills ierr = (*dm->ops->localtolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 3121f089877aSRichard Tran Mills PetscFunctionReturn(0); 3122f089877aSRichard Tran Mills } 3123f089877aSRichard Tran Mills 3124f089877aSRichard Tran Mills /*@ 3125bc0a1609SRichard Tran Mills DMLocalToLocalEnd - Maps from a local vector (including ghost points 3126bc0a1609SRichard Tran Mills that contain irrelevant values) to another local vector where the ghost 3127d78e899eSRichard Tran Mills points in the second are set correctly. Must be preceded by DMLocalToLocalBegin(). 3128f089877aSRichard Tran Mills 3129d083f849SBarry Smith Neighbor-wise Collective on dm 3130f089877aSRichard Tran Mills 3131f089877aSRichard Tran Mills Input Parameters: 3132bc0a1609SRichard Tran Mills + da - the DM object 3133bc0a1609SRichard Tran Mills . g - the original local vector 3134bc0a1609SRichard Tran Mills - mode - one of INSERT_VALUES or ADD_VALUES 3135f089877aSRichard Tran Mills 3136bc0a1609SRichard Tran Mills Output Parameter: 3137bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 3138f089877aSRichard Tran Mills 3139f089877aSRichard Tran Mills Level: intermediate 3140f089877aSRichard Tran Mills 3141bc0a1609SRichard Tran Mills Notes: 3142bc0a1609SRichard Tran Mills The local vectors used here need not be the same as those 3143bc0a1609SRichard Tran Mills obtained from DMCreateLocalVector(), BUT they 3144bc0a1609SRichard Tran Mills must have the same parallel data layout; they could, for example, be 3145bc0a1609SRichard Tran Mills obtained with VecDuplicate() from the DM originating vectors. 3146bc0a1609SRichard Tran Mills 3147bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalBegin(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 3148f089877aSRichard Tran Mills 3149f089877aSRichard Tran Mills @*/ 3150f089877aSRichard Tran Mills PetscErrorCode DMLocalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l) 3151f089877aSRichard Tran Mills { 3152f089877aSRichard Tran Mills PetscErrorCode ierr; 3153f089877aSRichard Tran Mills 3154f089877aSRichard Tran Mills PetscFunctionBegin; 3155f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3156bb358533SPatrick Sanan if (!dm->ops->localtolocalend) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM does not support local to local maps"); 3157f089877aSRichard Tran Mills ierr = (*dm->ops->localtolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr); 3158f089877aSRichard Tran Mills PetscFunctionReturn(0); 3159f089877aSRichard Tran Mills } 3160f089877aSRichard Tran Mills 316147c6ae99SBarry Smith /*@ 316247c6ae99SBarry Smith DMCoarsen - Coarsens a DM object 316347c6ae99SBarry Smith 3164d083f849SBarry Smith Collective on dm 316547c6ae99SBarry Smith 3166d8d19677SJose E. Roman Input Parameters: 316747c6ae99SBarry Smith + dm - the DM object 316891d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL) 316947c6ae99SBarry Smith 317047c6ae99SBarry Smith Output Parameter: 317147c6ae99SBarry Smith . dmc - the coarsened DM 317247c6ae99SBarry Smith 317347c6ae99SBarry Smith Level: developer 317447c6ae99SBarry Smith 3175e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 317647c6ae99SBarry Smith 317747c6ae99SBarry Smith @*/ 31787087cfbeSBarry Smith PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc) 317947c6ae99SBarry Smith { 318047c6ae99SBarry Smith PetscErrorCode ierr; 3181b17ce1afSJed Brown DMCoarsenHookLink link; 318247c6ae99SBarry Smith 318347c6ae99SBarry Smith PetscFunctionBegin; 3184171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3185b9d85ea2SLisandro Dalcin if (!dm->ops->coarsen) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCoarsen",((PetscObject)dm)->type_name); 318647a35634SPatrick Farrell ierr = PetscLogEventBegin(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr); 318747c6ae99SBarry Smith ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr); 3188b9d85ea2SLisandro Dalcin if (*dmc) { 3189a3574896SRichard Tran Mills (*dmc)->bind_below = dm->bind_below; /* Propagate this from parent DM; otherwise -dm_bind_below will be useless for multigrid cases. */ 3190a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dm,*dmc);CHKERRQ(ierr); 319143842a1eSJed Brown (*dmc)->ops->creatematrix = dm->ops->creatematrix; 31928cd211a4SJed Brown ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr); 3193644e2e5bSBarry Smith (*dmc)->ctx = dm->ctx; 31940598a293SJed Brown (*dmc)->levelup = dm->levelup; 3195656b349aSBarry Smith (*dmc)->leveldown = dm->leveldown + 1; 3196e4b4b23bSJed Brown ierr = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr); 3197b17ce1afSJed Brown for (link=dm->coarsenhook; link; link=link->next) { 3198b17ce1afSJed Brown if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);} 3199b17ce1afSJed Brown } 3200b9d85ea2SLisandro Dalcin } 320147a35634SPatrick Farrell ierr = PetscLogEventEnd(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr); 3202b9d85ea2SLisandro Dalcin if (!(*dmc)) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "NULL coarse mesh produced"); 3203b17ce1afSJed Brown PetscFunctionReturn(0); 3204b17ce1afSJed Brown } 3205b17ce1afSJed Brown 3206bb9467b5SJed Brown /*@C 3207b17ce1afSJed Brown DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid 3208b17ce1afSJed Brown 3209b17ce1afSJed Brown Logically Collective 3210b17ce1afSJed Brown 32114165533cSJose E. Roman Input Parameters: 3212b17ce1afSJed Brown + fine - nonlinear solver context on which to run a hook when restricting to a coarser level 3213b17ce1afSJed Brown . coarsenhook - function to run when setting up a coarser level 3214b17ce1afSJed Brown . restricthook - function to run to update data on coarser levels (once per SNESSolve()) 32150298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3216b17ce1afSJed Brown 3217b17ce1afSJed Brown Calling sequence of coarsenhook: 3218b17ce1afSJed Brown $ coarsenhook(DM fine,DM coarse,void *ctx); 3219b17ce1afSJed Brown 3220b17ce1afSJed Brown + fine - fine level DM 3221b17ce1afSJed Brown . coarse - coarse level DM to restrict problem to 3222b17ce1afSJed Brown - ctx - optional user-defined function context 3223b17ce1afSJed Brown 3224b17ce1afSJed Brown Calling sequence for restricthook: 3225c833c3b5SJed Brown $ restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx) 3226b17ce1afSJed Brown 3227b17ce1afSJed Brown + fine - fine level DM 3228b17ce1afSJed Brown . mrestrict - matrix restricting a fine-level solution to the coarse grid 3229c833c3b5SJed Brown . rscale - scaling vector for restriction 3230c833c3b5SJed Brown . inject - matrix restricting by injection 3231b17ce1afSJed Brown . coarse - coarse level DM to update 3232b17ce1afSJed Brown - ctx - optional user-defined function context 3233b17ce1afSJed Brown 3234b17ce1afSJed Brown Level: advanced 3235b17ce1afSJed Brown 3236b17ce1afSJed Brown Notes: 3237b17ce1afSJed Brown This function is only needed if auxiliary data needs to be set up on coarse grids. 3238b17ce1afSJed Brown 3239b17ce1afSJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 3240b17ce1afSJed Brown 3241b17ce1afSJed Brown In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3242b17ce1afSJed Brown extract the finest level information from its context (instead of from the SNES). 3243b17ce1afSJed Brown 3244bb9467b5SJed Brown This function is currently not available from Fortran. 3245bb9467b5SJed Brown 3246dc822a44SJed Brown .seealso: DMCoarsenHookRemove(), DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 3247b17ce1afSJed Brown @*/ 3248b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx) 3249b17ce1afSJed Brown { 3250b17ce1afSJed Brown PetscErrorCode ierr; 3251b17ce1afSJed Brown DMCoarsenHookLink link,*p; 3252b17ce1afSJed Brown 3253b17ce1afSJed Brown PetscFunctionBegin; 3254b17ce1afSJed Brown PetscValidHeaderSpecific(fine,DM_CLASSID,1); 32551e3d8eccSJed Brown for (p=&fine->coarsenhook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */ 32561e3d8eccSJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0); 32571e3d8eccSJed Brown } 325895dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 3259b17ce1afSJed Brown link->coarsenhook = coarsenhook; 3260b17ce1afSJed Brown link->restricthook = restricthook; 3261b17ce1afSJed Brown link->ctx = ctx; 32620298fd71SBarry Smith link->next = NULL; 3263b17ce1afSJed Brown *p = link; 3264b17ce1afSJed Brown PetscFunctionReturn(0); 3265b17ce1afSJed Brown } 3266b17ce1afSJed Brown 3267dc822a44SJed Brown /*@C 3268dc822a44SJed Brown DMCoarsenHookRemove - remove a callback from the list of hooks to be run when restricting a nonlinear problem to the coarse grid 3269dc822a44SJed Brown 3270dc822a44SJed Brown Logically Collective 3271dc822a44SJed Brown 32724165533cSJose E. Roman Input Parameters: 3273dc822a44SJed Brown + fine - nonlinear solver context on which to run a hook when restricting to a coarser level 3274dc822a44SJed Brown . coarsenhook - function to run when setting up a coarser level 3275dc822a44SJed Brown . restricthook - function to run to update data on coarser levels (once per SNESSolve()) 3276dc822a44SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3277dc822a44SJed Brown 3278dc822a44SJed Brown Level: advanced 3279dc822a44SJed Brown 3280dc822a44SJed Brown Notes: 3281dc822a44SJed Brown This function does nothing if the hook is not in the list. 3282dc822a44SJed Brown 3283dc822a44SJed Brown This function is currently not available from Fortran. 3284dc822a44SJed Brown 3285dc822a44SJed Brown .seealso: DMCoarsenHookAdd(), DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 3286dc822a44SJed Brown @*/ 3287dc822a44SJed Brown PetscErrorCode DMCoarsenHookRemove(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx) 3288dc822a44SJed Brown { 3289dc822a44SJed Brown PetscErrorCode ierr; 3290dc822a44SJed Brown DMCoarsenHookLink link,*p; 3291dc822a44SJed Brown 3292dc822a44SJed Brown PetscFunctionBegin; 3293dc822a44SJed Brown PetscValidHeaderSpecific(fine,DM_CLASSID,1); 3294dc822a44SJed Brown for (p=&fine->coarsenhook; *p; p=&(*p)->next) { /* Search the list of current hooks */ 3295dc822a44SJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3296dc822a44SJed Brown link = *p; 3297dc822a44SJed Brown *p = link->next; 3298dc822a44SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 3299dc822a44SJed Brown break; 3300dc822a44SJed Brown } 3301dc822a44SJed Brown } 3302dc822a44SJed Brown PetscFunctionReturn(0); 3303dc822a44SJed Brown } 3304dc822a44SJed Brown 3305b17ce1afSJed Brown /*@ 3306b17ce1afSJed Brown DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd() 3307b17ce1afSJed Brown 3308b17ce1afSJed Brown Collective if any hooks are 3309b17ce1afSJed Brown 33104165533cSJose E. Roman Input Parameters: 3311b17ce1afSJed Brown + fine - finer DM to use as a base 3312b17ce1afSJed Brown . restrct - restriction matrix, apply using MatRestrict() 3313e91eccc2SStefano Zampini . rscale - scaling vector for restriction 3314b17ce1afSJed Brown . inject - injection matrix, also use MatRestrict() 3315e91eccc2SStefano Zampini - coarse - coarser DM to update 3316b17ce1afSJed Brown 3317b17ce1afSJed Brown Level: developer 3318b17ce1afSJed Brown 3319b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict() 3320b17ce1afSJed Brown @*/ 3321b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse) 3322b17ce1afSJed Brown { 3323b17ce1afSJed Brown PetscErrorCode ierr; 3324b17ce1afSJed Brown DMCoarsenHookLink link; 3325b17ce1afSJed Brown 3326b17ce1afSJed Brown PetscFunctionBegin; 3327b17ce1afSJed Brown for (link=fine->coarsenhook; link; link=link->next) { 33288865f1eaSKarl Rupp if (link->restricthook) { 33298865f1eaSKarl Rupp ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr); 33308865f1eaSKarl Rupp } 3331b17ce1afSJed Brown } 333247c6ae99SBarry Smith PetscFunctionReturn(0); 333347c6ae99SBarry Smith } 333447c6ae99SBarry Smith 3335bb9467b5SJed Brown /*@C 3336be081cd6SPeter Brune DMSubDomainHookAdd - adds a callback to be run when restricting a problem to the coarse grid 33375dbd56e3SPeter Brune 3338d083f849SBarry Smith Logically Collective on global 33395dbd56e3SPeter Brune 33404165533cSJose E. Roman Input Parameters: 33415dbd56e3SPeter Brune + global - global DM 3342ec4806b8SPeter Brune . ddhook - function to run to pass data to the decomposition DM upon its creation 33435dbd56e3SPeter Brune . restricthook - function to run to update data on block solve (at the beginning of the block solve) 33440298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 33455dbd56e3SPeter Brune 3346ec4806b8SPeter Brune Calling sequence for ddhook: 3347ec4806b8SPeter Brune $ ddhook(DM global,DM block,void *ctx) 3348ec4806b8SPeter Brune 3349ec4806b8SPeter Brune + global - global DM 3350ec4806b8SPeter Brune . block - block DM 3351ec4806b8SPeter Brune - ctx - optional user-defined function context 3352ec4806b8SPeter Brune 33535dbd56e3SPeter Brune Calling sequence for restricthook: 3354ec4806b8SPeter Brune $ restricthook(DM global,VecScatter out,VecScatter in,DM block,void *ctx) 33555dbd56e3SPeter Brune 33565dbd56e3SPeter Brune + global - global DM 33575dbd56e3SPeter Brune . out - scatter to the outer (with ghost and overlap points) block vector 33585dbd56e3SPeter Brune . in - scatter to block vector values only owned locally 3359ec4806b8SPeter Brune . block - block DM 33605dbd56e3SPeter Brune - ctx - optional user-defined function context 33615dbd56e3SPeter Brune 33625dbd56e3SPeter Brune Level: advanced 33635dbd56e3SPeter Brune 33645dbd56e3SPeter Brune Notes: 3365ec4806b8SPeter Brune This function is only needed if auxiliary data needs to be set up on subdomain DMs. 33665dbd56e3SPeter Brune 33675dbd56e3SPeter Brune If this function is called multiple times, the hooks will be run in the order they are added. 33685dbd56e3SPeter Brune 33695dbd56e3SPeter Brune In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3370ec4806b8SPeter Brune extract the global information from its context (instead of from the SNES). 33715dbd56e3SPeter Brune 3372bb9467b5SJed Brown This function is currently not available from Fortran. 3373bb9467b5SJed Brown 33745dbd56e3SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 33755dbd56e3SPeter Brune @*/ 3376be081cd6SPeter Brune PetscErrorCode DMSubDomainHookAdd(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx) 33775dbd56e3SPeter Brune { 33785dbd56e3SPeter Brune PetscErrorCode ierr; 3379be081cd6SPeter Brune DMSubDomainHookLink link,*p; 33805dbd56e3SPeter Brune 33815dbd56e3SPeter Brune PetscFunctionBegin; 33825dbd56e3SPeter Brune PetscValidHeaderSpecific(global,DM_CLASSID,1); 3383b3a6b972SJed Brown for (p=&global->subdomainhook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */ 3384b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0); 3385b3a6b972SJed Brown } 338695dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 33875dbd56e3SPeter Brune link->restricthook = restricthook; 3388be081cd6SPeter Brune link->ddhook = ddhook; 33895dbd56e3SPeter Brune link->ctx = ctx; 33900298fd71SBarry Smith link->next = NULL; 33915dbd56e3SPeter Brune *p = link; 33925dbd56e3SPeter Brune PetscFunctionReturn(0); 33935dbd56e3SPeter Brune } 33945dbd56e3SPeter Brune 3395b3a6b972SJed Brown /*@C 3396b3a6b972SJed Brown DMSubDomainHookRemove - remove a callback from the list to be run when restricting a problem to the coarse grid 3397b3a6b972SJed Brown 3398b3a6b972SJed Brown Logically Collective 3399b3a6b972SJed Brown 34004165533cSJose E. Roman Input Parameters: 3401b3a6b972SJed Brown + global - global DM 3402b3a6b972SJed Brown . ddhook - function to run to pass data to the decomposition DM upon its creation 3403b3a6b972SJed Brown . restricthook - function to run to update data on block solve (at the beginning of the block solve) 3404b3a6b972SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3405b3a6b972SJed Brown 3406b3a6b972SJed Brown Level: advanced 3407b3a6b972SJed Brown 3408b3a6b972SJed Brown Notes: 3409b3a6b972SJed Brown 3410b3a6b972SJed Brown This function is currently not available from Fortran. 3411b3a6b972SJed Brown 3412b3a6b972SJed Brown .seealso: DMSubDomainHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate() 3413b3a6b972SJed Brown @*/ 3414b3a6b972SJed Brown PetscErrorCode DMSubDomainHookRemove(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx) 3415b3a6b972SJed Brown { 3416b3a6b972SJed Brown PetscErrorCode ierr; 3417b3a6b972SJed Brown DMSubDomainHookLink link,*p; 3418b3a6b972SJed Brown 3419b3a6b972SJed Brown PetscFunctionBegin; 3420b3a6b972SJed Brown PetscValidHeaderSpecific(global,DM_CLASSID,1); 3421b3a6b972SJed Brown for (p=&global->subdomainhook; *p; p=&(*p)->next) { /* Search the list of current hooks */ 3422b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3423b3a6b972SJed Brown link = *p; 3424b3a6b972SJed Brown *p = link->next; 3425b3a6b972SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 3426b3a6b972SJed Brown break; 3427b3a6b972SJed Brown } 3428b3a6b972SJed Brown } 3429b3a6b972SJed Brown PetscFunctionReturn(0); 3430b3a6b972SJed Brown } 3431b3a6b972SJed Brown 34325dbd56e3SPeter Brune /*@ 3433be081cd6SPeter Brune DMSubDomainRestrict - restricts user-defined problem data to a block DM by running hooks registered by DMSubDomainHookAdd() 34345dbd56e3SPeter Brune 34355dbd56e3SPeter Brune Collective if any hooks are 34365dbd56e3SPeter Brune 34374165533cSJose E. Roman Input Parameters: 34385dbd56e3SPeter Brune + fine - finer DM to use as a base 3439be081cd6SPeter Brune . oscatter - scatter from domain global vector filling subdomain global vector with overlap 3440be081cd6SPeter Brune . gscatter - scatter from domain global vector filling subdomain local vector with ghosts 34415dbd56e3SPeter Brune - coarse - coarer DM to update 34425dbd56e3SPeter Brune 34435dbd56e3SPeter Brune Level: developer 34445dbd56e3SPeter Brune 34455dbd56e3SPeter Brune .seealso: DMCoarsenHookAdd(), MatRestrict() 34465dbd56e3SPeter Brune @*/ 3447be081cd6SPeter Brune PetscErrorCode DMSubDomainRestrict(DM global,VecScatter oscatter,VecScatter gscatter,DM subdm) 34485dbd56e3SPeter Brune { 34495dbd56e3SPeter Brune PetscErrorCode ierr; 3450be081cd6SPeter Brune DMSubDomainHookLink link; 34515dbd56e3SPeter Brune 34525dbd56e3SPeter Brune PetscFunctionBegin; 3453be081cd6SPeter Brune for (link=global->subdomainhook; link; link=link->next) { 34548865f1eaSKarl Rupp if (link->restricthook) { 34558865f1eaSKarl Rupp ierr = (*link->restricthook)(global,oscatter,gscatter,subdm,link->ctx);CHKERRQ(ierr); 34568865f1eaSKarl Rupp } 34575dbd56e3SPeter Brune } 34585dbd56e3SPeter Brune PetscFunctionReturn(0); 34595dbd56e3SPeter Brune } 34605dbd56e3SPeter Brune 34615fe1f584SPeter Brune /*@ 34626a7d9d85SPeter Brune DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM. 34635fe1f584SPeter Brune 34645fe1f584SPeter Brune Not Collective 34655fe1f584SPeter Brune 34665fe1f584SPeter Brune Input Parameter: 34675fe1f584SPeter Brune . dm - the DM object 34685fe1f584SPeter Brune 34695fe1f584SPeter Brune Output Parameter: 34706a7d9d85SPeter Brune . level - number of coarsenings 34715fe1f584SPeter Brune 34725fe1f584SPeter Brune Level: developer 34735fe1f584SPeter Brune 34746a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 34755fe1f584SPeter Brune 34765fe1f584SPeter Brune @*/ 34775fe1f584SPeter Brune PetscErrorCode DMGetCoarsenLevel(DM dm,PetscInt *level) 34785fe1f584SPeter Brune { 34795fe1f584SPeter Brune PetscFunctionBegin; 34805fe1f584SPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3481b9d85ea2SLisandro Dalcin PetscValidIntPointer(level,2); 34825fe1f584SPeter Brune *level = dm->leveldown; 34835fe1f584SPeter Brune PetscFunctionReturn(0); 34845fe1f584SPeter Brune } 34855fe1f584SPeter Brune 34869a64c4a8SMatthew G. Knepley /*@ 34879a64c4a8SMatthew G. Knepley DMSetCoarsenLevel - Sets the number of coarsenings that have generated this DM. 34889a64c4a8SMatthew G. Knepley 34899a64c4a8SMatthew G. Knepley Not Collective 34909a64c4a8SMatthew G. Knepley 34919a64c4a8SMatthew G. Knepley Input Parameters: 34929a64c4a8SMatthew G. Knepley + dm - the DM object 34939a64c4a8SMatthew G. Knepley - level - number of coarsenings 34949a64c4a8SMatthew G. Knepley 34959a64c4a8SMatthew G. Knepley Level: developer 34969a64c4a8SMatthew G. Knepley 34979a64c4a8SMatthew G. Knepley .seealso DMCoarsen(), DMGetCoarsenLevel(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 34989a64c4a8SMatthew G. Knepley @*/ 34999a64c4a8SMatthew G. Knepley PetscErrorCode DMSetCoarsenLevel(DM dm,PetscInt level) 35009a64c4a8SMatthew G. Knepley { 35019a64c4a8SMatthew G. Knepley PetscFunctionBegin; 35029a64c4a8SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 35039a64c4a8SMatthew G. Knepley dm->leveldown = level; 35049a64c4a8SMatthew G. Knepley PetscFunctionReturn(0); 35059a64c4a8SMatthew G. Knepley } 35069a64c4a8SMatthew G. Knepley 350747c6ae99SBarry Smith /*@C 350847c6ae99SBarry Smith DMRefineHierarchy - Refines a DM object, all levels at once 350947c6ae99SBarry Smith 3510d083f849SBarry Smith Collective on dm 351147c6ae99SBarry Smith 3512d8d19677SJose E. Roman Input Parameters: 351347c6ae99SBarry Smith + dm - the DM object 351447c6ae99SBarry Smith - nlevels - the number of levels of refinement 351547c6ae99SBarry Smith 351647c6ae99SBarry Smith Output Parameter: 351747c6ae99SBarry Smith . dmf - the refined DM hierarchy 351847c6ae99SBarry Smith 351947c6ae99SBarry Smith Level: developer 352047c6ae99SBarry Smith 3521e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 352247c6ae99SBarry Smith 352347c6ae99SBarry Smith @*/ 35247087cfbeSBarry Smith PetscErrorCode DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[]) 352547c6ae99SBarry Smith { 352647c6ae99SBarry Smith PetscErrorCode ierr; 352747c6ae99SBarry Smith 352847c6ae99SBarry Smith PetscFunctionBegin; 3529171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3530ce94432eSBarry Smith if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 353147c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 3532b9d85ea2SLisandro Dalcin PetscValidPointer(dmf,3); 353347c6ae99SBarry Smith if (dm->ops->refinehierarchy) { 353447c6ae99SBarry Smith ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr); 353547c6ae99SBarry Smith } else if (dm->ops->refine) { 353647c6ae99SBarry Smith PetscInt i; 353747c6ae99SBarry Smith 3538ce94432eSBarry Smith ierr = DMRefine(dm,PetscObjectComm((PetscObject)dm),&dmf[0]);CHKERRQ(ierr); 353947c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 3540ce94432eSBarry Smith ierr = DMRefine(dmf[i-1],PetscObjectComm((PetscObject)dm),&dmf[i]);CHKERRQ(ierr); 354147c6ae99SBarry Smith } 3542ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No RefineHierarchy for this DM yet"); 354347c6ae99SBarry Smith PetscFunctionReturn(0); 354447c6ae99SBarry Smith } 354547c6ae99SBarry Smith 354647c6ae99SBarry Smith /*@C 354747c6ae99SBarry Smith DMCoarsenHierarchy - Coarsens a DM object, all levels at once 354847c6ae99SBarry Smith 3549d083f849SBarry Smith Collective on dm 355047c6ae99SBarry Smith 3551d8d19677SJose E. Roman Input Parameters: 355247c6ae99SBarry Smith + dm - the DM object 355347c6ae99SBarry Smith - nlevels - the number of levels of coarsening 355447c6ae99SBarry Smith 355547c6ae99SBarry Smith Output Parameter: 355647c6ae99SBarry Smith . dmc - the coarsened DM hierarchy 355747c6ae99SBarry Smith 355847c6ae99SBarry Smith Level: developer 355947c6ae99SBarry Smith 3560e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation() 356147c6ae99SBarry Smith 356247c6ae99SBarry Smith @*/ 35637087cfbeSBarry Smith PetscErrorCode DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[]) 356447c6ae99SBarry Smith { 356547c6ae99SBarry Smith PetscErrorCode ierr; 356647c6ae99SBarry Smith 356747c6ae99SBarry Smith PetscFunctionBegin; 3568171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3569ce94432eSBarry Smith if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 357047c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 357147c6ae99SBarry Smith PetscValidPointer(dmc,3); 357247c6ae99SBarry Smith if (dm->ops->coarsenhierarchy) { 357347c6ae99SBarry Smith ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr); 357447c6ae99SBarry Smith } else if (dm->ops->coarsen) { 357547c6ae99SBarry Smith PetscInt i; 357647c6ae99SBarry Smith 3577ce94432eSBarry Smith ierr = DMCoarsen(dm,PetscObjectComm((PetscObject)dm),&dmc[0]);CHKERRQ(ierr); 357847c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 3579ce94432eSBarry Smith ierr = DMCoarsen(dmc[i-1],PetscObjectComm((PetscObject)dm),&dmc[i]);CHKERRQ(ierr); 358047c6ae99SBarry Smith } 3581ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet"); 358247c6ae99SBarry Smith PetscFunctionReturn(0); 358347c6ae99SBarry Smith } 358447c6ae99SBarry Smith 35851a266240SBarry Smith /*@C 35861a266240SBarry Smith DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed 35871a266240SBarry Smith 35881a266240SBarry Smith Not Collective 35891a266240SBarry Smith 35901a266240SBarry Smith Input Parameters: 35911a266240SBarry Smith + dm - the DM object 35921a266240SBarry Smith - destroy - the destroy function 35931a266240SBarry Smith 35941a266240SBarry Smith Level: intermediate 35951a266240SBarry Smith 3596e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 35971a266240SBarry Smith 3598f07f9ceaSJed Brown @*/ 35991a266240SBarry Smith PetscErrorCode DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**)) 36001a266240SBarry Smith { 36011a266240SBarry Smith PetscFunctionBegin; 3602171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 36031a266240SBarry Smith dm->ctxdestroy = destroy; 36041a266240SBarry Smith PetscFunctionReturn(0); 36051a266240SBarry Smith } 36061a266240SBarry Smith 3607b07ff414SBarry Smith /*@ 36081b2093e4SBarry Smith DMSetApplicationContext - Set a user context into a DM object 360947c6ae99SBarry Smith 361047c6ae99SBarry Smith Not Collective 361147c6ae99SBarry Smith 361247c6ae99SBarry Smith Input Parameters: 361347c6ae99SBarry Smith + dm - the DM object 361447c6ae99SBarry Smith - ctx - the user context 361547c6ae99SBarry Smith 361647c6ae99SBarry Smith Level: intermediate 361747c6ae99SBarry Smith 3618e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 361947c6ae99SBarry Smith 362047c6ae99SBarry Smith @*/ 36211b2093e4SBarry Smith PetscErrorCode DMSetApplicationContext(DM dm,void *ctx) 362247c6ae99SBarry Smith { 362347c6ae99SBarry Smith PetscFunctionBegin; 3624171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 362547c6ae99SBarry Smith dm->ctx = ctx; 362647c6ae99SBarry Smith PetscFunctionReturn(0); 362747c6ae99SBarry Smith } 362847c6ae99SBarry Smith 362947c6ae99SBarry Smith /*@ 36301b2093e4SBarry Smith DMGetApplicationContext - Gets a user context from a DM object 363147c6ae99SBarry Smith 363247c6ae99SBarry Smith Not Collective 363347c6ae99SBarry Smith 363447c6ae99SBarry Smith Input Parameter: 363547c6ae99SBarry Smith . dm - the DM object 363647c6ae99SBarry Smith 363747c6ae99SBarry Smith Output Parameter: 363847c6ae99SBarry Smith . ctx - the user context 363947c6ae99SBarry Smith 364047c6ae99SBarry Smith Level: intermediate 364147c6ae99SBarry Smith 3642e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 364347c6ae99SBarry Smith 364447c6ae99SBarry Smith @*/ 36451b2093e4SBarry Smith PetscErrorCode DMGetApplicationContext(DM dm,void *ctx) 364647c6ae99SBarry Smith { 364747c6ae99SBarry Smith PetscFunctionBegin; 3648171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 36491b2093e4SBarry Smith *(void**)ctx = dm->ctx; 365047c6ae99SBarry Smith PetscFunctionReturn(0); 365147c6ae99SBarry Smith } 365247c6ae99SBarry Smith 365308da532bSDmitry Karpeev /*@C 3654df3898eeSBarry Smith DMSetVariableBounds - sets a function to compute the lower and upper bound vectors for SNESVI. 365508da532bSDmitry Karpeev 3656d083f849SBarry Smith Logically Collective on dm 365708da532bSDmitry Karpeev 3658d8d19677SJose E. Roman Input Parameters: 365908da532bSDmitry Karpeev + dm - the DM object 36600298fd71SBarry Smith - f - the function that computes variable bounds used by SNESVI (use NULL to cancel a previous function that was set) 366108da532bSDmitry Karpeev 366208da532bSDmitry Karpeev Level: intermediate 366308da532bSDmitry Karpeev 3664835c3ec7SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), 366508da532bSDmitry Karpeev DMSetJacobian() 366608da532bSDmitry Karpeev 366708da532bSDmitry Karpeev @*/ 366808da532bSDmitry Karpeev PetscErrorCode DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec)) 366908da532bSDmitry Karpeev { 367008da532bSDmitry Karpeev PetscFunctionBegin; 36715a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 367208da532bSDmitry Karpeev dm->ops->computevariablebounds = f; 367308da532bSDmitry Karpeev PetscFunctionReturn(0); 367408da532bSDmitry Karpeev } 367508da532bSDmitry Karpeev 367608da532bSDmitry Karpeev /*@ 367708da532bSDmitry Karpeev DMHasVariableBounds - does the DM object have a variable bounds function? 367808da532bSDmitry Karpeev 367908da532bSDmitry Karpeev Not Collective 368008da532bSDmitry Karpeev 368108da532bSDmitry Karpeev Input Parameter: 368208da532bSDmitry Karpeev . dm - the DM object to destroy 368308da532bSDmitry Karpeev 368408da532bSDmitry Karpeev Output Parameter: 368508da532bSDmitry Karpeev . flg - PETSC_TRUE if the variable bounds function exists 368608da532bSDmitry Karpeev 368708da532bSDmitry Karpeev Level: developer 368808da532bSDmitry Karpeev 368974e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 369008da532bSDmitry Karpeev 369108da532bSDmitry Karpeev @*/ 369208da532bSDmitry Karpeev PetscErrorCode DMHasVariableBounds(DM dm,PetscBool *flg) 369308da532bSDmitry Karpeev { 369408da532bSDmitry Karpeev PetscFunctionBegin; 36955a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3696534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 369708da532bSDmitry Karpeev *flg = (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE; 369808da532bSDmitry Karpeev PetscFunctionReturn(0); 369908da532bSDmitry Karpeev } 370008da532bSDmitry Karpeev 370108da532bSDmitry Karpeev /*@C 370208da532bSDmitry Karpeev DMComputeVariableBounds - compute variable bounds used by SNESVI. 370308da532bSDmitry Karpeev 3704d083f849SBarry Smith Logically Collective on dm 370508da532bSDmitry Karpeev 3706f899ff85SJose E. Roman Input Parameter: 3707907376e6SBarry Smith . dm - the DM object 370808da532bSDmitry Karpeev 370908da532bSDmitry Karpeev Output parameters: 371008da532bSDmitry Karpeev + xl - lower bound 371108da532bSDmitry Karpeev - xu - upper bound 371208da532bSDmitry Karpeev 3713907376e6SBarry Smith Level: advanced 3714907376e6SBarry Smith 371595452b02SPatrick Sanan Notes: 371695452b02SPatrick Sanan This is generally not called by users. It calls the function provided by the user with DMSetVariableBounds() 371708da532bSDmitry Karpeev 371874e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext() 371908da532bSDmitry Karpeev 372008da532bSDmitry Karpeev @*/ 372108da532bSDmitry Karpeev PetscErrorCode DMComputeVariableBounds(DM dm, Vec xl, Vec xu) 372208da532bSDmitry Karpeev { 372308da532bSDmitry Karpeev PetscErrorCode ierr; 37245fd66863SKarl Rupp 372508da532bSDmitry Karpeev PetscFunctionBegin; 37265a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 372708da532bSDmitry Karpeev PetscValidHeaderSpecific(xl,VEC_CLASSID,2); 37285a84ad33SLisandro Dalcin PetscValidHeaderSpecific(xu,VEC_CLASSID,3); 3729b9d85ea2SLisandro Dalcin if (!dm->ops->computevariablebounds) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeVariableBounds",((PetscObject)dm)->type_name); 373008da532bSDmitry Karpeev ierr = (*dm->ops->computevariablebounds)(dm, xl,xu);CHKERRQ(ierr); 373108da532bSDmitry Karpeev PetscFunctionReturn(0); 373208da532bSDmitry Karpeev } 373308da532bSDmitry Karpeev 3734b0ae01b7SPeter Brune /*@ 3735b0ae01b7SPeter Brune DMHasColoring - does the DM object have a method of providing a coloring? 3736b0ae01b7SPeter Brune 3737b0ae01b7SPeter Brune Not Collective 3738b0ae01b7SPeter Brune 3739b0ae01b7SPeter Brune Input Parameter: 3740b0ae01b7SPeter Brune . dm - the DM object 3741b0ae01b7SPeter Brune 3742b0ae01b7SPeter Brune Output Parameter: 3743b0ae01b7SPeter Brune . flg - PETSC_TRUE if the DM has facilities for DMCreateColoring(). 3744b0ae01b7SPeter Brune 3745b0ae01b7SPeter Brune Level: developer 3746b0ae01b7SPeter Brune 37471565f0a7SPatrick Sanan .seealso DMCreateColoring() 3748b0ae01b7SPeter Brune 3749b0ae01b7SPeter Brune @*/ 3750b0ae01b7SPeter Brune PetscErrorCode DMHasColoring(DM dm,PetscBool *flg) 3751b0ae01b7SPeter Brune { 3752b0ae01b7SPeter Brune PetscFunctionBegin; 37535a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3754534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 3755b0ae01b7SPeter Brune *flg = (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE; 3756b0ae01b7SPeter Brune PetscFunctionReturn(0); 3757b0ae01b7SPeter Brune } 3758b0ae01b7SPeter Brune 37593ad4599aSBarry Smith /*@ 37603ad4599aSBarry Smith DMHasCreateRestriction - does the DM object have a method of providing a restriction? 37613ad4599aSBarry Smith 37623ad4599aSBarry Smith Not Collective 37633ad4599aSBarry Smith 37643ad4599aSBarry Smith Input Parameter: 37653ad4599aSBarry Smith . dm - the DM object 37663ad4599aSBarry Smith 37673ad4599aSBarry Smith Output Parameter: 37683ad4599aSBarry Smith . flg - PETSC_TRUE if the DM has facilities for DMCreateRestriction(). 37693ad4599aSBarry Smith 37703ad4599aSBarry Smith Level: developer 37713ad4599aSBarry Smith 37721565f0a7SPatrick Sanan .seealso DMCreateRestriction() 37733ad4599aSBarry Smith 37743ad4599aSBarry Smith @*/ 37753ad4599aSBarry Smith PetscErrorCode DMHasCreateRestriction(DM dm,PetscBool *flg) 37763ad4599aSBarry Smith { 37773ad4599aSBarry Smith PetscFunctionBegin; 37785a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3779534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 37803ad4599aSBarry Smith *flg = (dm->ops->createrestriction) ? PETSC_TRUE : PETSC_FALSE; 37813ad4599aSBarry Smith PetscFunctionReturn(0); 37823ad4599aSBarry Smith } 37833ad4599aSBarry Smith 3784a7058e45SLawrence Mitchell /*@ 3785a7058e45SLawrence Mitchell DMHasCreateInjection - does the DM object have a method of providing an injection? 3786a7058e45SLawrence Mitchell 3787a7058e45SLawrence Mitchell Not Collective 3788a7058e45SLawrence Mitchell 3789a7058e45SLawrence Mitchell Input Parameter: 3790a7058e45SLawrence Mitchell . dm - the DM object 3791a7058e45SLawrence Mitchell 3792a7058e45SLawrence Mitchell Output Parameter: 3793a7058e45SLawrence Mitchell . flg - PETSC_TRUE if the DM has facilities for DMCreateInjection(). 3794a7058e45SLawrence Mitchell 3795a7058e45SLawrence Mitchell Level: developer 3796a7058e45SLawrence Mitchell 37971565f0a7SPatrick Sanan .seealso DMCreateInjection() 3798a7058e45SLawrence Mitchell 3799a7058e45SLawrence Mitchell @*/ 3800a7058e45SLawrence Mitchell PetscErrorCode DMHasCreateInjection(DM dm,PetscBool *flg) 3801a7058e45SLawrence Mitchell { 38024a7a4c06SLawrence Mitchell PetscErrorCode ierr; 38035a84ad33SLisandro Dalcin 3804a7058e45SLawrence Mitchell PetscFunctionBegin; 38055a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3806534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 38075a84ad33SLisandro Dalcin if (dm->ops->hascreateinjection) { 38084a7a4c06SLawrence Mitchell ierr = (*dm->ops->hascreateinjection)(dm,flg);CHKERRQ(ierr); 38095a84ad33SLisandro Dalcin } else { 38105a84ad33SLisandro Dalcin *flg = (dm->ops->createinjection) ? PETSC_TRUE : PETSC_FALSE; 38115a84ad33SLisandro Dalcin } 3812a7058e45SLawrence Mitchell PetscFunctionReturn(0); 3813a7058e45SLawrence Mitchell } 3814a7058e45SLawrence Mitchell 38150298fd71SBarry Smith PetscFunctionList DMList = NULL; 3816264ace61SBarry Smith PetscBool DMRegisterAllCalled = PETSC_FALSE; 3817264ace61SBarry Smith 3818264ace61SBarry Smith /*@C 3819264ace61SBarry Smith DMSetType - Builds a DM, for a particular DM implementation. 3820264ace61SBarry Smith 3821d083f849SBarry Smith Collective on dm 3822264ace61SBarry Smith 3823264ace61SBarry Smith Input Parameters: 3824264ace61SBarry Smith + dm - The DM object 3825264ace61SBarry Smith - method - The name of the DM type 3826264ace61SBarry Smith 3827264ace61SBarry Smith Options Database Key: 3828264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types 3829264ace61SBarry Smith 3830264ace61SBarry Smith Notes: 3831e1589f56SBarry Smith See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D). 3832264ace61SBarry Smith 3833264ace61SBarry Smith Level: intermediate 3834264ace61SBarry Smith 3835264ace61SBarry Smith .seealso: DMGetType(), DMCreate() 3836264ace61SBarry Smith @*/ 383719fd82e9SBarry Smith PetscErrorCode DMSetType(DM dm, DMType method) 3838264ace61SBarry Smith { 3839264ace61SBarry Smith PetscErrorCode (*r)(DM); 3840264ace61SBarry Smith PetscBool match; 3841264ace61SBarry Smith PetscErrorCode ierr; 3842264ace61SBarry Smith 3843264ace61SBarry Smith PetscFunctionBegin; 3844264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID,1); 3845251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr); 3846264ace61SBarry Smith if (match) PetscFunctionReturn(0); 3847264ace61SBarry Smith 38480f51fdf8SToby Isaac ierr = DMRegisterAll();CHKERRQ(ierr); 38491c9cd337SJed Brown ierr = PetscFunctionListFind(DMList,method,&r);CHKERRQ(ierr); 3850ce94432eSBarry Smith if (!r) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method); 3851264ace61SBarry Smith 3852264ace61SBarry Smith if (dm->ops->destroy) { 3853264ace61SBarry Smith ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr); 3854264ace61SBarry Smith } 3855d57f96a3SLisandro Dalcin ierr = PetscMemzero(dm->ops,sizeof(*dm->ops));CHKERRQ(ierr); 3856264ace61SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr); 3857d57f96a3SLisandro Dalcin ierr = (*r)(dm);CHKERRQ(ierr); 3858264ace61SBarry Smith PetscFunctionReturn(0); 3859264ace61SBarry Smith } 3860264ace61SBarry Smith 3861264ace61SBarry Smith /*@C 3862264ace61SBarry Smith DMGetType - Gets the DM type name (as a string) from the DM. 3863264ace61SBarry Smith 3864264ace61SBarry Smith Not Collective 3865264ace61SBarry Smith 3866264ace61SBarry Smith Input Parameter: 3867264ace61SBarry Smith . dm - The DM 3868264ace61SBarry Smith 3869264ace61SBarry Smith Output Parameter: 3870264ace61SBarry Smith . type - The DM type name 3871264ace61SBarry Smith 3872264ace61SBarry Smith Level: intermediate 3873264ace61SBarry Smith 3874264ace61SBarry Smith .seealso: DMSetType(), DMCreate() 3875264ace61SBarry Smith @*/ 387619fd82e9SBarry Smith PetscErrorCode DMGetType(DM dm, DMType *type) 3877264ace61SBarry Smith { 3878264ace61SBarry Smith PetscErrorCode ierr; 3879264ace61SBarry Smith 3880264ace61SBarry Smith PetscFunctionBegin; 3881264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID,1); 3882c959eef4SJed Brown PetscValidPointer(type,2); 3883607a6623SBarry Smith ierr = DMRegisterAll();CHKERRQ(ierr); 3884264ace61SBarry Smith *type = ((PetscObject)dm)->type_name; 3885264ace61SBarry Smith PetscFunctionReturn(0); 3886264ace61SBarry Smith } 3887264ace61SBarry Smith 388867a56275SMatthew G Knepley /*@C 388967a56275SMatthew G Knepley DMConvert - Converts a DM to another DM, either of the same or different type. 389067a56275SMatthew G Knepley 3891d083f849SBarry Smith Collective on dm 389267a56275SMatthew G Knepley 389367a56275SMatthew G Knepley Input Parameters: 389467a56275SMatthew G Knepley + dm - the DM 389567a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type) 389667a56275SMatthew G Knepley 389767a56275SMatthew G Knepley Output Parameter: 389867a56275SMatthew G Knepley . M - pointer to new DM 389967a56275SMatthew G Knepley 390067a56275SMatthew G Knepley Notes: 390167a56275SMatthew G Knepley Cannot be used to convert a sequential DM to parallel or parallel to sequential, 390267a56275SMatthew G Knepley the MPI communicator of the generated DM is always the same as the communicator 390367a56275SMatthew G Knepley of the input DM. 390467a56275SMatthew G Knepley 390567a56275SMatthew G Knepley Level: intermediate 390667a56275SMatthew G Knepley 390767a56275SMatthew G Knepley .seealso: DMCreate() 390867a56275SMatthew G Knepley @*/ 390919fd82e9SBarry Smith PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M) 391067a56275SMatthew G Knepley { 391167a56275SMatthew G Knepley DM B; 391267a56275SMatthew G Knepley char convname[256]; 3913c067b6caSMatthew G. Knepley PetscBool sametype/*, issame */; 391467a56275SMatthew G Knepley PetscErrorCode ierr; 391567a56275SMatthew G Knepley 391667a56275SMatthew G Knepley PetscFunctionBegin; 391767a56275SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 391867a56275SMatthew G Knepley PetscValidType(dm,1); 391967a56275SMatthew G Knepley PetscValidPointer(M,3); 3920251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr); 3921c067b6caSMatthew G. Knepley /* ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr); */ 3922c067b6caSMatthew G. Knepley if (sametype) { 3923c067b6caSMatthew G. Knepley *M = dm; 3924c067b6caSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr); 3925c067b6caSMatthew G. Knepley PetscFunctionReturn(0); 3926c067b6caSMatthew G. Knepley } else { 39270298fd71SBarry Smith PetscErrorCode (*conv)(DM, DMType, DM*) = NULL; 392867a56275SMatthew G Knepley 392967a56275SMatthew G Knepley /* 393067a56275SMatthew G Knepley Order of precedence: 393167a56275SMatthew G Knepley 1) See if a specialized converter is known to the current DM. 393267a56275SMatthew G Knepley 2) See if a specialized converter is known to the desired DM class. 393367a56275SMatthew G Knepley 3) See if a good general converter is registered for the desired class 393467a56275SMatthew G Knepley 4) See if a good general converter is known for the current matrix. 393567a56275SMatthew G Knepley 5) Use a really basic converter. 393667a56275SMatthew G Knepley */ 393767a56275SMatthew G Knepley 393867a56275SMatthew G Knepley /* 1) See if a specialized converter is known to the current DM and the desired class */ 3939a126751eSBarry Smith ierr = PetscStrncpy(convname,"DMConvert_",sizeof(convname));CHKERRQ(ierr); 3940a126751eSBarry Smith ierr = PetscStrlcat(convname,((PetscObject) dm)->type_name,sizeof(convname));CHKERRQ(ierr); 3941a126751eSBarry Smith ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 3942a126751eSBarry Smith ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 3943a126751eSBarry Smith ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 39440005d66cSJed Brown ierr = PetscObjectQueryFunction((PetscObject)dm,convname,&conv);CHKERRQ(ierr); 394567a56275SMatthew G Knepley if (conv) goto foundconv; 394667a56275SMatthew G Knepley 394767a56275SMatthew G Knepley /* 2) See if a specialized converter is known to the desired DM class. */ 394882f516ccSBarry Smith ierr = DMCreate(PetscObjectComm((PetscObject)dm), &B);CHKERRQ(ierr); 394967a56275SMatthew G Knepley ierr = DMSetType(B, newtype);CHKERRQ(ierr); 3950a126751eSBarry Smith ierr = PetscStrncpy(convname,"DMConvert_",sizeof(convname));CHKERRQ(ierr); 3951a126751eSBarry Smith ierr = PetscStrlcat(convname,((PetscObject) dm)->type_name,sizeof(convname));CHKERRQ(ierr); 3952a126751eSBarry Smith ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 3953a126751eSBarry Smith ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 3954a126751eSBarry Smith ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 39550005d66cSJed Brown ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 395667a56275SMatthew G Knepley if (conv) { 3957fcfd50ebSBarry Smith ierr = DMDestroy(&B);CHKERRQ(ierr); 395867a56275SMatthew G Knepley goto foundconv; 395967a56275SMatthew G Knepley } 396067a56275SMatthew G Knepley 396167a56275SMatthew G Knepley #if 0 396267a56275SMatthew G Knepley /* 3) See if a good general converter is registered for the desired class */ 396367a56275SMatthew G Knepley conv = B->ops->convertfrom; 3964fcfd50ebSBarry Smith ierr = DMDestroy(&B);CHKERRQ(ierr); 396567a56275SMatthew G Knepley if (conv) goto foundconv; 396667a56275SMatthew G Knepley 396767a56275SMatthew G Knepley /* 4) See if a good general converter is known for the current matrix */ 396867a56275SMatthew G Knepley if (dm->ops->convert) { 396967a56275SMatthew G Knepley conv = dm->ops->convert; 397067a56275SMatthew G Knepley } 397167a56275SMatthew G Knepley if (conv) goto foundconv; 397267a56275SMatthew G Knepley #endif 397367a56275SMatthew G Knepley 397467a56275SMatthew G Knepley /* 5) Use a really basic converter. */ 397582f516ccSBarry Smith SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype); 397667a56275SMatthew G Knepley 397767a56275SMatthew G Knepley foundconv: 397867a56275SMatthew G Knepley ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr); 397967a56275SMatthew G Knepley ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr); 398012fa691eSMatthew G. Knepley /* Things that are independent of DM type: We should consult DMClone() here */ 398190b157c4SStefano Zampini { 398290b157c4SStefano Zampini PetscBool isper; 398312fa691eSMatthew G. Knepley const PetscReal *maxCell, *L; 398412fa691eSMatthew G. Knepley const DMBoundaryType *bd; 398590b157c4SStefano Zampini ierr = DMGetPeriodicity(dm, &isper, &maxCell, &L, &bd);CHKERRQ(ierr); 398690b157c4SStefano Zampini ierr = DMSetPeriodicity(*M, isper, maxCell, L, bd);CHKERRQ(ierr); 3987c8a6034eSMark (*M)->prealloc_only = dm->prealloc_only; 3988a587d139SMark ierr = PetscFree((*M)->vectype);CHKERRQ(ierr); 3989a587d139SMark ierr = PetscStrallocpy(dm->vectype,(char**)&(*M)->vectype);CHKERRQ(ierr); 3990a587d139SMark ierr = PetscFree((*M)->mattype);CHKERRQ(ierr); 3991a587d139SMark ierr = PetscStrallocpy(dm->mattype,(char**)&(*M)->mattype);CHKERRQ(ierr); 399212fa691eSMatthew G. Knepley } 399367a56275SMatthew G Knepley ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr); 399467a56275SMatthew G Knepley } 399567a56275SMatthew G Knepley ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr); 399667a56275SMatthew G Knepley PetscFunctionReturn(0); 399767a56275SMatthew G Knepley } 3998264ace61SBarry Smith 3999264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/ 4000264ace61SBarry Smith 4001264ace61SBarry Smith /*@C 40021c84c290SBarry Smith DMRegister - Adds a new DM component implementation 40031c84c290SBarry Smith 40041c84c290SBarry Smith Not Collective 40051c84c290SBarry Smith 40061c84c290SBarry Smith Input Parameters: 40071c84c290SBarry Smith + name - The name of a new user-defined creation routine 40081c84c290SBarry Smith - create_func - The creation routine itself 40091c84c290SBarry Smith 40101c84c290SBarry Smith Notes: 40111c84c290SBarry Smith DMRegister() may be called multiple times to add several user-defined DMs 40121c84c290SBarry Smith 40131c84c290SBarry Smith Sample usage: 40141c84c290SBarry Smith .vb 4015bdf89e91SBarry Smith DMRegister("my_da", MyDMCreate); 40161c84c290SBarry Smith .ve 40171c84c290SBarry Smith 40181c84c290SBarry Smith Then, your DM type can be chosen with the procedural interface via 40191c84c290SBarry Smith .vb 40201c84c290SBarry Smith DMCreate(MPI_Comm, DM *); 40211c84c290SBarry Smith DMSetType(DM,"my_da"); 40221c84c290SBarry Smith .ve 40231c84c290SBarry Smith or at runtime via the option 40241c84c290SBarry Smith .vb 40251c84c290SBarry Smith -da_type my_da 40261c84c290SBarry Smith .ve 4027264ace61SBarry Smith 4028264ace61SBarry Smith Level: advanced 40291c84c290SBarry Smith 4030bdf89e91SBarry Smith .seealso: DMRegisterAll(), DMRegisterDestroy() 40311c84c290SBarry Smith 4032264ace61SBarry Smith @*/ 4033bdf89e91SBarry Smith PetscErrorCode DMRegister(const char sname[],PetscErrorCode (*function)(DM)) 4034264ace61SBarry Smith { 4035264ace61SBarry Smith PetscErrorCode ierr; 4036264ace61SBarry Smith 4037264ace61SBarry Smith PetscFunctionBegin; 40381d36bdfdSBarry Smith ierr = DMInitializePackage();CHKERRQ(ierr); 4039a240a19fSJed Brown ierr = PetscFunctionListAdd(&DMList,sname,function);CHKERRQ(ierr); 4040264ace61SBarry Smith PetscFunctionReturn(0); 4041264ace61SBarry Smith } 4042264ace61SBarry Smith 4043b859378eSBarry Smith /*@C 404455849f57SBarry Smith DMLoad - Loads a DM that has been stored in binary with DMView(). 4045b859378eSBarry Smith 4046d083f849SBarry Smith Collective on viewer 4047b859378eSBarry Smith 4048b859378eSBarry Smith Input Parameters: 4049b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or 4050b859378eSBarry Smith some related function before a call to DMLoad(). 4051b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or 4052b859378eSBarry Smith HDF5 file viewer, obtained from PetscViewerHDF5Open() 4053b859378eSBarry Smith 4054b859378eSBarry Smith Level: intermediate 4055b859378eSBarry Smith 4056b859378eSBarry Smith Notes: 405755849f57SBarry Smith The type is determined by the data in the file, any type set into the DM before this call is ignored. 4058b859378eSBarry Smith 4059cd7e8a5eSksagiyam Using PETSCVIEWERHDF5 type with PETSC_VIEWER_HDF5_PETSC format, one can save multiple DMPlex 4060cd7e8a5eSksagiyam meshes in a single HDF5 file. This in turn requires one to name the DMPlex object with PetscObjectSetName() 4061cd7e8a5eSksagiyam before saving it with DMView() and before loading it with DMLoad() for identification of the mesh object. 4062cd7e8a5eSksagiyam 4063b859378eSBarry Smith Notes for advanced users: 4064b859378eSBarry Smith Most users should not need to know the details of the binary storage 4065b859378eSBarry Smith format, since DMLoad() and DMView() completely hide these details. 4066b859378eSBarry Smith But for anyone who's interested, the standard binary matrix storage 4067b859378eSBarry Smith format is 4068b859378eSBarry Smith .vb 4069b859378eSBarry Smith has not yet been determined 4070b859378eSBarry Smith .ve 4071b859378eSBarry Smith 4072b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad() 4073b859378eSBarry Smith @*/ 4074b859378eSBarry Smith PetscErrorCode DMLoad(DM newdm, PetscViewer viewer) 4075b859378eSBarry Smith { 40769331c7a4SMatthew G. Knepley PetscBool isbinary, ishdf5; 4077b859378eSBarry Smith PetscErrorCode ierr; 4078b859378eSBarry Smith 4079b859378eSBarry Smith PetscFunctionBegin; 4080b859378eSBarry Smith PetscValidHeaderSpecific(newdm,DM_CLASSID,1); 4081b859378eSBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 4082fb694a9eSVaclav Hapla ierr = PetscViewerCheckReadable(viewer);CHKERRQ(ierr); 408332c0f0efSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 40849331c7a4SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 408558cd63d5SVaclav Hapla ierr = PetscLogEventBegin(DM_Load,viewer,0,0,0);CHKERRQ(ierr); 40869331c7a4SMatthew G. Knepley if (isbinary) { 40879331c7a4SMatthew G. Knepley PetscInt classid; 40889331c7a4SMatthew G. Knepley char type[256]; 4089b859378eSBarry Smith 4090060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr); 40919200755eSBarry Smith if (classid != DM_FILE_CLASSID) SETERRQ1(PetscObjectComm((PetscObject)newdm),PETSC_ERR_ARG_WRONG,"Not DM next in file, classid found %d",(int)classid); 4092060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr); 409332c0f0efSBarry Smith ierr = DMSetType(newdm, type);CHKERRQ(ierr); 40949331c7a4SMatthew G. Knepley if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);} 40959331c7a4SMatthew G. Knepley } else if (ishdf5) { 40969331c7a4SMatthew G. Knepley if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);} 40979331c7a4SMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()"); 409858cd63d5SVaclav Hapla ierr = PetscLogEventEnd(DM_Load,viewer,0,0,0);CHKERRQ(ierr); 4099b859378eSBarry Smith PetscFunctionReturn(0); 4100b859378eSBarry Smith } 4101b859378eSBarry Smith 4102b2e4378dSMatthew G. Knepley /*@ 4103b2e4378dSMatthew G. Knepley DMGetLocalBoundingBox - Returns the bounding box for the piece of the DM on this process. 4104b2e4378dSMatthew G. Knepley 4105b2e4378dSMatthew G. Knepley Not collective 4106b2e4378dSMatthew G. Knepley 4107b2e4378dSMatthew G. Knepley Input Parameter: 4108b2e4378dSMatthew G. Knepley . dm - the DM 4109b2e4378dSMatthew G. Knepley 4110b2e4378dSMatthew G. Knepley Output Parameters: 4111b2e4378dSMatthew G. Knepley + lmin - local minimum coordinates (length coord dim, optional) 4112b2e4378dSMatthew G. Knepley - lmax - local maximim coordinates (length coord dim, optional) 4113b2e4378dSMatthew G. Knepley 4114b2e4378dSMatthew G. Knepley Level: beginner 4115b2e4378dSMatthew G. Knepley 4116b2e4378dSMatthew G. Knepley Note: If the DM is a DMDA and has no coordinates, the index bounds are returned instead. 4117b2e4378dSMatthew G. Knepley 4118b2e4378dSMatthew G. Knepley .seealso: DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetBoundingBox() 4119b2e4378dSMatthew G. Knepley @*/ 4120b2e4378dSMatthew G. Knepley PetscErrorCode DMGetLocalBoundingBox(DM dm, PetscReal lmin[], PetscReal lmax[]) 4121b2e4378dSMatthew G. Knepley { 4122b2e4378dSMatthew G. Knepley Vec coords = NULL; 4123b2e4378dSMatthew G. Knepley PetscReal min[3] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MAX_REAL}; 4124b2e4378dSMatthew G. Knepley PetscReal max[3] = {PETSC_MIN_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 4125b2e4378dSMatthew G. Knepley const PetscScalar *local_coords; 4126b2e4378dSMatthew G. Knepley PetscInt N, Ni; 4127b2e4378dSMatthew G. Knepley PetscInt cdim, i, j; 4128b2e4378dSMatthew G. Knepley PetscErrorCode ierr; 4129b2e4378dSMatthew G. Knepley 4130b2e4378dSMatthew G. Knepley PetscFunctionBegin; 4131b2e4378dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4132b2e4378dSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 4133b2e4378dSMatthew G. Knepley ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr); 4134b2e4378dSMatthew G. Knepley if (coords) { 4135b2e4378dSMatthew G. Knepley ierr = VecGetArrayRead(coords, &local_coords);CHKERRQ(ierr); 4136b2e4378dSMatthew G. Knepley ierr = VecGetLocalSize(coords, &N);CHKERRQ(ierr); 4137b2e4378dSMatthew G. Knepley Ni = N/cdim; 4138b2e4378dSMatthew G. Knepley for (i = 0; i < Ni; ++i) { 4139b2e4378dSMatthew G. Knepley for (j = 0; j < 3; ++j) { 4140b2e4378dSMatthew G. Knepley min[j] = j < cdim ? PetscMin(min[j], PetscRealPart(local_coords[i*cdim+j])) : 0; 4141b2e4378dSMatthew G. Knepley max[j] = j < cdim ? PetscMax(max[j], PetscRealPart(local_coords[i*cdim+j])) : 0; 4142b2e4378dSMatthew G. Knepley } 4143b2e4378dSMatthew G. Knepley } 4144b2e4378dSMatthew G. Knepley ierr = VecRestoreArrayRead(coords, &local_coords);CHKERRQ(ierr); 4145b2e4378dSMatthew G. Knepley } else { 4146b2e4378dSMatthew G. Knepley PetscBool isda; 4147b2e4378dSMatthew G. Knepley 4148b2e4378dSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) dm, DMDA, &isda);CHKERRQ(ierr); 4149b2e4378dSMatthew G. Knepley if (isda) {ierr = DMGetLocalBoundingIndices_DMDA(dm, min, max);CHKERRQ(ierr);} 4150b2e4378dSMatthew G. Knepley } 4151b2e4378dSMatthew G. Knepley if (lmin) {ierr = PetscArraycpy(lmin, min, cdim);CHKERRQ(ierr);} 4152b2e4378dSMatthew G. Knepley if (lmax) {ierr = PetscArraycpy(lmax, max, cdim);CHKERRQ(ierr);} 4153b2e4378dSMatthew G. Knepley PetscFunctionReturn(0); 4154b2e4378dSMatthew G. Knepley } 4155b2e4378dSMatthew G. Knepley 4156b2e4378dSMatthew G. Knepley /*@ 4157b2e4378dSMatthew G. Knepley DMGetBoundingBox - Returns the global bounding box for the DM. 4158b2e4378dSMatthew G. Knepley 4159b2e4378dSMatthew G. Knepley Collective 4160b2e4378dSMatthew G. Knepley 4161b2e4378dSMatthew G. Knepley Input Parameter: 4162b2e4378dSMatthew G. Knepley . dm - the DM 4163b2e4378dSMatthew G. Knepley 4164b2e4378dSMatthew G. Knepley Output Parameters: 4165b2e4378dSMatthew G. Knepley + gmin - global minimum coordinates (length coord dim, optional) 4166b2e4378dSMatthew G. Knepley - gmax - global maximim coordinates (length coord dim, optional) 4167b2e4378dSMatthew G. Knepley 4168b2e4378dSMatthew G. Knepley Level: beginner 4169b2e4378dSMatthew G. Knepley 4170b2e4378dSMatthew G. Knepley .seealso: DMGetLocalBoundingBox(), DMGetCoordinates(), DMGetCoordinatesLocal() 4171b2e4378dSMatthew G. Knepley @*/ 4172b2e4378dSMatthew G. Knepley PetscErrorCode DMGetBoundingBox(DM dm, PetscReal gmin[], PetscReal gmax[]) 4173b2e4378dSMatthew G. Knepley { 4174b2e4378dSMatthew G. Knepley PetscReal lmin[3], lmax[3]; 41756ce308c4SMatthew G. Knepley PetscInt cdim; 41766ce308c4SMatthew G. Knepley PetscMPIInt count; 4177b2e4378dSMatthew G. Knepley PetscErrorCode ierr; 4178b2e4378dSMatthew G. Knepley 4179b2e4378dSMatthew G. Knepley PetscFunctionBegin; 4180b2e4378dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4181b2e4378dSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 4182b2e4378dSMatthew G. Knepley ierr = PetscMPIIntCast(cdim, &count);CHKERRQ(ierr); 4183b2e4378dSMatthew G. Knepley ierr = DMGetLocalBoundingBox(dm, lmin, lmax);CHKERRQ(ierr); 4184820f2d46SBarry Smith if (gmin) {ierr = MPIU_Allreduce(lmin, gmin, count, MPIU_REAL, MPIU_MIN, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr);} 4185820f2d46SBarry Smith if (gmax) {ierr = MPIU_Allreduce(lmax, gmax, count, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr);} 4186b2e4378dSMatthew G. Knepley PetscFunctionReturn(0); 4187b2e4378dSMatthew G. Knepley } 4188b2e4378dSMatthew G. Knepley 41897da65231SMatthew G Knepley /******************************** FEM Support **********************************/ 41907da65231SMatthew G Knepley 4191a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) 4192a6dfd86eSKarl Rupp { 41931d47ebbbSSatish Balay PetscInt f; 41941b30c384SMatthew G Knepley PetscErrorCode ierr; 41951b30c384SMatthew G Knepley 41967da65231SMatthew G Knepley PetscFunctionBegin; 419774778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr); 41981d47ebbbSSatish Balay for (f = 0; f < len; ++f) { 419957622a8eSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, " | %g |\n", (double)PetscRealPart(x[f]));CHKERRQ(ierr); 42007da65231SMatthew G Knepley } 42017da65231SMatthew G Knepley PetscFunctionReturn(0); 42027da65231SMatthew G Knepley } 42037da65231SMatthew G Knepley 4204a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) 4205a6dfd86eSKarl Rupp { 42061b30c384SMatthew G Knepley PetscInt f, g; 42077da65231SMatthew G Knepley PetscErrorCode ierr; 42087da65231SMatthew G Knepley 42097da65231SMatthew G Knepley PetscFunctionBegin; 421074778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr); 42111d47ebbbSSatish Balay for (f = 0; f < rows; ++f) { 421274778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, " |");CHKERRQ(ierr); 42131d47ebbbSSatish Balay for (g = 0; g < cols; ++g) { 4214e3556bceSMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5g", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr); 42157da65231SMatthew G Knepley } 421674778d6cSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr); 42177da65231SMatthew G Knepley } 42187da65231SMatthew G Knepley PetscFunctionReturn(0); 42197da65231SMatthew G Knepley } 4220e7c4fc90SDmitry Karpeev 42216113b454SMatthew G. Knepley PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X) 4222e759306cSMatthew G. Knepley { 42230c5b8624SToby Isaac PetscInt localSize, bs; 42240c5b8624SToby Isaac PetscMPIInt size; 42250c5b8624SToby Isaac Vec x, xglob; 42260c5b8624SToby Isaac const PetscScalar *xarray; 4227e759306cSMatthew G. Knepley PetscErrorCode ierr; 4228e759306cSMatthew G. Knepley 4229e759306cSMatthew G. Knepley PetscFunctionBegin; 4230ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm),&size);CHKERRMPI(ierr); 4231e759306cSMatthew G. Knepley ierr = VecDuplicate(X, &x);CHKERRQ(ierr); 4232e759306cSMatthew G. Knepley ierr = VecCopy(X, x);CHKERRQ(ierr); 42336113b454SMatthew G. Knepley ierr = VecChop(x, tol);CHKERRQ(ierr); 42340c5b8624SToby Isaac ierr = PetscPrintf(PetscObjectComm((PetscObject) dm),"%s:\n",name);CHKERRQ(ierr); 42350c5b8624SToby Isaac if (size > 1) { 42360c5b8624SToby Isaac ierr = VecGetLocalSize(x,&localSize);CHKERRQ(ierr); 42370c5b8624SToby Isaac ierr = VecGetArrayRead(x,&xarray);CHKERRQ(ierr); 42380c5b8624SToby Isaac ierr = VecGetBlockSize(x,&bs);CHKERRQ(ierr); 42390c5b8624SToby Isaac ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject) dm),bs,localSize,PETSC_DETERMINE,xarray,&xglob);CHKERRQ(ierr); 42400c5b8624SToby Isaac } else { 42410c5b8624SToby Isaac xglob = x; 42420c5b8624SToby Isaac } 42430c5b8624SToby Isaac ierr = VecView(xglob,PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject) dm)));CHKERRQ(ierr); 42440c5b8624SToby Isaac if (size > 1) { 42450c5b8624SToby Isaac ierr = VecDestroy(&xglob);CHKERRQ(ierr); 42460c5b8624SToby Isaac ierr = VecRestoreArrayRead(x,&xarray);CHKERRQ(ierr); 42470c5b8624SToby Isaac } 4248e759306cSMatthew G. Knepley ierr = VecDestroy(&x);CHKERRQ(ierr); 4249e759306cSMatthew G. Knepley PetscFunctionReturn(0); 4250e759306cSMatthew G. Knepley } 4251e759306cSMatthew G. Knepley 425288ed4aceSMatthew G Knepley /*@ 42531bb6d2a8SBarry Smith DMGetSection - Get the PetscSection encoding the local data layout for the DM. This is equivalent to DMGetLocalSection(). Deprecated in v3.12 4254061576a5SJed Brown 4255061576a5SJed Brown Input Parameter: 4256061576a5SJed Brown . dm - The DM 4257061576a5SJed Brown 4258061576a5SJed Brown Output Parameter: 4259061576a5SJed Brown . section - The PetscSection 4260061576a5SJed Brown 4261061576a5SJed Brown Options Database Keys: 4262061576a5SJed Brown . -dm_petscsection_view - View the Section created by the DM 4263061576a5SJed Brown 4264061576a5SJed Brown Level: advanced 4265061576a5SJed Brown 4266061576a5SJed Brown Notes: 4267061576a5SJed Brown Use DMGetLocalSection() in new code. 4268061576a5SJed Brown 4269061576a5SJed Brown This gets a borrowed reference, so the user should not destroy this PetscSection. 4270061576a5SJed Brown 4271061576a5SJed Brown .seealso: DMGetLocalSection(), DMSetLocalSection(), DMGetGlobalSection() 4272061576a5SJed Brown @*/ 4273061576a5SJed Brown PetscErrorCode DMGetSection(DM dm, PetscSection *section) 4274061576a5SJed Brown { 4275061576a5SJed Brown PetscErrorCode ierr; 4276061576a5SJed Brown 4277061576a5SJed Brown PetscFunctionBegin; 4278061576a5SJed Brown ierr = DMGetLocalSection(dm,section);CHKERRQ(ierr); 4279061576a5SJed Brown PetscFunctionReturn(0); 4280061576a5SJed Brown } 4281061576a5SJed Brown 4282061576a5SJed Brown /*@ 4283061576a5SJed Brown DMGetLocalSection - Get the PetscSection encoding the local data layout for the DM. 428488ed4aceSMatthew G Knepley 428588ed4aceSMatthew G Knepley Input Parameter: 428688ed4aceSMatthew G Knepley . dm - The DM 428788ed4aceSMatthew G Knepley 428888ed4aceSMatthew G Knepley Output Parameter: 428988ed4aceSMatthew G Knepley . section - The PetscSection 429088ed4aceSMatthew G Knepley 4291e5893cccSMatthew G. Knepley Options Database Keys: 4292e5893cccSMatthew G. Knepley . -dm_petscsection_view - View the Section created by the DM 4293e5893cccSMatthew G. Knepley 429488ed4aceSMatthew G Knepley Level: intermediate 429588ed4aceSMatthew G Knepley 429688ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSection. 429788ed4aceSMatthew G Knepley 4298061576a5SJed Brown .seealso: DMSetLocalSection(), DMGetGlobalSection() 429988ed4aceSMatthew G Knepley @*/ 4300061576a5SJed Brown PetscErrorCode DMGetLocalSection(DM dm, PetscSection *section) 43010adebc6cSBarry Smith { 4302fd59a867SMatthew G. Knepley PetscErrorCode ierr; 4303fd59a867SMatthew G. Knepley 430488ed4aceSMatthew G Knepley PetscFunctionBegin; 430588ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 430688ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 43071bb6d2a8SBarry Smith if (!dm->localSection && dm->ops->createlocalsection) { 4308e5e52638SMatthew G. Knepley PetscInt d; 4309e5e52638SMatthew G. Knepley 431045480ffeSMatthew G. Knepley if (dm->setfromoptionscalled) { 431145480ffeSMatthew G. Knepley PetscObject obj = (PetscObject) dm; 431245480ffeSMatthew G. Knepley PetscViewer viewer; 431345480ffeSMatthew G. Knepley PetscViewerFormat format; 431445480ffeSMatthew G. Knepley PetscBool flg; 431545480ffeSMatthew G. Knepley 431645480ffeSMatthew G. Knepley ierr = PetscOptionsGetViewer(PetscObjectComm(obj), obj->options, obj->prefix, "-dm_petscds_view", &viewer, &format, &flg);CHKERRQ(ierr); 431745480ffeSMatthew G. Knepley if (flg) {ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr);} 431845480ffeSMatthew G. Knepley for (d = 0; d < dm->Nds; ++d) { 431945480ffeSMatthew G. Knepley ierr = PetscDSSetFromOptions(dm->probs[d].ds);CHKERRQ(ierr); 432045480ffeSMatthew G. Knepley if (flg) {ierr = PetscDSView(dm->probs[d].ds, viewer);CHKERRQ(ierr);} 432145480ffeSMatthew G. Knepley } 432245480ffeSMatthew G. Knepley if (flg) { 432345480ffeSMatthew G. Knepley ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 432445480ffeSMatthew G. Knepley ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 432545480ffeSMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 432645480ffeSMatthew G. Knepley } 432745480ffeSMatthew G. Knepley } 43281bb6d2a8SBarry Smith ierr = (*dm->ops->createlocalsection)(dm);CHKERRQ(ierr); 43291bb6d2a8SBarry Smith if (dm->localSection) {ierr = PetscObjectViewFromOptions((PetscObject) dm->localSection, NULL, "-dm_petscsection_view");CHKERRQ(ierr);} 43302f0f8703SMatthew G. Knepley } 43311bb6d2a8SBarry Smith *section = dm->localSection; 433288ed4aceSMatthew G Knepley PetscFunctionReturn(0); 433388ed4aceSMatthew G Knepley } 433488ed4aceSMatthew G Knepley 433588ed4aceSMatthew G Knepley /*@ 43361bb6d2a8SBarry Smith DMSetSection - Set the PetscSection encoding the local data layout for the DM. This is equivalent to DMSetLocalSection(). Deprecated in v3.12 4337061576a5SJed Brown 4338061576a5SJed Brown Input Parameters: 4339061576a5SJed Brown + dm - The DM 4340061576a5SJed Brown - section - The PetscSection 4341061576a5SJed Brown 4342061576a5SJed Brown Level: advanced 4343061576a5SJed Brown 4344061576a5SJed Brown Notes: 4345061576a5SJed Brown Use DMSetLocalSection() in new code. 4346061576a5SJed Brown 4347061576a5SJed Brown Any existing Section will be destroyed 4348061576a5SJed Brown 4349061576a5SJed Brown .seealso: DMSetLocalSection(), DMGetLocalSection(), DMSetGlobalSection() 4350061576a5SJed Brown @*/ 4351061576a5SJed Brown PetscErrorCode DMSetSection(DM dm, PetscSection section) 4352061576a5SJed Brown { 4353061576a5SJed Brown PetscErrorCode ierr; 4354061576a5SJed Brown 4355061576a5SJed Brown PetscFunctionBegin; 4356061576a5SJed Brown ierr = DMSetLocalSection(dm,section);CHKERRQ(ierr); 4357061576a5SJed Brown PetscFunctionReturn(0); 4358061576a5SJed Brown } 4359061576a5SJed Brown 4360061576a5SJed Brown /*@ 4361061576a5SJed Brown DMSetLocalSection - Set the PetscSection encoding the local data layout for the DM. 436288ed4aceSMatthew G Knepley 436388ed4aceSMatthew G Knepley Input Parameters: 436488ed4aceSMatthew G Knepley + dm - The DM 436588ed4aceSMatthew G Knepley - section - The PetscSection 436688ed4aceSMatthew G Knepley 436788ed4aceSMatthew G Knepley Level: intermediate 436888ed4aceSMatthew G Knepley 436988ed4aceSMatthew G Knepley Note: Any existing Section will be destroyed 437088ed4aceSMatthew G Knepley 4371061576a5SJed Brown .seealso: DMGetLocalSection(), DMSetGlobalSection() 437288ed4aceSMatthew G Knepley @*/ 4373061576a5SJed Brown PetscErrorCode DMSetLocalSection(DM dm, PetscSection section) 43740adebc6cSBarry Smith { 4375c473ab19SMatthew G. Knepley PetscInt numFields = 0; 4376af122d2aSMatthew G Knepley PetscInt f; 437788ed4aceSMatthew G Knepley PetscErrorCode ierr; 437888ed4aceSMatthew G Knepley 437988ed4aceSMatthew G Knepley PetscFunctionBegin; 438088ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4381b9d85ea2SLisandro Dalcin if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 43821d799100SJed Brown ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 43831bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&dm->localSection);CHKERRQ(ierr); 43841bb6d2a8SBarry Smith dm->localSection = section; 43851bb6d2a8SBarry Smith if (section) {ierr = PetscSectionGetNumFields(dm->localSection, &numFields);CHKERRQ(ierr);} 4386af122d2aSMatthew G Knepley if (numFields) { 4387af122d2aSMatthew G Knepley ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr); 4388af122d2aSMatthew G Knepley for (f = 0; f < numFields; ++f) { 43890f21e855SMatthew G. Knepley PetscObject disc; 4390af122d2aSMatthew G Knepley const char *name; 4391af122d2aSMatthew G Knepley 43921bb6d2a8SBarry Smith ierr = PetscSectionGetFieldName(dm->localSection, f, &name);CHKERRQ(ierr); 439344a7f3ddSMatthew G. Knepley ierr = DMGetField(dm, f, NULL, &disc);CHKERRQ(ierr); 43940f21e855SMatthew G. Knepley ierr = PetscObjectSetName(disc, name);CHKERRQ(ierr); 4395af122d2aSMatthew G Knepley } 4396af122d2aSMatthew G Knepley } 4397e87a4003SBarry Smith /* The global section will be rebuilt in the next call to DMGetGlobalSection(). */ 43981bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&dm->globalSection);CHKERRQ(ierr); 439988ed4aceSMatthew G Knepley PetscFunctionReturn(0); 440088ed4aceSMatthew G Knepley } 440188ed4aceSMatthew G Knepley 44029435951eSToby Isaac /*@ 4403b7385021SStefano Zampini DMGetDefaultConstraints - Get the PetscSection and Mat that specify the local constraint interpolation. See DMSetDefaultConstraints() for a description of the purpose of constraint interpolation. 44049435951eSToby Isaac 4405e228b242SToby Isaac not collective 4406e228b242SToby Isaac 44079435951eSToby Isaac Input Parameter: 44089435951eSToby Isaac . dm - The DM 44099435951eSToby Isaac 4410d8d19677SJose E. Roman Output Parameters: 44119435951eSToby 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. 44129435951eSToby 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. 44139435951eSToby Isaac 44149435951eSToby Isaac Level: advanced 44159435951eSToby Isaac 44169435951eSToby Isaac Note: This gets borrowed references, so the user should not destroy the PetscSection or the Mat. 44179435951eSToby Isaac 44189435951eSToby Isaac .seealso: DMSetDefaultConstraints() 44199435951eSToby Isaac @*/ 44209435951eSToby Isaac PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat) 44219435951eSToby Isaac { 44229435951eSToby Isaac PetscErrorCode ierr; 44239435951eSToby Isaac 44249435951eSToby Isaac PetscFunctionBegin; 44259435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 44269435951eSToby Isaac if (!dm->defaultConstraintSection && !dm->defaultConstraintMat && dm->ops->createdefaultconstraints) {ierr = (*dm->ops->createdefaultconstraints)(dm);CHKERRQ(ierr);} 442745a75d81SToby Isaac if (section) {*section = dm->defaultConstraintSection;} 442845a75d81SToby Isaac if (mat) {*mat = dm->defaultConstraintMat;} 44299435951eSToby Isaac PetscFunctionReturn(0); 44309435951eSToby Isaac } 44319435951eSToby Isaac 44329435951eSToby Isaac /*@ 4433b7385021SStefano Zampini DMSetDefaultConstraints - Set the PetscSection and Mat that specify the local constraint interpolation. 44349435951eSToby Isaac 44359435951eSToby 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(). 44369435951eSToby Isaac 44379435951eSToby 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. 44389435951eSToby Isaac 4439e228b242SToby Isaac collective on dm 4440e228b242SToby Isaac 44419435951eSToby Isaac Input Parameters: 44429435951eSToby Isaac + dm - The DM 4443e228b242SToby 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). 4444e228b242SToby 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). 44459435951eSToby Isaac 44469435951eSToby Isaac Level: advanced 44479435951eSToby Isaac 44489435951eSToby Isaac Note: This increments the references of the PetscSection and the Mat, so they user can destroy them 44499435951eSToby Isaac 44509435951eSToby Isaac .seealso: DMGetDefaultConstraints() 44519435951eSToby Isaac @*/ 44529435951eSToby Isaac PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat) 44539435951eSToby Isaac { 4454e228b242SToby Isaac PetscMPIInt result; 44559435951eSToby Isaac PetscErrorCode ierr; 44569435951eSToby Isaac 44579435951eSToby Isaac PetscFunctionBegin; 44589435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4459e228b242SToby Isaac if (section) { 4460e228b242SToby Isaac PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 4461ffc4695bSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)section),&result);CHKERRMPI(ierr); 4462f60917d2SBarry Smith if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint section must have local communicator"); 4463e228b242SToby Isaac } 4464e228b242SToby Isaac if (mat) { 4465e228b242SToby Isaac PetscValidHeaderSpecific(mat,MAT_CLASSID,3); 4466ffc4695bSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)mat),&result);CHKERRMPI(ierr); 4467f60917d2SBarry Smith if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint matrix must have local communicator"); 4468e228b242SToby Isaac } 44699435951eSToby Isaac ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 44709435951eSToby Isaac ierr = PetscSectionDestroy(&dm->defaultConstraintSection);CHKERRQ(ierr); 44719435951eSToby Isaac dm->defaultConstraintSection = section; 44729435951eSToby Isaac ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 44739435951eSToby Isaac ierr = MatDestroy(&dm->defaultConstraintMat);CHKERRQ(ierr); 44749435951eSToby Isaac dm->defaultConstraintMat = mat; 44759435951eSToby Isaac PetscFunctionReturn(0); 44769435951eSToby Isaac } 44779435951eSToby Isaac 4478497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 4479507e4973SMatthew G. Knepley /* 4480507e4973SMatthew G. Knepley DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections. 4481507e4973SMatthew G. Knepley 4482507e4973SMatthew G. Knepley Input Parameters: 4483507e4973SMatthew G. Knepley + dm - The DM 4484507e4973SMatthew G. Knepley . localSection - PetscSection describing the local data layout 4485507e4973SMatthew G. Knepley - globalSection - PetscSection describing the global data layout 4486507e4973SMatthew G. Knepley 4487507e4973SMatthew G. Knepley Level: intermediate 4488507e4973SMatthew G. Knepley 44891bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMSetSectionSF() 4490507e4973SMatthew G. Knepley */ 4491f741bcd2SMatthew G. Knepley static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection) 4492507e4973SMatthew G. Knepley { 4493507e4973SMatthew G. Knepley MPI_Comm comm; 4494507e4973SMatthew G. Knepley PetscLayout layout; 4495507e4973SMatthew G. Knepley const PetscInt *ranges; 4496507e4973SMatthew G. Knepley PetscInt pStart, pEnd, p, nroots; 4497507e4973SMatthew G. Knepley PetscMPIInt size, rank; 4498507e4973SMatthew G. Knepley PetscBool valid = PETSC_TRUE, gvalid; 4499507e4973SMatthew G. Knepley PetscErrorCode ierr; 4500507e4973SMatthew G. Knepley 4501507e4973SMatthew G. Knepley PetscFunctionBegin; 4502507e4973SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 4503507e4973SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4504ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 4505ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 4506507e4973SMatthew G. Knepley ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr); 4507507e4973SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr); 4508507e4973SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr); 4509507e4973SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr); 4510507e4973SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr); 4511507e4973SMatthew G. Knepley ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr); 4512507e4973SMatthew G. Knepley ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr); 4513507e4973SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 4514f741bcd2SMatthew G. Knepley PetscInt dof, cdof, off, gdof, gcdof, goff, gsize, d; 4515507e4973SMatthew G. Knepley 4516507e4973SMatthew G. Knepley ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr); 4517507e4973SMatthew G. Knepley ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr); 4518507e4973SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr); 4519507e4973SMatthew G. Knepley ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr); 4520507e4973SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr); 4521507e4973SMatthew G. Knepley ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr); 4522507e4973SMatthew G. Knepley if (!gdof) continue; /* Censored point */ 4523507e4973SMatthew 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;} 4524507e4973SMatthew 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;} 4525507e4973SMatthew G. Knepley if (gdof < 0) { 4526507e4973SMatthew G. Knepley gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof; 4527507e4973SMatthew G. Knepley for (d = 0; d < gsize; ++d) { 4528507e4973SMatthew G. Knepley PetscInt offset = -(goff+1) + d, r; 4529507e4973SMatthew G. Knepley 4530507e4973SMatthew G. Knepley ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr); 4531507e4973SMatthew G. Knepley if (r < 0) r = -(r+2); 4532507e4973SMatthew 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;} 4533507e4973SMatthew G. Knepley } 4534507e4973SMatthew G. Knepley } 4535507e4973SMatthew G. Knepley } 4536507e4973SMatthew G. Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 4537507e4973SMatthew G. Knepley ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr); 4538820f2d46SBarry Smith ierr = MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRMPI(ierr); 4539507e4973SMatthew G. Knepley if (!gvalid) { 4540507e4973SMatthew G. Knepley ierr = DMView(dm, NULL);CHKERRQ(ierr); 4541507e4973SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections"); 4542507e4973SMatthew G. Knepley } 4543507e4973SMatthew G. Knepley PetscFunctionReturn(0); 4544507e4973SMatthew G. Knepley } 4545f741bcd2SMatthew G. Knepley #endif 4546507e4973SMatthew G. Knepley 454788ed4aceSMatthew G Knepley /*@ 4548e87a4003SBarry Smith DMGetGlobalSection - Get the PetscSection encoding the global data layout for the DM. 454988ed4aceSMatthew G Knepley 4550d083f849SBarry Smith Collective on dm 45518b1ab98fSJed Brown 455288ed4aceSMatthew G Knepley Input Parameter: 455388ed4aceSMatthew G Knepley . dm - The DM 455488ed4aceSMatthew G Knepley 455588ed4aceSMatthew G Knepley Output Parameter: 455688ed4aceSMatthew G Knepley . section - The PetscSection 455788ed4aceSMatthew G Knepley 455888ed4aceSMatthew G Knepley Level: intermediate 455988ed4aceSMatthew G Knepley 456088ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSection. 456188ed4aceSMatthew G Knepley 456292fd8e1eSJed Brown .seealso: DMSetLocalSection(), DMGetLocalSection() 456388ed4aceSMatthew G Knepley @*/ 4564e87a4003SBarry Smith PetscErrorCode DMGetGlobalSection(DM dm, PetscSection *section) 45650adebc6cSBarry Smith { 456688ed4aceSMatthew G Knepley PetscErrorCode ierr; 456788ed4aceSMatthew G Knepley 456888ed4aceSMatthew G Knepley PetscFunctionBegin; 456988ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 457088ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 45711bb6d2a8SBarry Smith if (!dm->globalSection) { 4572fd59a867SMatthew G. Knepley PetscSection s; 4573fd59a867SMatthew G. Knepley 457492fd8e1eSJed Brown ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr); 4575fd59a867SMatthew 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"); 457633907cc2SStefano 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"); 45771bb6d2a8SBarry Smith ierr = PetscSectionCreateGlobalSection(s, dm->sf, PETSC_FALSE, PETSC_FALSE, &dm->globalSection);CHKERRQ(ierr); 4578cf06b437SMatthew G. Knepley ierr = PetscLayoutDestroy(&dm->map);CHKERRQ(ierr); 45791bb6d2a8SBarry Smith ierr = PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->globalSection, &dm->map);CHKERRQ(ierr); 45801bb6d2a8SBarry Smith ierr = PetscSectionViewFromOptions(dm->globalSection, NULL, "-global_section_view");CHKERRQ(ierr); 458188ed4aceSMatthew G Knepley } 45821bb6d2a8SBarry Smith *section = dm->globalSection; 458388ed4aceSMatthew G Knepley PetscFunctionReturn(0); 458488ed4aceSMatthew G Knepley } 458588ed4aceSMatthew G Knepley 4586b21d0597SMatthew G Knepley /*@ 4587e87a4003SBarry Smith DMSetGlobalSection - Set the PetscSection encoding the global data layout for the DM. 4588b21d0597SMatthew G Knepley 4589b21d0597SMatthew G Knepley Input Parameters: 4590b21d0597SMatthew G Knepley + dm - The DM 45915080bbdbSMatthew G Knepley - section - The PetscSection, or NULL 4592b21d0597SMatthew G Knepley 4593b21d0597SMatthew G Knepley Level: intermediate 4594b21d0597SMatthew G Knepley 4595b21d0597SMatthew G Knepley Note: Any existing Section will be destroyed 4596b21d0597SMatthew G Knepley 459792fd8e1eSJed Brown .seealso: DMGetGlobalSection(), DMSetLocalSection() 4598b21d0597SMatthew G Knepley @*/ 4599e87a4003SBarry Smith PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section) 46000adebc6cSBarry Smith { 4601b21d0597SMatthew G Knepley PetscErrorCode ierr; 4602b21d0597SMatthew G Knepley 4603b21d0597SMatthew G Knepley PetscFunctionBegin; 4604b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 46055080bbdbSMatthew G Knepley if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 46061d799100SJed Brown ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr); 46071bb6d2a8SBarry Smith ierr = PetscSectionDestroy(&dm->globalSection);CHKERRQ(ierr); 46081bb6d2a8SBarry Smith dm->globalSection = section; 4609497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 46101bb6d2a8SBarry Smith if (section) {ierr = DMDefaultSectionCheckConsistency_Internal(dm, dm->localSection, section);CHKERRQ(ierr);} 4611507e4973SMatthew G. Knepley #endif 4612b21d0597SMatthew G Knepley PetscFunctionReturn(0); 4613b21d0597SMatthew G Knepley } 4614b21d0597SMatthew G Knepley 461588ed4aceSMatthew G Knepley /*@ 46161bb6d2a8SBarry Smith DMGetSectionSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set, 461788ed4aceSMatthew G Knepley it is created from the default PetscSection layouts in the DM. 461888ed4aceSMatthew G Knepley 461988ed4aceSMatthew G Knepley Input Parameter: 462088ed4aceSMatthew G Knepley . dm - The DM 462188ed4aceSMatthew G Knepley 462288ed4aceSMatthew G Knepley Output Parameter: 462388ed4aceSMatthew G Knepley . sf - The PetscSF 462488ed4aceSMatthew G Knepley 462588ed4aceSMatthew G Knepley Level: intermediate 462688ed4aceSMatthew G Knepley 462788ed4aceSMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSF. 462888ed4aceSMatthew G Knepley 46291bb6d2a8SBarry Smith .seealso: DMSetSectionSF(), DMCreateSectionSF() 463088ed4aceSMatthew G Knepley @*/ 46311bb6d2a8SBarry Smith PetscErrorCode DMGetSectionSF(DM dm, PetscSF *sf) 46320adebc6cSBarry Smith { 463388ed4aceSMatthew G Knepley PetscInt nroots; 463488ed4aceSMatthew G Knepley PetscErrorCode ierr; 463588ed4aceSMatthew G Knepley 463688ed4aceSMatthew G Knepley PetscFunctionBegin; 463788ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 463888ed4aceSMatthew G Knepley PetscValidPointer(sf, 2); 46391bb6d2a8SBarry Smith if (!dm->sectionSF) { 46401bb6d2a8SBarry Smith ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm),&dm->sectionSF);CHKERRQ(ierr); 464133907cc2SStefano Zampini } 46421bb6d2a8SBarry Smith ierr = PetscSFGetGraph(dm->sectionSF, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 464388ed4aceSMatthew G Knepley if (nroots < 0) { 464488ed4aceSMatthew G Knepley PetscSection section, gSection; 464588ed4aceSMatthew G Knepley 464692fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 464731ea6d37SMatthew G Knepley if (section) { 4648e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, &gSection);CHKERRQ(ierr); 46491bb6d2a8SBarry Smith ierr = DMCreateSectionSF(dm, section, gSection);CHKERRQ(ierr); 465031ea6d37SMatthew G Knepley } else { 46510298fd71SBarry Smith *sf = NULL; 465231ea6d37SMatthew G Knepley PetscFunctionReturn(0); 465331ea6d37SMatthew G Knepley } 465488ed4aceSMatthew G Knepley } 46551bb6d2a8SBarry Smith *sf = dm->sectionSF; 465688ed4aceSMatthew G Knepley PetscFunctionReturn(0); 465788ed4aceSMatthew G Knepley } 465888ed4aceSMatthew G Knepley 465988ed4aceSMatthew G Knepley /*@ 46601bb6d2a8SBarry Smith DMSetSectionSF - Set the PetscSF encoding the parallel dof overlap for the DM 466188ed4aceSMatthew G Knepley 466288ed4aceSMatthew G Knepley Input Parameters: 466388ed4aceSMatthew G Knepley + dm - The DM 466488ed4aceSMatthew G Knepley - sf - The PetscSF 466588ed4aceSMatthew G Knepley 466688ed4aceSMatthew G Knepley Level: intermediate 466788ed4aceSMatthew G Knepley 466888ed4aceSMatthew G Knepley Note: Any previous SF is destroyed 466988ed4aceSMatthew G Knepley 46701bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMCreateSectionSF() 467188ed4aceSMatthew G Knepley @*/ 46721bb6d2a8SBarry Smith PetscErrorCode DMSetSectionSF(DM dm, PetscSF sf) 46730adebc6cSBarry Smith { 467488ed4aceSMatthew G Knepley PetscErrorCode ierr; 467588ed4aceSMatthew G Knepley 467688ed4aceSMatthew G Knepley PetscFunctionBegin; 467788ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4678b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 467933907cc2SStefano Zampini ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr); 46801bb6d2a8SBarry Smith ierr = PetscSFDestroy(&dm->sectionSF);CHKERRQ(ierr); 46811bb6d2a8SBarry Smith dm->sectionSF = sf; 468288ed4aceSMatthew G Knepley PetscFunctionReturn(0); 468388ed4aceSMatthew G Knepley } 468488ed4aceSMatthew G Knepley 468588ed4aceSMatthew G Knepley /*@C 46861bb6d2a8SBarry Smith DMCreateSectionSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections 468788ed4aceSMatthew G Knepley describing the data layout. 468888ed4aceSMatthew G Knepley 468988ed4aceSMatthew G Knepley Input Parameters: 469088ed4aceSMatthew G Knepley + dm - The DM 469188ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout 469288ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout 469388ed4aceSMatthew G Knepley 46941bb6d2a8SBarry Smith Notes: One usually uses DMGetSectionSF() to obtain the PetscSF 469588ed4aceSMatthew G Knepley 46961bb6d2a8SBarry Smith Level: developer 46971bb6d2a8SBarry Smith 46981bb6d2a8SBarry Smith Developer Note: Since this routine has for arguments the two sections from the DM and puts the resulting PetscSF 46991bb6d2a8SBarry Smith directly into the DM, perhaps this function should not take the local and global sections as 47001bb6d2a8SBarry Smith input and should just obtain them from the DM? 47011bb6d2a8SBarry Smith 47021bb6d2a8SBarry Smith .seealso: DMGetSectionSF(), DMSetSectionSF(), DMGetLocalSection(), DMGetGlobalSection() 470388ed4aceSMatthew G Knepley @*/ 47041bb6d2a8SBarry Smith PetscErrorCode DMCreateSectionSF(DM dm, PetscSection localSection, PetscSection globalSection) 470588ed4aceSMatthew G Knepley { 470688ed4aceSMatthew G Knepley PetscErrorCode ierr; 470788ed4aceSMatthew G Knepley 470888ed4aceSMatthew G Knepley PetscFunctionBegin; 470988ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4710b0c7db22SLisandro Dalcin ierr = PetscSFSetGraphSection(dm->sectionSF, localSection, globalSection);CHKERRQ(ierr); 471188ed4aceSMatthew G Knepley PetscFunctionReturn(0); 471288ed4aceSMatthew G Knepley } 4713af122d2aSMatthew G Knepley 4714b21d0597SMatthew G Knepley /*@ 4715b21d0597SMatthew G Knepley DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM. 4716b21d0597SMatthew G Knepley 4717b21d0597SMatthew G Knepley Input Parameter: 4718b21d0597SMatthew G Knepley . dm - The DM 4719b21d0597SMatthew G Knepley 4720b21d0597SMatthew G Knepley Output Parameter: 4721b21d0597SMatthew G Knepley . sf - The PetscSF 4722b21d0597SMatthew G Knepley 4723b21d0597SMatthew G Knepley Level: intermediate 4724b21d0597SMatthew G Knepley 4725b21d0597SMatthew G Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSF. 4726b21d0597SMatthew G Knepley 47271bb6d2a8SBarry Smith .seealso: DMSetPointSF(), DMGetSectionSF(), DMSetSectionSF(), DMCreateSectionSF() 4728b21d0597SMatthew G Knepley @*/ 47290adebc6cSBarry Smith PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) 47300adebc6cSBarry Smith { 4731b21d0597SMatthew G Knepley PetscFunctionBegin; 4732b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4733b21d0597SMatthew G Knepley PetscValidPointer(sf, 2); 4734b21d0597SMatthew G Knepley *sf = dm->sf; 4735b21d0597SMatthew G Knepley PetscFunctionReturn(0); 4736b21d0597SMatthew G Knepley } 4737b21d0597SMatthew G Knepley 4738057b4bcdSMatthew G Knepley /*@ 4739057b4bcdSMatthew G Knepley DMSetPointSF - Set the PetscSF encoding the parallel section point overlap for the DM. 4740057b4bcdSMatthew G Knepley 4741057b4bcdSMatthew G Knepley Input Parameters: 4742057b4bcdSMatthew G Knepley + dm - The DM 4743057b4bcdSMatthew G Knepley - sf - The PetscSF 4744057b4bcdSMatthew G Knepley 4745057b4bcdSMatthew G Knepley Level: intermediate 4746057b4bcdSMatthew G Knepley 47471bb6d2a8SBarry Smith .seealso: DMGetPointSF(), DMGetSectionSF(), DMSetSectionSF(), DMCreateSectionSF() 4748057b4bcdSMatthew G Knepley @*/ 47490adebc6cSBarry Smith PetscErrorCode DMSetPointSF(DM dm, PetscSF sf) 47500adebc6cSBarry Smith { 4751057b4bcdSMatthew G Knepley PetscErrorCode ierr; 4752057b4bcdSMatthew G Knepley 4753057b4bcdSMatthew G Knepley PetscFunctionBegin; 4754057b4bcdSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4755b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 4756057b4bcdSMatthew G Knepley ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr); 475733907cc2SStefano Zampini ierr = PetscSFDestroy(&dm->sf);CHKERRQ(ierr); 4758057b4bcdSMatthew G Knepley dm->sf = sf; 4759057b4bcdSMatthew G Knepley PetscFunctionReturn(0); 4760057b4bcdSMatthew G Knepley } 4761057b4bcdSMatthew G Knepley 47624f37162bSMatthew G. Knepley /*@ 47634f37162bSMatthew G. Knepley DMGetNaturalSF - Get the PetscSF encoding the map back to the original mesh ordering 47644f37162bSMatthew G. Knepley 47654f37162bSMatthew G. Knepley Input Parameter: 47664f37162bSMatthew G. Knepley . dm - The DM 47674f37162bSMatthew G. Knepley 47684f37162bSMatthew G. Knepley Output Parameter: 47694f37162bSMatthew G. Knepley . sf - The PetscSF 47704f37162bSMatthew G. Knepley 47714f37162bSMatthew G. Knepley Level: intermediate 47724f37162bSMatthew G. Knepley 47734f37162bSMatthew G. Knepley Note: This gets a borrowed reference, so the user should not destroy this PetscSF. 47744f37162bSMatthew G. Knepley 47754f37162bSMatthew G. Knepley .seealso: DMSetNaturalSF(), DMSetUseNatural(), DMGetUseNatural(), DMPlexCreateGlobalToNaturalSF(), DMPlexDistribute() 47764f37162bSMatthew G. Knepley @*/ 47774f37162bSMatthew G. Knepley PetscErrorCode DMGetNaturalSF(DM dm, PetscSF *sf) 47784f37162bSMatthew G. Knepley { 47794f37162bSMatthew G. Knepley PetscFunctionBegin; 47804f37162bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47814f37162bSMatthew G. Knepley PetscValidPointer(sf, 2); 47824f37162bSMatthew G. Knepley *sf = dm->sfNatural; 47834f37162bSMatthew G. Knepley PetscFunctionReturn(0); 47844f37162bSMatthew G. Knepley } 47854f37162bSMatthew G. Knepley 47864f37162bSMatthew G. Knepley /*@ 47874f37162bSMatthew G. Knepley DMSetNaturalSF - Set the PetscSF encoding the map back to the original mesh ordering 47884f37162bSMatthew G. Knepley 47894f37162bSMatthew G. Knepley Input Parameters: 47904f37162bSMatthew G. Knepley + dm - The DM 47914f37162bSMatthew G. Knepley - sf - The PetscSF 47924f37162bSMatthew G. Knepley 47934f37162bSMatthew G. Knepley Level: intermediate 47944f37162bSMatthew G. Knepley 47954f37162bSMatthew G. Knepley .seealso: DMGetNaturalSF(), DMSetUseNatural(), DMGetUseNatural(), DMPlexCreateGlobalToNaturalSF(), DMPlexDistribute() 47964f37162bSMatthew G. Knepley @*/ 47974f37162bSMatthew G. Knepley PetscErrorCode DMSetNaturalSF(DM dm, PetscSF sf) 47984f37162bSMatthew G. Knepley { 47994f37162bSMatthew G. Knepley PetscErrorCode ierr; 48004f37162bSMatthew G. Knepley 48014f37162bSMatthew G. Knepley PetscFunctionBegin; 48024f37162bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 48034f37162bSMatthew G. Knepley if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 48044f37162bSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr); 48054f37162bSMatthew G. Knepley ierr = PetscSFDestroy(&dm->sfNatural);CHKERRQ(ierr); 48064f37162bSMatthew G. Knepley dm->sfNatural = sf; 48074f37162bSMatthew G. Knepley PetscFunctionReturn(0); 48084f37162bSMatthew G. Knepley } 48094f37162bSMatthew G. Knepley 481034aa8a36SMatthew G. Knepley static PetscErrorCode DMSetDefaultAdjacency_Private(DM dm, PetscInt f, PetscObject disc) 481134aa8a36SMatthew G. Knepley { 481234aa8a36SMatthew G. Knepley PetscClassId id; 481334aa8a36SMatthew G. Knepley PetscErrorCode ierr; 481434aa8a36SMatthew G. Knepley 481534aa8a36SMatthew G. Knepley PetscFunctionBegin; 481634aa8a36SMatthew G. Knepley ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr); 481734aa8a36SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 481834aa8a36SMatthew G. Knepley ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr); 481934aa8a36SMatthew G. Knepley } else if (id == PETSCFV_CLASSID) { 482034aa8a36SMatthew G. Knepley ierr = DMSetAdjacency(dm, f, PETSC_TRUE, PETSC_FALSE);CHKERRQ(ierr); 482117c1d62eSMatthew G. Knepley } else { 482217c1d62eSMatthew G. Knepley ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr); 482334aa8a36SMatthew G. Knepley } 482434aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 482534aa8a36SMatthew G. Knepley } 482634aa8a36SMatthew G. Knepley 482744a7f3ddSMatthew G. Knepley static PetscErrorCode DMFieldEnlarge_Static(DM dm, PetscInt NfNew) 482844a7f3ddSMatthew G. Knepley { 482944a7f3ddSMatthew G. Knepley RegionField *tmpr; 483044a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf, f; 483144a7f3ddSMatthew G. Knepley PetscErrorCode ierr; 483244a7f3ddSMatthew G. Knepley 483344a7f3ddSMatthew G. Knepley PetscFunctionBegin; 483444a7f3ddSMatthew G. Knepley if (Nf >= NfNew) PetscFunctionReturn(0); 483544a7f3ddSMatthew G. Knepley ierr = PetscMalloc1(NfNew, &tmpr);CHKERRQ(ierr); 483644a7f3ddSMatthew G. Knepley for (f = 0; f < Nf; ++f) tmpr[f] = dm->fields[f]; 4837e0b68406SMatthew Knepley for (f = Nf; f < NfNew; ++f) {tmpr[f].disc = NULL; tmpr[f].label = NULL; tmpr[f].avoidTensor = PETSC_FALSE;} 483844a7f3ddSMatthew G. Knepley ierr = PetscFree(dm->fields);CHKERRQ(ierr); 483944a7f3ddSMatthew G. Knepley dm->Nf = NfNew; 484044a7f3ddSMatthew G. Knepley dm->fields = tmpr; 484144a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 484244a7f3ddSMatthew G. Knepley } 484344a7f3ddSMatthew G. Knepley 484444a7f3ddSMatthew G. Knepley /*@ 484544a7f3ddSMatthew G. Knepley DMClearFields - Remove all fields from the DM 484644a7f3ddSMatthew G. Knepley 4847d083f849SBarry Smith Logically collective on dm 484844a7f3ddSMatthew G. Knepley 484944a7f3ddSMatthew G. Knepley Input Parameter: 485044a7f3ddSMatthew G. Knepley . dm - The DM 485144a7f3ddSMatthew G. Knepley 485244a7f3ddSMatthew G. Knepley Level: intermediate 485344a7f3ddSMatthew G. Knepley 485444a7f3ddSMatthew G. Knepley .seealso: DMGetNumFields(), DMSetNumFields(), DMSetField() 485544a7f3ddSMatthew G. Knepley @*/ 485644a7f3ddSMatthew G. Knepley PetscErrorCode DMClearFields(DM dm) 485744a7f3ddSMatthew G. Knepley { 485844a7f3ddSMatthew G. Knepley PetscInt f; 485944a7f3ddSMatthew G. Knepley PetscErrorCode ierr; 486044a7f3ddSMatthew G. Knepley 486144a7f3ddSMatthew G. Knepley PetscFunctionBegin; 486244a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 486344a7f3ddSMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 486444a7f3ddSMatthew G. Knepley ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr); 486544a7f3ddSMatthew G. Knepley ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr); 486644a7f3ddSMatthew G. Knepley } 486744a7f3ddSMatthew G. Knepley ierr = PetscFree(dm->fields);CHKERRQ(ierr); 486844a7f3ddSMatthew G. Knepley dm->fields = NULL; 486944a7f3ddSMatthew G. Knepley dm->Nf = 0; 487044a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 487144a7f3ddSMatthew G. Knepley } 487244a7f3ddSMatthew G. Knepley 4873689b5837SMatthew G. Knepley /*@ 4874689b5837SMatthew G. Knepley DMGetNumFields - Get the number of fields in the DM 4875689b5837SMatthew G. Knepley 4876689b5837SMatthew G. Knepley Not collective 4877689b5837SMatthew G. Knepley 4878689b5837SMatthew G. Knepley Input Parameter: 4879689b5837SMatthew G. Knepley . dm - The DM 4880689b5837SMatthew G. Knepley 4881689b5837SMatthew G. Knepley Output Parameter: 4882689b5837SMatthew G. Knepley . Nf - The number of fields 4883689b5837SMatthew G. Knepley 4884689b5837SMatthew G. Knepley Level: intermediate 4885689b5837SMatthew G. Knepley 4886689b5837SMatthew G. Knepley .seealso: DMSetNumFields(), DMSetField() 4887689b5837SMatthew G. Knepley @*/ 48880f21e855SMatthew G. Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields) 48890f21e855SMatthew G. Knepley { 48900f21e855SMatthew G. Knepley PetscFunctionBegin; 48910f21e855SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4892534a8f05SLisandro Dalcin PetscValidIntPointer(numFields, 2); 489344a7f3ddSMatthew G. Knepley *numFields = dm->Nf; 4894af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4895af122d2aSMatthew G Knepley } 4896af122d2aSMatthew G Knepley 4897689b5837SMatthew G. Knepley /*@ 4898689b5837SMatthew G. Knepley DMSetNumFields - Set the number of fields in the DM 4899689b5837SMatthew G. Knepley 4900d083f849SBarry Smith Logically collective on dm 4901689b5837SMatthew G. Knepley 4902689b5837SMatthew G. Knepley Input Parameters: 4903689b5837SMatthew G. Knepley + dm - The DM 4904689b5837SMatthew G. Knepley - Nf - The number of fields 4905689b5837SMatthew G. Knepley 4906689b5837SMatthew G. Knepley Level: intermediate 4907689b5837SMatthew G. Knepley 4908689b5837SMatthew G. Knepley .seealso: DMGetNumFields(), DMSetField() 4909689b5837SMatthew G. Knepley @*/ 4910af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields) 4911af122d2aSMatthew G Knepley { 49120f21e855SMatthew G. Knepley PetscInt Nf, f; 4913af122d2aSMatthew G Knepley PetscErrorCode ierr; 4914af122d2aSMatthew G Knepley 4915af122d2aSMatthew G Knepley PetscFunctionBegin; 4916af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 491744a7f3ddSMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 49180f21e855SMatthew G. Knepley for (f = Nf; f < numFields; ++f) { 49190f21e855SMatthew G. Knepley PetscContainer obj; 49200f21e855SMatthew G. Knepley 49210f21e855SMatthew G. Knepley ierr = PetscContainerCreate(PetscObjectComm((PetscObject) dm), &obj);CHKERRQ(ierr); 492244a7f3ddSMatthew G. Knepley ierr = DMAddField(dm, NULL, (PetscObject) obj);CHKERRQ(ierr); 49230f21e855SMatthew G. Knepley ierr = PetscContainerDestroy(&obj);CHKERRQ(ierr); 4924af122d2aSMatthew G Knepley } 4925af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4926af122d2aSMatthew G Knepley } 4927af122d2aSMatthew G Knepley 4928c1929be8SMatthew G. Knepley /*@ 4929c1929be8SMatthew G. Knepley DMGetField - Return the discretization object for a given DM field 4930c1929be8SMatthew G. Knepley 4931c1929be8SMatthew G. Knepley Not collective 4932c1929be8SMatthew G. Knepley 4933c1929be8SMatthew G. Knepley Input Parameters: 4934c1929be8SMatthew G. Knepley + dm - The DM 4935c1929be8SMatthew G. Knepley - f - The field number 4936c1929be8SMatthew G. Knepley 493744a7f3ddSMatthew G. Knepley Output Parameters: 493844a7f3ddSMatthew G. Knepley + label - The label indicating the support of the field, or NULL for the entire mesh 493944a7f3ddSMatthew G. Knepley - field - The discretization object 4940c1929be8SMatthew G. Knepley 494144a7f3ddSMatthew G. Knepley Level: intermediate 4942c1929be8SMatthew G. Knepley 494344a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMSetField() 4944c1929be8SMatthew G. Knepley @*/ 494544a7f3ddSMatthew G. Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, DMLabel *label, PetscObject *field) 4946af122d2aSMatthew G Knepley { 4947af122d2aSMatthew G Knepley PetscFunctionBegin; 4948af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4949064a246eSJacob Faibussowitsch PetscValidPointer(field, 4); 495044a7f3ddSMatthew 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); 495144a7f3ddSMatthew G. Knepley if (label) *label = dm->fields[f].label; 495244a7f3ddSMatthew G. Knepley if (field) *field = dm->fields[f].disc; 4953decb47aaSMatthew G. Knepley PetscFunctionReturn(0); 4954decb47aaSMatthew G. Knepley } 4955decb47aaSMatthew G. Knepley 4956083401c6SMatthew G. Knepley /* Does not clear the DS */ 4957083401c6SMatthew G. Knepley PetscErrorCode DMSetField_Internal(DM dm, PetscInt f, DMLabel label, PetscObject field) 4958083401c6SMatthew G. Knepley { 4959083401c6SMatthew G. Knepley PetscErrorCode ierr; 4960083401c6SMatthew G. Knepley 4961083401c6SMatthew G. Knepley PetscFunctionBegin; 4962083401c6SMatthew G. Knepley ierr = DMFieldEnlarge_Static(dm, f+1);CHKERRQ(ierr); 4963083401c6SMatthew G. Knepley ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr); 4964083401c6SMatthew G. Knepley ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr); 4965083401c6SMatthew G. Knepley dm->fields[f].label = label; 4966083401c6SMatthew G. Knepley dm->fields[f].disc = field; 4967083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 4968083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr); 4969083401c6SMatthew G. Knepley PetscFunctionReturn(0); 4970083401c6SMatthew G. Knepley } 4971083401c6SMatthew G. Knepley 4972c1929be8SMatthew G. Knepley /*@ 4973c1929be8SMatthew G. Knepley DMSetField - Set the discretization object for a given DM field 4974c1929be8SMatthew G. Knepley 4975d083f849SBarry Smith Logically collective on dm 4976c1929be8SMatthew G. Knepley 4977c1929be8SMatthew G. Knepley Input Parameters: 4978c1929be8SMatthew G. Knepley + dm - The DM 4979c1929be8SMatthew G. Knepley . f - The field number 498044a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh 4981c1929be8SMatthew G. Knepley - field - The discretization object 4982c1929be8SMatthew G. Knepley 498344a7f3ddSMatthew G. Knepley Level: intermediate 4984c1929be8SMatthew G. Knepley 498544a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMGetField() 4986c1929be8SMatthew G. Knepley @*/ 498744a7f3ddSMatthew G. Knepley PetscErrorCode DMSetField(DM dm, PetscInt f, DMLabel label, PetscObject field) 4988decb47aaSMatthew G. Knepley { 4989decb47aaSMatthew G. Knepley PetscErrorCode ierr; 4990decb47aaSMatthew G. Knepley 4991decb47aaSMatthew G. Knepley PetscFunctionBegin; 4992decb47aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4993e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 499444a7f3ddSMatthew G. Knepley PetscValidHeader(field, 4); 4995e5e52638SMatthew G. Knepley if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f); 4996083401c6SMatthew G. Knepley ierr = DMSetField_Internal(dm, f, label, field);CHKERRQ(ierr); 499734aa8a36SMatthew G. Knepley ierr = DMSetDefaultAdjacency_Private(dm, f, field);CHKERRQ(ierr); 49982df9ee95SMatthew G. Knepley ierr = DMClearDS(dm);CHKERRQ(ierr); 499944a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 500044a7f3ddSMatthew G. Knepley } 500144a7f3ddSMatthew G. Knepley 500244a7f3ddSMatthew G. Knepley /*@ 500344a7f3ddSMatthew G. Knepley DMAddField - Add the discretization object for the given DM field 500444a7f3ddSMatthew G. Knepley 5005d083f849SBarry Smith Logically collective on dm 500644a7f3ddSMatthew G. Knepley 500744a7f3ddSMatthew G. Knepley Input Parameters: 500844a7f3ddSMatthew G. Knepley + dm - The DM 500944a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh 501044a7f3ddSMatthew G. Knepley - field - The discretization object 501144a7f3ddSMatthew G. Knepley 501244a7f3ddSMatthew G. Knepley Level: intermediate 501344a7f3ddSMatthew G. Knepley 501444a7f3ddSMatthew G. Knepley .seealso: DMSetField(), DMGetField() 501544a7f3ddSMatthew G. Knepley @*/ 501644a7f3ddSMatthew G. Knepley PetscErrorCode DMAddField(DM dm, DMLabel label, PetscObject field) 501744a7f3ddSMatthew G. Knepley { 501844a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf; 501944a7f3ddSMatthew G. Knepley PetscErrorCode ierr; 502044a7f3ddSMatthew G. Knepley 502144a7f3ddSMatthew G. Knepley PetscFunctionBegin; 502244a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5023064a246eSJacob Faibussowitsch if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 502444a7f3ddSMatthew G. Knepley PetscValidHeader(field, 3); 502544a7f3ddSMatthew G. Knepley ierr = DMFieldEnlarge_Static(dm, Nf+1);CHKERRQ(ierr); 502644a7f3ddSMatthew G. Knepley dm->fields[Nf].label = label; 502744a7f3ddSMatthew G. Knepley dm->fields[Nf].disc = field; 502844a7f3ddSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 502944a7f3ddSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr); 503034aa8a36SMatthew G. Knepley ierr = DMSetDefaultAdjacency_Private(dm, Nf, field);CHKERRQ(ierr); 50312df9ee95SMatthew G. Knepley ierr = DMClearDS(dm);CHKERRQ(ierr); 5032af122d2aSMatthew G Knepley PetscFunctionReturn(0); 5033af122d2aSMatthew G Knepley } 50346636e97aSMatthew G Knepley 5035e5e52638SMatthew G. Knepley /*@ 5036e0b68406SMatthew Knepley DMSetFieldAvoidTensor - Set flag to avoid defining the field on tensor cells 5037e0b68406SMatthew Knepley 5038e0b68406SMatthew Knepley Logically collective on dm 5039e0b68406SMatthew Knepley 5040e0b68406SMatthew Knepley Input Parameters: 5041e0b68406SMatthew Knepley + dm - The DM 5042e0b68406SMatthew Knepley . f - The field index 5043e0b68406SMatthew Knepley - avoidTensor - The flag to avoid defining the field on tensor cells 5044e0b68406SMatthew Knepley 5045e0b68406SMatthew Knepley Level: intermediate 5046e0b68406SMatthew Knepley 5047e0b68406SMatthew Knepley .seealso: DMGetFieldAvoidTensor(), DMSetField(), DMGetField() 5048e0b68406SMatthew Knepley @*/ 5049e0b68406SMatthew Knepley PetscErrorCode DMSetFieldAvoidTensor(DM dm, PetscInt f, PetscBool avoidTensor) 5050e0b68406SMatthew Knepley { 5051e0b68406SMatthew Knepley PetscFunctionBegin; 5052e0b68406SMatthew 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); 5053e0b68406SMatthew Knepley dm->fields[f].avoidTensor = avoidTensor; 5054e0b68406SMatthew Knepley PetscFunctionReturn(0); 5055e0b68406SMatthew Knepley } 5056e0b68406SMatthew Knepley 5057e0b68406SMatthew Knepley /*@ 5058e0b68406SMatthew Knepley DMGetFieldAvoidTensor - Get flag to avoid defining the field on tensor cells 5059e0b68406SMatthew Knepley 5060e0b68406SMatthew Knepley Logically collective on dm 5061e0b68406SMatthew Knepley 5062e0b68406SMatthew Knepley Input Parameters: 5063e0b68406SMatthew Knepley + dm - The DM 5064e0b68406SMatthew Knepley - f - The field index 5065e0b68406SMatthew Knepley 5066e0b68406SMatthew Knepley Output Parameter: 5067e0b68406SMatthew Knepley . avoidTensor - The flag to avoid defining the field on tensor cells 5068e0b68406SMatthew Knepley 5069e0b68406SMatthew Knepley Level: intermediate 5070e0b68406SMatthew Knepley 5071e0b68406SMatthew Knepley .seealso: DMSetFieldAvoidTensor(), DMSetField(), DMGetField() 5072e0b68406SMatthew Knepley @*/ 5073e0b68406SMatthew Knepley PetscErrorCode DMGetFieldAvoidTensor(DM dm, PetscInt f, PetscBool *avoidTensor) 5074e0b68406SMatthew Knepley { 5075e0b68406SMatthew Knepley PetscFunctionBegin; 5076e0b68406SMatthew 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); 5077e0b68406SMatthew Knepley *avoidTensor = dm->fields[f].avoidTensor; 5078e0b68406SMatthew Knepley PetscFunctionReturn(0); 5079e0b68406SMatthew Knepley } 5080e0b68406SMatthew Knepley 5081e0b68406SMatthew Knepley /*@ 5082e5e52638SMatthew G. Knepley DMCopyFields - Copy the discretizations for the DM into another DM 5083e5e52638SMatthew G. Knepley 5084d083f849SBarry Smith Collective on dm 5085e5e52638SMatthew G. Knepley 5086e5e52638SMatthew G. Knepley Input Parameter: 5087e5e52638SMatthew G. Knepley . dm - The DM 5088e5e52638SMatthew G. Knepley 5089e5e52638SMatthew G. Knepley Output Parameter: 5090e5e52638SMatthew G. Knepley . newdm - The DM 5091e5e52638SMatthew G. Knepley 5092e5e52638SMatthew G. Knepley Level: advanced 5093e5e52638SMatthew G. Knepley 5094e5e52638SMatthew G. Knepley .seealso: DMGetField(), DMSetField(), DMAddField(), DMCopyDS(), DMGetDS(), DMGetCellDS() 5095e5e52638SMatthew G. Knepley @*/ 5096e5e52638SMatthew G. Knepley PetscErrorCode DMCopyFields(DM dm, DM newdm) 5097e5e52638SMatthew G. Knepley { 5098e5e52638SMatthew G. Knepley PetscInt Nf, f; 5099e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5100e5e52638SMatthew G. Knepley 5101e5e52638SMatthew G. Knepley PetscFunctionBegin; 5102e5e52638SMatthew G. Knepley if (dm == newdm) PetscFunctionReturn(0); 5103e5e52638SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 5104e5e52638SMatthew G. Knepley ierr = DMClearFields(newdm);CHKERRQ(ierr); 5105e5e52638SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5106e5e52638SMatthew G. Knepley DMLabel label; 5107e5e52638SMatthew G. Knepley PetscObject field; 510834aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 5109e5e52638SMatthew G. Knepley 5110e5e52638SMatthew G. Knepley ierr = DMGetField(dm, f, &label, &field);CHKERRQ(ierr); 5111e5e52638SMatthew G. Knepley ierr = DMSetField(newdm, f, label, field);CHKERRQ(ierr); 511234aa8a36SMatthew G. Knepley ierr = DMGetAdjacency(dm, f, &useCone, &useClosure);CHKERRQ(ierr); 511334aa8a36SMatthew G. Knepley ierr = DMSetAdjacency(newdm, f, useCone, useClosure);CHKERRQ(ierr); 511434aa8a36SMatthew G. Knepley } 511534aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 511634aa8a36SMatthew G. Knepley } 511734aa8a36SMatthew G. Knepley 511834aa8a36SMatthew G. Knepley /*@ 511934aa8a36SMatthew G. Knepley DMGetAdjacency - Returns the flags for determining variable influence 512034aa8a36SMatthew G. Knepley 512134aa8a36SMatthew G. Knepley Not collective 512234aa8a36SMatthew G. Knepley 512334aa8a36SMatthew G. Knepley Input Parameters: 512434aa8a36SMatthew G. Knepley + dm - The DM object 512534aa8a36SMatthew G. Knepley - f - The field number, or PETSC_DEFAULT for the default adjacency 512634aa8a36SMatthew G. Knepley 5127d8d19677SJose E. Roman Output Parameters: 512834aa8a36SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 512934aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 513034aa8a36SMatthew G. Knepley 513134aa8a36SMatthew G. Knepley Notes: 513234aa8a36SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 513334aa8a36SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 513434aa8a36SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5135979e053dSMatthew G. Knepley Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 513634aa8a36SMatthew G. Knepley 513734aa8a36SMatthew G. Knepley Level: developer 513834aa8a36SMatthew G. Knepley 513934aa8a36SMatthew G. Knepley .seealso: DMSetAdjacency(), DMGetField(), DMSetField() 514034aa8a36SMatthew G. Knepley @*/ 514134aa8a36SMatthew G. Knepley PetscErrorCode DMGetAdjacency(DM dm, PetscInt f, PetscBool *useCone, PetscBool *useClosure) 514234aa8a36SMatthew G. Knepley { 514334aa8a36SMatthew G. Knepley PetscFunctionBegin; 514434aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5145534a8f05SLisandro Dalcin if (useCone) PetscValidBoolPointer(useCone, 3); 5146534a8f05SLisandro Dalcin if (useClosure) PetscValidBoolPointer(useClosure, 4); 514734aa8a36SMatthew G. Knepley if (f < 0) { 514834aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->adjacency[0]; 514934aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->adjacency[1]; 515034aa8a36SMatthew G. Knepley } else { 515134aa8a36SMatthew G. Knepley PetscInt Nf; 515234aa8a36SMatthew G. Knepley PetscErrorCode ierr; 515334aa8a36SMatthew G. Knepley 515434aa8a36SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 515534aa8a36SMatthew G. Knepley if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf); 515634aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->fields[f].adjacency[0]; 515734aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->fields[f].adjacency[1]; 515834aa8a36SMatthew G. Knepley } 515934aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 516034aa8a36SMatthew G. Knepley } 516134aa8a36SMatthew G. Knepley 516234aa8a36SMatthew G. Knepley /*@ 516334aa8a36SMatthew G. Knepley DMSetAdjacency - Set the flags for determining variable influence 516434aa8a36SMatthew G. Knepley 516534aa8a36SMatthew G. Knepley Not collective 516634aa8a36SMatthew G. Knepley 516734aa8a36SMatthew G. Knepley Input Parameters: 516834aa8a36SMatthew G. Knepley + dm - The DM object 516934aa8a36SMatthew G. Knepley . f - The field number 517034aa8a36SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 517134aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 517234aa8a36SMatthew G. Knepley 517334aa8a36SMatthew G. Knepley Notes: 517434aa8a36SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 517534aa8a36SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 517634aa8a36SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5177979e053dSMatthew G. Knepley Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 517834aa8a36SMatthew G. Knepley 517934aa8a36SMatthew G. Knepley Level: developer 518034aa8a36SMatthew G. Knepley 518134aa8a36SMatthew G. Knepley .seealso: DMGetAdjacency(), DMGetField(), DMSetField() 518234aa8a36SMatthew G. Knepley @*/ 518334aa8a36SMatthew G. Knepley PetscErrorCode DMSetAdjacency(DM dm, PetscInt f, PetscBool useCone, PetscBool useClosure) 518434aa8a36SMatthew G. Knepley { 518534aa8a36SMatthew G. Knepley PetscFunctionBegin; 518634aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 518734aa8a36SMatthew G. Knepley if (f < 0) { 518834aa8a36SMatthew G. Knepley dm->adjacency[0] = useCone; 518934aa8a36SMatthew G. Knepley dm->adjacency[1] = useClosure; 519034aa8a36SMatthew G. Knepley } else { 519134aa8a36SMatthew G. Knepley PetscInt Nf; 519234aa8a36SMatthew G. Knepley PetscErrorCode ierr; 519334aa8a36SMatthew G. Knepley 519434aa8a36SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 519534aa8a36SMatthew G. Knepley if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf); 519634aa8a36SMatthew G. Knepley dm->fields[f].adjacency[0] = useCone; 519734aa8a36SMatthew G. Knepley dm->fields[f].adjacency[1] = useClosure; 5198e5e52638SMatthew G. Knepley } 5199e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5200e5e52638SMatthew G. Knepley } 5201e5e52638SMatthew G. Knepley 5202b0441da4SMatthew G. Knepley /*@ 5203b0441da4SMatthew G. Knepley DMGetBasicAdjacency - Returns the flags for determining variable influence, using either the default or field 0 if it is defined 5204b0441da4SMatthew G. Knepley 5205b0441da4SMatthew G. Knepley Not collective 5206b0441da4SMatthew G. Knepley 5207f899ff85SJose E. Roman Input Parameter: 5208b0441da4SMatthew G. Knepley . dm - The DM object 5209b0441da4SMatthew G. Knepley 5210d8d19677SJose E. Roman Output Parameters: 5211b0441da4SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 5212b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5213b0441da4SMatthew G. Knepley 5214b0441da4SMatthew G. Knepley Notes: 5215b0441da4SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 5216b0441da4SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 5217b0441da4SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5218b0441da4SMatthew G. Knepley 5219b0441da4SMatthew G. Knepley Level: developer 5220b0441da4SMatthew G. Knepley 5221b0441da4SMatthew G. Knepley .seealso: DMSetBasicAdjacency(), DMGetField(), DMSetField() 5222b0441da4SMatthew G. Knepley @*/ 5223b0441da4SMatthew G. Knepley PetscErrorCode DMGetBasicAdjacency(DM dm, PetscBool *useCone, PetscBool *useClosure) 5224b0441da4SMatthew G. Knepley { 5225b0441da4SMatthew G. Knepley PetscInt Nf; 5226b0441da4SMatthew G. Knepley PetscErrorCode ierr; 5227b0441da4SMatthew G. Knepley 5228b0441da4SMatthew G. Knepley PetscFunctionBegin; 5229b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5230064a246eSJacob Faibussowitsch if (useCone) PetscValidBoolPointer(useCone, 2); 5231064a246eSJacob Faibussowitsch if (useClosure) PetscValidBoolPointer(useClosure, 3); 5232b0441da4SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 5233b0441da4SMatthew G. Knepley if (!Nf) { 5234b0441da4SMatthew G. Knepley ierr = DMGetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr); 5235b0441da4SMatthew G. Knepley } else { 5236b0441da4SMatthew G. Knepley ierr = DMGetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr); 5237b0441da4SMatthew G. Knepley } 5238b0441da4SMatthew G. Knepley PetscFunctionReturn(0); 5239b0441da4SMatthew G. Knepley } 5240b0441da4SMatthew G. Knepley 5241b0441da4SMatthew G. Knepley /*@ 5242b0441da4SMatthew G. Knepley DMSetBasicAdjacency - Set the flags for determining variable influence, using either the default or field 0 if it is defined 5243b0441da4SMatthew G. Knepley 5244b0441da4SMatthew G. Knepley Not collective 5245b0441da4SMatthew G. Knepley 5246b0441da4SMatthew G. Knepley Input Parameters: 5247b0441da4SMatthew G. Knepley + dm - The DM object 5248b0441da4SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 5249b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5250b0441da4SMatthew G. Knepley 5251b0441da4SMatthew G. Knepley Notes: 5252b0441da4SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 5253b0441da4SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 5254b0441da4SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5255b0441da4SMatthew G. Knepley 5256b0441da4SMatthew G. Knepley Level: developer 5257b0441da4SMatthew G. Knepley 5258b0441da4SMatthew G. Knepley .seealso: DMGetBasicAdjacency(), DMGetField(), DMSetField() 5259b0441da4SMatthew G. Knepley @*/ 5260b0441da4SMatthew G. Knepley PetscErrorCode DMSetBasicAdjacency(DM dm, PetscBool useCone, PetscBool useClosure) 5261b0441da4SMatthew G. Knepley { 5262b0441da4SMatthew G. Knepley PetscInt Nf; 5263b0441da4SMatthew G. Knepley PetscErrorCode ierr; 5264b0441da4SMatthew G. Knepley 5265b0441da4SMatthew G. Knepley PetscFunctionBegin; 5266b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5267b0441da4SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 5268b0441da4SMatthew G. Knepley if (!Nf) { 5269b0441da4SMatthew G. Knepley ierr = DMSetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr); 5270b0441da4SMatthew G. Knepley } else { 5271b0441da4SMatthew G. Knepley ierr = DMSetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr); 5272e5e52638SMatthew G. Knepley } 5273e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5274e5e52638SMatthew G. Knepley } 5275e5e52638SMatthew G. Knepley 5276783e2ec8SMatthew G. Knepley /* Complete labels that are being used for FEM BC */ 527745480ffeSMatthew G. Knepley static PetscErrorCode DMCompleteBoundaryLabel_Internal(DM dm, PetscDS ds, PetscInt field, PetscInt bdNum, DMLabel label) 5278783e2ec8SMatthew G. Knepley { 5279783e2ec8SMatthew G. Knepley PetscObject obj; 5280783e2ec8SMatthew G. Knepley PetscClassId id; 5281783e2ec8SMatthew G. Knepley PetscInt Nbd, bd; 5282783e2ec8SMatthew G. Knepley PetscBool isFE = PETSC_FALSE; 5283783e2ec8SMatthew G. Knepley PetscBool duplicate = PETSC_FALSE; 5284783e2ec8SMatthew G. Knepley PetscErrorCode ierr; 5285783e2ec8SMatthew G. Knepley 5286783e2ec8SMatthew G. Knepley PetscFunctionBegin; 5287783e2ec8SMatthew G. Knepley ierr = DMGetField(dm, field, NULL, &obj);CHKERRQ(ierr); 5288783e2ec8SMatthew G. Knepley ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 5289783e2ec8SMatthew G. Knepley if (id == PETSCFE_CLASSID) isFE = PETSC_TRUE; 5290783e2ec8SMatthew G. Knepley if (isFE && label) { 5291783e2ec8SMatthew G. Knepley /* Only want to modify label once */ 5292783e2ec8SMatthew G. Knepley ierr = PetscDSGetNumBoundary(ds, &Nbd);CHKERRQ(ierr); 5293783e2ec8SMatthew G. Knepley for (bd = 0; bd < PetscMin(Nbd, bdNum); ++bd) { 529445480ffeSMatthew G. Knepley DMLabel l; 5295783e2ec8SMatthew G. Knepley 529645480ffeSMatthew G. Knepley ierr = PetscDSGetBoundary(ds, bd, NULL, NULL, NULL, &l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 529745480ffeSMatthew G. Knepley duplicate = l == label ? PETSC_TRUE : PETSC_FALSE; 5298783e2ec8SMatthew G. Knepley if (duplicate) break; 5299783e2ec8SMatthew G. Knepley } 5300783e2ec8SMatthew G. Knepley if (!duplicate) { 5301783e2ec8SMatthew G. Knepley DM plex; 5302783e2ec8SMatthew G. Knepley 5303783e2ec8SMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 5304783e2ec8SMatthew G. Knepley if (plex) {ierr = DMPlexLabelComplete(plex, label);CHKERRQ(ierr);} 5305783e2ec8SMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 5306783e2ec8SMatthew G. Knepley } 5307783e2ec8SMatthew G. Knepley } 5308783e2ec8SMatthew G. Knepley PetscFunctionReturn(0); 5309783e2ec8SMatthew G. Knepley } 5310783e2ec8SMatthew G. Knepley 5311e5e52638SMatthew G. Knepley static PetscErrorCode DMDSEnlarge_Static(DM dm, PetscInt NdsNew) 5312e5e52638SMatthew G. Knepley { 5313e5e52638SMatthew G. Knepley DMSpace *tmpd; 5314e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5315e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5316e5e52638SMatthew G. Knepley 5317e5e52638SMatthew G. Knepley PetscFunctionBegin; 5318e5e52638SMatthew G. Knepley if (Nds >= NdsNew) PetscFunctionReturn(0); 5319e5e52638SMatthew G. Knepley ierr = PetscMalloc1(NdsNew, &tmpd);CHKERRQ(ierr); 5320e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) tmpd[s] = dm->probs[s]; 5321b3cf3223SMatthew G. Knepley for (s = Nds; s < NdsNew; ++s) {tmpd[s].ds = NULL; tmpd[s].label = NULL; tmpd[s].fields = NULL;} 5322e5e52638SMatthew G. Knepley ierr = PetscFree(dm->probs);CHKERRQ(ierr); 5323e5e52638SMatthew G. Knepley dm->Nds = NdsNew; 5324e5e52638SMatthew G. Knepley dm->probs = tmpd; 5325e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5326e5e52638SMatthew G. Knepley } 5327e5e52638SMatthew G. Knepley 5328e5e52638SMatthew G. Knepley /*@ 5329e5e52638SMatthew G. Knepley DMGetNumDS - Get the number of discrete systems in the DM 5330e5e52638SMatthew G. Knepley 5331e5e52638SMatthew G. Knepley Not collective 5332e5e52638SMatthew G. Knepley 5333e5e52638SMatthew G. Knepley Input Parameter: 5334e5e52638SMatthew G. Knepley . dm - The DM 5335e5e52638SMatthew G. Knepley 5336e5e52638SMatthew G. Knepley Output Parameter: 5337e5e52638SMatthew G. Knepley . Nds - The number of PetscDS objects 5338e5e52638SMatthew G. Knepley 5339e5e52638SMatthew G. Knepley Level: intermediate 5340e5e52638SMatthew G. Knepley 5341e5e52638SMatthew G. Knepley .seealso: DMGetDS(), DMGetCellDS() 5342e5e52638SMatthew G. Knepley @*/ 5343e5e52638SMatthew G. Knepley PetscErrorCode DMGetNumDS(DM dm, PetscInt *Nds) 5344e5e52638SMatthew G. Knepley { 5345e5e52638SMatthew G. Knepley PetscFunctionBegin; 5346e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5347534a8f05SLisandro Dalcin PetscValidIntPointer(Nds, 2); 5348e5e52638SMatthew G. Knepley *Nds = dm->Nds; 5349e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5350e5e52638SMatthew G. Knepley } 5351e5e52638SMatthew G. Knepley 5352e5e52638SMatthew G. Knepley /*@ 5353e5e52638SMatthew G. Knepley DMClearDS - Remove all discrete systems from the DM 5354e5e52638SMatthew G. Knepley 5355d083f849SBarry Smith Logically collective on dm 5356e5e52638SMatthew G. Knepley 5357e5e52638SMatthew G. Knepley Input Parameter: 5358e5e52638SMatthew G. Knepley . dm - The DM 5359e5e52638SMatthew G. Knepley 5360e5e52638SMatthew G. Knepley Level: intermediate 5361e5e52638SMatthew G. Knepley 5362e5e52638SMatthew G. Knepley .seealso: DMGetNumDS(), DMGetDS(), DMSetField() 5363e5e52638SMatthew G. Knepley @*/ 5364e5e52638SMatthew G. Knepley PetscErrorCode DMClearDS(DM dm) 5365e5e52638SMatthew G. Knepley { 5366e5e52638SMatthew G. Knepley PetscInt s; 5367e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5368e5e52638SMatthew G. Knepley 5369e5e52638SMatthew G. Knepley PetscFunctionBegin; 5370e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5371e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5372e5e52638SMatthew G. Knepley ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr); 5373e5e52638SMatthew G. Knepley ierr = DMLabelDestroy(&dm->probs[s].label);CHKERRQ(ierr); 5374b3cf3223SMatthew G. Knepley ierr = ISDestroy(&dm->probs[s].fields);CHKERRQ(ierr); 5375e5e52638SMatthew G. Knepley } 5376e5e52638SMatthew G. Knepley ierr = PetscFree(dm->probs);CHKERRQ(ierr); 5377e5e52638SMatthew G. Knepley dm->probs = NULL; 5378e5e52638SMatthew G. Knepley dm->Nds = 0; 5379e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5380e5e52638SMatthew G. Knepley } 5381e5e52638SMatthew G. Knepley 5382e5e52638SMatthew G. Knepley /*@ 5383e5e52638SMatthew G. Knepley DMGetDS - Get the default PetscDS 5384e5e52638SMatthew G. Knepley 5385e5e52638SMatthew G. Knepley Not collective 5386e5e52638SMatthew G. Knepley 5387e5e52638SMatthew G. Knepley Input Parameter: 5388e5e52638SMatthew G. Knepley . dm - The DM 5389e5e52638SMatthew G. Knepley 5390e5e52638SMatthew G. Knepley Output Parameter: 5391e5e52638SMatthew G. Knepley . prob - The default PetscDS 5392e5e52638SMatthew G. Knepley 5393e5e52638SMatthew G. Knepley Level: intermediate 5394e5e52638SMatthew G. Knepley 5395e5e52638SMatthew G. Knepley .seealso: DMGetCellDS(), DMGetRegionDS() 5396e5e52638SMatthew G. Knepley @*/ 5397e5e52638SMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *prob) 5398e5e52638SMatthew G. Knepley { 5399b0143b4dSMatthew G. Knepley PetscErrorCode ierr; 5400b0143b4dSMatthew G. Knepley 5401e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5402e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5403e5e52638SMatthew G. Knepley PetscValidPointer(prob, 2); 5404b0143b4dSMatthew G. Knepley if (dm->Nds <= 0) { 5405b0143b4dSMatthew G. Knepley PetscDS ds; 5406b0143b4dSMatthew G. Knepley 540745480ffeSMatthew G. Knepley ierr = PetscDSCreate(PETSC_COMM_SELF, &ds);CHKERRQ(ierr); 5408b3cf3223SMatthew G. Knepley ierr = DMSetRegionDS(dm, NULL, NULL, ds);CHKERRQ(ierr); 5409b0143b4dSMatthew G. Knepley ierr = PetscDSDestroy(&ds);CHKERRQ(ierr); 5410b0143b4dSMatthew G. Knepley } 5411b0143b4dSMatthew G. Knepley *prob = dm->probs[0].ds; 5412e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5413e5e52638SMatthew G. Knepley } 5414e5e52638SMatthew G. Knepley 5415e5e52638SMatthew G. Knepley /*@ 5416e5e52638SMatthew G. Knepley DMGetCellDS - Get the PetscDS defined on a given cell 5417e5e52638SMatthew G. Knepley 5418e5e52638SMatthew G. Knepley Not collective 5419e5e52638SMatthew G. Knepley 5420e5e52638SMatthew G. Knepley Input Parameters: 5421e5e52638SMatthew G. Knepley + dm - The DM 5422e5e52638SMatthew G. Knepley - point - Cell for the DS 5423e5e52638SMatthew G. Knepley 5424e5e52638SMatthew G. Knepley Output Parameter: 5425e5e52638SMatthew G. Knepley . prob - The PetscDS defined on the given cell 5426e5e52638SMatthew G. Knepley 5427e5e52638SMatthew G. Knepley Level: developer 5428e5e52638SMatthew G. Knepley 5429b0143b4dSMatthew G. Knepley .seealso: DMGetDS(), DMSetRegionDS() 5430e5e52638SMatthew G. Knepley @*/ 5431e5e52638SMatthew G. Knepley PetscErrorCode DMGetCellDS(DM dm, PetscInt point, PetscDS *prob) 5432e5e52638SMatthew G. Knepley { 5433e5e52638SMatthew G. Knepley PetscDS probDef = NULL; 5434e5e52638SMatthew G. Knepley PetscInt s; 5435e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5436e5e52638SMatthew G. Knepley 5437e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5438e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5439e5e52638SMatthew G. Knepley PetscValidPointer(prob, 3); 5440360cf244SMatthew G. Knepley if (point < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Mesh point cannot be negative: %D", point); 5441e5e52638SMatthew G. Knepley *prob = NULL; 5442e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5443e5e52638SMatthew G. Knepley PetscInt val; 5444e5e52638SMatthew G. Knepley 5445e5e52638SMatthew G. Knepley if (!dm->probs[s].label) {probDef = dm->probs[s].ds;} 5446e5e52638SMatthew G. Knepley else { 5447e5e52638SMatthew G. Knepley ierr = DMLabelGetValue(dm->probs[s].label, point, &val);CHKERRQ(ierr); 5448e5e52638SMatthew G. Knepley if (val >= 0) {*prob = dm->probs[s].ds; break;} 5449e5e52638SMatthew G. Knepley } 5450e5e52638SMatthew G. Knepley } 5451e5e52638SMatthew G. Knepley if (!*prob) *prob = probDef; 5452e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5453e5e52638SMatthew G. Knepley } 5454e5e52638SMatthew G. Knepley 5455e5e52638SMatthew G. Knepley /*@ 5456e5e52638SMatthew G. Knepley DMGetRegionDS - Get the PetscDS for a given mesh region, defined by a DMLabel 5457e5e52638SMatthew G. Knepley 5458e5e52638SMatthew G. Knepley Not collective 5459e5e52638SMatthew G. Knepley 5460e5e52638SMatthew G. Knepley Input Parameters: 5461e5e52638SMatthew G. Knepley + dm - The DM 5462e5e52638SMatthew G. Knepley - label - The DMLabel defining the mesh region, or NULL for the entire mesh 5463e5e52638SMatthew G. Knepley 5464b3cf3223SMatthew G. Knepley Output Parameters: 5465b3cf3223SMatthew G. Knepley + fields - The IS containing the DM field numbers for the fields in this DS, or NULL 5466b3cf3223SMatthew G. Knepley - prob - The PetscDS defined on the given region, or NULL 5467e5e52638SMatthew G. Knepley 5468e5e52638SMatthew G. Knepley Note: If the label is missing, this function returns an error 5469e5e52638SMatthew G. Knepley 5470e5e52638SMatthew G. Knepley Level: advanced 5471e5e52638SMatthew G. Knepley 5472e5e52638SMatthew G. Knepley .seealso: DMGetRegionNumDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS() 5473e5e52638SMatthew G. Knepley @*/ 5474b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionDS(DM dm, DMLabel label, IS *fields, PetscDS *ds) 5475e5e52638SMatthew G. Knepley { 5476e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5477e5e52638SMatthew G. Knepley 5478e5e52638SMatthew G. Knepley PetscFunctionBegin; 5479e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5480e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5481b3cf3223SMatthew G. Knepley if (fields) {PetscValidPointer(fields, 3); *fields = NULL;} 5482b3cf3223SMatthew G. Knepley if (ds) {PetscValidPointer(ds, 4); *ds = NULL;} 5483e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5484b3cf3223SMatthew G. Knepley if (dm->probs[s].label == label) { 5485b3cf3223SMatthew G. Knepley if (fields) *fields = dm->probs[s].fields; 5486b3cf3223SMatthew G. Knepley if (ds) *ds = dm->probs[s].ds; 5487b3cf3223SMatthew G. Knepley PetscFunctionReturn(0); 5488b3cf3223SMatthew G. Knepley } 5489e5e52638SMatthew G. Knepley } 54902df9ee95SMatthew G. Knepley PetscFunctionReturn(0); 5491e5e52638SMatthew G. Knepley } 5492e5e52638SMatthew G. Knepley 5493e5e52638SMatthew G. Knepley /*@ 5494083401c6SMatthew G. Knepley DMSetRegionDS - Set the PetscDS for a given mesh region, defined by a DMLabel 5495083401c6SMatthew G. Knepley 5496083401c6SMatthew G. Knepley Collective on dm 5497083401c6SMatthew G. Knepley 5498083401c6SMatthew G. Knepley Input Parameters: 5499083401c6SMatthew G. Knepley + dm - The DM 5500083401c6SMatthew G. Knepley . label - The DMLabel defining the mesh region, or NULL for the entire mesh 5501083401c6SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL for all fields 5502083401c6SMatthew G. Knepley - prob - The PetscDS defined on the given cell 5503083401c6SMatthew G. Knepley 5504083401c6SMatthew 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, 5505083401c6SMatthew G. Knepley the fields argument is ignored. 5506083401c6SMatthew G. Knepley 5507083401c6SMatthew G. Knepley Level: advanced 5508083401c6SMatthew G. Knepley 5509083401c6SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionNumDS(), DMGetDS(), DMGetCellDS() 5510083401c6SMatthew G. Knepley @*/ 5511083401c6SMatthew G. Knepley PetscErrorCode DMSetRegionDS(DM dm, DMLabel label, IS fields, PetscDS ds) 5512083401c6SMatthew G. Knepley { 5513083401c6SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5514083401c6SMatthew G. Knepley PetscErrorCode ierr; 5515083401c6SMatthew G. Knepley 5516083401c6SMatthew G. Knepley PetscFunctionBegin; 5517083401c6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5518083401c6SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5519064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 4); 5520083401c6SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5521083401c6SMatthew G. Knepley if (dm->probs[s].label == label) { 5522083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr); 5523083401c6SMatthew G. Knepley dm->probs[s].ds = ds; 5524083401c6SMatthew G. Knepley PetscFunctionReturn(0); 5525083401c6SMatthew G. Knepley } 5526083401c6SMatthew G. Knepley } 5527083401c6SMatthew G. Knepley ierr = DMDSEnlarge_Static(dm, Nds+1);CHKERRQ(ierr); 5528083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 5529083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) fields);CHKERRQ(ierr); 5530083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) ds);CHKERRQ(ierr); 5531083401c6SMatthew G. Knepley if (!label) { 5532083401c6SMatthew G. Knepley /* Put the NULL label at the front, so it is returned as the default */ 5533083401c6SMatthew G. Knepley for (s = Nds-1; s >=0; --s) dm->probs[s+1] = dm->probs[s]; 5534083401c6SMatthew G. Knepley Nds = 0; 5535083401c6SMatthew G. Knepley } 5536083401c6SMatthew G. Knepley dm->probs[Nds].label = label; 5537083401c6SMatthew G. Knepley dm->probs[Nds].fields = fields; 5538083401c6SMatthew G. Knepley dm->probs[Nds].ds = ds; 5539083401c6SMatthew G. Knepley PetscFunctionReturn(0); 5540083401c6SMatthew G. Knepley } 5541083401c6SMatthew G. Knepley 5542083401c6SMatthew G. Knepley /*@ 5543e5e52638SMatthew G. Knepley DMGetRegionNumDS - Get the PetscDS for a given mesh region, defined by the region number 5544e5e52638SMatthew G. Knepley 5545e5e52638SMatthew G. Knepley Not collective 5546e5e52638SMatthew G. Knepley 5547e5e52638SMatthew G. Knepley Input Parameters: 5548e5e52638SMatthew G. Knepley + dm - The DM 5549e5e52638SMatthew G. Knepley - num - The region number, in [0, Nds) 5550e5e52638SMatthew G. Knepley 5551e5e52638SMatthew G. Knepley Output Parameters: 5552b3cf3223SMatthew G. Knepley + label - The region label, or NULL 5553b3cf3223SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL 5554083401c6SMatthew G. Knepley - ds - The PetscDS defined on the given region, or NULL 5555e5e52638SMatthew G. Knepley 5556e5e52638SMatthew G. Knepley Level: advanced 5557e5e52638SMatthew G. Knepley 5558e5e52638SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS() 5559e5e52638SMatthew G. Knepley @*/ 5560b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionNumDS(DM dm, PetscInt num, DMLabel *label, IS *fields, PetscDS *ds) 5561e5e52638SMatthew G. Knepley { 5562e5e52638SMatthew G. Knepley PetscInt Nds; 5563e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5564e5e52638SMatthew G. Knepley 5565e5e52638SMatthew G. Knepley PetscFunctionBegin; 5566e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5567e5e52638SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 5568e5e52638SMatthew 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); 5569e5e52638SMatthew G. Knepley if (label) { 5570e5e52638SMatthew G. Knepley PetscValidPointer(label, 3); 5571e5e52638SMatthew G. Knepley *label = dm->probs[num].label; 5572e5e52638SMatthew G. Knepley } 5573b3cf3223SMatthew G. Knepley if (fields) { 5574b3cf3223SMatthew G. Knepley PetscValidPointer(fields, 4); 5575b3cf3223SMatthew G. Knepley *fields = dm->probs[num].fields; 5576b3cf3223SMatthew G. Knepley } 5577e5e52638SMatthew G. Knepley if (ds) { 5578b3cf3223SMatthew G. Knepley PetscValidPointer(ds, 5); 5579e5e52638SMatthew G. Knepley *ds = dm->probs[num].ds; 5580e5e52638SMatthew G. Knepley } 5581e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5582e5e52638SMatthew G. Knepley } 5583e5e52638SMatthew G. Knepley 5584e5e52638SMatthew G. Knepley /*@ 5585083401c6SMatthew G. Knepley DMSetRegionNumDS - Set the PetscDS for a given mesh region, defined by the region number 5586e5e52638SMatthew G. Knepley 5587083401c6SMatthew G. Knepley Not collective 5588e5e52638SMatthew G. Knepley 5589e5e52638SMatthew G. Knepley Input Parameters: 5590e5e52638SMatthew G. Knepley + dm - The DM 5591083401c6SMatthew G. Knepley . num - The region number, in [0, Nds) 5592083401c6SMatthew G. Knepley . label - The region label, or NULL 5593083401c6SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL to prevent setting 5594083401c6SMatthew G. Knepley - ds - The PetscDS defined on the given region, or NULL to prevent setting 5595e5e52638SMatthew G. Knepley 5596e5e52638SMatthew G. Knepley Level: advanced 5597e5e52638SMatthew G. Knepley 5598083401c6SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS() 5599e5e52638SMatthew G. Knepley @*/ 5600083401c6SMatthew G. Knepley PetscErrorCode DMSetRegionNumDS(DM dm, PetscInt num, DMLabel label, IS fields, PetscDS ds) 5601e5e52638SMatthew G. Knepley { 5602083401c6SMatthew G. Knepley PetscInt Nds; 5603e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5604e5e52638SMatthew G. Knepley 5605e5e52638SMatthew G. Knepley PetscFunctionBegin; 5606e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5607083401c6SMatthew G. Knepley if (label) {PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3);} 5608083401c6SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 5609083401c6SMatthew 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); 5610e5e52638SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 5611083401c6SMatthew G. Knepley ierr = DMLabelDestroy(&dm->probs[num].label);CHKERRQ(ierr); 5612083401c6SMatthew G. Knepley dm->probs[num].label = label; 5613083401c6SMatthew G. Knepley if (fields) { 5614083401c6SMatthew G. Knepley PetscValidHeaderSpecific(fields, IS_CLASSID, 4); 5615b3cf3223SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) fields);CHKERRQ(ierr); 5616083401c6SMatthew G. Knepley ierr = ISDestroy(&dm->probs[num].fields);CHKERRQ(ierr); 5617083401c6SMatthew G. Knepley dm->probs[num].fields = fields; 5618e5e52638SMatthew G. Knepley } 5619083401c6SMatthew G. Knepley if (ds) { 5620083401c6SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 5); 5621083401c6SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) ds);CHKERRQ(ierr); 5622083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&dm->probs[num].ds);CHKERRQ(ierr); 5623083401c6SMatthew G. Knepley dm->probs[num].ds = ds; 5624083401c6SMatthew G. Knepley } 5625e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5626e5e52638SMatthew G. Knepley } 5627e5e52638SMatthew G. Knepley 5628e5e52638SMatthew G. Knepley /*@ 56291d3af9e0SMatthew G. Knepley DMFindRegionNum - Find the region number for a given PetscDS, or -1 if it is not found. 56301d3af9e0SMatthew G. Knepley 56311d3af9e0SMatthew G. Knepley Not collective 56321d3af9e0SMatthew G. Knepley 56331d3af9e0SMatthew G. Knepley Input Parameters: 56341d3af9e0SMatthew G. Knepley + dm - The DM 56351d3af9e0SMatthew G. Knepley - ds - The PetscDS defined on the given region 56361d3af9e0SMatthew G. Knepley 56371d3af9e0SMatthew G. Knepley Output Parameter: 56381d3af9e0SMatthew G. Knepley . num - The region number, in [0, Nds), or -1 if not found 56391d3af9e0SMatthew G. Knepley 56401d3af9e0SMatthew G. Knepley Level: advanced 56411d3af9e0SMatthew G. Knepley 56421d3af9e0SMatthew G. Knepley .seealso: DMGetRegionNumDS(), DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS() 56431d3af9e0SMatthew G. Knepley @*/ 56441d3af9e0SMatthew G. Knepley PetscErrorCode DMFindRegionNum(DM dm, PetscDS ds, PetscInt *num) 56451d3af9e0SMatthew G. Knepley { 56461d3af9e0SMatthew G. Knepley PetscInt Nds, n; 56471d3af9e0SMatthew G. Knepley PetscErrorCode ierr; 56481d3af9e0SMatthew G. Knepley 56491d3af9e0SMatthew G. Knepley PetscFunctionBegin; 56501d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 56511d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 2); 56521d3af9e0SMatthew G. Knepley PetscValidPointer(num, 3); 56531d3af9e0SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 56541d3af9e0SMatthew G. Knepley for (n = 0; n < Nds; ++n) if (ds == dm->probs[n].ds) break; 56551d3af9e0SMatthew G. Knepley if (n >= Nds) *num = -1; 56561d3af9e0SMatthew G. Knepley else *num = n; 56571d3af9e0SMatthew G. Knepley PetscFunctionReturn(0); 56581d3af9e0SMatthew G. Knepley } 56591d3af9e0SMatthew G. Knepley 56601d3af9e0SMatthew G. Knepley /*@ 5661e5e52638SMatthew G. Knepley DMCreateDS - Create the discrete systems for the DM based upon the fields added to the DM 5662e5e52638SMatthew G. Knepley 5663d083f849SBarry Smith Collective on dm 5664e5e52638SMatthew G. Knepley 5665e5e52638SMatthew G. Knepley Input Parameter: 5666e5e52638SMatthew G. Knepley . dm - The DM 5667e5e52638SMatthew G. Knepley 566845480ffeSMatthew G. Knepley Options Database Keys: 566945480ffeSMatthew G. Knepley . -dm_petscds_view - View all the PetscDS objects in this DM 567045480ffeSMatthew G. Knepley 5671e5e52638SMatthew G. Knepley Note: If the label has a DS defined, it will be replaced. Otherwise, it will be added to the DM. 5672e5e52638SMatthew G. Knepley 5673e5e52638SMatthew G. Knepley Level: intermediate 5674e5e52638SMatthew G. Knepley 5675e5e52638SMatthew G. Knepley .seealso: DMSetField, DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS() 5676e5e52638SMatthew G. Knepley @*/ 5677e5e52638SMatthew G. Knepley PetscErrorCode DMCreateDS(DM dm) 5678e5e52638SMatthew G. Knepley { 5679e5e52638SMatthew G. Knepley MPI_Comm comm; 5680083401c6SMatthew G. Knepley PetscDS dsDef; 5681083401c6SMatthew G. Knepley DMLabel *labelSet; 5682f9244615SMatthew G. Knepley PetscInt dE, Nf = dm->Nf, f, s, Nl, l, Ndef, k; 5683f9244615SMatthew G. Knepley PetscBool doSetup = PETSC_TRUE, flg; 5684e5e52638SMatthew G. Knepley PetscErrorCode ierr; 5685e5e52638SMatthew G. Knepley 5686e5e52638SMatthew G. Knepley PetscFunctionBegin; 5687e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5688e5e52638SMatthew G. Knepley if (!dm->fields) PetscFunctionReturn(0); 5689e5e52638SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 5690083401c6SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 5691083401c6SMatthew G. Knepley /* Determine how many regions we have */ 5692083401c6SMatthew G. Knepley ierr = PetscMalloc1(Nf, &labelSet);CHKERRQ(ierr); 5693083401c6SMatthew G. Knepley Nl = 0; 5694083401c6SMatthew G. Knepley Ndef = 0; 5695083401c6SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5696083401c6SMatthew G. Knepley DMLabel label = dm->fields[f].label; 5697083401c6SMatthew G. Knepley PetscInt l; 5698083401c6SMatthew G. Knepley 5699f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 5700f918ec44SMatthew G. Knepley /* Move CEED context to discretizations */ 5701f918ec44SMatthew G. Knepley { 5702f918ec44SMatthew G. Knepley PetscClassId id; 5703f918ec44SMatthew G. Knepley 5704f918ec44SMatthew G. Knepley ierr = PetscObjectGetClassId(dm->fields[f].disc, &id);CHKERRQ(ierr); 5705f918ec44SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 5706f918ec44SMatthew G. Knepley Ceed ceed; 5707f918ec44SMatthew G. Knepley 5708f918ec44SMatthew G. Knepley ierr = DMGetCeed(dm, &ceed);CHKERRQ(ierr); 5709f918ec44SMatthew G. Knepley ierr = PetscFESetCeed((PetscFE) dm->fields[f].disc, ceed);CHKERRQ(ierr); 5710f918ec44SMatthew G. Knepley } 5711f918ec44SMatthew G. Knepley } 5712f918ec44SMatthew G. Knepley #endif 5713083401c6SMatthew G. Knepley if (!label) {++Ndef; continue;} 5714083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) if (label == labelSet[l]) break; 5715083401c6SMatthew G. Knepley if (l < Nl) continue; 5716083401c6SMatthew G. Knepley labelSet[Nl++] = label; 5717083401c6SMatthew G. Knepley } 5718083401c6SMatthew G. Knepley /* Create default DS if there are no labels to intersect with */ 5719083401c6SMatthew G. Knepley ierr = DMGetRegionDS(dm, NULL, NULL, &dsDef);CHKERRQ(ierr); 5720083401c6SMatthew G. Knepley if (!dsDef && Ndef && !Nl) { 5721b3cf3223SMatthew G. Knepley IS fields; 5722b3cf3223SMatthew G. Knepley PetscInt *fld, nf; 5723b3cf3223SMatthew G. Knepley 5724b3cf3223SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) ++nf; 5725083401c6SMatthew G. Knepley if (nf) { 5726b3cf3223SMatthew G. Knepley ierr = PetscMalloc1(nf, &fld);CHKERRQ(ierr); 5727b3cf3223SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) fld[nf++] = f; 572888f0c812SMatthew G. Knepley ierr = ISCreate(PETSC_COMM_SELF, &fields);CHKERRQ(ierr); 572988f0c812SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_");CHKERRQ(ierr); 573088f0c812SMatthew G. Knepley ierr = ISSetType(fields, ISGENERAL);CHKERRQ(ierr); 573188f0c812SMatthew G. Knepley ierr = ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER);CHKERRQ(ierr); 573288f0c812SMatthew G. Knepley 573345480ffeSMatthew G. Knepley ierr = PetscDSCreate(PETSC_COMM_SELF, &dsDef);CHKERRQ(ierr); 5734083401c6SMatthew G. Knepley ierr = DMSetRegionDS(dm, NULL, fields, dsDef);CHKERRQ(ierr); 5735083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&dsDef);CHKERRQ(ierr); 5736b3cf3223SMatthew G. Knepley ierr = ISDestroy(&fields);CHKERRQ(ierr); 57372df9ee95SMatthew G. Knepley } 5738083401c6SMatthew G. Knepley } 5739083401c6SMatthew G. Knepley ierr = DMGetRegionDS(dm, NULL, NULL, &dsDef);CHKERRQ(ierr); 5740083401c6SMatthew G. Knepley if (dsDef) {ierr = PetscDSSetCoordinateDimension(dsDef, dE);CHKERRQ(ierr);} 5741083401c6SMatthew G. Knepley /* Intersect labels with default fields */ 5742083401c6SMatthew G. Knepley if (Ndef && Nl) { 57430122748bSMatthew G. Knepley DM plex; 5744083401c6SMatthew G. Knepley DMLabel cellLabel; 5745083401c6SMatthew G. Knepley IS fieldIS, allcellIS, defcellIS = NULL; 5746083401c6SMatthew G. Knepley PetscInt *fields; 5747083401c6SMatthew G. Knepley const PetscInt *cells; 5748083401c6SMatthew G. Knepley PetscInt depth, nf = 0, n, c; 57490122748bSMatthew G. Knepley 57500122748bSMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 57510122748bSMatthew G. Knepley ierr = DMPlexGetDepth(plex, &depth);CHKERRQ(ierr); 5752083401c6SMatthew G. Knepley ierr = DMGetStratumIS(plex, "dim", depth, &allcellIS);CHKERRQ(ierr); 5753083401c6SMatthew G. Knepley if (!allcellIS) {ierr = DMGetStratumIS(plex, "depth", depth, &allcellIS);CHKERRQ(ierr);} 5754083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5755083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5756083401c6SMatthew G. Knepley IS pointIS; 5757083401c6SMatthew G. Knepley 5758083401c6SMatthew G. Knepley ierr = ISDestroy(&defcellIS);CHKERRQ(ierr); 5759083401c6SMatthew G. Knepley ierr = DMLabelGetStratumIS(label, 1, &pointIS);CHKERRQ(ierr); 5760083401c6SMatthew G. Knepley ierr = ISDifference(allcellIS, pointIS, &defcellIS);CHKERRQ(ierr); 5761083401c6SMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 5762083401c6SMatthew G. Knepley } 5763083401c6SMatthew G. Knepley ierr = ISDestroy(&allcellIS);CHKERRQ(ierr); 5764083401c6SMatthew G. Knepley 5765083401c6SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, "defaultCells", &cellLabel);CHKERRQ(ierr); 5766083401c6SMatthew G. Knepley ierr = ISGetLocalSize(defcellIS, &n);CHKERRQ(ierr); 5767083401c6SMatthew G. Knepley ierr = ISGetIndices(defcellIS, &cells);CHKERRQ(ierr); 5768083401c6SMatthew G. Knepley for (c = 0; c < n; ++c) {ierr = DMLabelSetValue(cellLabel, cells[c], 1);CHKERRQ(ierr);} 5769083401c6SMatthew G. Knepley ierr = ISRestoreIndices(defcellIS, &cells);CHKERRQ(ierr); 5770083401c6SMatthew G. Knepley ierr = ISDestroy(&defcellIS);CHKERRQ(ierr); 5771083401c6SMatthew G. Knepley ierr = DMPlexLabelComplete(plex, cellLabel);CHKERRQ(ierr); 5772083401c6SMatthew G. Knepley 5773083401c6SMatthew G. Knepley ierr = PetscMalloc1(Ndef, &fields);CHKERRQ(ierr); 5774083401c6SMatthew G. Knepley for (f = 0; f < Nf; ++f) if (!dm->fields[f].label) fields[nf++] = f; 5775083401c6SMatthew G. Knepley ierr = ISCreate(PETSC_COMM_SELF, &fieldIS);CHKERRQ(ierr); 5776083401c6SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) fieldIS, "dm_fields_");CHKERRQ(ierr); 5777083401c6SMatthew G. Knepley ierr = ISSetType(fieldIS, ISGENERAL);CHKERRQ(ierr); 5778083401c6SMatthew G. Knepley ierr = ISGeneralSetIndices(fieldIS, nf, fields, PETSC_OWN_POINTER);CHKERRQ(ierr); 5779083401c6SMatthew G. Knepley 578045480ffeSMatthew G. Knepley ierr = PetscDSCreate(PETSC_COMM_SELF, &dsDef);CHKERRQ(ierr); 5781083401c6SMatthew G. Knepley ierr = DMSetRegionDS(dm, cellLabel, fieldIS, dsDef);CHKERRQ(ierr); 5782083401c6SMatthew G. Knepley ierr = DMLabelDestroy(&cellLabel);CHKERRQ(ierr); 5783083401c6SMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(dsDef, dE);CHKERRQ(ierr); 5784083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&dsDef);CHKERRQ(ierr); 5785083401c6SMatthew G. Knepley ierr = ISDestroy(&fieldIS);CHKERRQ(ierr); 57860122748bSMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 5787083401c6SMatthew G. Knepley } 5788083401c6SMatthew G. Knepley /* Create label DSes 5789083401c6SMatthew G. Knepley - WE ONLY SUPPORT IDENTICAL OR DISJOINT LABELS 5790083401c6SMatthew G. Knepley */ 5791083401c6SMatthew G. Knepley /* TODO Should check that labels are disjoint */ 5792083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5793083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5794083401c6SMatthew G. Knepley PetscDS ds; 5795083401c6SMatthew G. Knepley IS fields; 5796083401c6SMatthew G. Knepley PetscInt *fld, nf; 5797083401c6SMatthew G. Knepley 579845480ffeSMatthew G. Knepley ierr = PetscDSCreate(PETSC_COMM_SELF, &ds);CHKERRQ(ierr); 5799083401c6SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (label == dm->fields[f].label || !dm->fields[f].label) ++nf; 5800083401c6SMatthew G. Knepley ierr = PetscMalloc1(nf, &fld);CHKERRQ(ierr); 5801083401c6SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (label == dm->fields[f].label || !dm->fields[f].label) fld[nf++] = f; 5802083401c6SMatthew G. Knepley ierr = ISCreate(PETSC_COMM_SELF, &fields);CHKERRQ(ierr); 5803083401c6SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_");CHKERRQ(ierr); 5804083401c6SMatthew G. Knepley ierr = ISSetType(fields, ISGENERAL);CHKERRQ(ierr); 5805083401c6SMatthew G. Knepley ierr = ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER);CHKERRQ(ierr); 5806083401c6SMatthew G. Knepley ierr = DMSetRegionDS(dm, label, fields, ds);CHKERRQ(ierr); 5807083401c6SMatthew G. Knepley ierr = ISDestroy(&fields);CHKERRQ(ierr); 5808083401c6SMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(ds, dE);CHKERRQ(ierr); 5809083401c6SMatthew G. Knepley { 5810083401c6SMatthew G. Knepley DMPolytopeType ct; 5811083401c6SMatthew G. Knepley PetscInt lStart, lEnd; 5812083401c6SMatthew G. Knepley PetscBool isHybridLocal = PETSC_FALSE, isHybrid; 58130122748bSMatthew G. Knepley 5814e5e52638SMatthew G. Knepley ierr = DMLabelGetBounds(label, &lStart, &lEnd);CHKERRQ(ierr); 5815665f567fSMatthew G. Knepley if (lStart >= 0) { 5816412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, lStart, &ct);CHKERRQ(ierr); 5817412e9a14SMatthew G. Knepley switch (ct) { 5818412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 5819412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 5820412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 5821412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 5822083401c6SMatthew G. Knepley isHybridLocal = PETSC_TRUE;break; 5823083401c6SMatthew G. Knepley default: break; 5824412e9a14SMatthew G. Knepley } 5825665f567fSMatthew G. Knepley } 5826ffc4695bSBarry Smith ierr = MPI_Allreduce(&isHybridLocal, &isHybrid, 1, MPIU_BOOL, MPI_LOR, comm);CHKERRMPI(ierr); 5827083401c6SMatthew G. Knepley ierr = PetscDSSetHybrid(ds, isHybrid);CHKERRQ(ierr); 5828e5e52638SMatthew G. Knepley } 5829083401c6SMatthew G. Knepley ierr = PetscDSDestroy(&ds);CHKERRQ(ierr); 5830e5e52638SMatthew G. Knepley } 5831083401c6SMatthew G. Knepley ierr = PetscFree(labelSet);CHKERRQ(ierr); 5832e5e52638SMatthew G. Knepley /* Set fields in DSes */ 5833083401c6SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5834083401c6SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 5835083401c6SMatthew G. Knepley IS fields = dm->probs[s].fields; 5836083401c6SMatthew G. Knepley const PetscInt *fld; 5837083401c6SMatthew G. Knepley PetscInt nf; 5838e5e52638SMatthew G. Knepley 5839083401c6SMatthew G. Knepley ierr = ISGetLocalSize(fields, &nf);CHKERRQ(ierr); 5840083401c6SMatthew G. Knepley ierr = ISGetIndices(fields, &fld);CHKERRQ(ierr); 5841083401c6SMatthew G. Knepley for (f = 0; f < nf; ++f) { 5842083401c6SMatthew G. Knepley PetscObject disc = dm->fields[fld[f]].disc; 5843083401c6SMatthew G. Knepley PetscBool isHybrid; 5844e5e52638SMatthew G. Knepley PetscClassId id; 5845e5e52638SMatthew G. Knepley 5846083401c6SMatthew G. Knepley ierr = PetscDSGetHybrid(ds, &isHybrid);CHKERRQ(ierr); 5847083401c6SMatthew G. Knepley /* If this is a cohesive cell, then it needs the lower dimensional discretization */ 5848083401c6SMatthew G. Knepley if (isHybrid && f < nf-1) {ierr = PetscFEGetHeightSubspace((PetscFE) disc, 1, (PetscFE *) &disc);CHKERRQ(ierr);} 5849083401c6SMatthew G. Knepley ierr = PetscDSSetDiscretization(ds, f, disc);CHKERRQ(ierr); 5850083401c6SMatthew G. Knepley /* We allow people to have placeholder fields and construct the Section by hand */ 5851e5e52638SMatthew G. Knepley ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr); 5852e5e52638SMatthew G. Knepley if ((id != PETSCFE_CLASSID) && (id != PETSCFV_CLASSID)) doSetup = PETSC_FALSE; 5853e5e52638SMatthew G. Knepley } 5854083401c6SMatthew G. Knepley ierr = ISRestoreIndices(fields, &fld);CHKERRQ(ierr); 5855e5e52638SMatthew G. Knepley } 5856f9244615SMatthew G. Knepley /* Allow k-jet tabulation */ 5857f9244615SMatthew G. Knepley ierr = PetscOptionsGetInt(NULL, ((PetscObject) dm)->prefix, "-dm_ds_jet_degree", &k, &flg);CHKERRQ(ierr); 5858f9244615SMatthew G. Knepley if (flg) { 58593b4aee56SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 58603b4aee56SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 58613b4aee56SMatthew G. Knepley PetscInt Nf, f; 58623b4aee56SMatthew G. Knepley 58633b4aee56SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 58643b4aee56SMatthew G. Knepley for (f = 0; f < Nf; ++f) {ierr = PetscDSSetJetDegree(ds, f, k);CHKERRQ(ierr);} 58653b4aee56SMatthew G. Knepley } 5866f9244615SMatthew G. Knepley } 5867e5e52638SMatthew G. Knepley /* Setup DSes */ 5868e5e52638SMatthew G. Knepley if (doSetup) { 5869e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) {ierr = PetscDSSetUp(dm->probs[s].ds);CHKERRQ(ierr);} 5870e5e52638SMatthew G. Knepley } 5871e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5872e5e52638SMatthew G. Knepley } 5873e5e52638SMatthew G. Knepley 5874e5e52638SMatthew G. Knepley /*@ 58757f96f943SMatthew G. Knepley DMComputeExactSolution - Compute the exact solution for a given DM, using the PetscDS information. 58767f96f943SMatthew G. Knepley 5877f2cacb80SMatthew G. Knepley Collective on DM 5878f2cacb80SMatthew G. Knepley 58797f96f943SMatthew G. Knepley Input Parameters: 58807f96f943SMatthew G. Knepley + dm - The DM 58817f96f943SMatthew G. Knepley - time - The time 58827f96f943SMatthew G. Knepley 58837f96f943SMatthew G. Knepley Output Parameters: 5884f2cacb80SMatthew G. Knepley + u - The vector will be filled with exact solution values, or NULL 5885f2cacb80SMatthew G. Knepley - u_t - The vector will be filled with the time derivative of exact solution values, or NULL 58867f96f943SMatthew G. Knepley 58877f96f943SMatthew G. Knepley Note: The user must call PetscDSSetExactSolution() beforehand 58887f96f943SMatthew G. Knepley 58897f96f943SMatthew G. Knepley Level: developer 58907f96f943SMatthew G. Knepley 58917f96f943SMatthew G. Knepley .seealso: PetscDSSetExactSolution() 58927f96f943SMatthew G. Knepley @*/ 5893f2cacb80SMatthew G. Knepley PetscErrorCode DMComputeExactSolution(DM dm, PetscReal time, Vec u, Vec u_t) 58947f96f943SMatthew G. Knepley { 58957f96f943SMatthew G. Knepley PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx); 58967f96f943SMatthew G. Knepley void **ectxs; 58977f96f943SMatthew G. Knepley PetscInt Nf, Nds, s; 58987f96f943SMatthew G. Knepley PetscErrorCode ierr; 58997f96f943SMatthew G. Knepley 59007f96f943SMatthew G. Knepley PetscFunctionBegin; 5901f2cacb80SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5902f2cacb80SMatthew G. Knepley if (u) PetscValidHeaderSpecific(u, VEC_CLASSID, 3); 5903f2cacb80SMatthew G. Knepley if (u_t) PetscValidHeaderSpecific(u_t, VEC_CLASSID, 4); 59047f96f943SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 59057f96f943SMatthew G. Knepley ierr = PetscMalloc2(Nf, &exacts, Nf, &ectxs);CHKERRQ(ierr); 59067f96f943SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 59077f96f943SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 59087f96f943SMatthew G. Knepley PetscDS ds; 59097f96f943SMatthew G. Knepley DMLabel label; 59107f96f943SMatthew G. Knepley IS fieldIS; 59117f96f943SMatthew G. Knepley const PetscInt *fields, id = 1; 59127f96f943SMatthew G. Knepley PetscInt dsNf, f; 59137f96f943SMatthew G. Knepley 59147f96f943SMatthew G. Knepley ierr = DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds);CHKERRQ(ierr); 59157f96f943SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &dsNf);CHKERRQ(ierr); 59167f96f943SMatthew G. Knepley ierr = ISGetIndices(fieldIS, &fields);CHKERRQ(ierr); 59177f96f943SMatthew G. Knepley ierr = PetscArrayzero(exacts, Nf);CHKERRQ(ierr); 59187f96f943SMatthew G. Knepley ierr = PetscArrayzero(ectxs, Nf);CHKERRQ(ierr); 5919f2cacb80SMatthew G. Knepley if (u) { 59207f96f943SMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 59217f96f943SMatthew G. Knepley const PetscInt field = fields[f]; 59227f96f943SMatthew G. Knepley ierr = PetscDSGetExactSolution(ds, field, &exacts[field], &ectxs[field]);CHKERRQ(ierr); 59237f96f943SMatthew G. Knepley } 59247f96f943SMatthew G. Knepley ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr); 59257f96f943SMatthew G. Knepley if (label) { 59267f96f943SMatthew G. Knepley ierr = DMProjectFunctionLabel(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, u);CHKERRQ(ierr); 59277f96f943SMatthew G. Knepley } else { 59287f96f943SMatthew G. Knepley ierr = DMProjectFunction(dm, time, exacts, ectxs, INSERT_ALL_VALUES, u);CHKERRQ(ierr); 59297f96f943SMatthew G. Knepley } 59307f96f943SMatthew G. Knepley } 5931f2cacb80SMatthew G. Knepley if (u_t) { 5932f2cacb80SMatthew G. Knepley ierr = PetscArrayzero(exacts, Nf);CHKERRQ(ierr); 5933f2cacb80SMatthew G. Knepley ierr = PetscArrayzero(ectxs, Nf);CHKERRQ(ierr); 5934f2cacb80SMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 5935f2cacb80SMatthew G. Knepley const PetscInt field = fields[f]; 5936f2cacb80SMatthew G. Knepley ierr = PetscDSGetExactSolutionTimeDerivative(ds, field, &exacts[field], &ectxs[field]);CHKERRQ(ierr); 5937f2cacb80SMatthew G. Knepley } 5938f2cacb80SMatthew G. Knepley ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr); 5939f2cacb80SMatthew G. Knepley if (label) { 5940f2cacb80SMatthew G. Knepley ierr = DMProjectFunctionLabel(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, u_t);CHKERRQ(ierr); 5941f2cacb80SMatthew G. Knepley } else { 5942f2cacb80SMatthew G. Knepley ierr = DMProjectFunction(dm, time, exacts, ectxs, INSERT_ALL_VALUES, u_t);CHKERRQ(ierr); 5943f2cacb80SMatthew G. Knepley } 5944f2cacb80SMatthew G. Knepley } 5945f2cacb80SMatthew G. Knepley } 5946f2cacb80SMatthew G. Knepley if (u) { 59477f96f943SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) u, "Exact Solution");CHKERRQ(ierr); 59487f96f943SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) u, "exact_");CHKERRQ(ierr); 5949f2cacb80SMatthew G. Knepley } 5950f2cacb80SMatthew G. Knepley if (u_t) { 5951f2cacb80SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) u, "Exact Solution Time Derivative");CHKERRQ(ierr); 5952f2cacb80SMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) u_t, "exact_t_");CHKERRQ(ierr); 5953f2cacb80SMatthew G. Knepley } 59547f96f943SMatthew G. Knepley ierr = PetscFree2(exacts, ectxs);CHKERRQ(ierr); 59557f96f943SMatthew G. Knepley PetscFunctionReturn(0); 59567f96f943SMatthew G. Knepley } 59577f96f943SMatthew G. Knepley 595845480ffeSMatthew G. Knepley PetscErrorCode DMTransferDS_Internal(DM dm, DMLabel label, IS fields, PetscDS ds) 595945480ffeSMatthew G. Knepley { 596045480ffeSMatthew G. Knepley PetscDS dsNew; 596145480ffeSMatthew G. Knepley DSBoundary b; 596245480ffeSMatthew G. Knepley PetscInt cdim, Nf, f; 5963df911668SMatthew G. Knepley PetscBool isHybrid; 596445480ffeSMatthew G. Knepley void *ctx; 596545480ffeSMatthew G. Knepley PetscErrorCode ierr; 596645480ffeSMatthew G. Knepley 596745480ffeSMatthew G. Knepley PetscFunctionBegin; 596845480ffeSMatthew G. Knepley ierr = PetscDSCreate(PetscObjectComm((PetscObject) ds), &dsNew);CHKERRQ(ierr); 596945480ffeSMatthew G. Knepley ierr = PetscDSCopyConstants(ds, dsNew);CHKERRQ(ierr); 597045480ffeSMatthew G. Knepley ierr = PetscDSCopyExactSolutions(ds, dsNew);CHKERRQ(ierr); 597145480ffeSMatthew G. Knepley ierr = PetscDSSelectDiscretizations(ds, PETSC_DETERMINE, NULL, dsNew);CHKERRQ(ierr); 597245480ffeSMatthew G. Knepley ierr = PetscDSCopyEquations(ds, dsNew);CHKERRQ(ierr); 597345480ffeSMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 597445480ffeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 597545480ffeSMatthew G. Knepley ierr = PetscDSGetContext(ds, f, &ctx);CHKERRQ(ierr); 597645480ffeSMatthew G. Knepley ierr = PetscDSSetContext(dsNew, f, ctx);CHKERRQ(ierr); 597745480ffeSMatthew G. Knepley } 597845480ffeSMatthew G. Knepley if (Nf) { 597945480ffeSMatthew G. Knepley ierr = PetscDSGetCoordinateDimension(ds, &cdim);CHKERRQ(ierr); 598045480ffeSMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(dsNew, cdim);CHKERRQ(ierr); 598145480ffeSMatthew G. Knepley } 598245480ffeSMatthew G. Knepley ierr = PetscDSCopyBoundary(ds, PETSC_DETERMINE, NULL, dsNew);CHKERRQ(ierr); 598345480ffeSMatthew G. Knepley for (b = dsNew->boundary; b; b = b->next) { 598445480ffeSMatthew G. Knepley ierr = DMGetLabel(dm, b->lname, &b->label);CHKERRQ(ierr); 598545480ffeSMatthew G. Knepley /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */ 598645480ffeSMatthew G. Knepley //if (!b->label) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Label %s missing in new DM", name); 598745480ffeSMatthew G. Knepley } 5988df911668SMatthew G. Knepley ierr = PetscDSGetHybrid(ds, &isHybrid);CHKERRQ(ierr); 5989df911668SMatthew G. Knepley ierr = PetscDSSetHybrid(dsNew, isHybrid);CHKERRQ(ierr); 599045480ffeSMatthew G. Knepley 599145480ffeSMatthew G. Knepley ierr = DMSetRegionDS(dm, label, fields, dsNew);CHKERRQ(ierr); 599245480ffeSMatthew G. Knepley ierr = PetscDSDestroy(&dsNew);CHKERRQ(ierr); 599345480ffeSMatthew G. Knepley PetscFunctionReturn(0); 599445480ffeSMatthew G. Knepley } 599545480ffeSMatthew G. Knepley 59967f96f943SMatthew G. Knepley /*@ 5997e5e52638SMatthew G. Knepley DMCopyDS - Copy the discrete systems for the DM into another DM 5998e5e52638SMatthew G. Knepley 5999d083f849SBarry Smith Collective on dm 6000e5e52638SMatthew G. Knepley 6001e5e52638SMatthew G. Knepley Input Parameter: 6002e5e52638SMatthew G. Knepley . dm - The DM 6003e5e52638SMatthew G. Knepley 6004e5e52638SMatthew G. Knepley Output Parameter: 6005e5e52638SMatthew G. Knepley . newdm - The DM 6006e5e52638SMatthew G. Knepley 6007e5e52638SMatthew G. Knepley Level: advanced 6008e5e52638SMatthew G. Knepley 6009e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS() 6010e5e52638SMatthew G. Knepley @*/ 6011e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDS(DM dm, DM newdm) 6012e5e52638SMatthew G. Knepley { 6013e5e52638SMatthew G. Knepley PetscInt Nds, s; 6014e5e52638SMatthew G. Knepley PetscErrorCode ierr; 6015e5e52638SMatthew G. Knepley 6016e5e52638SMatthew G. Knepley PetscFunctionBegin; 6017e5e52638SMatthew G. Knepley if (dm == newdm) PetscFunctionReturn(0); 6018e5e52638SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 6019e5e52638SMatthew G. Knepley ierr = DMClearDS(newdm);CHKERRQ(ierr); 6020e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 6021e5e52638SMatthew G. Knepley DMLabel label; 6022b3cf3223SMatthew G. Knepley IS fields; 602345480ffeSMatthew G. Knepley PetscDS ds, newds; 6024783e2ec8SMatthew G. Knepley PetscInt Nbd, bd; 6025e5e52638SMatthew G. Knepley 6026b3cf3223SMatthew G. Knepley ierr = DMGetRegionNumDS(dm, s, &label, &fields, &ds);CHKERRQ(ierr); 6027b8025e53SMatthew G. Knepley /* TODO: We need to change all keys from labels in the old DM to labels in the new DM */ 602845480ffeSMatthew G. Knepley ierr = DMTransferDS_Internal(newdm, label, fields, ds);CHKERRQ(ierr); 602945480ffeSMatthew G. Knepley /* Commplete new labels in the new DS */ 603045480ffeSMatthew G. Knepley ierr = DMGetRegionDS(newdm, label, NULL, &newds);CHKERRQ(ierr); 603145480ffeSMatthew G. Knepley ierr = PetscDSGetNumBoundary(newds, &Nbd);CHKERRQ(ierr); 6032783e2ec8SMatthew G. Knepley for (bd = 0; bd < Nbd; ++bd) { 6033b8025e53SMatthew G. Knepley PetscWeakForm wf; 603445480ffeSMatthew G. Knepley DMLabel label; 6035783e2ec8SMatthew G. Knepley PetscInt field; 6036783e2ec8SMatthew G. Knepley 6037b8025e53SMatthew G. Knepley ierr = PetscDSGetBoundary(newds, bd, &wf, NULL, NULL, &label, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 603845480ffeSMatthew G. Knepley ierr = DMCompleteBoundaryLabel_Internal(newdm, newds, field, bd, label);CHKERRQ(ierr); 6039b8025e53SMatthew G. Knepley ierr = PetscWeakFormReplaceLabel(wf, label);CHKERRQ(ierr); 6040783e2ec8SMatthew G. Knepley } 6041e5e52638SMatthew G. Knepley } 6042e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 6043e5e52638SMatthew G. Knepley } 6044e5e52638SMatthew G. Knepley 6045e5e52638SMatthew G. Knepley /*@ 6046e5e52638SMatthew G. Knepley DMCopyDisc - Copy the fields and discrete systems for the DM into another DM 6047e5e52638SMatthew G. Knepley 6048d083f849SBarry Smith Collective on dm 6049e5e52638SMatthew G. Knepley 6050e5e52638SMatthew G. Knepley Input Parameter: 6051e5e52638SMatthew G. Knepley . dm - The DM 6052e5e52638SMatthew G. Knepley 6053e5e52638SMatthew G. Knepley Output Parameter: 6054e5e52638SMatthew G. Knepley . newdm - The DM 6055e5e52638SMatthew G. Knepley 6056e5e52638SMatthew G. Knepley Level: advanced 6057e5e52638SMatthew G. Knepley 6058e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMCopyDS() 6059e5e52638SMatthew G. Knepley @*/ 6060e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDisc(DM dm, DM newdm) 6061e5e52638SMatthew G. Knepley { 6062e5e52638SMatthew G. Knepley PetscErrorCode ierr; 6063e5e52638SMatthew G. Knepley 6064e5e52638SMatthew G. Knepley PetscFunctionBegin; 6065e5e52638SMatthew G. Knepley ierr = DMCopyFields(dm, newdm);CHKERRQ(ierr); 6066e5e52638SMatthew G. Knepley ierr = DMCopyDS(dm, newdm);CHKERRQ(ierr); 6067e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 6068e5e52638SMatthew G. Knepley } 6069e5e52638SMatthew G. Knepley 6070b64e0483SPeter Brune PetscErrorCode DMRestrictHook_Coordinates(DM dm,DM dmc,void *ctx) 6071b64e0483SPeter Brune { 6072b64e0483SPeter Brune DM dm_coord,dmc_coord; 6073b64e0483SPeter Brune PetscErrorCode ierr; 6074b64e0483SPeter Brune Vec coords,ccoords; 60756dbf9973SLawrence Mitchell Mat inject; 6076b64e0483SPeter Brune PetscFunctionBegin; 6077b64e0483SPeter Brune ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr); 6078b64e0483SPeter Brune ierr = DMGetCoordinateDM(dmc,&dmc_coord);CHKERRQ(ierr); 6079b64e0483SPeter Brune ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr); 6080b64e0483SPeter Brune ierr = DMGetCoordinates(dmc,&ccoords);CHKERRQ(ierr); 6081b64e0483SPeter Brune if (coords && !ccoords) { 6082b64e0483SPeter Brune ierr = DMCreateGlobalVector(dmc_coord,&ccoords);CHKERRQ(ierr); 60836668ed41SLisandro Dalcin ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr); 60846dbf9973SLawrence Mitchell ierr = DMCreateInjection(dmc_coord,dm_coord,&inject);CHKERRQ(ierr); 60852adcf181SLawrence Mitchell ierr = MatRestrict(inject,coords,ccoords);CHKERRQ(ierr); 60866dbf9973SLawrence Mitchell ierr = MatDestroy(&inject);CHKERRQ(ierr); 6087b64e0483SPeter Brune ierr = DMSetCoordinates(dmc,ccoords);CHKERRQ(ierr); 6088b64e0483SPeter Brune ierr = VecDestroy(&ccoords);CHKERRQ(ierr); 6089b64e0483SPeter Brune } 6090b64e0483SPeter Brune PetscFunctionReturn(0); 6091b64e0483SPeter Brune } 6092b64e0483SPeter Brune 609303dadc2fSPeter Brune static PetscErrorCode DMSubDomainHook_Coordinates(DM dm,DM subdm,void *ctx) 609403dadc2fSPeter Brune { 609503dadc2fSPeter Brune DM dm_coord,subdm_coord; 609603dadc2fSPeter Brune PetscErrorCode ierr; 609703dadc2fSPeter Brune Vec coords,ccoords,clcoords; 609803dadc2fSPeter Brune VecScatter *scat_i,*scat_g; 609903dadc2fSPeter Brune PetscFunctionBegin; 610003dadc2fSPeter Brune ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr); 610103dadc2fSPeter Brune ierr = DMGetCoordinateDM(subdm,&subdm_coord);CHKERRQ(ierr); 610203dadc2fSPeter Brune ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr); 610303dadc2fSPeter Brune ierr = DMGetCoordinates(subdm,&ccoords);CHKERRQ(ierr); 610403dadc2fSPeter Brune if (coords && !ccoords) { 610503dadc2fSPeter Brune ierr = DMCreateGlobalVector(subdm_coord,&ccoords);CHKERRQ(ierr); 61066668ed41SLisandro Dalcin ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr); 610703dadc2fSPeter Brune ierr = DMCreateLocalVector(subdm_coord,&clcoords);CHKERRQ(ierr); 610824640c55SToby Isaac ierr = PetscObjectSetName((PetscObject)clcoords,"coordinates");CHKERRQ(ierr); 610903dadc2fSPeter Brune ierr = DMCreateDomainDecompositionScatters(dm_coord,1,&subdm_coord,NULL,&scat_i,&scat_g);CHKERRQ(ierr); 611003dadc2fSPeter Brune ierr = VecScatterBegin(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 611103dadc2fSPeter Brune ierr = VecScatterEnd(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 61121ed9ada7SJunchao Zhang ierr = VecScatterBegin(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 611303dadc2fSPeter Brune ierr = VecScatterEnd(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 611403dadc2fSPeter Brune ierr = DMSetCoordinates(subdm,ccoords);CHKERRQ(ierr); 611503dadc2fSPeter Brune ierr = DMSetCoordinatesLocal(subdm,clcoords);CHKERRQ(ierr); 611603dadc2fSPeter Brune ierr = VecScatterDestroy(&scat_i[0]);CHKERRQ(ierr); 611703dadc2fSPeter Brune ierr = VecScatterDestroy(&scat_g[0]);CHKERRQ(ierr); 611803dadc2fSPeter Brune ierr = VecDestroy(&ccoords);CHKERRQ(ierr); 611903dadc2fSPeter Brune ierr = VecDestroy(&clcoords);CHKERRQ(ierr); 612003dadc2fSPeter Brune ierr = PetscFree(scat_i);CHKERRQ(ierr); 612103dadc2fSPeter Brune ierr = PetscFree(scat_g);CHKERRQ(ierr); 612203dadc2fSPeter Brune } 612303dadc2fSPeter Brune PetscFunctionReturn(0); 612403dadc2fSPeter Brune } 612503dadc2fSPeter Brune 6126c73cfb54SMatthew G. Knepley /*@ 6127c73cfb54SMatthew G. Knepley DMGetDimension - Return the topological dimension of the DM 6128c73cfb54SMatthew G. Knepley 6129c73cfb54SMatthew G. Knepley Not collective 6130c73cfb54SMatthew G. Knepley 6131c73cfb54SMatthew G. Knepley Input Parameter: 6132c73cfb54SMatthew G. Knepley . dm - The DM 6133c73cfb54SMatthew G. Knepley 6134c73cfb54SMatthew G. Knepley Output Parameter: 6135c73cfb54SMatthew G. Knepley . dim - The topological dimension 6136c73cfb54SMatthew G. Knepley 6137c73cfb54SMatthew G. Knepley Level: beginner 6138c73cfb54SMatthew G. Knepley 6139c73cfb54SMatthew G. Knepley .seealso: DMSetDimension(), DMCreate() 6140c73cfb54SMatthew G. Knepley @*/ 6141c73cfb54SMatthew G. Knepley PetscErrorCode DMGetDimension(DM dm, PetscInt *dim) 6142c73cfb54SMatthew G. Knepley { 6143c73cfb54SMatthew G. Knepley PetscFunctionBegin; 6144c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6145534a8f05SLisandro Dalcin PetscValidIntPointer(dim, 2); 6146c73cfb54SMatthew G. Knepley *dim = dm->dim; 6147c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 6148c73cfb54SMatthew G. Knepley } 6149c73cfb54SMatthew G. Knepley 6150c73cfb54SMatthew G. Knepley /*@ 6151c73cfb54SMatthew G. Knepley DMSetDimension - Set the topological dimension of the DM 6152c73cfb54SMatthew G. Knepley 6153c73cfb54SMatthew G. Knepley Collective on dm 6154c73cfb54SMatthew G. Knepley 6155c73cfb54SMatthew G. Knepley Input Parameters: 6156c73cfb54SMatthew G. Knepley + dm - The DM 6157c73cfb54SMatthew G. Knepley - dim - The topological dimension 6158c73cfb54SMatthew G. Knepley 6159c73cfb54SMatthew G. Knepley Level: beginner 6160c73cfb54SMatthew G. Knepley 6161c73cfb54SMatthew G. Knepley .seealso: DMGetDimension(), DMCreate() 6162c73cfb54SMatthew G. Knepley @*/ 6163c73cfb54SMatthew G. Knepley PetscErrorCode DMSetDimension(DM dm, PetscInt dim) 6164c73cfb54SMatthew G. Knepley { 6165e5e52638SMatthew G. Knepley PetscDS ds; 616645480ffeSMatthew G. Knepley PetscInt Nds, n; 6167f17e8794SMatthew G. Knepley PetscErrorCode ierr; 6168f17e8794SMatthew G. Knepley 6169c73cfb54SMatthew G. Knepley PetscFunctionBegin; 6170c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6171c73cfb54SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 6172c73cfb54SMatthew G. Knepley dm->dim = dim; 6173d17bd122SMatthew G. Knepley if (dm->dim >= 0) { 617445480ffeSMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 617545480ffeSMatthew G. Knepley for (n = 0; n < Nds; ++n) { 617645480ffeSMatthew G. Knepley ierr = DMGetRegionNumDS(dm, n, NULL, NULL, &ds);CHKERRQ(ierr); 617745480ffeSMatthew G. Knepley if (ds->dimEmbed < 0) {ierr = PetscDSSetCoordinateDimension(ds, dim);CHKERRQ(ierr);} 617845480ffeSMatthew G. Knepley } 6179d17bd122SMatthew G. Knepley } 6180c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 6181c73cfb54SMatthew G. Knepley } 6182c73cfb54SMatthew G. Knepley 6183793f3fe5SMatthew G. Knepley /*@ 6184793f3fe5SMatthew G. Knepley DMGetDimPoints - Get the half-open interval for all points of a given dimension 6185793f3fe5SMatthew G. Knepley 6186d083f849SBarry Smith Collective on dm 6187793f3fe5SMatthew G. Knepley 6188793f3fe5SMatthew G. Knepley Input Parameters: 6189793f3fe5SMatthew G. Knepley + dm - the DM 6190793f3fe5SMatthew G. Knepley - dim - the dimension 6191793f3fe5SMatthew G. Knepley 6192793f3fe5SMatthew G. Knepley Output Parameters: 6193793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension 6194aa049354SPatrick Sanan - pEnd - The first point following points of the given dimension 6195793f3fe5SMatthew G. Knepley 6196793f3fe5SMatthew G. Knepley Note: 6197793f3fe5SMatthew G. Knepley The points are vertices in the Hasse diagram encoding the topology. This is explained in 6198a8d69d7bSBarry Smith https://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme, 6199793f3fe5SMatthew G. Knepley then the interval is empty. 6200793f3fe5SMatthew G. Knepley 6201793f3fe5SMatthew G. Knepley Level: intermediate 6202793f3fe5SMatthew G. Knepley 6203793f3fe5SMatthew G. Knepley .seealso: DMPLEX, DMPlexGetDepthStratum(), DMPlexGetHeightStratum() 6204793f3fe5SMatthew G. Knepley @*/ 6205793f3fe5SMatthew G. Knepley PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 6206793f3fe5SMatthew G. Knepley { 6207793f3fe5SMatthew G. Knepley PetscInt d; 6208793f3fe5SMatthew G. Knepley PetscErrorCode ierr; 6209793f3fe5SMatthew G. Knepley 6210793f3fe5SMatthew G. Knepley PetscFunctionBegin; 6211793f3fe5SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6212793f3fe5SMatthew G. Knepley ierr = DMGetDimension(dm, &d);CHKERRQ(ierr); 6213793f3fe5SMatthew G. Knepley if ((dim < 0) || (dim > d)) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %d 1", dim, d); 6214b9d85ea2SLisandro Dalcin if (!dm->ops->getdimpoints) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "DM type %s does not implement DMGetDimPoints",((PetscObject)dm)->type_name); 6215793f3fe5SMatthew G. Knepley ierr = (*dm->ops->getdimpoints)(dm, dim, pStart, pEnd);CHKERRQ(ierr); 6216793f3fe5SMatthew G. Knepley PetscFunctionReturn(0); 6217793f3fe5SMatthew G. Knepley } 6218793f3fe5SMatthew G. Knepley 62196636e97aSMatthew G Knepley /*@ 62206636e97aSMatthew G Knepley DMSetCoordinates - Sets into the DM a global vector that holds the coordinates 62216636e97aSMatthew G Knepley 6222d083f849SBarry Smith Collective on dm 62236636e97aSMatthew G Knepley 62246636e97aSMatthew G Knepley Input Parameters: 62256636e97aSMatthew G Knepley + dm - the DM 62266636e97aSMatthew G Knepley - c - coordinate vector 62276636e97aSMatthew G Knepley 62282dd40e9bSPatrick Sanan Notes: 62292dd40e9bSPatrick Sanan The coordinates do include those for ghost points, which are in the local vector. 62302dd40e9bSPatrick Sanan 62312dd40e9bSPatrick Sanan The vector c should be destroyed by the caller. 62326636e97aSMatthew G Knepley 62336636e97aSMatthew G Knepley Level: intermediate 62346636e97aSMatthew G Knepley 623560c22052SBarry Smith .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMDASetUniformCoordinates() 62366636e97aSMatthew G Knepley @*/ 62376636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c) 62386636e97aSMatthew G Knepley { 62396636e97aSMatthew G Knepley PetscErrorCode ierr; 62406636e97aSMatthew G Knepley 62416636e97aSMatthew G Knepley PetscFunctionBegin; 62426636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 62436636e97aSMatthew G Knepley PetscValidHeaderSpecific(c,VEC_CLASSID,2); 62446636e97aSMatthew G Knepley ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr); 62456636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr); 62466636e97aSMatthew G Knepley dm->coordinates = c; 62476636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr); 6248b64e0483SPeter Brune ierr = DMCoarsenHookAdd(dm,DMRestrictHook_Coordinates,NULL,NULL);CHKERRQ(ierr); 624903dadc2fSPeter Brune ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_Coordinates,NULL,NULL);CHKERRQ(ierr); 62506636e97aSMatthew G Knepley PetscFunctionReturn(0); 62516636e97aSMatthew G Knepley } 62526636e97aSMatthew G Knepley 62536636e97aSMatthew G Knepley /*@ 62546636e97aSMatthew G Knepley DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates 62556636e97aSMatthew G Knepley 62567058e716SVaclav Hapla Not collective 62576636e97aSMatthew G Knepley 62586636e97aSMatthew G Knepley Input Parameters: 62596636e97aSMatthew G Knepley + dm - the DM 62606636e97aSMatthew G Knepley - c - coordinate vector 62616636e97aSMatthew G Knepley 62622dd40e9bSPatrick Sanan Notes: 62636636e97aSMatthew G Knepley The coordinates of ghost points can be set using DMSetCoordinates() 62646636e97aSMatthew G Knepley followed by DMGetCoordinatesLocal(). This is intended to enable the 62656636e97aSMatthew G Knepley setting of ghost coordinates outside of the domain. 62666636e97aSMatthew G Knepley 62672dd40e9bSPatrick Sanan The vector c should be destroyed by the caller. 62682dd40e9bSPatrick Sanan 62696636e97aSMatthew G Knepley Level: intermediate 62706636e97aSMatthew G Knepley 62716636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM() 62726636e97aSMatthew G Knepley @*/ 62736636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c) 62746636e97aSMatthew G Knepley { 62756636e97aSMatthew G Knepley PetscErrorCode ierr; 62766636e97aSMatthew G Knepley 62776636e97aSMatthew G Knepley PetscFunctionBegin; 62786636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 62796636e97aSMatthew G Knepley PetscValidHeaderSpecific(c,VEC_CLASSID,2); 62806636e97aSMatthew G Knepley ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr); 62816636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr); 62828865f1eaSKarl Rupp 62836636e97aSMatthew G Knepley dm->coordinatesLocal = c; 62848865f1eaSKarl Rupp 62856636e97aSMatthew G Knepley ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr); 62866636e97aSMatthew G Knepley PetscFunctionReturn(0); 62876636e97aSMatthew G Knepley } 62886636e97aSMatthew G Knepley 62896636e97aSMatthew G Knepley /*@ 62906636e97aSMatthew G Knepley DMGetCoordinates - Gets a global vector with the coordinates associated with the DM. 62916636e97aSMatthew G Knepley 6292d083f849SBarry Smith Collective on dm 62936636e97aSMatthew G Knepley 62946636e97aSMatthew G Knepley Input Parameter: 62956636e97aSMatthew G Knepley . dm - the DM 62966636e97aSMatthew G Knepley 62976636e97aSMatthew G Knepley Output Parameter: 62986636e97aSMatthew G Knepley . c - global coordinate vector 62996636e97aSMatthew G Knepley 63006636e97aSMatthew G Knepley Note: 630160c22052SBarry Smith This is a borrowed reference, so the user should NOT destroy this vector. When the DM is 630260c22052SBarry Smith destroyed the array will no longer be valid. 63036636e97aSMatthew G Knepley 6304959c7569SPatrick Sanan Each process has only the locally-owned portion of the global coordinates (does NOT have the ghost coordinates). 63056636e97aSMatthew G Knepley 63066636e97aSMatthew G Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 63076636e97aSMatthew G Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 63086636e97aSMatthew G Knepley 63096636e97aSMatthew G Knepley Level: intermediate 63106636e97aSMatthew G Knepley 631160c22052SBarry Smith .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMDASetUniformCoordinates() 63126636e97aSMatthew G Knepley @*/ 63136636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c) 63146636e97aSMatthew G Knepley { 63156636e97aSMatthew G Knepley PetscErrorCode ierr; 63166636e97aSMatthew G Knepley 63176636e97aSMatthew G Knepley PetscFunctionBegin; 63186636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 63196636e97aSMatthew G Knepley PetscValidPointer(c,2); 63201f588964SMatthew G Knepley if (!dm->coordinates && dm->coordinatesLocal) { 63210298fd71SBarry Smith DM cdm = NULL; 63221970a576SMatthew G. Knepley PetscBool localized; 63236636e97aSMatthew G Knepley 63246636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 63256636e97aSMatthew G Knepley ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr); 63261970a576SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 63271970a576SMatthew G. Knepley /* Block size is not correctly set by CreateGlobalVector() if coordinates are localized */ 63281970a576SMatthew G. Knepley if (localized) { 63291970a576SMatthew G. Knepley PetscInt cdim; 63301970a576SMatthew G. Knepley 63311970a576SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 63321970a576SMatthew G. Knepley ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr); 63331970a576SMatthew G. Knepley } 63346636e97aSMatthew G Knepley ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr); 63356636e97aSMatthew G Knepley ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr); 63366636e97aSMatthew G Knepley ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr); 63376636e97aSMatthew G Knepley } 63386636e97aSMatthew G Knepley *c = dm->coordinates; 63396636e97aSMatthew G Knepley PetscFunctionReturn(0); 63406636e97aSMatthew G Knepley } 63416636e97aSMatthew G Knepley 63426636e97aSMatthew G Knepley /*@ 634381e9a530SVaclav Hapla DMGetCoordinatesLocalSetUp - Prepares a local vector of coordinates, so that DMGetCoordinatesLocalNoncollective() can be used as non-collective afterwards. 634481e9a530SVaclav Hapla 6345d083f849SBarry Smith Collective on dm 634681e9a530SVaclav Hapla 634781e9a530SVaclav Hapla Input Parameter: 634881e9a530SVaclav Hapla . dm - the DM 634981e9a530SVaclav Hapla 635081e9a530SVaclav Hapla Level: advanced 635181e9a530SVaclav Hapla 635281e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalNoncollective() 635381e9a530SVaclav Hapla @*/ 635481e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalSetUp(DM dm) 635581e9a530SVaclav Hapla { 635681e9a530SVaclav Hapla PetscErrorCode ierr; 635781e9a530SVaclav Hapla 635881e9a530SVaclav Hapla PetscFunctionBegin; 635981e9a530SVaclav Hapla PetscValidHeaderSpecific(dm,DM_CLASSID,1); 636081e9a530SVaclav Hapla if (!dm->coordinatesLocal && dm->coordinates) { 63611970a576SMatthew G. Knepley DM cdm = NULL; 63621970a576SMatthew G. Knepley PetscBool localized; 63631970a576SMatthew G. Knepley 636481e9a530SVaclav Hapla ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 636581e9a530SVaclav Hapla ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr); 63661970a576SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 63671970a576SMatthew G. Knepley /* Block size is not correctly set by CreateLocalVector() if coordinates are localized */ 63681970a576SMatthew G. Knepley if (localized) { 63691970a576SMatthew G. Knepley PetscInt cdim; 63701970a576SMatthew G. Knepley 63711970a576SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 63721970a576SMatthew G. Knepley ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr); 63731970a576SMatthew G. Knepley } 637481e9a530SVaclav Hapla ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr); 637581e9a530SVaclav Hapla ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr); 637681e9a530SVaclav Hapla ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr); 637781e9a530SVaclav Hapla } 637881e9a530SVaclav Hapla PetscFunctionReturn(0); 637981e9a530SVaclav Hapla } 638081e9a530SVaclav Hapla 638181e9a530SVaclav Hapla /*@ 63826636e97aSMatthew G Knepley DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM. 63836636e97aSMatthew G Knepley 6384d083f849SBarry Smith Collective on dm 63856636e97aSMatthew G Knepley 63866636e97aSMatthew G Knepley Input Parameter: 63876636e97aSMatthew G Knepley . dm - the DM 63886636e97aSMatthew G Knepley 63896636e97aSMatthew G Knepley Output Parameter: 63906636e97aSMatthew G Knepley . c - coordinate vector 63916636e97aSMatthew G Knepley 63926636e97aSMatthew G Knepley Note: 63936636e97aSMatthew G Knepley This is a borrowed reference, so the user should NOT destroy this vector 63946636e97aSMatthew G Knepley 63956636e97aSMatthew G Knepley Each process has the local and ghost coordinates 63966636e97aSMatthew G Knepley 63976636e97aSMatthew G Knepley For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 63986636e97aSMatthew G Knepley and (x_0,y_0,z_0,x_1,y_1,z_1...) 63996636e97aSMatthew G Knepley 64006636e97aSMatthew G Knepley Level: intermediate 64016636e97aSMatthew G Knepley 640281e9a530SVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM(), DMGetCoordinatesLocalNoncollective() 64036636e97aSMatthew G Knepley @*/ 64046636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c) 64056636e97aSMatthew G Knepley { 64066636e97aSMatthew G Knepley PetscErrorCode ierr; 64076636e97aSMatthew G Knepley 64086636e97aSMatthew G Knepley PetscFunctionBegin; 64096636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 64106636e97aSMatthew G Knepley PetscValidPointer(c,2); 641181e9a530SVaclav Hapla ierr = DMGetCoordinatesLocalSetUp(dm);CHKERRQ(ierr); 64126636e97aSMatthew G Knepley *c = dm->coordinatesLocal; 64136636e97aSMatthew G Knepley PetscFunctionReturn(0); 64146636e97aSMatthew G Knepley } 64156636e97aSMatthew G Knepley 641681e9a530SVaclav Hapla /*@ 641781e9a530SVaclav Hapla DMGetCoordinatesLocalNoncollective - Non-collective version of DMGetCoordinatesLocal(). Fails if global coordinates have been set and DMGetCoordinatesLocalSetUp() not called. 641881e9a530SVaclav Hapla 641981e9a530SVaclav Hapla Not collective 642081e9a530SVaclav Hapla 642181e9a530SVaclav Hapla Input Parameter: 642281e9a530SVaclav Hapla . dm - the DM 642381e9a530SVaclav Hapla 642481e9a530SVaclav Hapla Output Parameter: 642581e9a530SVaclav Hapla . c - coordinate vector 642681e9a530SVaclav Hapla 642781e9a530SVaclav Hapla Level: advanced 642881e9a530SVaclav Hapla 642981e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalSetUp(), DMGetCoordinatesLocal(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM() 643081e9a530SVaclav Hapla @*/ 643181e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalNoncollective(DM dm, Vec *c) 643281e9a530SVaclav Hapla { 643381e9a530SVaclav Hapla PetscFunctionBegin; 643481e9a530SVaclav Hapla PetscValidHeaderSpecific(dm,DM_CLASSID,1); 643581e9a530SVaclav Hapla PetscValidPointer(c,2); 643681e9a530SVaclav Hapla if (!dm->coordinatesLocal && dm->coordinates) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called"); 64376636e97aSMatthew G Knepley *c = dm->coordinatesLocal; 64386636e97aSMatthew G Knepley PetscFunctionReturn(0); 64396636e97aSMatthew G Knepley } 64406636e97aSMatthew G Knepley 64412db98f8dSVaclav Hapla /*@ 64422db98f8dSVaclav Hapla DMGetCoordinatesLocalTuple - Gets a local vector with the coordinates of specified points and section describing its layout. 64432db98f8dSVaclav Hapla 64442db98f8dSVaclav Hapla Not collective 64452db98f8dSVaclav Hapla 6446d8d19677SJose E. Roman Input Parameters: 64472db98f8dSVaclav Hapla + dm - the DM 64482db98f8dSVaclav Hapla - p - the IS of points whose coordinates will be returned 64492db98f8dSVaclav Hapla 6450d8d19677SJose E. Roman Output Parameters: 64512db98f8dSVaclav Hapla + pCoordSection - the PetscSection describing the layout of pCoord, i.e. each point corresponds to one point in p, and DOFs correspond to coordinates 64522db98f8dSVaclav Hapla - pCoord - the Vec with coordinates of points in p 64532db98f8dSVaclav Hapla 64542db98f8dSVaclav Hapla Note: 64552db98f8dSVaclav Hapla DMGetCoordinatesLocalSetUp() must be called first. This function employs DMGetCoordinatesLocalNoncollective() so it is not collective. 64562db98f8dSVaclav Hapla 64572db98f8dSVaclav Hapla This creates a new vector, so the user SHOULD destroy this vector 64582db98f8dSVaclav Hapla 64592db98f8dSVaclav Hapla Each process has the local and ghost coordinates 64602db98f8dSVaclav Hapla 64612db98f8dSVaclav Hapla For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 64622db98f8dSVaclav Hapla and (x_0,y_0,z_0,x_1,y_1,z_1...) 64632db98f8dSVaclav Hapla 64642db98f8dSVaclav Hapla Level: advanced 64652db98f8dSVaclav Hapla 64662db98f8dSVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinatesLocal(), DMGetCoordinatesLocalNoncollective(), DMGetCoordinatesLocalSetUp(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM() 64672db98f8dSVaclav Hapla @*/ 64682db98f8dSVaclav Hapla PetscErrorCode DMGetCoordinatesLocalTuple(DM dm, IS p, PetscSection *pCoordSection, Vec *pCoord) 64692db98f8dSVaclav Hapla { 64702db98f8dSVaclav Hapla PetscSection cs, newcs; 64712db98f8dSVaclav Hapla Vec coords; 64722db98f8dSVaclav Hapla const PetscScalar *arr; 64732db98f8dSVaclav Hapla PetscScalar *newarr=NULL; 64742db98f8dSVaclav Hapla PetscInt n; 64752db98f8dSVaclav Hapla PetscErrorCode ierr; 64762db98f8dSVaclav Hapla 64772db98f8dSVaclav Hapla PetscFunctionBegin; 64782db98f8dSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 64792db98f8dSVaclav Hapla PetscValidHeaderSpecific(p, IS_CLASSID, 2); 64802db98f8dSVaclav Hapla if (pCoordSection) PetscValidPointer(pCoordSection, 3); 64812db98f8dSVaclav Hapla if (pCoord) PetscValidPointer(pCoord, 4); 64822db98f8dSVaclav Hapla if (!dm->coordinatesLocal) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called or coordinates not set"); 64831bb6d2a8SBarry Smith if (!dm->coordinateDM || !dm->coordinateDM->localSection) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM not supported"); 64841bb6d2a8SBarry Smith cs = dm->coordinateDM->localSection; 64852db98f8dSVaclav Hapla coords = dm->coordinatesLocal; 64862db98f8dSVaclav Hapla ierr = VecGetArrayRead(coords, &arr);CHKERRQ(ierr); 64872db98f8dSVaclav Hapla ierr = PetscSectionExtractDofsFromArray(cs, MPIU_SCALAR, arr, p, &newcs, pCoord ? ((void**)&newarr) : NULL);CHKERRQ(ierr); 64882db98f8dSVaclav Hapla ierr = VecRestoreArrayRead(coords, &arr);CHKERRQ(ierr); 64892db98f8dSVaclav Hapla if (pCoord) { 64902db98f8dSVaclav Hapla ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr); 64912db98f8dSVaclav Hapla /* set array in two steps to mimic PETSC_OWN_POINTER */ 64922db98f8dSVaclav Hapla ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)p), 1, n, NULL, pCoord);CHKERRQ(ierr); 64932db98f8dSVaclav Hapla ierr = VecReplaceArray(*pCoord, newarr);CHKERRQ(ierr); 6494ad9ac99dSVaclav Hapla } else { 6495ad9ac99dSVaclav Hapla ierr = PetscFree(newarr);CHKERRQ(ierr); 64962db98f8dSVaclav Hapla } 6497ad9ac99dSVaclav Hapla if (pCoordSection) {*pCoordSection = newcs;} 6498ad9ac99dSVaclav Hapla else {ierr = PetscSectionDestroy(&newcs);CHKERRQ(ierr);} 64992db98f8dSVaclav Hapla PetscFunctionReturn(0); 65002db98f8dSVaclav Hapla } 65012db98f8dSVaclav Hapla 6502f19dbd58SToby Isaac PetscErrorCode DMGetCoordinateField(DM dm, DMField *field) 6503f19dbd58SToby Isaac { 6504f19dbd58SToby Isaac PetscErrorCode ierr; 6505f19dbd58SToby Isaac 6506f19dbd58SToby Isaac PetscFunctionBegin; 6507f19dbd58SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6508f19dbd58SToby Isaac PetscValidPointer(field,2); 6509f19dbd58SToby Isaac if (!dm->coordinateField) { 6510f19dbd58SToby Isaac if (dm->ops->createcoordinatefield) { 6511f19dbd58SToby Isaac ierr = (*dm->ops->createcoordinatefield)(dm,&dm->coordinateField);CHKERRQ(ierr); 6512f19dbd58SToby Isaac } 6513f19dbd58SToby Isaac } 6514f19dbd58SToby Isaac *field = dm->coordinateField; 6515f19dbd58SToby Isaac PetscFunctionReturn(0); 6516f19dbd58SToby Isaac } 6517f19dbd58SToby Isaac 6518f19dbd58SToby Isaac PetscErrorCode DMSetCoordinateField(DM dm, DMField field) 6519f19dbd58SToby Isaac { 6520f19dbd58SToby Isaac PetscErrorCode ierr; 6521f19dbd58SToby Isaac 6522f19dbd58SToby Isaac PetscFunctionBegin; 6523f19dbd58SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6524f19dbd58SToby Isaac if (field) PetscValidHeaderSpecific(field,DMFIELD_CLASSID,2); 6525c4e6da2cSBarry Smith ierr = PetscObjectReference((PetscObject)field);CHKERRQ(ierr); 6526f19dbd58SToby Isaac ierr = DMFieldDestroy(&dm->coordinateField);CHKERRQ(ierr); 6527f19dbd58SToby Isaac dm->coordinateField = field; 6528f19dbd58SToby Isaac PetscFunctionReturn(0); 6529f19dbd58SToby Isaac } 6530f19dbd58SToby Isaac 65316636e97aSMatthew G Knepley /*@ 65321cfe2091SMatthew G. Knepley DMGetCoordinateDM - Gets the DM that prescribes coordinate layout and scatters between global and local coordinates 65336636e97aSMatthew G Knepley 6534d083f849SBarry Smith Collective on dm 65356636e97aSMatthew G Knepley 65366636e97aSMatthew G Knepley Input Parameter: 65376636e97aSMatthew G Knepley . dm - the DM 65386636e97aSMatthew G Knepley 65396636e97aSMatthew G Knepley Output Parameter: 65406636e97aSMatthew G Knepley . cdm - coordinate DM 65416636e97aSMatthew G Knepley 65426636e97aSMatthew G Knepley Level: intermediate 65436636e97aSMatthew G Knepley 65441cfe2091SMatthew G. Knepley .seealso: DMSetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal() 65456636e97aSMatthew G Knepley @*/ 65466636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm) 65476636e97aSMatthew G Knepley { 65486636e97aSMatthew G Knepley PetscErrorCode ierr; 65496636e97aSMatthew G Knepley 65506636e97aSMatthew G Knepley PetscFunctionBegin; 65516636e97aSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 65526636e97aSMatthew G Knepley PetscValidPointer(cdm,2); 65536636e97aSMatthew G Knepley if (!dm->coordinateDM) { 6554308f8a94SToby Isaac DM cdm; 6555308f8a94SToby Isaac 655682f516ccSBarry Smith if (!dm->ops->createcoordinatedm) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unable to create coordinates for this DM"); 6557308f8a94SToby Isaac ierr = (*dm->ops->createcoordinatedm)(dm, &cdm);CHKERRQ(ierr); 6558c9ad657eSksagiyam ierr = PetscObjectSetName((PetscObject)cdm, "coordinateDM");CHKERRQ(ierr); 6559308f8a94SToby Isaac /* Just in case the DM sets the coordinate DM when creating it (DMP4est can do this, because it may not setup 6560308f8a94SToby Isaac * until the call to CreateCoordinateDM) */ 6561308f8a94SToby Isaac ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr); 6562308f8a94SToby Isaac dm->coordinateDM = cdm; 65636636e97aSMatthew G Knepley } 65646636e97aSMatthew G Knepley *cdm = dm->coordinateDM; 65656636e97aSMatthew G Knepley PetscFunctionReturn(0); 65666636e97aSMatthew G Knepley } 6567e87bb0d3SMatthew G Knepley 65681cfe2091SMatthew G. Knepley /*@ 65691cfe2091SMatthew G. Knepley DMSetCoordinateDM - Sets the DM that prescribes coordinate layout and scatters between global and local coordinates 65701cfe2091SMatthew G. Knepley 6571d083f849SBarry Smith Logically Collective on dm 65721cfe2091SMatthew G. Knepley 65731cfe2091SMatthew G. Knepley Input Parameters: 65741cfe2091SMatthew G. Knepley + dm - the DM 65751cfe2091SMatthew G. Knepley - cdm - coordinate DM 65761cfe2091SMatthew G. Knepley 65771cfe2091SMatthew G. Knepley Level: intermediate 65781cfe2091SMatthew G. Knepley 65791cfe2091SMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal() 65801cfe2091SMatthew G. Knepley @*/ 65811cfe2091SMatthew G. Knepley PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm) 65821cfe2091SMatthew G. Knepley { 65831cfe2091SMatthew G. Knepley PetscErrorCode ierr; 65841cfe2091SMatthew G. Knepley 65851cfe2091SMatthew G. Knepley PetscFunctionBegin; 65861cfe2091SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 65871cfe2091SMatthew G. Knepley PetscValidHeaderSpecific(cdm,DM_CLASSID,2); 6588f26b38b9SToby Isaac ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr); 65891cfe2091SMatthew G. Knepley ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr); 65901cfe2091SMatthew G. Knepley dm->coordinateDM = cdm; 65911cfe2091SMatthew G. Knepley PetscFunctionReturn(0); 65921cfe2091SMatthew G. Knepley } 65931cfe2091SMatthew G. Knepley 659446e270d4SMatthew G. Knepley /*@ 659546e270d4SMatthew G. Knepley DMGetCoordinateDim - Retrieve the dimension of embedding space for coordinate values. 659646e270d4SMatthew G. Knepley 659746e270d4SMatthew G. Knepley Not Collective 659846e270d4SMatthew G. Knepley 659946e270d4SMatthew G. Knepley Input Parameter: 660046e270d4SMatthew G. Knepley . dm - The DM object 660146e270d4SMatthew G. Knepley 660246e270d4SMatthew G. Knepley Output Parameter: 660346e270d4SMatthew G. Knepley . dim - The embedding dimension 660446e270d4SMatthew G. Knepley 660546e270d4SMatthew G. Knepley Level: intermediate 660646e270d4SMatthew G. Knepley 660792fd8e1eSJed Brown .seealso: DMSetCoordinateDim(), DMGetCoordinateSection(), DMGetCoordinateDM(), DMGetLocalSection(), DMSetLocalSection() 660846e270d4SMatthew G. Knepley @*/ 660946e270d4SMatthew G. Knepley PetscErrorCode DMGetCoordinateDim(DM dm, PetscInt *dim) 661046e270d4SMatthew G. Knepley { 661146e270d4SMatthew G. Knepley PetscFunctionBegin; 661246e270d4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6613534a8f05SLisandro Dalcin PetscValidIntPointer(dim, 2); 66149a9a41abSToby Isaac if (dm->dimEmbed == PETSC_DEFAULT) { 66159a9a41abSToby Isaac dm->dimEmbed = dm->dim; 66169a9a41abSToby Isaac } 661746e270d4SMatthew G. Knepley *dim = dm->dimEmbed; 661846e270d4SMatthew G. Knepley PetscFunctionReturn(0); 661946e270d4SMatthew G. Knepley } 662046e270d4SMatthew G. Knepley 662146e270d4SMatthew G. Knepley /*@ 662246e270d4SMatthew G. Knepley DMSetCoordinateDim - Set the dimension of the embedding space for coordinate values. 662346e270d4SMatthew G. Knepley 662446e270d4SMatthew G. Knepley Not Collective 662546e270d4SMatthew G. Knepley 662646e270d4SMatthew G. Knepley Input Parameters: 662746e270d4SMatthew G. Knepley + dm - The DM object 662846e270d4SMatthew G. Knepley - dim - The embedding dimension 662946e270d4SMatthew G. Knepley 663046e270d4SMatthew G. Knepley Level: intermediate 663146e270d4SMatthew G. Knepley 663292fd8e1eSJed Brown .seealso: DMGetCoordinateDim(), DMSetCoordinateSection(), DMGetCoordinateSection(), DMGetLocalSection(), DMSetLocalSection() 663346e270d4SMatthew G. Knepley @*/ 663446e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateDim(DM dm, PetscInt dim) 663546e270d4SMatthew G. Knepley { 6636e5e52638SMatthew G. Knepley PetscDS ds; 663745480ffeSMatthew G. Knepley PetscInt Nds, n; 6638f17e8794SMatthew G. Knepley PetscErrorCode ierr; 6639f17e8794SMatthew G. Knepley 664046e270d4SMatthew G. Knepley PetscFunctionBegin; 664146e270d4SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 664246e270d4SMatthew G. Knepley dm->dimEmbed = dim; 6643d17bd122SMatthew G. Knepley if (dm->dim >= 0) { 664445480ffeSMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 664545480ffeSMatthew G. Knepley for (n = 0; n < Nds; ++n) { 664645480ffeSMatthew G. Knepley ierr = DMGetRegionNumDS(dm, n, NULL, NULL, &ds);CHKERRQ(ierr); 6647e5e52638SMatthew G. Knepley ierr = PetscDSSetCoordinateDimension(ds, dim);CHKERRQ(ierr); 664845480ffeSMatthew G. Knepley } 6649d17bd122SMatthew G. Knepley } 665046e270d4SMatthew G. Knepley PetscFunctionReturn(0); 665146e270d4SMatthew G. Knepley } 665246e270d4SMatthew G. Knepley 6653e8abe2deSMatthew G. Knepley /*@ 6654e8abe2deSMatthew G. Knepley DMGetCoordinateSection - Retrieve the layout of coordinate values over the mesh. 6655e8abe2deSMatthew G. Knepley 6656d083f849SBarry Smith Collective on dm 6657e8abe2deSMatthew G. Knepley 6658e8abe2deSMatthew G. Knepley Input Parameter: 6659e8abe2deSMatthew G. Knepley . dm - The DM object 6660e8abe2deSMatthew G. Knepley 6661e8abe2deSMatthew G. Knepley Output Parameter: 6662e8abe2deSMatthew G. Knepley . section - The PetscSection object 6663e8abe2deSMatthew G. Knepley 6664e8abe2deSMatthew G. Knepley Level: intermediate 6665e8abe2deSMatthew G. Knepley 666692fd8e1eSJed Brown .seealso: DMGetCoordinateDM(), DMGetLocalSection(), DMSetLocalSection() 6667e8abe2deSMatthew G. Knepley @*/ 6668e8abe2deSMatthew G. Knepley PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section) 6669e8abe2deSMatthew G. Knepley { 6670e8abe2deSMatthew G. Knepley DM cdm; 6671e8abe2deSMatthew G. Knepley PetscErrorCode ierr; 6672e8abe2deSMatthew G. Knepley 6673e8abe2deSMatthew G. Knepley PetscFunctionBegin; 6674e8abe2deSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6675e8abe2deSMatthew G. Knepley PetscValidPointer(section, 2); 6676e8abe2deSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 667792fd8e1eSJed Brown ierr = DMGetLocalSection(cdm, section);CHKERRQ(ierr); 6678e8abe2deSMatthew G. Knepley PetscFunctionReturn(0); 6679e8abe2deSMatthew G. Knepley } 6680e8abe2deSMatthew G. Knepley 6681e8abe2deSMatthew G. Knepley /*@ 6682e8abe2deSMatthew G. Knepley DMSetCoordinateSection - Set the layout of coordinate values over the mesh. 6683e8abe2deSMatthew G. Knepley 6684e8abe2deSMatthew G. Knepley Not Collective 6685e8abe2deSMatthew G. Knepley 6686e8abe2deSMatthew G. Knepley Input Parameters: 6687e8abe2deSMatthew G. Knepley + dm - The DM object 668846e270d4SMatthew G. Knepley . dim - The embedding dimension, or PETSC_DETERMINE 6689e8abe2deSMatthew G. Knepley - section - The PetscSection object 6690e8abe2deSMatthew G. Knepley 6691e8abe2deSMatthew G. Knepley Level: intermediate 6692e8abe2deSMatthew G. Knepley 669392fd8e1eSJed Brown .seealso: DMGetCoordinateSection(), DMGetLocalSection(), DMSetLocalSection() 6694e8abe2deSMatthew G. Knepley @*/ 669546e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateSection(DM dm, PetscInt dim, PetscSection section) 6696e8abe2deSMatthew G. Knepley { 6697e8abe2deSMatthew G. Knepley DM cdm; 6698e8abe2deSMatthew G. Knepley PetscErrorCode ierr; 6699e8abe2deSMatthew G. Knepley 6700e8abe2deSMatthew G. Knepley PetscFunctionBegin; 6701e8abe2deSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 670246e270d4SMatthew G. Knepley PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,3); 6703e8abe2deSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 670492fd8e1eSJed Brown ierr = DMSetLocalSection(cdm, section);CHKERRQ(ierr); 670546e270d4SMatthew G. Knepley if (dim == PETSC_DETERMINE) { 67064c1069a6SMatthew G. Knepley PetscInt d = PETSC_DEFAULT; 670746e270d4SMatthew G. Knepley PetscInt pStart, pEnd, vStart, vEnd, v, dd; 670846e270d4SMatthew G. Knepley 670946e270d4SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 671046e270d4SMatthew G. Knepley ierr = DMGetDimPoints(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 671146e270d4SMatthew G. Knepley pStart = PetscMax(vStart, pStart); 671246e270d4SMatthew G. Knepley pEnd = PetscMin(vEnd, pEnd); 671346e270d4SMatthew G. Knepley for (v = pStart; v < pEnd; ++v) { 671446e270d4SMatthew G. Knepley ierr = PetscSectionGetDof(section, v, &dd);CHKERRQ(ierr); 671546e270d4SMatthew G. Knepley if (dd) {d = dd; break;} 671646e270d4SMatthew G. Knepley } 6717ebfe4b0dSMatthew G. Knepley if (d >= 0) {ierr = DMSetCoordinateDim(dm, d);CHKERRQ(ierr);} 671846e270d4SMatthew G. Knepley } 6719e8abe2deSMatthew G. Knepley PetscFunctionReturn(0); 6720e8abe2deSMatthew G. Knepley } 6721e8abe2deSMatthew G. Knepley 6722d864a3eaSLisandro Dalcin /*@ 6723d864a3eaSLisandro Dalcin DMProjectCoordinates - Project coordinates to a different space 6724d864a3eaSLisandro Dalcin 6725d864a3eaSLisandro Dalcin Input Parameters: 6726d864a3eaSLisandro Dalcin + dm - The DM object 6727d864a3eaSLisandro Dalcin - disc - The new coordinate discretization 6728d864a3eaSLisandro Dalcin 6729d864a3eaSLisandro Dalcin Level: intermediate 6730d864a3eaSLisandro Dalcin 6731d864a3eaSLisandro Dalcin .seealso: DMGetCoordinateField() 6732d864a3eaSLisandro Dalcin @*/ 6733d864a3eaSLisandro Dalcin PetscErrorCode DMProjectCoordinates(DM dm, PetscFE disc) 6734d864a3eaSLisandro Dalcin { 6735d864a3eaSLisandro Dalcin PetscObject discOld; 6736d864a3eaSLisandro Dalcin PetscClassId classid; 6737d864a3eaSLisandro Dalcin DM cdmOld,cdmNew; 6738d864a3eaSLisandro Dalcin Vec coordsOld,coordsNew; 6739d864a3eaSLisandro Dalcin Mat matInterp; 6740d864a3eaSLisandro Dalcin PetscErrorCode ierr; 6741d864a3eaSLisandro Dalcin 6742d864a3eaSLisandro Dalcin PetscFunctionBegin; 6743d864a3eaSLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6744d864a3eaSLisandro Dalcin PetscValidHeaderSpecific(disc,PETSCFE_CLASSID,2); 6745d864a3eaSLisandro Dalcin 6746d864a3eaSLisandro Dalcin ierr = DMGetCoordinateDM(dm, &cdmOld);CHKERRQ(ierr); 6747d864a3eaSLisandro Dalcin /* Check current discretization is compatible */ 6748d864a3eaSLisandro Dalcin ierr = DMGetField(cdmOld, 0, NULL, &discOld);CHKERRQ(ierr); 6749d864a3eaSLisandro Dalcin ierr = PetscObjectGetClassId(discOld, &classid);CHKERRQ(ierr); 675029ad44c5SMatthew G. Knepley if (classid != PETSCFE_CLASSID) { 675129ad44c5SMatthew G. Knepley if (classid == PETSC_CONTAINER_CLASSID) { 675229ad44c5SMatthew G. Knepley PetscFE feLinear; 675329ad44c5SMatthew G. Knepley DMPolytopeType ct; 675429ad44c5SMatthew G. Knepley PetscInt dim, dE, cStart; 675529ad44c5SMatthew G. Knepley PetscBool simplex; 675629ad44c5SMatthew G. Knepley 675729ad44c5SMatthew G. Knepley /* Assume linear vertex coordinates */ 675829ad44c5SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 675929ad44c5SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 676029ad44c5SMatthew G. Knepley ierr = DMPlexGetHeightStratum(cdmOld, 0, &cStart, NULL);CHKERRQ(ierr); 676129ad44c5SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 676229ad44c5SMatthew G. Knepley switch (ct) { 676329ad44c5SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 676429ad44c5SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 676529ad44c5SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot autoamtically create coordinate space for prisms"); 676629ad44c5SMatthew G. Knepley default: break; 676729ad44c5SMatthew G. Knepley } 676829ad44c5SMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 676929ad44c5SMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, dE, simplex, 1, -1, &feLinear);CHKERRQ(ierr); 677029ad44c5SMatthew G. Knepley ierr = DMSetField(cdmOld, 0, NULL, (PetscObject) feLinear);CHKERRQ(ierr); 677129ad44c5SMatthew G. Knepley ierr = PetscFEDestroy(&feLinear);CHKERRQ(ierr); 677229ad44c5SMatthew G. Knepley ierr = DMCreateDS(cdmOld);CHKERRQ(ierr); 677329ad44c5SMatthew G. Knepley } else { 677429ad44c5SMatthew G. Knepley const char *discname; 677529ad44c5SMatthew G. Knepley 677629ad44c5SMatthew G. Knepley ierr = PetscObjectGetType(discOld, &discname);CHKERRQ(ierr); 677729ad44c5SMatthew G. Knepley SETERRQ1(PetscObjectComm(discOld), PETSC_ERR_SUP, "Discretization type %s not supported", discname); 677829ad44c5SMatthew G. Knepley } 677929ad44c5SMatthew G. Knepley } 6780d864a3eaSLisandro Dalcin /* Make a fresh clone of the coordinate DM */ 6781d864a3eaSLisandro Dalcin ierr = DMClone(cdmOld, &cdmNew);CHKERRQ(ierr); 6782d864a3eaSLisandro Dalcin ierr = DMSetField(cdmNew, 0, NULL, (PetscObject) disc);CHKERRQ(ierr); 6783d864a3eaSLisandro Dalcin ierr = DMCreateDS(cdmNew);CHKERRQ(ierr); 6784d864a3eaSLisandro Dalcin /* Project the coordinate vector from old to new space */ 6785d864a3eaSLisandro Dalcin ierr = DMGetCoordinates(dm, &coordsOld);CHKERRQ(ierr); 6786d864a3eaSLisandro Dalcin ierr = DMCreateGlobalVector(cdmNew, &coordsNew);CHKERRQ(ierr); 6787d864a3eaSLisandro Dalcin ierr = DMCreateInterpolation(cdmOld, cdmNew, &matInterp, NULL);CHKERRQ(ierr); 6788d864a3eaSLisandro Dalcin ierr = MatInterpolate(matInterp, coordsOld, coordsNew);CHKERRQ(ierr); 6789d864a3eaSLisandro Dalcin ierr = MatDestroy(&matInterp);CHKERRQ(ierr); 6790d864a3eaSLisandro Dalcin /* Set new coordinate structures */ 6791d864a3eaSLisandro Dalcin ierr = DMSetCoordinateField(dm, NULL);CHKERRQ(ierr); 6792d864a3eaSLisandro Dalcin ierr = DMSetCoordinateDM(dm, cdmNew);CHKERRQ(ierr); 6793d864a3eaSLisandro Dalcin ierr = DMSetCoordinates(dm, coordsNew);CHKERRQ(ierr); 6794d864a3eaSLisandro Dalcin ierr = VecDestroy(&coordsNew);CHKERRQ(ierr); 6795d864a3eaSLisandro Dalcin ierr = DMDestroy(&cdmNew);CHKERRQ(ierr); 6796d864a3eaSLisandro Dalcin PetscFunctionReturn(0); 6797d864a3eaSLisandro Dalcin } 6798d864a3eaSLisandro Dalcin 67995dc8c3f7SMatthew G. Knepley /*@C 680090b157c4SStefano Zampini DMGetPeriodicity - Get the description of mesh periodicity 68015dc8c3f7SMatthew G. Knepley 6802f899ff85SJose E. Roman Input Parameter: 680390b157c4SStefano Zampini . dm - The DM object 680490b157c4SStefano Zampini 680590b157c4SStefano Zampini Output Parameters: 680690b157c4SStefano Zampini + per - Whether the DM is periodic or not 68075dc8c3f7SMatthew 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 68085dc8c3f7SMatthew G. Knepley . L - If we assume the mesh is a torus, this is the length of each coordinate 68095dc8c3f7SMatthew G. Knepley - bd - This describes the type of periodicity in each topological dimension 68105dc8c3f7SMatthew G. Knepley 68115dc8c3f7SMatthew G. Knepley Level: developer 68125dc8c3f7SMatthew G. Knepley 68135dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity() 68145dc8c3f7SMatthew G. Knepley @*/ 681590b157c4SStefano Zampini PetscErrorCode DMGetPeriodicity(DM dm, PetscBool *per, const PetscReal **maxCell, const PetscReal **L, const DMBoundaryType **bd) 6816c6b900c6SMatthew G. Knepley { 6817c6b900c6SMatthew G. Knepley PetscFunctionBegin; 6818c6b900c6SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 681990b157c4SStefano Zampini if (per) *per = dm->periodic; 6820c6b900c6SMatthew G. Knepley if (L) *L = dm->L; 6821c6b900c6SMatthew G. Knepley if (maxCell) *maxCell = dm->maxCell; 68225dc8c3f7SMatthew G. Knepley if (bd) *bd = dm->bdtype; 6823c6b900c6SMatthew G. Knepley PetscFunctionReturn(0); 6824c6b900c6SMatthew G. Knepley } 6825c6b900c6SMatthew G. Knepley 68265dc8c3f7SMatthew G. Knepley /*@C 68275dc8c3f7SMatthew G. Knepley DMSetPeriodicity - Set the description of mesh periodicity 68285dc8c3f7SMatthew G. Knepley 68295dc8c3f7SMatthew G. Knepley Input Parameters: 68305dc8c3f7SMatthew G. Knepley + dm - The DM object 6831db2bf62eSStefano Zampini . per - Whether the DM is periodic or not. 6832db2bf62eSStefano 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. 68335dc8c3f7SMatthew G. Knepley . L - If we assume the mesh is a torus, this is the length of each coordinate 68345dc8c3f7SMatthew G. Knepley - bd - This describes the type of periodicity in each topological dimension 68355dc8c3f7SMatthew G. Knepley 6836db2bf62eSStefano 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. 6837db2bf62eSStefano Zampini 68385dc8c3f7SMatthew G. Knepley Level: developer 68395dc8c3f7SMatthew G. Knepley 68405dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity() 68415dc8c3f7SMatthew G. Knepley @*/ 684290b157c4SStefano Zampini PetscErrorCode DMSetPeriodicity(DM dm, PetscBool per, const PetscReal maxCell[], const PetscReal L[], const DMBoundaryType bd[]) 6843c6b900c6SMatthew G. Knepley { 6844c6b900c6SMatthew G. Knepley PetscInt dim, d; 6845c6b900c6SMatthew G. Knepley PetscErrorCode ierr; 6846c6b900c6SMatthew G. Knepley 6847c6b900c6SMatthew G. Knepley PetscFunctionBegin; 6848c6b900c6SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 684990b157c4SStefano Zampini PetscValidLogicalCollectiveBool(dm,per,2); 6850412e9a14SMatthew G. Knepley if (maxCell) {PetscValidRealPointer(maxCell,3);} 6851412e9a14SMatthew G. Knepley if (L) {PetscValidRealPointer(L,4);} 6852412e9a14SMatthew G. Knepley if (bd) {PetscValidPointer(bd,5);} 68535dc8c3f7SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 685490b157c4SStefano Zampini if (maxCell) { 6855412e9a14SMatthew G. Knepley if (!dm->maxCell) {ierr = PetscMalloc1(dim, &dm->maxCell);CHKERRQ(ierr);} 6856412e9a14SMatthew G. Knepley for (d = 0; d < dim; ++d) dm->maxCell[d] = maxCell[d]; 6857db2bf62eSStefano Zampini } else { /* remove maxCell information to disable automatic computation of localized vertices */ 6858db2bf62eSStefano Zampini ierr = PetscFree(dm->maxCell);CHKERRQ(ierr); 6859412e9a14SMatthew G. Knepley } 6860db2bf62eSStefano Zampini 6861412e9a14SMatthew G. Knepley if (L) { 6862412e9a14SMatthew G. Knepley if (!dm->L) {ierr = PetscMalloc1(dim, &dm->L);CHKERRQ(ierr);} 6863412e9a14SMatthew G. Knepley for (d = 0; d < dim; ++d) dm->L[d] = L[d]; 6864412e9a14SMatthew G. Knepley } 6865412e9a14SMatthew G. Knepley if (bd) { 6866412e9a14SMatthew G. Knepley if (!dm->bdtype) {ierr = PetscMalloc1(dim, &dm->bdtype);CHKERRQ(ierr);} 6867412e9a14SMatthew G. Knepley for (d = 0; d < dim; ++d) dm->bdtype[d] = bd[d]; 686890b157c4SStefano Zampini } 6869072d7d67SStefano Zampini dm->periodic = per; 6870c6b900c6SMatthew G. Knepley PetscFunctionReturn(0); 6871c6b900c6SMatthew G. Knepley } 6872c6b900c6SMatthew G. Knepley 68732e17dfb7SMatthew G. Knepley /*@ 68742e17dfb7SMatthew 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. 68752e17dfb7SMatthew G. Knepley 68762e17dfb7SMatthew G. Knepley Input Parameters: 68772e17dfb7SMatthew G. Knepley + dm - The DM 687865da65dcSMatthew G. Knepley . in - The input coordinate point (dim numbers) 687965da65dcSMatthew G. Knepley - endpoint - Include the endpoint L_i 68802e17dfb7SMatthew G. Knepley 68812e17dfb7SMatthew G. Knepley Output Parameter: 68822e17dfb7SMatthew G. Knepley . out - The localized coordinate point 68832e17dfb7SMatthew G. Knepley 68842e17dfb7SMatthew G. Knepley Level: developer 68852e17dfb7SMatthew G. Knepley 68862e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate() 68872e17dfb7SMatthew G. Knepley @*/ 688865da65dcSMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate(DM dm, const PetscScalar in[], PetscBool endpoint, PetscScalar out[]) 68892e17dfb7SMatthew G. Knepley { 68902e17dfb7SMatthew G. Knepley PetscInt dim, d; 68912e17dfb7SMatthew G. Knepley PetscErrorCode ierr; 68922e17dfb7SMatthew G. Knepley 68932e17dfb7SMatthew G. Knepley PetscFunctionBegin; 68942e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 68952e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 68962e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 68972e17dfb7SMatthew G. Knepley } else { 689865da65dcSMatthew G. Knepley if (endpoint) { 689965da65dcSMatthew G. Knepley for (d = 0; d < dim; ++d) { 6900da3333bfSMatthew 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)) { 6901da3333bfSMatthew G. Knepley out[d] = in[d] - dm->L[d]*(PetscFloorReal(PetscRealPart(in[d])/dm->L[d]) - 1); 690265da65dcSMatthew G. Knepley } else { 6903da3333bfSMatthew G. Knepley out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]); 690465da65dcSMatthew G. Knepley } 690565da65dcSMatthew G. Knepley } 690665da65dcSMatthew G. Knepley } else { 69072e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 69081118d4bcSLisandro Dalcin out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]); 69092e17dfb7SMatthew G. Knepley } 69102e17dfb7SMatthew G. Knepley } 691165da65dcSMatthew G. Knepley } 69122e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 69132e17dfb7SMatthew G. Knepley } 69142e17dfb7SMatthew G. Knepley 69152e17dfb7SMatthew G. Knepley /* 69162e17dfb7SMatthew 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. 69172e17dfb7SMatthew G. Knepley 69182e17dfb7SMatthew G. Knepley Input Parameters: 69192e17dfb7SMatthew G. Knepley + dm - The DM 69202e17dfb7SMatthew G. Knepley . dim - The spatial dimension 69212e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it 69222e17dfb7SMatthew G. Knepley - in - The input coordinate point (dim numbers) 69232e17dfb7SMatthew G. Knepley 69242e17dfb7SMatthew G. Knepley Output Parameter: 69252e17dfb7SMatthew G. Knepley . out - The localized coordinate point 69262e17dfb7SMatthew G. Knepley 69272e17dfb7SMatthew G. Knepley Level: developer 69282e17dfb7SMatthew G. Knepley 69292e17dfb7SMatthew 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 69302e17dfb7SMatthew G. Knepley 69312e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate() 69322e17dfb7SMatthew G. Knepley */ 69332e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[]) 69342e17dfb7SMatthew G. Knepley { 69352e17dfb7SMatthew G. Knepley PetscInt d; 69362e17dfb7SMatthew G. Knepley 69372e17dfb7SMatthew G. Knepley PetscFunctionBegin; 69382e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 69392e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 69402e17dfb7SMatthew G. Knepley } else { 69412e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 6942908eca10SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) { 69432e17dfb7SMatthew G. Knepley out[d] = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d]; 69442e17dfb7SMatthew G. Knepley } else { 69452e17dfb7SMatthew G. Knepley out[d] = in[d]; 69462e17dfb7SMatthew G. Knepley } 69472e17dfb7SMatthew G. Knepley } 69482e17dfb7SMatthew G. Knepley } 69492e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 69502e17dfb7SMatthew G. Knepley } 6951a5801f52SStefano Zampini 69522e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinateReal_Internal(DM dm, PetscInt dim, const PetscReal anchor[], const PetscReal in[], PetscReal out[]) 69532e17dfb7SMatthew G. Knepley { 69542e17dfb7SMatthew G. Knepley PetscInt d; 69552e17dfb7SMatthew G. Knepley 69562e17dfb7SMatthew G. Knepley PetscFunctionBegin; 69572e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 69582e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 69592e17dfb7SMatthew G. Knepley } else { 69602e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 6961908eca10SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsReal(anchor[d] - in[d]) > dm->maxCell[d])) { 69622e17dfb7SMatthew G. Knepley out[d] = anchor[d] > in[d] ? dm->L[d] + in[d] : in[d] - dm->L[d]; 69632e17dfb7SMatthew G. Knepley } else { 69642e17dfb7SMatthew G. Knepley out[d] = in[d]; 69652e17dfb7SMatthew G. Knepley } 69662e17dfb7SMatthew G. Knepley } 69672e17dfb7SMatthew G. Knepley } 69682e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 69692e17dfb7SMatthew G. Knepley } 69702e17dfb7SMatthew G. Knepley 69712e17dfb7SMatthew G. Knepley /* 69722e17dfb7SMatthew 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. 69732e17dfb7SMatthew G. Knepley 69742e17dfb7SMatthew G. Knepley Input Parameters: 69752e17dfb7SMatthew G. Knepley + dm - The DM 69762e17dfb7SMatthew G. Knepley . dim - The spatial dimension 69772e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it 69782e17dfb7SMatthew G. Knepley . in - The input coordinate delta (dim numbers) 69792e17dfb7SMatthew G. Knepley - out - The input coordinate point (dim numbers) 69802e17dfb7SMatthew G. Knepley 69812e17dfb7SMatthew G. Knepley Output Parameter: 69822e17dfb7SMatthew G. Knepley . out - The localized coordinate in + out 69832e17dfb7SMatthew G. Knepley 69842e17dfb7SMatthew G. Knepley Level: developer 69852e17dfb7SMatthew G. Knepley 69862e17dfb7SMatthew 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 69872e17dfb7SMatthew G. Knepley 69882e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeCoordinate() 69892e17dfb7SMatthew G. Knepley */ 69902e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeAddCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[]) 69912e17dfb7SMatthew G. Knepley { 69922e17dfb7SMatthew G. Knepley PetscInt d; 69932e17dfb7SMatthew G. Knepley 69942e17dfb7SMatthew G. Knepley PetscFunctionBegin; 69952e17dfb7SMatthew G. Knepley if (!dm->maxCell) { 69962e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] += in[d]; 69972e17dfb7SMatthew G. Knepley } else { 69982e17dfb7SMatthew G. Knepley for (d = 0; d < dim; ++d) { 6999412e9a14SMatthew G. Knepley const PetscReal maxC = dm->maxCell[d]; 7000412e9a14SMatthew G. Knepley 7001412e9a14SMatthew G. Knepley if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > maxC)) { 7002412e9a14SMatthew G. Knepley const PetscScalar newCoord = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d]; 7003412e9a14SMatthew G. Knepley 7004412e9a14SMatthew G. Knepley if (PetscAbsScalar(newCoord - anchor[d]) > maxC) 7005412e9a14SMatthew 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])); 7006412e9a14SMatthew G. Knepley out[d] += newCoord; 70072e17dfb7SMatthew G. Knepley } else { 70082e17dfb7SMatthew G. Knepley out[d] += in[d]; 70092e17dfb7SMatthew G. Knepley } 70102e17dfb7SMatthew G. Knepley } 70112e17dfb7SMatthew G. Knepley } 70122e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 70132e17dfb7SMatthew G. Knepley } 70142e17dfb7SMatthew G. Knepley 701536447a5eSToby Isaac /*@ 70168f700142SStefano Zampini DMGetCoordinatesLocalizedLocal - Check if the DM coordinates have been localized for cells on this process 70178f700142SStefano Zampini 70188f700142SStefano Zampini Not collective 701936447a5eSToby Isaac 702036447a5eSToby Isaac Input Parameter: 702136447a5eSToby Isaac . dm - The DM 702236447a5eSToby Isaac 702336447a5eSToby Isaac Output Parameter: 702436447a5eSToby Isaac areLocalized - True if localized 702536447a5eSToby Isaac 702636447a5eSToby Isaac Level: developer 702736447a5eSToby Isaac 70288f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMGetCoordinatesLocalized(), DMSetPeriodicity() 702936447a5eSToby Isaac @*/ 70308f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalizedLocal(DM dm,PetscBool *areLocalized) 703136447a5eSToby Isaac { 703236447a5eSToby Isaac DM cdm; 703336447a5eSToby Isaac PetscSection coordSection; 70342ccac677SMatthew G. Knepley PetscInt depth, cStart, cEnd, sStart, sEnd, c, dof; 703546a3a80fSLisandro Dalcin PetscBool isPlex, alreadyLocalized; 703636447a5eSToby Isaac PetscErrorCode ierr; 703736447a5eSToby Isaac 703836447a5eSToby Isaac PetscFunctionBegin; 703936447a5eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7040534a8f05SLisandro Dalcin PetscValidBoolPointer(areLocalized, 2); 70418b09590cSToby Isaac *areLocalized = PETSC_FALSE; 704246a3a80fSLisandro Dalcin 704336447a5eSToby Isaac /* We need some generic way of refering to cells/vertices */ 704436447a5eSToby Isaac ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 704546a3a80fSLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isPlex);CHKERRQ(ierr); 70469f7230bfSMatthew G. Knepley if (!isPlex) PetscFunctionReturn(0); 70472ccac677SMatthew G. Knepley ierr = DMPlexGetDepth(cdm, &depth);CHKERRQ(ierr); 70482ccac677SMatthew G. Knepley if (!depth) PetscFunctionReturn(0); 704946a3a80fSLisandro Dalcin 70509f7230bfSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 705146a3a80fSLisandro Dalcin ierr = DMPlexGetHeightStratum(cdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 705236447a5eSToby Isaac ierr = PetscSectionGetChart(coordSection, &sStart, &sEnd);CHKERRQ(ierr); 705336447a5eSToby Isaac alreadyLocalized = PETSC_FALSE; 705446a3a80fSLisandro Dalcin for (c = cStart; c < cEnd; ++c) { 705546a3a80fSLisandro Dalcin if (c < sStart || c >= sEnd) continue; 705636447a5eSToby Isaac ierr = PetscSectionGetDof(coordSection, c, &dof);CHKERRQ(ierr); 705746a3a80fSLisandro Dalcin if (dof) { alreadyLocalized = PETSC_TRUE; break; } 705836447a5eSToby Isaac } 70598f700142SStefano Zampini *areLocalized = alreadyLocalized; 706036447a5eSToby Isaac PetscFunctionReturn(0); 706136447a5eSToby Isaac } 706236447a5eSToby Isaac 70638f700142SStefano Zampini /*@ 70648f700142SStefano Zampini DMGetCoordinatesLocalized - Check if the DM coordinates have been localized for cells 70658f700142SStefano Zampini 70668f700142SStefano Zampini Collective on dm 70678f700142SStefano Zampini 70688f700142SStefano Zampini Input Parameter: 70698f700142SStefano Zampini . dm - The DM 70708f700142SStefano Zampini 70718f700142SStefano Zampini Output Parameter: 70728f700142SStefano Zampini areLocalized - True if localized 70738f700142SStefano Zampini 70748f700142SStefano Zampini Level: developer 70758f700142SStefano Zampini 70768f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMSetPeriodicity(), DMGetCoordinatesLocalizedLocal() 70778f700142SStefano Zampini @*/ 70788f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalized(DM dm,PetscBool *areLocalized) 70798f700142SStefano Zampini { 70808f700142SStefano Zampini PetscBool localized; 70818f700142SStefano Zampini PetscErrorCode ierr; 70828f700142SStefano Zampini 70838f700142SStefano Zampini PetscFunctionBegin; 70848f700142SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7085534a8f05SLisandro Dalcin PetscValidBoolPointer(areLocalized, 2); 70868f700142SStefano Zampini ierr = DMGetCoordinatesLocalizedLocal(dm,&localized);CHKERRQ(ierr); 7087820f2d46SBarry Smith ierr = MPIU_Allreduce(&localized,areLocalized,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 70888f700142SStefano Zampini PetscFunctionReturn(0); 70898f700142SStefano Zampini } 709036447a5eSToby Isaac 70912e17dfb7SMatthew G. Knepley /*@ 7092492b8470SStefano Zampini DMLocalizeCoordinates - If a mesh is periodic, create local coordinates for cells having periodic faces 70932e17dfb7SMatthew G. Knepley 70948f700142SStefano Zampini Collective on dm 70958f700142SStefano Zampini 70962e17dfb7SMatthew G. Knepley Input Parameter: 70972e17dfb7SMatthew G. Knepley . dm - The DM 70982e17dfb7SMatthew G. Knepley 70992e17dfb7SMatthew G. Knepley Level: developer 71002e17dfb7SMatthew G. Knepley 71018f700142SStefano Zampini .seealso: DMSetPeriodicity(), DMLocalizeCoordinate(), DMLocalizeAddCoordinate() 71022e17dfb7SMatthew G. Knepley @*/ 71032e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinates(DM dm) 71042e17dfb7SMatthew G. Knepley { 71052e17dfb7SMatthew G. Knepley DM cdm; 71062e17dfb7SMatthew G. Knepley PetscSection coordSection, cSection; 71072e17dfb7SMatthew G. Knepley Vec coordinates, cVec; 71083e922f36SToby Isaac PetscScalar *coords, *coords2, *anchor, *localized; 71093e922f36SToby Isaac PetscInt Nc, vStart, vEnd, v, sStart, sEnd, newStart = PETSC_MAX_INT, newEnd = PETSC_MIN_INT, dof, d, off, off2, bs, coordSize; 7110e0ae35bbSToby Isaac PetscBool alreadyLocalized, alreadyLocalizedGlobal; 71113e922f36SToby Isaac PetscInt maxHeight = 0, h; 71123e922f36SToby Isaac PetscInt *pStart = NULL, *pEnd = NULL; 71132e17dfb7SMatthew G. Knepley PetscErrorCode ierr; 71142e17dfb7SMatthew G. Knepley 71152e17dfb7SMatthew G. Knepley PetscFunctionBegin; 71162e17dfb7SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 711792c9c85fSStefano Zampini if (!dm->periodic) PetscFunctionReturn(0); 7118f7cbd40bSStefano Zampini ierr = DMGetCoordinatesLocalized(dm, &alreadyLocalized);CHKERRQ(ierr); 7119f7cbd40bSStefano Zampini if (alreadyLocalized) PetscFunctionReturn(0); 7120f7cbd40bSStefano Zampini 71212e17dfb7SMatthew G. Knepley /* We need some generic way of refering to cells/vertices */ 71222e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 71232e17dfb7SMatthew G. Knepley { 71242e17dfb7SMatthew G. Knepley PetscBool isplex; 71252e17dfb7SMatthew G. Knepley 71262e17dfb7SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isplex);CHKERRQ(ierr); 71272e17dfb7SMatthew G. Knepley if (isplex) { 71282e17dfb7SMatthew G. Knepley ierr = DMPlexGetDepthStratum(cdm, 0, &vStart, &vEnd);CHKERRQ(ierr); 71293e922f36SToby Isaac ierr = DMPlexGetMaxProjectionHeight(cdm,&maxHeight);CHKERRQ(ierr); 713069291d52SBarry Smith ierr = DMGetWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 71313e922f36SToby Isaac pEnd = &pStart[maxHeight + 1]; 71323e922f36SToby Isaac newStart = vStart; 71333e922f36SToby Isaac newEnd = vEnd; 71343e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 71353e922f36SToby Isaac ierr = DMPlexGetHeightStratum(cdm, h, &pStart[h], &pEnd[h]);CHKERRQ(ierr); 71363e922f36SToby Isaac newStart = PetscMin(newStart,pStart[h]); 71373e922f36SToby Isaac newEnd = PetscMax(newEnd,pEnd[h]); 71383e922f36SToby Isaac } 71392e17dfb7SMatthew G. Knepley } else SETERRQ(PetscObjectComm((PetscObject) cdm), PETSC_ERR_ARG_WRONG, "Coordinate localization requires a DMPLEX coordinate DM"); 71402e17dfb7SMatthew G. Knepley } 71412e17dfb7SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 714243eeeb2dSStefano Zampini if (!coordinates) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Missing local coordinates vector"); 71432e17dfb7SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 71443e922f36SToby Isaac ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 7145e0ae35bbSToby Isaac ierr = PetscSectionGetChart(coordSection,&sStart,&sEnd);CHKERRQ(ierr); 71463e922f36SToby Isaac 71472e17dfb7SMatthew G. Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &cSection);CHKERRQ(ierr); 71482e17dfb7SMatthew G. Knepley ierr = PetscSectionSetNumFields(cSection, 1);CHKERRQ(ierr); 71492e17dfb7SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(coordSection, 0, &Nc);CHKERRQ(ierr); 71502e17dfb7SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(cSection, 0, Nc);CHKERRQ(ierr); 71513e922f36SToby Isaac ierr = PetscSectionSetChart(cSection, newStart, newEnd);CHKERRQ(ierr); 71523e922f36SToby Isaac 715369291d52SBarry Smith ierr = DMGetWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 71543e922f36SToby Isaac localized = &anchor[bs]; 71553e922f36SToby Isaac alreadyLocalized = alreadyLocalizedGlobal = PETSC_TRUE; 71563e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 71573e922f36SToby Isaac PetscInt cStart = pStart[h], cEnd = pEnd[h], c; 71583e922f36SToby Isaac 71593e922f36SToby Isaac for (c = cStart; c < cEnd; ++c) { 71603e922f36SToby Isaac PetscScalar *cellCoords = NULL; 71613e922f36SToby Isaac PetscInt b; 71623e922f36SToby Isaac 71633e922f36SToby Isaac if (c < sStart || c >= sEnd) alreadyLocalized = PETSC_FALSE; 71643e922f36SToby Isaac ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 71653e922f36SToby Isaac for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b]; 71663e922f36SToby Isaac for (d = 0; d < dof/bs; ++d) { 71673e922f36SToby Isaac ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], localized);CHKERRQ(ierr); 71683e922f36SToby Isaac for (b = 0; b < bs; b++) { 71693e922f36SToby Isaac if (cellCoords[d*bs + b] != localized[b]) break; 71703e922f36SToby Isaac } 71713e922f36SToby Isaac if (b < bs) break; 71723e922f36SToby Isaac } 71733e922f36SToby Isaac if (d < dof/bs) { 71743e922f36SToby Isaac if (c >= sStart && c < sEnd) { 71753e922f36SToby Isaac PetscInt cdof; 71763e922f36SToby Isaac 71773e922f36SToby Isaac ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 71783e922f36SToby Isaac if (cdof != dof) alreadyLocalized = PETSC_FALSE; 71793e922f36SToby Isaac } 71803e922f36SToby Isaac ierr = PetscSectionSetDof(cSection, c, dof);CHKERRQ(ierr); 71813e922f36SToby Isaac ierr = PetscSectionSetFieldDof(cSection, c, 0, dof);CHKERRQ(ierr); 71823e922f36SToby Isaac } 71833e922f36SToby Isaac ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 71843e922f36SToby Isaac } 71853e922f36SToby Isaac } 7186ffc4695bSBarry Smith ierr = MPI_Allreduce(&alreadyLocalized,&alreadyLocalizedGlobal,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 71873e922f36SToby Isaac if (alreadyLocalizedGlobal) { 718869291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 71893e922f36SToby Isaac ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr); 719069291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 71913e922f36SToby Isaac PetscFunctionReturn(0); 71923e922f36SToby Isaac } 71932e17dfb7SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 71942e17dfb7SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 71952e17dfb7SMatthew G. Knepley ierr = PetscSectionSetDof(cSection, v, dof);CHKERRQ(ierr); 71962e17dfb7SMatthew G. Knepley ierr = PetscSectionSetFieldDof(cSection, v, 0, dof);CHKERRQ(ierr); 71972e17dfb7SMatthew G. Knepley } 71982e17dfb7SMatthew G. Knepley ierr = PetscSectionSetUp(cSection);CHKERRQ(ierr); 71992e17dfb7SMatthew G. Knepley ierr = PetscSectionGetStorageSize(cSection, &coordSize);CHKERRQ(ierr); 7200c2be7e5eSLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &cVec);CHKERRQ(ierr); 72012e17dfb7SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject)cVec,"coordinates");CHKERRQ(ierr); 72022e17dfb7SMatthew G. Knepley ierr = VecSetBlockSize(cVec, bs);CHKERRQ(ierr); 72032e17dfb7SMatthew G. Knepley ierr = VecSetSizes(cVec, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 72042e17dfb7SMatthew G. Knepley ierr = VecSetType(cVec, VECSTANDARD);CHKERRQ(ierr); 7205c2be7e5eSLisandro Dalcin ierr = VecGetArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr); 72062e17dfb7SMatthew G. Knepley ierr = VecGetArray(cVec, &coords2);CHKERRQ(ierr); 72072e17dfb7SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 72082e17dfb7SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 72092e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 72102e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(cSection, v, &off2);CHKERRQ(ierr); 72112e17dfb7SMatthew G. Knepley for (d = 0; d < dof; ++d) coords2[off2+d] = coords[off+d]; 72122e17dfb7SMatthew G. Knepley } 72133e922f36SToby Isaac for (h = 0; h <= maxHeight; h++) { 72143e922f36SToby Isaac PetscInt cStart = pStart[h], cEnd = pEnd[h], c; 72153e922f36SToby Isaac 72162e17dfb7SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 72172e17dfb7SMatthew G. Knepley PetscScalar *cellCoords = NULL; 72183e922f36SToby Isaac PetscInt b, cdof; 72192e17dfb7SMatthew G. Knepley 72203e922f36SToby Isaac ierr = PetscSectionGetDof(cSection,c,&cdof);CHKERRQ(ierr); 72213e922f36SToby Isaac if (!cdof) continue; 72222e17dfb7SMatthew G. Knepley ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 72232e17dfb7SMatthew G. Knepley ierr = PetscSectionGetOffset(cSection, c, &off2);CHKERRQ(ierr); 72242e17dfb7SMatthew G. Knepley for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b]; 72252e17dfb7SMatthew G. Knepley for (d = 0; d < dof/bs; ++d) {ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], &coords2[off2+d*bs]);CHKERRQ(ierr);} 72262e17dfb7SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 72272e17dfb7SMatthew G. Knepley } 72283e922f36SToby Isaac } 722969291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr); 723069291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr); 7231c2be7e5eSLisandro Dalcin ierr = VecRestoreArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr); 72322e17dfb7SMatthew G. Knepley ierr = VecRestoreArray(cVec, &coords2);CHKERRQ(ierr); 72332e17dfb7SMatthew G. Knepley ierr = DMSetCoordinateSection(dm, PETSC_DETERMINE, cSection);CHKERRQ(ierr); 72342e17dfb7SMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, cVec);CHKERRQ(ierr); 72352e17dfb7SMatthew G. Knepley ierr = VecDestroy(&cVec);CHKERRQ(ierr); 72362e17dfb7SMatthew G. Knepley ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr); 72372e17dfb7SMatthew G. Knepley PetscFunctionReturn(0); 72382e17dfb7SMatthew G. Knepley } 72392e17dfb7SMatthew G. Knepley 7240e87bb0d3SMatthew G Knepley /*@ 72413a93e3b7SToby Isaac DMLocatePoints - Locate the points in v in the mesh and return a PetscSF of the containing cells 7242e87bb0d3SMatthew G Knepley 7243d083f849SBarry Smith Collective on v (see explanation below) 7244e87bb0d3SMatthew G Knepley 7245e87bb0d3SMatthew G Knepley Input Parameters: 7246e87bb0d3SMatthew G Knepley + dm - The DM 72476b867d5aSJose E. Roman - ltype - The type of point location, e.g. DM_POINTLOCATION_NONE or DM_POINTLOCATION_NEAREST 7248e87bb0d3SMatthew G Knepley 72496b867d5aSJose E. Roman Input/Output Parameters: 72506b867d5aSJose E. Roman + v - The Vec of points, on output contains the nearest mesh points to the given points if DM_POINTLOCATION_NEAREST is used 72516b867d5aSJose E. Roman - cellSF - Points to either NULL, or a PetscSF with guesses for which cells contain each point; 72526b867d5aSJose E. Roman on output, the PetscSF containing the ranks and local indices of the containing points 72533a93e3b7SToby Isaac 7254e87bb0d3SMatthew G Knepley Level: developer 725561e3bb9bSMatthew G Knepley 725662a38674SMatthew G. Knepley Notes: 72573a93e3b7SToby Isaac To do a search of the local cells of the mesh, v should have PETSC_COMM_SELF as its communicator. 725862a38674SMatthew G. Knepley To do a search of all the cells in the distributed mesh, v should have the same communicator as dm. 72593a93e3b7SToby Isaac 72603a93e3b7SToby Isaac If *cellSF is NULL on input, a PetscSF will be created. 726162a38674SMatthew G. Knepley If *cellSF is not NULL on input, it should point to an existing PetscSF, whose graph will be used as initial guesses. 72623a93e3b7SToby Isaac 72633a93e3b7SToby Isaac An array that maps each point to its containing cell can be obtained with 72643a93e3b7SToby Isaac 726562a38674SMatthew G. Knepley $ const PetscSFNode *cells; 726662a38674SMatthew G. Knepley $ PetscInt nFound; 7267a6216909SToby Isaac $ const PetscInt *found; 726862a38674SMatthew G. Knepley $ 7269a6216909SToby Isaac $ PetscSFGetGraph(cellSF,NULL,&nFound,&found,&cells); 72703a93e3b7SToby Isaac 72713a93e3b7SToby 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 72723a93e3b7SToby Isaac the index of the cell in its rank's local numbering. 72733a93e3b7SToby Isaac 727462a38674SMatthew G. Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMPointLocationType 727561e3bb9bSMatthew G Knepley @*/ 727662a38674SMatthew G. Knepley PetscErrorCode DMLocatePoints(DM dm, Vec v, DMPointLocationType ltype, PetscSF *cellSF) 7277e87bb0d3SMatthew G Knepley { 7278735aa83eSMatthew G Knepley PetscErrorCode ierr; 7279735aa83eSMatthew G Knepley 7280e87bb0d3SMatthew G Knepley PetscFunctionBegin; 7281e87bb0d3SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7282e87bb0d3SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,2); 7283e0fc9d1bSMatthew G. Knepley PetscValidPointer(cellSF,4); 72843a93e3b7SToby Isaac if (*cellSF) { 72853a93e3b7SToby Isaac PetscMPIInt result; 72863a93e3b7SToby Isaac 7287e0fc9d1bSMatthew G. Knepley PetscValidHeaderSpecific(*cellSF,PETSCSF_CLASSID,4); 7288ffc4695bSBarry Smith ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)v),PetscObjectComm((PetscObject)*cellSF),&result);CHKERRMPI(ierr); 72893a93e3b7SToby 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"); 7290e0fc9d1bSMatthew G. Knepley } else { 72913a93e3b7SToby Isaac ierr = PetscSFCreate(PetscObjectComm((PetscObject)v),cellSF);CHKERRQ(ierr); 72923a93e3b7SToby Isaac } 7293b9d85ea2SLisandro Dalcin if (!dm->ops->locatepoints) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Point location not available for this DM"); 729447a35634SPatrick Farrell ierr = PetscLogEventBegin(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr); 729562a38674SMatthew G. Knepley ierr = (*dm->ops->locatepoints)(dm,v,ltype,*cellSF);CHKERRQ(ierr); 729647a35634SPatrick Farrell ierr = PetscLogEventEnd(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr); 7297e87bb0d3SMatthew G Knepley PetscFunctionReturn(0); 7298e87bb0d3SMatthew G Knepley } 729914f150ffSMatthew G. Knepley 7300f4d763aaSMatthew G. Knepley /*@ 7301f4d763aaSMatthew G. Knepley DMGetOutputDM - Retrieve the DM associated with the layout for output 7302f4d763aaSMatthew G. Knepley 73038f700142SStefano Zampini Collective on dm 73048f700142SStefano Zampini 7305f4d763aaSMatthew G. Knepley Input Parameter: 7306f4d763aaSMatthew G. Knepley . dm - The original DM 7307f4d763aaSMatthew G. Knepley 7308f4d763aaSMatthew G. Knepley Output Parameter: 7309f4d763aaSMatthew G. Knepley . odm - The DM which provides the layout for output 7310f4d763aaSMatthew G. Knepley 7311f4d763aaSMatthew G. Knepley Level: intermediate 7312f4d763aaSMatthew G. Knepley 7313e87a4003SBarry Smith .seealso: VecView(), DMGetGlobalSection() 7314f4d763aaSMatthew G. Knepley @*/ 731514f150ffSMatthew G. Knepley PetscErrorCode DMGetOutputDM(DM dm, DM *odm) 731614f150ffSMatthew G. Knepley { 7317c26acbdeSMatthew G. Knepley PetscSection section; 73182d4e4a49SMatthew G. Knepley PetscBool hasConstraints, ghasConstraints; 731914f150ffSMatthew G. Knepley PetscErrorCode ierr; 732014f150ffSMatthew G. Knepley 732114f150ffSMatthew G. Knepley PetscFunctionBegin; 732214f150ffSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 732314f150ffSMatthew G. Knepley PetscValidPointer(odm,2); 732492fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 7325c26acbdeSMatthew G. Knepley ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr); 7326ffc4695bSBarry Smith ierr = MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 73272d4e4a49SMatthew G. Knepley if (!ghasConstraints) { 7328c26acbdeSMatthew G. Knepley *odm = dm; 7329c26acbdeSMatthew G. Knepley PetscFunctionReturn(0); 7330c26acbdeSMatthew G. Knepley } 733114f150ffSMatthew G. Knepley if (!dm->dmBC) { 7332c26acbdeSMatthew G. Knepley PetscSection newSection, gsection; 733314f150ffSMatthew G. Knepley PetscSF sf; 733414f150ffSMatthew G. Knepley 733514f150ffSMatthew G. Knepley ierr = DMClone(dm, &dm->dmBC);CHKERRQ(ierr); 7336e5e52638SMatthew G. Knepley ierr = DMCopyDisc(dm, dm->dmBC);CHKERRQ(ierr); 733714f150ffSMatthew G. Knepley ierr = PetscSectionClone(section, &newSection);CHKERRQ(ierr); 733892fd8e1eSJed Brown ierr = DMSetLocalSection(dm->dmBC, newSection);CHKERRQ(ierr); 733914f150ffSMatthew G. Knepley ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr); 734014f150ffSMatthew G. Knepley ierr = DMGetPointSF(dm->dmBC, &sf);CHKERRQ(ierr); 734115b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr); 7342e87a4003SBarry Smith ierr = DMSetGlobalSection(dm->dmBC, gsection);CHKERRQ(ierr); 734314f150ffSMatthew G. Knepley ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr); 734414f150ffSMatthew G. Knepley } 734514f150ffSMatthew G. Knepley *odm = dm->dmBC; 734614f150ffSMatthew G. Knepley PetscFunctionReturn(0); 734714f150ffSMatthew G. Knepley } 7348f4d763aaSMatthew G. Knepley 7349f4d763aaSMatthew G. Knepley /*@ 7350cdb7a50dSMatthew G. Knepley DMGetOutputSequenceNumber - Retrieve the sequence number/value for output 7351f4d763aaSMatthew G. Knepley 7352f4d763aaSMatthew G. Knepley Input Parameter: 7353f4d763aaSMatthew G. Knepley . dm - The original DM 7354f4d763aaSMatthew G. Knepley 7355cdb7a50dSMatthew G. Knepley Output Parameters: 7356cdb7a50dSMatthew G. Knepley + num - The output sequence number 7357cdb7a50dSMatthew G. Knepley - val - The output sequence value 7358f4d763aaSMatthew G. Knepley 7359f4d763aaSMatthew G. Knepley Level: intermediate 7360f4d763aaSMatthew G. Knepley 7361f4d763aaSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 7362f4d763aaSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 7363f4d763aaSMatthew G. Knepley 7364f4d763aaSMatthew G. Knepley .seealso: VecView() 7365f4d763aaSMatthew G. Knepley @*/ 7366cdb7a50dSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val) 7367f4d763aaSMatthew G. Knepley { 7368f4d763aaSMatthew G. Knepley PetscFunctionBegin; 7369f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7370534a8f05SLisandro Dalcin if (num) {PetscValidIntPointer(num,2); *num = dm->outputSequenceNum;} 7371534a8f05SLisandro Dalcin if (val) {PetscValidRealPointer(val,3);*val = dm->outputSequenceVal;} 7372f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 7373f4d763aaSMatthew G. Knepley } 7374f4d763aaSMatthew G. Knepley 7375f4d763aaSMatthew G. Knepley /*@ 7376cdb7a50dSMatthew G. Knepley DMSetOutputSequenceNumber - Set the sequence number/value for output 7377f4d763aaSMatthew G. Knepley 7378f4d763aaSMatthew G. Knepley Input Parameters: 7379f4d763aaSMatthew G. Knepley + dm - The original DM 7380cdb7a50dSMatthew G. Knepley . num - The output sequence number 7381cdb7a50dSMatthew G. Knepley - val - The output sequence value 7382f4d763aaSMatthew G. Knepley 7383f4d763aaSMatthew G. Knepley Level: intermediate 7384f4d763aaSMatthew G. Knepley 7385f4d763aaSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 7386f4d763aaSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 7387f4d763aaSMatthew G. Knepley 7388f4d763aaSMatthew G. Knepley .seealso: VecView() 7389f4d763aaSMatthew G. Knepley @*/ 7390cdb7a50dSMatthew G. Knepley PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val) 7391f4d763aaSMatthew G. Knepley { 7392f4d763aaSMatthew G. Knepley PetscFunctionBegin; 7393f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7394f4d763aaSMatthew G. Knepley dm->outputSequenceNum = num; 7395cdb7a50dSMatthew G. Knepley dm->outputSequenceVal = val; 7396cdb7a50dSMatthew G. Knepley PetscFunctionReturn(0); 7397cdb7a50dSMatthew G. Knepley } 7398cdb7a50dSMatthew G. Knepley 7399cdb7a50dSMatthew G. Knepley /*@C 7400cdb7a50dSMatthew G. Knepley DMOutputSequenceLoad - Retrieve the sequence value from a Viewer 7401cdb7a50dSMatthew G. Knepley 7402cdb7a50dSMatthew G. Knepley Input Parameters: 7403cdb7a50dSMatthew G. Knepley + dm - The original DM 7404cdb7a50dSMatthew G. Knepley . name - The sequence name 7405cdb7a50dSMatthew G. Knepley - num - The output sequence number 7406cdb7a50dSMatthew G. Knepley 7407cdb7a50dSMatthew G. Knepley Output Parameter: 7408cdb7a50dSMatthew G. Knepley . val - The output sequence value 7409cdb7a50dSMatthew G. Knepley 7410cdb7a50dSMatthew G. Knepley Level: intermediate 7411cdb7a50dSMatthew G. Knepley 7412cdb7a50dSMatthew G. Knepley Note: This is intended for output that should appear in sequence, for instance 7413cdb7a50dSMatthew G. Knepley a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system. 7414cdb7a50dSMatthew G. Knepley 7415cdb7a50dSMatthew G. Knepley .seealso: DMGetOutputSequenceNumber(), DMSetOutputSequenceNumber(), VecView() 7416cdb7a50dSMatthew G. Knepley @*/ 7417cdb7a50dSMatthew G. Knepley PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val) 7418cdb7a50dSMatthew G. Knepley { 7419cdb7a50dSMatthew G. Knepley PetscBool ishdf5; 7420cdb7a50dSMatthew G. Knepley PetscErrorCode ierr; 7421cdb7a50dSMatthew G. Knepley 7422cdb7a50dSMatthew G. Knepley PetscFunctionBegin; 7423cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7424cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 7425064a246eSJacob Faibussowitsch PetscValidRealPointer(val,5); 7426cdb7a50dSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 7427cdb7a50dSMatthew G. Knepley if (ishdf5) { 7428cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 7429cdb7a50dSMatthew G. Knepley PetscScalar value; 7430cdb7a50dSMatthew G. Knepley 743139d25373SMatthew G. Knepley ierr = DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer);CHKERRQ(ierr); 74324aeb217fSMatthew G. Knepley *val = PetscRealPart(value); 7433cdb7a50dSMatthew G. Knepley #endif 7434cdb7a50dSMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()"); 7435f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 7436f4d763aaSMatthew G. Knepley } 74378e4ac7eaSMatthew G. Knepley 74388e4ac7eaSMatthew G. Knepley /*@ 74398e4ac7eaSMatthew G. Knepley DMGetUseNatural - Get the flag for creating a mapping to the natural order on distribution 74408e4ac7eaSMatthew G. Knepley 74418e4ac7eaSMatthew G. Knepley Not collective 74428e4ac7eaSMatthew G. Knepley 74438e4ac7eaSMatthew G. Knepley Input Parameter: 74448e4ac7eaSMatthew G. Knepley . dm - The DM 74458e4ac7eaSMatthew G. Knepley 74468e4ac7eaSMatthew G. Knepley Output Parameter: 74478e4ac7eaSMatthew G. Knepley . useNatural - The flag to build the mapping to a natural order during distribution 74488e4ac7eaSMatthew G. Knepley 74498e4ac7eaSMatthew G. Knepley Level: beginner 74508e4ac7eaSMatthew G. Knepley 74518e4ac7eaSMatthew G. Knepley .seealso: DMSetUseNatural(), DMCreate() 74528e4ac7eaSMatthew G. Knepley @*/ 74538e4ac7eaSMatthew G. Knepley PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural) 74548e4ac7eaSMatthew G. Knepley { 74558e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 74568e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7457534a8f05SLisandro Dalcin PetscValidBoolPointer(useNatural, 2); 74588e4ac7eaSMatthew G. Knepley *useNatural = dm->useNatural; 74598e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 74608e4ac7eaSMatthew G. Knepley } 74618e4ac7eaSMatthew G. Knepley 74628e4ac7eaSMatthew G. Knepley /*@ 74635d3b26e6SMatthew G. Knepley DMSetUseNatural - Set the flag for creating a mapping to the natural order after distribution 74648e4ac7eaSMatthew G. Knepley 74658e4ac7eaSMatthew G. Knepley Collective on dm 74668e4ac7eaSMatthew G. Knepley 74678e4ac7eaSMatthew G. Knepley Input Parameters: 74688e4ac7eaSMatthew G. Knepley + dm - The DM 74698e4ac7eaSMatthew G. Knepley - useNatural - The flag to build the mapping to a natural order during distribution 74708e4ac7eaSMatthew G. Knepley 74715d3b26e6SMatthew G. Knepley Note: This also causes the map to be build after DMCreateSubDM() and DMCreateSuperDM() 74725d3b26e6SMatthew G. Knepley 74738e4ac7eaSMatthew G. Knepley Level: beginner 74748e4ac7eaSMatthew G. Knepley 74755d3b26e6SMatthew G. Knepley .seealso: DMGetUseNatural(), DMCreate(), DMPlexDistribute(), DMCreateSubDM(), DMCreateSuperDM() 74768e4ac7eaSMatthew G. Knepley @*/ 74778e4ac7eaSMatthew G. Knepley PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural) 74788e4ac7eaSMatthew G. Knepley { 74798e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 74808e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 74818833efb5SBlaise Bourdin PetscValidLogicalCollectiveBool(dm, useNatural, 2); 74828e4ac7eaSMatthew G. Knepley dm->useNatural = useNatural; 74838e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 74848e4ac7eaSMatthew G. Knepley } 7485c58f1c22SToby Isaac 7486c58f1c22SToby Isaac /*@C 7487c58f1c22SToby Isaac DMCreateLabel - Create a label of the given name if it does not already exist 7488c58f1c22SToby Isaac 7489c58f1c22SToby Isaac Not Collective 7490c58f1c22SToby Isaac 7491c58f1c22SToby Isaac Input Parameters: 7492c58f1c22SToby Isaac + dm - The DM object 7493c58f1c22SToby Isaac - name - The label name 7494c58f1c22SToby Isaac 7495c58f1c22SToby Isaac Level: intermediate 7496c58f1c22SToby Isaac 7497c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7498c58f1c22SToby Isaac @*/ 7499c58f1c22SToby Isaac PetscErrorCode DMCreateLabel(DM dm, const char name[]) 7500c58f1c22SToby Isaac { 75015d80c0bfSVaclav Hapla PetscBool flg; 75025d80c0bfSVaclav Hapla DMLabel label; 7503c58f1c22SToby Isaac PetscErrorCode ierr; 7504c58f1c22SToby Isaac 7505c58f1c22SToby Isaac PetscFunctionBegin; 7506c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7507c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 75085d80c0bfSVaclav Hapla ierr = DMHasLabel(dm, name, &flg);CHKERRQ(ierr); 7509c58f1c22SToby Isaac if (!flg) { 75105d80c0bfSVaclav Hapla ierr = DMLabelCreate(PETSC_COMM_SELF, name, &label);CHKERRQ(ierr); 75115d80c0bfSVaclav Hapla ierr = DMAddLabel(dm, label);CHKERRQ(ierr); 75125d80c0bfSVaclav Hapla ierr = DMLabelDestroy(&label);CHKERRQ(ierr); 7513c58f1c22SToby Isaac } 7514c58f1c22SToby Isaac PetscFunctionReturn(0); 7515c58f1c22SToby Isaac } 7516c58f1c22SToby Isaac 7517c58f1c22SToby Isaac /*@C 75180fdc7489SMatthew Knepley DMCreateLabelAtIndex - Create a label of the given name at the iven index. If it already exists, move it to this index. 75190fdc7489SMatthew Knepley 75200fdc7489SMatthew Knepley Not Collective 75210fdc7489SMatthew Knepley 75220fdc7489SMatthew Knepley Input Parameters: 75230fdc7489SMatthew Knepley + dm - The DM object 75240fdc7489SMatthew Knepley . l - The index for the label 75250fdc7489SMatthew Knepley - name - The label name 75260fdc7489SMatthew Knepley 75270fdc7489SMatthew Knepley Level: intermediate 75280fdc7489SMatthew Knepley 75290fdc7489SMatthew Knepley .seealso: DMCreateLabel(), DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 75300fdc7489SMatthew Knepley @*/ 75310fdc7489SMatthew Knepley PetscErrorCode DMCreateLabelAtIndex(DM dm, PetscInt l, const char name[]) 75320fdc7489SMatthew Knepley { 75330fdc7489SMatthew Knepley DMLabelLink orig, prev = NULL; 75340fdc7489SMatthew Knepley DMLabel label; 75350fdc7489SMatthew Knepley PetscInt Nl, m; 75360fdc7489SMatthew Knepley PetscBool flg, match; 75370fdc7489SMatthew Knepley const char *lname; 75380fdc7489SMatthew Knepley PetscErrorCode ierr; 75390fdc7489SMatthew Knepley 75400fdc7489SMatthew Knepley PetscFunctionBegin; 75410fdc7489SMatthew Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7542064a246eSJacob Faibussowitsch PetscValidCharPointer(name, 3); 75430fdc7489SMatthew Knepley ierr = DMHasLabel(dm, name, &flg);CHKERRQ(ierr); 75440fdc7489SMatthew Knepley if (!flg) { 75450fdc7489SMatthew Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, name, &label);CHKERRQ(ierr); 75460fdc7489SMatthew Knepley ierr = DMAddLabel(dm, label);CHKERRQ(ierr); 75470fdc7489SMatthew Knepley ierr = DMLabelDestroy(&label);CHKERRQ(ierr); 75480fdc7489SMatthew Knepley } 75490fdc7489SMatthew Knepley ierr = DMGetNumLabels(dm, &Nl);CHKERRQ(ierr); 75500fdc7489SMatthew Knepley if (l >= Nl) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label index %D must be in [0, %D)", l, Nl); 75510fdc7489SMatthew Knepley for (m = 0, orig = dm->labels; m < Nl; ++m, prev = orig, orig = orig->next) { 75520fdc7489SMatthew Knepley ierr = PetscObjectGetName((PetscObject) orig->label, &lname);CHKERRQ(ierr); 75530fdc7489SMatthew Knepley ierr = PetscStrcmp(name, lname, &match);CHKERRQ(ierr); 75540fdc7489SMatthew Knepley if (match) break; 75550fdc7489SMatthew Knepley } 75560fdc7489SMatthew Knepley if (m == l) PetscFunctionReturn(0); 75570fdc7489SMatthew Knepley if (!m) dm->labels = orig->next; 75580fdc7489SMatthew Knepley else prev->next = orig->next; 75590fdc7489SMatthew Knepley if (!l) { 75600fdc7489SMatthew Knepley orig->next = dm->labels; 75610fdc7489SMatthew Knepley dm->labels = orig; 75620fdc7489SMatthew Knepley } else { 75630fdc7489SMatthew Knepley for (m = 0, prev = dm->labels; m < l-1; ++m, prev = prev->next); 75640fdc7489SMatthew Knepley orig->next = prev->next; 75650fdc7489SMatthew Knepley prev->next = orig; 75660fdc7489SMatthew Knepley } 75670fdc7489SMatthew Knepley PetscFunctionReturn(0); 75680fdc7489SMatthew Knepley } 75690fdc7489SMatthew Knepley 75700fdc7489SMatthew Knepley /*@C 7571c58f1c22SToby Isaac DMGetLabelValue - Get the value in a Sieve Label for the given point, with 0 as the default 7572c58f1c22SToby Isaac 7573c58f1c22SToby Isaac Not Collective 7574c58f1c22SToby Isaac 7575c58f1c22SToby Isaac Input Parameters: 7576c58f1c22SToby Isaac + dm - The DM object 7577c58f1c22SToby Isaac . name - The label name 7578c58f1c22SToby Isaac - point - The mesh point 7579c58f1c22SToby Isaac 7580c58f1c22SToby Isaac Output Parameter: 7581c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label 7582c58f1c22SToby Isaac 7583c58f1c22SToby Isaac Level: beginner 7584c58f1c22SToby Isaac 7585c58f1c22SToby Isaac .seealso: DMLabelGetValue(), DMSetLabelValue(), DMGetStratumIS() 7586c58f1c22SToby Isaac @*/ 7587c58f1c22SToby Isaac PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value) 7588c58f1c22SToby Isaac { 7589c58f1c22SToby Isaac DMLabel label; 7590c58f1c22SToby Isaac PetscErrorCode ierr; 7591c58f1c22SToby Isaac 7592c58f1c22SToby Isaac PetscFunctionBegin; 7593c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7594c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7595c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 759613903a91SSatish Balay if (!label) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name); 7597c58f1c22SToby Isaac ierr = DMLabelGetValue(label, point, value);CHKERRQ(ierr); 7598c58f1c22SToby Isaac PetscFunctionReturn(0); 7599c58f1c22SToby Isaac } 7600c58f1c22SToby Isaac 7601c58f1c22SToby Isaac /*@C 7602c58f1c22SToby Isaac DMSetLabelValue - Add a point to a Sieve Label with given value 7603c58f1c22SToby Isaac 7604c58f1c22SToby Isaac Not Collective 7605c58f1c22SToby Isaac 7606c58f1c22SToby Isaac Input Parameters: 7607c58f1c22SToby Isaac + dm - The DM object 7608c58f1c22SToby Isaac . name - The label name 7609c58f1c22SToby Isaac . point - The mesh point 7610c58f1c22SToby Isaac - value - The label value for this point 7611c58f1c22SToby Isaac 7612c58f1c22SToby Isaac Output Parameter: 7613c58f1c22SToby Isaac 7614c58f1c22SToby Isaac Level: beginner 7615c58f1c22SToby Isaac 7616c58f1c22SToby Isaac .seealso: DMLabelSetValue(), DMGetStratumIS(), DMClearLabelValue() 7617c58f1c22SToby Isaac @*/ 7618c58f1c22SToby Isaac PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 7619c58f1c22SToby Isaac { 7620c58f1c22SToby Isaac DMLabel label; 7621c58f1c22SToby Isaac PetscErrorCode ierr; 7622c58f1c22SToby Isaac 7623c58f1c22SToby Isaac PetscFunctionBegin; 7624c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7625c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7626c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7627c58f1c22SToby Isaac if (!label) { 7628c58f1c22SToby Isaac ierr = DMCreateLabel(dm, name);CHKERRQ(ierr); 7629c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7630c58f1c22SToby Isaac } 7631c58f1c22SToby Isaac ierr = DMLabelSetValue(label, point, value);CHKERRQ(ierr); 7632c58f1c22SToby Isaac PetscFunctionReturn(0); 7633c58f1c22SToby Isaac } 7634c58f1c22SToby Isaac 7635c58f1c22SToby Isaac /*@C 7636c58f1c22SToby Isaac DMClearLabelValue - Remove a point from a Sieve Label with given value 7637c58f1c22SToby Isaac 7638c58f1c22SToby Isaac Not Collective 7639c58f1c22SToby Isaac 7640c58f1c22SToby Isaac Input Parameters: 7641c58f1c22SToby Isaac + dm - The DM object 7642c58f1c22SToby Isaac . name - The label name 7643c58f1c22SToby Isaac . point - The mesh point 7644c58f1c22SToby Isaac - value - The label value for this point 7645c58f1c22SToby Isaac 7646c58f1c22SToby Isaac Output Parameter: 7647c58f1c22SToby Isaac 7648c58f1c22SToby Isaac Level: beginner 7649c58f1c22SToby Isaac 7650c58f1c22SToby Isaac .seealso: DMLabelClearValue(), DMSetLabelValue(), DMGetStratumIS() 7651c58f1c22SToby Isaac @*/ 7652c58f1c22SToby Isaac PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 7653c58f1c22SToby Isaac { 7654c58f1c22SToby Isaac DMLabel label; 7655c58f1c22SToby Isaac PetscErrorCode ierr; 7656c58f1c22SToby Isaac 7657c58f1c22SToby Isaac PetscFunctionBegin; 7658c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7659c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7660c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7661c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7662c58f1c22SToby Isaac ierr = DMLabelClearValue(label, point, value);CHKERRQ(ierr); 7663c58f1c22SToby Isaac PetscFunctionReturn(0); 7664c58f1c22SToby Isaac } 7665c58f1c22SToby Isaac 7666c58f1c22SToby Isaac /*@C 7667c58f1c22SToby Isaac DMGetLabelSize - Get the number of different integer ids in a Label 7668c58f1c22SToby Isaac 7669c58f1c22SToby Isaac Not Collective 7670c58f1c22SToby Isaac 7671c58f1c22SToby Isaac Input Parameters: 7672c58f1c22SToby Isaac + dm - The DM object 7673c58f1c22SToby Isaac - name - The label name 7674c58f1c22SToby Isaac 7675c58f1c22SToby Isaac Output Parameter: 7676c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist 7677c58f1c22SToby Isaac 7678c58f1c22SToby Isaac Level: beginner 7679c58f1c22SToby Isaac 7680df813f42SMatthew G. Knepley .seealso: DMLabelGetNumValues(), DMSetLabelValue() 7681c58f1c22SToby Isaac @*/ 7682c58f1c22SToby Isaac PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size) 7683c58f1c22SToby Isaac { 7684c58f1c22SToby Isaac DMLabel label; 7685c58f1c22SToby Isaac PetscErrorCode ierr; 7686c58f1c22SToby Isaac 7687c58f1c22SToby Isaac PetscFunctionBegin; 7688c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7689c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7690534a8f05SLisandro Dalcin PetscValidIntPointer(size, 3); 7691c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7692c58f1c22SToby Isaac *size = 0; 7693c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7694c58f1c22SToby Isaac ierr = DMLabelGetNumValues(label, size);CHKERRQ(ierr); 7695c58f1c22SToby Isaac PetscFunctionReturn(0); 7696c58f1c22SToby Isaac } 7697c58f1c22SToby Isaac 7698c58f1c22SToby Isaac /*@C 7699c58f1c22SToby Isaac DMGetLabelIdIS - Get the integer ids in a label 7700c58f1c22SToby Isaac 7701c58f1c22SToby Isaac Not Collective 7702c58f1c22SToby Isaac 7703c58f1c22SToby Isaac Input Parameters: 7704c58f1c22SToby Isaac + mesh - The DM object 7705c58f1c22SToby Isaac - name - The label name 7706c58f1c22SToby Isaac 7707c58f1c22SToby Isaac Output Parameter: 7708c58f1c22SToby Isaac . ids - The integer ids, or NULL if the label does not exist 7709c58f1c22SToby Isaac 7710c58f1c22SToby Isaac Level: beginner 7711c58f1c22SToby Isaac 7712c58f1c22SToby Isaac .seealso: DMLabelGetValueIS(), DMGetLabelSize() 7713c58f1c22SToby Isaac @*/ 7714c58f1c22SToby Isaac PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids) 7715c58f1c22SToby Isaac { 7716c58f1c22SToby Isaac DMLabel label; 7717c58f1c22SToby Isaac PetscErrorCode ierr; 7718c58f1c22SToby Isaac 7719c58f1c22SToby Isaac PetscFunctionBegin; 7720c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7721c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7722c58f1c22SToby Isaac PetscValidPointer(ids, 3); 7723c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7724c58f1c22SToby Isaac *ids = NULL; 7725dab2e251SBlaise Bourdin if (label) { 7726c58f1c22SToby Isaac ierr = DMLabelGetValueIS(label, ids);CHKERRQ(ierr); 7727dab2e251SBlaise Bourdin } else { 7728dab2e251SBlaise Bourdin /* returning an empty IS */ 7729dab2e251SBlaise Bourdin ierr = ISCreateGeneral(PETSC_COMM_SELF,0,NULL,PETSC_USE_POINTER,ids);CHKERRQ(ierr); 7730dab2e251SBlaise Bourdin } 7731c58f1c22SToby Isaac PetscFunctionReturn(0); 7732c58f1c22SToby Isaac } 7733c58f1c22SToby Isaac 7734c58f1c22SToby Isaac /*@C 7735c58f1c22SToby Isaac DMGetStratumSize - Get the number of points in a label stratum 7736c58f1c22SToby Isaac 7737c58f1c22SToby Isaac Not Collective 7738c58f1c22SToby Isaac 7739c58f1c22SToby Isaac Input Parameters: 7740c58f1c22SToby Isaac + dm - The DM object 7741c58f1c22SToby Isaac . name - The label name 7742c58f1c22SToby Isaac - value - The stratum value 7743c58f1c22SToby Isaac 7744c58f1c22SToby Isaac Output Parameter: 7745c58f1c22SToby Isaac . size - The stratum size 7746c58f1c22SToby Isaac 7747c58f1c22SToby Isaac Level: beginner 7748c58f1c22SToby Isaac 7749c58f1c22SToby Isaac .seealso: DMLabelGetStratumSize(), DMGetLabelSize(), DMGetLabelIds() 7750c58f1c22SToby Isaac @*/ 7751c58f1c22SToby Isaac PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size) 7752c58f1c22SToby Isaac { 7753c58f1c22SToby Isaac DMLabel label; 7754c58f1c22SToby Isaac PetscErrorCode ierr; 7755c58f1c22SToby Isaac 7756c58f1c22SToby Isaac PetscFunctionBegin; 7757c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7758c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7759534a8f05SLisandro Dalcin PetscValidIntPointer(size, 4); 7760c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7761c58f1c22SToby Isaac *size = 0; 7762c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7763c58f1c22SToby Isaac ierr = DMLabelGetStratumSize(label, value, size);CHKERRQ(ierr); 7764c58f1c22SToby Isaac PetscFunctionReturn(0); 7765c58f1c22SToby Isaac } 7766c58f1c22SToby Isaac 7767c58f1c22SToby Isaac /*@C 7768c58f1c22SToby Isaac DMGetStratumIS - Get the points in a label stratum 7769c58f1c22SToby Isaac 7770c58f1c22SToby Isaac Not Collective 7771c58f1c22SToby Isaac 7772c58f1c22SToby Isaac Input Parameters: 7773c58f1c22SToby Isaac + dm - The DM object 7774c58f1c22SToby Isaac . name - The label name 7775c58f1c22SToby Isaac - value - The stratum value 7776c58f1c22SToby Isaac 7777c58f1c22SToby Isaac Output Parameter: 7778c58f1c22SToby Isaac . points - The stratum points, or NULL if the label does not exist or does not have that value 7779c58f1c22SToby Isaac 7780c58f1c22SToby Isaac Level: beginner 7781c58f1c22SToby Isaac 7782c58f1c22SToby Isaac .seealso: DMLabelGetStratumIS(), DMGetStratumSize() 7783c58f1c22SToby Isaac @*/ 7784c58f1c22SToby Isaac PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points) 7785c58f1c22SToby Isaac { 7786c58f1c22SToby Isaac DMLabel label; 7787c58f1c22SToby Isaac PetscErrorCode ierr; 7788c58f1c22SToby Isaac 7789c58f1c22SToby Isaac PetscFunctionBegin; 7790c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7791c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7792c58f1c22SToby Isaac PetscValidPointer(points, 4); 7793c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7794c58f1c22SToby Isaac *points = NULL; 7795c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7796c58f1c22SToby Isaac ierr = DMLabelGetStratumIS(label, value, points);CHKERRQ(ierr); 7797c58f1c22SToby Isaac PetscFunctionReturn(0); 7798c58f1c22SToby Isaac } 7799c58f1c22SToby Isaac 78004de306b1SToby Isaac /*@C 78019044fa66SMatthew G. Knepley DMSetStratumIS - Set the points in a label stratum 78024de306b1SToby Isaac 78034de306b1SToby Isaac Not Collective 78044de306b1SToby Isaac 78054de306b1SToby Isaac Input Parameters: 78064de306b1SToby Isaac + dm - The DM object 78074de306b1SToby Isaac . name - The label name 78084de306b1SToby Isaac . value - The stratum value 78094de306b1SToby Isaac - points - The stratum points 78104de306b1SToby Isaac 78114de306b1SToby Isaac Level: beginner 78124de306b1SToby Isaac 78134de306b1SToby Isaac .seealso: DMLabelSetStratumIS(), DMGetStratumSize() 78144de306b1SToby Isaac @*/ 78154de306b1SToby Isaac PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points) 78164de306b1SToby Isaac { 78174de306b1SToby Isaac DMLabel label; 78184de306b1SToby Isaac PetscErrorCode ierr; 78194de306b1SToby Isaac 78204de306b1SToby Isaac PetscFunctionBegin; 78214de306b1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 78224de306b1SToby Isaac PetscValidCharPointer(name, 2); 78234de306b1SToby Isaac PetscValidPointer(points, 4); 78244de306b1SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 78254de306b1SToby Isaac if (!label) PetscFunctionReturn(0); 78264de306b1SToby Isaac ierr = DMLabelSetStratumIS(label, value, points);CHKERRQ(ierr); 78274de306b1SToby Isaac PetscFunctionReturn(0); 78284de306b1SToby Isaac } 78294de306b1SToby Isaac 7830c58f1c22SToby Isaac /*@C 7831c58f1c22SToby Isaac DMClearLabelStratum - Remove all points from a stratum from a Sieve Label 7832c58f1c22SToby Isaac 7833c58f1c22SToby Isaac Not Collective 7834c58f1c22SToby Isaac 7835c58f1c22SToby Isaac Input Parameters: 7836c58f1c22SToby Isaac + dm - The DM object 7837c58f1c22SToby Isaac . name - The label name 7838c58f1c22SToby Isaac - value - The label value for this point 7839c58f1c22SToby Isaac 7840c58f1c22SToby Isaac Output Parameter: 7841c58f1c22SToby Isaac 7842c58f1c22SToby Isaac Level: beginner 7843c58f1c22SToby Isaac 7844c58f1c22SToby Isaac .seealso: DMLabelClearStratum(), DMSetLabelValue(), DMGetStratumIS(), DMClearLabelValue() 7845c58f1c22SToby Isaac @*/ 7846c58f1c22SToby Isaac PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value) 7847c58f1c22SToby Isaac { 7848c58f1c22SToby Isaac DMLabel label; 7849c58f1c22SToby Isaac PetscErrorCode ierr; 7850c58f1c22SToby Isaac 7851c58f1c22SToby Isaac PetscFunctionBegin; 7852c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7853c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7854c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7855c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 7856c58f1c22SToby Isaac ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr); 7857c58f1c22SToby Isaac PetscFunctionReturn(0); 7858c58f1c22SToby Isaac } 7859c58f1c22SToby Isaac 7860c58f1c22SToby Isaac /*@ 7861c58f1c22SToby Isaac DMGetNumLabels - Return the number of labels defined by the mesh 7862c58f1c22SToby Isaac 7863c58f1c22SToby Isaac Not Collective 7864c58f1c22SToby Isaac 7865c58f1c22SToby Isaac Input Parameter: 7866c58f1c22SToby Isaac . dm - The DM object 7867c58f1c22SToby Isaac 7868c58f1c22SToby Isaac Output Parameter: 7869c58f1c22SToby Isaac . numLabels - the number of Labels 7870c58f1c22SToby Isaac 7871c58f1c22SToby Isaac Level: intermediate 7872c58f1c22SToby Isaac 7873c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7874c58f1c22SToby Isaac @*/ 7875c58f1c22SToby Isaac PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels) 7876c58f1c22SToby Isaac { 78775d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7878c58f1c22SToby Isaac PetscInt n = 0; 7879c58f1c22SToby Isaac 7880c58f1c22SToby Isaac PetscFunctionBegin; 7881c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7882534a8f05SLisandro Dalcin PetscValidIntPointer(numLabels, 2); 7883c58f1c22SToby Isaac while (next) {++n; next = next->next;} 7884c58f1c22SToby Isaac *numLabels = n; 7885c58f1c22SToby Isaac PetscFunctionReturn(0); 7886c58f1c22SToby Isaac } 7887c58f1c22SToby Isaac 7888c58f1c22SToby Isaac /*@C 7889c58f1c22SToby Isaac DMGetLabelName - Return the name of nth label 7890c58f1c22SToby Isaac 7891c58f1c22SToby Isaac Not Collective 7892c58f1c22SToby Isaac 7893c58f1c22SToby Isaac Input Parameters: 7894c58f1c22SToby Isaac + dm - The DM object 7895c58f1c22SToby Isaac - n - the label number 7896c58f1c22SToby Isaac 7897c58f1c22SToby Isaac Output Parameter: 7898c58f1c22SToby Isaac . name - the label name 7899c58f1c22SToby Isaac 7900c58f1c22SToby Isaac Level: intermediate 7901c58f1c22SToby Isaac 7902c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7903c58f1c22SToby Isaac @*/ 7904c58f1c22SToby Isaac PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name) 7905c58f1c22SToby Isaac { 79065d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7907c58f1c22SToby Isaac PetscInt l = 0; 7908d67d17b1SMatthew G. Knepley PetscErrorCode ierr; 7909c58f1c22SToby Isaac 7910c58f1c22SToby Isaac PetscFunctionBegin; 7911c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7912c58f1c22SToby Isaac PetscValidPointer(name, 3); 7913c58f1c22SToby Isaac while (next) { 7914c58f1c22SToby Isaac if (l == n) { 7915d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, name);CHKERRQ(ierr); 7916c58f1c22SToby Isaac PetscFunctionReturn(0); 7917c58f1c22SToby Isaac } 7918c58f1c22SToby Isaac ++l; 7919c58f1c22SToby Isaac next = next->next; 7920c58f1c22SToby Isaac } 7921c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n); 7922c58f1c22SToby Isaac } 7923c58f1c22SToby Isaac 7924c58f1c22SToby Isaac /*@C 7925c58f1c22SToby Isaac DMHasLabel - Determine whether the mesh has a label of a given name 7926c58f1c22SToby Isaac 7927c58f1c22SToby Isaac Not Collective 7928c58f1c22SToby Isaac 7929c58f1c22SToby Isaac Input Parameters: 7930c58f1c22SToby Isaac + dm - The DM object 7931c58f1c22SToby Isaac - name - The label name 7932c58f1c22SToby Isaac 7933c58f1c22SToby Isaac Output Parameter: 7934c58f1c22SToby Isaac . hasLabel - PETSC_TRUE if the label is present 7935c58f1c22SToby Isaac 7936c58f1c22SToby Isaac Level: intermediate 7937c58f1c22SToby Isaac 7938c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 7939c58f1c22SToby Isaac @*/ 7940c58f1c22SToby Isaac PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel) 7941c58f1c22SToby Isaac { 79425d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7943d67d17b1SMatthew G. Knepley const char *lname; 7944c58f1c22SToby Isaac PetscErrorCode ierr; 7945c58f1c22SToby Isaac 7946c58f1c22SToby Isaac PetscFunctionBegin; 7947c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7948c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7949534a8f05SLisandro Dalcin PetscValidBoolPointer(hasLabel, 3); 7950c58f1c22SToby Isaac *hasLabel = PETSC_FALSE; 7951c58f1c22SToby Isaac while (next) { 7952d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 7953d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, hasLabel);CHKERRQ(ierr); 7954c58f1c22SToby Isaac if (*hasLabel) break; 7955c58f1c22SToby Isaac next = next->next; 7956c58f1c22SToby Isaac } 7957c58f1c22SToby Isaac PetscFunctionReturn(0); 7958c58f1c22SToby Isaac } 7959c58f1c22SToby Isaac 7960c58f1c22SToby Isaac /*@C 7961c58f1c22SToby Isaac DMGetLabel - Return the label of a given name, or NULL 7962c58f1c22SToby Isaac 7963c58f1c22SToby Isaac Not Collective 7964c58f1c22SToby Isaac 7965c58f1c22SToby Isaac Input Parameters: 7966c58f1c22SToby Isaac + dm - The DM object 7967c58f1c22SToby Isaac - name - The label name 7968c58f1c22SToby Isaac 7969c58f1c22SToby Isaac Output Parameter: 7970c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent 7971c58f1c22SToby Isaac 79726d7c9049SMatthew G. Knepley Note: Some of the default labels in a DMPlex will be 79736d7c9049SMatthew G. Knepley $ "depth" - Holds the depth (co-dimension) of each mesh point 79746d7c9049SMatthew G. Knepley $ "celltype" - Holds the topological type of each cell 79756d7c9049SMatthew G. Knepley $ "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 79766d7c9049SMatthew G. Knepley $ "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 79776d7c9049SMatthew G. Knepley $ "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 79786d7c9049SMatthew G. Knepley $ "Vertex Sets" - Mirrors the vertex sets defined by GMsh 79796d7c9049SMatthew G. Knepley 7980c58f1c22SToby Isaac Level: intermediate 7981c58f1c22SToby Isaac 79826d7c9049SMatthew G. Knepley .seealso: DMCreateLabel(), DMHasLabel(), DMPlexGetDepthLabel(), DMPlexGetCellType() 7983c58f1c22SToby Isaac @*/ 7984c58f1c22SToby Isaac PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label) 7985c58f1c22SToby Isaac { 79865d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7987c58f1c22SToby Isaac PetscBool hasLabel; 7988d67d17b1SMatthew G. Knepley const char *lname; 7989c58f1c22SToby Isaac PetscErrorCode ierr; 7990c58f1c22SToby Isaac 7991c58f1c22SToby Isaac PetscFunctionBegin; 7992c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7993c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 7994c58f1c22SToby Isaac PetscValidPointer(label, 3); 7995c58f1c22SToby Isaac *label = NULL; 7996c58f1c22SToby Isaac while (next) { 7997d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 7998d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr); 7999c58f1c22SToby Isaac if (hasLabel) { 8000c58f1c22SToby Isaac *label = next->label; 8001c58f1c22SToby Isaac break; 8002c58f1c22SToby Isaac } 8003c58f1c22SToby Isaac next = next->next; 8004c58f1c22SToby Isaac } 8005c58f1c22SToby Isaac PetscFunctionReturn(0); 8006c58f1c22SToby Isaac } 8007c58f1c22SToby Isaac 8008c58f1c22SToby Isaac /*@C 8009c58f1c22SToby Isaac DMGetLabelByNum - Return the nth label 8010c58f1c22SToby Isaac 8011c58f1c22SToby Isaac Not Collective 8012c58f1c22SToby Isaac 8013c58f1c22SToby Isaac Input Parameters: 8014c58f1c22SToby Isaac + dm - The DM object 8015c58f1c22SToby Isaac - n - the label number 8016c58f1c22SToby Isaac 8017c58f1c22SToby Isaac Output Parameter: 8018c58f1c22SToby Isaac . label - the label 8019c58f1c22SToby Isaac 8020c58f1c22SToby Isaac Level: intermediate 8021c58f1c22SToby Isaac 8022c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 8023c58f1c22SToby Isaac @*/ 8024c58f1c22SToby Isaac PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label) 8025c58f1c22SToby Isaac { 80265d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 8027c58f1c22SToby Isaac PetscInt l = 0; 8028c58f1c22SToby Isaac 8029c58f1c22SToby Isaac PetscFunctionBegin; 8030c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8031c58f1c22SToby Isaac PetscValidPointer(label, 3); 8032c58f1c22SToby Isaac while (next) { 8033c58f1c22SToby Isaac if (l == n) { 8034c58f1c22SToby Isaac *label = next->label; 8035c58f1c22SToby Isaac PetscFunctionReturn(0); 8036c58f1c22SToby Isaac } 8037c58f1c22SToby Isaac ++l; 8038c58f1c22SToby Isaac next = next->next; 8039c58f1c22SToby Isaac } 8040c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n); 8041c58f1c22SToby Isaac } 8042c58f1c22SToby Isaac 8043c58f1c22SToby Isaac /*@C 8044c58f1c22SToby Isaac DMAddLabel - Add the label to this mesh 8045c58f1c22SToby Isaac 8046c58f1c22SToby Isaac Not Collective 8047c58f1c22SToby Isaac 8048c58f1c22SToby Isaac Input Parameters: 8049c58f1c22SToby Isaac + dm - The DM object 8050c58f1c22SToby Isaac - label - The DMLabel 8051c58f1c22SToby Isaac 8052c58f1c22SToby Isaac Level: developer 8053c58f1c22SToby Isaac 8054c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 8055c58f1c22SToby Isaac @*/ 8056c58f1c22SToby Isaac PetscErrorCode DMAddLabel(DM dm, DMLabel label) 8057c58f1c22SToby Isaac { 80585d80c0bfSVaclav Hapla DMLabelLink l, *p, tmpLabel; 8059c58f1c22SToby Isaac PetscBool hasLabel; 8060d67d17b1SMatthew G. Knepley const char *lname; 80615d80c0bfSVaclav Hapla PetscBool flg; 8062c58f1c22SToby Isaac PetscErrorCode ierr; 8063c58f1c22SToby Isaac 8064c58f1c22SToby Isaac PetscFunctionBegin; 8065c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8066d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 8067d67d17b1SMatthew G. Knepley ierr = DMHasLabel(dm, lname, &hasLabel);CHKERRQ(ierr); 8068d67d17b1SMatthew G. Knepley if (hasLabel) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname); 8069c58f1c22SToby Isaac ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr); 8070c58f1c22SToby Isaac tmpLabel->label = label; 8071c58f1c22SToby Isaac tmpLabel->output = PETSC_TRUE; 80725d80c0bfSVaclav Hapla for (p=&dm->labels; (l=*p); p=&l->next) {} 80735d80c0bfSVaclav Hapla *p = tmpLabel; 807408f633c4SVaclav Hapla ierr = PetscObjectReference((PetscObject)label);CHKERRQ(ierr); 80755d80c0bfSVaclav Hapla ierr = PetscStrcmp(lname, "depth", &flg);CHKERRQ(ierr); 80765d80c0bfSVaclav Hapla if (flg) dm->depthLabel = label; 8077ba2698f1SMatthew G. Knepley ierr = PetscStrcmp(lname, "celltype", &flg);CHKERRQ(ierr); 8078ba2698f1SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 8079c58f1c22SToby Isaac PetscFunctionReturn(0); 8080c58f1c22SToby Isaac } 8081c58f1c22SToby Isaac 8082c58f1c22SToby Isaac /*@C 80834a7ee7d0SMatthew G. Knepley DMSetLabel - Replaces the label of a given name, or ignores it if the name is not present 80844a7ee7d0SMatthew G. Knepley 80854a7ee7d0SMatthew G. Knepley Not Collective 80864a7ee7d0SMatthew G. Knepley 80874a7ee7d0SMatthew G. Knepley Input Parameters: 80884a7ee7d0SMatthew G. Knepley + dm - The DM object 80894a7ee7d0SMatthew G. Knepley - label - The DMLabel, having the same name, to substitute 80904a7ee7d0SMatthew G. Knepley 80914a7ee7d0SMatthew G. Knepley Note: Some of the default labels in a DMPlex will be 80924a7ee7d0SMatthew G. Knepley $ "depth" - Holds the depth (co-dimension) of each mesh point 80934a7ee7d0SMatthew G. Knepley $ "celltype" - Holds the topological type of each cell 80944a7ee7d0SMatthew G. Knepley $ "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 80954a7ee7d0SMatthew G. Knepley $ "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 80964a7ee7d0SMatthew G. Knepley $ "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 80974a7ee7d0SMatthew G. Knepley $ "Vertex Sets" - Mirrors the vertex sets defined by GMsh 80984a7ee7d0SMatthew G. Knepley 80994a7ee7d0SMatthew G. Knepley Level: intermediate 81004a7ee7d0SMatthew G. Knepley 81014a7ee7d0SMatthew G. Knepley .seealso: DMCreateLabel(), DMHasLabel(), DMPlexGetDepthLabel(), DMPlexGetCellType() 81024a7ee7d0SMatthew G. Knepley @*/ 81034a7ee7d0SMatthew G. Knepley PetscErrorCode DMSetLabel(DM dm, DMLabel label) 81044a7ee7d0SMatthew G. Knepley { 81054a7ee7d0SMatthew G. Knepley DMLabelLink next = dm->labels; 81064a7ee7d0SMatthew G. Knepley PetscBool hasLabel, flg; 81074a7ee7d0SMatthew G. Knepley const char *name, *lname; 81084a7ee7d0SMatthew G. Knepley PetscErrorCode ierr; 81094a7ee7d0SMatthew G. Knepley 81104a7ee7d0SMatthew G. Knepley PetscFunctionBegin; 81114a7ee7d0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 81124a7ee7d0SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 81134a7ee7d0SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &name);CHKERRQ(ierr); 81144a7ee7d0SMatthew G. Knepley while (next) { 81154a7ee7d0SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 81164a7ee7d0SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr); 81174a7ee7d0SMatthew G. Knepley if (hasLabel) { 81184a7ee7d0SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 81194a7ee7d0SMatthew G. Knepley ierr = PetscStrcmp(lname, "depth", &flg);CHKERRQ(ierr); 81204a7ee7d0SMatthew G. Knepley if (flg) dm->depthLabel = label; 81214a7ee7d0SMatthew G. Knepley ierr = PetscStrcmp(lname, "celltype", &flg);CHKERRQ(ierr); 81224a7ee7d0SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 81234a7ee7d0SMatthew G. Knepley ierr = DMLabelDestroy(&next->label);CHKERRQ(ierr); 81244a7ee7d0SMatthew G. Knepley next->label = label; 81254a7ee7d0SMatthew G. Knepley break; 81264a7ee7d0SMatthew G. Knepley } 81274a7ee7d0SMatthew G. Knepley next = next->next; 81284a7ee7d0SMatthew G. Knepley } 81294a7ee7d0SMatthew G. Knepley PetscFunctionReturn(0); 81304a7ee7d0SMatthew G. Knepley } 81314a7ee7d0SMatthew G. Knepley 81324a7ee7d0SMatthew G. Knepley /*@C 8133e5472504SVaclav Hapla DMRemoveLabel - Remove the label given by name from this mesh 8134c58f1c22SToby Isaac 8135c58f1c22SToby Isaac Not Collective 8136c58f1c22SToby Isaac 8137c58f1c22SToby Isaac Input Parameters: 8138c58f1c22SToby Isaac + dm - The DM object 8139c58f1c22SToby Isaac - name - The label name 8140c58f1c22SToby Isaac 8141c58f1c22SToby Isaac Output Parameter: 8142c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent 8143c58f1c22SToby Isaac 8144c58f1c22SToby Isaac Level: developer 8145c58f1c22SToby Isaac 8146e5472504SVaclav Hapla Notes: 8147e5472504SVaclav Hapla DMRemoveLabel(dm,name,NULL) removes the label from dm and calls 8148e5472504SVaclav Hapla DMLabelDestroy() on the label. 8149e5472504SVaclav Hapla 8150e5472504SVaclav Hapla DMRemoveLabel(dm,name,&label) removes the label from dm, but it DOES NOT 8151e5472504SVaclav Hapla call DMLabelDestroy(). Instead, the label is returned and the user is 8152e5472504SVaclav Hapla responsible of calling DMLabelDestroy() at some point. 8153e5472504SVaclav Hapla 8154e5472504SVaclav Hapla .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabel(), DMGetLabelValue(), DMSetLabelValue(), DMLabelDestroy(), DMRemoveLabelBySelf() 8155c58f1c22SToby Isaac @*/ 8156c58f1c22SToby Isaac PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label) 8157c58f1c22SToby Isaac { 815895d578d6SVaclav Hapla DMLabelLink link, *pnext; 8159c58f1c22SToby Isaac PetscBool hasLabel; 8160d67d17b1SMatthew G. Knepley const char *lname; 8161c58f1c22SToby Isaac PetscErrorCode ierr; 8162c58f1c22SToby Isaac 8163c58f1c22SToby Isaac PetscFunctionBegin; 8164c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8165e5472504SVaclav Hapla PetscValidCharPointer(name, 2); 8166e5472504SVaclav Hapla if (label) { 8167e5472504SVaclav Hapla PetscValidPointer(label, 3); 8168c58f1c22SToby Isaac *label = NULL; 8169e5472504SVaclav Hapla } 81705d80c0bfSVaclav Hapla for (pnext=&dm->labels; (link=*pnext); pnext=&link->next) { 817195d578d6SVaclav Hapla ierr = PetscObjectGetName((PetscObject) link->label, &lname);CHKERRQ(ierr); 8172d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr); 8173c58f1c22SToby Isaac if (hasLabel) { 817495d578d6SVaclav Hapla *pnext = link->next; /* Remove from list */ 8175c58f1c22SToby Isaac ierr = PetscStrcmp(name, "depth", &hasLabel);CHKERRQ(ierr); 817695d578d6SVaclav Hapla if (hasLabel) dm->depthLabel = NULL; 8177ba2698f1SMatthew G. Knepley ierr = PetscStrcmp(name, "celltype", &hasLabel);CHKERRQ(ierr); 8178ba2698f1SMatthew G. Knepley if (hasLabel) dm->celltypeLabel = NULL; 817995d578d6SVaclav Hapla if (label) *label = link->label; 818095d578d6SVaclav Hapla else {ierr = DMLabelDestroy(&link->label);CHKERRQ(ierr);} 818195d578d6SVaclav Hapla ierr = PetscFree(link);CHKERRQ(ierr); 8182c58f1c22SToby Isaac break; 8183c58f1c22SToby Isaac } 8184c58f1c22SToby Isaac } 8185c58f1c22SToby Isaac PetscFunctionReturn(0); 8186c58f1c22SToby Isaac } 8187c58f1c22SToby Isaac 8188306894acSVaclav Hapla /*@ 8189306894acSVaclav Hapla DMRemoveLabelBySelf - Remove the label from this mesh 8190306894acSVaclav Hapla 8191306894acSVaclav Hapla Not Collective 8192306894acSVaclav Hapla 8193306894acSVaclav Hapla Input Parameters: 8194306894acSVaclav Hapla + dm - The DM object 8195876aa926SVaclav Hapla . label - The DMLabel to be removed from the DM 8196306894acSVaclav Hapla - failNotFound - Should it fail if the label is not found in the DM? 8197306894acSVaclav Hapla 8198306894acSVaclav Hapla Level: developer 8199306894acSVaclav Hapla 8200306894acSVaclav Hapla Notes: 8201306894acSVaclav Hapla Only exactly the same instance is removed if found, name match is ignored. 8202306894acSVaclav Hapla If the DM has an exclusive reference to the label, it gets destroyed and 8203306894acSVaclav Hapla *label nullified. 8204306894acSVaclav Hapla 8205306894acSVaclav Hapla .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabel() DMGetLabelValue(), DMSetLabelValue(), DMLabelDestroy(), DMRemoveLabel() 8206306894acSVaclav Hapla @*/ 8207306894acSVaclav Hapla PetscErrorCode DMRemoveLabelBySelf(DM dm, DMLabel *label, PetscBool failNotFound) 8208306894acSVaclav Hapla { 820943e45a93SVaclav Hapla DMLabelLink link, *pnext; 8210306894acSVaclav Hapla PetscBool hasLabel = PETSC_FALSE; 8211306894acSVaclav Hapla PetscErrorCode ierr; 8212306894acSVaclav Hapla 8213306894acSVaclav Hapla PetscFunctionBegin; 8214306894acSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8215306894acSVaclav Hapla PetscValidPointer(label, 2); 8216f39a9ae0SVaclav Hapla if (!*label && !failNotFound) PetscFunctionReturn(0); 8217306894acSVaclav Hapla PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 2); 8218306894acSVaclav Hapla PetscValidLogicalCollectiveBool(dm,failNotFound,3); 82195d80c0bfSVaclav Hapla for (pnext=&dm->labels; (link=*pnext); pnext=&link->next) { 822043e45a93SVaclav Hapla if (*label == link->label) { 8221306894acSVaclav Hapla hasLabel = PETSC_TRUE; 822243e45a93SVaclav Hapla *pnext = link->next; /* Remove from list */ 8223306894acSVaclav Hapla if (*label == dm->depthLabel) dm->depthLabel = NULL; 8224ba2698f1SMatthew G. Knepley if (*label == dm->celltypeLabel) dm->celltypeLabel = NULL; 822543e45a93SVaclav Hapla if (((PetscObject) link->label)->refct < 2) *label = NULL; /* nullify if exclusive reference */ 822643e45a93SVaclav Hapla ierr = DMLabelDestroy(&link->label);CHKERRQ(ierr); 822743e45a93SVaclav Hapla ierr = PetscFree(link);CHKERRQ(ierr); 8228306894acSVaclav Hapla break; 8229306894acSVaclav Hapla } 8230306894acSVaclav Hapla } 8231306894acSVaclav Hapla if (!hasLabel && failNotFound) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Given label not found in DM"); 8232306894acSVaclav Hapla PetscFunctionReturn(0); 8233306894acSVaclav Hapla } 8234306894acSVaclav Hapla 8235c58f1c22SToby Isaac /*@C 8236c58f1c22SToby Isaac DMGetLabelOutput - Get the output flag for a given label 8237c58f1c22SToby Isaac 8238c58f1c22SToby Isaac Not Collective 8239c58f1c22SToby Isaac 8240c58f1c22SToby Isaac Input Parameters: 8241c58f1c22SToby Isaac + dm - The DM object 8242c58f1c22SToby Isaac - name - The label name 8243c58f1c22SToby Isaac 8244c58f1c22SToby Isaac Output Parameter: 8245c58f1c22SToby Isaac . output - The flag for output 8246c58f1c22SToby Isaac 8247c58f1c22SToby Isaac Level: developer 8248c58f1c22SToby Isaac 8249c58f1c22SToby Isaac .seealso: DMSetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 8250c58f1c22SToby Isaac @*/ 8251c58f1c22SToby Isaac PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output) 8252c58f1c22SToby Isaac { 82535d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 8254d67d17b1SMatthew G. Knepley const char *lname; 8255c58f1c22SToby Isaac PetscErrorCode ierr; 8256c58f1c22SToby Isaac 8257c58f1c22SToby Isaac PetscFunctionBegin; 8258c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8259c58f1c22SToby Isaac PetscValidPointer(name, 2); 8260c58f1c22SToby Isaac PetscValidPointer(output, 3); 8261c58f1c22SToby Isaac while (next) { 8262c58f1c22SToby Isaac PetscBool flg; 8263c58f1c22SToby Isaac 8264d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 8265d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr); 8266c58f1c22SToby Isaac if (flg) {*output = next->output; PetscFunctionReturn(0);} 8267c58f1c22SToby Isaac next = next->next; 8268c58f1c22SToby Isaac } 8269c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 8270c58f1c22SToby Isaac } 8271c58f1c22SToby Isaac 8272c58f1c22SToby Isaac /*@C 8273c58f1c22SToby Isaac DMSetLabelOutput - Set the output flag for a given label 8274c58f1c22SToby Isaac 8275c58f1c22SToby Isaac Not Collective 8276c58f1c22SToby Isaac 8277c58f1c22SToby Isaac Input Parameters: 8278c58f1c22SToby Isaac + dm - The DM object 8279c58f1c22SToby Isaac . name - The label name 8280c58f1c22SToby Isaac - output - The flag for output 8281c58f1c22SToby Isaac 8282c58f1c22SToby Isaac Level: developer 8283c58f1c22SToby Isaac 8284c58f1c22SToby Isaac .seealso: DMGetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS() 8285c58f1c22SToby Isaac @*/ 8286c58f1c22SToby Isaac PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output) 8287c58f1c22SToby Isaac { 82885d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 8289d67d17b1SMatthew G. Knepley const char *lname; 8290c58f1c22SToby Isaac PetscErrorCode ierr; 8291c58f1c22SToby Isaac 8292c58f1c22SToby Isaac PetscFunctionBegin; 8293c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8294534a8f05SLisandro Dalcin PetscValidCharPointer(name, 2); 8295c58f1c22SToby Isaac while (next) { 8296c58f1c22SToby Isaac PetscBool flg; 8297c58f1c22SToby Isaac 8298d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr); 8299d67d17b1SMatthew G. Knepley ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr); 8300c58f1c22SToby Isaac if (flg) {next->output = output; PetscFunctionReturn(0);} 8301c58f1c22SToby Isaac next = next->next; 8302c58f1c22SToby Isaac } 8303c58f1c22SToby Isaac SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 8304c58f1c22SToby Isaac } 8305c58f1c22SToby Isaac 8306c58f1c22SToby Isaac /*@ 8307c58f1c22SToby Isaac DMCopyLabels - Copy labels from one mesh to another with a superset of the points 8308c58f1c22SToby Isaac 8309d083f849SBarry Smith Collective on dmA 8310c58f1c22SToby Isaac 8311d8d19677SJose E. Roman Input Parameters: 83125d80c0bfSVaclav Hapla + dmA - The DM object with initial labels 83132cbb9b06SVaclav Hapla . dmB - The DM object to which labels are copied 83145d80c0bfSVaclav Hapla . mode - Copy labels by pointers (PETSC_OWN_POINTER) or duplicate them (PETSC_COPY_VALUES) 83152cbb9b06SVaclav Hapla . all - Copy all labels including "depth", "dim", and "celltype" (PETSC_TRUE) which are otherwise ignored (PETSC_FALSE) 83162cbb9b06SVaclav Hapla - emode - How to behave when a DMLabel in the source and destination DMs with the same name is encountered (see DMCopyLabelsMode) 8317c58f1c22SToby Isaac 8318c58f1c22SToby Isaac Level: intermediate 8319c58f1c22SToby Isaac 83202cbb9b06SVaclav Hapla Notes: 83212cbb9b06SVaclav Hapla This is typically used when interpolating or otherwise adding to a mesh, or testing. 8322c58f1c22SToby Isaac 83232cbb9b06SVaclav Hapla .seealso: DMAddLabel(), DMCopyLabelsMode 8324c58f1c22SToby Isaac @*/ 83252cbb9b06SVaclav Hapla PetscErrorCode DMCopyLabels(DM dmA, DM dmB, PetscCopyMode mode, PetscBool all, DMCopyLabelsMode emode) 8326c58f1c22SToby Isaac { 83272cbb9b06SVaclav Hapla DMLabel label, labelNew, labelOld; 8328c58f1c22SToby Isaac const char *name; 8329c58f1c22SToby Isaac PetscBool flg; 83305d80c0bfSVaclav Hapla DMLabelLink link; 83315d80c0bfSVaclav Hapla PetscErrorCode ierr; 8332c58f1c22SToby Isaac 83335d80c0bfSVaclav Hapla PetscFunctionBegin; 83345d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 83355d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 83365d80c0bfSVaclav Hapla PetscValidLogicalCollectiveEnum(dmA, mode,3); 83375d80c0bfSVaclav Hapla PetscValidLogicalCollectiveBool(dmA, all, 4); 83385d80c0bfSVaclav Hapla if (mode==PETSC_USE_POINTER) SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_SUP, "PETSC_USE_POINTER not supported for objects"); 83395d80c0bfSVaclav Hapla if (dmA == dmB) PetscFunctionReturn(0); 83405d80c0bfSVaclav Hapla for (link=dmA->labels; link; link=link->next) { 83415d80c0bfSVaclav Hapla label=link->label; 83425d80c0bfSVaclav Hapla ierr = PetscObjectGetName((PetscObject)label, &name);CHKERRQ(ierr); 83435d80c0bfSVaclav Hapla if (!all) { 8344c58f1c22SToby Isaac ierr = PetscStrcmp(name, "depth", &flg);CHKERRQ(ierr); 8345c58f1c22SToby Isaac if (flg) continue; 83467d5acc75SStefano Zampini ierr = PetscStrcmp(name, "dim", &flg);CHKERRQ(ierr); 83477d5acc75SStefano Zampini if (flg) continue; 8348ba2698f1SMatthew G. Knepley ierr = PetscStrcmp(name, "celltype", &flg);CHKERRQ(ierr); 8349ba2698f1SMatthew G. Knepley if (flg) continue; 83505d80c0bfSVaclav Hapla } 83512cbb9b06SVaclav Hapla ierr = DMGetLabel(dmB, name, &labelOld);CHKERRQ(ierr); 83522cbb9b06SVaclav Hapla if (labelOld) { 83532cbb9b06SVaclav Hapla switch (emode) { 83542cbb9b06SVaclav Hapla case DM_COPY_LABELS_KEEP: 83552cbb9b06SVaclav Hapla continue; 83562cbb9b06SVaclav Hapla case DM_COPY_LABELS_REPLACE: 83572cbb9b06SVaclav Hapla ierr = DMRemoveLabelBySelf(dmB, &labelOld, PETSC_TRUE);CHKERRQ(ierr); 83582cbb9b06SVaclav Hapla break; 83592cbb9b06SVaclav Hapla case DM_COPY_LABELS_FAIL: 83602cbb9b06SVaclav Hapla SETERRQ1(PetscObjectComm((PetscObject)dmA), PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in destination DM", name); 83612cbb9b06SVaclav Hapla default: 83622cbb9b06SVaclav Hapla SETERRQ1(PetscObjectComm((PetscObject)dmA), PETSC_ERR_ARG_OUTOFRANGE, "Unhandled DMCopyLabelsMode %d", emode); 83632cbb9b06SVaclav Hapla } 83642cbb9b06SVaclav Hapla } 83655d80c0bfSVaclav Hapla if (mode==PETSC_COPY_VALUES) { 8366c58f1c22SToby Isaac ierr = DMLabelDuplicate(label, &labelNew);CHKERRQ(ierr); 83675d80c0bfSVaclav Hapla } else { 83685d80c0bfSVaclav Hapla labelNew = label; 83695d80c0bfSVaclav Hapla } 8370c58f1c22SToby Isaac ierr = DMAddLabel(dmB, labelNew);CHKERRQ(ierr); 83715d80c0bfSVaclav Hapla if (mode==PETSC_COPY_VALUES) {ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr);} 8372c58f1c22SToby Isaac } 8373c58f1c22SToby Isaac PetscFunctionReturn(0); 8374c58f1c22SToby Isaac } 8375461a15a0SLisandro Dalcin 8376609dae6eSVaclav Hapla /*@C 8377609dae6eSVaclav Hapla DMCompareLabels - Compare labels of two DMPlex meshes 8378609dae6eSVaclav Hapla 8379609dae6eSVaclav Hapla Collective on dmA 8380609dae6eSVaclav Hapla 8381609dae6eSVaclav Hapla Input Parameters: 8382609dae6eSVaclav Hapla + dm0 - First DM object 8383609dae6eSVaclav Hapla - dm1 - Second DM object 8384609dae6eSVaclav Hapla 8385609dae6eSVaclav Hapla Output Parameters 8386609dae6eSVaclav Hapla + same - (Optional) Flag whether labels of dm0 and dm1 are the same 8387609dae6eSVaclav Hapla - message - (Optional) Message describing the difference, or NULL if there is no difference 8388609dae6eSVaclav Hapla 8389609dae6eSVaclav Hapla Level: intermediate 8390609dae6eSVaclav Hapla 8391609dae6eSVaclav Hapla Notes: 8392609dae6eSVaclav Hapla If both same and message is passed as NULL, and difference is found, an error is thrown with a message describing the difference. 8393609dae6eSVaclav Hapla 8394609dae6eSVaclav Hapla Message must be freed by user. 8395609dae6eSVaclav Hapla 8396609dae6eSVaclav Hapla Labels are matched by name. If the number of labels and their names are equal, 8397609dae6eSVaclav Hapla DMLabelCompare() is used to compare each pair of labels with the same name. 8398609dae6eSVaclav Hapla 8399609dae6eSVaclav Hapla Fortran Notes: 8400609dae6eSVaclav Hapla This function is currently not available from Fortran. 8401609dae6eSVaclav Hapla 8402609dae6eSVaclav Hapla .seealso: DMAddLabel(), DMCopyLabelsMode, DMLabelCompare() 8403609dae6eSVaclav Hapla @*/ 8404609dae6eSVaclav Hapla PetscErrorCode DMCompareLabels(DM dm0, DM dm1, PetscBool *same, char **message) 8405609dae6eSVaclav Hapla { 8406609dae6eSVaclav Hapla PetscInt n0, n1, i; 8407609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 8408609dae6eSVaclav Hapla MPI_Comm comm; 8409609dae6eSVaclav Hapla PetscErrorCode ierr; 8410609dae6eSVaclav Hapla 8411609dae6eSVaclav Hapla PetscFunctionBegin; 8412609dae6eSVaclav Hapla PetscValidHeaderSpecific(dm0,DM_CLASSID,1); 8413609dae6eSVaclav Hapla PetscValidHeaderSpecific(dm1,DM_CLASSID,2); 8414609dae6eSVaclav Hapla PetscCheckSameComm(dm0,1,dm1,2); 8415609dae6eSVaclav Hapla if (same) PetscValidBoolPointer(same,3); 8416609dae6eSVaclav Hapla if (message) PetscValidPointer(message, 4); 8417609dae6eSVaclav Hapla ierr = PetscObjectGetComm((PetscObject)dm0, &comm);CHKERRQ(ierr); 8418609dae6eSVaclav Hapla ierr = DMGetNumLabels(dm0, &n0);CHKERRQ(ierr); 8419609dae6eSVaclav Hapla ierr = DMGetNumLabels(dm1, &n1);CHKERRQ(ierr); 8420609dae6eSVaclav Hapla if (n0 != n1) { 8421609dae6eSVaclav Hapla ierr = PetscSNPrintf(msg, sizeof(msg), "Number of labels in dm0 = %D != %D = Number of labels in dm1", n0, n1);CHKERRQ(ierr); 8422609dae6eSVaclav Hapla goto finish; 8423609dae6eSVaclav Hapla } 8424609dae6eSVaclav Hapla for (i=0; i<n0; i++) { 8425609dae6eSVaclav Hapla DMLabel l0, l1; 8426609dae6eSVaclav Hapla const char *name; 8427609dae6eSVaclav Hapla char *msgInner; 8428609dae6eSVaclav Hapla 8429609dae6eSVaclav Hapla /* Ignore label order */ 8430609dae6eSVaclav Hapla ierr = DMGetLabelByNum(dm0, i, &l0);CHKERRQ(ierr); 8431609dae6eSVaclav Hapla ierr = PetscObjectGetName((PetscObject)l0, &name);CHKERRQ(ierr); 8432609dae6eSVaclav Hapla ierr = DMGetLabel(dm1, name, &l1);CHKERRQ(ierr); 8433609dae6eSVaclav Hapla if (!l1) { 8434609dae6eSVaclav Hapla ierr = PetscSNPrintf(msg, sizeof(msg), "Label \"%s\" (#%D in dm0) not found in dm1", name, i);CHKERRQ(ierr); 8435609dae6eSVaclav Hapla goto finish; 8436609dae6eSVaclav Hapla } 8437609dae6eSVaclav Hapla ierr = DMLabelCompare(l0, l1, NULL, &msgInner);CHKERRQ(ierr); 8438609dae6eSVaclav Hapla ierr = PetscStrncpy(msg, msgInner, sizeof(msg));CHKERRQ(ierr); 8439609dae6eSVaclav Hapla ierr = PetscFree(msgInner);CHKERRQ(ierr); 8440609dae6eSVaclav Hapla if (msg[0]) goto finish; 8441609dae6eSVaclav Hapla } 8442609dae6eSVaclav Hapla finish: 8443609dae6eSVaclav Hapla if (msg[0] && !same && !message) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, msg); 8444609dae6eSVaclav Hapla if (same) *same = (PetscBool) !msg[0]; 8445609dae6eSVaclav Hapla if (message) { 8446609dae6eSVaclav Hapla *message = NULL; 8447609dae6eSVaclav Hapla if (msg[0]) { 8448609dae6eSVaclav Hapla ierr = PetscStrallocpy(msg, message);CHKERRQ(ierr); 8449609dae6eSVaclav Hapla } 8450609dae6eSVaclav Hapla } 8451609dae6eSVaclav Hapla PetscFunctionReturn(0); 8452609dae6eSVaclav Hapla } 8453609dae6eSVaclav Hapla 8454461a15a0SLisandro Dalcin PetscErrorCode DMSetLabelValue_Fast(DM dm, DMLabel *label, const char name[], PetscInt point, PetscInt value) 8455461a15a0SLisandro Dalcin { 8456461a15a0SLisandro Dalcin PetscErrorCode ierr; 8457609dae6eSVaclav Hapla 8458461a15a0SLisandro Dalcin PetscFunctionBegin; 8459461a15a0SLisandro Dalcin PetscValidPointer(label,2); 8460461a15a0SLisandro Dalcin if (!*label) { 8461461a15a0SLisandro Dalcin ierr = DMCreateLabel(dm, name);CHKERRQ(ierr); 8462461a15a0SLisandro Dalcin ierr = DMGetLabel(dm, name, label);CHKERRQ(ierr); 8463461a15a0SLisandro Dalcin } 8464461a15a0SLisandro Dalcin ierr = DMLabelSetValue(*label, point, value);CHKERRQ(ierr); 8465461a15a0SLisandro Dalcin PetscFunctionReturn(0); 8466461a15a0SLisandro Dalcin } 8467461a15a0SLisandro Dalcin 84680fdc7489SMatthew Knepley /* 84690fdc7489SMatthew Knepley Many mesh programs, such as Triangle and TetGen, allow only a single label for each mesh point. Therefore, we would 84700fdc7489SMatthew Knepley like to encode all label IDs using a single, universal label. We can do this by assigning an integer to every 84710fdc7489SMatthew Knepley (label, id) pair in the DM. 84720fdc7489SMatthew Knepley 84730fdc7489SMatthew Knepley However, a mesh point can have multiple labels, so we must separate all these values. We will assign a bit range to 84740fdc7489SMatthew Knepley each label. 84750fdc7489SMatthew Knepley */ 84760fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelCreate(DM dm, DMUniversalLabel *universal) 84770fdc7489SMatthew Knepley { 84780fdc7489SMatthew Knepley DMUniversalLabel ul; 84790fdc7489SMatthew Knepley PetscBool *active; 84800fdc7489SMatthew Knepley PetscInt pStart, pEnd, p, Nl, l, m; 84810fdc7489SMatthew Knepley PetscErrorCode ierr; 84820fdc7489SMatthew Knepley 84830fdc7489SMatthew Knepley PetscFunctionBegin; 84840fdc7489SMatthew Knepley ierr = PetscMalloc1(1, &ul);CHKERRQ(ierr); 84850fdc7489SMatthew Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, "universal", &ul->label);CHKERRQ(ierr); 84860fdc7489SMatthew Knepley ierr = DMGetNumLabels(dm, &Nl);CHKERRQ(ierr); 84870fdc7489SMatthew Knepley ierr = PetscCalloc1(Nl, &active);CHKERRQ(ierr); 84880fdc7489SMatthew Knepley ul->Nl = 0; 84890fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 84900fdc7489SMatthew Knepley PetscBool isdepth, iscelltype; 84910fdc7489SMatthew Knepley const char *name; 84920fdc7489SMatthew Knepley 84930fdc7489SMatthew Knepley ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 84940fdc7489SMatthew Knepley ierr = PetscStrncmp(name, "depth", 6, &isdepth);CHKERRQ(ierr); 84950fdc7489SMatthew Knepley ierr = PetscStrncmp(name, "celltype", 9, &iscelltype);CHKERRQ(ierr); 84960fdc7489SMatthew Knepley active[l] = !(isdepth || iscelltype) ? PETSC_TRUE : PETSC_FALSE; 84970fdc7489SMatthew Knepley if (active[l]) ++ul->Nl; 84980fdc7489SMatthew Knepley } 84990fdc7489SMatthew 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); 85000fdc7489SMatthew Knepley ul->Nv = 0; 85010fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 85020fdc7489SMatthew Knepley DMLabel label; 85030fdc7489SMatthew Knepley PetscInt nv; 85040fdc7489SMatthew Knepley const char *name; 85050fdc7489SMatthew Knepley 85060fdc7489SMatthew Knepley if (!active[l]) continue; 85070fdc7489SMatthew Knepley ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 85080fdc7489SMatthew Knepley ierr = DMGetLabelByNum(dm, l, &label);CHKERRQ(ierr); 85090fdc7489SMatthew Knepley ierr = DMLabelGetNumValues(label, &nv);CHKERRQ(ierr); 85100fdc7489SMatthew Knepley ierr = PetscStrallocpy(name, &ul->names[m]);CHKERRQ(ierr); 85110fdc7489SMatthew Knepley ul->indices[m] = l; 85120fdc7489SMatthew Knepley ul->Nv += nv; 85130fdc7489SMatthew Knepley ul->offsets[m+1] = nv; 85140fdc7489SMatthew Knepley ul->bits[m+1] = PetscCeilReal(PetscLog2Real(nv+1)); 85150fdc7489SMatthew Knepley ++m; 85160fdc7489SMatthew Knepley } 85170fdc7489SMatthew Knepley for (l = 1; l <= ul->Nl; ++l) { 85180fdc7489SMatthew Knepley ul->offsets[l] = ul->offsets[l-1] + ul->offsets[l]; 85190fdc7489SMatthew Knepley ul->bits[l] = ul->bits[l-1] + ul->bits[l]; 85200fdc7489SMatthew Knepley } 85210fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 85220fdc7489SMatthew Knepley PetscInt b; 85230fdc7489SMatthew Knepley 85240fdc7489SMatthew Knepley ul->masks[l] = 0; 85250fdc7489SMatthew Knepley for (b = ul->bits[l]; b < ul->bits[l+1]; ++b) ul->masks[l] |= 1 << b; 85260fdc7489SMatthew Knepley } 85270fdc7489SMatthew Knepley ierr = PetscMalloc1(ul->Nv, &ul->values);CHKERRQ(ierr); 85280fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 85290fdc7489SMatthew Knepley DMLabel label; 85300fdc7489SMatthew Knepley IS valueIS; 85310fdc7489SMatthew Knepley const PetscInt *varr; 85320fdc7489SMatthew Knepley PetscInt nv, v; 85330fdc7489SMatthew Knepley 85340fdc7489SMatthew Knepley if (!active[l]) continue; 85350fdc7489SMatthew Knepley ierr = DMGetLabelByNum(dm, l, &label);CHKERRQ(ierr); 85360fdc7489SMatthew Knepley ierr = DMLabelGetNumValues(label, &nv);CHKERRQ(ierr); 85370fdc7489SMatthew Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 85380fdc7489SMatthew Knepley ierr = ISGetIndices(valueIS, &varr);CHKERRQ(ierr); 85390fdc7489SMatthew Knepley for (v = 0; v < nv; ++v) { 85400fdc7489SMatthew Knepley ul->values[ul->offsets[m]+v] = varr[v]; 85410fdc7489SMatthew Knepley } 85420fdc7489SMatthew Knepley ierr = ISRestoreIndices(valueIS, &varr);CHKERRQ(ierr); 85430fdc7489SMatthew Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 85440fdc7489SMatthew Knepley ierr = PetscSortInt(nv, &ul->values[ul->offsets[m]]);CHKERRQ(ierr); 85450fdc7489SMatthew Knepley ++m; 85460fdc7489SMatthew Knepley } 85470fdc7489SMatthew Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 85480fdc7489SMatthew Knepley for (p = pStart; p < pEnd; ++p) { 85490fdc7489SMatthew Knepley PetscInt uval = 0; 85500fdc7489SMatthew Knepley PetscBool marked = PETSC_FALSE; 85510fdc7489SMatthew Knepley 85520fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 85530fdc7489SMatthew Knepley DMLabel label; 85540649b39aSStefano Zampini PetscInt val, defval, loc, nv; 85550fdc7489SMatthew Knepley 85560fdc7489SMatthew Knepley if (!active[l]) continue; 85570fdc7489SMatthew Knepley ierr = DMGetLabelByNum(dm, l, &label);CHKERRQ(ierr); 85580fdc7489SMatthew Knepley ierr = DMLabelGetValue(label, p, &val);CHKERRQ(ierr); 85590fdc7489SMatthew Knepley ierr = DMLabelGetDefaultValue(label, &defval);CHKERRQ(ierr); 85600fdc7489SMatthew Knepley if (val == defval) {++m; continue;} 85610649b39aSStefano Zampini nv = ul->offsets[m+1]-ul->offsets[m]; 85620fdc7489SMatthew Knepley marked = PETSC_TRUE; 85630fdc7489SMatthew Knepley ierr = PetscFindInt(val, nv, &ul->values[ul->offsets[m]], &loc);CHKERRQ(ierr); 85640fdc7489SMatthew Knepley if (loc < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Label value %D not found in compression array", val); 85650fdc7489SMatthew Knepley uval += (loc+1) << ul->bits[m]; 85660fdc7489SMatthew Knepley ++m; 85670fdc7489SMatthew Knepley } 85680fdc7489SMatthew Knepley if (marked) {ierr = DMLabelSetValue(ul->label, p, uval);CHKERRQ(ierr);} 85690fdc7489SMatthew Knepley } 85700fdc7489SMatthew Knepley ierr = PetscFree(active);CHKERRQ(ierr); 85710fdc7489SMatthew Knepley *universal = ul; 85720fdc7489SMatthew Knepley PetscFunctionReturn(0); 85730fdc7489SMatthew Knepley } 85740fdc7489SMatthew Knepley 85750fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelDestroy(DMUniversalLabel *universal) 85760fdc7489SMatthew Knepley { 85770fdc7489SMatthew Knepley PetscInt l; 85780fdc7489SMatthew Knepley PetscErrorCode ierr; 85790fdc7489SMatthew Knepley 85800fdc7489SMatthew Knepley PetscFunctionBegin; 85810fdc7489SMatthew Knepley for (l = 0; l < (*universal)->Nl; ++l) {ierr = PetscFree((*universal)->names[l]);CHKERRQ(ierr);} 85820fdc7489SMatthew Knepley ierr = DMLabelDestroy(&(*universal)->label);CHKERRQ(ierr); 85830fdc7489SMatthew Knepley ierr = PetscFree5((*universal)->names, (*universal)->indices, (*universal)->offsets, (*universal)->bits, (*universal)->masks);CHKERRQ(ierr); 85840fdc7489SMatthew Knepley ierr = PetscFree((*universal)->values);CHKERRQ(ierr); 85850fdc7489SMatthew Knepley ierr = PetscFree(*universal);CHKERRQ(ierr); 85860fdc7489SMatthew Knepley *universal = NULL; 85870fdc7489SMatthew Knepley PetscFunctionReturn(0); 85880fdc7489SMatthew Knepley } 85890fdc7489SMatthew Knepley 85900fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelGetLabel(DMUniversalLabel ul, DMLabel *ulabel) 85910fdc7489SMatthew Knepley { 85920fdc7489SMatthew Knepley PetscFunctionBegin; 85930fdc7489SMatthew Knepley PetscValidPointer(ulabel, 2); 85940fdc7489SMatthew Knepley *ulabel = ul->label; 85950fdc7489SMatthew Knepley PetscFunctionReturn(0); 85960fdc7489SMatthew Knepley } 85970fdc7489SMatthew Knepley 85980fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelCreateLabels(DMUniversalLabel ul, PetscBool preserveOrder, DM dm) 85990fdc7489SMatthew Knepley { 86000fdc7489SMatthew Knepley PetscInt Nl = ul->Nl, l; 86010fdc7489SMatthew Knepley PetscErrorCode ierr; 86020fdc7489SMatthew Knepley 86030fdc7489SMatthew Knepley PetscFunctionBegin; 8604064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 3); 86050fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 86060fdc7489SMatthew Knepley if (preserveOrder) {ierr = DMCreateLabelAtIndex(dm, ul->indices[l], ul->names[l]);CHKERRQ(ierr);} 86070fdc7489SMatthew Knepley else {ierr = DMCreateLabel(dm, ul->names[l]);CHKERRQ(ierr);} 86080fdc7489SMatthew Knepley } 86090fdc7489SMatthew Knepley if (preserveOrder) { 86100fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 86110fdc7489SMatthew Knepley const char *name; 86120fdc7489SMatthew Knepley PetscBool match; 86130fdc7489SMatthew Knepley 86140fdc7489SMatthew Knepley ierr = DMGetLabelName(dm, ul->indices[l], &name);CHKERRQ(ierr); 86150fdc7489SMatthew Knepley ierr = PetscStrcmp(name, ul->names[l], &match);CHKERRQ(ierr); 86160fdc7489SMatthew 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]); 86170fdc7489SMatthew Knepley } 86180fdc7489SMatthew Knepley } 86190fdc7489SMatthew Knepley PetscFunctionReturn(0); 86200fdc7489SMatthew Knepley } 86210fdc7489SMatthew Knepley 86220fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelSetLabelValue(DMUniversalLabel ul, DM dm, PetscBool useIndex, PetscInt p, PetscInt value) 86230fdc7489SMatthew Knepley { 86240fdc7489SMatthew Knepley PetscInt l; 86250fdc7489SMatthew Knepley PetscErrorCode ierr; 86260fdc7489SMatthew Knepley 86270fdc7489SMatthew Knepley PetscFunctionBegin; 86280fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 86290fdc7489SMatthew Knepley DMLabel label; 86300fdc7489SMatthew Knepley PetscInt lval = (value & ul->masks[l]) >> ul->bits[l]; 86310fdc7489SMatthew Knepley 86320fdc7489SMatthew Knepley if (lval) { 86330fdc7489SMatthew Knepley if (useIndex) {ierr = DMGetLabelByNum(dm, ul->indices[l], &label);CHKERRQ(ierr);} 86340fdc7489SMatthew Knepley else {ierr = DMGetLabel(dm, ul->names[l], &label);CHKERRQ(ierr);} 86350fdc7489SMatthew Knepley ierr = DMLabelSetValue(label, p, ul->values[ul->offsets[l]+lval-1]);CHKERRQ(ierr); 86360fdc7489SMatthew Knepley } 86370fdc7489SMatthew Knepley } 86380fdc7489SMatthew Knepley PetscFunctionReturn(0); 86390fdc7489SMatthew Knepley } 8640a8fb8f29SToby Isaac 8641a8fb8f29SToby Isaac /*@ 8642a8fb8f29SToby Isaac DMGetCoarseDM - Get the coarse mesh from which this was obtained by refinement 8643a8fb8f29SToby Isaac 8644a8fb8f29SToby Isaac Input Parameter: 8645a8fb8f29SToby Isaac . dm - The DM object 8646a8fb8f29SToby Isaac 8647a8fb8f29SToby Isaac Output Parameter: 8648a8fb8f29SToby Isaac . cdm - The coarse DM 8649a8fb8f29SToby Isaac 8650a8fb8f29SToby Isaac Level: intermediate 8651a8fb8f29SToby Isaac 8652a8fb8f29SToby Isaac .seealso: DMSetCoarseDM() 8653a8fb8f29SToby Isaac @*/ 8654a8fb8f29SToby Isaac PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm) 8655a8fb8f29SToby Isaac { 8656a8fb8f29SToby Isaac PetscFunctionBegin; 8657a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8658a8fb8f29SToby Isaac PetscValidPointer(cdm, 2); 8659a8fb8f29SToby Isaac *cdm = dm->coarseMesh; 8660a8fb8f29SToby Isaac PetscFunctionReturn(0); 8661a8fb8f29SToby Isaac } 8662a8fb8f29SToby Isaac 8663a8fb8f29SToby Isaac /*@ 8664a8fb8f29SToby Isaac DMSetCoarseDM - Set the coarse mesh from which this was obtained by refinement 8665a8fb8f29SToby Isaac 8666a8fb8f29SToby Isaac Input Parameters: 8667a8fb8f29SToby Isaac + dm - The DM object 8668a8fb8f29SToby Isaac - cdm - The coarse DM 8669a8fb8f29SToby Isaac 8670a8fb8f29SToby Isaac Level: intermediate 8671a8fb8f29SToby Isaac 8672a8fb8f29SToby Isaac .seealso: DMGetCoarseDM() 8673a8fb8f29SToby Isaac @*/ 8674a8fb8f29SToby Isaac PetscErrorCode DMSetCoarseDM(DM dm, DM cdm) 8675a8fb8f29SToby Isaac { 8676a8fb8f29SToby Isaac PetscErrorCode ierr; 8677a8fb8f29SToby Isaac 8678a8fb8f29SToby Isaac PetscFunctionBegin; 8679a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8680a8fb8f29SToby Isaac if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 8681a8fb8f29SToby Isaac ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr); 8682a8fb8f29SToby Isaac ierr = DMDestroy(&dm->coarseMesh);CHKERRQ(ierr); 8683a8fb8f29SToby Isaac dm->coarseMesh = cdm; 8684a8fb8f29SToby Isaac PetscFunctionReturn(0); 8685a8fb8f29SToby Isaac } 8686a8fb8f29SToby Isaac 868788bdff64SToby Isaac /*@ 868888bdff64SToby Isaac DMGetFineDM - Get the fine mesh from which this was obtained by refinement 868988bdff64SToby Isaac 869088bdff64SToby Isaac Input Parameter: 869188bdff64SToby Isaac . dm - The DM object 869288bdff64SToby Isaac 869388bdff64SToby Isaac Output Parameter: 869488bdff64SToby Isaac . fdm - The fine DM 869588bdff64SToby Isaac 869688bdff64SToby Isaac Level: intermediate 869788bdff64SToby Isaac 869888bdff64SToby Isaac .seealso: DMSetFineDM() 869988bdff64SToby Isaac @*/ 870088bdff64SToby Isaac PetscErrorCode DMGetFineDM(DM dm, DM *fdm) 870188bdff64SToby Isaac { 870288bdff64SToby Isaac PetscFunctionBegin; 870388bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 870488bdff64SToby Isaac PetscValidPointer(fdm, 2); 870588bdff64SToby Isaac *fdm = dm->fineMesh; 870688bdff64SToby Isaac PetscFunctionReturn(0); 870788bdff64SToby Isaac } 870888bdff64SToby Isaac 870988bdff64SToby Isaac /*@ 871088bdff64SToby Isaac DMSetFineDM - Set the fine mesh from which this was obtained by refinement 871188bdff64SToby Isaac 871288bdff64SToby Isaac Input Parameters: 871388bdff64SToby Isaac + dm - The DM object 871488bdff64SToby Isaac - fdm - The fine DM 871588bdff64SToby Isaac 871688bdff64SToby Isaac Level: intermediate 871788bdff64SToby Isaac 871888bdff64SToby Isaac .seealso: DMGetFineDM() 871988bdff64SToby Isaac @*/ 872088bdff64SToby Isaac PetscErrorCode DMSetFineDM(DM dm, DM fdm) 872188bdff64SToby Isaac { 872288bdff64SToby Isaac PetscErrorCode ierr; 872388bdff64SToby Isaac 872488bdff64SToby Isaac PetscFunctionBegin; 872588bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 872688bdff64SToby Isaac if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2); 872788bdff64SToby Isaac ierr = PetscObjectReference((PetscObject)fdm);CHKERRQ(ierr); 872888bdff64SToby Isaac ierr = DMDestroy(&dm->fineMesh);CHKERRQ(ierr); 872988bdff64SToby Isaac dm->fineMesh = fdm; 873088bdff64SToby Isaac PetscFunctionReturn(0); 873188bdff64SToby Isaac } 873288bdff64SToby Isaac 8733a6ba4734SToby Isaac /*=== DMBoundary code ===*/ 8734a6ba4734SToby Isaac 8735a6ba4734SToby Isaac /*@C 8736a6ba4734SToby Isaac DMAddBoundary - Add a boundary condition to the model 8737a6ba4734SToby Isaac 8738783e2ec8SMatthew G. Knepley Collective on dm 8739783e2ec8SMatthew G. Knepley 8740a6ba4734SToby Isaac Input Parameters: 87414c258f51SMatthew G. Knepley + dm - The DM, with a PetscDS that matches the problem being constrained 8742f971fd6bSMatthew G. Knepley . type - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann) 8743a6ba4734SToby Isaac . name - The BC name 874445480ffeSMatthew G. Knepley . label - The label defining constrained points 874545480ffeSMatthew G. Knepley . Nv - The number of DMLabel values for constrained points 874645480ffeSMatthew G. Knepley . values - An array of values for constrained points 8747a6ba4734SToby Isaac . field - The field to constrain 874845480ffeSMatthew G. Knepley . Nc - The number of constrained field components (0 will constrain all fields) 8749a6ba4734SToby Isaac . comps - An array of constrained component numbers 8750a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 875156cf3b9cSMatthew G. Knepley . bcFunc_t - A pointwise function giving the time deriative of the boundary values, or NULL 8752a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 8753a6ba4734SToby Isaac 875445480ffeSMatthew G. Knepley Output Parameter: 875545480ffeSMatthew G. Knepley . bd - (Optional) Boundary number 875645480ffeSMatthew G. Knepley 8757a6ba4734SToby Isaac Options Database Keys: 8758a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 8759a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 8760a6ba4734SToby Isaac 876156cf3b9cSMatthew G. Knepley Note: 876256cf3b9cSMatthew 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: 876356cf3b9cSMatthew G. Knepley 876456cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[]) 876556cf3b9cSMatthew G. Knepley 876656cf3b9cSMatthew G. Knepley If the type is DM_BC_ESSENTIAL_FIELD or other _FIELD value, then the calling sequence is: 876756cf3b9cSMatthew G. Knepley 876856cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux, 876956cf3b9cSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 877056cf3b9cSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 877156cf3b9cSMatthew G. Knepley $ PetscReal time, const PetscReal x[], PetscScalar bcval[]) 877256cf3b9cSMatthew G. Knepley 877356cf3b9cSMatthew G. Knepley + dim - the spatial dimension 877456cf3b9cSMatthew G. Knepley . Nf - the number of fields 877556cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field 877656cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field 877756cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point 877856cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point 877956cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point 878056cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field 878156cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field 878256cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point 878356cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point 878456cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point 878556cf3b9cSMatthew G. Knepley . t - current time 878656cf3b9cSMatthew G. Knepley . x - coordinates of the current point 878756cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters 878856cf3b9cSMatthew G. Knepley . constants - constant parameters 878956cf3b9cSMatthew G. Knepley - bcval - output values at the current point 879056cf3b9cSMatthew G. Knepley 8791a6ba4734SToby Isaac Level: developer 8792a6ba4734SToby Isaac 879345480ffeSMatthew G. Knepley .seealso: DSGetBoundary(), PetscDSAddBoundary() 8794a6ba4734SToby Isaac @*/ 879545480ffeSMatthew 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) 8796a6ba4734SToby Isaac { 8797e5e52638SMatthew G. Knepley PetscDS ds; 8798a6ba4734SToby Isaac PetscErrorCode ierr; 8799a6ba4734SToby Isaac 8800a6ba4734SToby Isaac PetscFunctionBegin; 8801a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8802783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveEnum(dm, type, 2); 880345480ffeSMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 880445480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nv, 5); 880545480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, field, 7); 880645480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nc, 8); 8807e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 880845480ffeSMatthew G. Knepley ierr = DMCompleteBoundaryLabel_Internal(dm, ds, field, PETSC_MAX_INT, label);CHKERRQ(ierr); 880945480ffeSMatthew G. Knepley ierr = PetscDSAddBoundary(ds, type, name, label, Nv, values, field, Nc, comps, bcFunc, bcFunc_t, ctx, bd);CHKERRQ(ierr); 8810a6ba4734SToby Isaac PetscFunctionReturn(0); 8811a6ba4734SToby Isaac } 8812a6ba4734SToby Isaac 881345480ffeSMatthew G. Knepley /* TODO Remove this since now the structures are the same */ 8814e6f8dbb6SToby Isaac static PetscErrorCode DMPopulateBoundary(DM dm) 8815e6f8dbb6SToby Isaac { 8816e5e52638SMatthew G. Knepley PetscDS ds; 8817dff059c6SToby Isaac DMBoundary *lastnext; 8818e6f8dbb6SToby Isaac DSBoundary dsbound; 8819e6f8dbb6SToby Isaac PetscErrorCode ierr; 8820e6f8dbb6SToby Isaac 8821e6f8dbb6SToby Isaac PetscFunctionBegin; 8822e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 8823e5e52638SMatthew G. Knepley dsbound = ds->boundary; 882447a1f5adSToby Isaac if (dm->boundary) { 882547a1f5adSToby Isaac DMBoundary next = dm->boundary; 882647a1f5adSToby Isaac 882747a1f5adSToby Isaac /* quick check to see if the PetscDS has changed */ 882847a1f5adSToby Isaac if (next->dsboundary == dsbound) PetscFunctionReturn(0); 882947a1f5adSToby Isaac /* the PetscDS has changed: tear down and rebuild */ 883047a1f5adSToby Isaac while (next) { 883147a1f5adSToby Isaac DMBoundary b = next; 883247a1f5adSToby Isaac 883347a1f5adSToby Isaac next = b->next; 883447a1f5adSToby Isaac ierr = PetscFree(b);CHKERRQ(ierr); 8835a6ba4734SToby Isaac } 883647a1f5adSToby Isaac dm->boundary = NULL; 8837a6ba4734SToby Isaac } 883847a1f5adSToby Isaac 8839dff059c6SToby Isaac lastnext = &(dm->boundary); 8840e6f8dbb6SToby Isaac while (dsbound) { 8841e6f8dbb6SToby Isaac DMBoundary dmbound; 8842e6f8dbb6SToby Isaac 8843e6f8dbb6SToby Isaac ierr = PetscNew(&dmbound);CHKERRQ(ierr); 8844e6f8dbb6SToby Isaac dmbound->dsboundary = dsbound; 884545480ffeSMatthew G. Knepley dmbound->label = dsbound->label; 884647a1f5adSToby Isaac /* push on the back instead of the front so that it is in the same order as in the PetscDS */ 8847dff059c6SToby Isaac *lastnext = dmbound; 8848dff059c6SToby Isaac lastnext = &(dmbound->next); 8849dff059c6SToby Isaac dsbound = dsbound->next; 8850a6ba4734SToby Isaac } 8851a6ba4734SToby Isaac PetscFunctionReturn(0); 8852a6ba4734SToby Isaac } 8853a6ba4734SToby Isaac 8854a6ba4734SToby Isaac PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd) 8855a6ba4734SToby Isaac { 8856b95f2879SToby Isaac DMBoundary b; 8857a6ba4734SToby Isaac PetscErrorCode ierr; 8858a6ba4734SToby Isaac 8859a6ba4734SToby Isaac PetscFunctionBegin; 8860a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8861534a8f05SLisandro Dalcin PetscValidBoolPointer(isBd, 3); 8862a6ba4734SToby Isaac *isBd = PETSC_FALSE; 8863e6f8dbb6SToby Isaac ierr = DMPopulateBoundary(dm);CHKERRQ(ierr); 8864b95f2879SToby Isaac b = dm->boundary; 8865a6ba4734SToby Isaac while (b && !(*isBd)) { 8866e6f8dbb6SToby Isaac DMLabel label = b->label; 8867e6f8dbb6SToby Isaac DSBoundary dsb = b->dsboundary; 8868a6ba4734SToby Isaac PetscInt i; 8869a6ba4734SToby Isaac 887045480ffeSMatthew G. Knepley if (label) { 887145480ffeSMatthew G. Knepley for (i = 0; i < dsb->Nv && !(*isBd); ++i) {ierr = DMLabelStratumHasPoint(label, dsb->values[i], point, isBd);CHKERRQ(ierr);} 8872a6ba4734SToby Isaac } 8873a6ba4734SToby Isaac b = b->next; 8874a6ba4734SToby Isaac } 8875a6ba4734SToby Isaac PetscFunctionReturn(0); 8876a6ba4734SToby Isaac } 88774d6f44ffSToby Isaac 88784d6f44ffSToby Isaac /*@C 8879a6e0b375SMatthew G. Knepley DMProjectFunction - This projects the given function into the function space provided, putting the coefficients in a global vector. 8880a6e0b375SMatthew G. Knepley 8881a6e0b375SMatthew G. Knepley Collective on DM 88824d6f44ffSToby Isaac 88834d6f44ffSToby Isaac Input Parameters: 88844d6f44ffSToby Isaac + dm - The DM 88850709b2feSToby Isaac . time - The time 88864d6f44ffSToby Isaac . funcs - The coordinate functions to evaluate, one per field 88874d6f44ffSToby Isaac . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 88884d6f44ffSToby Isaac - mode - The insertion mode for values 88894d6f44ffSToby Isaac 88904d6f44ffSToby Isaac Output Parameter: 88914d6f44ffSToby Isaac . X - vector 88924d6f44ffSToby Isaac 88934d6f44ffSToby Isaac Calling sequence of func: 889477b739a6SMatthew Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx); 88954d6f44ffSToby Isaac 88964d6f44ffSToby Isaac + dim - The spatial dimension 88978ec8862eSJed Brown . time - The time at which to sample 88984d6f44ffSToby Isaac . x - The coordinates 889977b739a6SMatthew Knepley . Nc - The number of components 89004d6f44ffSToby Isaac . u - The output field values 89014d6f44ffSToby Isaac - ctx - optional user-defined function context 89024d6f44ffSToby Isaac 89034d6f44ffSToby Isaac Level: developer 89044d6f44ffSToby Isaac 8905a6e0b375SMatthew G. Knepley .seealso: DMProjectFunctionLocal(), DMProjectFunctionLabel(), DMComputeL2Diff() 89064d6f44ffSToby Isaac @*/ 89070709b2feSToby Isaac PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X) 89084d6f44ffSToby Isaac { 89094d6f44ffSToby Isaac Vec localX; 89104d6f44ffSToby Isaac PetscErrorCode ierr; 89114d6f44ffSToby Isaac 89124d6f44ffSToby Isaac PetscFunctionBegin; 89134d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89144d6f44ffSToby Isaac ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr); 89150709b2feSToby Isaac ierr = DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr); 89164d6f44ffSToby Isaac ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr); 89174d6f44ffSToby Isaac ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr); 89184d6f44ffSToby Isaac ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr); 89194d6f44ffSToby Isaac PetscFunctionReturn(0); 89204d6f44ffSToby Isaac } 89214d6f44ffSToby Isaac 8922a6e0b375SMatthew G. Knepley /*@C 8923a6e0b375SMatthew G. Knepley DMProjectFunctionLocal - This projects the given function into the function space provided, putting the coefficients in a local vector. 8924a6e0b375SMatthew G. Knepley 8925a6e0b375SMatthew G. Knepley Not collective 8926a6e0b375SMatthew G. Knepley 8927a6e0b375SMatthew G. Knepley Input Parameters: 8928a6e0b375SMatthew G. Knepley + dm - The DM 8929a6e0b375SMatthew G. Knepley . time - The time 8930a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8931a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8932a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8933a6e0b375SMatthew G. Knepley 8934a6e0b375SMatthew G. Knepley Output Parameter: 8935a6e0b375SMatthew G. Knepley . localX - vector 8936a6e0b375SMatthew G. Knepley 8937a6e0b375SMatthew G. Knepley Calling sequence of func: 893877b739a6SMatthew Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx); 8939a6e0b375SMatthew G. Knepley 8940a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8941a6e0b375SMatthew G. Knepley . x - The coordinates 894277b739a6SMatthew Knepley . Nc - The number of components 8943a6e0b375SMatthew G. Knepley . u - The output field values 8944a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8945a6e0b375SMatthew G. Knepley 8946a6e0b375SMatthew G. Knepley Level: developer 8947a6e0b375SMatthew G. Knepley 8948a6e0b375SMatthew G. Knepley .seealso: DMProjectFunction(), DMProjectFunctionLabel(), DMComputeL2Diff() 8949a6e0b375SMatthew G. Knepley @*/ 89500709b2feSToby Isaac PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 89514d6f44ffSToby Isaac { 89524d6f44ffSToby Isaac PetscErrorCode ierr; 89534d6f44ffSToby Isaac 89544d6f44ffSToby Isaac PetscFunctionBegin; 89554d6f44ffSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8956064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX,VEC_CLASSID,6); 89570918c465SMatthew G. Knepley if (!dm->ops->projectfunctionlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLocal",((PetscObject)dm)->type_name); 89580709b2feSToby Isaac ierr = (dm->ops->projectfunctionlocal) (dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr); 89594d6f44ffSToby Isaac PetscFunctionReturn(0); 89604d6f44ffSToby Isaac } 89614d6f44ffSToby Isaac 8962a6e0b375SMatthew G. Knepley /*@C 8963a6e0b375SMatthew 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. 8964a6e0b375SMatthew G. Knepley 8965a6e0b375SMatthew G. Knepley Collective on DM 8966a6e0b375SMatthew G. Knepley 8967a6e0b375SMatthew G. Knepley Input Parameters: 8968a6e0b375SMatthew G. Knepley + dm - The DM 8969a6e0b375SMatthew G. Knepley . time - The time 8970a6e0b375SMatthew G. Knepley . label - The DMLabel selecting the portion of the mesh for projection 8971a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8972a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8973a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8974a6e0b375SMatthew G. Knepley 8975a6e0b375SMatthew G. Knepley Output Parameter: 8976a6e0b375SMatthew G. Knepley . X - vector 8977a6e0b375SMatthew G. Knepley 8978a6e0b375SMatthew G. Knepley Calling sequence of func: 897977b739a6SMatthew Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx); 8980a6e0b375SMatthew G. Knepley 8981a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8982a6e0b375SMatthew G. Knepley . x - The coordinates 898377b739a6SMatthew Knepley . Nc - The number of components 8984a6e0b375SMatthew G. Knepley . u - The output field values 8985a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8986a6e0b375SMatthew G. Knepley 8987a6e0b375SMatthew G. Knepley Level: developer 8988a6e0b375SMatthew G. Knepley 8989a6e0b375SMatthew G. Knepley .seealso: DMProjectFunction(), DMProjectFunctionLocal(), DMProjectFunctionLabelLocal(), DMComputeL2Diff() 8990a6e0b375SMatthew G. Knepley @*/ 89912c53366bSMatthew 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) 89922c53366bSMatthew G. Knepley { 89932c53366bSMatthew G. Knepley Vec localX; 89942c53366bSMatthew G. Knepley PetscErrorCode ierr; 89952c53366bSMatthew G. Knepley 89962c53366bSMatthew G. Knepley PetscFunctionBegin; 89972c53366bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89982c53366bSMatthew G. Knepley ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr); 89992c53366bSMatthew G. Knepley ierr = DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr); 90002c53366bSMatthew G. Knepley ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr); 90012c53366bSMatthew G. Knepley ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr); 90022c53366bSMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr); 90032c53366bSMatthew G. Knepley PetscFunctionReturn(0); 90042c53366bSMatthew G. Knepley } 90052c53366bSMatthew G. Knepley 9006a6e0b375SMatthew G. Knepley /*@C 9007a6e0b375SMatthew 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. 9008a6e0b375SMatthew G. Knepley 9009a6e0b375SMatthew G. Knepley Not collective 9010a6e0b375SMatthew G. Knepley 9011a6e0b375SMatthew G. Knepley Input Parameters: 9012a6e0b375SMatthew G. Knepley + dm - The DM 9013a6e0b375SMatthew G. Knepley . time - The time 9014a6e0b375SMatthew G. Knepley . label - The DMLabel selecting the portion of the mesh for projection 9015a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 9016a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 9017a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 9018a6e0b375SMatthew G. Knepley 9019a6e0b375SMatthew G. Knepley Output Parameter: 9020a6e0b375SMatthew G. Knepley . localX - vector 9021a6e0b375SMatthew G. Knepley 9022a6e0b375SMatthew G. Knepley Calling sequence of func: 902377b739a6SMatthew Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx); 9024a6e0b375SMatthew G. Knepley 9025a6e0b375SMatthew G. Knepley + dim - The spatial dimension 9026a6e0b375SMatthew G. Knepley . x - The coordinates 902777b739a6SMatthew Knepley . Nc - The number of components 9028a6e0b375SMatthew G. Knepley . u - The output field values 9029a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 9030a6e0b375SMatthew G. Knepley 9031a6e0b375SMatthew G. Knepley Level: developer 9032a6e0b375SMatthew G. Knepley 9033a6e0b375SMatthew G. Knepley .seealso: DMProjectFunction(), DMProjectFunctionLocal(), DMProjectFunctionLabel(), DMComputeL2Diff() 9034a6e0b375SMatthew G. Knepley @*/ 90351c531cf8SMatthew 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) 90364d6f44ffSToby Isaac { 90374d6f44ffSToby Isaac PetscErrorCode ierr; 90384d6f44ffSToby Isaac 90394d6f44ffSToby Isaac PetscFunctionBegin; 90404d6f44ffSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 9041064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX,VEC_CLASSID,11); 90420918c465SMatthew G. Knepley if (!dm->ops->projectfunctionlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLabelLocal",((PetscObject)dm)->type_name); 90431c531cf8SMatthew G. Knepley ierr = (dm->ops->projectfunctionlabellocal) (dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr); 90444d6f44ffSToby Isaac PetscFunctionReturn(0); 90454d6f44ffSToby Isaac } 90462716604bSToby Isaac 9047a6e0b375SMatthew G. Knepley /*@C 9048a6e0b375SMatthew G. Knepley DMProjectFieldLocal - This projects the given function of the input fields into the function space provided, putting the coefficients in a local vector. 9049a6e0b375SMatthew G. Knepley 9050a6e0b375SMatthew G. Knepley Not collective 9051a6e0b375SMatthew G. Knepley 9052a6e0b375SMatthew G. Knepley Input Parameters: 9053a6e0b375SMatthew G. Knepley + dm - The DM 9054a6e0b375SMatthew G. Knepley . time - The time 9055a6e0b375SMatthew G. Knepley . localU - The input field vector 9056a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 9057a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 9058a6e0b375SMatthew G. Knepley 9059a6e0b375SMatthew G. Knepley Output Parameter: 9060a6e0b375SMatthew G. Knepley . localX - The output vector 9061a6e0b375SMatthew G. Knepley 9062a6e0b375SMatthew G. Knepley Calling sequence of func: 9063a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 9064a6e0b375SMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 9065a6e0b375SMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 9066a6e0b375SMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 9067a6e0b375SMatthew G. Knepley 9068a6e0b375SMatthew G. Knepley + dim - The spatial dimension 9069a6e0b375SMatthew G. Knepley . Nf - The number of input fields 9070a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 9071a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 9072a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 9073a6e0b375SMatthew G. Knepley . u - The field values at this point in space 9074a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 9075a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 9076a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 9077a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 9078a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 9079a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 9080a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 9081a6e0b375SMatthew G. Knepley . t - The current time 9082a6e0b375SMatthew G. Knepley . x - The coordinates of this point 9083a6e0b375SMatthew G. Knepley . numConstants - The number of constants 9084a6e0b375SMatthew G. Knepley . constants - The value of each constant 9085a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 9086a6e0b375SMatthew G. Knepley 9087a6e0b375SMatthew 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. 9088a6e0b375SMatthew 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 9089a6e0b375SMatthew 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 9090a6e0b375SMatthew 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. 9091a6e0b375SMatthew G. Knepley 9092a6e0b375SMatthew G. Knepley Level: intermediate 9093a6e0b375SMatthew G. Knepley 9094a6e0b375SMatthew G. Knepley .seealso: DMProjectField(), DMProjectFieldLabelLocal(), DMProjectFunction(), DMComputeL2Diff() 9095a6e0b375SMatthew G. Knepley @*/ 90968c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal(DM dm, PetscReal time, Vec localU, 90978c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 90988c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 90998c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 9100191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 91018c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 91028c6c5593SMatthew G. Knepley { 91038c6c5593SMatthew G. Knepley PetscErrorCode ierr; 91048c6c5593SMatthew G. Knepley 91058c6c5593SMatthew G. Knepley PetscFunctionBegin; 91068c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 91078c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,3); 91088c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,6); 91090918c465SMatthew G. Knepley if (!dm->ops->projectfieldlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name); 91108c6c5593SMatthew G. Knepley ierr = (dm->ops->projectfieldlocal) (dm, time, localU, funcs, mode, localX);CHKERRQ(ierr); 91118c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 91128c6c5593SMatthew G. Knepley } 91138c6c5593SMatthew G. Knepley 9114a6e0b375SMatthew G. Knepley /*@C 9115a6e0b375SMatthew 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. 9116a6e0b375SMatthew G. Knepley 9117a6e0b375SMatthew G. Knepley Not collective 9118a6e0b375SMatthew G. Knepley 9119a6e0b375SMatthew G. Knepley Input Parameters: 9120a6e0b375SMatthew G. Knepley + dm - The DM 9121a6e0b375SMatthew G. Knepley . time - The time 9122a6e0b375SMatthew G. Knepley . label - The DMLabel marking the portion of the domain to output 9123a6e0b375SMatthew G. Knepley . numIds - The number of label ids to use 9124a6e0b375SMatthew G. Knepley . ids - The label ids to use for marking 9125a6e0b375SMatthew G. Knepley . Nc - The number of components to set in the output, or PETSC_DETERMINE for all components 9126a6e0b375SMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 9127a6e0b375SMatthew G. Knepley . localU - The input field vector 9128a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 9129a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 9130a6e0b375SMatthew G. Knepley 9131a6e0b375SMatthew G. Knepley Output Parameter: 9132a6e0b375SMatthew G. Knepley . localX - The output vector 9133a6e0b375SMatthew G. Knepley 9134a6e0b375SMatthew G. Knepley Calling sequence of func: 9135a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 9136a6e0b375SMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 9137a6e0b375SMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 9138a6e0b375SMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 9139a6e0b375SMatthew G. Knepley 9140a6e0b375SMatthew G. Knepley + dim - The spatial dimension 9141a6e0b375SMatthew G. Knepley . Nf - The number of input fields 9142a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 9143a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 9144a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 9145a6e0b375SMatthew G. Knepley . u - The field values at this point in space 9146a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 9147a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 9148a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 9149a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 9150a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 9151a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 9152a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 9153a6e0b375SMatthew G. Knepley . t - The current time 9154a6e0b375SMatthew G. Knepley . x - The coordinates of this point 9155a6e0b375SMatthew G. Knepley . numConstants - The number of constants 9156a6e0b375SMatthew G. Knepley . constants - The value of each constant 9157a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 9158a6e0b375SMatthew G. Knepley 9159a6e0b375SMatthew 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. 9160a6e0b375SMatthew 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 9161a6e0b375SMatthew 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 9162a6e0b375SMatthew 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. 9163a6e0b375SMatthew G. Knepley 9164a6e0b375SMatthew G. Knepley Level: intermediate 9165a6e0b375SMatthew G. Knepley 9166a6e0b375SMatthew G. Knepley .seealso: DMProjectField(), DMProjectFieldLabelLocal(), DMProjectFunction(), DMComputeL2Diff() 9167a6e0b375SMatthew G. Knepley @*/ 91681c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, 91698c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 91708c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 91718c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 9172191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 91738c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 91748c6c5593SMatthew G. Knepley { 91758c6c5593SMatthew G. Knepley PetscErrorCode ierr; 91768c6c5593SMatthew G. Knepley 91778c6c5593SMatthew G. Knepley PetscFunctionBegin; 91788c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 9179064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localU,VEC_CLASSID,8); 9180064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX,VEC_CLASSID,11); 9181ece3a9fcSMatthew G. Knepley if (!dm->ops->projectfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLabelLocal",((PetscObject)dm)->type_name); 91821c531cf8SMatthew G. Knepley ierr = (dm->ops->projectfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX);CHKERRQ(ierr); 91838c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 91848c6c5593SMatthew G. Knepley } 91858c6c5593SMatthew G. Knepley 91862716604bSToby Isaac /*@C 9187ece3a9fcSMatthew 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. 9188ece3a9fcSMatthew G. Knepley 9189ece3a9fcSMatthew G. Knepley Not collective 9190ece3a9fcSMatthew G. Knepley 9191ece3a9fcSMatthew G. Knepley Input Parameters: 9192ece3a9fcSMatthew G. Knepley + dm - The DM 9193ece3a9fcSMatthew G. Knepley . time - The time 9194ece3a9fcSMatthew G. Knepley . label - The DMLabel marking the portion of the domain boundary to output 9195ece3a9fcSMatthew G. Knepley . numIds - The number of label ids to use 9196ece3a9fcSMatthew G. Knepley . ids - The label ids to use for marking 9197ece3a9fcSMatthew G. Knepley . Nc - The number of components to set in the output, or PETSC_DETERMINE for all components 9198ece3a9fcSMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 9199ece3a9fcSMatthew G. Knepley . localU - The input field vector 9200ece3a9fcSMatthew G. Knepley . funcs - The functions to evaluate, one per field 9201ece3a9fcSMatthew G. Knepley - mode - The insertion mode for values 9202ece3a9fcSMatthew G. Knepley 9203ece3a9fcSMatthew G. Knepley Output Parameter: 9204ece3a9fcSMatthew G. Knepley . localX - The output vector 9205ece3a9fcSMatthew G. Knepley 9206ece3a9fcSMatthew G. Knepley Calling sequence of func: 9207ece3a9fcSMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 9208ece3a9fcSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 9209ece3a9fcSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 9210ece3a9fcSMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 9211ece3a9fcSMatthew G. Knepley 9212ece3a9fcSMatthew G. Knepley + dim - The spatial dimension 9213ece3a9fcSMatthew G. Knepley . Nf - The number of input fields 9214ece3a9fcSMatthew G. Knepley . NfAux - The number of input auxiliary fields 9215ece3a9fcSMatthew G. Knepley . uOff - The offset of each field in u[] 9216ece3a9fcSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 9217ece3a9fcSMatthew G. Knepley . u - The field values at this point in space 9218ece3a9fcSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 9219ece3a9fcSMatthew G. Knepley . u_x - The field derivatives at this point in space 9220ece3a9fcSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 9221ece3a9fcSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 9222ece3a9fcSMatthew G. Knepley . a - The auxiliary field values at this point in space 9223ece3a9fcSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 9224ece3a9fcSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 9225ece3a9fcSMatthew G. Knepley . t - The current time 9226ece3a9fcSMatthew G. Knepley . x - The coordinates of this point 9227ece3a9fcSMatthew G. Knepley . n - The face normal 9228ece3a9fcSMatthew G. Knepley . numConstants - The number of constants 9229ece3a9fcSMatthew G. Knepley . constants - The value of each constant 9230ece3a9fcSMatthew G. Knepley - f - The value of the function at this point in space 9231ece3a9fcSMatthew G. Knepley 9232ece3a9fcSMatthew G. Knepley Note: 9233ece3a9fcSMatthew 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. 9234ece3a9fcSMatthew 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 9235ece3a9fcSMatthew 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 9236ece3a9fcSMatthew 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. 9237ece3a9fcSMatthew G. Knepley 9238ece3a9fcSMatthew G. Knepley Level: intermediate 9239ece3a9fcSMatthew G. Knepley 9240ece3a9fcSMatthew G. Knepley .seealso: DMProjectField(), DMProjectFieldLabelLocal(), DMProjectFunction(), DMComputeL2Diff() 9241ece3a9fcSMatthew G. Knepley @*/ 9242ece3a9fcSMatthew G. Knepley PetscErrorCode DMProjectBdFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, 9243ece3a9fcSMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 9244ece3a9fcSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 9245ece3a9fcSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 9246ece3a9fcSMatthew G. Knepley PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 9247ece3a9fcSMatthew G. Knepley InsertMode mode, Vec localX) 9248ece3a9fcSMatthew G. Knepley { 9249ece3a9fcSMatthew G. Knepley PetscErrorCode ierr; 9250ece3a9fcSMatthew G. Knepley 9251ece3a9fcSMatthew G. Knepley PetscFunctionBegin; 9252ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 9253064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localU,VEC_CLASSID,8); 9254064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX,VEC_CLASSID,11); 9255ece3a9fcSMatthew G. Knepley if (!dm->ops->projectbdfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectBdFieldLabelLocal",((PetscObject)dm)->type_name); 9256ece3a9fcSMatthew G. Knepley ierr = (dm->ops->projectbdfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX);CHKERRQ(ierr); 9257ece3a9fcSMatthew G. Knepley PetscFunctionReturn(0); 9258ece3a9fcSMatthew G. Knepley } 9259ece3a9fcSMatthew G. Knepley 9260ece3a9fcSMatthew G. Knepley /*@C 92612716604bSToby Isaac DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h. 92622716604bSToby Isaac 92632716604bSToby Isaac Input Parameters: 92642716604bSToby Isaac + dm - The DM 92650709b2feSToby Isaac . time - The time 92662716604bSToby Isaac . funcs - The functions to evaluate for each field component 92672716604bSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 9268574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 92692716604bSToby Isaac 92702716604bSToby Isaac Output Parameter: 92712716604bSToby Isaac . diff - The diff ||u - u_h||_2 92722716604bSToby Isaac 92732716604bSToby Isaac Level: developer 92742716604bSToby Isaac 92751189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff() 92762716604bSToby Isaac @*/ 92770709b2feSToby Isaac PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff) 92782716604bSToby Isaac { 92792716604bSToby Isaac PetscErrorCode ierr; 92802716604bSToby Isaac 92812716604bSToby Isaac PetscFunctionBegin; 92822716604bSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 9283b698f381SToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 92840918c465SMatthew G. Knepley if (!dm->ops->computel2diff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2Diff",((PetscObject)dm)->type_name); 92850709b2feSToby Isaac ierr = (dm->ops->computel2diff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr); 92862716604bSToby Isaac PetscFunctionReturn(0); 92872716604bSToby Isaac } 9288b698f381SToby Isaac 9289b698f381SToby Isaac /*@C 9290b698f381SToby Isaac DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h. 9291b698f381SToby Isaac 9292d083f849SBarry Smith Collective on dm 9293d083f849SBarry Smith 9294b698f381SToby Isaac Input Parameters: 9295b698f381SToby Isaac + dm - The DM 9296b698f381SToby Isaac , time - The time 9297b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component 9298b698f381SToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 9299574a98acSMatthew G. Knepley . X - The coefficient vector u_h, a global vector 9300b698f381SToby Isaac - n - The vector to project along 9301b698f381SToby Isaac 9302b698f381SToby Isaac Output Parameter: 9303b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2 9304b698f381SToby Isaac 9305b698f381SToby Isaac Level: developer 9306b698f381SToby Isaac 9307b698f381SToby Isaac .seealso: DMProjectFunction(), DMComputeL2Diff() 9308b698f381SToby Isaac @*/ 9309b698f381SToby 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) 9310b698f381SToby Isaac { 9311b698f381SToby Isaac PetscErrorCode ierr; 9312b698f381SToby Isaac 9313b698f381SToby Isaac PetscFunctionBegin; 9314b698f381SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 9315b698f381SToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 9316b698f381SToby Isaac if (!dm->ops->computel2gradientdiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2GradientDiff",((PetscObject)dm)->type_name); 9317b698f381SToby Isaac ierr = (dm->ops->computel2gradientdiff)(dm,time,funcs,ctxs,X,n,diff);CHKERRQ(ierr); 9318b698f381SToby Isaac PetscFunctionReturn(0); 9319b698f381SToby Isaac } 9320b698f381SToby Isaac 93212a16baeaSToby Isaac /*@C 93222a16baeaSToby Isaac DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components. 93232a16baeaSToby Isaac 9324d083f849SBarry Smith Collective on dm 9325d083f849SBarry Smith 93262a16baeaSToby Isaac Input Parameters: 93272a16baeaSToby Isaac + dm - The DM 93282a16baeaSToby Isaac . time - The time 93292a16baeaSToby Isaac . funcs - The functions to evaluate for each field component 93302a16baeaSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 9331574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 93322a16baeaSToby Isaac 93332a16baeaSToby Isaac Output Parameter: 93342a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2 93352a16baeaSToby Isaac 93362a16baeaSToby Isaac Level: developer 93372a16baeaSToby Isaac 93381189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff() 93392a16baeaSToby Isaac @*/ 93401189c1efSToby Isaac PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[]) 93412a16baeaSToby Isaac { 93422a16baeaSToby Isaac PetscErrorCode ierr; 93432a16baeaSToby Isaac 93442a16baeaSToby Isaac PetscFunctionBegin; 93452a16baeaSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 93462a16baeaSToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 93470918c465SMatthew G. Knepley if (!dm->ops->computel2fielddiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2FieldDiff",((PetscObject)dm)->type_name); 93482a16baeaSToby Isaac ierr = (dm->ops->computel2fielddiff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr); 93492a16baeaSToby Isaac PetscFunctionReturn(0); 93502a16baeaSToby Isaac } 93512a16baeaSToby Isaac 9352df0b854cSToby Isaac /*@C 9353502a2867SDave May DMGetNeighbors - Gets an array containing the MPI rank of all the processes neighbors 9354502a2867SDave May 9355502a2867SDave May Not Collective 9356502a2867SDave May 9357502a2867SDave May Input Parameter: 9358502a2867SDave May . dm - The DM 9359502a2867SDave May 93600a19bb7dSprj- Output Parameters: 93610a19bb7dSprj- + nranks - the number of neighbours 93620a19bb7dSprj- - ranks - the neighbors ranks 9363502a2867SDave May 9364502a2867SDave May Notes: 9365502a2867SDave May Do not free the array, it is freed when the DM is destroyed. 9366502a2867SDave May 9367502a2867SDave May Level: beginner 9368502a2867SDave May 9369dec1416fSJunchao Zhang .seealso: DMDAGetNeighbors(), PetscSFGetRootRanks() 9370502a2867SDave May @*/ 9371502a2867SDave May PetscErrorCode DMGetNeighbors(DM dm,PetscInt *nranks,const PetscMPIInt *ranks[]) 9372502a2867SDave May { 9373502a2867SDave May PetscErrorCode ierr; 9374502a2867SDave May 9375502a2867SDave May PetscFunctionBegin; 9376502a2867SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 93770918c465SMatthew G. Knepley if (!dm->ops->getneighbors) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMGetNeighbors",((PetscObject)dm)->type_name); 9378502a2867SDave May ierr = (dm->ops->getneighbors)(dm,nranks,ranks);CHKERRQ(ierr); 9379502a2867SDave May PetscFunctionReturn(0); 9380502a2867SDave May } 9381502a2867SDave May 9382531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */ 9383531c7667SBarry Smith 9384531c7667SBarry Smith /* 9385531c7667SBarry Smith Converts the input vector to a ghosted vector and then calls the standard coloring code. 9386531c7667SBarry Smith This has be a different function because it requires DM which is not defined in the Mat library 9387531c7667SBarry Smith */ 9388531c7667SBarry Smith PetscErrorCode MatFDColoringApply_AIJDM(Mat J,MatFDColoring coloring,Vec x1,void *sctx) 9389531c7667SBarry Smith { 9390531c7667SBarry Smith PetscErrorCode ierr; 9391531c7667SBarry Smith 9392531c7667SBarry Smith PetscFunctionBegin; 9393531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 9394531c7667SBarry Smith Vec x1local; 9395531c7667SBarry Smith DM dm; 9396531c7667SBarry Smith ierr = MatGetDM(J,&dm);CHKERRQ(ierr); 9397531c7667SBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_INCOMP,"IS_COLORING_LOCAL requires a DM"); 9398531c7667SBarry Smith ierr = DMGetLocalVector(dm,&x1local);CHKERRQ(ierr); 9399531c7667SBarry Smith ierr = DMGlobalToLocalBegin(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr); 9400531c7667SBarry Smith ierr = DMGlobalToLocalEnd(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr); 9401531c7667SBarry Smith x1 = x1local; 9402531c7667SBarry Smith } 9403531c7667SBarry Smith ierr = MatFDColoringApply_AIJ(J,coloring,x1,sctx);CHKERRQ(ierr); 9404531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 9405531c7667SBarry Smith DM dm; 9406531c7667SBarry Smith ierr = MatGetDM(J,&dm);CHKERRQ(ierr); 9407531c7667SBarry Smith ierr = DMRestoreLocalVector(dm,&x1);CHKERRQ(ierr); 9408531c7667SBarry Smith } 9409531c7667SBarry Smith PetscFunctionReturn(0); 9410531c7667SBarry Smith } 9411531c7667SBarry Smith 9412531c7667SBarry Smith /*@ 9413531c7667SBarry Smith MatFDColoringUseDM - allows a MatFDColoring object to use the DM associated with the matrix to use a IS_COLORING_LOCAL coloring 9414531c7667SBarry Smith 9415531c7667SBarry Smith Input Parameter: 9416531c7667SBarry Smith . coloring - the MatFDColoring object 9417531c7667SBarry Smith 941895452b02SPatrick Sanan Developer Notes: 941995452b02SPatrick Sanan this routine exists because the PETSc Mat library does not know about the DM objects 9420531c7667SBarry Smith 94211b266c99SBarry Smith Level: advanced 94221b266c99SBarry Smith 9423531c7667SBarry Smith .seealso: MatFDColoring, MatFDColoringCreate(), ISColoringType 9424531c7667SBarry Smith @*/ 9425531c7667SBarry Smith PetscErrorCode MatFDColoringUseDM(Mat coloring,MatFDColoring fdcoloring) 9426531c7667SBarry Smith { 9427531c7667SBarry Smith PetscFunctionBegin; 9428531c7667SBarry Smith coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM; 9429531c7667SBarry Smith PetscFunctionReturn(0); 9430531c7667SBarry Smith } 94318320bc6fSPatrick Sanan 94328320bc6fSPatrick Sanan /*@ 94338320bc6fSPatrick Sanan DMGetCompatibility - determine if two DMs are compatible 94348320bc6fSPatrick Sanan 94358320bc6fSPatrick Sanan Collective 94368320bc6fSPatrick Sanan 94378320bc6fSPatrick Sanan Input Parameters: 9438a5bc1bf3SBarry Smith + dm1 - the first DM 94398320bc6fSPatrick Sanan - dm2 - the second DM 94408320bc6fSPatrick Sanan 94418320bc6fSPatrick Sanan Output Parameters: 94428320bc6fSPatrick Sanan + compatible - whether or not the two DMs are compatible 94438320bc6fSPatrick Sanan - set - whether or not the compatible value was set 94448320bc6fSPatrick Sanan 94458320bc6fSPatrick Sanan Notes: 94468320bc6fSPatrick Sanan Two DMs are deemed compatible if they represent the same parallel decomposition 94473d862458SPatrick Sanan of the same topology. This implies that the section (field data) on one 94488320bc6fSPatrick Sanan "makes sense" with respect to the topology and parallel decomposition of the other. 94493d862458SPatrick Sanan Loosely speaking, compatible DMs represent the same domain and parallel 94503d862458SPatrick Sanan decomposition, but hold different data. 94518320bc6fSPatrick Sanan 94528320bc6fSPatrick Sanan Typically, one would confirm compatibility if intending to simultaneously iterate 94538320bc6fSPatrick Sanan over a pair of vectors obtained from different DMs. 94548320bc6fSPatrick Sanan 94558320bc6fSPatrick Sanan For example, two DMDA objects are compatible if they have the same local 94568320bc6fSPatrick Sanan and global sizes and the same stencil width. They can have different numbers 94578320bc6fSPatrick Sanan of degrees of freedom per node. Thus, one could use the node numbering from 94588320bc6fSPatrick Sanan either DM in bounds for a loop over vectors derived from either DM. 94598320bc6fSPatrick Sanan 94608320bc6fSPatrick Sanan Consider the operation of summing data living on a 2-dof DMDA to data living 94618320bc6fSPatrick Sanan on a 1-dof DMDA, which should be compatible, as in the following snippet. 94628320bc6fSPatrick Sanan .vb 94638320bc6fSPatrick Sanan ... 94648320bc6fSPatrick Sanan ierr = DMGetCompatibility(da1,da2,&compatible,&set);CHKERRQ(ierr); 94658320bc6fSPatrick Sanan if (set && compatible) { 94668320bc6fSPatrick Sanan ierr = DMDAVecGetArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr); 94678320bc6fSPatrick Sanan ierr = DMDAVecGetArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr); 94683d862458SPatrick Sanan ierr = DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL);CHKERRQ(ierr); 94698320bc6fSPatrick Sanan for (j=y; j<y+n; ++j) { 94708320bc6fSPatrick Sanan for (i=x; i<x+m, ++i) { 94718320bc6fSPatrick Sanan arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1]; 94728320bc6fSPatrick Sanan } 94738320bc6fSPatrick Sanan } 94748320bc6fSPatrick Sanan ierr = DMDAVecRestoreArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr); 94758320bc6fSPatrick Sanan ierr = DMDAVecRestoreArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr); 94768320bc6fSPatrick Sanan } else { 94778320bc6fSPatrick Sanan SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible"); 94788320bc6fSPatrick Sanan } 94798320bc6fSPatrick Sanan ... 94808320bc6fSPatrick Sanan .ve 94818320bc6fSPatrick Sanan 94828320bc6fSPatrick Sanan Checking compatibility might be expensive for a given implementation of DM, 94838320bc6fSPatrick Sanan or might be impossible to unambiguously confirm or deny. For this reason, 94848320bc6fSPatrick Sanan this function may decline to determine compatibility, and hence users should 94858320bc6fSPatrick Sanan always check the "set" output parameter. 94868320bc6fSPatrick Sanan 94878320bc6fSPatrick Sanan A DM is always compatible with itself. 94888320bc6fSPatrick Sanan 94898320bc6fSPatrick Sanan In the current implementation, DMs which live on "unequal" communicators 94908320bc6fSPatrick Sanan (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed 94918320bc6fSPatrick Sanan incompatible. 94928320bc6fSPatrick Sanan 94938320bc6fSPatrick Sanan This function is labeled "Collective," as information about all subdomains 94948320bc6fSPatrick Sanan is required on each rank. However, in DM implementations which store all this 94958320bc6fSPatrick Sanan information locally, this function may be merely "Logically Collective". 94968320bc6fSPatrick Sanan 94978320bc6fSPatrick Sanan Developer Notes: 94983d862458SPatrick Sanan Compatibility is assumed to be a symmetric concept; DM A is compatible with DM B 94993d862458SPatrick Sanan iff B is compatible with A. Thus, this function checks the implementations 9500a5bc1bf3SBarry Smith of both dm and dmc (if they are of different types), attempting to determine 95018320bc6fSPatrick Sanan compatibility. It is left to DM implementers to ensure that symmetry is 95028320bc6fSPatrick Sanan preserved. The simplest way to do this is, when implementing type-specific 95033d862458SPatrick Sanan logic for this function, is to check for existing logic in the implementation 95043d862458SPatrick Sanan of other DM types and let *set = PETSC_FALSE if found. 95058320bc6fSPatrick Sanan 95068320bc6fSPatrick Sanan Level: advanced 95078320bc6fSPatrick Sanan 95083d862458SPatrick Sanan .seealso: DM, DMDACreateCompatibleDMDA(), DMStagCreateCompatibleDMStag() 95098320bc6fSPatrick Sanan @*/ 95108320bc6fSPatrick Sanan 9511a5bc1bf3SBarry Smith PetscErrorCode DMGetCompatibility(DM dm1,DM dm2,PetscBool *compatible,PetscBool *set) 95128320bc6fSPatrick Sanan { 95138320bc6fSPatrick Sanan PetscErrorCode ierr; 95148320bc6fSPatrick Sanan PetscMPIInt compareResult; 95158320bc6fSPatrick Sanan DMType type,type2; 95168320bc6fSPatrick Sanan PetscBool sameType; 95178320bc6fSPatrick Sanan 95188320bc6fSPatrick Sanan PetscFunctionBegin; 9519a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dm1,DM_CLASSID,1); 95208320bc6fSPatrick Sanan PetscValidHeaderSpecific(dm2,DM_CLASSID,2); 95218320bc6fSPatrick Sanan 95228320bc6fSPatrick Sanan /* Declare a DM compatible with itself */ 9523a5bc1bf3SBarry Smith if (dm1 == dm2) { 95248320bc6fSPatrick Sanan *set = PETSC_TRUE; 95258320bc6fSPatrick Sanan *compatible = PETSC_TRUE; 95268320bc6fSPatrick Sanan PetscFunctionReturn(0); 95278320bc6fSPatrick Sanan } 95288320bc6fSPatrick Sanan 95298320bc6fSPatrick Sanan /* Declare a DM incompatible with a DM that lives on an "unequal" 95308320bc6fSPatrick Sanan communicator. Note that this does not preclude compatibility with 95318320bc6fSPatrick Sanan DMs living on "congruent" or "similar" communicators, but this must be 95328320bc6fSPatrick Sanan determined by the implementation-specific logic */ 9533ffc4695bSBarry Smith ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dm1),PetscObjectComm((PetscObject)dm2),&compareResult);CHKERRMPI(ierr); 95348320bc6fSPatrick Sanan if (compareResult == MPI_UNEQUAL) { 95358320bc6fSPatrick Sanan *set = PETSC_TRUE; 95368320bc6fSPatrick Sanan *compatible = PETSC_FALSE; 95378320bc6fSPatrick Sanan PetscFunctionReturn(0); 95388320bc6fSPatrick Sanan } 95398320bc6fSPatrick Sanan 95408320bc6fSPatrick Sanan /* Pass to the implementation-specific routine, if one exists. */ 9541a5bc1bf3SBarry Smith if (dm1->ops->getcompatibility) { 9542a5bc1bf3SBarry Smith ierr = (*dm1->ops->getcompatibility)(dm1,dm2,compatible,set);CHKERRQ(ierr); 9543b9d85ea2SLisandro Dalcin if (*set) PetscFunctionReturn(0); 95448320bc6fSPatrick Sanan } 95458320bc6fSPatrick Sanan 9546a5bc1bf3SBarry Smith /* If dm1 and dm2 are of different types, then attempt to check compatibility 95478320bc6fSPatrick Sanan with an implementation of this function from dm2 */ 9548a5bc1bf3SBarry Smith ierr = DMGetType(dm1,&type);CHKERRQ(ierr); 95498320bc6fSPatrick Sanan ierr = DMGetType(dm2,&type2);CHKERRQ(ierr); 95508320bc6fSPatrick Sanan ierr = PetscStrcmp(type,type2,&sameType);CHKERRQ(ierr); 95518320bc6fSPatrick Sanan if (!sameType && dm2->ops->getcompatibility) { 9552a5bc1bf3SBarry Smith ierr = (*dm2->ops->getcompatibility)(dm2,dm1,compatible,set);CHKERRQ(ierr); /* Note argument order */ 95538320bc6fSPatrick Sanan } else { 95548320bc6fSPatrick Sanan *set = PETSC_FALSE; 95558320bc6fSPatrick Sanan } 95568320bc6fSPatrick Sanan PetscFunctionReturn(0); 95578320bc6fSPatrick Sanan } 9558c0f0dcc3SMatthew G. Knepley 9559c0f0dcc3SMatthew G. Knepley /*@C 9560c0f0dcc3SMatthew G. Knepley DMMonitorSet - Sets an ADDITIONAL function that is to be used after a solve to monitor discretization performance. 9561c0f0dcc3SMatthew G. Knepley 9562c0f0dcc3SMatthew G. Knepley Logically Collective on DM 9563c0f0dcc3SMatthew G. Knepley 9564c0f0dcc3SMatthew G. Knepley Input Parameters: 9565c0f0dcc3SMatthew G. Knepley + DM - the DM 9566c0f0dcc3SMatthew G. Knepley . f - the monitor function 9567c0f0dcc3SMatthew G. Knepley . mctx - [optional] user-defined context for private data for the monitor routine (use NULL if no context is desired) 9568c0f0dcc3SMatthew G. Knepley - monitordestroy - [optional] routine that frees monitor context (may be NULL) 9569c0f0dcc3SMatthew G. Knepley 9570c0f0dcc3SMatthew G. Knepley Options Database Keys: 9571c0f0dcc3SMatthew G. Knepley - -dm_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to DMMonitorSet(), but 9572c0f0dcc3SMatthew G. Knepley does not cancel those set via the options database. 9573c0f0dcc3SMatthew G. Knepley 9574c0f0dcc3SMatthew G. Knepley Notes: 9575c0f0dcc3SMatthew G. Knepley Several different monitoring routines may be set by calling 9576c0f0dcc3SMatthew G. Knepley DMMonitorSet() multiple times; all will be called in the 9577c0f0dcc3SMatthew G. Knepley order in which they were set. 9578c0f0dcc3SMatthew G. Knepley 9579c0f0dcc3SMatthew G. Knepley Fortran Notes: 9580c0f0dcc3SMatthew G. Knepley Only a single monitor function can be set for each DM object 9581c0f0dcc3SMatthew G. Knepley 9582c0f0dcc3SMatthew G. Knepley Level: intermediate 9583c0f0dcc3SMatthew G. Knepley 9584c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorCancel() 9585c0f0dcc3SMatthew G. Knepley @*/ 9586c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorSet(DM dm, PetscErrorCode (*f)(DM, void *), void *mctx, PetscErrorCode (*monitordestroy)(void**)) 9587c0f0dcc3SMatthew G. Knepley { 9588c0f0dcc3SMatthew G. Knepley PetscInt m; 9589c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9590c0f0dcc3SMatthew G. Knepley 9591c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9592c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9593c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 9594c0f0dcc3SMatthew G. Knepley PetscBool identical; 9595c0f0dcc3SMatthew G. Knepley 9596c0f0dcc3SMatthew G. Knepley ierr = PetscMonitorCompare((PetscErrorCode (*)(void)) f, mctx, monitordestroy, (PetscErrorCode (*)(void)) dm->monitor[m], dm->monitorcontext[m], dm->monitordestroy[m], &identical);CHKERRQ(ierr); 9597c0f0dcc3SMatthew G. Knepley if (identical) PetscFunctionReturn(0); 9598c0f0dcc3SMatthew G. Knepley } 9599c0f0dcc3SMatthew G. Knepley if (dm->numbermonitors >= MAXDMMONITORS) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 9600c0f0dcc3SMatthew G. Knepley dm->monitor[dm->numbermonitors] = f; 9601c0f0dcc3SMatthew G. Knepley dm->monitordestroy[dm->numbermonitors] = monitordestroy; 9602c0f0dcc3SMatthew G. Knepley dm->monitorcontext[dm->numbermonitors++] = (void *) mctx; 9603c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9604c0f0dcc3SMatthew G. Knepley } 9605c0f0dcc3SMatthew G. Knepley 9606c0f0dcc3SMatthew G. Knepley /*@ 9607c0f0dcc3SMatthew G. Knepley DMMonitorCancel - Clears all the monitor functions for a DM object. 9608c0f0dcc3SMatthew G. Knepley 9609c0f0dcc3SMatthew G. Knepley Logically Collective on DM 9610c0f0dcc3SMatthew G. Knepley 9611c0f0dcc3SMatthew G. Knepley Input Parameter: 9612c0f0dcc3SMatthew G. Knepley . dm - the DM 9613c0f0dcc3SMatthew G. Knepley 9614c0f0dcc3SMatthew G. Knepley Options Database Key: 9615c0f0dcc3SMatthew G. Knepley . -dm_monitor_cancel - cancels all monitors that have been hardwired 9616c0f0dcc3SMatthew G. Knepley into a code by calls to DMonitorSet(), but does not cancel those 9617c0f0dcc3SMatthew G. Knepley set via the options database 9618c0f0dcc3SMatthew G. Knepley 9619c0f0dcc3SMatthew G. Knepley Notes: 9620c0f0dcc3SMatthew G. Knepley There is no way to clear one specific monitor from a DM object. 9621c0f0dcc3SMatthew G. Knepley 9622c0f0dcc3SMatthew G. Knepley Level: intermediate 9623c0f0dcc3SMatthew G. Knepley 9624c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorSet() 9625c0f0dcc3SMatthew G. Knepley @*/ 9626c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorCancel(DM dm) 9627c0f0dcc3SMatthew G. Knepley { 9628c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9629c0f0dcc3SMatthew G. Knepley PetscInt m; 9630c0f0dcc3SMatthew G. Knepley 9631c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9632c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9633c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 9634c0f0dcc3SMatthew G. Knepley if (dm->monitordestroy[m]) {ierr = (*dm->monitordestroy[m])(&dm->monitorcontext[m]);CHKERRQ(ierr);} 9635c0f0dcc3SMatthew G. Knepley } 9636c0f0dcc3SMatthew G. Knepley dm->numbermonitors = 0; 9637c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9638c0f0dcc3SMatthew G. Knepley } 9639c0f0dcc3SMatthew G. Knepley 9640c0f0dcc3SMatthew G. Knepley /*@C 9641c0f0dcc3SMatthew G. Knepley DMMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 9642c0f0dcc3SMatthew G. Knepley 9643c0f0dcc3SMatthew G. Knepley Collective on DM 9644c0f0dcc3SMatthew G. Knepley 9645c0f0dcc3SMatthew G. Knepley Input Parameters: 9646c0f0dcc3SMatthew G. Knepley + dm - DM object you wish to monitor 9647c0f0dcc3SMatthew G. Knepley . name - the monitor type one is seeking 9648c0f0dcc3SMatthew G. Knepley . help - message indicating what monitoring is done 9649c0f0dcc3SMatthew G. Knepley . manual - manual page for the monitor 9650c0f0dcc3SMatthew G. Knepley . monitor - the monitor function 9651c0f0dcc3SMatthew 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 9652c0f0dcc3SMatthew G. Knepley 9653c0f0dcc3SMatthew G. Knepley Output Parameter: 9654c0f0dcc3SMatthew G. Knepley . flg - Flag set if the monitor was created 9655c0f0dcc3SMatthew G. Knepley 9656c0f0dcc3SMatthew G. Knepley Level: developer 9657c0f0dcc3SMatthew G. Knepley 9658c0f0dcc3SMatthew G. Knepley .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 9659c0f0dcc3SMatthew G. Knepley PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 9660c0f0dcc3SMatthew G. Knepley PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 9661c0f0dcc3SMatthew G. Knepley PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 9662c0f0dcc3SMatthew G. Knepley PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 9663c0f0dcc3SMatthew G. Knepley PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 9664c0f0dcc3SMatthew G. Knepley PetscOptionsFList(), PetscOptionsEList() 9665c0f0dcc3SMatthew G. Knepley @*/ 9666c0f0dcc3SMatthew 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) 9667c0f0dcc3SMatthew G. Knepley { 9668c0f0dcc3SMatthew G. Knepley PetscViewer viewer; 9669c0f0dcc3SMatthew G. Knepley PetscViewerFormat format; 9670c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9671c0f0dcc3SMatthew G. Knepley 9672c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9673c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9674c0f0dcc3SMatthew G. Knepley ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) dm), ((PetscObject) dm)->options, ((PetscObject) dm)->prefix, name, &viewer, &format, flg);CHKERRQ(ierr); 9675c0f0dcc3SMatthew G. Knepley if (*flg) { 9676c0f0dcc3SMatthew G. Knepley PetscViewerAndFormat *vf; 9677c0f0dcc3SMatthew G. Knepley 9678c0f0dcc3SMatthew G. Knepley ierr = PetscViewerAndFormatCreate(viewer, format, &vf);CHKERRQ(ierr); 9679c0f0dcc3SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) viewer);CHKERRQ(ierr); 9680c0f0dcc3SMatthew G. Knepley if (monitorsetup) {ierr = (*monitorsetup)(dm, vf);CHKERRQ(ierr);} 9681c0f0dcc3SMatthew G. Knepley ierr = DMMonitorSet(dm,(PetscErrorCode (*)(DM, void *)) monitor, vf, (PetscErrorCode (*)(void **)) PetscViewerAndFormatDestroy);CHKERRQ(ierr); 9682c0f0dcc3SMatthew G. Knepley } 9683c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9684c0f0dcc3SMatthew G. Knepley } 9685c0f0dcc3SMatthew G. Knepley 9686c0f0dcc3SMatthew G. Knepley /*@ 9687c0f0dcc3SMatthew G. Knepley DMMonitor - runs the user provided monitor routines, if they exist 9688c0f0dcc3SMatthew G. Knepley 9689c0f0dcc3SMatthew G. Knepley Collective on DM 9690c0f0dcc3SMatthew G. Knepley 9691c0f0dcc3SMatthew G. Knepley Input Parameters: 9692c0f0dcc3SMatthew G. Knepley . dm - The DM 9693c0f0dcc3SMatthew G. Knepley 9694c0f0dcc3SMatthew G. Knepley Level: developer 9695c0f0dcc3SMatthew G. Knepley 9696c0f0dcc3SMatthew G. Knepley .seealso: DMMonitorSet() 9697c0f0dcc3SMatthew G. Knepley @*/ 9698c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitor(DM dm) 9699c0f0dcc3SMatthew G. Knepley { 9700c0f0dcc3SMatthew G. Knepley PetscInt m; 9701c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9702c0f0dcc3SMatthew G. Knepley 9703c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9704c0f0dcc3SMatthew G. Knepley if (!dm) PetscFunctionReturn(0); 9705c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9706c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 9707c0f0dcc3SMatthew G. Knepley ierr = (*dm->monitor[m])(dm, dm->monitorcontext[m]);CHKERRQ(ierr); 9708c0f0dcc3SMatthew G. Knepley } 9709c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9710c0f0dcc3SMatthew G. Knepley } 97112e4af2aeSMatthew G. Knepley 97122e4af2aeSMatthew G. Knepley /*@ 97132e4af2aeSMatthew G. Knepley DMComputeError - Computes the error assuming the user has given exact solution functions 97142e4af2aeSMatthew G. Knepley 97152e4af2aeSMatthew G. Knepley Collective on DM 97162e4af2aeSMatthew G. Knepley 97172e4af2aeSMatthew G. Knepley Input Parameters: 97182e4af2aeSMatthew G. Knepley + dm - The DM 97196b867d5aSJose E. Roman - sol - The solution vector 97202e4af2aeSMatthew G. Knepley 97216b867d5aSJose E. Roman Input/Output Parameter: 97226b867d5aSJose E. Roman . errors - An array of length Nf, the number of fields, or NULL for no output; on output 97236b867d5aSJose E. Roman contains the error in each field 97246b867d5aSJose E. Roman 97256b867d5aSJose E. Roman Output Parameter: 97266b867d5aSJose E. Roman . errorVec - A vector to hold the cellwise error (may be NULL) 97272e4af2aeSMatthew G. Knepley 97282e4af2aeSMatthew G. Knepley Note: The exact solutions come from the PetscDS object, and the time comes from DMGetOutputSequenceNumber(). 97292e4af2aeSMatthew G. Knepley 97302e4af2aeSMatthew G. Knepley Level: developer 97312e4af2aeSMatthew G. Knepley 97322e4af2aeSMatthew G. Knepley .seealso: DMMonitorSet(), DMGetRegionNumDS(), PetscDSGetExactSolution(), DMGetOutputSequenceNumber() 97332e4af2aeSMatthew G. Knepley @*/ 97342e4af2aeSMatthew G. Knepley PetscErrorCode DMComputeError(DM dm, Vec sol, PetscReal errors[], Vec *errorVec) 97352e4af2aeSMatthew G. Knepley { 97362e4af2aeSMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 97372e4af2aeSMatthew G. Knepley void **ctxs; 97382e4af2aeSMatthew G. Knepley PetscReal time; 97392e4af2aeSMatthew G. Knepley PetscInt Nf, f, Nds, s; 97402e4af2aeSMatthew G. Knepley PetscErrorCode ierr; 97412e4af2aeSMatthew G. Knepley 97422e4af2aeSMatthew G. Knepley PetscFunctionBegin; 97432e4af2aeSMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 97442e4af2aeSMatthew G. Knepley ierr = PetscCalloc2(Nf, &exactSol, Nf, &ctxs);CHKERRQ(ierr); 97452e4af2aeSMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 97462e4af2aeSMatthew G. Knepley for (s = 0; s < Nds; ++s) { 97472e4af2aeSMatthew G. Knepley PetscDS ds; 97482e4af2aeSMatthew G. Knepley DMLabel label; 97492e4af2aeSMatthew G. Knepley IS fieldIS; 97502e4af2aeSMatthew G. Knepley const PetscInt *fields; 97512e4af2aeSMatthew G. Knepley PetscInt dsNf; 97522e4af2aeSMatthew G. Knepley 97532e4af2aeSMatthew G. Knepley ierr = DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds);CHKERRQ(ierr); 97542e4af2aeSMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &dsNf);CHKERRQ(ierr); 97552e4af2aeSMatthew G. Knepley if (fieldIS) {ierr = ISGetIndices(fieldIS, &fields);CHKERRQ(ierr);} 97562e4af2aeSMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 97572e4af2aeSMatthew G. Knepley const PetscInt field = fields[f]; 97582e4af2aeSMatthew G. Knepley ierr = PetscDSGetExactSolution(ds, field, &exactSol[field], &ctxs[field]);CHKERRQ(ierr); 97592e4af2aeSMatthew G. Knepley } 97602e4af2aeSMatthew G. Knepley if (fieldIS) {ierr = ISRestoreIndices(fieldIS, &fields);CHKERRQ(ierr);} 97612e4af2aeSMatthew G. Knepley } 97622e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 97632e4af2aeSMatthew 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); 97642e4af2aeSMatthew G. Knepley } 97652e4af2aeSMatthew G. Knepley ierr = DMGetOutputSequenceNumber(dm, NULL, &time);CHKERRQ(ierr); 97662e4af2aeSMatthew G. Knepley if (errors) {ierr = DMComputeL2FieldDiff(dm, time, exactSol, ctxs, sol, errors);CHKERRQ(ierr);} 97672e4af2aeSMatthew G. Knepley if (errorVec) { 97682e4af2aeSMatthew G. Knepley DM edm; 97692e4af2aeSMatthew G. Knepley DMPolytopeType ct; 97702e4af2aeSMatthew G. Knepley PetscBool simplex; 97712e4af2aeSMatthew G. Knepley PetscInt dim, cStart, Nf; 97722e4af2aeSMatthew G. Knepley 97732e4af2aeSMatthew G. Knepley ierr = DMClone(dm, &edm);CHKERRQ(ierr); 97742e4af2aeSMatthew G. Knepley ierr = DMGetDimension(edm, &dim);CHKERRQ(ierr); 97752e4af2aeSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, NULL);CHKERRQ(ierr); 97762e4af2aeSMatthew G. Knepley ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 97772e4af2aeSMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 97782e4af2aeSMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 97792e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 97802e4af2aeSMatthew G. Knepley PetscFE fe, efe; 97812e4af2aeSMatthew G. Knepley PetscQuadrature q; 97822e4af2aeSMatthew G. Knepley const char *name; 97832e4af2aeSMatthew G. Knepley 97842e4af2aeSMatthew G. Knepley ierr = DMGetField(dm, f, NULL, (PetscObject *) &fe);CHKERRQ(ierr); 97852e4af2aeSMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, Nf, simplex, 0, PETSC_DETERMINE, &efe);CHKERRQ(ierr); 97862e4af2aeSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) fe, &name);CHKERRQ(ierr); 97872e4af2aeSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) efe, name);CHKERRQ(ierr); 97882e4af2aeSMatthew G. Knepley ierr = PetscFEGetQuadrature(fe, &q);CHKERRQ(ierr); 97892e4af2aeSMatthew G. Knepley ierr = PetscFESetQuadrature(efe, q);CHKERRQ(ierr); 97902e4af2aeSMatthew G. Knepley ierr = DMSetField(edm, f, NULL, (PetscObject) efe);CHKERRQ(ierr); 97912e4af2aeSMatthew G. Knepley ierr = PetscFEDestroy(&efe);CHKERRQ(ierr); 97922e4af2aeSMatthew G. Knepley } 97932e4af2aeSMatthew G. Knepley ierr = DMCreateDS(edm);CHKERRQ(ierr); 97942e4af2aeSMatthew G. Knepley 97951e1ea65dSPierre Jolivet ierr = DMCreateGlobalVector(edm, errorVec);CHKERRQ(ierr); 97962e4af2aeSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *errorVec, "Error");CHKERRQ(ierr); 97972e4af2aeSMatthew G. Knepley ierr = DMPlexComputeL2DiffVec(dm, time, exactSol, ctxs, sol, *errorVec);CHKERRQ(ierr); 97982e4af2aeSMatthew G. Knepley ierr = DMDestroy(&edm);CHKERRQ(ierr); 97992e4af2aeSMatthew G. Knepley } 98002e4af2aeSMatthew G. Knepley ierr = PetscFree2(exactSol, ctxs);CHKERRQ(ierr); 98012e4af2aeSMatthew G. Knepley PetscFunctionReturn(0); 98022e4af2aeSMatthew G. Knepley } 98039a2a23afSMatthew G. Knepley 98049a2a23afSMatthew G. Knepley /*@ 98059a2a23afSMatthew G. Knepley DMGetNumAuxiliaryVec - Get the number of auxiliary vectors associated with this DM 98069a2a23afSMatthew G. Knepley 98079a2a23afSMatthew G. Knepley Not collective 98089a2a23afSMatthew G. Knepley 98099a2a23afSMatthew G. Knepley Input Parameter: 98109a2a23afSMatthew G. Knepley . dm - The DM 98119a2a23afSMatthew G. Knepley 98129a2a23afSMatthew G. Knepley Output Parameter: 9813a5b23f4aSJose E. Roman . numAux - The number of auxiliary data vectors 98149a2a23afSMatthew G. Knepley 98159a2a23afSMatthew G. Knepley Level: advanced 98169a2a23afSMatthew G. Knepley 98179a2a23afSMatthew G. Knepley .seealso: DMGetAuxiliaryLabels(), DMGetAuxiliaryVec(), DMSetAuxiliaryVec() 98189a2a23afSMatthew G. Knepley @*/ 98199a2a23afSMatthew G. Knepley PetscErrorCode DMGetNumAuxiliaryVec(DM dm, PetscInt *numAux) 98209a2a23afSMatthew G. Knepley { 98219a2a23afSMatthew G. Knepley PetscErrorCode ierr; 98229a2a23afSMatthew G. Knepley 98239a2a23afSMatthew G. Knepley PetscFunctionBegin; 98249a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 98259a2a23afSMatthew G. Knepley ierr = PetscHMapAuxGetSize(dm->auxData, numAux);CHKERRQ(ierr); 98269a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 98279a2a23afSMatthew G. Knepley } 98289a2a23afSMatthew G. Knepley 98299a2a23afSMatthew G. Knepley /*@ 98309a2a23afSMatthew G. Knepley DMGetAuxiliaryVec - Get the auxiliary vector for region specified by the given label and value 98319a2a23afSMatthew G. Knepley 98329a2a23afSMatthew G. Knepley Not collective 98339a2a23afSMatthew G. Knepley 98349a2a23afSMatthew G. Knepley Input Parameters: 98359a2a23afSMatthew G. Knepley + dm - The DM 98369a2a23afSMatthew G. Knepley . label - The DMLabel 98379a2a23afSMatthew G. Knepley - value - The label value indicating the region 98389a2a23afSMatthew G. Knepley 98399a2a23afSMatthew G. Knepley Output Parameter: 98409a2a23afSMatthew G. Knepley . aux - The Vec holding auxiliary field data 98419a2a23afSMatthew G. Knepley 984204c51a94SMatthew G. Knepley Note: If no auxiliary vector is found for this (label, value), (NULL, 0) is checked as well. 984304c51a94SMatthew G. Knepley 98449a2a23afSMatthew G. Knepley Level: advanced 98459a2a23afSMatthew G. Knepley 98469a2a23afSMatthew G. Knepley .seealso: DMSetAuxiliaryVec(), DMGetNumAuxiliaryVec() 98479a2a23afSMatthew G. Knepley @*/ 98489a2a23afSMatthew G. Knepley PetscErrorCode DMGetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, Vec *aux) 98499a2a23afSMatthew G. Knepley { 985004c51a94SMatthew G. Knepley PetscHashAuxKey key, wild = {NULL, 0}; 985104c51a94SMatthew G. Knepley PetscBool has; 98529a2a23afSMatthew G. Knepley PetscErrorCode ierr; 98539a2a23afSMatthew G. Knepley 98549a2a23afSMatthew G. Knepley PetscFunctionBegin; 98559a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 98569a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 98579a2a23afSMatthew G. Knepley key.label = label; 98589a2a23afSMatthew G. Knepley key.value = value; 985904c51a94SMatthew G. Knepley ierr = PetscHMapAuxHas(dm->auxData, key, &has);CHKERRQ(ierr); 986004c51a94SMatthew G. Knepley if (has) {ierr = PetscHMapAuxGet(dm->auxData, key, aux);CHKERRQ(ierr);} 986104c51a94SMatthew G. Knepley else {ierr = PetscHMapAuxGet(dm->auxData, wild, aux);CHKERRQ(ierr);} 98629a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 98639a2a23afSMatthew G. Knepley } 98649a2a23afSMatthew G. Knepley 98659a2a23afSMatthew G. Knepley /*@ 98669a2a23afSMatthew G. Knepley DMSetAuxiliaryVec - Set the auxiliary vector for region specified by the given label and value 98679a2a23afSMatthew G. Knepley 98689a2a23afSMatthew G. Knepley Not collective 98699a2a23afSMatthew G. Knepley 98709a2a23afSMatthew G. Knepley Input Parameters: 98719a2a23afSMatthew G. Knepley + dm - The DM 98729a2a23afSMatthew G. Knepley . label - The DMLabel 98739a2a23afSMatthew G. Knepley . value - The label value indicating the region 98749a2a23afSMatthew G. Knepley - aux - The Vec holding auxiliary field data 98759a2a23afSMatthew G. Knepley 98769a2a23afSMatthew G. Knepley Level: advanced 98779a2a23afSMatthew G. Knepley 98789a2a23afSMatthew G. Knepley .seealso: DMGetAuxiliaryVec() 98799a2a23afSMatthew G. Knepley @*/ 98809a2a23afSMatthew G. Knepley PetscErrorCode DMSetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, Vec aux) 98819a2a23afSMatthew G. Knepley { 98829a2a23afSMatthew G. Knepley Vec old; 98839a2a23afSMatthew G. Knepley PetscHashAuxKey key; 98849a2a23afSMatthew G. Knepley PetscErrorCode ierr; 98859a2a23afSMatthew G. Knepley 98869a2a23afSMatthew G. Knepley PetscFunctionBegin; 98879a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 98889a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 98899a2a23afSMatthew G. Knepley key.label = label; 98909a2a23afSMatthew G. Knepley key.value = value; 98919a2a23afSMatthew G. Knepley ierr = PetscHMapAuxGet(dm->auxData, key, &old);CHKERRQ(ierr); 98929a2a23afSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) aux);CHKERRQ(ierr); 98939a2a23afSMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) old);CHKERRQ(ierr); 98949a2a23afSMatthew G. Knepley if (!aux) {ierr = PetscHMapAuxDel(dm->auxData, key);CHKERRQ(ierr);} 98959a2a23afSMatthew G. Knepley else {ierr = PetscHMapAuxSet(dm->auxData, key, aux);CHKERRQ(ierr);} 98969a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 98979a2a23afSMatthew G. Knepley } 98989a2a23afSMatthew G. Knepley 98999a2a23afSMatthew G. Knepley /*@C 99009a2a23afSMatthew G. Knepley DMGetAuxiliaryLabels - Get the labels and values for all auxiliary vectors in this DM 99019a2a23afSMatthew G. Knepley 99029a2a23afSMatthew G. Knepley Not collective 99039a2a23afSMatthew G. Knepley 99049a2a23afSMatthew G. Knepley Input Parameter: 99059a2a23afSMatthew G. Knepley . dm - The DM 99069a2a23afSMatthew G. Knepley 99079a2a23afSMatthew G. Knepley Output Parameters: 99089a2a23afSMatthew G. Knepley + labels - The DMLabels for each Vec 99099a2a23afSMatthew G. Knepley - values - The label values for each Vec 99109a2a23afSMatthew G. Knepley 99119a2a23afSMatthew G. Knepley Note: The arrays passed in must be at least as large as DMGetNumAuxiliaryVec(). 99129a2a23afSMatthew G. Knepley 99139a2a23afSMatthew G. Knepley Level: advanced 99149a2a23afSMatthew G. Knepley 99159a2a23afSMatthew G. Knepley .seealso: DMGetNumAuxiliaryVec(), DMGetAuxiliaryVec(), DMSetAuxiliaryVec() 99169a2a23afSMatthew G. Knepley @*/ 99179a2a23afSMatthew G. Knepley PetscErrorCode DMGetAuxiliaryLabels(DM dm, DMLabel labels[], PetscInt values[]) 99189a2a23afSMatthew G. Knepley { 99199a2a23afSMatthew G. Knepley PetscHashAuxKey *keys; 99209a2a23afSMatthew G. Knepley PetscInt n, i, off = 0; 99219a2a23afSMatthew G. Knepley PetscErrorCode ierr; 99229a2a23afSMatthew G. Knepley 99239a2a23afSMatthew G. Knepley PetscFunctionBegin; 99249a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 99259a2a23afSMatthew G. Knepley PetscValidPointer(labels, 2); 99269a2a23afSMatthew G. Knepley PetscValidPointer(values, 3); 99279a2a23afSMatthew G. Knepley ierr = DMGetNumAuxiliaryVec(dm, &n);CHKERRQ(ierr); 99289a2a23afSMatthew G. Knepley ierr = PetscMalloc1(n, &keys);CHKERRQ(ierr); 99299a2a23afSMatthew G. Knepley ierr = PetscHMapAuxGetKeys(dm->auxData, &off, keys);CHKERRQ(ierr); 99309a2a23afSMatthew G. Knepley for (i = 0; i < n; ++i) {labels[i] = keys[i].label; values[i] = keys[i].value;} 99319a2a23afSMatthew G. Knepley ierr = PetscFree(keys);CHKERRQ(ierr); 99329a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 99339a2a23afSMatthew G. Knepley } 99349a2a23afSMatthew G. Knepley 99359a2a23afSMatthew G. Knepley /*@ 99369a2a23afSMatthew G. Knepley DMCopyAuxiliaryVec - Copy the auxiliary data to a new DM 99379a2a23afSMatthew G. Knepley 99389a2a23afSMatthew G. Knepley Not collective 99399a2a23afSMatthew G. Knepley 99409a2a23afSMatthew G. Knepley Input Parameter: 99419a2a23afSMatthew G. Knepley . dm - The DM 99429a2a23afSMatthew G. Knepley 99439a2a23afSMatthew G. Knepley Output Parameter: 99449a2a23afSMatthew G. Knepley . dmNew - The new DM, now with the same auxiliary data 99459a2a23afSMatthew G. Knepley 99469a2a23afSMatthew G. Knepley Level: advanced 99479a2a23afSMatthew G. Knepley 99489a2a23afSMatthew G. Knepley .seealso: DMGetNumAuxiliaryVec(), DMGetAuxiliaryVec(), DMSetAuxiliaryVec() 99499a2a23afSMatthew G. Knepley @*/ 99509a2a23afSMatthew G. Knepley PetscErrorCode DMCopyAuxiliaryVec(DM dm, DM dmNew) 99519a2a23afSMatthew G. Knepley { 99529a2a23afSMatthew G. Knepley PetscErrorCode ierr; 99539a2a23afSMatthew G. Knepley 99549a2a23afSMatthew G. Knepley PetscFunctionBegin; 99559a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 99569a2a23afSMatthew G. Knepley ierr = PetscHMapAuxDestroy(&dmNew->auxData);CHKERRQ(ierr); 99579a2a23afSMatthew G. Knepley ierr = PetscHMapAuxDuplicate(dm->auxData, &dmNew->auxData);CHKERRQ(ierr); 99589a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 99599a2a23afSMatthew G. Knepley } 9960b5a892a1SMatthew G. Knepley 9961b5a892a1SMatthew G. Knepley /*@C 9962b5a892a1SMatthew G. Knepley DMPolytopeMatchOrientation - Determine an orientation that takes the source face arrangement to the target face arrangement 9963b5a892a1SMatthew G. Knepley 9964b5a892a1SMatthew G. Knepley Not collective 9965b5a892a1SMatthew G. Knepley 9966b5a892a1SMatthew G. Knepley Input Parameters: 9967b5a892a1SMatthew G. Knepley + ct - The DMPolytopeType 9968b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of faces 9969b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of faces 9970b5a892a1SMatthew G. Knepley 9971b5a892a1SMatthew G. Knepley Output Parameters: 9972b5a892a1SMatthew G. Knepley + ornt - The orientation which will take the source arrangement to the target arrangement 9973b5a892a1SMatthew G. Knepley - found - Flag indicating that a suitable orientation was found 9974b5a892a1SMatthew G. Knepley 9975b5a892a1SMatthew G. Knepley Level: advanced 9976b5a892a1SMatthew G. Knepley 9977b5a892a1SMatthew G. Knepley .seealso: DMPolytopeGetOrientation(), DMPolytopeMatchVertexOrientation() 9978b5a892a1SMatthew G. Knepley @*/ 9979b5a892a1SMatthew G. Knepley PetscErrorCode DMPolytopeMatchOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt, PetscBool *found) 9980b5a892a1SMatthew G. Knepley { 9981b5a892a1SMatthew G. Knepley const PetscInt cS = DMPolytopeTypeGetConeSize(ct); 9982b5a892a1SMatthew G. Knepley const PetscInt nO = DMPolytopeTypeGetNumArrangments(ct)/2; 9983b5a892a1SMatthew G. Knepley PetscInt o, c; 9984b5a892a1SMatthew G. Knepley 9985b5a892a1SMatthew G. Knepley PetscFunctionBegin; 9986b5a892a1SMatthew G. Knepley if (!nO) {*ornt = 0; *found = PETSC_TRUE; PetscFunctionReturn(0);} 9987b5a892a1SMatthew G. Knepley for (o = -nO; o < nO; ++o) { 9988b5a892a1SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetArrangment(ct, o); 9989b5a892a1SMatthew G. Knepley 9990b5a892a1SMatthew G. Knepley for (c = 0; c < cS; ++c) if (sourceCone[arr[c*2]] != targetCone[c]) break; 9991b5a892a1SMatthew G. Knepley if (c == cS) {*ornt = o; break;} 9992b5a892a1SMatthew G. Knepley } 9993b5a892a1SMatthew G. Knepley *found = o == nO ? PETSC_FALSE : PETSC_TRUE; 9994b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 9995b5a892a1SMatthew G. Knepley } 9996b5a892a1SMatthew G. Knepley 9997b5a892a1SMatthew G. Knepley /*@C 9998b5a892a1SMatthew G. Knepley DMPolytopeGetOrientation - Determine an orientation that takes the source face arrangement to the target face arrangement 9999b5a892a1SMatthew G. Knepley 10000b5a892a1SMatthew G. Knepley Not collective 10001b5a892a1SMatthew G. Knepley 10002b5a892a1SMatthew G. Knepley Input Parameters: 10003b5a892a1SMatthew G. Knepley + ct - The DMPolytopeType 10004b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of faces 10005b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of faces 10006b5a892a1SMatthew G. Knepley 10007b5a892a1SMatthew G. Knepley Output Parameters: 10008b5a892a1SMatthew G. Knepley . ornt - The orientation which will take the source arrangement to the target arrangement 10009b5a892a1SMatthew G. Knepley 10010b5a892a1SMatthew G. Knepley Note: This function will fail if no suitable orientation can be found. 10011b5a892a1SMatthew G. Knepley 10012b5a892a1SMatthew G. Knepley Level: advanced 10013b5a892a1SMatthew G. Knepley 10014b5a892a1SMatthew G. Knepley .seealso: DMPolytopeMatchOrientation(), DMPolytopeGetVertexOrientation() 10015b5a892a1SMatthew G. Knepley @*/ 10016b5a892a1SMatthew G. Knepley PetscErrorCode DMPolytopeGetOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt) 10017b5a892a1SMatthew G. Knepley { 10018b5a892a1SMatthew G. Knepley PetscBool found; 10019b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 10020b5a892a1SMatthew G. Knepley 10021b5a892a1SMatthew G. Knepley PetscFunctionBegin; 10022b5a892a1SMatthew G. Knepley ierr = DMPolytopeMatchOrientation(ct, sourceCone, targetCone, ornt, &found);CHKERRQ(ierr); 10023b5a892a1SMatthew G. Knepley if (!found) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find orientation for %s", DMPolytopeTypes[ct]); 10024b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 10025b5a892a1SMatthew G. Knepley } 10026b5a892a1SMatthew G. Knepley 10027b5a892a1SMatthew G. Knepley /*@C 10028b5a892a1SMatthew G. Knepley DMPolytopeMatchVertexOrientation - Determine an orientation that takes the source vertex arrangement to the target vertex arrangement 10029b5a892a1SMatthew G. Knepley 10030b5a892a1SMatthew G. Knepley Not collective 10031b5a892a1SMatthew G. Knepley 10032b5a892a1SMatthew G. Knepley Input Parameters: 10033b5a892a1SMatthew G. Knepley + ct - The DMPolytopeType 10034b5a892a1SMatthew G. Knepley . sourceVert - The source arrangement of vertices 10035b5a892a1SMatthew G. Knepley - targetVert - The target arrangement of vertices 10036b5a892a1SMatthew G. Knepley 10037b5a892a1SMatthew G. Knepley Output Parameters: 10038b5a892a1SMatthew G. Knepley + ornt - The orientation which will take the source arrangement to the target arrangement 10039b5a892a1SMatthew G. Knepley - found - Flag indicating that a suitable orientation was found 10040b5a892a1SMatthew G. Knepley 10041b5a892a1SMatthew G. Knepley Level: advanced 10042b5a892a1SMatthew G. Knepley 10043b5a892a1SMatthew G. Knepley .seealso: DMPolytopeGetOrientation(), DMPolytopeMatchOrientation() 10044b5a892a1SMatthew G. Knepley @*/ 10045b5a892a1SMatthew G. Knepley PetscErrorCode DMPolytopeMatchVertexOrientation(DMPolytopeType ct, const PetscInt sourceVert[], const PetscInt targetVert[], PetscInt *ornt, PetscBool *found) 10046b5a892a1SMatthew G. Knepley { 10047b5a892a1SMatthew G. Knepley const PetscInt cS = DMPolytopeTypeGetNumVertices(ct); 10048b5a892a1SMatthew G. Knepley const PetscInt nO = DMPolytopeTypeGetNumArrangments(ct)/2; 10049b5a892a1SMatthew G. Knepley PetscInt o, c; 10050b5a892a1SMatthew G. Knepley 10051b5a892a1SMatthew G. Knepley PetscFunctionBegin; 10052b5a892a1SMatthew G. Knepley if (!nO) {*ornt = 0; *found = PETSC_TRUE; PetscFunctionReturn(0);} 10053b5a892a1SMatthew G. Knepley for (o = -nO; o < nO; ++o) { 10054b5a892a1SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetVertexArrangment(ct, o); 10055b5a892a1SMatthew G. Knepley 10056b5a892a1SMatthew G. Knepley for (c = 0; c < cS; ++c) if (sourceVert[arr[c]] != targetVert[c]) break; 10057b5a892a1SMatthew G. Knepley if (c == cS) {*ornt = o; break;} 10058b5a892a1SMatthew G. Knepley } 10059b5a892a1SMatthew G. Knepley *found = o == nO ? PETSC_FALSE : PETSC_TRUE; 10060b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 10061b5a892a1SMatthew G. Knepley } 10062b5a892a1SMatthew G. Knepley 10063b5a892a1SMatthew G. Knepley /*@C 10064b5a892a1SMatthew G. Knepley DMPolytopeGetVertexOrientation - Determine an orientation that takes the source vertex arrangement to the target vertex arrangement 10065b5a892a1SMatthew G. Knepley 10066b5a892a1SMatthew G. Knepley Not collective 10067b5a892a1SMatthew G. Knepley 10068b5a892a1SMatthew G. Knepley Input Parameters: 10069b5a892a1SMatthew G. Knepley + ct - The DMPolytopeType 10070b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of vertices 10071b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of vertices 10072b5a892a1SMatthew G. Knepley 10073b5a892a1SMatthew G. Knepley Output Parameters: 10074b5a892a1SMatthew G. Knepley . ornt - The orientation which will take the source arrangement to the target arrangement 10075b5a892a1SMatthew G. Knepley 10076b5a892a1SMatthew G. Knepley Note: This function will fail if no suitable orientation can be found. 10077b5a892a1SMatthew G. Knepley 10078b5a892a1SMatthew G. Knepley Level: advanced 10079b5a892a1SMatthew G. Knepley 10080b5a892a1SMatthew G. Knepley .seealso: DMPolytopeMatchVertexOrientation(), DMPolytopeGetOrientation() 10081b5a892a1SMatthew G. Knepley @*/ 10082b5a892a1SMatthew G. Knepley PetscErrorCode DMPolytopeGetVertexOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt) 10083b5a892a1SMatthew G. Knepley { 10084b5a892a1SMatthew G. Knepley PetscBool found; 10085b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 10086b5a892a1SMatthew G. Knepley 10087b5a892a1SMatthew G. Knepley PetscFunctionBegin; 10088b5a892a1SMatthew G. Knepley ierr = DMPolytopeMatchVertexOrientation(ct, sourceCone, targetCone, ornt, &found);CHKERRQ(ierr); 10089b5a892a1SMatthew G. Knepley if (!found) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find orientation for %s", DMPolytopeTypes[ct]); 10090b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 10091b5a892a1SMatthew G. Knepley } 10092012bc364SMatthew G. Knepley 10093012bc364SMatthew G. Knepley /*@C 10094012bc364SMatthew G. Knepley DMPolytopeInCellTest - Check whether a point lies inside the reference cell of given type 10095012bc364SMatthew G. Knepley 10096012bc364SMatthew G. Knepley Not collective 10097012bc364SMatthew G. Knepley 10098012bc364SMatthew G. Knepley Input Parameters: 10099012bc364SMatthew G. Knepley + ct - The DMPolytopeType 10100012bc364SMatthew G. Knepley - point - Coordinates of the point 10101012bc364SMatthew G. Knepley 10102012bc364SMatthew G. Knepley Output Parameters: 10103012bc364SMatthew G. Knepley . inside - Flag indicating whether the point is inside the reference cell of given type 10104012bc364SMatthew G. Knepley 10105012bc364SMatthew G. Knepley Level: advanced 10106012bc364SMatthew G. Knepley 10107012bc364SMatthew G. Knepley .seealso: DMLocatePoints() 10108012bc364SMatthew G. Knepley @*/ 10109012bc364SMatthew G. Knepley PetscErrorCode DMPolytopeInCellTest(DMPolytopeType ct, const PetscReal point[], PetscBool *inside) 10110012bc364SMatthew G. Knepley { 10111012bc364SMatthew G. Knepley PetscReal sum = 0.0; 10112012bc364SMatthew G. Knepley PetscInt d; 10113012bc364SMatthew G. Knepley 10114012bc364SMatthew G. Knepley PetscFunctionBegin; 10115012bc364SMatthew G. Knepley *inside = PETSC_TRUE; 10116012bc364SMatthew G. Knepley switch (ct) { 10117012bc364SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 10118012bc364SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 10119012bc364SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) { 10120012bc364SMatthew G. Knepley if (point[d] < -1.0) {*inside = PETSC_FALSE; break;} 10121012bc364SMatthew G. Knepley sum += point[d]; 10122012bc364SMatthew G. Knepley } 10123012bc364SMatthew G. Knepley if (sum > PETSC_SMALL) {*inside = PETSC_FALSE; break;} 10124012bc364SMatthew G. Knepley break; 10125012bc364SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 10126012bc364SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 10127012bc364SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) 10128012bc364SMatthew G. Knepley if (PetscAbsReal(point[d]) > 1.+PETSC_SMALL) {*inside = PETSC_FALSE; break;} 10129012bc364SMatthew G. Knepley break; 10130012bc364SMatthew G. Knepley default: 10131012bc364SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 10132012bc364SMatthew G. Knepley } 10133012bc364SMatthew G. Knepley PetscFunctionReturn(0); 10134012bc364SMatthew G. Knepley } 10135