xref: /petsc/src/ksp/pc/impls/is/pcis.c (revision bb943df913c21490647d842d48200c8dc4bd6dce)
123ce1328SBarry Smith 
2ccd284c7SBarry Smith #include "../src/ksp/pc/impls/is/pcis.h" /*I "petscpc.h" I*/
3831a100dSStefano Zampini 
4831a100dSStefano Zampini #undef __FUNCT__
5b965d45eSStefano Zampini #define __FUNCT__ "PCISSetUseStiffnessScaling_IS"
6b965d45eSStefano Zampini static PetscErrorCode PCISSetUseStiffnessScaling_IS(PC pc, PetscBool use)
7b965d45eSStefano Zampini {
8b965d45eSStefano Zampini   PC_IS *pcis = (PC_IS*)pc->data;
9b965d45eSStefano Zampini 
10b965d45eSStefano Zampini   PetscFunctionBegin;
11b965d45eSStefano Zampini   pcis->use_stiffness_scaling = use;
12b965d45eSStefano Zampini   PetscFunctionReturn(0);
13b965d45eSStefano Zampini }
14b965d45eSStefano Zampini 
15b965d45eSStefano Zampini #undef __FUNCT__
16b965d45eSStefano Zampini #define __FUNCT__ "PCISSetUseStiffnessScaling"
17b965d45eSStefano Zampini /*@
18b965d45eSStefano Zampini  PCISSetUseStiffnessScaling - Tells PCIS to construct partition of unity using
19b965d45eSStefano Zampini                               local matrices' diagonal.
20b965d45eSStefano Zampini 
21b965d45eSStefano Zampini    Not collective
22b965d45eSStefano Zampini 
23b965d45eSStefano Zampini    Input Parameters:
24b965d45eSStefano Zampini +  pc - the preconditioning context
25b965d45eSStefano Zampini -  use - whether or not pcis use matrix diagonal to build partition of unity.
26b965d45eSStefano Zampini 
27b965d45eSStefano Zampini    Level: intermediate
28b965d45eSStefano Zampini 
29b965d45eSStefano Zampini    Notes:
30b965d45eSStefano Zampini 
31b965d45eSStefano Zampini .seealso: PCBDDC
32b965d45eSStefano Zampini @*/
33b965d45eSStefano Zampini PetscErrorCode PCISSetUseStiffnessScaling(PC pc, PetscBool use)
34b965d45eSStefano Zampini {
35b965d45eSStefano Zampini   PetscErrorCode ierr;
36b965d45eSStefano Zampini 
37b965d45eSStefano Zampini   PetscFunctionBegin;
38b965d45eSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
39b965d45eSStefano Zampini   ierr = PetscTryMethod(pc,"PCISSetUseStiffnessScaling_C",(PC,PetscBool),(pc,use));CHKERRQ(ierr);
40b965d45eSStefano Zampini   PetscFunctionReturn(0);
41b965d45eSStefano Zampini }
42b965d45eSStefano Zampini 
43b965d45eSStefano Zampini #undef __FUNCT__
44ba1573a8SStefano Zampini #define __FUNCT__ "PCISSetSubdomainDiagonalScaling_IS"
45ba1573a8SStefano Zampini static PetscErrorCode PCISSetSubdomainDiagonalScaling_IS(PC pc, Vec scaling_factors)
46ba1573a8SStefano Zampini {
47ba1573a8SStefano Zampini   PetscErrorCode ierr;
48ba1573a8SStefano Zampini   PC_IS          *pcis = (PC_IS*)pc->data;
49ba1573a8SStefano Zampini 
50ba1573a8SStefano Zampini   PetscFunctionBegin;
51ba1573a8SStefano Zampini   ierr    = VecDestroy(&pcis->D);CHKERRQ(ierr);
52ba1573a8SStefano Zampini   ierr    = PetscObjectReference((PetscObject)scaling_factors);CHKERRQ(ierr);
53ba1573a8SStefano Zampini   pcis->D = scaling_factors;
54ba1573a8SStefano Zampini   PetscFunctionReturn(0);
55ba1573a8SStefano Zampini }
56ba1573a8SStefano Zampini 
57ba1573a8SStefano Zampini #undef __FUNCT__
58ba1573a8SStefano Zampini #define __FUNCT__ "PCISSetSubdomainDiagonalScaling"
59ba1573a8SStefano Zampini /*@
60ba1573a8SStefano Zampini  PCISSetSubdomainDiagonalScaling - Set diagonal scaling for PCIS.
61ba1573a8SStefano Zampini 
62ba1573a8SStefano Zampini    Not collective
63ba1573a8SStefano Zampini 
64ba1573a8SStefano Zampini    Input Parameters:
65ba1573a8SStefano Zampini +  pc - the preconditioning context
66ba1573a8SStefano Zampini -  scaling_factors - scaling factors for the subdomain
67ba1573a8SStefano Zampini 
68ba1573a8SStefano Zampini    Level: intermediate
69ba1573a8SStefano Zampini 
70ba1573a8SStefano Zampini    Notes:
71ba1573a8SStefano Zampini    Intended to use with jumping coefficients cases.
72ba1573a8SStefano Zampini 
73ba1573a8SStefano Zampini .seealso: PCBDDC
74ba1573a8SStefano Zampini @*/
75ba1573a8SStefano Zampini PetscErrorCode PCISSetSubdomainDiagonalScaling(PC pc, Vec scaling_factors)
76ba1573a8SStefano Zampini {
77ba1573a8SStefano Zampini   PetscErrorCode ierr;
78ba1573a8SStefano Zampini 
79ba1573a8SStefano Zampini   PetscFunctionBegin;
80ba1573a8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
81ba1573a8SStefano Zampini   ierr = PetscTryMethod(pc,"PCISSetSubdomainDiagonalScaling_C",(PC,Vec),(pc,scaling_factors));CHKERRQ(ierr);
82ba1573a8SStefano Zampini   PetscFunctionReturn(0);
83ba1573a8SStefano Zampini }
84ba1573a8SStefano Zampini 
85ba1573a8SStefano Zampini #undef __FUNCT__
86831a100dSStefano Zampini #define __FUNCT__ "PCISSetSubdomainScalingFactor_IS"
87831a100dSStefano Zampini static PetscErrorCode PCISSetSubdomainScalingFactor_IS(PC pc, PetscScalar scal)
88831a100dSStefano Zampini {
89831a100dSStefano Zampini   PC_IS *pcis = (PC_IS*)pc->data;
90831a100dSStefano Zampini 
91831a100dSStefano Zampini   PetscFunctionBegin;
92831a100dSStefano Zampini   pcis->scaling_factor = scal;
93831a100dSStefano Zampini   PetscFunctionReturn(0);
94831a100dSStefano Zampini }
95831a100dSStefano Zampini 
96831a100dSStefano Zampini #undef __FUNCT__
97831a100dSStefano Zampini #define __FUNCT__ "PCISSetSubdomainScalingFactor"
98831a100dSStefano Zampini /*@
99831a100dSStefano Zampini  PCISSetSubdomainScalingFactor - Set scaling factor for PCIS.
100831a100dSStefano Zampini 
101831a100dSStefano Zampini    Not collective
102831a100dSStefano Zampini 
103831a100dSStefano Zampini    Input Parameters:
104831a100dSStefano Zampini +  pc - the preconditioning context
105831a100dSStefano Zampini -  scal - scaling factor for the subdomain
106831a100dSStefano Zampini 
107831a100dSStefano Zampini    Level: intermediate
108831a100dSStefano Zampini 
109831a100dSStefano Zampini    Notes:
110831a100dSStefano Zampini    Intended to use with jumping coefficients cases.
111831a100dSStefano Zampini 
112831a100dSStefano Zampini .seealso: PCBDDC
113831a100dSStefano Zampini @*/
114831a100dSStefano Zampini PetscErrorCode PCISSetSubdomainScalingFactor(PC pc, PetscScalar scal)
115831a100dSStefano Zampini {
116831a100dSStefano Zampini   PetscErrorCode ierr;
117831a100dSStefano Zampini 
118831a100dSStefano Zampini   PetscFunctionBegin;
119831a100dSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
120831a100dSStefano Zampini   ierr = PetscTryMethod(pc,"PCISSetSubdomainScalingFactor_C",(PC,PetscScalar),(pc,scal));CHKERRQ(ierr);
121831a100dSStefano Zampini   PetscFunctionReturn(0);
122831a100dSStefano Zampini }
123831a100dSStefano Zampini 
124b4319ba4SBarry Smith 
125b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */
126b4319ba4SBarry Smith /*
127b4319ba4SBarry Smith    PCISSetUp -
128b4319ba4SBarry Smith */
129b4319ba4SBarry Smith #undef __FUNCT__
130b4319ba4SBarry Smith #define __FUNCT__ "PCISSetUp"
1317087cfbeSBarry Smith PetscErrorCode  PCISSetUp(PC pc)
132b4319ba4SBarry Smith {
133b4319ba4SBarry Smith   PC_IS          *pcis  = (PC_IS*)(pc->data);
134b4319ba4SBarry Smith   Mat_IS         *matis = (Mat_IS*)pc->mat->data;
13513f74950SBarry Smith   PetscInt       i;
1366849ba73SBarry Smith   PetscErrorCode ierr;
137ace3abfcSBarry Smith   PetscBool      flg;
138831a100dSStefano Zampini   Vec            counter;
139b4319ba4SBarry Smith 
140b4319ba4SBarry Smith   PetscFunctionBegin;
141251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->mat,MATIS,&flg);CHKERRQ(ierr);
142ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Preconditioner type of Neumann Neumman requires matrix of type MATIS");
143b4319ba4SBarry Smith 
144b4319ba4SBarry Smith   pcis->pure_neumann = matis->pure_neumann;
145b4319ba4SBarry Smith 
146b4319ba4SBarry Smith   /*
147b4319ba4SBarry Smith     Creating the local vector vec1_N, containing the inverse of the number
148b4319ba4SBarry Smith     of subdomains to which each local node (either owned or ghost)
149b4319ba4SBarry Smith     pertains. To accomplish that, we scatter local vectors of 1's to
150b4319ba4SBarry Smith     a global vector (adding the values); scatter the result back to
151b4319ba4SBarry Smith     local vectors and finally invert the result.
152b4319ba4SBarry Smith   */
153b4319ba4SBarry Smith   ierr = VecDuplicate(matis->x,&pcis->vec1_N);CHKERRQ(ierr);
15423ce1328SBarry Smith   ierr = MatGetVecs(pc->pmat,&counter,0);CHKERRQ(ierr); /* temporary auxiliar vector */
155efb30889SBarry Smith   ierr = VecSet(counter,0.0);CHKERRQ(ierr);
156efb30889SBarry Smith   ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr);
157ca9f406cSSatish Balay   ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
158ca9f406cSSatish Balay   ierr = VecScatterEnd  (matis->ctx,pcis->vec1_N,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
159ca9f406cSSatish Balay   ierr = VecScatterBegin(matis->ctx,counter,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
160ca9f406cSSatish Balay   ierr = VecScatterEnd  (matis->ctx,counter,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
161b4319ba4SBarry Smith   /*
162b4319ba4SBarry Smith     Creating local and global index sets for interior and
163b4319ba4SBarry Smith     inteface nodes. Notice that interior nodes have D[i]==1.0.
164b4319ba4SBarry Smith   */
165b4319ba4SBarry Smith   {
16613f74950SBarry Smith     PetscInt    n_I;
16713f74950SBarry Smith     PetscInt    *idx_I_local,*idx_B_local,*idx_I_global,*idx_B_global;
168b4319ba4SBarry Smith     PetscScalar *array;
169b4319ba4SBarry Smith     /* Identifying interior and interface nodes, in local numbering */
170b4319ba4SBarry Smith     ierr = VecGetSize(pcis->vec1_N,&pcis->n);CHKERRQ(ierr);
171b4319ba4SBarry Smith     ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr);
17213f74950SBarry Smith     ierr = PetscMalloc(pcis->n*sizeof(PetscInt),&idx_I_local);CHKERRQ(ierr);
17313f74950SBarry Smith     ierr = PetscMalloc(pcis->n*sizeof(PetscInt),&idx_B_local);CHKERRQ(ierr);
174b4319ba4SBarry Smith     for (i=0, pcis->n_B=0, n_I=0; i<pcis->n; i++) {
1752fa5cd67SKarl Rupp       if (array[i] == 1.0) {
1762fa5cd67SKarl Rupp         idx_I_local[n_I] = i;
1772fa5cd67SKarl Rupp         n_I++;
1782fa5cd67SKarl Rupp       } else {
1792fa5cd67SKarl Rupp         idx_B_local[pcis->n_B] = i;
1802fa5cd67SKarl Rupp         pcis->n_B++;
1812fa5cd67SKarl Rupp       }
182b4319ba4SBarry Smith     }
183b4319ba4SBarry Smith     /* Getting the global numbering */
184b4319ba4SBarry Smith     idx_B_global = idx_I_local + n_I; /* Just avoiding allocating extra memory, since we have vacant space */
185b4319ba4SBarry Smith     idx_I_global = idx_B_local + pcis->n_B;
186b4319ba4SBarry Smith     ierr         = ISLocalToGlobalMappingApply(matis->mapping,pcis->n_B,idx_B_local,idx_B_global);CHKERRQ(ierr);
187b4319ba4SBarry Smith     ierr         = ISLocalToGlobalMappingApply(matis->mapping,n_I,      idx_I_local,idx_I_global);CHKERRQ(ierr);
1882fa5cd67SKarl Rupp 
189b4319ba4SBarry Smith     /* Creating the index sets. */
190*bb943df9SStefano Zampini     ierr = ISCreateGeneral(PETSC_COMM_SELF,pcis->n_B,idx_B_local,PETSC_COPY_VALUES, &pcis->is_B_local);CHKERRQ(ierr);
191*bb943df9SStefano Zampini     ierr = ISCreateGeneral(PETSC_COMM_SELF,pcis->n_B,idx_B_global,PETSC_COPY_VALUES,&pcis->is_B_global);CHKERRQ(ierr);
192*bb943df9SStefano Zampini     ierr = ISCreateGeneral(PETSC_COMM_SELF,n_I,idx_I_local,PETSC_COPY_VALUES, &pcis->is_I_local);CHKERRQ(ierr);
193*bb943df9SStefano Zampini     ierr = ISCreateGeneral(PETSC_COMM_SELF,n_I,idx_I_global,PETSC_COPY_VALUES,&pcis->is_I_global);CHKERRQ(ierr);
1942fa5cd67SKarl Rupp 
195b4319ba4SBarry Smith     /* Freeing memory and restoring arrays */
196b4319ba4SBarry Smith     ierr = PetscFree(idx_B_local);CHKERRQ(ierr);
197b4319ba4SBarry Smith     ierr = PetscFree(idx_I_local);CHKERRQ(ierr);
198b4319ba4SBarry Smith     ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr);
199b4319ba4SBarry Smith   }
200b4319ba4SBarry Smith 
201b4319ba4SBarry Smith   /*
202b4319ba4SBarry Smith     Extracting the blocks A_II, A_BI, A_IB and A_BB from A. If the numbering
203b4319ba4SBarry Smith     is such that interior nodes come first than the interface ones, we have
204b4319ba4SBarry Smith 
205b4319ba4SBarry Smith     [           |      ]
206b4319ba4SBarry Smith     [    A_II   | A_IB ]
207b4319ba4SBarry Smith     A = [           |      ]
208b4319ba4SBarry Smith     [-----------+------]
209b4319ba4SBarry Smith     [    A_BI   | A_BB ]
210b4319ba4SBarry Smith   */
211b4319ba4SBarry Smith 
2124aa3045dSJed Brown   ierr = MatGetSubMatrix(matis->A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_II);CHKERRQ(ierr);
2134aa3045dSJed Brown   ierr = MatGetSubMatrix(matis->A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr);
2144aa3045dSJed Brown   ierr = MatGetSubMatrix(matis->A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr);
2154aa3045dSJed Brown   ierr = MatGetSubMatrix(matis->A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr);
216b4319ba4SBarry Smith 
217b4319ba4SBarry Smith   /*
218b4319ba4SBarry Smith     Creating work vectors and arrays
219b4319ba4SBarry Smith   */
220b4319ba4SBarry Smith   /* pcis->vec1_N has already been created */
221b4319ba4SBarry Smith   ierr = VecDuplicate(pcis->vec1_N,&pcis->vec2_N);CHKERRQ(ierr);
222b4319ba4SBarry Smith   ierr = VecCreateSeq(PETSC_COMM_SELF,pcis->n-pcis->n_B,&pcis->vec1_D);CHKERRQ(ierr);
223b4319ba4SBarry Smith   ierr = VecDuplicate(pcis->vec1_D,&pcis->vec2_D);CHKERRQ(ierr);
224b4319ba4SBarry Smith   ierr = VecDuplicate(pcis->vec1_D,&pcis->vec3_D);CHKERRQ(ierr);
225b4319ba4SBarry Smith   ierr = VecCreateSeq(PETSC_COMM_SELF,pcis->n_B,&pcis->vec1_B);CHKERRQ(ierr);
226b4319ba4SBarry Smith   ierr = VecDuplicate(pcis->vec1_B,&pcis->vec2_B);CHKERRQ(ierr);
227b4319ba4SBarry Smith   ierr = VecDuplicate(pcis->vec1_B,&pcis->vec3_B);CHKERRQ(ierr);
22823ce1328SBarry Smith   ierr = MatGetVecs(pc->pmat,&pcis->vec1_global,0);CHKERRQ(ierr);
229b4319ba4SBarry Smith   ierr = PetscMalloc((pcis->n)*sizeof(PetscScalar),&pcis->work_N);CHKERRQ(ierr);
230b4319ba4SBarry Smith 
231b4319ba4SBarry Smith   /* Creating the scatter contexts */
23223ce1328SBarry Smith   ierr = VecScatterCreate(pcis->vec1_global,pcis->is_I_global,pcis->vec1_D,(IS)0,&pcis->global_to_D);CHKERRQ(ierr);
233b4319ba4SBarry Smith   ierr = VecScatterCreate(pcis->vec1_N,pcis->is_B_local,pcis->vec1_B,(IS)0,&pcis->N_to_B);CHKERRQ(ierr);
23423ce1328SBarry Smith   ierr = VecScatterCreate(pcis->vec1_global,pcis->is_B_global,pcis->vec1_B,(IS)0,&pcis->global_to_B);CHKERRQ(ierr);
235b4319ba4SBarry Smith 
236831a100dSStefano Zampini   /* Creating scaling "matrix" D */
2370298fd71SBarry Smith   ierr = PetscOptionsGetBool(((PetscObject)pc)->prefix,"-pc_is_use_stiffness_scaling",&pcis->use_stiffness_scaling,NULL);CHKERRQ(ierr);
238831a100dSStefano Zampini   if (!pcis->D) {
239b965d45eSStefano Zampini     ierr = VecDuplicate(pcis->vec1_B,&pcis->D);CHKERRQ(ierr);
240b965d45eSStefano Zampini     if (!pcis->use_stiffness_scaling) {
241b965d45eSStefano Zampini       ierr = VecSet(pcis->D,pcis->scaling_factor);CHKERRQ(ierr);
242ba1573a8SStefano Zampini     } else {
243b965d45eSStefano Zampini       ierr = MatGetDiagonal(matis->A,pcis->vec1_N);CHKERRQ(ierr);
244b965d45eSStefano Zampini       ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
245b965d45eSStefano Zampini       ierr = VecScatterEnd  (pcis->N_to_B,pcis->vec1_N,pcis->D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
246ba1573a8SStefano Zampini     }
247b965d45eSStefano Zampini   }
248b965d45eSStefano Zampini   ierr = VecCopy(pcis->D,pcis->vec1_B);CHKERRQ(ierr);
249831a100dSStefano Zampini   ierr = VecSet(counter,0.0);CHKERRQ(ierr);
250ba1573a8SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
251ba1573a8SStefano Zampini   ierr = VecScatterEnd  (pcis->global_to_B,pcis->vec1_B,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
252ba1573a8SStefano Zampini   ierr = VecScatterBegin(pcis->global_to_B,counter,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
253ba1573a8SStefano Zampini   ierr = VecScatterEnd  (pcis->global_to_B,counter,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
254ba1573a8SStefano Zampini   ierr = VecPointwiseDivide(pcis->D,pcis->D,pcis->vec1_B);CHKERRQ(ierr);
255b4319ba4SBarry Smith 
256b4319ba4SBarry Smith   /* See historical note 01, at the bottom of this file. */
257b4319ba4SBarry Smith 
258b4319ba4SBarry Smith   /*
259b4319ba4SBarry Smith     Creating the KSP contexts for the local Dirichlet and Neumann problems.
260b4319ba4SBarry Smith   */
261b4319ba4SBarry Smith   {
262b4319ba4SBarry Smith     PC pc_ctx;
263b4319ba4SBarry Smith     /* Dirichlet */
264b4319ba4SBarry Smith     ierr = KSPCreate(PETSC_COMM_SELF,&pcis->ksp_D);CHKERRQ(ierr);
2651cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)pcis->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr);
266b4319ba4SBarry Smith     ierr = KSPSetOperators(pcis->ksp_D,pcis->A_II,pcis->A_II,SAME_PRECONDITIONER);CHKERRQ(ierr);
267b4319ba4SBarry Smith     ierr = KSPSetOptionsPrefix(pcis->ksp_D,"is_localD_");CHKERRQ(ierr);
268b4319ba4SBarry Smith     ierr = KSPGetPC(pcis->ksp_D,&pc_ctx);CHKERRQ(ierr);
269b4319ba4SBarry Smith     ierr = PCSetType(pc_ctx,PCLU);CHKERRQ(ierr);
270b4319ba4SBarry Smith     ierr = KSPSetType(pcis->ksp_D,KSPPREONLY);CHKERRQ(ierr);
271b4319ba4SBarry Smith     ierr = KSPSetFromOptions(pcis->ksp_D);CHKERRQ(ierr);
272b4319ba4SBarry Smith     /* the vectors in the following line are dummy arguments, just telling the KSP the vector size. Values are not used */
273b4319ba4SBarry Smith     ierr = KSPSetUp(pcis->ksp_D);CHKERRQ(ierr);
274b4319ba4SBarry Smith     /* Neumann */
275b4319ba4SBarry Smith     ierr = KSPCreate(PETSC_COMM_SELF,&pcis->ksp_N);CHKERRQ(ierr);
2761cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)pcis->ksp_N,(PetscObject)pc,1);CHKERRQ(ierr);
277b4319ba4SBarry Smith     ierr = KSPSetOperators(pcis->ksp_N,matis->A,matis->A,SAME_PRECONDITIONER);CHKERRQ(ierr);
278b4319ba4SBarry Smith     ierr = KSPSetOptionsPrefix(pcis->ksp_N,"is_localN_");CHKERRQ(ierr);
279b4319ba4SBarry Smith     ierr = KSPGetPC(pcis->ksp_N,&pc_ctx);CHKERRQ(ierr);
280b4319ba4SBarry Smith     ierr = PCSetType(pc_ctx,PCLU);CHKERRQ(ierr);
281b4319ba4SBarry Smith     ierr = KSPSetType(pcis->ksp_N,KSPPREONLY);CHKERRQ(ierr);
282b4319ba4SBarry Smith     ierr = KSPSetFromOptions(pcis->ksp_N);CHKERRQ(ierr);
283b4319ba4SBarry Smith     {
284ace3abfcSBarry Smith       PetscBool damp_fixed                    = PETSC_FALSE,
28590d69ab7SBarry Smith                 remove_nullspace_fixed        = PETSC_FALSE,
28690d69ab7SBarry Smith                 set_damping_factor_floating   = PETSC_FALSE,
28790d69ab7SBarry Smith                 not_damp_floating             = PETSC_FALSE,
28890d69ab7SBarry Smith                 not_remove_nullspace_floating = PETSC_FALSE;
289b4319ba4SBarry Smith       PetscReal fixed_factor,
290b4319ba4SBarry Smith                 floating_factor;
291b4319ba4SBarry Smith 
2927adad957SLisandro Dalcin       ierr = PetscOptionsGetReal(((PetscObject)pc_ctx)->prefix,"-pc_is_damp_fixed",&fixed_factor,&damp_fixed);CHKERRQ(ierr);
2932fa5cd67SKarl Rupp       if (!damp_fixed) fixed_factor = 0.0;
2940298fd71SBarry Smith       ierr = PetscOptionsGetBool(((PetscObject)pc_ctx)->prefix,"-pc_is_damp_fixed",&damp_fixed,NULL);CHKERRQ(ierr);
295b4319ba4SBarry Smith 
2960298fd71SBarry Smith       ierr = PetscOptionsGetBool(((PetscObject)pc_ctx)->prefix,"-pc_is_remove_nullspace_fixed",&remove_nullspace_fixed,NULL);CHKERRQ(ierr);
297b4319ba4SBarry Smith 
2987adad957SLisandro Dalcin       ierr = PetscOptionsGetReal(((PetscObject)pc_ctx)->prefix,"-pc_is_set_damping_factor_floating",
299b4319ba4SBarry Smith                               &floating_factor,&set_damping_factor_floating);CHKERRQ(ierr);
3002fa5cd67SKarl Rupp       if (!set_damping_factor_floating) floating_factor = 0.0;
3010298fd71SBarry Smith       ierr = PetscOptionsGetBool(((PetscObject)pc_ctx)->prefix,"-pc_is_set_damping_factor_floating",&set_damping_factor_floating,NULL);CHKERRQ(ierr);
3022fa5cd67SKarl Rupp       if (!set_damping_factor_floating) floating_factor = 1.e-12;
303b4319ba4SBarry Smith 
3040298fd71SBarry Smith       ierr = PetscOptionsGetBool(((PetscObject)pc_ctx)->prefix,"-pc_is_not_damp_floating",&not_damp_floating,NULL);CHKERRQ(ierr);
305b4319ba4SBarry Smith 
3060298fd71SBarry Smith       ierr = PetscOptionsGetBool(((PetscObject)pc_ctx)->prefix,"-pc_is_not_remove_nullspace_floating",&not_remove_nullspace_floating,NULL);CHKERRQ(ierr);
307b4319ba4SBarry Smith 
308b4319ba4SBarry Smith       if (pcis->pure_neumann) {  /* floating subdomain */
309b4319ba4SBarry Smith         if (!(not_damp_floating)) {
310c88783f4SHong Zhang           ierr = PCFactorSetShiftType(pc_ctx,MAT_SHIFT_NONZERO);CHKERRQ(ierr);
311c88783f4SHong Zhang           ierr = PCFactorSetShiftAmount(pc_ctx,floating_factor);CHKERRQ(ierr);
312b4319ba4SBarry Smith         }
313b4319ba4SBarry Smith         if (!(not_remove_nullspace_floating)) {
314b4319ba4SBarry Smith           MatNullSpace nullsp;
3150298fd71SBarry Smith           ierr = MatNullSpaceCreate(PETSC_COMM_SELF,PETSC_TRUE,0,NULL,&nullsp);CHKERRQ(ierr);
316d8fd42c4SBarry Smith           ierr = KSPSetNullSpace(pcis->ksp_N,nullsp);CHKERRQ(ierr);
317d34fcf5fSBarry Smith           ierr = MatNullSpaceDestroy(&nullsp);CHKERRQ(ierr);
318b4319ba4SBarry Smith         }
319b4319ba4SBarry Smith       } else {  /* fixed subdomain */
320b4319ba4SBarry Smith         if (damp_fixed) {
321c88783f4SHong Zhang           ierr = PCFactorSetShiftType(pc_ctx,MAT_SHIFT_NONZERO);CHKERRQ(ierr);
322c88783f4SHong Zhang           ierr = PCFactorSetShiftAmount(pc_ctx,floating_factor);CHKERRQ(ierr);
323b4319ba4SBarry Smith         }
324b4319ba4SBarry Smith         if (remove_nullspace_fixed) {
325b4319ba4SBarry Smith           MatNullSpace nullsp;
3260298fd71SBarry Smith           ierr = MatNullSpaceCreate(PETSC_COMM_SELF,PETSC_TRUE,0,NULL,&nullsp);CHKERRQ(ierr);
327d8fd42c4SBarry Smith           ierr = KSPSetNullSpace(pcis->ksp_N,nullsp);CHKERRQ(ierr);
328d34fcf5fSBarry Smith           ierr = MatNullSpaceDestroy(&nullsp);CHKERRQ(ierr);
329b4319ba4SBarry Smith         }
330b4319ba4SBarry Smith       }
331b4319ba4SBarry Smith     }
332b4319ba4SBarry Smith     /* the vectors in the following line are dummy arguments, just telling the KSP the vector size. Values are not used */
333b4319ba4SBarry Smith     ierr = KSPSetUp(pcis->ksp_N);CHKERRQ(ierr);
334b4319ba4SBarry Smith   }
335b4319ba4SBarry Smith 
3367c334f02SBarry Smith   ierr = ISLocalToGlobalMappingGetInfo(((Mat_IS*)(pc->mat->data))->mapping,&(pcis->n_neigh),&(pcis->neigh),&(pcis->n_shared),&(pcis->shared));CHKERRQ(ierr);
3372fa5cd67SKarl Rupp 
338b4319ba4SBarry Smith   pcis->ISLocalToGlobalMappingGetInfoWasCalled = PETSC_TRUE;
3392fa5cd67SKarl Rupp 
340831a100dSStefano Zampini   ierr = VecDestroy(&counter);CHKERRQ(ierr);
341b4319ba4SBarry Smith   PetscFunctionReturn(0);
342b4319ba4SBarry Smith }
343b4319ba4SBarry Smith 
344b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */
345b4319ba4SBarry Smith /*
346b4319ba4SBarry Smith    PCISDestroy -
347b4319ba4SBarry Smith */
348b4319ba4SBarry Smith #undef __FUNCT__
349b4319ba4SBarry Smith #define __FUNCT__ "PCISDestroy"
3507087cfbeSBarry Smith PetscErrorCode  PCISDestroy(PC pc)
351b4319ba4SBarry Smith {
352b4319ba4SBarry Smith   PC_IS          *pcis = (PC_IS*)(pc->data);
353dfbe8321SBarry Smith   PetscErrorCode ierr;
354b4319ba4SBarry Smith 
355b4319ba4SBarry Smith   PetscFunctionBegin;
356fcfd50ebSBarry Smith   ierr = ISDestroy(&pcis->is_B_local);CHKERRQ(ierr);
357fcfd50ebSBarry Smith   ierr = ISDestroy(&pcis->is_I_local);CHKERRQ(ierr);
358fcfd50ebSBarry Smith   ierr = ISDestroy(&pcis->is_B_global);CHKERRQ(ierr);
359fcfd50ebSBarry Smith   ierr = ISDestroy(&pcis->is_I_global);CHKERRQ(ierr);
360fcfd50ebSBarry Smith   ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr);
361fcfd50ebSBarry Smith   ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr);
362fcfd50ebSBarry Smith   ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr);
363fcfd50ebSBarry Smith   ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr);
364fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->D);CHKERRQ(ierr);
365fcfd50ebSBarry Smith   ierr = KSPDestroy(&pcis->ksp_N);CHKERRQ(ierr);
366fcfd50ebSBarry Smith   ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr);
367fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec1_N);CHKERRQ(ierr);
368fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec2_N);CHKERRQ(ierr);
369fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec1_D);CHKERRQ(ierr);
370fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec2_D);CHKERRQ(ierr);
371fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec3_D);CHKERRQ(ierr);
372fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec1_B);CHKERRQ(ierr);
373fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec2_B);CHKERRQ(ierr);
374fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec3_B);CHKERRQ(ierr);
375fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec1_global);CHKERRQ(ierr);
376fcfd50ebSBarry Smith   ierr = VecScatterDestroy(&pcis->global_to_D);CHKERRQ(ierr);
377fcfd50ebSBarry Smith   ierr = VecScatterDestroy(&pcis->N_to_B);CHKERRQ(ierr);
378fcfd50ebSBarry Smith   ierr = VecScatterDestroy(&pcis->global_to_B);CHKERRQ(ierr);
37905b42c5fSBarry Smith   ierr = PetscFree(pcis->work_N);CHKERRQ(ierr);
380b4319ba4SBarry Smith   if (pcis->ISLocalToGlobalMappingGetInfoWasCalled) {
381b4319ba4SBarry Smith     ierr = ISLocalToGlobalMappingRestoreInfo((ISLocalToGlobalMapping)0,&(pcis->n_neigh),&(pcis->neigh),&(pcis->n_shared),&(pcis->shared));CHKERRQ(ierr);
382b4319ba4SBarry Smith   }
383bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCISSetUseStiffnessScaling_C",NULL);CHKERRQ(ierr);
384bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCISSetSubdomainScalingFactor_C",NULL);CHKERRQ(ierr);
385bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCISSetSubdomainDiagonalScaling_C",NULL);CHKERRQ(ierr);
386b4319ba4SBarry Smith   PetscFunctionReturn(0);
387b4319ba4SBarry Smith }
388b4319ba4SBarry Smith 
389b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */
390b4319ba4SBarry Smith /*
391b4319ba4SBarry Smith    PCISCreate -
392b4319ba4SBarry Smith */
393b4319ba4SBarry Smith #undef __FUNCT__
394b4319ba4SBarry Smith #define __FUNCT__ "PCISCreate"
3957087cfbeSBarry Smith PetscErrorCode  PCISCreate(PC pc)
396b4319ba4SBarry Smith {
397b4319ba4SBarry Smith   PC_IS          *pcis = (PC_IS*)(pc->data);
398831a100dSStefano Zampini   PetscErrorCode ierr;
399b4319ba4SBarry Smith 
400b4319ba4SBarry Smith   PetscFunctionBegin;
401b4319ba4SBarry Smith   pcis->is_B_local  = 0;
402b4319ba4SBarry Smith   pcis->is_I_local  = 0;
403b4319ba4SBarry Smith   pcis->is_B_global = 0;
404b4319ba4SBarry Smith   pcis->is_I_global = 0;
405b4319ba4SBarry Smith   pcis->A_II        = 0;
406b4319ba4SBarry Smith   pcis->A_IB        = 0;
407b4319ba4SBarry Smith   pcis->A_BI        = 0;
408b4319ba4SBarry Smith   pcis->A_BB        = 0;
409b4319ba4SBarry Smith   pcis->D           = 0;
410b4319ba4SBarry Smith   pcis->ksp_N       = 0;
411b4319ba4SBarry Smith   pcis->ksp_D      = 0;
412b4319ba4SBarry Smith   pcis->vec1_N      = 0;
413b4319ba4SBarry Smith   pcis->vec2_N      = 0;
414b4319ba4SBarry Smith   pcis->vec1_D      = 0;
415b4319ba4SBarry Smith   pcis->vec2_D      = 0;
416b4319ba4SBarry Smith   pcis->vec3_D      = 0;
417b4319ba4SBarry Smith   pcis->vec1_B      = 0;
418b4319ba4SBarry Smith   pcis->vec2_B      = 0;
419b4319ba4SBarry Smith   pcis->vec3_B      = 0;
420b4319ba4SBarry Smith   pcis->vec1_global = 0;
421b4319ba4SBarry Smith   pcis->work_N      = 0;
422b4319ba4SBarry Smith   pcis->global_to_D = 0;
423b4319ba4SBarry Smith   pcis->N_to_B      = 0;
424b4319ba4SBarry Smith   pcis->global_to_B = 0;
4252fa5cd67SKarl Rupp 
426b4319ba4SBarry Smith   pcis->ISLocalToGlobalMappingGetInfoWasCalled = PETSC_FALSE;
4272fa5cd67SKarl Rupp 
428831a100dSStefano Zampini   pcis->scaling_factor = 1.0;
429831a100dSStefano Zampini   /* composing functions */
430bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCISSetUseStiffnessScaling_C",PCISSetUseStiffnessScaling_IS);CHKERRQ(ierr);
431bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCISSetSubdomainScalingFactor_C",PCISSetSubdomainScalingFactor_IS);CHKERRQ(ierr);
432bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCISSetSubdomainDiagonalScaling_C",PCISSetSubdomainDiagonalScaling_IS);CHKERRQ(ierr);
433b4319ba4SBarry Smith   PetscFunctionReturn(0);
434b4319ba4SBarry Smith }
435b4319ba4SBarry Smith 
436b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */
437b4319ba4SBarry Smith /*
438b4319ba4SBarry Smith    PCISApplySchur -
439b4319ba4SBarry Smith 
440b4319ba4SBarry Smith    Input parameters:
441b4319ba4SBarry Smith .  pc - preconditioner context
442b4319ba4SBarry Smith .  v - vector to which the Schur complement is to be applied (it is NOT modified inside this function, UNLESS vec2_B is null)
443b4319ba4SBarry Smith 
444b4319ba4SBarry Smith    Output parameters:
445b4319ba4SBarry Smith .  vec1_B - result of Schur complement applied to chunk
446b4319ba4SBarry Smith .  vec2_B - garbage (used as work space), or null (and v is used as workspace)
447b4319ba4SBarry Smith .  vec1_D - garbage (used as work space)
448b4319ba4SBarry Smith .  vec2_D - garbage (used as work space)
449b4319ba4SBarry Smith 
450b4319ba4SBarry Smith */
451b4319ba4SBarry Smith #undef __FUNCT__
452831a100dSStefano Zampini #define __FUNCT__ "PCISApplySchur"
4537087cfbeSBarry Smith PetscErrorCode  PCISApplySchur(PC pc, Vec v, Vec vec1_B, Vec vec2_B, Vec vec1_D, Vec vec2_D)
454b4319ba4SBarry Smith {
455dfbe8321SBarry Smith   PetscErrorCode ierr;
456b4319ba4SBarry Smith   PC_IS          *pcis = (PC_IS*)(pc->data);
457b4319ba4SBarry Smith 
458b4319ba4SBarry Smith   PetscFunctionBegin;
4592fa5cd67SKarl Rupp   if (!vec2_B) vec2_B = v;
460b4319ba4SBarry Smith 
461b4319ba4SBarry Smith   ierr = MatMult(pcis->A_BB,v,vec1_B);CHKERRQ(ierr);
462b4319ba4SBarry Smith   ierr = MatMult(pcis->A_IB,v,vec1_D);CHKERRQ(ierr);
46323ce1328SBarry Smith   ierr = KSPSolve(pcis->ksp_D,vec1_D,vec2_D);CHKERRQ(ierr);
464b4319ba4SBarry Smith   ierr = MatMult(pcis->A_BI,vec2_D,vec2_B);CHKERRQ(ierr);
465efb30889SBarry Smith   ierr = VecAXPY(vec1_B,-1.0,vec2_B);CHKERRQ(ierr);
466b4319ba4SBarry Smith   PetscFunctionReturn(0);
467b4319ba4SBarry Smith }
468b4319ba4SBarry Smith 
469b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */
470b4319ba4SBarry Smith /*
471b4319ba4SBarry Smith    PCISScatterArrayNToVecB - Scatters interface node values from a big array (of all local nodes, interior or interface,
472b4319ba4SBarry Smith    including ghosts) into an interface vector, when in SCATTER_FORWARD mode, or vice-versa, when in SCATTER_REVERSE
473b4319ba4SBarry Smith    mode.
474b4319ba4SBarry Smith 
475b4319ba4SBarry Smith    Input parameters:
476b4319ba4SBarry Smith .  pc - preconditioner context
477b4319ba4SBarry Smith .  array_N - [when in SCATTER_FORWARD mode] Array to be scattered into the vector
478b4319ba4SBarry Smith .  v_B - [when in SCATTER_REVERSE mode] Vector to be scattered into the array
479b4319ba4SBarry Smith 
480b4319ba4SBarry Smith    Output parameter:
481b4319ba4SBarry Smith .  array_N - [when in SCATTER_REVERSE mode] Array to receive the scattered vector
482b4319ba4SBarry Smith .  v_B - [when in SCATTER_FORWARD mode] Vector to receive the scattered array
483b4319ba4SBarry Smith 
484b4319ba4SBarry Smith    Notes:
485b4319ba4SBarry Smith    The entries in the array that do not correspond to interface nodes remain unaltered.
486b4319ba4SBarry Smith */
487b4319ba4SBarry Smith #undef __FUNCT__
488b4319ba4SBarry Smith #define __FUNCT__ "PCISScatterArrayNToVecB"
4897087cfbeSBarry Smith PetscErrorCode  PCISScatterArrayNToVecB(PetscScalar *array_N, Vec v_B, InsertMode imode, ScatterMode smode, PC pc)
490b4319ba4SBarry Smith {
4915d0c19d7SBarry Smith   PetscInt       i;
4925d0c19d7SBarry Smith   const PetscInt *idex;
4936849ba73SBarry Smith   PetscErrorCode ierr;
494b4319ba4SBarry Smith   PetscScalar    *array_B;
495b4319ba4SBarry Smith   PC_IS          *pcis = (PC_IS*)(pc->data);
496b4319ba4SBarry Smith 
497b4319ba4SBarry Smith   PetscFunctionBegin;
498b4319ba4SBarry Smith   ierr = VecGetArray(v_B,&array_B);CHKERRQ(ierr);
499b4319ba4SBarry Smith   ierr = ISGetIndices(pcis->is_B_local,&idex);CHKERRQ(ierr);
500b4319ba4SBarry Smith 
501b4319ba4SBarry Smith   if (smode == SCATTER_FORWARD) {
502b4319ba4SBarry Smith     if (imode == INSERT_VALUES) {
5032fa5cd67SKarl Rupp       for (i=0; i<pcis->n_B; i++) array_B[i] = array_N[idex[i]];
504b4319ba4SBarry Smith     } else {  /* ADD_VALUES */
5052fa5cd67SKarl Rupp       for (i=0; i<pcis->n_B; i++) array_B[i] += array_N[idex[i]];
506b4319ba4SBarry Smith     }
507b4319ba4SBarry Smith   } else {  /* SCATTER_REVERSE */
508b4319ba4SBarry Smith     if (imode == INSERT_VALUES) {
5092fa5cd67SKarl Rupp       for (i=0; i<pcis->n_B; i++) array_N[idex[i]] = array_B[i];
510b4319ba4SBarry Smith     } else {  /* ADD_VALUES */
5112fa5cd67SKarl Rupp       for (i=0; i<pcis->n_B; i++) array_N[idex[i]] += array_B[i];
512b4319ba4SBarry Smith     }
513b4319ba4SBarry Smith   }
514b4319ba4SBarry Smith   ierr = ISRestoreIndices(pcis->is_B_local,&idex);CHKERRQ(ierr);
515b4319ba4SBarry Smith   ierr = VecRestoreArray(v_B,&array_B);CHKERRQ(ierr);
516b4319ba4SBarry Smith   PetscFunctionReturn(0);
517b4319ba4SBarry Smith }
518b4319ba4SBarry Smith 
519b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */
520b4319ba4SBarry Smith /*
521b4319ba4SBarry Smith    PCISApplyInvSchur - Solves the Neumann problem related to applying the inverse of the Schur complement.
522b4319ba4SBarry Smith    More precisely, solves the problem:
523b4319ba4SBarry Smith                                         [ A_II  A_IB ] [ . ]   [ 0 ]
524b4319ba4SBarry Smith                                         [            ] [   ] = [   ]
525b4319ba4SBarry Smith                                         [ A_BI  A_BB ] [ x ]   [ b ]
526b4319ba4SBarry Smith 
527b4319ba4SBarry Smith    Input parameters:
528b4319ba4SBarry Smith .  pc - preconditioner context
529b4319ba4SBarry Smith .  b - vector of local interface nodes (including ghosts)
530b4319ba4SBarry Smith 
531b4319ba4SBarry Smith    Output parameters:
532b4319ba4SBarry Smith .  x - vector of local interface nodes (including ghosts); returns the application of the inverse of the Schur
533b4319ba4SBarry Smith        complement to b
534b4319ba4SBarry Smith .  vec1_N - vector of local nodes (interior and interface, including ghosts); returns garbage (used as work space)
535b4319ba4SBarry Smith .  vec2_N - vector of local nodes (interior and interface, including ghosts); returns garbage (used as work space)
536b4319ba4SBarry Smith 
537b4319ba4SBarry Smith */
538b4319ba4SBarry Smith #undef __FUNCT__
539b4319ba4SBarry Smith #define __FUNCT__ "PCISApplyInvSchur"
5407087cfbeSBarry Smith PetscErrorCode  PCISApplyInvSchur(PC pc, Vec b, Vec x, Vec vec1_N, Vec vec2_N)
541b4319ba4SBarry Smith {
542dfbe8321SBarry Smith   PetscErrorCode ierr;
543b4319ba4SBarry Smith   PC_IS          *pcis = (PC_IS*)(pc->data);
544b4319ba4SBarry Smith 
545b4319ba4SBarry Smith   PetscFunctionBegin;
546b4319ba4SBarry Smith   /*
547b4319ba4SBarry Smith     Neumann solvers.
548b4319ba4SBarry Smith     Applying the inverse of the local Schur complement, i.e, solving a Neumann
549b4319ba4SBarry Smith     Problem with zero at the interior nodes of the RHS and extracting the interface
550b4319ba4SBarry Smith     part of the solution. inverse Schur complement is applied to b and the result
551b4319ba4SBarry Smith     is stored in x.
552b4319ba4SBarry Smith   */
553b4319ba4SBarry Smith   /* Setting the RHS vec1_N */
554efb30889SBarry Smith   ierr = VecSet(vec1_N,0.0);CHKERRQ(ierr);
555ca9f406cSSatish Balay   ierr = VecScatterBegin(pcis->N_to_B,b,vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
556ca9f406cSSatish Balay   ierr = VecScatterEnd  (pcis->N_to_B,b,vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
557b4319ba4SBarry Smith   /* Checking for consistency of the RHS */
558b4319ba4SBarry Smith   {
559ace3abfcSBarry Smith     PetscBool flg = PETSC_FALSE;
5600298fd71SBarry Smith     ierr = PetscOptionsGetBool(NULL,"-pc_is_check_consistency",&flg,NULL);CHKERRQ(ierr);
561b4319ba4SBarry Smith     if (flg) {
562b4319ba4SBarry Smith       PetscScalar average;
5633050cee2SBarry Smith       PetscViewer viewer;
564ce94432eSBarry Smith       ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pc),&viewer);CHKERRQ(ierr);
5653050cee2SBarry Smith 
566b4319ba4SBarry Smith       ierr    = VecSum(vec1_N,&average);CHKERRQ(ierr);
567b4319ba4SBarry Smith       average = average / ((PetscReal)pcis->n);
5687b23a99aSBarry Smith       ierr    = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr);
569b4319ba4SBarry Smith       if (pcis->pure_neumann) {
5709f73f8ecSBarry Smith         ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d is floating. Average = % 1.14e\n",PetscGlobalRank,PetscAbsScalar(average));CHKERRQ(ierr);
571b4319ba4SBarry Smith       } else {
5729f73f8ecSBarry Smith         ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d is fixed.    Average = % 1.14e\n",PetscGlobalRank,PetscAbsScalar(average));CHKERRQ(ierr);
573b4319ba4SBarry Smith       }
5743050cee2SBarry Smith       ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
5757b23a99aSBarry Smith       ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr);
576b4319ba4SBarry Smith     }
577b4319ba4SBarry Smith   }
578b4319ba4SBarry Smith   /* Solving the system for vec2_N */
57923ce1328SBarry Smith   ierr = KSPSolve(pcis->ksp_N,vec1_N,vec2_N);CHKERRQ(ierr);
580b4319ba4SBarry Smith   /* Extracting the local interface vector out of the solution */
581ca9f406cSSatish Balay   ierr = VecScatterBegin(pcis->N_to_B,vec2_N,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
582ca9f406cSSatish Balay   ierr = VecScatterEnd  (pcis->N_to_B,vec2_N,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
583b4319ba4SBarry Smith   PetscFunctionReturn(0);
584b4319ba4SBarry Smith }
585b4319ba4SBarry Smith 
586b4319ba4SBarry Smith 
587b4319ba4SBarry Smith 
588b4319ba4SBarry Smith 
589b4319ba4SBarry Smith 
590b4319ba4SBarry Smith 
591b4319ba4SBarry Smith 
592b4319ba4SBarry Smith 
593b4319ba4SBarry Smith 
594