10971522cSBarry Smith /* 20971522cSBarry Smith 30971522cSBarry Smith */ 40971522cSBarry Smith #include "src/ksp/pc/pcimpl.h" /*I "petscpc.h" I*/ 50971522cSBarry Smith 60971522cSBarry Smith typedef struct _PC_FieldSplitLink *PC_FieldSplitLink; 70971522cSBarry Smith struct _PC_FieldSplitLink { 869a612a9SBarry Smith KSP ksp; 90971522cSBarry Smith Vec x,y; 100971522cSBarry Smith PetscInt nfields; 110971522cSBarry Smith PetscInt *fields; 12*1b9fc7fcSBarry Smith VecScatter sctx; 130971522cSBarry Smith PC_FieldSplitLink next; 140971522cSBarry Smith }; 150971522cSBarry Smith 160971522cSBarry Smith typedef struct { 1797bbdb24SBarry Smith PetscTruth defaultsplit; 180971522cSBarry Smith PetscInt bs; 190971522cSBarry Smith PetscInt nsplits; 200971522cSBarry Smith Vec *x,*y; 2197bbdb24SBarry Smith Mat *pmat; 2297bbdb24SBarry Smith IS *is; 2397bbdb24SBarry Smith PC_FieldSplitLink head; 240971522cSBarry Smith } PC_FieldSplit; 250971522cSBarry Smith 260971522cSBarry Smith #undef __FUNCT__ 270971522cSBarry Smith #define __FUNCT__ "PCView_FieldSplit" 280971522cSBarry Smith static PetscErrorCode PCView_FieldSplit(PC pc,PetscViewer viewer) 290971522cSBarry Smith { 300971522cSBarry Smith PC_FieldSplit *jac = (PC_FieldSplit*)pc->data; 310971522cSBarry Smith PetscErrorCode ierr; 320971522cSBarry Smith PetscTruth iascii; 330971522cSBarry Smith PetscInt i,j; 340971522cSBarry Smith PC_FieldSplitLink link = jac->head; 350971522cSBarry Smith 360971522cSBarry Smith PetscFunctionBegin; 370971522cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 380971522cSBarry Smith if (iascii) { 390971522cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," FieldSplit: total splits = %D",jac->nsplits);CHKERRQ(ierr); 4069a612a9SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Solver info for each split is in the following KSP objects:\n");CHKERRQ(ierr); 410971522cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 420971522cSBarry Smith for (i=0; i<jac->nsplits; i++) { 430971522cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Split number %D Fields ",i);CHKERRQ(ierr); 440971522cSBarry Smith for (j=0; j<link->nfields; j++) { 450971522cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D \n",link->fields[j]);CHKERRQ(ierr); 460971522cSBarry Smith } 470971522cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 4869a612a9SBarry Smith ierr = KSPView(link->ksp,viewer);CHKERRQ(ierr); 490971522cSBarry Smith link = link->next; 500971522cSBarry Smith } 510971522cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 520971522cSBarry Smith } else { 530971522cSBarry Smith SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for PCFieldSplit",((PetscObject)viewer)->type_name); 540971522cSBarry Smith } 550971522cSBarry Smith PetscFunctionReturn(0); 560971522cSBarry Smith } 570971522cSBarry Smith 580971522cSBarry Smith #undef __FUNCT__ 5969a612a9SBarry Smith #define __FUNCT__ "PCFieldSplitSetDefaults" 6069a612a9SBarry Smith static PetscErrorCode PCFieldSplitSetDefaults(PC pc) 610971522cSBarry Smith { 620971522cSBarry Smith PC_FieldSplit *jac = (PC_FieldSplit*)pc->data; 630971522cSBarry Smith PetscErrorCode ierr; 640971522cSBarry Smith PC_FieldSplitLink link = jac->head; 6569a612a9SBarry Smith PetscInt i; 660971522cSBarry Smith 670971522cSBarry Smith PetscFunctionBegin; 6869a612a9SBarry Smith /* user has not split fields so use default */ 6969a612a9SBarry Smith if (!link) { 70*1b9fc7fcSBarry Smith ierr = PetscLogInfo(pc,"PCFieldSplitSetDefaults: Using default splitting of fields");CHKERRQ(ierr); 71521d7252SBarry Smith if (jac->bs <= 0) { 72521d7252SBarry Smith ierr = MatGetBlockSize(pc->pmat,&jac->bs);CHKERRQ(ierr); 73521d7252SBarry Smith } 74521d7252SBarry Smith for (i=0; i<jac->bs; i++) { 75521d7252SBarry Smith ierr = PCFieldSplitSetFields(pc,1,&i);CHKERRQ(ierr); 76521d7252SBarry Smith } 77521d7252SBarry Smith link = jac->head; 7897bbdb24SBarry Smith jac->defaultsplit = PETSC_TRUE; 79521d7252SBarry Smith } 8069a612a9SBarry Smith PetscFunctionReturn(0); 8169a612a9SBarry Smith } 8269a612a9SBarry Smith 8369a612a9SBarry Smith 8469a612a9SBarry Smith #undef __FUNCT__ 8569a612a9SBarry Smith #define __FUNCT__ "PCSetUp_FieldSplit" 8669a612a9SBarry Smith static PetscErrorCode PCSetUp_FieldSplit(PC pc) 8769a612a9SBarry Smith { 8869a612a9SBarry Smith PC_FieldSplit *jac = (PC_FieldSplit*)pc->data; 8969a612a9SBarry Smith PetscErrorCode ierr; 9069a612a9SBarry Smith PC_FieldSplitLink link; 9169a612a9SBarry Smith PetscInt i,nsplit; 9269a612a9SBarry Smith MatStructure flag = pc->flag; 9369a612a9SBarry Smith 9469a612a9SBarry Smith PetscFunctionBegin; 9569a612a9SBarry Smith ierr = PCFieldSplitSetDefaults(pc);CHKERRQ(ierr); 9697bbdb24SBarry Smith nsplit = jac->nsplits; 9769a612a9SBarry Smith link = jac->head; 9897bbdb24SBarry Smith 9997bbdb24SBarry Smith /* get the matrices for each split */ 10097bbdb24SBarry Smith if (!jac->is) { 101*1b9fc7fcSBarry Smith PetscInt rstart,rend,nslots,bs; 10297bbdb24SBarry Smith 103*1b9fc7fcSBarry Smith ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 10497bbdb24SBarry Smith ierr = MatGetOwnershipRange(pc->pmat,&rstart,&rend);CHKERRQ(ierr); 105*1b9fc7fcSBarry Smith nslots = (rend - rstart)/bs; 106*1b9fc7fcSBarry Smith ierr = PetscMalloc(nsplit*sizeof(IS),&jac->is);CHKERRQ(ierr); 107*1b9fc7fcSBarry Smith for (i=0; i<nsplit; i++) { 108*1b9fc7fcSBarry Smith if (jac->defaultsplit) { 109*1b9fc7fcSBarry Smith ierr = ISCreateStride(pc->comm,nslots,rstart+i,nsplit,&jac->is[i]);CHKERRQ(ierr); 11097bbdb24SBarry Smith } else { 111*1b9fc7fcSBarry Smith PetscInt *ii,j,k,nfields = link->nfields,*fields = link->fields; 112*1b9fc7fcSBarry Smith PetscTruth sorted; 113*1b9fc7fcSBarry Smith ierr = PetscMalloc(link->nfields*nslots*sizeof(PetscInt),&ii);CHKERRQ(ierr); 114*1b9fc7fcSBarry Smith for (j=0; j<nslots; j++) { 115*1b9fc7fcSBarry Smith for (k=0; k<nfields; k++) { 116*1b9fc7fcSBarry Smith ii[nfields*j + k] = rstart + bs*j + fields[k]; 11797bbdb24SBarry Smith } 11897bbdb24SBarry Smith } 119*1b9fc7fcSBarry Smith ierr = ISCreateGeneral(pc->comm,nslots*nfields,ii,&jac->is[i]);CHKERRQ(ierr); 120*1b9fc7fcSBarry Smith ierr = ISSorted(jac->is[i],&sorted);CHKERRQ(ierr); 121*1b9fc7fcSBarry Smith if (!sorted) SETERRQ(PETSC_ERR_USER,"Fields must be sorted when creating split"); 122*1b9fc7fcSBarry Smith ierr = PetscFree(ii);CHKERRQ(ierr); 123*1b9fc7fcSBarry Smith link = link->next; 124*1b9fc7fcSBarry Smith } 125*1b9fc7fcSBarry Smith } 126*1b9fc7fcSBarry Smith } 127*1b9fc7fcSBarry Smith 12897bbdb24SBarry Smith if (!jac->pmat) { 12997bbdb24SBarry Smith ierr = MatGetSubMatrices(pc->pmat,nsplit,jac->is,jac->is,MAT_INITIAL_MATRIX,&jac->pmat);CHKERRQ(ierr); 13097bbdb24SBarry Smith } else { 13197bbdb24SBarry Smith ierr = MatGetSubMatrices(pc->pmat,nsplit,jac->is,jac->is,MAT_REUSE_MATRIX,&jac->pmat);CHKERRQ(ierr); 13297bbdb24SBarry Smith } 13397bbdb24SBarry Smith 13497bbdb24SBarry Smith /* set up the individual PCs */ 13597bbdb24SBarry Smith i = 0; 136*1b9fc7fcSBarry Smith link = jac->head; 1370971522cSBarry Smith while (link) { 13869a612a9SBarry Smith ierr = KSPSetOperators(link->ksp,jac->pmat[i],jac->pmat[i],flag);CHKERRQ(ierr); 13969a612a9SBarry Smith ierr = KSPSetFromOptions(link->ksp);CHKERRQ(ierr); 14069a612a9SBarry Smith ierr = KSPSetUp(link->ksp);CHKERRQ(ierr); 14197bbdb24SBarry Smith i++; 1420971522cSBarry Smith link = link->next; 1430971522cSBarry Smith } 14497bbdb24SBarry Smith 14597bbdb24SBarry Smith /* create work vectors for each split */ 146*1b9fc7fcSBarry Smith if (!jac->x) { 14797bbdb24SBarry Smith ierr = PetscMalloc2(nsplit,Vec,&jac->x,nsplit,Vec,&jac->y);CHKERRQ(ierr); 14897bbdb24SBarry Smith link = jac->head; 14997bbdb24SBarry Smith for (i=0; i<nsplit; i++) { 15097bbdb24SBarry Smith Mat A; 15169a612a9SBarry Smith ierr = KSPGetOperators(link->ksp,PETSC_NULL,&A,PETSC_NULL);CHKERRQ(ierr); 15297bbdb24SBarry Smith ierr = MatGetVecs(A,&link->x,&link->y);CHKERRQ(ierr); 15397bbdb24SBarry Smith jac->x[i] = link->x; 15497bbdb24SBarry Smith jac->y[i] = link->y; 15597bbdb24SBarry Smith link = link->next; 15697bbdb24SBarry Smith } 157*1b9fc7fcSBarry Smith if (!jac->defaultsplit) { 158*1b9fc7fcSBarry Smith Vec xtmp; 159*1b9fc7fcSBarry Smith 160*1b9fc7fcSBarry Smith link = jac->head; 161*1b9fc7fcSBarry Smith ierr = MatGetVecs(pc->pmat,&xtmp,PETSC_NULL);CHKERRQ(ierr); 162*1b9fc7fcSBarry Smith for (i=0; i<nsplit; i++) { 163*1b9fc7fcSBarry Smith ierr = VecScatterCreate(xtmp,jac->is[i],jac->x[i],PETSC_NULL,&link->sctx);CHKERRQ(ierr); 164*1b9fc7fcSBarry Smith link = link->next; 165*1b9fc7fcSBarry Smith } 166*1b9fc7fcSBarry Smith ierr = VecDestroy(xtmp);CHKERRQ(ierr); 167*1b9fc7fcSBarry Smith } 16897bbdb24SBarry Smith } 1690971522cSBarry Smith PetscFunctionReturn(0); 1700971522cSBarry Smith } 1710971522cSBarry Smith 1720971522cSBarry Smith #undef __FUNCT__ 1730971522cSBarry Smith #define __FUNCT__ "PCApply_FieldSplit" 1740971522cSBarry Smith static PetscErrorCode PCApply_FieldSplit(PC pc,Vec x,Vec y) 1750971522cSBarry Smith { 1760971522cSBarry Smith PC_FieldSplit *jac = (PC_FieldSplit*)pc->data; 1770971522cSBarry Smith PetscErrorCode ierr; 1780971522cSBarry Smith PC_FieldSplitLink link = jac->head; 1790971522cSBarry Smith 1800971522cSBarry Smith PetscFunctionBegin; 181*1b9fc7fcSBarry Smith if (jac->defaultsplit) { 1820971522cSBarry Smith ierr = VecStrideGatherAll(x,jac->x,INSERT_VALUES);CHKERRQ(ierr); 1830971522cSBarry Smith while (link) { 18469a612a9SBarry Smith ierr = KSPSolve(link->ksp,link->x,link->y);CHKERRQ(ierr); 1850971522cSBarry Smith link = link->next; 1860971522cSBarry Smith } 1870971522cSBarry Smith ierr = VecStrideScatterAll(jac->y,y,INSERT_VALUES);CHKERRQ(ierr); 188*1b9fc7fcSBarry Smith } else { 189*1b9fc7fcSBarry Smith PetscScalar zero = 0.0; 190*1b9fc7fcSBarry Smith PetscInt i = 0; 191*1b9fc7fcSBarry Smith 192*1b9fc7fcSBarry Smith ierr = VecSet(&zero,y);CHKERRQ(ierr); 193*1b9fc7fcSBarry Smith while (link) { 194*1b9fc7fcSBarry Smith ierr = VecScatterBegin(x,link->x,INSERT_VALUES,SCATTER_FORWARD,link->sctx);CHKERRQ(ierr); 195*1b9fc7fcSBarry Smith ierr = VecScatterEnd(x,link->x,INSERT_VALUES,SCATTER_FORWARD,link->sctx);CHKERRQ(ierr); 196*1b9fc7fcSBarry Smith ierr = KSPSolve(link->ksp,link->x,link->y);CHKERRQ(ierr); 197*1b9fc7fcSBarry Smith ierr = VecScatterBegin(link->y,y,ADD_VALUES,SCATTER_REVERSE,link->sctx);CHKERRQ(ierr); 198*1b9fc7fcSBarry Smith ierr = VecScatterEnd(y,link->y,ADD_VALUES,SCATTER_REVERSE,link->sctx);CHKERRQ(ierr); 199*1b9fc7fcSBarry Smith 200*1b9fc7fcSBarry Smith link = link->next; 201*1b9fc7fcSBarry Smith i++; 202*1b9fc7fcSBarry Smith } 203*1b9fc7fcSBarry Smith } 2040971522cSBarry Smith PetscFunctionReturn(0); 2050971522cSBarry Smith } 2060971522cSBarry Smith 2070971522cSBarry Smith #undef __FUNCT__ 2080971522cSBarry Smith #define __FUNCT__ "PCDestroy_FieldSplit" 2090971522cSBarry Smith static PetscErrorCode PCDestroy_FieldSplit(PC pc) 2100971522cSBarry Smith { 2110971522cSBarry Smith PC_FieldSplit *jac = (PC_FieldSplit*)pc->data; 2120971522cSBarry Smith PetscErrorCode ierr; 21397bbdb24SBarry Smith PC_FieldSplitLink link = jac->head,next; 2140971522cSBarry Smith 2150971522cSBarry Smith PetscFunctionBegin; 2160971522cSBarry Smith while (link) { 21769a612a9SBarry Smith ierr = KSPDestroy(link->ksp);CHKERRQ(ierr); 21869a612a9SBarry Smith if (link->x) {ierr = VecDestroy(link->x);CHKERRQ(ierr);} 21969a612a9SBarry Smith if (link->y) {ierr = VecDestroy(link->y);CHKERRQ(ierr);} 220*1b9fc7fcSBarry Smith if (link->sctx) {ierr = VecScatterDestroy(link->sctx);CHKERRQ(ierr);} 22197bbdb24SBarry Smith next = link->next; 2220971522cSBarry Smith ierr = PetscFree2(link,link->fields);CHKERRQ(ierr); 22397bbdb24SBarry Smith link = next; 2240971522cSBarry Smith } 2250971522cSBarry Smith if (jac->x) {ierr = PetscFree2(jac->x,jac->y);CHKERRQ(ierr);} 22697bbdb24SBarry Smith if (jac->pmat) {ierr = MatDestroyMatrices(jac->nsplits,&jac->pmat);CHKERRQ(ierr);} 22797bbdb24SBarry Smith if (jac->is) { 22897bbdb24SBarry Smith PetscInt i; 22997bbdb24SBarry Smith for (i=0; i<jac->nsplits; i++) {ierr = ISDestroy(jac->is[i]);CHKERRQ(ierr);} 23097bbdb24SBarry Smith ierr = PetscFree(jac->is);CHKERRQ(ierr); 23197bbdb24SBarry Smith } 2320971522cSBarry Smith ierr = PetscFree(jac);CHKERRQ(ierr); 2330971522cSBarry Smith PetscFunctionReturn(0); 2340971522cSBarry Smith } 2350971522cSBarry Smith 2360971522cSBarry Smith #undef __FUNCT__ 2370971522cSBarry Smith #define __FUNCT__ "PCSetFromOptions_FieldSplit" 2380971522cSBarry Smith static PetscErrorCode PCSetFromOptions_FieldSplit(PC pc) 239*1b9fc7fcSBarry Smith /* This does not call KSPSetFromOptions() on the subksp's, see PCSetFromOptionsBJacobi/ASM() */ 2400971522cSBarry Smith { 241*1b9fc7fcSBarry Smith PetscErrorCode ierr; 242*1b9fc7fcSBarry Smith PetscInt i = 0,nfields,fields[12]; 243*1b9fc7fcSBarry Smith PetscTruth flg; 244*1b9fc7fcSBarry Smith char optionname[128]; 245*1b9fc7fcSBarry Smith 2460971522cSBarry Smith PetscFunctionBegin; 247*1b9fc7fcSBarry Smith ierr = PetscOptionsHead("FieldSplit options");CHKERRQ(ierr); 248*1b9fc7fcSBarry Smith while (PETSC_TRUE) { 249*1b9fc7fcSBarry Smith sprintf(optionname,"-pc_fieldsplit_%d_fields",i++); 250*1b9fc7fcSBarry Smith nfields = 12; 251*1b9fc7fcSBarry Smith ierr = PetscOptionsIntArray(optionname,"Fields in this split","PCFieldSplitSetFields",fields,&nfields,&flg);CHKERRQ(ierr); 252*1b9fc7fcSBarry Smith if (!flg) break; 253*1b9fc7fcSBarry Smith if (!nfields) SETERRQ(PETSC_ERR_USER,"Cannot list zero fields"); 254*1b9fc7fcSBarry Smith ierr = PCFieldSplitSetFields(pc,nfields,fields);CHKERRQ(ierr); 255*1b9fc7fcSBarry Smith } 256*1b9fc7fcSBarry Smith ierr = PetscOptionsTail();CHKERRQ(ierr); 2570971522cSBarry Smith PetscFunctionReturn(0); 2580971522cSBarry Smith } 2590971522cSBarry Smith 2600971522cSBarry Smith /*------------------------------------------------------------------------------------*/ 2610971522cSBarry Smith 2620971522cSBarry Smith EXTERN_C_BEGIN 2630971522cSBarry Smith #undef __FUNCT__ 2640971522cSBarry Smith #define __FUNCT__ "PCFieldSplitSetFields_FieldSplit" 2650971522cSBarry Smith PetscErrorCode PCFieldSplitSetFields_FieldSplit(PC pc,PetscInt n,PetscInt *fields) 2660971522cSBarry Smith { 26797bbdb24SBarry Smith PC_FieldSplit *jac = (PC_FieldSplit*)pc->data; 2680971522cSBarry Smith PetscErrorCode ierr; 2690971522cSBarry Smith PC_FieldSplitLink link,next = jac->head; 27069a612a9SBarry Smith char prefix[128]; 2710971522cSBarry Smith 2720971522cSBarry Smith PetscFunctionBegin; 2730971522cSBarry Smith if (n <= 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative number of fields requested"); 27497bbdb24SBarry Smith ierr = PetscMalloc2(1,struct _PC_FieldSplitLink,&link,n,PetscInt,&link->fields);CHKERRQ(ierr); 27597bbdb24SBarry Smith ierr = PetscMemcpy(link->fields,fields,n*sizeof(PetscInt));CHKERRQ(ierr); 2760971522cSBarry Smith link->nfields = n; 27797bbdb24SBarry Smith link->next = PETSC_NULL; 27869a612a9SBarry Smith ierr = KSPCreate(pc->comm,&link->ksp);CHKERRQ(ierr); 27969a612a9SBarry Smith ierr = KSPSetType(link->ksp,KSPPREONLY);CHKERRQ(ierr); 28069a612a9SBarry Smith 28169a612a9SBarry Smith if (pc->prefix) { 28269a612a9SBarry Smith sprintf(prefix,"%s_fieldsplit_%d_",pc->prefix,jac->nsplits); 28369a612a9SBarry Smith } else { 28469a612a9SBarry Smith sprintf(prefix,"fieldsplit_%d_",jac->nsplits); 28569a612a9SBarry Smith } 28669a612a9SBarry Smith ierr = KSPSetOptionsPrefix(link->ksp,prefix);CHKERRQ(ierr); 2870971522cSBarry Smith 2880971522cSBarry Smith if (!next) { 2890971522cSBarry Smith jac->head = link; 2900971522cSBarry Smith } else { 2910971522cSBarry Smith while (next->next) { 2920971522cSBarry Smith next = next->next; 2930971522cSBarry Smith } 2940971522cSBarry Smith next->next = link; 2950971522cSBarry Smith } 2960971522cSBarry Smith jac->nsplits++; 2970971522cSBarry Smith PetscFunctionReturn(0); 2980971522cSBarry Smith } 2990971522cSBarry Smith EXTERN_C_END 3000971522cSBarry Smith 3010971522cSBarry Smith 3020971522cSBarry Smith EXTERN_C_BEGIN 3030971522cSBarry Smith #undef __FUNCT__ 30469a612a9SBarry Smith #define __FUNCT__ "PCFieldSplitGetSubKSP_FieldSplit" 30569a612a9SBarry Smith PetscErrorCode PCFieldSplitGetSubKSP_FieldSplit(PC pc,PetscInt *n,KSP **subksp) 3060971522cSBarry Smith { 3070971522cSBarry Smith PC_FieldSplit *jac = (PC_FieldSplit*)pc->data; 3080971522cSBarry Smith PetscErrorCode ierr; 3090971522cSBarry Smith PetscInt cnt = 0; 3100971522cSBarry Smith PC_FieldSplitLink link; 3110971522cSBarry Smith 3120971522cSBarry Smith PetscFunctionBegin; 31369a612a9SBarry Smith ierr = PetscMalloc(jac->nsplits*sizeof(KSP*),subksp);CHKERRQ(ierr); 3140971522cSBarry Smith while (link) { 31569a612a9SBarry Smith (*subksp)[cnt++] = link->ksp; 3160971522cSBarry Smith link = link->next; 3170971522cSBarry Smith } 3180971522cSBarry Smith if (cnt != jac->nsplits) SETERRQ2(PETSC_ERR_PLIB,"Corrupt PCFIELDSPLIT object: number splits in linked list %D in object %D",cnt,jac->nsplits); 3190971522cSBarry Smith *n = jac->nsplits; 3200971522cSBarry Smith PetscFunctionReturn(0); 3210971522cSBarry Smith } 3220971522cSBarry Smith EXTERN_C_END 3230971522cSBarry Smith 3240971522cSBarry Smith #undef __FUNCT__ 3250971522cSBarry Smith #define __FUNCT__ "PCFieldSplitSetFields" 3260971522cSBarry Smith /*@ 3270971522cSBarry Smith PCFieldSplitSetFields - Sets the fields for one particular split in the field split preconditioner 3280971522cSBarry Smith 3290971522cSBarry Smith Collective on PC 3300971522cSBarry Smith 3310971522cSBarry Smith Input Parameters: 3320971522cSBarry Smith + pc - the preconditioner context 3330971522cSBarry Smith . n - the number of fields in this split 3340971522cSBarry Smith . fields - the fields in this split 3350971522cSBarry Smith 3360971522cSBarry Smith Level: intermediate 3370971522cSBarry Smith 33869a612a9SBarry Smith .seealso: PCFieldSplitGetSubKSP(), PCFIELDSPLIT 3390971522cSBarry Smith 3400971522cSBarry Smith @*/ 3410971522cSBarry Smith PetscErrorCode PCFieldSplitSetFields(PC pc,PetscInt n, PetscInt *fields) 3420971522cSBarry Smith { 3430971522cSBarry Smith PetscErrorCode ierr,(*f)(PC,PetscInt,PetscInt *); 3440971522cSBarry Smith 3450971522cSBarry Smith PetscFunctionBegin; 3460971522cSBarry Smith PetscValidHeaderSpecific(pc,PC_COOKIE,1); 3470971522cSBarry Smith ierr = PetscObjectQueryFunction((PetscObject)pc,"PCFieldSplitSetFields_C",(void (**)(void))&f);CHKERRQ(ierr); 3480971522cSBarry Smith if (f) { 3490971522cSBarry Smith ierr = (*f)(pc,n,fields);CHKERRQ(ierr); 3500971522cSBarry Smith } 3510971522cSBarry Smith PetscFunctionReturn(0); 3520971522cSBarry Smith } 3530971522cSBarry Smith 3540971522cSBarry Smith #undef __FUNCT__ 35569a612a9SBarry Smith #define __FUNCT__ "PCFieldSplitGetSubKSP" 3560971522cSBarry Smith /*@C 35769a612a9SBarry Smith PCFieldSplitGetSubKSP - Gets the KSP contexts for all splits 3580971522cSBarry Smith 35969a612a9SBarry Smith Collective on KSP 3600971522cSBarry Smith 3610971522cSBarry Smith Input Parameter: 3620971522cSBarry Smith . pc - the preconditioner context 3630971522cSBarry Smith 3640971522cSBarry Smith Output Parameters: 3650971522cSBarry Smith + n - the number of split 36669a612a9SBarry Smith - pc - the array of KSP contexts 3670971522cSBarry Smith 3680971522cSBarry Smith Note: 36969a612a9SBarry Smith After PCFieldSplitGetSubKSP() the array of KSPs IS to be freed 3700971522cSBarry Smith 37169a612a9SBarry Smith You must call KSPSetUp() before calling PCFieldSplitGetSubKSP(). 3720971522cSBarry Smith 3730971522cSBarry Smith Level: advanced 3740971522cSBarry Smith 3750971522cSBarry Smith .seealso: PCFIELDSPLIT 3760971522cSBarry Smith @*/ 37769a612a9SBarry Smith PetscErrorCode PCFieldSplitGetSubKSP(PC pc,PetscInt *n,KSP *subksp[]) 3780971522cSBarry Smith { 37969a612a9SBarry Smith PetscErrorCode ierr,(*f)(PC,PetscInt*,KSP **); 3800971522cSBarry Smith 3810971522cSBarry Smith PetscFunctionBegin; 3820971522cSBarry Smith PetscValidHeaderSpecific(pc,PC_COOKIE,1); 3830971522cSBarry Smith PetscValidIntPointer(n,2); 38469a612a9SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)pc,"PCFieldSplitGetSubKSP_C",(void (**)(void))&f);CHKERRQ(ierr); 3850971522cSBarry Smith if (f) { 38669a612a9SBarry Smith ierr = (*f)(pc,n,subksp);CHKERRQ(ierr); 3870971522cSBarry Smith } else { 38869a612a9SBarry Smith SETERRQ(PETSC_ERR_ARG_WRONG,"Cannot get subksp for this type of PC"); 3890971522cSBarry Smith } 3900971522cSBarry Smith PetscFunctionReturn(0); 3910971522cSBarry Smith } 3920971522cSBarry Smith 3930971522cSBarry Smith /* -------------------------------------------------------------------------------------*/ 3940971522cSBarry Smith /*MC 3950971522cSBarry Smith PCFieldSplit - Preconditioner created by combining seperate preconditioners for individual 3960971522cSBarry Smith fields or groups of fields 3970971522cSBarry Smith 3980971522cSBarry Smith 3990971522cSBarry Smith To set options on the solvers for each block append -sub_ to all the PC 4000971522cSBarry Smith options database keys. For example, -sub_pc_type ilu -sub_pc_ilu_levels 1 4010971522cSBarry Smith 40269a612a9SBarry Smith To set the options on the solvers seperate for each block call PCFieldSplitGetSubKSP() 40369a612a9SBarry Smith and set the options directly on the resulting KSP object 4040971522cSBarry Smith 4050971522cSBarry Smith Level: intermediate 4060971522cSBarry Smith 4070971522cSBarry Smith Concepts: physics based preconditioners 4080971522cSBarry Smith 4090971522cSBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 41069a612a9SBarry Smith PCFieldSplitGetSubKSP(), PCFieldSplitSetFields() 4110971522cSBarry Smith M*/ 4120971522cSBarry Smith 4130971522cSBarry Smith EXTERN_C_BEGIN 4140971522cSBarry Smith #undef __FUNCT__ 4150971522cSBarry Smith #define __FUNCT__ "PCCreate_FieldSplit" 4160971522cSBarry Smith PetscErrorCode PCCreate_FieldSplit(PC pc) 4170971522cSBarry Smith { 4180971522cSBarry Smith PetscErrorCode ierr; 4190971522cSBarry Smith PC_FieldSplit *jac; 4200971522cSBarry Smith 4210971522cSBarry Smith PetscFunctionBegin; 4220971522cSBarry Smith ierr = PetscNew(PC_FieldSplit,&jac);CHKERRQ(ierr); 4230971522cSBarry Smith PetscLogObjectMemory(pc,sizeof(PC_FieldSplit)); 4240971522cSBarry Smith ierr = PetscMemzero(jac,sizeof(PC_FieldSplit));CHKERRQ(ierr); 4250971522cSBarry Smith jac->bs = -1; 4260971522cSBarry Smith jac->nsplits = 0; 4270971522cSBarry Smith pc->data = (void*)jac; 4280971522cSBarry Smith 4290971522cSBarry Smith pc->ops->apply = PCApply_FieldSplit; 4300971522cSBarry Smith pc->ops->setup = PCSetUp_FieldSplit; 4310971522cSBarry Smith pc->ops->destroy = PCDestroy_FieldSplit; 4320971522cSBarry Smith pc->ops->setfromoptions = PCSetFromOptions_FieldSplit; 4330971522cSBarry Smith pc->ops->view = PCView_FieldSplit; 4340971522cSBarry Smith pc->ops->applyrichardson = 0; 4350971522cSBarry Smith 43669a612a9SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFieldSplitGetSubKSP_C","PCFieldSplitGetSubKSP_FieldSplit", 43769a612a9SBarry Smith PCFieldSplitGetSubKSP_FieldSplit);CHKERRQ(ierr); 4380971522cSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFieldSplitSetFields_C","PCFieldSplitSetFields_FieldSplit", 4390971522cSBarry Smith PCFieldSplitSetFields_FieldSplit);CHKERRQ(ierr); 4400971522cSBarry Smith PetscFunctionReturn(0); 4410971522cSBarry Smith } 4420971522cSBarry Smith EXTERN_C_END 4430971522cSBarry Smith 4440971522cSBarry Smith 445