fieldsplit.c (207126cb90d7f2cb72e2179925bb8d6adc164b40) fieldsplit.c (d32f9abdbc052d6e1fd06679b17a55415c3aae30)
1#define PETSCKSP_DLL
2
3/*
4
5*/
6#include "private/pcimpl.h" /*I "petscpc.h" I*/
7
8typedef struct _PC_FieldSplitLink *PC_FieldSplitLink;

--- 67 unchanged lines hidden (view full) ---

76
77#undef __FUNCT__
78#define __FUNCT__ "PCFieldSplitSetDefaults"
79static PetscErrorCode PCFieldSplitSetDefaults(PC pc)
80{
81 PC_FieldSplit *jac = (PC_FieldSplit*)pc->data;
82 PetscErrorCode ierr;
83 PC_FieldSplitLink ilink = jac->head;
1#define PETSCKSP_DLL
2
3/*
4
5*/
6#include "private/pcimpl.h" /*I "petscpc.h" I*/
7
8typedef struct _PC_FieldSplitLink *PC_FieldSplitLink;

--- 67 unchanged lines hidden (view full) ---

76
77#undef __FUNCT__
78#define __FUNCT__ "PCFieldSplitSetDefaults"
79static PetscErrorCode PCFieldSplitSetDefaults(PC pc)
80{
81 PC_FieldSplit *jac = (PC_FieldSplit*)pc->data;
82 PetscErrorCode ierr;
83 PC_FieldSplitLink ilink = jac->head;
84 PetscInt i;
85 PetscTruth flg = PETSC_FALSE,*fields;
84 PetscInt i = 0,*ifields,nfields;
85 PetscTruth flg = PETSC_FALSE,*fields,flg2;
86 char optionname[128];
86
87 PetscFunctionBegin;
87
88 PetscFunctionBegin;
88 ierr = PetscOptionsGetTruth(((PetscObject)pc)->prefix,"-pc_fieldsplit_default",&flg,PETSC_NULL);CHKERRQ(ierr);
89 if (!ilink || flg) {
90 ierr = PetscInfo(pc,"Using default splitting of fields\n");CHKERRQ(ierr);
89 if (!ilink) {
90
91 if (jac->bs <= 0) {
92 if (pc->pmat) {
93 ierr = MatGetBlockSize(pc->pmat,&jac->bs);CHKERRQ(ierr);
94 } else {
95 jac->bs = 1;
96 }
97 }
91 if (jac->bs <= 0) {
92 if (pc->pmat) {
93 ierr = MatGetBlockSize(pc->pmat,&jac->bs);CHKERRQ(ierr);
94 } else {
95 jac->bs = 1;
96 }
97 }
98 ierr = PetscMalloc(jac->bs*sizeof(PetscTruth),&fields);CHKERRQ(ierr);
99 ierr = PetscMemzero(fields,jac->bs*sizeof(PetscTruth));CHKERRQ(ierr);
100 while (ilink) {
101 for (i=0; i<ilink->nfields; i++) {
102 fields[ilink->fields[i]] = PETSC_TRUE;
98
99 ierr = PetscOptionsGetTruth(((PetscObject)pc)->prefix,"-pc_fieldsplit_default",&flg,PETSC_NULL);CHKERRQ(ierr);
100 if (!flg) {
101 /* Allow user to set fields from command line, if bs was known at the time of PCSetFromOptions_FieldSplit()
102 then it is set there. This is not ideal because we should only have options set in XXSetFromOptions(). */
103 flg = PETSC_TRUE; /* switched off automatically if user sets fields manually here */
104 ierr = PetscMalloc(jac->bs*sizeof(PetscInt),&ifields);CHKERRQ(ierr);
105 while (PETSC_TRUE) {
106 sprintf(optionname,"-pc_fieldsplit_%d_fields",(int)i++);
107 nfields = jac->bs;
108 ierr = PetscOptionsGetIntArray(((PetscObject)pc)->prefix,optionname,ifields,&nfields,&flg2);CHKERRQ(ierr);
109 if (!flg2) break;
110 if (!nfields) SETERRQ(PETSC_ERR_USER,"Cannot list zero fields");
111 flg = PETSC_FALSE;
112 ierr = PCFieldSplitSetFields(pc,nfields,ifields);CHKERRQ(ierr);
103 }
113 }
104 ilink = ilink->next;
114 ierr = PetscFree(ifields);CHKERRQ(ierr);
105 }
115 }
106 jac->defaultsplit = PETSC_TRUE;
107 for (i=0; i<jac->bs; i++) {
108 if (!fields[i]) {
109 ierr = PCFieldSplitSetFields(pc,1,&i);CHKERRQ(ierr);
110 } else {
111 jac->defaultsplit = PETSC_FALSE;
116
117 if (flg) {
118 ierr = PetscInfo(pc,"Using default splitting of fields\n");CHKERRQ(ierr);
119 ierr = PetscMalloc(jac->bs*sizeof(PetscTruth),&fields);CHKERRQ(ierr);
120 ierr = PetscMemzero(fields,jac->bs*sizeof(PetscTruth));CHKERRQ(ierr);
121 while (ilink) {
122 for (i=0; i<ilink->nfields; i++) {
123 fields[ilink->fields[i]] = PETSC_TRUE;
124 }
125 ilink = ilink->next;
112 }
126 }
127 jac->defaultsplit = PETSC_TRUE;
128 for (i=0; i<jac->bs; i++) {
129 if (!fields[i]) {
130 ierr = PCFieldSplitSetFields(pc,1,&i);CHKERRQ(ierr);
131 } else {
132 jac->defaultsplit = PETSC_FALSE;
133 }
134 }
113 }
114 }
115 PetscFunctionReturn(0);
116}
117
118
119#undef __FUNCT__
120#define __FUNCT__ "PCSetUp_FieldSplit"

--- 281 unchanged lines hidden (view full) ---

402 PC_FieldSplit *jac = (PC_FieldSplit*)pc->data;
403
404 PetscFunctionBegin;
405 ierr = PetscOptionsHead("FieldSplit options");CHKERRQ(ierr);
406 ierr = PetscOptionsInt("-pc_fieldsplit_block_size","Blocksize that defines number of fields","PCFieldSplitSetBlockSize",jac->bs,&bs,&flg);CHKERRQ(ierr);
407 if (flg) {
408 ierr = PCFieldSplitSetBlockSize(pc,bs);CHKERRQ(ierr);
409 }
135 }
136 }
137 PetscFunctionReturn(0);
138}
139
140
141#undef __FUNCT__
142#define __FUNCT__ "PCSetUp_FieldSplit"

--- 281 unchanged lines hidden (view full) ---

424 PC_FieldSplit *jac = (PC_FieldSplit*)pc->data;
425
426 PetscFunctionBegin;
427 ierr = PetscOptionsHead("FieldSplit options");CHKERRQ(ierr);
428 ierr = PetscOptionsInt("-pc_fieldsplit_block_size","Blocksize that defines number of fields","PCFieldSplitSetBlockSize",jac->bs,&bs,&flg);CHKERRQ(ierr);
429 if (flg) {
430 ierr = PCFieldSplitSetBlockSize(pc,bs);CHKERRQ(ierr);
431 }
410 if (jac->bs <= 0) {
411
412 ierr = PCFieldSplitSetBlockSize(pc,1);CHKERRQ(ierr);
413 }
432
414 ierr = PetscOptionsEnum("-pc_fieldsplit_type","Type of composition","PCFieldSplitSetType",PCCompositeTypes,(PetscEnum)jac->type,(PetscEnum*)&jac->type,&flg);CHKERRQ(ierr);
433 ierr = PetscOptionsEnum("-pc_fieldsplit_type","Type of composition","PCFieldSplitSetType",PCCompositeTypes,(PetscEnum)jac->type,(PetscEnum*)&jac->type,&flg);CHKERRQ(ierr);
415 ierr = PetscMalloc(jac->bs*sizeof(PetscInt),&fields);CHKERRQ(ierr);
416 while (PETSC_TRUE) {
417 sprintf(optionname,"-pc_fieldsplit_%d_fields",(int)i++);
418 nfields = jac->bs;
419 ierr = PetscOptionsIntArray(optionname,"Fields in this split","PCFieldSplitSetFields",fields,&nfields,&flg);CHKERRQ(ierr);
420 if (!flg) break;
421 if (!nfields) SETERRQ(PETSC_ERR_USER,"Cannot list zero fields");
422 ierr = PCFieldSplitSetFields(pc,nfields,fields);CHKERRQ(ierr);
434
435 if (jac->bs > 0) {
436 /* only allow user to set fields from command line if bs is already known.
437 otherwise user can set them in PCFieldSplitSetDefaults() */
438 ierr = PetscMalloc(jac->bs*sizeof(PetscInt),&fields);CHKERRQ(ierr);
439 while (PETSC_TRUE) {
440 sprintf(optionname,"-pc_fieldsplit_%d_fields",(int)i++);
441 nfields = jac->bs;
442 ierr = PetscOptionsIntArray(optionname,"Fields in this split","PCFieldSplitSetFields",fields,&nfields,&flg);CHKERRQ(ierr);
443 if (!flg) break;
444 if (!nfields) SETERRQ(PETSC_ERR_USER,"Cannot list zero fields");
445 ierr = PCFieldSplitSetFields(pc,nfields,fields);CHKERRQ(ierr);
446 }
447 ierr = PetscFree(fields);CHKERRQ(ierr);
423 }
448 }
424 ierr = PetscFree(fields);CHKERRQ(ierr);
425 ierr = PetscOptionsTail();CHKERRQ(ierr);
426 PetscFunctionReturn(0);
427}
428
429/*------------------------------------------------------------------------------------*/
430
431EXTERN_C_BEGIN
432#undef __FUNCT__

--- 115 unchanged lines hidden (view full) ---

548
549 Input Parameters:
550+ pc - the preconditioner context
551. n - the number of fields in this split
552. fields - the fields in this split
553
554 Level: intermediate
555
449 ierr = PetscOptionsTail();CHKERRQ(ierr);
450 PetscFunctionReturn(0);
451}
452
453/*------------------------------------------------------------------------------------*/
454
455EXTERN_C_BEGIN
456#undef __FUNCT__

--- 115 unchanged lines hidden (view full) ---

572
573 Input Parameters:
574+ pc - the preconditioner context
575. n - the number of fields in this split
576. fields - the fields in this split
577
578 Level: intermediate
579
556.seealso: PCFieldSplitGetSubKSP(), PCFIELDSPLIT, PCFieldSplitSetBlockSize()
580 Notes: Use PCFieldSplitSetIS() to set a completely general set of indices as a field.
557
581
582 The PCFieldSplitSetFields() is for defining fields as a strided blocks. For example, if the block
583 size is three then one can define a field as 0, or 1 or 2 or 0,1 or 0,2 or 1,2 which mean
584 0xx3xx6xx9xx12 ... x1xx4xx7xx ... xx2xx5xx8xx.. 01x34x67x... 0x1x3x5x7.. x12x45x78x....
585 where the numbered entries indicate what is in the field.
586
587.seealso: PCFieldSplitGetSubKSP(), PCFIELDSPLIT, PCFieldSplitSetBlockSize(), PCFieldSplitSetIS()
588
558@*/
559PetscErrorCode PETSCKSP_DLLEXPORT PCFieldSplitSetFields(PC pc,PetscInt n, PetscInt *fields)
560{
561 PetscErrorCode ierr,(*f)(PC,PetscInt,PetscInt *);
562
563 PetscFunctionBegin;
564 PetscValidHeaderSpecific(pc,PC_COOKIE,1);
565 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCFieldSplitSetFields_C",(void (**)(void))&f);CHKERRQ(ierr);

--- 9 unchanged lines hidden (view full) ---

575 PCFieldSplitSetIS - Sets the exact elements for field
576
577 Collective on PC
578
579 Input Parameters:
580+ pc - the preconditioner context
581. is - the index set that defines the vector elements in this field
582
589@*/
590PetscErrorCode PETSCKSP_DLLEXPORT PCFieldSplitSetFields(PC pc,PetscInt n, PetscInt *fields)
591{
592 PetscErrorCode ierr,(*f)(PC,PetscInt,PetscInt *);
593
594 PetscFunctionBegin;
595 PetscValidHeaderSpecific(pc,PC_COOKIE,1);
596 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCFieldSplitSetFields_C",(void (**)(void))&f);CHKERRQ(ierr);

--- 9 unchanged lines hidden (view full) ---

606 PCFieldSplitSetIS - Sets the exact elements for field
607
608 Collective on PC
609
610 Input Parameters:
611+ pc - the preconditioner context
612. is - the index set that defines the vector elements in this field
613
614
615 Notes: Use PCFieldSplitSetFields(), for fields defined by strided types.
616
583 Level: intermediate
584
585.seealso: PCFieldSplitGetSubKSP(), PCFIELDSPLIT, PCFieldSplitSetBlockSize()
586
587@*/
588PetscErrorCode PETSCKSP_DLLEXPORT PCFieldSplitSetIS(PC pc,IS is)
589{
590 PetscErrorCode ierr,(*f)(PC,IS);

--- 48 unchanged lines hidden (view full) ---

639 Input Parameter:
640. pc - the preconditioner context
641
642 Output Parameters:
643+ n - the number of split
644- pc - the array of KSP contexts
645
646 Note:
617 Level: intermediate
618
619.seealso: PCFieldSplitGetSubKSP(), PCFIELDSPLIT, PCFieldSplitSetBlockSize()
620
621@*/
622PetscErrorCode PETSCKSP_DLLEXPORT PCFieldSplitSetIS(PC pc,IS is)
623{
624 PetscErrorCode ierr,(*f)(PC,IS);

--- 48 unchanged lines hidden (view full) ---

673 Input Parameter:
674. pc - the preconditioner context
675
676 Output Parameters:
677+ n - the number of split
678- pc - the array of KSP contexts
679
680 Note:
647 After PCFieldSplitGetSubKSP() the array of KSPs IS to be freed
681 After PCFieldSplitGetSubKSP() the array of KSPs IS to be freed by the user
682 (not the KSP just the array that contains them).
648
649 You must call KSPSetUp() before calling PCFieldSplitGetSubKSP().
650
651 Level: advanced
652
653.seealso: PCFIELDSPLIT
654@*/
655PetscErrorCode PETSCKSP_DLLEXPORT PCFieldSplitGetSubKSP(PC pc,PetscInt *n,KSP *subksp[])

--- 90 unchanged lines hidden (view full) ---

746
747 Options Database Keys:
748+ -pc_splitfield_%d_fields <a,b,..> - indicates the fields to be used in the %d'th split
749. -pc_splitfield_default - automatically add any fields to additional splits that have not
750 been supplied explicitly by -pc_splitfield_%d_fields
751. -pc_splitfield_block_size <bs> - size of block that defines fields (i.e. there are bs fields)
752- -pc_splitfield_type <additive,multiplicative>
753
683
684 You must call KSPSetUp() before calling PCFieldSplitGetSubKSP().
685
686 Level: advanced
687
688.seealso: PCFIELDSPLIT
689@*/
690PetscErrorCode PETSCKSP_DLLEXPORT PCFieldSplitGetSubKSP(PC pc,PetscInt *n,KSP *subksp[])

--- 90 unchanged lines hidden (view full) ---

781
782 Options Database Keys:
783+ -pc_splitfield_%d_fields <a,b,..> - indicates the fields to be used in the %d'th split
784. -pc_splitfield_default - automatically add any fields to additional splits that have not
785 been supplied explicitly by -pc_splitfield_%d_fields
786. -pc_splitfield_block_size <bs> - size of block that defines fields (i.e. there are bs fields)
787- -pc_splitfield_type <additive,multiplicative>
788
789 Notes: use PCFieldSplitSetFields() to set fields defined by "strided" entries and PCFieldSplitSetIS()
790 to define a field by an arbitrary collection of entries.
791
792 If no fields are set the default is used. The fields are defined by entries strided by bs,
793 beginning at 0 then 1, etc to bs-1. The block size can be set with PCFieldSplitSetBlockSize(),
794 if this is not called the block size defaults to the blocksize of the second matrix passed
795 to KSPSetOperators()/PCSetOperators().
796
797 Currently for the multiplicative version, the updated residual needed for the next field
798 solve is computed via a matrix vector product over the entire array. An optimization would be
799 to update the residual only for the part of the right hand side associated with the next field
800 solve. (This would involve more MatGetSubMatrix() calls or some other mechanism to compute the
801 part of the matrix needed to just update part of the residual).
802
754 Concepts: physics based preconditioners
755
756.seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC,
803 Concepts: physics based preconditioners
804
805.seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC,
757 PCFieldSplitGetSubKSP(), PCFieldSplitSetFields(),PCFieldSplitSetType()
806 PCFieldSplitGetSubKSP(), PCFieldSplitSetFields(), PCFieldSplitSetType(), PCFieldSplitSetIS()
758M*/
759
760EXTERN_C_BEGIN
761#undef __FUNCT__
762#define __FUNCT__ "PCCreate_FieldSplit"
763PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_FieldSplit(PC pc)
764{
765 PetscErrorCode ierr;

--- 33 unchanged lines hidden ---
807M*/
808
809EXTERN_C_BEGIN
810#undef __FUNCT__
811#define __FUNCT__ "PCCreate_FieldSplit"
812PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_FieldSplit(PC pc)
813{
814 PetscErrorCode ierr;

--- 33 unchanged lines hidden ---