示例#1
0
/*@C
    DMMGSetNullSpace - Indicates the null space in the linear operator (this is needed by the linear solver)

    Collective on DMMG

    Input Parameter:
+   dmmg - the context
.   has_cnst - is the constant vector in the null space
.   n - number of null vectors (excluding the possible constant vector)
-   func - a function that fills an array of vectors with the null vectors (must be orthonormal), may be PETSC_NULL

    Level: advanced

.seealso DMMGCreate(), DMMGDestroy, DMMGSetDM(), DMMGSolve(), MatNullSpaceCreate(), KSPSetNullSpace(), DMMGSetMatType()

@*/
PetscErrorCode PETSCSNES_DLLEXPORT DMMGSetNullSpace(DMMG *dmmg,PetscTruth has_cnst,PetscInt n,PetscErrorCode (*func)(DMMG,Vec[]))
{
  PetscErrorCode ierr;
  PetscInt       i,j,nlevels = dmmg[0]->nlevels;
  Vec            *nulls = 0;
  MatNullSpace   nullsp;
  KSP            iksp;
  PC             pc,ipc;
  PetscTruth     ismg,isred;

  PetscFunctionBegin;
  if (!dmmg) SETERRQ(PETSC_ERR_ARG_NULL,"Passing null as DMMG");
  if (!dmmg[0]->ksp) SETERRQ(PETSC_ERR_ORDER,"Must call AFTER DMMGSetKSP() or DMMGSetSNES()");
  if ((n && !func) || (!n && func)) SETERRQ(PETSC_ERR_ARG_INCOMP,"Both n and func() must be set together");
  if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Cannot have negative number of vectors in null space n = %D",n)

  for (i=0; i<nlevels; i++) {
    if (n) {
      ierr = VecDuplicateVecs(dmmg[i]->b,n,&nulls);CHKERRQ(ierr);
      ierr = (*func)(dmmg[i],nulls);CHKERRQ(ierr);
    }
    ierr = MatNullSpaceCreate(dmmg[i]->comm,has_cnst,n,nulls,&nullsp);CHKERRQ(ierr);
    ierr = KSPSetNullSpace(dmmg[i]->ksp,nullsp);CHKERRQ(ierr);
    for (j=i; j<nlevels; j++) {
      ierr = KSPGetPC(dmmg[j]->ksp,&pc);CHKERRQ(ierr);
      ierr = PetscTypeCompare((PetscObject)pc,PCMG,&ismg);CHKERRQ(ierr);
      if (ismg) {
        ierr = PCMGGetSmoother(pc,i,&iksp);CHKERRQ(ierr);
        ierr = KSPSetNullSpace(iksp, nullsp);CHKERRQ(ierr);
      }
    }
    ierr = MatNullSpaceDestroy(nullsp);CHKERRQ(ierr);
    if (n) {
      ierr = VecDestroyVecs(nulls,n);CHKERRQ(ierr);
    }
  }
  /* make all the coarse grid solvers have LU shift since they are singular */
  for (i=0; i<nlevels; i++) {
    ierr = KSPGetPC(dmmg[i]->ksp,&pc);CHKERRQ(ierr);
    ierr = PetscTypeCompare((PetscObject)pc,PCMG,&ismg);CHKERRQ(ierr);
    if (ismg) {
      ierr = PCMGGetSmoother(pc,0,&iksp);CHKERRQ(ierr);
      ierr = KSPGetPC(iksp,&ipc);CHKERRQ(ierr);
      ierr = PetscTypeCompare((PetscObject)ipc,PCREDUNDANT,&isred);CHKERRQ(ierr);
      if (isred) {
        ierr = PCRedundantGetPC(ipc,&ipc);CHKERRQ(ierr);
      }
      ierr = PCFactorSetShiftType(ipc,MAT_SHIFT_POSITIVE_DEFINITE);CHKERRQ(ierr);
    }
  }
  PetscFunctionReturn(0);
}
MGSolver_PETScData* MultigridSolver_CreateCoarseSolver( MultigridSolver* self, Mat matrix ) {
	//MatrixSolver*	coarseSolver;
	MGSolver_PETScData* courseSolver;
	unsigned	nProcs;
	PC		pc;

	MPI_Comm_size( self->mgData->comm, (int*)&nProcs );

	/*
	coarseSolver = (MatrixSolver*)PETScMatrixSolver_New( "" );
	PETScMatrixSolver_SetKSPType( coarseSolver, 
				      PETScMatrixSolver_KSPType_PreOnly );
	if( nProcs == 1 ) {
		PETScMatrixSolver_SetPCType( coarseSolver, 
					     PETScMatrixSolver_PCType_LU );
	}
	else {
		PETScMatrixSolver_SetPCType( coarseSolver, 
					     PETScMatrixSolver_PCType_RedundantLU );
	}
	MatrixSolver_SetMatrix( coarseSolver, matrix );
	*/
	
	if( nProcs == 1 ){
	    KSPCreate( MPI_COMM_WORLD, &courseSolver->ksp );
	    KSPSetType( courseSolver->ksp, KSPPREONLY );
	    KSPGetPC( courseSolver->ksp, &pc );
	    PCSetType( pc, PCLU );
	}
	else {
		PCSetType( pc, PCREDUNDANT );
		#if ((PETSC_VERSION_MAJOR>=3) && (PETSC_VERSION_MINOR>=2) )
		PCCreate( MPI_COMM_WORLD, &pc);
		PCRedundantGetKSP( pc, &courseSolver->ksp );
		#else
		KSPCreate( MPI_COMM_WORLD, &courseSolver->ksp );
		KSPSetType( courseSolver->ksp, KSPPREONLY );
		KSPGetPC( courseSolver->ksp, &pc );
		PCRedundantGetPC( pc, &pc );
                #endif
		PCSetType( pc, PCLU );
	}
        if( courseSolver->matrix != PETSC_NULL ){
	    Stg_MatDestroy(&courseSolver->matrix );}

	courseSolver->matrix = matrix;
	Stg_KSPSetOperators( courseSolver->ksp, matrix, matrix, DIFFERENT_NONZERO_PATTERN );

	return courseSolver;
}
示例#3
0
void PETSC_STDCALL   pcredundantgetpc_(PC pc,PC *innerpc, int *__ierr ){
*__ierr = PCRedundantGetPC(
	(PC)PetscToPointer((pc) ),innerpc);
}