PetscErrorCode DMCreateSubDM_Shell(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm) { PetscErrorCode ierr; PetscFunctionBegin; if (subdm) {ierr = DMShellCreate(PetscObjectComm((PetscObject) dm), subdm);CHKERRQ(ierr);} ierr = DMCreateSubDM_Section_Private(dm, numFields, fields, is, subdm);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode DMCreateSubDM_DA(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm) { DM_DA *da = (DM_DA*) dm->data; PetscSection section; PetscErrorCode ierr; PetscFunctionBegin; if (subdm) { PetscSF sf; Vec coords; void *ctx; /* Cannot use DMClone since the dof stuff is mixed in. Ugh ierr = DMClone(dm, subdm);CHKERRQ(ierr); */ ierr = DMCreate(PetscObjectComm((PetscObject)dm), subdm);CHKERRQ(ierr); ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); ierr = DMSetPointSF(*subdm, sf);CHKERRQ(ierr); ierr = DMGetApplicationContext(dm, &ctx);CHKERRQ(ierr); ierr = DMSetApplicationContext(*subdm, ctx);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(dm, &coords);CHKERRQ(ierr); if (coords) { ierr = DMSetCoordinatesLocal(*subdm, coords);CHKERRQ(ierr); } else { ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr); if (coords) {ierr = DMSetCoordinates(*subdm, coords);CHKERRQ(ierr);} } ierr = DMSetType(*subdm, DMDA);CHKERRQ(ierr); ierr = DMSetDimension(*subdm, dm->dim);CHKERRQ(ierr); ierr = DMDASetSizes(*subdm, da->M, da->N, da->P);CHKERRQ(ierr); ierr = DMDASetNumProcs(*subdm, da->m, da->n, da->p);CHKERRQ(ierr); ierr = DMDASetBoundaryType(*subdm, da->bx, da->by, da->bz);CHKERRQ(ierr); ierr = DMDASetDof(*subdm, numFields);CHKERRQ(ierr); ierr = DMDASetStencilType(*subdm, da->stencil_type);CHKERRQ(ierr); ierr = DMDASetStencilWidth(*subdm, da->s);CHKERRQ(ierr); ierr = DMDASetOwnershipRanges(*subdm, da->lx, da->ly, da->lz);CHKERRQ(ierr); } ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); if (section) { ierr = DMCreateSubDM_Section_Private(dm, numFields, fields, is, subdm);CHKERRQ(ierr); } else { if (is) { PetscInt *indices, cnt = 0, dof = da->w, i, j; ierr = PetscMalloc1(da->Nlocal*numFields/dof, &indices);CHKERRQ(ierr); for (i = da->base/dof; i < (da->base+da->Nlocal)/dof; ++i) { for (j = 0; j < numFields; ++j) { indices[cnt++] = dof*i + fields[j]; } } if (cnt != da->Nlocal*numFields/dof) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Count %d does not equal expected value %d", cnt, da->Nlocal*numFields/dof); ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), cnt, indices, PETSC_OWN_POINTER, is);CHKERRQ(ierr); } } PetscFunctionReturn(0); }