xref: /petsc/src/ksp/pc/impls/is/pcis.c (revision b965d45e4cc2ca989486d1da9ac509e90ac821e9)
123ce1328SBarry Smith 
2ccd284c7SBarry Smith #include "../src/ksp/pc/impls/is/pcis.h" /*I "petscpc.h" I*/
3831a100dSStefano Zampini 
4831a100dSStefano Zampini EXTERN_C_BEGIN
5831a100dSStefano Zampini #undef __FUNCT__
6*b965d45eSStefano Zampini #define __FUNCT__ "PCISSetUseStiffnessScaling_IS"
7*b965d45eSStefano Zampini static PetscErrorCode PCISSetUseStiffnessScaling_IS(PC pc, PetscBool use)
8*b965d45eSStefano Zampini {
9*b965d45eSStefano Zampini   PetscErrorCode ierr;
10*b965d45eSStefano Zampini   PC_IS  *pcis = (PC_IS*)pc->data;
11*b965d45eSStefano Zampini 
12*b965d45eSStefano Zampini   PetscFunctionBegin;
13*b965d45eSStefano Zampini   pcis->use_stiffness_scaling = use;
14*b965d45eSStefano Zampini   PetscFunctionReturn(0);
15*b965d45eSStefano Zampini }
16*b965d45eSStefano Zampini EXTERN_C_END
17*b965d45eSStefano Zampini 
18*b965d45eSStefano Zampini #undef __FUNCT__
19*b965d45eSStefano Zampini #define __FUNCT__ "PCISSetUseStiffnessScaling"
20*b965d45eSStefano Zampini /*@
21*b965d45eSStefano Zampini  PCISSetUseStiffnessScaling - Tells PCIS to construct partition of unity using
22*b965d45eSStefano Zampini                               local matrices' diagonal.
23*b965d45eSStefano Zampini 
24*b965d45eSStefano Zampini    Not collective
25*b965d45eSStefano Zampini 
26*b965d45eSStefano Zampini    Input Parameters:
27*b965d45eSStefano Zampini +  pc - the preconditioning context
28*b965d45eSStefano Zampini -  use - whether or not pcis use matrix diagonal to build partition of unity.
29*b965d45eSStefano Zampini 
30*b965d45eSStefano Zampini    Level: intermediate
31*b965d45eSStefano Zampini 
32*b965d45eSStefano Zampini    Notes:
33*b965d45eSStefano Zampini 
34*b965d45eSStefano Zampini .seealso: PCBDDC
35*b965d45eSStefano Zampini @*/
36*b965d45eSStefano Zampini PetscErrorCode PCISSetUseStiffnessScaling(PC pc, PetscBool use)
37*b965d45eSStefano Zampini {
38*b965d45eSStefano Zampini   PetscErrorCode ierr;
39*b965d45eSStefano Zampini 
40*b965d45eSStefano Zampini   PetscFunctionBegin;
41*b965d45eSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
42*b965d45eSStefano Zampini   ierr = PetscTryMethod(pc,"PCISSetUseStiffnessScaling_C",(PC,PetscBool),(pc,use));CHKERRQ(ierr);
43*b965d45eSStefano Zampini   PetscFunctionReturn(0);
44*b965d45eSStefano Zampini }
45*b965d45eSStefano Zampini 
46*b965d45eSStefano Zampini EXTERN_C_BEGIN
47*b965d45eSStefano Zampini #undef __FUNCT__
48ba1573a8SStefano Zampini #define __FUNCT__ "PCISSetSubdomainDiagonalScaling_IS"
49ba1573a8SStefano Zampini static PetscErrorCode PCISSetSubdomainDiagonalScaling_IS(PC pc, Vec scaling_factors)
50ba1573a8SStefano Zampini {
51ba1573a8SStefano Zampini   PetscErrorCode ierr;
52ba1573a8SStefano Zampini   PC_IS  *pcis = (PC_IS*)pc->data;
53ba1573a8SStefano Zampini 
54ba1573a8SStefano Zampini   PetscFunctionBegin;
55ba1573a8SStefano Zampini   ierr = VecDestroy(&pcis->D);CHKERRQ(ierr);
56ba1573a8SStefano Zampini   ierr = PetscObjectReference((PetscObject)scaling_factors);CHKERRQ(ierr);
57ba1573a8SStefano Zampini   pcis->D = scaling_factors;
58ba1573a8SStefano Zampini   PetscFunctionReturn(0);
59ba1573a8SStefano Zampini }
60ba1573a8SStefano Zampini EXTERN_C_END
61ba1573a8SStefano Zampini 
62ba1573a8SStefano Zampini #undef __FUNCT__
63ba1573a8SStefano Zampini #define __FUNCT__ "PCISSetSubdomainDiagonalScaling"
64ba1573a8SStefano Zampini /*@
65ba1573a8SStefano Zampini  PCISSetSubdomainDiagonalScaling - Set diagonal scaling for PCIS.
66ba1573a8SStefano Zampini 
67ba1573a8SStefano Zampini    Not collective
68ba1573a8SStefano Zampini 
69ba1573a8SStefano Zampini    Input Parameters:
70ba1573a8SStefano Zampini +  pc - the preconditioning context
71ba1573a8SStefano Zampini -  scaling_factors - scaling factors for the subdomain
72ba1573a8SStefano Zampini 
73ba1573a8SStefano Zampini    Level: intermediate
74ba1573a8SStefano Zampini 
75ba1573a8SStefano Zampini    Notes:
76ba1573a8SStefano Zampini    Intended to use with jumping coefficients cases.
77ba1573a8SStefano Zampini 
78ba1573a8SStefano Zampini .seealso: PCBDDC
79ba1573a8SStefano Zampini @*/
80ba1573a8SStefano Zampini PetscErrorCode PCISSetSubdomainDiagonalScaling(PC pc, Vec scaling_factors)
81ba1573a8SStefano Zampini {
82ba1573a8SStefano Zampini   PetscErrorCode ierr;
83ba1573a8SStefano Zampini 
84ba1573a8SStefano Zampini   PetscFunctionBegin;
85ba1573a8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
86ba1573a8SStefano Zampini   ierr = PetscTryMethod(pc,"PCISSetSubdomainDiagonalScaling_C",(PC,Vec),(pc,scaling_factors));CHKERRQ(ierr);
87ba1573a8SStefano Zampini   PetscFunctionReturn(0);
88ba1573a8SStefano Zampini }
89ba1573a8SStefano Zampini 
90ba1573a8SStefano Zampini EXTERN_C_BEGIN
91ba1573a8SStefano Zampini #undef __FUNCT__
92831a100dSStefano Zampini #define __FUNCT__ "PCISSetSubdomainScalingFactor_IS"
93831a100dSStefano Zampini static PetscErrorCode PCISSetSubdomainScalingFactor_IS(PC pc, PetscScalar scal)
94831a100dSStefano Zampini {
95831a100dSStefano Zampini   PC_IS  *pcis = (PC_IS*)pc->data;
96831a100dSStefano Zampini 
97831a100dSStefano Zampini   PetscFunctionBegin;
98831a100dSStefano Zampini   pcis->scaling_factor = scal;
99831a100dSStefano Zampini   PetscFunctionReturn(0);
100831a100dSStefano Zampini }
101831a100dSStefano Zampini EXTERN_C_END
102831a100dSStefano Zampini 
103831a100dSStefano Zampini #undef __FUNCT__
104831a100dSStefano Zampini #define __FUNCT__ "PCISSetSubdomainScalingFactor"
105831a100dSStefano Zampini /*@
106831a100dSStefano Zampini  PCISSetSubdomainScalingFactor - Set scaling factor for PCIS.
107831a100dSStefano Zampini 
108831a100dSStefano Zampini    Not collective
109831a100dSStefano Zampini 
110831a100dSStefano Zampini    Input Parameters:
111831a100dSStefano Zampini +  pc - the preconditioning context
112831a100dSStefano Zampini -  scal - scaling factor for the subdomain
113831a100dSStefano Zampini 
114831a100dSStefano Zampini    Level: intermediate
115831a100dSStefano Zampini 
116831a100dSStefano Zampini    Notes:
117831a100dSStefano Zampini    Intended to use with jumping coefficients cases.
118831a100dSStefano Zampini 
119831a100dSStefano Zampini .seealso: PCBDDC
120831a100dSStefano Zampini @*/
121831a100dSStefano Zampini PetscErrorCode PCISSetSubdomainScalingFactor(PC pc, PetscScalar scal)
122831a100dSStefano Zampini {
123831a100dSStefano Zampini   PetscErrorCode ierr;
124831a100dSStefano Zampini 
125831a100dSStefano Zampini   PetscFunctionBegin;
126831a100dSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
127831a100dSStefano Zampini   ierr = PetscTryMethod(pc,"PCISSetSubdomainScalingFactor_C",(PC,PetscScalar),(pc,scal));CHKERRQ(ierr);
128831a100dSStefano Zampini   PetscFunctionReturn(0);
129831a100dSStefano Zampini }
130831a100dSStefano Zampini 
131b4319ba4SBarry Smith 
132b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */
133b4319ba4SBarry Smith /*
134b4319ba4SBarry Smith    PCISSetUp -
135b4319ba4SBarry Smith */
136b4319ba4SBarry Smith #undef __FUNCT__
137b4319ba4SBarry Smith #define __FUNCT__ "PCISSetUp"
1387087cfbeSBarry Smith PetscErrorCode  PCISSetUp(PC pc)
139b4319ba4SBarry Smith {
140b4319ba4SBarry Smith   PC_IS           *pcis = (PC_IS*)(pc->data);
141b4319ba4SBarry Smith   Mat_IS          *matis = (Mat_IS*)pc->mat->data;
14213f74950SBarry Smith   PetscInt        i;
1436849ba73SBarry Smith   PetscErrorCode  ierr;
144ace3abfcSBarry Smith   PetscBool       flg;
145831a100dSStefano Zampini   Vec    counter;
146b4319ba4SBarry Smith 
147b4319ba4SBarry Smith   PetscFunctionBegin;
148251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->mat,MATIS,&flg);CHKERRQ(ierr);
149e7e72b3dSBarry Smith   if (!flg) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_WRONG,"Preconditioner type of Neumann Neumman requires matrix of type MATIS");
150b4319ba4SBarry Smith 
151b4319ba4SBarry Smith   pcis->pure_neumann = matis->pure_neumann;
152b4319ba4SBarry Smith 
153b4319ba4SBarry Smith   /*
154b4319ba4SBarry Smith     Creating the local vector vec1_N, containing the inverse of the number
155b4319ba4SBarry Smith     of subdomains to which each local node (either owned or ghost)
156b4319ba4SBarry Smith     pertains. To accomplish that, we scatter local vectors of 1's to
157b4319ba4SBarry Smith     a global vector (adding the values); scatter the result back to
158b4319ba4SBarry Smith     local vectors and finally invert the result.
159b4319ba4SBarry Smith   */
160b4319ba4SBarry Smith   ierr = VecDuplicate(matis->x,&pcis->vec1_N);CHKERRQ(ierr);
16123ce1328SBarry Smith   ierr = MatGetVecs(pc->pmat,&counter,0);CHKERRQ(ierr); /* temporary auxiliar vector */
162efb30889SBarry Smith   ierr = VecSet(counter,0.0);CHKERRQ(ierr);
163efb30889SBarry Smith   ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr);
164ca9f406cSSatish Balay   ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
165ca9f406cSSatish Balay   ierr = VecScatterEnd  (matis->ctx,pcis->vec1_N,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
166ca9f406cSSatish Balay   ierr = VecScatterBegin(matis->ctx,counter,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
167ca9f406cSSatish Balay   ierr = VecScatterEnd  (matis->ctx,counter,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
168b4319ba4SBarry Smith   /*
169b4319ba4SBarry Smith     Creating local and global index sets for interior and
170b4319ba4SBarry Smith     inteface nodes. Notice that interior nodes have D[i]==1.0.
171b4319ba4SBarry Smith   */
172b4319ba4SBarry Smith   {
17313f74950SBarry Smith     PetscInt     n_I;
17413f74950SBarry Smith     PetscInt    *idx_I_local,*idx_B_local,*idx_I_global,*idx_B_global;
175b4319ba4SBarry Smith     PetscScalar *array;
176b4319ba4SBarry Smith     /* Identifying interior and interface nodes, in local numbering */
177b4319ba4SBarry Smith     ierr = VecGetSize(pcis->vec1_N,&pcis->n);CHKERRQ(ierr);
178b4319ba4SBarry Smith     ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr);
17913f74950SBarry Smith     ierr = PetscMalloc(pcis->n*sizeof(PetscInt),&idx_I_local);CHKERRQ(ierr);
18013f74950SBarry Smith     ierr = PetscMalloc(pcis->n*sizeof(PetscInt),&idx_B_local);CHKERRQ(ierr);
181b4319ba4SBarry Smith     for (i=0, pcis->n_B=0, n_I=0; i<pcis->n; i++) {
182b4319ba4SBarry Smith       if (array[i] == 1.0) { idx_I_local[n_I]       = i; n_I++;       }
183b4319ba4SBarry Smith       else                 { idx_B_local[pcis->n_B] = i; pcis->n_B++; }
184b4319ba4SBarry Smith     }
185b4319ba4SBarry Smith     /* Getting the global numbering */
186b4319ba4SBarry Smith     idx_B_global = idx_I_local + n_I; /* Just avoiding allocating extra memory, since we have vacant space */
187b4319ba4SBarry Smith     idx_I_global = idx_B_local + pcis->n_B;
188b4319ba4SBarry Smith     ierr = ISLocalToGlobalMappingApply(matis->mapping,pcis->n_B,idx_B_local,idx_B_global);CHKERRQ(ierr);
189b4319ba4SBarry Smith     ierr = ISLocalToGlobalMappingApply(matis->mapping,n_I,      idx_I_local,idx_I_global);CHKERRQ(ierr);
190b4319ba4SBarry Smith     /* Creating the index sets. */
19170b3c8c7SBarry Smith     ierr = ISCreateGeneral(MPI_COMM_SELF,pcis->n_B,idx_B_local,PETSC_COPY_VALUES, &pcis->is_B_local);CHKERRQ(ierr);
19270b3c8c7SBarry Smith     ierr = ISCreateGeneral(MPI_COMM_SELF,pcis->n_B,idx_B_global,PETSC_COPY_VALUES,&pcis->is_B_global);CHKERRQ(ierr);
19370b3c8c7SBarry Smith     ierr = ISCreateGeneral(MPI_COMM_SELF,n_I      ,idx_I_local,PETSC_COPY_VALUES, &pcis->is_I_local);CHKERRQ(ierr);
19470b3c8c7SBarry Smith     ierr = ISCreateGeneral(MPI_COMM_SELF,n_I      ,idx_I_global,PETSC_COPY_VALUES,&pcis->is_I_global);CHKERRQ(ierr);
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 */
237*b965d45eSStefano Zampini   ierr = PetscOptionsGetBool(((PetscObject)pc)->prefix,"-pc_is_use_stiffness_scaling",&pcis->use_stiffness_scaling,PETSC_NULL);CHKERRQ(ierr);
238831a100dSStefano Zampini   if ( !pcis->D ) {
239*b965d45eSStefano Zampini     ierr = VecDuplicate(pcis->vec1_B,&pcis->D);CHKERRQ(ierr);
240*b965d45eSStefano Zampini     if (!pcis->use_stiffness_scaling) {
241*b965d45eSStefano Zampini       ierr = VecSet(pcis->D,pcis->scaling_factor);CHKERRQ(ierr);
242ba1573a8SStefano Zampini     } else {
243*b965d45eSStefano Zampini       ierr = MatGetDiagonal(matis->A,pcis->vec1_N);CHKERRQ(ierr);
244*b965d45eSStefano Zampini       ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
245*b965d45eSStefano Zampini       ierr = VecScatterEnd  (pcis->N_to_B,pcis->vec1_N,pcis->D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
246ba1573a8SStefano Zampini     }
247*b965d45eSStefano Zampini   }
248*b965d45eSStefano 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);
293b4319ba4SBarry Smith       if (!damp_fixed) { fixed_factor = 0.0; }
294acfcf0e5SJed Brown       ierr = PetscOptionsGetBool(((PetscObject)pc_ctx)->prefix,"-pc_is_damp_fixed",&damp_fixed,PETSC_NULL);CHKERRQ(ierr);
295b4319ba4SBarry Smith 
296acfcf0e5SJed Brown       ierr = PetscOptionsGetBool(((PetscObject)pc_ctx)->prefix,"-pc_is_remove_nullspace_fixed",&remove_nullspace_fixed,PETSC_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);
300b4319ba4SBarry Smith       if (!set_damping_factor_floating) { floating_factor = 0.0; }
301acfcf0e5SJed Brown       ierr = PetscOptionsGetBool(((PetscObject)pc_ctx)->prefix,"-pc_is_set_damping_factor_floating",&set_damping_factor_floating,PETSC_NULL);CHKERRQ(ierr);
302b4319ba4SBarry Smith       if (!set_damping_factor_floating) { floating_factor = 1.e-12; }
303b4319ba4SBarry Smith 
304acfcf0e5SJed Brown       ierr = PetscOptionsGetBool(((PetscObject)pc_ctx)->prefix,"-pc_is_not_damp_floating",&not_damp_floating,PETSC_NULL);CHKERRQ(ierr);
305b4319ba4SBarry Smith 
306acfcf0e5SJed Brown       ierr = PetscOptionsGetBool(((PetscObject)pc_ctx)->prefix,"-pc_is_not_remove_nullspace_floating",&not_remove_nullspace_floating,PETSC_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;
315ee512c37SSatish Balay 	  ierr = MatNullSpaceCreate(PETSC_COMM_SELF,PETSC_TRUE,0,PETSC_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;
326ee512c37SSatish Balay 	  ierr = MatNullSpaceCreate(PETSC_COMM_SELF,PETSC_TRUE,0,PETSC_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);
337b4319ba4SBarry Smith   pcis->ISLocalToGlobalMappingGetInfoWasCalled = PETSC_TRUE;
338831a100dSStefano Zampini   ierr = VecDestroy(&counter);CHKERRQ(ierr);
339b4319ba4SBarry Smith   PetscFunctionReturn(0);
340b4319ba4SBarry Smith }
341b4319ba4SBarry Smith 
342b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */
343b4319ba4SBarry Smith /*
344b4319ba4SBarry Smith    PCISDestroy -
345b4319ba4SBarry Smith */
346b4319ba4SBarry Smith #undef __FUNCT__
347b4319ba4SBarry Smith #define __FUNCT__ "PCISDestroy"
3487087cfbeSBarry Smith PetscErrorCode  PCISDestroy(PC pc)
349b4319ba4SBarry Smith {
350b4319ba4SBarry Smith   PC_IS          *pcis = (PC_IS*)(pc->data);
351dfbe8321SBarry Smith   PetscErrorCode ierr;
352b4319ba4SBarry Smith 
353b4319ba4SBarry Smith   PetscFunctionBegin;
354fcfd50ebSBarry Smith   ierr = ISDestroy(&pcis->is_B_local);CHKERRQ(ierr);
355fcfd50ebSBarry Smith   ierr = ISDestroy(&pcis->is_I_local);CHKERRQ(ierr);
356fcfd50ebSBarry Smith   ierr = ISDestroy(&pcis->is_B_global);CHKERRQ(ierr);
357fcfd50ebSBarry Smith   ierr = ISDestroy(&pcis->is_I_global);CHKERRQ(ierr);
358fcfd50ebSBarry Smith   ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr);
359fcfd50ebSBarry Smith   ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr);
360fcfd50ebSBarry Smith   ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr);
361fcfd50ebSBarry Smith   ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr);
362fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->D);CHKERRQ(ierr);
363fcfd50ebSBarry Smith   ierr = KSPDestroy(&pcis->ksp_N);CHKERRQ(ierr);
364fcfd50ebSBarry Smith   ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr);
365fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec1_N);CHKERRQ(ierr);
366fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec2_N);CHKERRQ(ierr);
367fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec1_D);CHKERRQ(ierr);
368fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec2_D);CHKERRQ(ierr);
369fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec3_D);CHKERRQ(ierr);
370fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec1_B);CHKERRQ(ierr);
371fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec2_B);CHKERRQ(ierr);
372fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec3_B);CHKERRQ(ierr);
373fcfd50ebSBarry Smith   ierr = VecDestroy(&pcis->vec1_global);CHKERRQ(ierr);
374fcfd50ebSBarry Smith   ierr = VecScatterDestroy(&pcis->global_to_D);CHKERRQ(ierr);
375fcfd50ebSBarry Smith   ierr = VecScatterDestroy(&pcis->N_to_B);CHKERRQ(ierr);
376fcfd50ebSBarry Smith   ierr = VecScatterDestroy(&pcis->global_to_B);CHKERRQ(ierr);
37705b42c5fSBarry Smith   ierr = PetscFree(pcis->work_N);CHKERRQ(ierr);
378b4319ba4SBarry Smith   if (pcis->ISLocalToGlobalMappingGetInfoWasCalled) {
379b4319ba4SBarry Smith     ierr = ISLocalToGlobalMappingRestoreInfo((ISLocalToGlobalMapping)0,&(pcis->n_neigh),&(pcis->neigh),&(pcis->n_shared),&(pcis->shared));CHKERRQ(ierr);
380b4319ba4SBarry Smith   }
381*b965d45eSStefano Zampini   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCISSetUseStiffnessScaling_C","",PETSC_NULL);CHKERRQ(ierr);
38246caae47SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCISSetSubdomainScalingFactor_C","",PETSC_NULL);CHKERRQ(ierr);
38346caae47SJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCISSetSubdomainDiagonalScaling_C","",PETSC_NULL);CHKERRQ(ierr);
384b4319ba4SBarry Smith   PetscFunctionReturn(0);
385b4319ba4SBarry Smith }
386b4319ba4SBarry Smith 
387b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */
388b4319ba4SBarry Smith /*
389b4319ba4SBarry Smith    PCISCreate -
390b4319ba4SBarry Smith */
391b4319ba4SBarry Smith #undef __FUNCT__
392b4319ba4SBarry Smith #define __FUNCT__ "PCISCreate"
3937087cfbeSBarry Smith PetscErrorCode  PCISCreate(PC pc)
394b4319ba4SBarry Smith {
395b4319ba4SBarry Smith   PC_IS *pcis = (PC_IS*)(pc->data);
396831a100dSStefano Zampini   PetscErrorCode ierr;
397b4319ba4SBarry Smith 
398b4319ba4SBarry Smith   PetscFunctionBegin;
399b4319ba4SBarry Smith   pcis->is_B_local  = 0;
400b4319ba4SBarry Smith   pcis->is_I_local  = 0;
401b4319ba4SBarry Smith   pcis->is_B_global = 0;
402b4319ba4SBarry Smith   pcis->is_I_global = 0;
403b4319ba4SBarry Smith   pcis->A_II        = 0;
404b4319ba4SBarry Smith   pcis->A_IB        = 0;
405b4319ba4SBarry Smith   pcis->A_BI        = 0;
406b4319ba4SBarry Smith   pcis->A_BB        = 0;
407b4319ba4SBarry Smith   pcis->D           = 0;
408b4319ba4SBarry Smith   pcis->ksp_N      = 0;
409b4319ba4SBarry Smith   pcis->ksp_D      = 0;
410b4319ba4SBarry Smith   pcis->vec1_N      = 0;
411b4319ba4SBarry Smith   pcis->vec2_N      = 0;
412b4319ba4SBarry Smith   pcis->vec1_D      = 0;
413b4319ba4SBarry Smith   pcis->vec2_D      = 0;
414b4319ba4SBarry Smith   pcis->vec3_D      = 0;
415b4319ba4SBarry Smith   pcis->vec1_B      = 0;
416b4319ba4SBarry Smith   pcis->vec2_B      = 0;
417b4319ba4SBarry Smith   pcis->vec3_B      = 0;
418b4319ba4SBarry Smith   pcis->vec1_global = 0;
419b4319ba4SBarry Smith   pcis->work_N      = 0;
420b4319ba4SBarry Smith   pcis->global_to_D = 0;
421b4319ba4SBarry Smith   pcis->N_to_B      = 0;
422b4319ba4SBarry Smith   pcis->global_to_B = 0;
423b4319ba4SBarry Smith   pcis->ISLocalToGlobalMappingGetInfoWasCalled = PETSC_FALSE;
424831a100dSStefano Zampini   pcis->scaling_factor = 1.0;
425831a100dSStefano Zampini   /* composing functions */
426*b965d45eSStefano Zampini   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCISSetUseStiffnessScaling_C","PCISSetUseStiffnessScaling_IS",
427*b965d45eSStefano Zampini                     PCISSetUseStiffnessScaling_IS);CHKERRQ(ierr);
428831a100dSStefano Zampini   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCISSetSubdomainScalingFactor_C","PCISSetSubdomainScalingFactor_IS",
429831a100dSStefano Zampini                     PCISSetSubdomainScalingFactor_IS);CHKERRQ(ierr);
430ba1573a8SStefano Zampini   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCISSetSubdomainDiagonalScaling_C","PCISSetSubdomainDiagonalScaling_IS",
431ba1573a8SStefano Zampini                     PCISSetSubdomainDiagonalScaling_IS);CHKERRQ(ierr);
432b4319ba4SBarry Smith   PetscFunctionReturn(0);
433b4319ba4SBarry Smith }
434b4319ba4SBarry Smith 
435b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */
436b4319ba4SBarry Smith /*
437b4319ba4SBarry Smith    PCISApplySchur -
438b4319ba4SBarry Smith 
439b4319ba4SBarry Smith    Input parameters:
440b4319ba4SBarry Smith .  pc - preconditioner context
441b4319ba4SBarry Smith .  v - vector to which the Schur complement is to be applied (it is NOT modified inside this function, UNLESS vec2_B is null)
442b4319ba4SBarry Smith 
443b4319ba4SBarry Smith    Output parameters:
444b4319ba4SBarry Smith .  vec1_B - result of Schur complement applied to chunk
445b4319ba4SBarry Smith .  vec2_B - garbage (used as work space), or null (and v is used as workspace)
446b4319ba4SBarry Smith .  vec1_D - garbage (used as work space)
447b4319ba4SBarry Smith .  vec2_D - garbage (used as work space)
448b4319ba4SBarry Smith 
449b4319ba4SBarry Smith */
450b4319ba4SBarry Smith #undef __FUNCT__
451831a100dSStefano Zampini #define __FUNCT__ "PCISApplySchur"
4527087cfbeSBarry Smith PetscErrorCode  PCISApplySchur(PC pc, Vec v, Vec vec1_B, Vec vec2_B, Vec vec1_D, Vec vec2_D)
453b4319ba4SBarry Smith {
454dfbe8321SBarry Smith   PetscErrorCode ierr;
455b4319ba4SBarry Smith   PC_IS          *pcis = (PC_IS*)(pc->data);
456b4319ba4SBarry Smith 
457b4319ba4SBarry Smith   PetscFunctionBegin;
45813f74950SBarry Smith   if (!vec2_B) { vec2_B = v; }
459b4319ba4SBarry Smith 
460b4319ba4SBarry Smith   ierr = MatMult(pcis->A_BB,v,vec1_B);CHKERRQ(ierr);
461b4319ba4SBarry Smith   ierr = MatMult(pcis->A_IB,v,vec1_D);CHKERRQ(ierr);
46223ce1328SBarry Smith   ierr = KSPSolve(pcis->ksp_D,vec1_D,vec2_D);CHKERRQ(ierr);
463b4319ba4SBarry Smith   ierr = MatMult(pcis->A_BI,vec2_D,vec2_B);CHKERRQ(ierr);
464efb30889SBarry Smith   ierr = VecAXPY(vec1_B,-1.0,vec2_B);CHKERRQ(ierr);
465b4319ba4SBarry Smith   PetscFunctionReturn(0);
466b4319ba4SBarry Smith }
467b4319ba4SBarry Smith 
468b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */
469b4319ba4SBarry Smith /*
470b4319ba4SBarry Smith    PCISScatterArrayNToVecB - Scatters interface node values from a big array (of all local nodes, interior or interface,
471b4319ba4SBarry Smith    including ghosts) into an interface vector, when in SCATTER_FORWARD mode, or vice-versa, when in SCATTER_REVERSE
472b4319ba4SBarry Smith    mode.
473b4319ba4SBarry Smith 
474b4319ba4SBarry Smith    Input parameters:
475b4319ba4SBarry Smith .  pc - preconditioner context
476b4319ba4SBarry Smith .  array_N - [when in SCATTER_FORWARD mode] Array to be scattered into the vector
477b4319ba4SBarry Smith .  v_B - [when in SCATTER_REVERSE mode] Vector to be scattered into the array
478b4319ba4SBarry Smith 
479b4319ba4SBarry Smith    Output parameter:
480b4319ba4SBarry Smith .  array_N - [when in SCATTER_REVERSE mode] Array to receive the scattered vector
481b4319ba4SBarry Smith .  v_B - [when in SCATTER_FORWARD mode] Vector to receive the scattered array
482b4319ba4SBarry Smith 
483b4319ba4SBarry Smith    Notes:
484b4319ba4SBarry Smith    The entries in the array that do not correspond to interface nodes remain unaltered.
485b4319ba4SBarry Smith */
486b4319ba4SBarry Smith #undef __FUNCT__
487b4319ba4SBarry Smith #define __FUNCT__ "PCISScatterArrayNToVecB"
4887087cfbeSBarry Smith PetscErrorCode  PCISScatterArrayNToVecB (PetscScalar *array_N, Vec v_B, InsertMode imode, ScatterMode smode, PC pc)
489b4319ba4SBarry Smith {
4905d0c19d7SBarry Smith   PetscInt       i;
4915d0c19d7SBarry Smith   const PetscInt *idex;
4926849ba73SBarry Smith   PetscErrorCode ierr;
493b4319ba4SBarry Smith   PetscScalar    *array_B;
494b4319ba4SBarry Smith   PC_IS          *pcis = (PC_IS*)(pc->data);
495b4319ba4SBarry Smith 
496b4319ba4SBarry Smith   PetscFunctionBegin;
497b4319ba4SBarry Smith   ierr = VecGetArray(v_B,&array_B);CHKERRQ(ierr);
498b4319ba4SBarry Smith   ierr = ISGetIndices(pcis->is_B_local,&idex);CHKERRQ(ierr);
499b4319ba4SBarry Smith 
500b4319ba4SBarry Smith   if (smode == SCATTER_FORWARD) {
501b4319ba4SBarry Smith     if (imode == INSERT_VALUES) {
502b4319ba4SBarry Smith       for (i=0; i<pcis->n_B; i++) { array_B[i]  = array_N[idex[i]]; }
503b4319ba4SBarry Smith     } else {  /* ADD_VALUES */
504b4319ba4SBarry Smith       for (i=0; i<pcis->n_B; i++) { array_B[i] += array_N[idex[i]]; }
505b4319ba4SBarry Smith     }
506b4319ba4SBarry Smith   } else {  /* SCATTER_REVERSE */
507b4319ba4SBarry Smith     if (imode == INSERT_VALUES) {
508b4319ba4SBarry Smith       for (i=0; i<pcis->n_B; i++) { array_N[idex[i]]  = array_B[i]; }
509b4319ba4SBarry Smith     } else {  /* ADD_VALUES */
510b4319ba4SBarry Smith       for (i=0; i<pcis->n_B; i++) { array_N[idex[i]] += array_B[i]; }
511b4319ba4SBarry Smith     }
512b4319ba4SBarry Smith   }
513b4319ba4SBarry Smith   ierr = ISRestoreIndices(pcis->is_B_local,&idex);CHKERRQ(ierr);
514b4319ba4SBarry Smith   ierr = VecRestoreArray(v_B,&array_B);CHKERRQ(ierr);
515b4319ba4SBarry Smith   PetscFunctionReturn(0);
516b4319ba4SBarry Smith }
517b4319ba4SBarry Smith 
518b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */
519b4319ba4SBarry Smith /*
520b4319ba4SBarry Smith    PCISApplyInvSchur - Solves the Neumann problem related to applying the inverse of the Schur complement.
521b4319ba4SBarry Smith    More precisely, solves the problem:
522b4319ba4SBarry Smith                                         [ A_II  A_IB ] [ . ]   [ 0 ]
523b4319ba4SBarry Smith                                         [            ] [   ] = [   ]
524b4319ba4SBarry Smith                                         [ A_BI  A_BB ] [ x ]   [ b ]
525b4319ba4SBarry Smith 
526b4319ba4SBarry Smith    Input parameters:
527b4319ba4SBarry Smith .  pc - preconditioner context
528b4319ba4SBarry Smith .  b - vector of local interface nodes (including ghosts)
529b4319ba4SBarry Smith 
530b4319ba4SBarry Smith    Output parameters:
531b4319ba4SBarry Smith .  x - vector of local interface nodes (including ghosts); returns the application of the inverse of the Schur
532b4319ba4SBarry Smith        complement to b
533b4319ba4SBarry Smith .  vec1_N - vector of local nodes (interior and interface, including ghosts); returns garbage (used as work space)
534b4319ba4SBarry Smith .  vec2_N - vector of local nodes (interior and interface, including ghosts); returns garbage (used as work space)
535b4319ba4SBarry Smith 
536b4319ba4SBarry Smith */
537b4319ba4SBarry Smith #undef __FUNCT__
538b4319ba4SBarry Smith #define __FUNCT__ "PCISApplyInvSchur"
5397087cfbeSBarry Smith PetscErrorCode  PCISApplyInvSchur (PC pc, Vec b, Vec x, Vec vec1_N, Vec vec2_N)
540b4319ba4SBarry Smith {
541dfbe8321SBarry Smith   PetscErrorCode ierr;
542b4319ba4SBarry Smith   PC_IS          *pcis = (PC_IS*)(pc->data);
543b4319ba4SBarry Smith 
544b4319ba4SBarry Smith   PetscFunctionBegin;
545b4319ba4SBarry Smith   /*
546b4319ba4SBarry Smith     Neumann solvers.
547b4319ba4SBarry Smith     Applying the inverse of the local Schur complement, i.e, solving a Neumann
548b4319ba4SBarry Smith     Problem with zero at the interior nodes of the RHS and extracting the interface
549b4319ba4SBarry Smith     part of the solution. inverse Schur complement is applied to b and the result
550b4319ba4SBarry Smith     is stored in x.
551b4319ba4SBarry Smith   */
552b4319ba4SBarry Smith   /* Setting the RHS vec1_N */
553efb30889SBarry Smith   ierr = VecSet(vec1_N,0.0);CHKERRQ(ierr);
554ca9f406cSSatish Balay   ierr = VecScatterBegin(pcis->N_to_B,b,vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
555ca9f406cSSatish Balay   ierr = VecScatterEnd  (pcis->N_to_B,b,vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
556b4319ba4SBarry Smith   /* Checking for consistency of the RHS */
557b4319ba4SBarry Smith   {
558ace3abfcSBarry Smith     PetscBool  flg = PETSC_FALSE;
559acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(PETSC_NULL,"-pc_is_check_consistency",&flg,PETSC_NULL);CHKERRQ(ierr);
560b4319ba4SBarry Smith     if (flg) {
561b4319ba4SBarry Smith       PetscScalar average;
5623050cee2SBarry Smith       PetscViewer viewer;
5637adad957SLisandro Dalcin       ierr = PetscViewerASCIIGetStdout(((PetscObject)pc)->comm,&viewer);CHKERRQ(ierr);
5643050cee2SBarry Smith 
565b4319ba4SBarry Smith       ierr = VecSum(vec1_N,&average);CHKERRQ(ierr);
566b4319ba4SBarry Smith       average = average / ((PetscReal)pcis->n);
5677b23a99aSBarry Smith       ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr);
568b4319ba4SBarry Smith       if (pcis->pure_neumann) {
5699f73f8ecSBarry Smith         ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d is floating. Average = % 1.14e\n",PetscGlobalRank,PetscAbsScalar(average));CHKERRQ(ierr);
570b4319ba4SBarry Smith       } else {
5719f73f8ecSBarry Smith         ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d is fixed.    Average = % 1.14e\n",PetscGlobalRank,PetscAbsScalar(average));CHKERRQ(ierr);
572b4319ba4SBarry Smith       }
5733050cee2SBarry Smith       ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
5747b23a99aSBarry Smith       ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr);
575b4319ba4SBarry Smith     }
576b4319ba4SBarry Smith   }
577b4319ba4SBarry Smith   /* Solving the system for vec2_N */
57823ce1328SBarry Smith   ierr = KSPSolve(pcis->ksp_N,vec1_N,vec2_N);CHKERRQ(ierr);
579b4319ba4SBarry Smith   /* Extracting the local interface vector out of the solution */
580ca9f406cSSatish Balay   ierr = VecScatterBegin(pcis->N_to_B,vec2_N,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
581ca9f406cSSatish Balay   ierr = VecScatterEnd  (pcis->N_to_B,vec2_N,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
582b4319ba4SBarry Smith   PetscFunctionReturn(0);
583b4319ba4SBarry Smith }
584b4319ba4SBarry Smith 
585b4319ba4SBarry Smith 
586b4319ba4SBarry Smith 
587b4319ba4SBarry Smith 
588b4319ba4SBarry Smith 
589b4319ba4SBarry Smith 
590b4319ba4SBarry Smith 
591b4319ba4SBarry Smith 
592b4319ba4SBarry Smith 
593