/*@ KSPSetDM - Sets the DM that may be used by some preconditioners Logically Collective on KSP Input Parameters: + ksp - the preconditioner context - dm - the dm, cannot be NULL Notes: If this is used then the KSP will attempt to use the DM to create the matrix and use the routine set with DMKSPSetComputeOperators(). Use KSPSetDMActive(ksp,PETSC_FALSE) to instead use the matrix you've provided with KSPSetOperators(). Level: intermediate .seealso: KSPGetDM(), KSPSetDMActive(), KSPSetComputeOperators(), KSPSetComputeRHS(), KSPSetComputeInitialGuess(), DMKSPSetComputeOperators(), DMKSPSetComputeRHS(), DMKSPSetComputeInitialGuess() @*/ PetscErrorCode KSPSetDM(KSP ksp,DM dm) { PetscErrorCode ierr; PC pc; PetscFunctionBegin; PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); PetscValidHeaderSpecific(dm,DM_CLASSID,2); ierr = PetscObjectReference((PetscObject)dm); CHKERRQ(ierr); if (ksp->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ if (ksp->dm->dmksp && !dm->dmksp) { DMKSP kdm; ierr = DMCopyDMKSP(ksp->dm,dm); CHKERRQ(ierr); ierr = DMGetDMKSP(ksp->dm,&kdm); CHKERRQ(ierr); if (kdm->originaldm == ksp->dm) kdm->originaldm = dm; /* Grant write privileges to the replacement DM */ } ierr = DMDestroy(&ksp->dm); CHKERRQ(ierr); } ksp->dm = dm; ksp->dmAuto = PETSC_FALSE; ierr = KSPGetPC(ksp,&pc); CHKERRQ(ierr); ierr = PCSetDM(pc,dm); CHKERRQ(ierr); ksp->dmActive = PETSC_TRUE; PetscFunctionReturn(0); }
/* Attaches the DMKSP to the coarse level. * Under what conditions should we copy versus duplicate? */ static PetscErrorCode DMRefineHook_DMKSP(DM dm,DM dmc,void *ctx) { PetscErrorCode ierr; PetscFunctionBegin; ierr = DMCopyDMKSP(dm,dmc);CHKERRQ(ierr); PetscFunctionReturn(0); }