xref: /petsc/src/ksp/pc/impls/bddc/bddcscalingbasic.c (revision 28b400f66ebc7ae0049166a2294dfcd3df27e64b)
1ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h>
2ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h>
372b8c272SStefano Zampini #include <petscblaslapack.h>
4839e9adbSstefano_zampini #include <../src/mat/impls/dense/seq/dense.h>
5674ae819SStefano Zampini 
634a97f8cSStefano Zampini /* prototypes for deluxe functions */
734a97f8cSStefano Zampini static PetscErrorCode PCBDDCScalingCreate_Deluxe(PC);
834a97f8cSStefano Zampini static PetscErrorCode PCBDDCScalingDestroy_Deluxe(PC);
934a97f8cSStefano Zampini static PetscErrorCode PCBDDCScalingSetUp_Deluxe(PC);
105a95e1ceSStefano Zampini static PetscErrorCode PCBDDCScalingSetUp_Deluxe_Private(PC);
1134a97f8cSStefano Zampini static PetscErrorCode PCBDDCScalingReset_Deluxe_Solvers(PCBDDCDeluxeScaling);
12674ae819SStefano Zampini 
13839e9adbSstefano_zampini static PetscErrorCode PCBDDCMatTransposeMatSolve_SeqDense(Mat A,Mat B,Mat X)
14839e9adbSstefano_zampini {
15839e9adbSstefano_zampini   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
161683a169SBarry Smith   const PetscScalar *b;
171683a169SBarry Smith   PetscScalar       *x;
18839e9adbSstefano_zampini   PetscInt          n;
19839e9adbSstefano_zampini   PetscBLASInt      nrhs,info,m;
20839e9adbSstefano_zampini   PetscBool         flg;
21839e9adbSstefano_zampini 
22839e9adbSstefano_zampini   PetscFunctionBegin;
235f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscBLASIntCast(A->rmap->n,&m));
245f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL));
25*28b400f6SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
265f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL));
27*28b400f6SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
28839e9adbSstefano_zampini 
295f80ce2aSJacob Faibussowitsch   CHKERRQ(MatGetSize(B,NULL,&n));
305f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscBLASIntCast(n,&nrhs));
315f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDenseGetArrayRead(B,&b));
325f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDenseGetArray(X,&x));
335f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscArraycpy(x,b,m*nrhs));
345f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDenseRestoreArrayRead(B,&b));
35839e9adbSstefano_zampini 
36839e9adbSstefano_zampini   if (A->factortype == MAT_FACTOR_LU) {
37839e9adbSstefano_zampini     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
38*28b400f6SJacob Faibussowitsch     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
393829e7e6SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only LU factor supported");
40839e9adbSstefano_zampini 
415f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDenseRestoreArray(X,&x));
425f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscLogFlops(nrhs*(2.0*m*m - m)));
43839e9adbSstefano_zampini   PetscFunctionReturn(0);
44839e9adbSstefano_zampini }
45839e9adbSstefano_zampini 
46674ae819SStefano Zampini static PetscErrorCode PCBDDCScalingExtension_Basic(PC pc, Vec local_interface_vector, Vec global_vector)
47674ae819SStefano Zampini {
48674ae819SStefano Zampini   PC_IS*         pcis = (PC_IS*)pc->data;
49674ae819SStefano Zampini   PC_BDDC*       pcbddc = (PC_BDDC*)pc->data;
50674ae819SStefano Zampini 
51674ae819SStefano Zampini   PetscFunctionBegin;
52674ae819SStefano Zampini   /* Apply partition of unity */
535f80ce2aSJacob Faibussowitsch   CHKERRQ(VecPointwiseMult(pcbddc->work_scaling,pcis->D,local_interface_vector));
545f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSet(global_vector,0.0));
555f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(pcis->global_to_B,pcbddc->work_scaling,global_vector,ADD_VALUES,SCATTER_REVERSE));
565f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(pcis->global_to_B,pcbddc->work_scaling,global_vector,ADD_VALUES,SCATTER_REVERSE));
57674ae819SStefano Zampini   PetscFunctionReturn(0);
58674ae819SStefano Zampini }
59674ae819SStefano Zampini 
60674ae819SStefano Zampini static PetscErrorCode PCBDDCScalingExtension_Deluxe(PC pc, Vec x, Vec y)
61674ae819SStefano Zampini {
62674ae819SStefano Zampini   PC_IS*              pcis=(PC_IS*)pc->data;
63674ae819SStefano Zampini   PC_BDDC*            pcbddc=(PC_BDDC*)pc->data;
64674ae819SStefano Zampini   PCBDDCDeluxeScaling deluxe_ctx = pcbddc->deluxe_ctx;
65674ae819SStefano Zampini 
66674ae819SStefano Zampini   PetscFunctionBegin;
675f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSet(pcbddc->work_scaling,0.0));
685f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSet(y,0.0));
695a95e1ceSStefano Zampini   if (deluxe_ctx->n_simple) { /* scale deluxe vertices using diagonal scaling */
705a95e1ceSStefano Zampini     PetscInt          i;
712b095fd8SStefano Zampini     const PetscScalar *array_x,*array_D;
722b095fd8SStefano Zampini     PetscScalar       *array;
735f80ce2aSJacob Faibussowitsch     CHKERRQ(VecGetArrayRead(x,&array_x));
745f80ce2aSJacob Faibussowitsch     CHKERRQ(VecGetArrayRead(pcis->D,&array_D));
755f80ce2aSJacob Faibussowitsch     CHKERRQ(VecGetArray(pcbddc->work_scaling,&array));
76674ae819SStefano Zampini     for (i=0;i<deluxe_ctx->n_simple;i++) {
77674ae819SStefano Zampini       array[deluxe_ctx->idx_simple_B[i]] = array_x[deluxe_ctx->idx_simple_B[i]]*array_D[deluxe_ctx->idx_simple_B[i]];
78674ae819SStefano Zampini     }
795f80ce2aSJacob Faibussowitsch     CHKERRQ(VecRestoreArray(pcbddc->work_scaling,&array));
805f80ce2aSJacob Faibussowitsch     CHKERRQ(VecRestoreArrayRead(pcis->D,&array_D));
815f80ce2aSJacob Faibussowitsch     CHKERRQ(VecRestoreArrayRead(x,&array_x));
8234a97f8cSStefano Zampini   }
83ac632422SStefano Zampini   /* sequential part : all problems and Schur applications collapsed into a single matrix vector multiplication or a matvec and a solve */
845a95e1ceSStefano Zampini   if (deluxe_ctx->seq_mat) {
8572b8c272SStefano Zampini     PetscInt i;
8672b8c272SStefano Zampini     for (i=0;i<deluxe_ctx->seq_n;i++) {
8716e386b8SStefano Zampini       if (deluxe_ctx->change) {
885f80ce2aSJacob Faibussowitsch         CHKERRQ(VecScatterBegin(deluxe_ctx->seq_scctx[i],x,deluxe_ctx->seq_work2[i],INSERT_VALUES,SCATTER_FORWARD));
895f80ce2aSJacob Faibussowitsch         CHKERRQ(VecScatterEnd(deluxe_ctx->seq_scctx[i],x,deluxe_ctx->seq_work2[i],INSERT_VALUES,SCATTER_FORWARD));
9072b8c272SStefano Zampini         if (deluxe_ctx->change_with_qr) {
9172b8c272SStefano Zampini           Mat change;
9272b8c272SStefano Zampini 
935f80ce2aSJacob Faibussowitsch           CHKERRQ(KSPGetOperators(deluxe_ctx->change[i],&change,NULL));
945f80ce2aSJacob Faibussowitsch           CHKERRQ(MatMultTranspose(change,deluxe_ctx->seq_work2[i],deluxe_ctx->seq_work1[i]));
9572b8c272SStefano Zampini         } else {
965f80ce2aSJacob Faibussowitsch           CHKERRQ(KSPSolve(deluxe_ctx->change[i],deluxe_ctx->seq_work2[i],deluxe_ctx->seq_work1[i]));
9716e386b8SStefano Zampini         }
9872b8c272SStefano Zampini       } else {
995f80ce2aSJacob Faibussowitsch         CHKERRQ(VecScatterBegin(deluxe_ctx->seq_scctx[i],x,deluxe_ctx->seq_work1[i],INSERT_VALUES,SCATTER_FORWARD));
1005f80ce2aSJacob Faibussowitsch         CHKERRQ(VecScatterEnd(deluxe_ctx->seq_scctx[i],x,deluxe_ctx->seq_work1[i],INSERT_VALUES,SCATTER_FORWARD));
10172b8c272SStefano Zampini       }
1025f80ce2aSJacob Faibussowitsch       CHKERRQ(MatMultTranspose(deluxe_ctx->seq_mat[i],deluxe_ctx->seq_work1[i],deluxe_ctx->seq_work2[i]));
10372b8c272SStefano Zampini       if (deluxe_ctx->seq_mat_inv_sum[i]) {
10472b8c272SStefano Zampini         PetscScalar *x;
10572b8c272SStefano Zampini 
1065f80ce2aSJacob Faibussowitsch         CHKERRQ(VecGetArray(deluxe_ctx->seq_work2[i],&x));
1075f80ce2aSJacob Faibussowitsch         CHKERRQ(VecPlaceArray(deluxe_ctx->seq_work1[i],x));
1085f80ce2aSJacob Faibussowitsch         CHKERRQ(VecRestoreArray(deluxe_ctx->seq_work2[i],&x));
1095f80ce2aSJacob Faibussowitsch         CHKERRQ(MatSolveTranspose(deluxe_ctx->seq_mat_inv_sum[i],deluxe_ctx->seq_work1[i],deluxe_ctx->seq_work2[i]));
1105f80ce2aSJacob Faibussowitsch         CHKERRQ(VecResetArray(deluxe_ctx->seq_work1[i]));
111ac632422SStefano Zampini       }
11216e386b8SStefano Zampini       if (deluxe_ctx->change) {
11316e386b8SStefano Zampini         Mat change;
11416e386b8SStefano Zampini 
1155f80ce2aSJacob Faibussowitsch         CHKERRQ(KSPGetOperators(deluxe_ctx->change[i],&change,NULL));
1165f80ce2aSJacob Faibussowitsch         CHKERRQ(MatMult(change,deluxe_ctx->seq_work2[i],deluxe_ctx->seq_work1[i]));
1175f80ce2aSJacob Faibussowitsch         CHKERRQ(VecScatterBegin(deluxe_ctx->seq_scctx[i],deluxe_ctx->seq_work1[i],pcbddc->work_scaling,INSERT_VALUES,SCATTER_REVERSE));
1185f80ce2aSJacob Faibussowitsch         CHKERRQ(VecScatterEnd(deluxe_ctx->seq_scctx[i],deluxe_ctx->seq_work1[i],pcbddc->work_scaling,INSERT_VALUES,SCATTER_REVERSE));
11916e386b8SStefano Zampini       } else {
1205f80ce2aSJacob Faibussowitsch         CHKERRQ(VecScatterBegin(deluxe_ctx->seq_scctx[i],deluxe_ctx->seq_work2[i],pcbddc->work_scaling,INSERT_VALUES,SCATTER_REVERSE));
1215f80ce2aSJacob Faibussowitsch         CHKERRQ(VecScatterEnd(deluxe_ctx->seq_scctx[i],deluxe_ctx->seq_work2[i],pcbddc->work_scaling,INSERT_VALUES,SCATTER_REVERSE));
12272b8c272SStefano Zampini       }
123674ae819SStefano Zampini     }
12416e386b8SStefano Zampini   }
125674ae819SStefano Zampini   /* put local boundary part in global vector */
1265f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(pcis->global_to_B,pcbddc->work_scaling,y,ADD_VALUES,SCATTER_REVERSE));
1275f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(pcis->global_to_B,pcbddc->work_scaling,y,ADD_VALUES,SCATTER_REVERSE));
128674ae819SStefano Zampini   PetscFunctionReturn(0);
129674ae819SStefano Zampini }
130674ae819SStefano Zampini 
131674ae819SStefano Zampini PetscErrorCode PCBDDCScalingExtension(PC pc, Vec local_interface_vector, Vec global_vector)
132674ae819SStefano Zampini {
133674ae819SStefano Zampini   PC_BDDC        *pcbddc=(PC_BDDC*)pc->data;
134674ae819SStefano Zampini 
135674ae819SStefano Zampini   PetscFunctionBegin;
136674ae819SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
137674ae819SStefano Zampini   PetscValidHeaderSpecific(local_interface_vector,VEC_CLASSID,2);
138674ae819SStefano Zampini   PetscValidHeaderSpecific(global_vector,VEC_CLASSID,3);
1392c71b3e2SJacob Faibussowitsch   PetscCheckFalse(local_interface_vector == pcbddc->work_scaling,PETSC_COMM_SELF,PETSC_ERR_SUP,"Local vector cannot be pcbddc->work_scaling!");
1405f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscUseMethod(pc,"PCBDDCScalingExtension_C",(PC,Vec,Vec),(pc,local_interface_vector,global_vector)));
141674ae819SStefano Zampini   PetscFunctionReturn(0);
142674ae819SStefano Zampini }
143674ae819SStefano Zampini 
144674ae819SStefano Zampini static PetscErrorCode PCBDDCScalingRestriction_Basic(PC pc, Vec global_vector, Vec local_interface_vector)
145674ae819SStefano Zampini {
146674ae819SStefano Zampini   PC_IS          *pcis = (PC_IS*)pc->data;
147674ae819SStefano Zampini 
148674ae819SStefano Zampini   PetscFunctionBegin;
1495f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(pcis->global_to_B,global_vector,local_interface_vector,INSERT_VALUES,SCATTER_FORWARD));
1505f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(pcis->global_to_B,global_vector,local_interface_vector,INSERT_VALUES,SCATTER_FORWARD));
151674ae819SStefano Zampini   /* Apply partition of unity */
1525f80ce2aSJacob Faibussowitsch   CHKERRQ(VecPointwiseMult(local_interface_vector,pcis->D,local_interface_vector));
153674ae819SStefano Zampini   PetscFunctionReturn(0);
154674ae819SStefano Zampini }
155674ae819SStefano Zampini 
156674ae819SStefano Zampini static PetscErrorCode PCBDDCScalingRestriction_Deluxe(PC pc, Vec x, Vec y)
157674ae819SStefano Zampini {
158674ae819SStefano Zampini   PC_IS*              pcis=(PC_IS*)pc->data;
159674ae819SStefano Zampini   PC_BDDC*            pcbddc=(PC_BDDC*)pc->data;
160674ae819SStefano Zampini   PCBDDCDeluxeScaling deluxe_ctx = pcbddc->deluxe_ctx;
161674ae819SStefano Zampini 
162674ae819SStefano Zampini   PetscFunctionBegin;
163674ae819SStefano Zampini   /* get local boundary part of global vector */
1645f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(pcis->global_to_B,x,y,INSERT_VALUES,SCATTER_FORWARD));
1655f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(pcis->global_to_B,x,y,INSERT_VALUES,SCATTER_FORWARD));
1665a95e1ceSStefano Zampini   if (deluxe_ctx->n_simple) { /* scale deluxe vertices using diagonal scaling */
1675a95e1ceSStefano Zampini     PetscInt          i;
1682b095fd8SStefano Zampini     PetscScalar       *array_y;
1692b095fd8SStefano Zampini     const PetscScalar *array_D;
1705f80ce2aSJacob Faibussowitsch     CHKERRQ(VecGetArray(y,&array_y));
1715f80ce2aSJacob Faibussowitsch     CHKERRQ(VecGetArrayRead(pcis->D,&array_D));
172674ae819SStefano Zampini     for (i=0;i<deluxe_ctx->n_simple;i++) {
173674ae819SStefano Zampini       array_y[deluxe_ctx->idx_simple_B[i]] *= array_D[deluxe_ctx->idx_simple_B[i]];
174674ae819SStefano Zampini     }
1755f80ce2aSJacob Faibussowitsch     CHKERRQ(VecRestoreArrayRead(pcis->D,&array_D));
1765f80ce2aSJacob Faibussowitsch     CHKERRQ(VecRestoreArray(y,&array_y));
17734a97f8cSStefano Zampini   }
178729c86d3Sstefano_zampini   /* sequential part : all problems and Schur applications collapsed into a single matrix vector multiplication or a matvec and a solve */
1795a95e1ceSStefano Zampini   if (deluxe_ctx->seq_mat) {
18072b8c272SStefano Zampini     PetscInt i;
18172b8c272SStefano Zampini     for (i=0;i<deluxe_ctx->seq_n;i++) {
18216e386b8SStefano Zampini       if (deluxe_ctx->change) {
18316e386b8SStefano Zampini         Mat change;
18416e386b8SStefano Zampini 
1855f80ce2aSJacob Faibussowitsch         CHKERRQ(VecScatterBegin(deluxe_ctx->seq_scctx[i],y,deluxe_ctx->seq_work2[i],INSERT_VALUES,SCATTER_FORWARD));
1865f80ce2aSJacob Faibussowitsch         CHKERRQ(VecScatterEnd(deluxe_ctx->seq_scctx[i],y,deluxe_ctx->seq_work2[i],INSERT_VALUES,SCATTER_FORWARD));
1875f80ce2aSJacob Faibussowitsch         CHKERRQ(KSPGetOperators(deluxe_ctx->change[i],&change,NULL));
1885f80ce2aSJacob Faibussowitsch         CHKERRQ(MatMultTranspose(change,deluxe_ctx->seq_work2[i],deluxe_ctx->seq_work1[i]));
18916e386b8SStefano Zampini       } else {
1905f80ce2aSJacob Faibussowitsch         CHKERRQ(VecScatterBegin(deluxe_ctx->seq_scctx[i],y,deluxe_ctx->seq_work1[i],INSERT_VALUES,SCATTER_FORWARD));
1915f80ce2aSJacob Faibussowitsch         CHKERRQ(VecScatterEnd(deluxe_ctx->seq_scctx[i],y,deluxe_ctx->seq_work1[i],INSERT_VALUES,SCATTER_FORWARD));
19216e386b8SStefano Zampini       }
19372b8c272SStefano Zampini       if (deluxe_ctx->seq_mat_inv_sum[i]) {
19472b8c272SStefano Zampini         PetscScalar *x;
19572b8c272SStefano Zampini 
1965f80ce2aSJacob Faibussowitsch         CHKERRQ(VecGetArray(deluxe_ctx->seq_work1[i],&x));
1975f80ce2aSJacob Faibussowitsch         CHKERRQ(VecPlaceArray(deluxe_ctx->seq_work2[i],x));
1985f80ce2aSJacob Faibussowitsch         CHKERRQ(VecRestoreArray(deluxe_ctx->seq_work1[i],&x));
1995f80ce2aSJacob Faibussowitsch         CHKERRQ(MatSolve(deluxe_ctx->seq_mat_inv_sum[i],deluxe_ctx->seq_work1[i],deluxe_ctx->seq_work2[i]));
2005f80ce2aSJacob Faibussowitsch         CHKERRQ(VecResetArray(deluxe_ctx->seq_work2[i]));
201ac632422SStefano Zampini       }
2025f80ce2aSJacob Faibussowitsch       CHKERRQ(MatMult(deluxe_ctx->seq_mat[i],deluxe_ctx->seq_work1[i],deluxe_ctx->seq_work2[i]));
20316e386b8SStefano Zampini       if (deluxe_ctx->change) {
20472b8c272SStefano Zampini         if (deluxe_ctx->change_with_qr) {
20572b8c272SStefano Zampini           Mat change;
20672b8c272SStefano Zampini 
2075f80ce2aSJacob Faibussowitsch           CHKERRQ(KSPGetOperators(deluxe_ctx->change[i],&change,NULL));
2085f80ce2aSJacob Faibussowitsch           CHKERRQ(MatMult(change,deluxe_ctx->seq_work2[i],deluxe_ctx->seq_work1[i]));
20972b8c272SStefano Zampini         } else {
2105f80ce2aSJacob Faibussowitsch           CHKERRQ(KSPSolveTranspose(deluxe_ctx->change[i],deluxe_ctx->seq_work2[i],deluxe_ctx->seq_work1[i]));
21116e386b8SStefano Zampini         }
2125f80ce2aSJacob Faibussowitsch         CHKERRQ(VecScatterBegin(deluxe_ctx->seq_scctx[i],deluxe_ctx->seq_work1[i],y,INSERT_VALUES,SCATTER_REVERSE));
2135f80ce2aSJacob Faibussowitsch         CHKERRQ(VecScatterEnd(deluxe_ctx->seq_scctx[i],deluxe_ctx->seq_work1[i],y,INSERT_VALUES,SCATTER_REVERSE));
21472b8c272SStefano Zampini       } else {
2155f80ce2aSJacob Faibussowitsch         CHKERRQ(VecScatterBegin(deluxe_ctx->seq_scctx[i],deluxe_ctx->seq_work2[i],y,INSERT_VALUES,SCATTER_REVERSE));
2165f80ce2aSJacob Faibussowitsch         CHKERRQ(VecScatterEnd(deluxe_ctx->seq_scctx[i],deluxe_ctx->seq_work2[i],y,INSERT_VALUES,SCATTER_REVERSE));
21772b8c272SStefano Zampini       }
21872b8c272SStefano Zampini     }
219674ae819SStefano Zampini   }
220674ae819SStefano Zampini   PetscFunctionReturn(0);
221674ae819SStefano Zampini }
222674ae819SStefano Zampini 
223674ae819SStefano Zampini PetscErrorCode PCBDDCScalingRestriction(PC pc, Vec global_vector, Vec local_interface_vector)
224674ae819SStefano Zampini {
225674ae819SStefano Zampini   PC_BDDC        *pcbddc=(PC_BDDC*)pc->data;
226674ae819SStefano Zampini 
227674ae819SStefano Zampini   PetscFunctionBegin;
228674ae819SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
229674ae819SStefano Zampini   PetscValidHeaderSpecific(global_vector,VEC_CLASSID,2);
230674ae819SStefano Zampini   PetscValidHeaderSpecific(local_interface_vector,VEC_CLASSID,3);
2312c71b3e2SJacob Faibussowitsch   PetscCheckFalse(local_interface_vector == pcbddc->work_scaling,PETSC_COMM_SELF,PETSC_ERR_SUP,"Local vector cannot be pcbddc->work_scaling!");
2325f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscUseMethod(pc,"PCBDDCScalingRestriction_C",(PC,Vec,Vec),(pc,global_vector,local_interface_vector)));
233674ae819SStefano Zampini   PetscFunctionReturn(0);
234674ae819SStefano Zampini }
235674ae819SStefano Zampini 
236674ae819SStefano Zampini PetscErrorCode PCBDDCScalingSetUp(PC pc)
237674ae819SStefano Zampini {
238674ae819SStefano Zampini   PC_IS*         pcis=(PC_IS*)pc->data;
239674ae819SStefano Zampini   PC_BDDC*       pcbddc=(PC_BDDC*)pc->data;
240674ae819SStefano Zampini 
241674ae819SStefano Zampini   PetscFunctionBegin;
242674ae819SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2435f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscLogEventBegin(PC_BDDC_Scaling[pcbddc->current_level],pc,0,0,0));
244674ae819SStefano Zampini   /* create work vector for the operator */
2455f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&pcbddc->work_scaling));
2465f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDuplicate(pcis->vec1_B,&pcbddc->work_scaling));
24734a97f8cSStefano Zampini   /* always rebuild pcis->D */
24828d874f6SStefano Zampini   if (pcis->use_stiffness_scaling) {
24915f235b8SStefano Zampini     PetscScalar *a;
25015f235b8SStefano Zampini     PetscInt    i,n;
25115f235b8SStefano Zampini 
2525f80ce2aSJacob Faibussowitsch     CHKERRQ(MatGetDiagonal(pcbddc->local_mat,pcis->vec1_N));
2535f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->D,INSERT_VALUES,SCATTER_FORWARD));
2545f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->D,INSERT_VALUES,SCATTER_FORWARD));
2555f80ce2aSJacob Faibussowitsch     CHKERRQ(VecAbs(pcis->D));
2565f80ce2aSJacob Faibussowitsch     CHKERRQ(VecGetLocalSize(pcis->D,&n));
2575f80ce2aSJacob Faibussowitsch     CHKERRQ(VecGetArray(pcis->D,&a));
25815f235b8SStefano Zampini     for (i=0;i<n;i++) if (PetscAbsScalar(a[i])<PETSC_SMALL) a[i] = 1.0;
2595f80ce2aSJacob Faibussowitsch     CHKERRQ(VecRestoreArray(pcis->D,&a));
260674ae819SStefano Zampini   }
2615f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSet(pcis->vec1_global,0.0));
2625f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(pcis->global_to_B,pcis->D,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE));
2635f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(pcis->global_to_B,pcis->D,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE));
2645f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(pcis->global_to_B,pcis->vec1_global,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD));
2655f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(pcis->global_to_B,pcis->vec1_global,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD));
2665f80ce2aSJacob Faibussowitsch   CHKERRQ(VecPointwiseDivide(pcis->D,pcis->D,pcis->vec1_B));
267674ae819SStefano Zampini   /* now setup */
268681e7c04SStefano Zampini   if (pcbddc->use_deluxe_scaling) {
26934a97f8cSStefano Zampini     if (!pcbddc->deluxe_ctx) {
2705f80ce2aSJacob Faibussowitsch       CHKERRQ(PCBDDCScalingCreate_Deluxe(pc));
27134a97f8cSStefano Zampini     }
2725f80ce2aSJacob Faibussowitsch     CHKERRQ(PCBDDCScalingSetUp_Deluxe(pc));
2735f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCBDDCScalingRestriction_C",PCBDDCScalingRestriction_Deluxe));
2745f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCBDDCScalingExtension_C",PCBDDCScalingExtension_Deluxe));
275674ae819SStefano Zampini   } else {
2765f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCBDDCScalingRestriction_C",PCBDDCScalingRestriction_Basic));
2775f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCBDDCScalingExtension_C",PCBDDCScalingExtension_Basic));
278674ae819SStefano Zampini   }
2795f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscLogEventEnd(PC_BDDC_Scaling[pcbddc->current_level],pc,0,0,0));
28034a97f8cSStefano Zampini 
281674ae819SStefano Zampini   /* test */
282674ae819SStefano Zampini   if (pcbddc->dbg_flag) {
28372b8c272SStefano Zampini     Mat         B0_B = NULL;
28472b8c272SStefano Zampini     Vec         B0_Bv = NULL, B0_Bv2 = NULL;
28534a97f8cSStefano Zampini     Vec         vec2_global;
286674ae819SStefano Zampini     PetscViewer viewer = pcbddc->dbg_viewer;
28734a97f8cSStefano Zampini     PetscReal   error;
288674ae819SStefano Zampini 
289674ae819SStefano Zampini     /* extension -> from local to parallel */
2905f80ce2aSJacob Faibussowitsch     CHKERRQ(VecSet(pcis->vec1_global,0.0));
2915f80ce2aSJacob Faibussowitsch     CHKERRQ(VecSetRandom(pcis->vec1_B,NULL));
2925f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterBegin(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE));
2935f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterEnd(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE));
2945f80ce2aSJacob Faibussowitsch     CHKERRQ(VecDuplicate(pcis->vec1_global,&vec2_global));
2955f80ce2aSJacob Faibussowitsch     CHKERRQ(VecCopy(pcis->vec1_global,vec2_global));
2965f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterBegin(pcis->global_to_B,pcis->vec1_global,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD));
2975f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterEnd(pcis->global_to_B,pcis->vec1_global,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD));
29872b8c272SStefano Zampini     if (pcbddc->benign_n) {
29972b8c272SStefano Zampini       IS is_dummy;
30072b8c272SStefano Zampini 
3015f80ce2aSJacob Faibussowitsch       CHKERRQ(ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy));
3025f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B));
3035f80ce2aSJacob Faibussowitsch       CHKERRQ(ISDestroy(&is_dummy));
3045f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateVecs(B0_B,NULL,&B0_Bv));
3055f80ce2aSJacob Faibussowitsch       CHKERRQ(VecDuplicate(B0_Bv,&B0_Bv2));
3065f80ce2aSJacob Faibussowitsch       CHKERRQ(MatMult(B0_B,pcis->vec1_B,B0_Bv));
30772b8c272SStefano Zampini     }
3085f80ce2aSJacob Faibussowitsch     CHKERRQ(PCBDDCScalingExtension(pc,pcis->vec1_B,pcis->vec1_global));
30972b8c272SStefano Zampini     if (pcbddc->benign_saddle_point) {
31072b8c272SStefano Zampini       PetscReal errorl = 0.;
3115f80ce2aSJacob Faibussowitsch       CHKERRQ(VecScatterBegin(pcis->global_to_B,pcis->vec1_global,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD));
3125f80ce2aSJacob Faibussowitsch       CHKERRQ(VecScatterEnd(pcis->global_to_B,pcis->vec1_global,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD));
31372b8c272SStefano Zampini       if (pcbddc->benign_n) {
3145f80ce2aSJacob Faibussowitsch         CHKERRQ(MatMult(B0_B,pcis->vec1_B,B0_Bv2));
3155f80ce2aSJacob Faibussowitsch         CHKERRQ(VecAXPY(B0_Bv,-1.0,B0_Bv2));
3165f80ce2aSJacob Faibussowitsch         CHKERRQ(VecNorm(B0_Bv,NORM_INFINITY,&errorl));
31772b8c272SStefano Zampini       }
3185f80ce2aSJacob Faibussowitsch       CHKERRMPI(MPI_Allreduce(&errorl,&error,1,MPIU_REAL,MPI_SUM,PetscObjectComm((PetscObject)pc)));
3195f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"Error benign extension %1.14e\n",error));
32072b8c272SStefano Zampini     }
3215f80ce2aSJacob Faibussowitsch     CHKERRQ(VecAXPY(pcis->vec1_global,-1.0,vec2_global));
3225f80ce2aSJacob Faibussowitsch     CHKERRQ(VecNorm(pcis->vec1_global,NORM_INFINITY,&error));
3235f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"Error scaling extension %1.14e\n",error));
3245f80ce2aSJacob Faibussowitsch     CHKERRQ(VecDestroy(&vec2_global));
32534a97f8cSStefano Zampini 
326674ae819SStefano Zampini     /* restriction -> from parallel to local */
3275f80ce2aSJacob Faibussowitsch     CHKERRQ(VecSet(pcis->vec1_global,0.0));
3285f80ce2aSJacob Faibussowitsch     CHKERRQ(VecSetRandom(pcis->vec1_B,NULL));
3295f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterBegin(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE));
3305f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterEnd(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE));
3315f80ce2aSJacob Faibussowitsch     CHKERRQ(PCBDDCScalingRestriction(pc,pcis->vec1_global,pcis->vec1_B));
3325f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScale(pcis->vec1_B,-1.0));
3335f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterBegin(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE));
3345f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterEnd(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE));
3355f80ce2aSJacob Faibussowitsch     CHKERRQ(VecNorm(pcis->vec1_global,NORM_INFINITY,&error));
3365f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"Error scaling restriction %1.14e\n",error));
3375f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&B0_B));
3385f80ce2aSJacob Faibussowitsch     CHKERRQ(VecDestroy(&B0_Bv));
3395f80ce2aSJacob Faibussowitsch     CHKERRQ(VecDestroy(&B0_Bv2));
340674ae819SStefano Zampini   }
341674ae819SStefano Zampini   PetscFunctionReturn(0);
342674ae819SStefano Zampini }
343674ae819SStefano Zampini 
344674ae819SStefano Zampini PetscErrorCode PCBDDCScalingDestroy(PC pc)
345674ae819SStefano Zampini {
346674ae819SStefano Zampini   PC_BDDC*       pcbddc=(PC_BDDC*)pc->data;
347674ae819SStefano Zampini 
348674ae819SStefano Zampini   PetscFunctionBegin;
34934a97f8cSStefano Zampini   if (pcbddc->deluxe_ctx) {
3505f80ce2aSJacob Faibussowitsch     CHKERRQ(PCBDDCScalingDestroy_Deluxe(pc));
351674ae819SStefano Zampini   }
3525f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&pcbddc->work_scaling));
3535f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCBDDCScalingRestriction_C",NULL));
3545f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCBDDCScalingExtension_C",NULL));
355674ae819SStefano Zampini   PetscFunctionReturn(0);
356674ae819SStefano Zampini }
357674ae819SStefano Zampini 
35834a97f8cSStefano Zampini static PetscErrorCode PCBDDCScalingCreate_Deluxe(PC pc)
35934a97f8cSStefano Zampini {
36034a97f8cSStefano Zampini   PC_BDDC*            pcbddc=(PC_BDDC*)pc->data;
36134a97f8cSStefano Zampini   PCBDDCDeluxeScaling deluxe_ctx;
36234a97f8cSStefano Zampini 
36334a97f8cSStefano Zampini   PetscFunctionBegin;
3645f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscNew(&deluxe_ctx));
36534a97f8cSStefano Zampini   pcbddc->deluxe_ctx = deluxe_ctx;
36634a97f8cSStefano Zampini   PetscFunctionReturn(0);
36734a97f8cSStefano Zampini }
36834a97f8cSStefano Zampini 
36934a97f8cSStefano Zampini static PetscErrorCode PCBDDCScalingDestroy_Deluxe(PC pc)
37034a97f8cSStefano Zampini {
37134a97f8cSStefano Zampini   PC_BDDC*            pcbddc=(PC_BDDC*)pc->data;
37234a97f8cSStefano Zampini 
37334a97f8cSStefano Zampini   PetscFunctionBegin;
3745f80ce2aSJacob Faibussowitsch   CHKERRQ(PCBDDCScalingReset_Deluxe_Solvers(pcbddc->deluxe_ctx));
3755f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(pcbddc->deluxe_ctx));
37634a97f8cSStefano Zampini   PetscFunctionReturn(0);
37734a97f8cSStefano Zampini }
37834a97f8cSStefano Zampini 
37934a97f8cSStefano Zampini static PetscErrorCode PCBDDCScalingReset_Deluxe_Solvers(PCBDDCDeluxeScaling deluxe_ctx)
38034a97f8cSStefano Zampini {
38172b8c272SStefano Zampini   PetscInt       i;
38234a97f8cSStefano Zampini 
38334a97f8cSStefano Zampini   PetscFunctionBegin;
3845f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(deluxe_ctx->idx_simple_B));
38534a97f8cSStefano Zampini   deluxe_ctx->n_simple = 0;
38672b8c272SStefano Zampini   for (i=0;i<deluxe_ctx->seq_n;i++) {
3875f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterDestroy(&deluxe_ctx->seq_scctx[i]));
3885f80ce2aSJacob Faibussowitsch     CHKERRQ(VecDestroy(&deluxe_ctx->seq_work1[i]));
3895f80ce2aSJacob Faibussowitsch     CHKERRQ(VecDestroy(&deluxe_ctx->seq_work2[i]));
3905f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&deluxe_ctx->seq_mat[i]));
3915f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&deluxe_ctx->seq_mat_inv_sum[i]));
39272b8c272SStefano Zampini   }
3935f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree5(deluxe_ctx->seq_scctx,deluxe_ctx->seq_work1,deluxe_ctx->seq_work2,deluxe_ctx->seq_mat,deluxe_ctx->seq_mat_inv_sum));
3945f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(deluxe_ctx->workspace));
39572b8c272SStefano Zampini   deluxe_ctx->seq_n = 0;
39634a97f8cSStefano Zampini   PetscFunctionReturn(0);
39734a97f8cSStefano Zampini }
39834a97f8cSStefano Zampini 
39934a97f8cSStefano Zampini static PetscErrorCode PCBDDCScalingSetUp_Deluxe(PC pc)
40034a97f8cSStefano Zampini {
40134a97f8cSStefano Zampini   PC_IS               *pcis=(PC_IS*)pc->data;
40234a97f8cSStefano Zampini   PC_BDDC             *pcbddc=(PC_BDDC*)pc->data;
40334a97f8cSStefano Zampini   PCBDDCDeluxeScaling deluxe_ctx=pcbddc->deluxe_ctx;
404b96c3477SStefano Zampini   PCBDDCSubSchurs     sub_schurs=pcbddc->sub_schurs;
40534a97f8cSStefano Zampini 
40634a97f8cSStefano Zampini   PetscFunctionBegin;
40772b8c272SStefano Zampini   /* reset data structures if the topology has changed */
40872b8c272SStefano Zampini   if (pcbddc->recompute_topography) {
4095f80ce2aSJacob Faibussowitsch     CHKERRQ(PCBDDCScalingReset_Deluxe_Solvers(deluxe_ctx));
41072b8c272SStefano Zampini   }
41134a97f8cSStefano Zampini 
412b1b3d7a2SStefano Zampini   /* Compute data structures to solve sequential problems */
4135f80ce2aSJacob Faibussowitsch   CHKERRQ(PCBDDCScalingSetUp_Deluxe_Private(pc));
4145db18549SStefano Zampini 
415b1b3d7a2SStefano Zampini   /* diagonal scaling on interface dofs not contained in cc */
416d62866d3SStefano Zampini   if (sub_schurs->is_vertices || sub_schurs->is_dir) {
4171b968477SStefano Zampini     PetscInt n_com,n_dir;
4181b968477SStefano Zampini     n_com = 0;
419d62866d3SStefano Zampini     if (sub_schurs->is_vertices) {
4205f80ce2aSJacob Faibussowitsch       CHKERRQ(ISGetLocalSize(sub_schurs->is_vertices,&n_com));
4211b968477SStefano Zampini     }
4221b968477SStefano Zampini     n_dir = 0;
423d62866d3SStefano Zampini     if (sub_schurs->is_dir) {
4245f80ce2aSJacob Faibussowitsch       CHKERRQ(ISGetLocalSize(sub_schurs->is_dir,&n_dir));
4251b968477SStefano Zampini     }
42672b8c272SStefano Zampini     if (!deluxe_ctx->n_simple) {
4271b968477SStefano Zampini       deluxe_ctx->n_simple = n_dir + n_com;
4285f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscMalloc1(deluxe_ctx->n_simple,&deluxe_ctx->idx_simple_B));
429d62866d3SStefano Zampini       if (sub_schurs->is_vertices) {
4309bb4a8caSStefano Zampini         PetscInt       nmap;
4319bb4a8caSStefano Zampini         const PetscInt *idxs;
4321b968477SStefano Zampini 
4335f80ce2aSJacob Faibussowitsch         CHKERRQ(ISGetIndices(sub_schurs->is_vertices,&idxs));
4345f80ce2aSJacob Faibussowitsch         CHKERRQ(ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_com,idxs,&nmap,deluxe_ctx->idx_simple_B));
4352c71b3e2SJacob Faibussowitsch         PetscCheckFalse(nmap != n_com,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error when mapping simply scaled dofs (is_vertices)! %D != %D",nmap,n_com);
4365f80ce2aSJacob Faibussowitsch         CHKERRQ(ISRestoreIndices(sub_schurs->is_vertices,&idxs));
4371b968477SStefano Zampini       }
438d62866d3SStefano Zampini       if (sub_schurs->is_dir) {
4391b968477SStefano Zampini         PetscInt       nmap;
4401b968477SStefano Zampini         const PetscInt *idxs;
4411b968477SStefano Zampini 
4425f80ce2aSJacob Faibussowitsch         CHKERRQ(ISGetIndices(sub_schurs->is_dir,&idxs));
4435f80ce2aSJacob Faibussowitsch         CHKERRQ(ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_dir,idxs,&nmap,deluxe_ctx->idx_simple_B+n_com));
4442c71b3e2SJacob Faibussowitsch         PetscCheckFalse(nmap != n_dir,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error when mapping simply scaled dofs (sub_schurs->is_dir)! %D != %D",nmap,n_dir);
4455f80ce2aSJacob Faibussowitsch         CHKERRQ(ISRestoreIndices(sub_schurs->is_dir,&idxs));
4461b968477SStefano Zampini       }
4475f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSortInt(deluxe_ctx->n_simple,deluxe_ctx->idx_simple_B));
4489bb4a8caSStefano Zampini     } else {
4492c71b3e2SJacob Faibussowitsch       PetscCheckFalse(deluxe_ctx->n_simple != n_dir + n_com,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Number of simply scaled dofs %D is different from the previous one computed %D",n_dir + n_com,deluxe_ctx->n_simple);
45072b8c272SStefano Zampini     }
45172b8c272SStefano Zampini   } else {
452b1b3d7a2SStefano Zampini     deluxe_ctx->n_simple = 0;
4530a545947SLisandro Dalcin     deluxe_ctx->idx_simple_B = NULL;
454b1b3d7a2SStefano Zampini   }
45534a97f8cSStefano Zampini   PetscFunctionReturn(0);
45634a97f8cSStefano Zampini }
45734a97f8cSStefano Zampini 
4585a95e1ceSStefano Zampini static PetscErrorCode PCBDDCScalingSetUp_Deluxe_Private(PC pc)
4595db18549SStefano Zampini {
4605db18549SStefano Zampini   PC_BDDC                *pcbddc=(PC_BDDC*)pc->data;
4615db18549SStefano Zampini   PCBDDCDeluxeScaling    deluxe_ctx=pcbddc->deluxe_ctx;
462b96c3477SStefano Zampini   PCBDDCSubSchurs        sub_schurs = pcbddc->sub_schurs;
46372b8c272SStefano Zampini   PetscScalar            *matdata,*matdata2;
46472b8c272SStefano Zampini   PetscInt               i,max_subset_size,cum,cum2;
46572b8c272SStefano Zampini   const PetscInt         *idxs;
46672b8c272SStefano Zampini   PetscBool              newsetup = PETSC_FALSE;
4675db18549SStefano Zampini 
4685db18549SStefano Zampini   PetscFunctionBegin;
469*28b400f6SJacob Faibussowitsch   PetscCheck(sub_schurs,PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Missing PCBDDCSubSchurs");
47086bfa4cfSStefano Zampini   if (!sub_schurs->n_subs) PetscFunctionReturn(0);
4719221af80SStefano Zampini 
47272b8c272SStefano Zampini   /* Allocate arrays for subproblems */
47372b8c272SStefano Zampini   if (!deluxe_ctx->seq_n) {
47472b8c272SStefano Zampini     deluxe_ctx->seq_n = sub_schurs->n_subs;
4755f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscCalloc5(deluxe_ctx->seq_n,&deluxe_ctx->seq_scctx,deluxe_ctx->seq_n,&deluxe_ctx->seq_work1,deluxe_ctx->seq_n,&deluxe_ctx->seq_work2,deluxe_ctx->seq_n,&deluxe_ctx->seq_mat,deluxe_ctx->seq_n,&deluxe_ctx->seq_mat_inv_sum));
47672b8c272SStefano Zampini     newsetup = PETSC_TRUE;
4772c71b3e2SJacob Faibussowitsch   } else PetscCheckFalse(deluxe_ctx->seq_n != sub_schurs->n_subs,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Number of deluxe subproblems %D is different from the sub_schurs %D",deluxe_ctx->seq_n,sub_schurs->n_subs);
4786080607fSStefano Zampini 
4792f41f7d1SStefano Zampini   /* the change of basis is just a reference to sub_schurs->change (if any) */
4802f41f7d1SStefano Zampini   deluxe_ctx->change         = sub_schurs->change;
48172b8c272SStefano Zampini   deluxe_ctx->change_with_qr = sub_schurs->change_with_qr;
4825db18549SStefano Zampini 
48372b8c272SStefano Zampini   /* Create objects for deluxe */
48472b8c272SStefano Zampini   max_subset_size = 0;
48572b8c272SStefano Zampini   for (i=0;i<sub_schurs->n_subs;i++) {
48672b8c272SStefano Zampini     PetscInt subset_size;
4875f80ce2aSJacob Faibussowitsch     CHKERRQ(ISGetLocalSize(sub_schurs->is_subs[i],&subset_size));
48872b8c272SStefano Zampini     max_subset_size = PetscMax(subset_size,max_subset_size);
48972b8c272SStefano Zampini   }
49072b8c272SStefano Zampini   if (newsetup) {
4915f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscMalloc1(2*max_subset_size,&deluxe_ctx->workspace));
49272b8c272SStefano Zampini   }
49372b8c272SStefano Zampini   cum = cum2 = 0;
4945f80ce2aSJacob Faibussowitsch   CHKERRQ(ISGetIndices(sub_schurs->is_Ej_all,&idxs));
4955f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSeqAIJGetArray(sub_schurs->S_Ej_all,&matdata));
4965f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSeqAIJGetArray(sub_schurs->sum_S_Ej_all,&matdata2));
49772b8c272SStefano Zampini   for (i=0;i<deluxe_ctx->seq_n;i++) {
49872b8c272SStefano Zampini     PetscInt     subset_size;
499925dfd53SStefano Zampini 
5005f80ce2aSJacob Faibussowitsch     CHKERRQ(ISGetLocalSize(sub_schurs->is_subs[i],&subset_size));
50172b8c272SStefano Zampini     if (newsetup) {
50272b8c272SStefano Zampini       IS  sub;
50372b8c272SStefano Zampini       /* work vectors */
5045f80ce2aSJacob Faibussowitsch       CHKERRQ(VecCreateSeqWithArray(PETSC_COMM_SELF,1,subset_size,deluxe_ctx->workspace,&deluxe_ctx->seq_work1[i]));
5055f80ce2aSJacob Faibussowitsch       CHKERRQ(VecCreateSeqWithArray(PETSC_COMM_SELF,1,subset_size,deluxe_ctx->workspace+subset_size,&deluxe_ctx->seq_work2[i]));
50672b8c272SStefano Zampini 
50772b8c272SStefano Zampini       /* scatters */
5085f80ce2aSJacob Faibussowitsch       CHKERRQ(ISCreateGeneral(PETSC_COMM_SELF,subset_size,idxs+cum,PETSC_COPY_VALUES,&sub));
5095f80ce2aSJacob Faibussowitsch       CHKERRQ(VecScatterCreate(pcbddc->work_scaling,sub,deluxe_ctx->seq_work1[i],NULL,&deluxe_ctx->seq_scctx[i]));
5105f80ce2aSJacob Faibussowitsch       CHKERRQ(ISDestroy(&sub));
511839e9adbSstefano_zampini     }
51272b8c272SStefano Zampini 
51372b8c272SStefano Zampini     /* S_E_j */
5145f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&deluxe_ctx->seq_mat[i]));
5155f80ce2aSJacob Faibussowitsch     CHKERRQ(MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,matdata+cum2,&deluxe_ctx->seq_mat[i]));
516839e9adbSstefano_zampini 
51772b8c272SStefano Zampini     /* \sum_k S^k_E_j */
5185f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&deluxe_ctx->seq_mat_inv_sum[i]));
5195f80ce2aSJacob Faibussowitsch     CHKERRQ(MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,matdata2+cum2,&deluxe_ctx->seq_mat_inv_sum[i]));
5205f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetOption(deluxe_ctx->seq_mat_inv_sum[i],MAT_SPD,sub_schurs->is_posdef));
5215f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetOption(deluxe_ctx->seq_mat_inv_sum[i],MAT_HERMITIAN,sub_schurs->is_hermitian));
5223829e7e6SStefano Zampini     if (sub_schurs->is_hermitian) {
5235f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCholeskyFactor(deluxe_ctx->seq_mat_inv_sum[i],NULL,NULL));
524d62866d3SStefano Zampini     } else {
5255f80ce2aSJacob Faibussowitsch       CHKERRQ(MatLUFactor(deluxe_ctx->seq_mat_inv_sum[i],NULL,NULL,NULL));
526d62866d3SStefano Zampini     }
527839e9adbSstefano_zampini     if (pcbddc->deluxe_singlemat) {
528839e9adbSstefano_zampini       Mat X,Y;
5293829e7e6SStefano Zampini       if (!sub_schurs->is_hermitian) {
5305f80ce2aSJacob Faibussowitsch         CHKERRQ(MatTranspose(deluxe_ctx->seq_mat[i],MAT_INITIAL_MATRIX,&X));
531839e9adbSstefano_zampini       } else {
5325f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscObjectReference((PetscObject)deluxe_ctx->seq_mat[i]));
533839e9adbSstefano_zampini         X    = deluxe_ctx->seq_mat[i];
534839e9adbSstefano_zampini       }
5355f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDuplicate(X,MAT_DO_NOT_COPY_VALUES,&Y));
5363829e7e6SStefano Zampini       if (!sub_schurs->is_hermitian) {
5375f80ce2aSJacob Faibussowitsch         CHKERRQ(PCBDDCMatTransposeMatSolve_SeqDense(deluxe_ctx->seq_mat_inv_sum[i],X,Y));
538839e9adbSstefano_zampini       } else {
5395f80ce2aSJacob Faibussowitsch         CHKERRQ(MatMatSolve(deluxe_ctx->seq_mat_inv_sum[i],X,Y));
540839e9adbSstefano_zampini       }
541729c86d3Sstefano_zampini 
5425f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&deluxe_ctx->seq_mat_inv_sum[i]));
5435f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&deluxe_ctx->seq_mat[i]));
5445f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&X));
5452f41f7d1SStefano Zampini       if (deluxe_ctx->change) {
5462f41f7d1SStefano Zampini         Mat C,CY;
547*28b400f6SJacob Faibussowitsch         PetscCheck(deluxe_ctx->change_with_qr,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only QR based change of basis");
5485f80ce2aSJacob Faibussowitsch         CHKERRQ(KSPGetOperators(deluxe_ctx->change[i],&C,NULL));
5495f80ce2aSJacob Faibussowitsch         CHKERRQ(MatMatMult(C,Y,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&CY));
5505f80ce2aSJacob Faibussowitsch         CHKERRQ(MatMatTransposeMult(CY,C,MAT_REUSE_MATRIX,PETSC_DEFAULT,&Y));
5515f80ce2aSJacob Faibussowitsch         CHKERRQ(MatDestroy(&CY));
5525f80ce2aSJacob Faibussowitsch         CHKERRQ(MatProductClear(Y)); /* clear internal matproduct structure of Y since CY is destroyed */
5532f41f7d1SStefano Zampini       }
5545f80ce2aSJacob Faibussowitsch       CHKERRQ(MatTranspose(Y,MAT_INPLACE_MATRIX,&Y));
555839e9adbSstefano_zampini       deluxe_ctx->seq_mat[i] = Y;
55672b8c272SStefano Zampini     }
55772b8c272SStefano Zampini     cum += subset_size;
55872b8c272SStefano Zampini     cum2 += subset_size*subset_size;
55972b8c272SStefano Zampini   }
5605f80ce2aSJacob Faibussowitsch   CHKERRQ(ISRestoreIndices(sub_schurs->is_Ej_all,&idxs));
5615f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSeqAIJRestoreArray(sub_schurs->S_Ej_all,&matdata));
5625f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_all,&matdata2));
5632f41f7d1SStefano Zampini   if (pcbddc->deluxe_singlemat) {
5642f41f7d1SStefano Zampini     deluxe_ctx->change         = NULL;
5652f41f7d1SStefano Zampini     deluxe_ctx->change_with_qr = PETSC_FALSE;
5662f41f7d1SStefano Zampini   }
5675db18549SStefano Zampini 
56872b8c272SStefano Zampini   if (deluxe_ctx->change && !deluxe_ctx->change_with_qr) {
56972b8c272SStefano Zampini     for (i=0;i<deluxe_ctx->seq_n;i++) {
57072b8c272SStefano Zampini       if (newsetup) {
57172b8c272SStefano Zampini         PC pc;
57272b8c272SStefano Zampini 
5735f80ce2aSJacob Faibussowitsch         CHKERRQ(KSPGetPC(deluxe_ctx->change[i],&pc));
5745f80ce2aSJacob Faibussowitsch         CHKERRQ(PCSetType(pc,PCLU));
5755f80ce2aSJacob Faibussowitsch         CHKERRQ(KSPSetFromOptions(deluxe_ctx->change[i]));
57672b8c272SStefano Zampini       }
5775f80ce2aSJacob Faibussowitsch       CHKERRQ(KSPSetUp(deluxe_ctx->change[i]));
57872b8c272SStefano Zampini     }
57916e386b8SStefano Zampini   }
5805db18549SStefano Zampini   PetscFunctionReturn(0);
5815db18549SStefano Zampini }
582