PETSC_EXTERN void PETSC_STDCALL pcfieldsplitsetfields_(PC pc, char splitname[],PetscInt *n, PetscInt *fields, PetscInt *fields_col, int *__ierr ){ *__ierr = PCFieldSplitSetFields( (PC)PetscToPointer((pc) ),splitname,*n,fields,fields_col); }
PetscErrorCode FluidFieldSetup( FluidField f ) { PetscLogDouble t1,t2; PetscErrorCode ierr; PetscFunctionBegin; // Assemble viscous matricies ierr = FluidFieldMatAssemble( f ); CHKERRQ(ierr); ierr = PetscInfo3( 0, "Lengths: %e %e %e\n", f->lens.x, f->lens.y, f->lens.z ); CHKERRQ(ierr); ierr = PetscInfo3( 0, "Size: %d %d %d\n", f->dims.x, f->dims.y, f->dims.z ); CHKERRQ(ierr); ierr = PetscInfo3( 0, "dx: %e %e %e\n", f->dh.x, f->dh.y, f->dh.z ); CHKERRQ(ierr); ierr = PetscTime(&t1); CHKERRQ(ierr); // Create vectors ierr = GACreate( f->daV, &f->ga); CHKERRQ(ierr); ierr = DMCreateGlobalVector(f->daV,&f->rhs); CHKERRQ(ierr); ierr = VecDuplicate(f->rhs,&f->vel); CHKERRQ(ierr); ierr = VecDuplicate(f->rhs,&f->vel0); CHKERRQ(ierr); // ierr = DACreateGlobalVector(f->daE,&f->E); CHKERRQ(ierr); ierr = DMCreateGlobalVector(f->daB,&f->buf); CHKERRQ(ierr); // Set up the outer solver ierr = KSPCreate(f->comm,&f->ksp); CHKERRQ(ierr); ierr = KSPSetOperators(f->ksp,f->mat,f->mat, SAME_PRECONDITIONER); CHKERRQ(ierr); ierr = KSPSetType(f->ksp,KSPFGMRES); CHKERRQ(ierr); ierr = KSPSetInitialGuessNonzero(f->ksp,PETSC_TRUE); CHKERRQ(ierr); ierr = KSPSetTolerances(f->ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT); CHKERRQ(ierr); ierr = KSPSetFromOptions(f->ksp);CHKERRQ(ierr); // Split pressure from velocity [ u v w | p ] PC pc; ierr = KSPGetPC(f->ksp,&pc); CHKERRQ(ierr); ierr = PCSetType(pc, PCFIELDSPLIT); CHKERRQ(ierr); ierr = PCFieldSplitSetType(pc,PC_COMPOSITE_SCHUR); CHKERRQ(ierr); if( f->is3D ) { const PetscInt ufields[] = {U_FACE,V_FACE,W_FACE}; const PetscInt pfields[] = {CELL_CENTER}; ierr = PCFieldSplitSetBlockSize(pc,4); CHKERRQ(ierr); // [p u v w] ierr = PCFieldSplitSetFields(pc,"v",3,ufields,ufields); CHKERRQ(ierr); // [u v w] ierr = PCFieldSplitSetFields(pc,"p",1,pfields,pfields); CHKERRQ(ierr); // [ p ] } else { const PetscInt ufields[] = {U_FACE,V_FACE}; const PetscInt pfields[] = {CELL_CENTER}; ierr = PCFieldSplitSetBlockSize(pc,3); CHKERRQ(ierr); // [p u v] ierr = PCFieldSplitSetFields(pc,"v",2,ufields,ufields); CHKERRQ(ierr); // [u v] ierr = PCFieldSplitSetFields(pc,"p",1,pfields,pfields); CHKERRQ(ierr); // [ p ] } ierr = PCSetUp(pc); CHKERRQ(ierr); int nVelP; KSP *kspVelP; ierr = PCFieldSplitGetSubKSP(pc,&nVelP,&kspVelP); CHKERRQ(ierr); ierr = KSPSetTolerances(kspVelP[1],PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,4); CHKERRQ(ierr); ierr = KSPSetType(kspVelP[1],KSPGMRES); CHKERRQ(ierr); ierr = KSPGetPC(kspVelP[1],&pc); CHKERRQ(ierr); ierr = PCSetType(pc,PCNONE); CHKERRQ(ierr); ierr = KSPSetFromOptions(kspVelP[1]);CHKERRQ(ierr); // Split velocity [u v w] into component matricies [u], [v], [w] ierr = KSPSetType(kspVelP[0],KSPPREONLY); CHKERRQ(ierr); ierr = KSPGetPC(kspVelP[0],&pc); CHKERRQ(ierr); ierr = PCSetType(pc, PCFIELDSPLIT); CHKERRQ(ierr); ierr = PCFieldSplitSetType(pc,PC_COMPOSITE_ADDITIVE); CHKERRQ(ierr); ierr = PCFieldSplitSetBlockSize(pc,f->is3D?3:2); CHKERRQ(ierr); ierr = PCSetUp(pc); CHKERRQ(ierr); /* Set solver for each velocity component * Split component velocity as parallel blocks along processors * Use direct solver for each block * TODO: use MG, w/FFT on coarse grid */ ierr = PetscTime(&t2); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Finished Solver Setup: %f sec\n",t2-t1); CHKERRQ(ierr); PetscFunctionReturn(0); }