/*@ 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); }
PETSC_EXTERN void PETSC_STDCALL dmkspsetcomputeoperators_(DM *dm,void (PETSC_STDCALL *func)(KSP*,Vec*,void*,PetscErrorCode*),void *ctx,PetscErrorCode *ierr) { DMKSP kdm; CHKFORTRANNULLOBJECT(ctx); *ierr = DMGetDMKSP(*dm,&kdm); if (!*ierr) { kdm->fortran_func_pointers[1] = (PetscVoidFunction)func; *ierr = DMKSPSetComputeOperators(*dm,ourkspcomputeoperators,ctx); } }
static PetscErrorCode ourkspcomputeoperators(KSP ksp,Mat A,Mat B,void *ctx) { PetscErrorCode ierr = 0; DM dm; DMKSP kdm; ierr = KSPGetDM(ksp,&dm);CHKERRQ(ierr); ierr = DMGetDMKSP(dm,&kdm);CHKERRQ(ierr); (*(void (PETSC_STDCALL *)(KSP*,Mat*,Mat*,void*,PetscErrorCode*))(kdm->fortran_func_pointers[1]))(&ksp,&A,&B,ctx,&ierr);CHKERRQ(ierr); return 0; }
static PetscErrorCode ourkspcomputeinitialguess(KSP ksp,Vec b,void *ctx) { PetscErrorCode ierr = 0; DM dm; DMKSP kdm; ierr = KSPGetDM(ksp,&dm);CHKERRQ(ierr); ierr = DMGetDMKSP(dm,&kdm);CHKERRQ(ierr); (*(void (PETSC_STDCALL *)(KSP*,Vec*,void*,PetscErrorCode*))(kdm->fortran_func_pointers[2]))(&ksp,&b,ctx,&ierr);CHKERRQ(ierr); return 0; }
/*@C DMKSPGetComputeInitialGuess - get KSP initial guess evaluation function Not Collective Input Argument: . dm - DM to be used with KSP Output Arguments: + func - initial guess evaluation function, see KSPSetComputeInitialGuess() for calling sequence - ctx - context for right hand side evaluation Level: advanced .seealso: DMKSPSetContext(), KSPSetComputeRHS(), DMKSPSetComputeRHS() @*/ PetscErrorCode DMKSPGetComputeInitialGuess(DM dm,PetscErrorCode (**func)(KSP,Vec,void*),void *ctx) { PetscErrorCode ierr; DMKSP kdm; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); ierr = DMGetDMKSP(dm,&kdm);CHKERRQ(ierr); if (func) *func = kdm->ops->computeinitialguess; if (ctx) *(void**)ctx = kdm->initialguessctx; PetscFunctionReturn(0); }
/*@C DMKSPGetComputeOperators - get KSP matrix evaluation function Not Collective Input Argument: . dm - DM to be used with KSP Output Arguments: + func - matrix evaluation function, see KSPSetComputeOperators() for calling sequence - ctx - context for matrix evaluation Level: advanced .seealso: DMKSPSetContext(), KSPSetComputeOperators(), DMKSPSetComputeOperators() @*/ PetscErrorCode DMKSPGetComputeOperators(DM dm,PetscErrorCode (**func)(KSP,Mat,Mat,MatStructure*,void*),void *ctx) { PetscErrorCode ierr; DMKSP kdm; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); ierr = DMGetDMKSP(dm,&kdm);CHKERRQ(ierr); if (func) *func = kdm->ops->computeoperators; if (ctx) *(void**)ctx = kdm->operatorsctx; PetscFunctionReturn(0); }
/*@C DMGetDMKSPWrite - get write access to private DMKSP context from a DM Not Collective Input Argument: . dm - DM to be used with KSP Output Argument: . kspdm - private DMKSP context Level: developer .seealso: DMGetDMKSP() @*/ PetscErrorCode DMGetDMKSPWrite(DM dm,DMKSP *kspdm) { PetscErrorCode ierr; DMKSP kdm; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); ierr = DMGetDMKSP(dm,&kdm);CHKERRQ(ierr); if (!kdm->originaldm) kdm->originaldm = dm; if (kdm->originaldm != dm) { /* Copy on write */ DMKSP oldkdm = kdm; ierr = PetscInfo(dm,"Copying DMKSP due to write\n");CHKERRQ(ierr); ierr = DMKSPCreate(PetscObjectComm((PetscObject)dm),&kdm);CHKERRQ(ierr); ierr = DMKSPCopy(oldkdm,kdm);CHKERRQ(ierr); ierr = DMKSPDestroy((DMKSP*)&dm->dmksp);CHKERRQ(ierr); dm->dmksp = (PetscObject)kdm; } *kspdm = kdm; PetscFunctionReturn(0); }