1*1cf9b237SStefano Zampini #include <../src/mat/impls/aij/seq/aij.h> 2ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> 3ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 4674ae819SStefano Zampini #include <petscblaslapack.h> 5674ae819SStefano Zampini 6906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y); 7906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y); 8906d46d4SStefano Zampini 9*1cf9b237SStefano Zampini /* TODO: add reuse flag */ 10*1cf9b237SStefano Zampini #undef __FUNCT__ 11*1cf9b237SStefano Zampini #define __FUNCT__ "MatSeqAIJCompress" 12*1cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 13*1cf9b237SStefano Zampini { 14*1cf9b237SStefano Zampini Mat Bt; 15*1cf9b237SStefano Zampini PetscScalar *a,*bdata; 16*1cf9b237SStefano Zampini const PetscInt *ii,*ij; 17*1cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 18*1cf9b237SStefano Zampini PetscBool flg_row; 19*1cf9b237SStefano Zampini PetscErrorCode ierr; 20*1cf9b237SStefano Zampini 21*1cf9b237SStefano Zampini PetscFunctionBegin; 22*1cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 23*1cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 24*1cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 25*1cf9b237SStefano Zampini nnz = n; 26*1cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 27*1cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 28*1cf9b237SStefano Zampini } 29*1cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 30*1cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 31*1cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 32*1cf9b237SStefano Zampini nnz = 0; 33*1cf9b237SStefano Zampini bii[0] = 0; 34*1cf9b237SStefano Zampini for (i=0;i<n;i++) { 35*1cf9b237SStefano Zampini PetscInt j; 36*1cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 37*1cf9b237SStefano Zampini PetscScalar entry = a[j]; 38*1cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 39*1cf9b237SStefano Zampini bij[nnz] = ij[j]; 40*1cf9b237SStefano Zampini bdata[nnz] = entry; 41*1cf9b237SStefano Zampini nnz++; 42*1cf9b237SStefano Zampini } 43*1cf9b237SStefano Zampini } 44*1cf9b237SStefano Zampini bii[i+1] = nnz; 45*1cf9b237SStefano Zampini } 46*1cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 47*1cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 48*1cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 49*1cf9b237SStefano Zampini { 50*1cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 51*1cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 52*1cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 53*1cf9b237SStefano Zampini } 54*1cf9b237SStefano Zampini *B = Bt; 55*1cf9b237SStefano Zampini PetscFunctionReturn(0); 56*1cf9b237SStefano Zampini } 57*1cf9b237SStefano Zampini 58674ae819SStefano Zampini #undef __FUNCT__ 594f1b2e48SStefano Zampini #define __FUNCT__ "MatDetectDisconnectedComponents" 604f1b2e48SStefano Zampini PetscErrorCode MatDetectDisconnectedComponents(Mat A, PetscBool filter, PetscInt *ncc, IS* cc[]) 614f1b2e48SStefano Zampini { 624f1b2e48SStefano Zampini Mat B; 634f1b2e48SStefano Zampini IS is_dummy,*cc_n; 644f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 654f1b2e48SStefano Zampini PCBDDCGraph graph; 664f1b2e48SStefano Zampini PetscInt i,n; 674f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 684f1b2e48SStefano Zampini PetscInt *xadj_filtered,*adjncy_filtered; 694f1b2e48SStefano Zampini PetscBool flg_row,isseqaij; 704f1b2e48SStefano Zampini PetscErrorCode ierr; 714f1b2e48SStefano Zampini 724f1b2e48SStefano Zampini PetscFunctionBegin; 734f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 744f1b2e48SStefano Zampini if (!isseqaij && filter) { 75*1cf9b237SStefano Zampini PetscBool isseqdense; 76*1cf9b237SStefano Zampini 77*1cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 78*1cf9b237SStefano Zampini if (!isseqdense) { 794f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 80*1cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 81*1cf9b237SStefano Zampini PetscScalar *array; 82*1cf9b237SStefano Zampini PetscReal chop=1.e-6; 83*1cf9b237SStefano Zampini 84*1cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 85*1cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 86*1cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 87*1cf9b237SStefano Zampini for (i=0;i<n;i++) { 88*1cf9b237SStefano Zampini PetscInt j; 89*1cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 90*1cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 91*1cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 92*1cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 93*1cf9b237SStefano Zampini } 94*1cf9b237SStefano Zampini } 95*1cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 96*1cf9b237SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_REUSE_MATRIX,&B);CHKERRQ(ierr); 97*1cf9b237SStefano Zampini } 984f1b2e48SStefano Zampini } else { 994f1b2e48SStefano Zampini B = A; 1004f1b2e48SStefano Zampini } 1014f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 1024f1b2e48SStefano Zampini 1034f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 1044f1b2e48SStefano Zampini if (filter) { 1054f1b2e48SStefano Zampini PetscScalar *data; 1064f1b2e48SStefano Zampini PetscInt j,cum; 1074f1b2e48SStefano Zampini 1084f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 1094f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 1104f1b2e48SStefano Zampini cum = 0; 1114f1b2e48SStefano Zampini for (i=0;i<n;i++) { 1124f1b2e48SStefano Zampini PetscInt t; 1134f1b2e48SStefano Zampini 1144f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 1154f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 1164f1b2e48SStefano Zampini continue; 1174f1b2e48SStefano Zampini } 1184f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 1194f1b2e48SStefano Zampini } 1204f1b2e48SStefano Zampini t = xadj_filtered[i]; 1214f1b2e48SStefano Zampini xadj_filtered[i] = cum; 1224f1b2e48SStefano Zampini cum += t; 1234f1b2e48SStefano Zampini } 1244f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 1254f1b2e48SStefano Zampini } else { 1264f1b2e48SStefano Zampini xadj_filtered = NULL; 1274f1b2e48SStefano Zampini adjncy_filtered = NULL; 1284f1b2e48SStefano Zampini } 1294f1b2e48SStefano Zampini 1304f1b2e48SStefano Zampini /* compute local connected components using PCBDDCGraph */ 1314f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 1324f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 1334f1b2e48SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 1344f1b2e48SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 1354f1b2e48SStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n);CHKERRQ(ierr); 1364f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 1374f1b2e48SStefano Zampini if (xadj_filtered) { 1384f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 1394f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 1404f1b2e48SStefano Zampini } else { 1414f1b2e48SStefano Zampini graph->xadj = xadj; 1424f1b2e48SStefano Zampini graph->adjncy = adjncy; 1434f1b2e48SStefano Zampini } 1444f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 1454f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 1464f1b2e48SStefano Zampini 1474f1b2e48SStefano Zampini /* partial clean up */ 1484f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 1494f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 150*1cf9b237SStefano Zampini if (A != B) { 1514f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1524f1b2e48SStefano Zampini } 1534f1b2e48SStefano Zampini 1544f1b2e48SStefano Zampini /* get back data */ 155*1cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 156*1cf9b237SStefano Zampini if (cc) { 1574f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 1584f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 1594f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,graph->cptr[i+1]-graph->cptr[i],graph->queue+graph->cptr[i],PETSC_COPY_VALUES,&cc_n[i]);CHKERRQ(ierr); 1604f1b2e48SStefano Zampini } 1614f1b2e48SStefano Zampini *cc = cc_n; 162*1cf9b237SStefano Zampini } 1634f1b2e48SStefano Zampini /* clean up graph */ 1644f1b2e48SStefano Zampini graph->xadj = 0; 1654f1b2e48SStefano Zampini graph->adjncy = 0; 1664f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 1674f1b2e48SStefano Zampini PetscFunctionReturn(0); 1684f1b2e48SStefano Zampini } 1694f1b2e48SStefano Zampini 1704f1b2e48SStefano Zampini #undef __FUNCT__ 1715408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 1725408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 1735408967cSStefano Zampini { 1745408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1755408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 176dee84bffSStefano Zampini IS dirIS = NULL; 1774f1b2e48SStefano Zampini PetscInt i; 1785408967cSStefano Zampini PetscErrorCode ierr; 1795408967cSStefano Zampini 1805408967cSStefano Zampini PetscFunctionBegin; 181dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 1825408967cSStefano Zampini if (zerodiag) { 1835408967cSStefano Zampini Mat A; 1845408967cSStefano Zampini Vec vec3_N; 1855408967cSStefano Zampini PetscScalar *vals; 1865408967cSStefano Zampini const PetscInt *idxs; 1874f1b2e48SStefano Zampini PetscInt nz; 1885408967cSStefano Zampini 1895408967cSStefano Zampini /* p0 */ 1905408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 1915408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 1925408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 1935408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 1944f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 1955408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1965408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 1975408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 1985408967cSStefano Zampini /* v_I */ 1995408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 2005408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 2015408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 2025408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 2035408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2045408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 2055408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 2065408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2075408967cSStefano Zampini if (dirIS) { 2085408967cSStefano Zampini PetscInt n; 2095408967cSStefano Zampini 2105408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 2115408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 2125408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 2135408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 2145408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 2155408967cSStefano Zampini } 2165408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 2175408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 2185408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 2195408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 2205408967cSStefano Zampini ierr = MatISGetLocalMat(pc->mat,&A);CHKERRQ(ierr); 2215408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 2225408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 2234f1b2e48SStefano Zampini if (PetscAbsScalar(vals[0]) > PETSC_SMALL) { 2245408967cSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! b(v_I,p_0) = %f (should be numerically 0.)",PetscAbsScalar(vals[0])); 2255408967cSStefano Zampini } 2265408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 2275408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 2285408967cSStefano Zampini } 229dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 2305408967cSStefano Zampini 2315408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 2325408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 2334f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 2345408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 2354f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 2365408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 2374f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2384f1b2e48SStefano Zampini if ((PetscInt)PetscRealPart(pcbddc->benign_p0[i]) != -PetscGlobalRank-i) { 2394f1b2e48SStefano Zampini SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error testing PCBDDCBenignGetOrSetP0! Found %1.4e at %d instead of %1.4e\n",pcbddc->benign_p0[i],i,-PetscGlobalRank-i);CHKERRQ(ierr); 2404f1b2e48SStefano Zampini } 2415408967cSStefano Zampini } 2425408967cSStefano Zampini PetscFunctionReturn(0); 2435408967cSStefano Zampini } 2445408967cSStefano Zampini 2455408967cSStefano Zampini #undef __FUNCT__ 246339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 247339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 248339f8db1SStefano Zampini { 249339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2504f1b2e48SStefano Zampini IS pressures,zerodiag,*zerodiag_subs; 251b0f5fe93SStefano Zampini PetscInt nz,n; 2524f1b2e48SStefano Zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag; 253339f8db1SStefano Zampini PetscErrorCode ierr; 254339f8db1SStefano Zampini 255339f8db1SStefano Zampini PetscFunctionBegin; 256339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 257339f8db1SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->local_mat);CHKERRQ(ierr); 258339f8db1SStefano Zampini pcbddc->benign_original_mat = pcbddc->local_mat; 2594f1b2e48SStefano Zampini /* if a local info on dofs is present, assumes the last field is represented by "pressures" 2604f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 2614f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 2624f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 2634f1b2e48SStefano Zampini since the local Schur complements are SPD 2644f1b2e48SStefano Zampini */ 2654f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 2664f1b2e48SStefano Zampini have_null = PETSC_TRUE; 26740fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 2684f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 2694f1b2e48SStefano Zampini 2704f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 2714f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 2724f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 2734f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 274ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 27540fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 27640fa8d13SStefano Zampini if (!sorted) { 27740fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 27840fa8d13SStefano Zampini } 27940fa8d13SStefano Zampini } else { 28040fa8d13SStefano Zampini pressures = NULL; 28140fa8d13SStefano Zampini } 2824f1b2e48SStefano Zampini ierr = MatGetLocalSize(pcbddc->benign_original_mat,&n,NULL);CHKERRQ(ierr); 2834f1b2e48SStefano Zampini /* TODO: add check for shared dofs and raise error */ 284339f8db1SStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->benign_original_mat,&zerodiag);CHKERRQ(ierr); 285339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 286339f8db1SStefano Zampini if (!sorted) { 287339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 288339f8db1SStefano Zampini } 289339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 2904f1b2e48SStefano Zampini if (!nz) { 2914f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 2924f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 29340fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 29440fa8d13SStefano Zampini } 2954f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 2964f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 2974f1b2e48SStefano Zampini zerodiag_subs = NULL; 2984f1b2e48SStefano Zampini pcbddc->benign_n = 0; 2994f1b2e48SStefano Zampini if (has_null_pressures) { 3004f1b2e48SStefano Zampini IS *subs; 3014f1b2e48SStefano Zampini PetscInt nsubs,i; 3024f1b2e48SStefano Zampini 3034f1b2e48SStefano Zampini subs = pcbddc->local_subs; 3044f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 3054f1b2e48SStefano Zampini if (nsubs > 1) { 3064f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 3074f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 3084f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 3094f1b2e48SStefano Zampini IS t_zerodiag_subs; 3104f1b2e48SStefano Zampini PetscInt nl; 3114f1b2e48SStefano Zampini 3124f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 3134f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 3144f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 3154f1b2e48SStefano Zampini if (nl) { 3164f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 3174f1b2e48SStefano Zampini 3184f1b2e48SStefano Zampini if (pressures) { 3194f1b2e48SStefano Zampini IS t_pressure_subs; 3204f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 3214f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 3224f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 3234f1b2e48SStefano Zampini } 3244f1b2e48SStefano Zampini if (valid) { 3254f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 3264f1b2e48SStefano Zampini pcbddc->benign_n++; 3274f1b2e48SStefano Zampini } else { 3284f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 3294f1b2e48SStefano Zampini } 3304f1b2e48SStefano Zampini } 3314f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 3324f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 3334f1b2e48SStefano Zampini } 3344f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 3354f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 3364f1b2e48SStefano Zampini if (pressures) { 3374f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 3384f1b2e48SStefano Zampini } 3394f1b2e48SStefano Zampini if (valid) { 3404f1b2e48SStefano Zampini pcbddc->benign_n = 1; 3414f1b2e48SStefano Zampini ierr = PetscCalloc1(1,&zerodiag_subs);CHKERRQ(ierr); 3424f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 3434f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 3444f1b2e48SStefano Zampini } 3454f1b2e48SStefano Zampini } 3464f1b2e48SStefano Zampini } 3474f1b2e48SStefano Zampini 3484f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 3494f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 3504f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 3514f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 3524f1b2e48SStefano Zampini have_null = PETSC_FALSE; 3534f1b2e48SStefano Zampini } 3544f1b2e48SStefano Zampini 3554f1b2e48SStefano Zampini /* final check for null pressures */ 3564f1b2e48SStefano Zampini if (zerodiag && pressures) { 3574f1b2e48SStefano Zampini PetscInt nz,np; 3584f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 3594f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 3604f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 3614f1b2e48SStefano Zampini } 3624f1b2e48SStefano Zampini 3634f1b2e48SStefano Zampini if (recompute_zerodiag) { 3644f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 3654f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 3664f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 3674f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 3684f1b2e48SStefano Zampini } else { 3694f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 3704f1b2e48SStefano Zampini 3714f1b2e48SStefano Zampini nzn = 0; 3724f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3734f1b2e48SStefano Zampini PetscInt ns; 3744f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 3754f1b2e48SStefano Zampini nzn += ns; 3764f1b2e48SStefano Zampini } 3774f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 3784f1b2e48SStefano Zampini nzn = 0; 3794f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3804f1b2e48SStefano Zampini PetscInt ns,*idxs; 3814f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 3824f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 3834f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 3844f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 3854f1b2e48SStefano Zampini nzn += ns; 3864f1b2e48SStefano Zampini } 3874f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 3884f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 3894f1b2e48SStefano Zampini } 3904f1b2e48SStefano Zampini have_null = PETSC_FALSE; 3914f1b2e48SStefano Zampini } 3924f1b2e48SStefano Zampini 3934f1b2e48SStefano Zampini if (has_null_pressures) { 3944f1b2e48SStefano Zampini IS zerodiagc; 3954f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 3964f1b2e48SStefano Zampini PetscInt i,s,*nnz; 397*1cf9b237SStefano Zampini Mat M; 3984f1b2e48SStefano Zampini 3994f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 400339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 401339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 402339f8db1SStefano Zampini /* local change of basis for pressures */ 403339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 404339f8db1SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->benign_original_mat),&pcbddc->benign_change);CHKERRQ(ierr); 405339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 406339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 407339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 4084f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 4094f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 4104f1b2e48SStefano Zampini PetscInt nzs,j; 4114f1b2e48SStefano Zampini 4124f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 4134f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 4144f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 4154f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 4164f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 4174f1b2e48SStefano Zampini } 418339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 419339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 420339f8db1SStefano Zampini /* set identity on velocities */ 421339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 422339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 423339f8db1SStefano Zampini } 4244f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 4254f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 4264f1b2e48SStefano Zampini ierr = PetscMalloc3(pcbddc->benign_n,&pcbddc->benign_p0_lidx,pcbddc->benign_n,&pcbddc->benign_p0_gidx,pcbddc->benign_n,&pcbddc->benign_p0);CHKERRQ(ierr); 427339f8db1SStefano Zampini /* set change on pressures */ 4284f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 4294f1b2e48SStefano Zampini PetscScalar *array; 4304f1b2e48SStefano Zampini PetscInt nzs; 4314f1b2e48SStefano Zampini 4324f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 4334f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 4344f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 435339f8db1SStefano Zampini PetscScalar vals[2]; 436339f8db1SStefano Zampini PetscInt cols[2]; 437339f8db1SStefano Zampini 438339f8db1SStefano Zampini cols[0] = idxs[i]; 4394f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 440339f8db1SStefano Zampini vals[0] = 1.; 441b0f5fe93SStefano Zampini vals[1] = 1.; 4424f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 443339f8db1SStefano Zampini } 4444f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 4454f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 4464f1b2e48SStefano Zampini array[nzs-1] = 1.; 4474f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 4484f1b2e48SStefano Zampini /* store local idxs for p0 */ 4494f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 4504f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 4514f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag_subs[s]);CHKERRQ(ierr); 452339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 4534f1b2e48SStefano Zampini } 454339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 455339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 456339f8db1SStefano Zampini /* TODO: need optimization? */ 457339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 458*1cf9b237SStefano Zampini ierr = MatPtAP(pcbddc->benign_original_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 459*1cf9b237SStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 460*1cf9b237SStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 4614f1b2e48SStefano Zampini /* store global idxs for p0 */ 4624f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 463339f8db1SStefano Zampini } 4644f1b2e48SStefano Zampini ierr = PetscFree(zerodiag_subs);CHKERRQ(ierr); 4654f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 466b0f5fe93SStefano Zampini 467b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 468b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 469339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 470339f8db1SStefano Zampini PetscFunctionReturn(0); 471339f8db1SStefano Zampini } 472339f8db1SStefano Zampini 473339f8db1SStefano Zampini #undef __FUNCT__ 474015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 475015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 476efc2fbd9SStefano Zampini { 477efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 478efc2fbd9SStefano Zampini PetscErrorCode ierr; 479efc2fbd9SStefano Zampini 480efc2fbd9SStefano Zampini PetscFunctionBegin; 481efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 482efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 4834f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 484efc2fbd9SStefano Zampini } 485015636ebSStefano Zampini if (get) { /* use SF to get values */ 486efc2fbd9SStefano Zampini PetscScalar *array; 487efc2fbd9SStefano Zampini 488efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 4894f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 4904f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 491efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 4924f1b2e48SStefano Zampini } else { /* use VecSetValues (not scalable, I should try to find a better solution (defining a new MPI_OP for reduction) */ 4934f1b2e48SStefano Zampini ierr = VecSetValues(v,pcbddc->benign_n,pcbddc->benign_p0_gidx,pcbddc->benign_p0,INSERT_VALUES);CHKERRQ(ierr); 494efc2fbd9SStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 495efc2fbd9SStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 496efc2fbd9SStefano Zampini } 497efc2fbd9SStefano Zampini PetscFunctionReturn(0); 498efc2fbd9SStefano Zampini } 499efc2fbd9SStefano Zampini 500efc2fbd9SStefano Zampini #undef __FUNCT__ 501c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 502c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 503c263805aSStefano Zampini { 504c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 505c263805aSStefano Zampini PetscErrorCode ierr; 506c263805aSStefano Zampini 507c263805aSStefano Zampini PetscFunctionBegin; 508c263805aSStefano Zampini /* TODO: add error checking 509c263805aSStefano Zampini - avoid nested pop (or push) calls. 510c263805aSStefano Zampini - cannot push before pop. 5111c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 512c263805aSStefano Zampini */ 5134f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 514efc2fbd9SStefano Zampini PetscFunctionReturn(0); 515efc2fbd9SStefano Zampini } 516c263805aSStefano Zampini if (pop) { 5174f1b2e48SStefano Zampini IS is_p0; 5184f1b2e48SStefano Zampini MatReuse reuse; 519c263805aSStefano Zampini 520c263805aSStefano Zampini /* extract B_0 */ 5214f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 5224f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 5234f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 5244f1b2e48SStefano Zampini } 5254f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 5264f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 527c263805aSStefano Zampini /* remove rows and cols from local problem */ 528c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 5294f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 5304f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 531c263805aSStefano Zampini } else { /* push */ 5324f1b2e48SStefano Zampini PetscInt i; 5334f1b2e48SStefano Zampini 5344f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 5354f1b2e48SStefano Zampini PetscScalar *B0_vals; 5364f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 5374f1b2e48SStefano Zampini 5384f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 5394f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 5404f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+1,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 5414f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 5424f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 5434f1b2e48SStefano Zampini } 544c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 545c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 546c263805aSStefano Zampini } 547c263805aSStefano Zampini PetscFunctionReturn(0); 548c263805aSStefano Zampini } 549c263805aSStefano Zampini 550c263805aSStefano Zampini #undef __FUNCT__ 551b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 55208122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 553b1b3d7a2SStefano Zampini { 554b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 55508122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 55608122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 55708122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 55808122e43SStefano Zampini PetscScalar *work,lwork; 55908122e43SStefano Zampini PetscScalar *St,*S,*eigv; 56008122e43SStefano Zampini PetscScalar *Sarray,*Starray; 56108122e43SStefano Zampini PetscReal *eigs,thresh; 5621b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 563f6f667cfSStefano Zampini PetscBool allocated_S_St; 56408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 56508122e43SStefano Zampini PetscReal *rwork; 56608122e43SStefano Zampini #endif 567b1b3d7a2SStefano Zampini PetscErrorCode ierr; 568b1b3d7a2SStefano Zampini 569b1b3d7a2SStefano Zampini PetscFunctionBegin; 57008122e43SStefano Zampini if (!sub_schurs->use_mumps) { 57108122e43SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS"); 57208122e43SStefano Zampini } 57308122e43SStefano Zampini 57406a4e24aSStefano Zampini if (sub_schurs->n_subs && (!sub_schurs->is_hermitian || !sub_schurs->is_posdef)) { 57506a4e24aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Adaptive selection not yet implemented for general matrix pencils (herm %d, posdef %d)\n",sub_schurs->is_hermitian,sub_schurs->is_posdef); 57606a4e24aSStefano Zampini } 57706a4e24aSStefano Zampini 578fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 579fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 580fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 581fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 582fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 583fd14bc51SStefano Zampini } 584fd14bc51SStefano Zampini 585e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 586e496cd5dSStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d cc %d (%d,%d).\n",PetscGlobalRank,sub_schurs->n_subs,sub_schurs->is_hermitian,sub_schurs->is_posdef); 587e496cd5dSStefano Zampini } 588e496cd5dSStefano Zampini 58908122e43SStefano Zampini /* max size of subsets */ 59008122e43SStefano Zampini mss = 0; 59108122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 59208122e43SStefano Zampini PetscInt subset_size; 593862806e4SStefano Zampini 59408122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 59508122e43SStefano Zampini mss = PetscMax(mss,subset_size); 59608122e43SStefano Zampini } 59708122e43SStefano Zampini 59808122e43SStefano Zampini /* min/max and threshold */ 59908122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 600f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 60108122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 602f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 603f6f667cfSStefano Zampini if (nmin) { 604f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 605f6f667cfSStefano Zampini } 60608122e43SStefano Zampini 60708122e43SStefano Zampini /* allocate lapack workspace */ 60808122e43SStefano Zampini cum = cum2 = 0; 60908122e43SStefano Zampini maxneigs = 0; 61008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 61108122e43SStefano Zampini PetscInt n,subset_size; 612f6f667cfSStefano Zampini 61308122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 61408122e43SStefano Zampini n = PetscMin(subset_size,nmax); 6159162d606SStefano Zampini cum += subset_size; 6169162d606SStefano Zampini cum2 += subset_size*n; 61708122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 61808122e43SStefano Zampini } 61908122e43SStefano Zampini if (mss) { 6209ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 62108122e43SStefano Zampini PetscBLASInt B_itype = 1; 62208122e43SStefano Zampini PetscBLASInt B_N = mss; 6234c6709b3SStefano Zampini PetscReal zero = 0.0; 6244c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 62508122e43SStefano Zampini 62608122e43SStefano Zampini B_lwork = -1; 62708122e43SStefano Zampini S = NULL; 62808122e43SStefano Zampini St = NULL; 629a58a30b4SStefano Zampini eigs = NULL; 630a58a30b4SStefano Zampini eigv = NULL; 631a58a30b4SStefano Zampini B_iwork = NULL; 632a58a30b4SStefano Zampini B_ifail = NULL; 633d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 634d1710679SStefano Zampini rwork = NULL; 635d1710679SStefano Zampini #endif 6368bec7fa6SStefano Zampini thresh = 1.0; 63708122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 63808122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 63908122e43SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&zero,&thresh,&B_dummyint,&B_dummyint,&eps,&B_neigs,eigs,eigv,&B_N,&lwork,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 64008122e43SStefano Zampini #else 64108122e43SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&zero,&thresh,&B_dummyint,&B_dummyint,&eps,&B_neigs,eigs,eigv,&B_N,&lwork,&B_lwork,B_iwork,B_ifail,&B_ierr)); 64208122e43SStefano Zampini #endif 64308122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 64408122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 64508122e43SStefano Zampini } else { 64608122e43SStefano Zampini /* TODO */ 64708122e43SStefano Zampini } 64808122e43SStefano Zampini } else { 64908122e43SStefano Zampini lwork = 0; 65008122e43SStefano Zampini } 65108122e43SStefano Zampini 65208122e43SStefano Zampini nv = 0; 653d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { /* complement set of active subsets, each entry is a vertex (boundary made by active subsets, vertices and dirichlet dofs) */ 654d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 65508122e43SStefano Zampini } 6564c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 657f6f667cfSStefano Zampini if (allocated_S_St) { 658f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 659f6f667cfSStefano Zampini } 660f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 66108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 66208122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 66308122e43SStefano Zampini #endif 6649162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 6659162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 6669162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 66708122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 6689162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 66908122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 67008122e43SStefano Zampini 67108122e43SStefano Zampini maxneigs = 0; 67208122e43SStefano Zampini cum = cum2 = cumarray = 0; 6739162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 6749162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 675d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 67608122e43SStefano Zampini const PetscInt *idxs; 67708122e43SStefano Zampini 678d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 67908122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 68008122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 68108122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 68208122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 6839162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 6849162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 68508122e43SStefano Zampini } 68608122e43SStefano Zampini cum2 = cum; 687d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 68808122e43SStefano Zampini } 68908122e43SStefano Zampini 69008122e43SStefano Zampini if (mss) { /* multilevel */ 69108122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 69208122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 69308122e43SStefano Zampini } 69408122e43SStefano Zampini 69508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 69608122e43SStefano Zampini 69708122e43SStefano Zampini const PetscInt *idxs; 698f6f667cfSStefano Zampini PetscReal infty = PETSC_MAX_REAL; 699862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 70008122e43SStefano Zampini PetscBLASInt B_N; 701aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 70208122e43SStefano Zampini 703862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 704f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 705f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 7069ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 707aff50787SStefano Zampini PetscInt j,k; 708aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 709aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 710aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 71108122e43SStefano Zampini } 71208122e43SStefano Zampini for (j=0;j<subset_size;j++) { 713aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 714aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 715aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 716aff50787SStefano Zampini } 71708122e43SStefano Zampini } 71808122e43SStefano Zampini } else { 71908122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 72008122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 72108122e43SStefano Zampini } 7228bec7fa6SStefano Zampini } else { 723f6f667cfSStefano Zampini S = Sarray + cumarray; 724f6f667cfSStefano Zampini St = Starray + cumarray; 7258bec7fa6SStefano Zampini } 72608122e43SStefano Zampini 727f6f667cfSStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 728aff50787SStefano Zampini /* see if we can save some work */ 729aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { 730aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 731aff50787SStefano Zampini } 732aff50787SStefano Zampini 733aff50787SStefano Zampini if (same_data) { /* there's no need of constraints here, deluxe scaling is enough */ 734aff50787SStefano Zampini B_neigs = 0; 735aff50787SStefano Zampini } else { 736aff50787SStefano Zampini /* Threshold: this is an heuristic for edges */ 737f6f667cfSStefano Zampini thresh = pcbddc->mat_graph->count[idxs[0]]*pcbddc->adaptive_threshold; 738*1cf9b237SStefano Zampini if (nmin) { 739*1cf9b237SStefano Zampini Mat SM,StM; 740*1cf9b237SStefano Zampini PetscInt j,k,nccs,nccst; 741*1cf9b237SStefano Zampini 742*1cf9b237SStefano Zampini for (j=0;j<subset_size;j++) { 743*1cf9b237SStefano Zampini for (k=j;k<subset_size;k++) { 744*1cf9b237SStefano Zampini S [k*subset_size+j] = S [j*subset_size+k]; 745*1cf9b237SStefano Zampini St[k*subset_size+j] = St[j*subset_size+k]; 746*1cf9b237SStefano Zampini } 747*1cf9b237SStefano Zampini } 748*1cf9b237SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,S,&SM);CHKERRQ(ierr); 749*1cf9b237SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,St,&StM);CHKERRQ(ierr); 750*1cf9b237SStefano Zampini ierr = MatDetectDisconnectedComponents(SM,PETSC_TRUE,&nccs,NULL);CHKERRQ(ierr); 751*1cf9b237SStefano Zampini ierr = MatDetectDisconnectedComponents(StM,PETSC_TRUE,&nccst,NULL);CHKERRQ(ierr); 752*1cf9b237SStefano Zampini if (nccs != 1 || nccst != 1) { 753*1cf9b237SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] Found disc %d %d (size %d)\n",PetscGlobalRank,nccs,nccst,subset_size); 754*1cf9b237SStefano Zampini } 755*1cf9b237SStefano Zampini ierr = MatDestroy(&SM);CHKERRQ(ierr); 756*1cf9b237SStefano Zampini ierr = MatDestroy(&StM);CHKERRQ(ierr); 757*1cf9b237SStefano Zampini } 758f6f667cfSStefano Zampini 7599ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 76008122e43SStefano Zampini PetscBLASInt B_itype = 1; 761f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 7624c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 7639552c7c7SStefano Zampini PetscInt nmin_s; 76408122e43SStefano Zampini 765fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 7668bec7fa6SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Computing for sub %d/%d %d %d.\n",i,sub_schurs->n_subs,subset_size,pcbddc->mat_graph->count[idxs[0]]); 767fd14bc51SStefano Zampini } 768d16cbb6bSStefano Zampini 76908122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 770d16cbb6bSStefano Zampini if (thresh > 1.+PETSC_SMALL) { 771d16cbb6bSStefano Zampini 772d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 77308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 774f6f667cfSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 77508122e43SStefano Zampini #else 776f6f667cfSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 77708122e43SStefano Zampini #endif 778d16cbb6bSStefano Zampini } else { 779d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 780d16cbb6bSStefano Zampini B_IL = 1; 781d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 782d16cbb6bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 783d16cbb6bSStefano Zampini #else 784d16cbb6bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 785d16cbb6bSStefano Zampini #endif 786d16cbb6bSStefano Zampini } 78708122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 78808122e43SStefano Zampini if (B_ierr) { 78908122e43SStefano Zampini if (B_ierr < 0 ) { 79008122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 79108122e43SStefano Zampini } else if (B_ierr <= B_N) { 79208122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 79308122e43SStefano Zampini } else { 7949552c7c7SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: leading minor of order %d is not positive definite",(int)B_ierr-B_N-1); 79508122e43SStefano Zampini } 79608122e43SStefano Zampini } 79708122e43SStefano Zampini 79808122e43SStefano Zampini if (B_neigs > nmax) { 799fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 800fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 801fd14bc51SStefano Zampini } 802f6f667cfSStefano Zampini eigs_start = B_neigs -nmax; 80308122e43SStefano Zampini B_neigs = nmax; 80408122e43SStefano Zampini } 80508122e43SStefano Zampini 8069552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 8079552c7c7SStefano Zampini if (B_neigs < nmin_s) { 80808122e43SStefano Zampini PetscBLASInt B_neigs2; 80908122e43SStefano Zampini 810f6f667cfSStefano Zampini B_IU = B_N - B_neigs; 811f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 812fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 813fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, less than minimum required %d. Asking for %d to %d incl (fortran like)\n",B_neigs,nmin,B_IL,B_IU); 814fd14bc51SStefano Zampini } 8159ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 81608122e43SStefano Zampini PetscInt j; 81708122e43SStefano Zampini for (j=0;j<subset_size;j++) { 81808122e43SStefano Zampini ierr = PetscMemcpy(S+j*(subset_size+1),Sarray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 81908122e43SStefano Zampini } 82008122e43SStefano Zampini for (j=0;j<subset_size;j++) { 82108122e43SStefano Zampini ierr = PetscMemcpy(St+j*(subset_size+1),Starray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 82208122e43SStefano Zampini } 82308122e43SStefano Zampini } else { 82408122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 82508122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 82608122e43SStefano Zampini } 82708122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 82808122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 829f6f667cfSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*subset_size,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 83008122e43SStefano Zampini #else 831f6f667cfSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*subset_size,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 83208122e43SStefano Zampini #endif 83308122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 83408122e43SStefano Zampini B_neigs += B_neigs2; 83508122e43SStefano Zampini } 83608122e43SStefano Zampini if (B_ierr) { 83708122e43SStefano Zampini if (B_ierr < 0 ) { 83808122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 83908122e43SStefano Zampini } else if (B_ierr <= B_N) { 84008122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 84108122e43SStefano Zampini } else { 8429552c7c7SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: leading minor of order %d is not positive definite",(int)B_ierr-B_N-1); 84308122e43SStefano Zampini } 84408122e43SStefano Zampini } 845fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 846ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 84708122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 84808122e43SStefano Zampini if (eigs[j] == 0.0) { 849ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 85008122e43SStefano Zampini } else { 851ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 852fd14bc51SStefano Zampini } 85308122e43SStefano Zampini } 85408122e43SStefano Zampini } 85508122e43SStefano Zampini } else { 85608122e43SStefano Zampini /* TODO */ 85708122e43SStefano Zampini } 858aff50787SStefano Zampini } 8598bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 8608bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 8619162d606SStefano Zampini if (B_neigs) { 8629162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum],eigv+eigs_start*subset_size,B_neigs*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 863fd14bc51SStefano Zampini 864fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 8659552c7c7SStefano Zampini PetscInt ii; 8669552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 867ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 8689552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 869ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 870ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 871ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 872ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 873ac47001eSStefano Zampini #else 874ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]);CHKERRQ(ierr); 875ac47001eSStefano Zampini #endif 8769552c7c7SStefano Zampini } 8779552c7c7SStefano Zampini } 878fd14bc51SStefano Zampini } 87908122e43SStefano Zampini #if 0 8809162d606SStefano Zampini for (j=0;j<B_neigs;j++) { 88108122e43SStefano Zampini PetscBLASInt Blas_N,Blas_one = 1.0; 88208122e43SStefano Zampini PetscScalar norm; 88308122e43SStefano Zampini ierr = PetscBLASIntCast(subset_size,&Blas_N);CHKERRQ(ierr); 8849162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size, 8859162d606SStefano Zampini &Blas_one,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 88608122e43SStefano Zampini if (pcbddc->adaptive_constraints_data[cum2] > 0.0) { 88708122e43SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 88808122e43SStefano Zampini } else { 88908122e43SStefano Zampini norm = -1.0/PetscSqrtReal(PetscRealPart(norm)); 89008122e43SStefano Zampini } 8919162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 892b1b3d7a2SStefano Zampini } 893b1b3d7a2SStefano Zampini #endif 8949162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 8959162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 8969162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 8979162d606SStefano Zampini cum++; 89808122e43SStefano Zampini } 89908122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 90008122e43SStefano Zampini /* shift for next computation */ 90108122e43SStefano Zampini cumarray += subset_size*subset_size; 90208122e43SStefano Zampini } 903fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 904fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 905fd14bc51SStefano Zampini } 90608122e43SStefano Zampini 90708122e43SStefano Zampini if (mss) { 90808122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 90908122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 910f6f667cfSStefano Zampini /* destroy matrices (junk) */ 911f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 912f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 91308122e43SStefano Zampini } 914f6f667cfSStefano Zampini if (allocated_S_St) { 915f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 916f6f667cfSStefano Zampini } 917f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 91808122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 91908122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 92008122e43SStefano Zampini #endif 92108122e43SStefano Zampini if (pcbddc->dbg_flag) { 9221b968477SStefano Zampini PetscInt maxneigs_r; 92308122e43SStefano Zampini ierr = MPI_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 9249b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 92508122e43SStefano Zampini } 92608122e43SStefano Zampini PetscFunctionReturn(0); 92708122e43SStefano Zampini } 928b1b3d7a2SStefano Zampini 929674ae819SStefano Zampini #undef __FUNCT__ 930c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 931c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 932c8587f34SStefano Zampini { 933c8587f34SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 9348629588bSStefano Zampini PetscScalar *coarse_submat_vals; 935c8587f34SStefano Zampini PetscErrorCode ierr; 936c8587f34SStefano Zampini 937c8587f34SStefano Zampini PetscFunctionBegin; 938f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 9395e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 940c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 941c8587f34SStefano Zampini 942684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 9430fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 944684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 945c8587f34SStefano Zampini 946c8587f34SStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 947b9b85e73SStefano Zampini if (pcbddc->NullSpace && pcbddc->ChangeOfBasisMatrix) { 948c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 949c8587f34SStefano Zampini } 950c8587f34SStefano Zampini 9518629588bSStefano Zampini /* 9528629588bSStefano Zampini Setup local correction and local part of coarse basis. 9538629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 9548629588bSStefano Zampini */ 95547f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 9568629588bSStefano Zampini 9578629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 9588629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 9598629588bSStefano Zampini 9608629588bSStefano Zampini /* free */ 9618629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 962c8587f34SStefano Zampini PetscFunctionReturn(0); 963c8587f34SStefano Zampini } 964c8587f34SStefano Zampini 965c8587f34SStefano Zampini #undef __FUNCT__ 966674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 967674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 968674ae819SStefano Zampini { 969674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 970674ae819SStefano Zampini PetscErrorCode ierr; 971674ae819SStefano Zampini 972674ae819SStefano Zampini PetscFunctionBegin; 973674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 974674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 975674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 976674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 977785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 978674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 979f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 980f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 981785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 98263602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 98363602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 984674ae819SStefano Zampini PetscFunctionReturn(0); 985674ae819SStefano Zampini } 986674ae819SStefano Zampini 987674ae819SStefano Zampini #undef __FUNCT__ 988674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 989674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 990674ae819SStefano Zampini { 991674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 9924f1b2e48SStefano Zampini PetscInt i; 993674ae819SStefano Zampini PetscErrorCode ierr; 994674ae819SStefano Zampini 995674ae819SStefano Zampini PetscFunctionBegin; 996b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 997674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 998674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 999674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 10004f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 10014f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 10024f1b2e48SStefano Zampini } 10034f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 1004b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 1005674ae819SStefano Zampini PetscFunctionReturn(0); 1006674ae819SStefano Zampini } 1007674ae819SStefano Zampini 1008674ae819SStefano Zampini #undef __FUNCT__ 1009674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 1010674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 1011674ae819SStefano Zampini { 1012674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 101306656605SStefano Zampini PetscScalar *array; 1014674ae819SStefano Zampini PetscErrorCode ierr; 1015674ae819SStefano Zampini 1016674ae819SStefano Zampini PetscFunctionBegin; 1017674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 101858da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 101906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 102006656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 102158da7f69SStefano Zampini } 1022674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1023674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 102415aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 102515aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1026674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 1027674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 1028674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 102906656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 1030674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1031674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 10328ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1033674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1034674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1035674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 1036f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 1037f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 1038f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 1039f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 1040727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 10410e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 1042f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 104370cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 10446e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 104581d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 10460369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 10478b9f24d4SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 10484f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 10494f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 10508b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 10514f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 1052674ae819SStefano Zampini PetscFunctionReturn(0); 1053674ae819SStefano Zampini } 1054674ae819SStefano Zampini 1055674ae819SStefano Zampini #undef __FUNCT__ 1056f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 1057f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 10586bfb1811SStefano Zampini { 10596bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 10606bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 10616bfb1811SStefano Zampini VecType impVecType; 10624f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 10636bfb1811SStefano Zampini PetscErrorCode ierr; 10646bfb1811SStefano Zampini 10656bfb1811SStefano Zampini PetscFunctionBegin; 1066f4ddd8eeSStefano Zampini if (!pcbddc->ConstraintMatrix) { 1067019a44ceSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 1068f4ddd8eeSStefano Zampini } 1069e7b262bdSStefano Zampini /* get sizes */ 10704f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 1071b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 10726bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 1073e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 1074e7b262bdSStefano Zampini /* R nodes */ 1075e7b262bdSStefano Zampini old_size = -1; 1076e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 1077e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 1078e7b262bdSStefano Zampini } 1079e7b262bdSStefano Zampini if (n_R != old_size) { 1080e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1081e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 10826bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 10836bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 10846bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 10856bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 1086e7b262bdSStefano Zampini } 1087e7b262bdSStefano Zampini /* local primal dofs */ 1088e7b262bdSStefano Zampini old_size = -1; 1089e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 1090e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 1091e7b262bdSStefano Zampini } 1092e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 1093e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 109483b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 1095e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 10966bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 1097e7b262bdSStefano Zampini } 1098e7b262bdSStefano Zampini /* local explicit constraints */ 1099e7b262bdSStefano Zampini old_size = -1; 1100e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 1101e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 1102e7b262bdSStefano Zampini } 1103e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 1104e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 110583b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 110683b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 110783b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 110883b7ccabSStefano Zampini } 11096bfb1811SStefano Zampini PetscFunctionReturn(0); 11106bfb1811SStefano Zampini } 11116bfb1811SStefano Zampini 11126bfb1811SStefano Zampini #undef __FUNCT__ 111347f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 111447f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 111588ebb749SStefano Zampini { 111625084f0cSStefano Zampini PetscErrorCode ierr; 111725084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 111888ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 111988ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1120d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 112125084f0cSStefano Zampini /* submatrices of local problem */ 112280677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 1123019a44ceSStefano Zampini /* submatrices of benign trick */ 1124d16cbb6bSStefano Zampini Mat B0_V = NULL; 112506656605SStefano Zampini /* submatrices of local coarse problem */ 112606656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 112725084f0cSStefano Zampini /* working matrices */ 112806656605SStefano Zampini Mat C_CR; 112925084f0cSStefano Zampini /* additional working stuff */ 113006656605SStefano Zampini PC pc_R; 11314f1b2e48SStefano Zampini Mat F; 113206656605SStefano Zampini PetscBool isLU,isCHOL,isILU; 113306656605SStefano Zampini 113425084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 113506656605SStefano Zampini PetscScalar *work; 113606656605SStefano Zampini PetscInt *idx_V_B; 11374f1b2e48SStefano Zampini PetscInt n,n_vertices,n_constraints,*p0_lidx_I; 113806656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 1139b9d89cd5SStefano Zampini PetscBool unsymmetric_check; 114045a1bb75SStefano Zampini /* matrix type (vector type propagated downstream from vec1_C and local matrix type) */ 114188ebb749SStefano Zampini MatType impMatType; 114225084f0cSStefano Zampini /* some shortcuts to scalars */ 114306656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 114488ebb749SStefano Zampini 114588ebb749SStefano Zampini PetscFunctionBegin; 1146b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 11474f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 114888ebb749SStefano Zampini /* Set Non-overlapping dimensions */ 1149b371cd4fSStefano Zampini n_B = pcis->n_B; 1150b371cd4fSStefano Zampini n_D = pcis->n - n_B; 115188ebb749SStefano Zampini n_R = pcis->n - n_vertices; 115288ebb749SStefano Zampini 115388ebb749SStefano Zampini /* Set types for local objects needed by BDDC precondtioner */ 115488ebb749SStefano Zampini impMatType = MATSEQDENSE; 115588ebb749SStefano Zampini 115688ebb749SStefano Zampini /* vertices in boundary numbering */ 1157785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 11580e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 115988ebb749SStefano Zampini if (i != n_vertices) { 116022d5777bSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 116188ebb749SStefano Zampini } 116288ebb749SStefano Zampini 116306656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 1164019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 116506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 116606656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 116706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 116806656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 116906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 117006656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 117106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 117206656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 117306656605SStefano Zampini 117406656605SStefano Zampini unsymmetric_check = PETSC_FALSE; 117506656605SStefano Zampini /* allocate workspace */ 117606656605SStefano Zampini n = 0; 117706656605SStefano Zampini if (n_constraints) { 117806656605SStefano Zampini n += n_R*n_constraints; 117906656605SStefano Zampini } 118006656605SStefano Zampini if (n_vertices) { 118106656605SStefano Zampini n = PetscMax(2*n_R*n_vertices,n); 118280677318SStefano Zampini n = PetscMax((n_R+n_B)*n_vertices,n); 118306656605SStefano Zampini } 11843301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 118506656605SStefano Zampini n = PetscMax(2*n_R*pcbddc->local_primal_size,n); 118606656605SStefano Zampini unsymmetric_check = PETSC_TRUE; 118706656605SStefano Zampini } 118806656605SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 118906656605SStefano Zampini 119006656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 119106656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 119206656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 119306656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 119406656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 119506656605SStefano Zampini if (isLU || isILU || isCHOL) { 119606656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 1197d62866d3SStefano Zampini } else if (sub_schurs->reuse_mumps) { 1198d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 1199d62866d3SStefano Zampini MatFactorType type; 1200d62866d3SStefano Zampini 12016816873aSStefano Zampini F = reuse_mumps->F; 12026816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 1203d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 120406656605SStefano Zampini } else { 120506656605SStefano Zampini F = NULL; 120606656605SStefano Zampini } 120706656605SStefano Zampini 120888ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 120988ebb749SStefano Zampini if (n_constraints) { 121006656605SStefano Zampini Mat M1,M2,M3; 121180677318SStefano Zampini Mat auxmat; 121206656605SStefano Zampini IS is_aux; 121380677318SStefano Zampini PetscScalar *array,*array2; 121406656605SStefano Zampini 1215f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 121680677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 121788ebb749SStefano Zampini 121825084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 121925084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 12208ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 122180677318SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&auxmat);CHKERRQ(ierr); 122288ebb749SStefano Zampini 122380677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 122480677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 122506656605SStefano Zampini ierr = PetscMemzero(work,n_R*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 122688ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 122706656605SStefano Zampini const PetscScalar *row_cmat_values; 122806656605SStefano Zampini const PetscInt *row_cmat_indices; 122906656605SStefano Zampini PetscInt size_of_constraint,j; 123088ebb749SStefano Zampini 123106656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 123206656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 123306656605SStefano Zampini work[row_cmat_indices[j]+i*n_R] = -row_cmat_values[j]; 123406656605SStefano Zampini } 123506656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 123606656605SStefano Zampini } 123780677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 123806656605SStefano Zampini if (F) { 123906656605SStefano Zampini Mat B; 124006656605SStefano Zampini 124106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 124280677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 124306656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 124406656605SStefano Zampini } else { 124580677318SStefano Zampini PetscScalar *marr; 124680677318SStefano Zampini 124780677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 124806656605SStefano Zampini for (i=0;i<n_constraints;i++) { 124906656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 125080677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*n_R);CHKERRQ(ierr); 125106656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 125206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 125306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 125406656605SStefano Zampini } 125580677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 125606656605SStefano Zampini } 125780677318SStefano Zampini if (!pcbddc->switch_static) { 125880677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 125980677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 126080677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 126180677318SStefano Zampini for (i=0;i<n_constraints;i++) { 126280677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*n_R);CHKERRQ(ierr); 126380677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 126480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 126580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 126680677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 126780677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 126880677318SStefano Zampini } 126980677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 127080677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 127180677318SStefano Zampini ierr = MatMatMult(auxmat,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 127280677318SStefano Zampini } else { 127380677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 127480677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 127525084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 127680677318SStefano Zampini } 127780677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 127880677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 127980677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 128006656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 128106656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 128280677318SStefano Zampini if (isCHOL) { 128380677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 128480677318SStefano Zampini } else { 128525084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 128680677318SStefano Zampini } 128780677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 128806656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 128925084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 129025084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 129125084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 129280677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 129380677318SStefano Zampini ierr = MatMatMult(M1,auxmat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 129480677318SStefano Zampini ierr = MatDestroy(&auxmat);CHKERRQ(ierr); 129506656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 129606656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 1297f4ddd8eeSStefano Zampini } 129888ebb749SStefano Zampini /* Get submatrices from subdomain matrix */ 12994f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1300d16cbb6bSStefano Zampini IS dummy; 1301d16cbb6bSStefano Zampini Mat B0_R; 1302d16cbb6bSStefano Zampini PetscReal norm; 1303d16cbb6bSStefano Zampini 13044f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 13054f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&B0_R);CHKERRQ(ierr); 1306d16cbb6bSStefano Zampini ierr = MatNorm(B0_R,NORM_INFINITY,&norm);CHKERRQ(ierr); 1307d16cbb6bSStefano Zampini if (norm > PETSC_SMALL) { 1308d16cbb6bSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! ||B0_R|| = %f (should be numerically 0.)",norm); 1309d16cbb6bSStefano Zampini } 1310d16cbb6bSStefano Zampini ierr = MatDestroy(&B0_R);CHKERRQ(ierr); 1311d16cbb6bSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1312d16cbb6bSStefano Zampini } 1313d16cbb6bSStefano Zampini 131488ebb749SStefano Zampini if (n_vertices) { 131506656605SStefano Zampini IS is_aux; 13163a50541eSStefano Zampini 13176816873aSStefano Zampini if (sub_schurs->reuse_mumps) { /* is_R_local is not sorted, ISComplement doesn't like it */ 13186816873aSStefano Zampini IS tis; 13196816873aSStefano Zampini 13206816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 13216816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 13226816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 13236816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 13246816873aSStefano Zampini } else { 13253a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 13266816873aSStefano Zampini } 13279577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 13289577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 132904708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 13304f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1331019a44ceSStefano Zampini IS dummy; 1332019a44ceSStefano Zampini 13334f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 13344f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,is_aux,MAT_INITIAL_MATRIX,&B0_V);CHKERRQ(ierr); 1335019a44ceSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1336019a44ceSStefano Zampini } 133725084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 133888ebb749SStefano Zampini } 133988ebb749SStefano Zampini 134088ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 1341f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 134206656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 134306656605SStefano Zampini if (pcbddc->coarse_phi_D) { 134406656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 134506656605SStefano Zampini } 1346f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 134706656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 134806656605SStefano Zampini PetscScalar *marray; 134906656605SStefano Zampini 135006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 135106656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 1352f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1353f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 1354f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 1355f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1356f4ddd8eeSStefano Zampini } 1357f4ddd8eeSStefano Zampini } 135806656605SStefano Zampini 1359f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 136006656605SStefano Zampini PetscScalar *marray; 136188ebb749SStefano Zampini 136206656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 13638eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 136406656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 136588ebb749SStefano Zampini } 13663301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 136706656605SStefano Zampini n *= 2; 136888ebb749SStefano Zampini } 136906656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 137006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 137106656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 13728eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 137306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 137406656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 137588ebb749SStefano Zampini } 13763301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 137706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 13788eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 137906656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 138006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 138188ebb749SStefano Zampini } 138288ebb749SStefano Zampini } else { 1383c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 1384c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 13851b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1386c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 1387c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 1388c0553b1fSStefano Zampini } 138988ebb749SStefano Zampini } 139006656605SStefano Zampini } 1391019a44ceSStefano Zampini 139206656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 13934f1b2e48SStefano Zampini p0_lidx_I = NULL; 13944f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 1395d12edf2fSStefano Zampini const PetscInt *idxs; 1396d12edf2fSStefano Zampini 1397d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 13984f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 13994f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 14004f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 14014f1b2e48SStefano Zampini } 1402d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 1403d12edf2fSStefano Zampini } 1404d16cbb6bSStefano Zampini 140506656605SStefano Zampini /* vertices */ 140606656605SStefano Zampini if (n_vertices) { 140716f15bc4SStefano Zampini 140804708bb6SStefano Zampini ierr = MatConvert(A_VV,impMatType,MAT_REUSE_MATRIX,&A_VV);CHKERRQ(ierr); 140904708bb6SStefano Zampini 141016f15bc4SStefano Zampini if (n_R) { 141106656605SStefano Zampini Mat A_RRmA_RV,S_VVt; /* S_VVt with LDA=N */ 141206656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 141316f15bc4SStefano Zampini PetscScalar *x,*y; 141404708bb6SStefano Zampini PetscBool isseqaij; 141506656605SStefano Zampini 141621eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 141706656605SStefano Zampini ierr = MatConvert(A_RV,impMatType,MAT_REUSE_MATRIX,&A_RV);CHKERRQ(ierr); 141804708bb6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 14196816873aSStefano Zampini if (F) { /* TODO could be optimized for symmetric problems */ 142006656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 142106656605SStefano Zampini } else { 142206656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 142306656605SStefano Zampini for (i=0;i<n_vertices;i++) { 142406656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*n_R);CHKERRQ(ierr); 142506656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 142606656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 142706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 142806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 142906656605SStefano Zampini } 143006656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 143106656605SStefano Zampini } 143280677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 143306656605SStefano Zampini /* S_VV and S_CV are the subdomain contribution to coarse matrix. WARNING -> column major ordering */ 143406656605SStefano Zampini if (n_constraints) { 143506656605SStefano Zampini Mat B; 143680677318SStefano Zampini 1437b3d85658SStefano Zampini ierr = PetscMemzero(work+n_R*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 143880677318SStefano Zampini for (i=0;i<n_vertices;i++) { 143980677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 144080677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+n_R*n_vertices+i*n_B);CHKERRQ(ierr); 144180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 144280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 144380677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 144480677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 144580677318SStefano Zampini } 144680677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+n_R*n_vertices,&B);CHKERRQ(ierr); 144780677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 144880677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 144906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work+n_R*n_vertices,&B);CHKERRQ(ierr); 145080677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 145106656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 145206656605SStefano Zampini ierr = PetscBLASIntCast(n_R*n_vertices,&B_N);CHKERRQ(ierr); 145306656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+n_R*n_vertices,&B_one,work,&B_one)); 145406656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 145506656605SStefano Zampini } 145604708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 145704708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 145804708bb6SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_REUSE_MATRIX,&A_VR);CHKERRQ(ierr); 145904708bb6SStefano Zampini } 146006656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 146180677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 146206656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 146306656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 146406656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 146506656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 146606656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 146706656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 146806656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1469d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 1470019a44ceSStefano Zampini } else { 1471d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1472d16cbb6bSStefano Zampini } 14734f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1474019a44ceSStefano Zampini const PetscScalar *vals; 1475019a44ceSStefano Zampini const PetscInt *idxs; 14764f1b2e48SStefano Zampini PetscInt n,j,primal_idx; 1477019a44ceSStefano Zampini 14784f1b2e48SStefano Zampini ierr = MatGetRow(B0_V,i,&n,&idxs,&vals);CHKERRQ(ierr); 14794f1b2e48SStefano Zampini primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + i; 1480d16cbb6bSStefano Zampini for (j=0;j<n;j++) { 14814f1b2e48SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+idxs[j]] = vals[j]; 14824f1b2e48SStefano Zampini coarse_submat_vals[idxs[j]*pcbddc->local_primal_size+primal_idx] = vals[j]; 1483019a44ceSStefano Zampini } 14844f1b2e48SStefano Zampini ierr = MatRestoreRow(B0_V,i,&n,&idxs,&vals);CHKERRQ(ierr); 148516f15bc4SStefano Zampini } 148621eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 1487d16cbb6bSStefano Zampini 148806656605SStefano Zampini /* coarse basis functions */ 148906656605SStefano Zampini for (i=0;i<n_vertices;i++) { 149016f15bc4SStefano Zampini PetscScalar *y; 149116f15bc4SStefano Zampini 149206656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*i);CHKERRQ(ierr); 149306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 149406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 149506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 149606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 149706656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 149806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 149906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 150006656605SStefano Zampini 150106656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 15024f1b2e48SStefano Zampini PetscInt j; 15034f1b2e48SStefano Zampini 150406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 150506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 150606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 150706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 150806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 15094f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 151006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 151106656605SStefano Zampini } 151206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 151306656605SStefano Zampini } 151404708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 151504708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 151606656605SStefano Zampini } 151706656605SStefano Zampini 151806656605SStefano Zampini if (n_constraints) { 151906656605SStefano Zampini Mat B; 152006656605SStefano Zampini 152106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 152206656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 152380677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 152406656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 152506656605SStefano Zampini if (n_vertices) { 152680677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 152780677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 152880677318SStefano Zampini } else { 152980677318SStefano Zampini Mat S_VCt; 153080677318SStefano Zampini 153180677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 153280677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 153380677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 153480677318SStefano Zampini } 153506656605SStefano Zampini } 153606656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 153706656605SStefano Zampini /* coarse basis functions */ 153806656605SStefano Zampini for (i=0;i<n_constraints;i++) { 153906656605SStefano Zampini PetscScalar *y; 154006656605SStefano Zampini 154106656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*i);CHKERRQ(ierr); 154206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 154306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 154406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 154506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 154606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 154706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 154806656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 15494f1b2e48SStefano Zampini PetscInt j; 15504f1b2e48SStefano Zampini 155106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 155206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 155306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 155406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 155506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 15564f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 155706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 155806656605SStefano Zampini } 155906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 156006656605SStefano Zampini } 156106656605SStefano Zampini } 156280677318SStefano Zampini if (n_constraints) { 156380677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 156480677318SStefano Zampini } 15654f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 1566019a44ceSStefano Zampini ierr = MatDestroy(&B0_V);CHKERRQ(ierr); 1567019a44ceSStefano Zampini 156806656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 15693301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 157006656605SStefano Zampini 157106656605SStefano Zampini if (n_constraints) { 157216f15bc4SStefano Zampini Mat S_CCT,B_C; 157306656605SStefano Zampini 157480677318SStefano Zampini /* this is a lazy thing */ 157580677318SStefano Zampini ierr = MatConvert(C_CR,impMatType,MAT_REUSE_MATRIX,&C_CR);CHKERRQ(ierr); 157606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work+n_vertices*n_R,&B_C);CHKERRQ(ierr); 157706656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 157806656605SStefano Zampini ierr = MatTransposeMatMult(C_CR,S_CCT,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 157916f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 158006656605SStefano Zampini if (n_vertices) { 158116f15bc4SStefano Zampini Mat B_V,S_VCT; 158206656605SStefano Zampini 158306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&B_V);CHKERRQ(ierr); 158406656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 158506656605SStefano Zampini ierr = MatTransposeMatMult(C_CR,S_VCT,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 158606656605SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 158716f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 158806656605SStefano Zampini } 158906656605SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 159080677318SStefano Zampini } else { /* if there are no constraints, reset work */ 159180677318SStefano Zampini ierr = PetscMemzero(work,n_R*pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 159206656605SStefano Zampini } 159316f15bc4SStefano Zampini if (n_vertices && n_R) { 159406656605SStefano Zampini Mat A_VRT; 159580677318SStefano Zampini PetscScalar *marray; 159606656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 159706656605SStefano Zampini 159880677318SStefano Zampini ierr = MatTranspose(A_VR,MAT_INITIAL_MATRIX,&A_VRT);CHKERRQ(ierr); 159980677318SStefano Zampini ierr = MatConvert(A_VRT,impMatType,MAT_REUSE_MATRIX,&A_VRT);CHKERRQ(ierr); 160080677318SStefano Zampini ierr = MatDenseGetArray(A_VRT,&marray);CHKERRQ(ierr); 160106656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_R,&B_N);CHKERRQ(ierr); 160280677318SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&m_one,marray,&B_one,work,&B_one)); 160380677318SStefano Zampini ierr = MatDenseRestoreArray(A_VRT,&marray);CHKERRQ(ierr); 160416f15bc4SStefano Zampini ierr = MatDestroy(&A_VRT);CHKERRQ(ierr); 160506656605SStefano Zampini } 160606656605SStefano Zampini 160706656605SStefano Zampini if (F) { /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 160806656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 160906656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 161006656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+(i+pcbddc->local_primal_size)*n_R);CHKERRQ(ierr); 161106656605SStefano Zampini ierr = MatSolveTranspose(F,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 161206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 161306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 161406656605SStefano Zampini } 161506656605SStefano Zampini } else { 161606656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 161706656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 161806656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+(i+pcbddc->local_primal_size)*n_R);CHKERRQ(ierr); 161906656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 162006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 162106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 162206656605SStefano Zampini } 162306656605SStefano Zampini } 162406656605SStefano Zampini /* coarse basis functions */ 162506656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 162606656605SStefano Zampini PetscScalar *y; 162706656605SStefano Zampini 162806656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*(i+pcbddc->local_primal_size));CHKERRQ(ierr); 162906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 163006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 163106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 163206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 163306656605SStefano Zampini if (i<n_vertices) { 163406656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 163506656605SStefano Zampini } 163606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 163706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 163806656605SStefano Zampini 163906656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 164006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 164106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 164206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 164306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 164406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 164506656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 164606656605SStefano Zampini } 164706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 164806656605SStefano Zampini } 164906656605SStefano Zampini } 1650d62866d3SStefano Zampini /* free memory */ 165188ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 165206656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 165306656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 165406656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 165506656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 1656d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 1657d62866d3SStefano Zampini if (n_vertices) { 1658d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 1659d62866d3SStefano Zampini } 1660d62866d3SStefano Zampini if (n_constraints) { 1661d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 1662d62866d3SStefano Zampini } 166388ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 166488ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 166588ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 1666d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 166788ebb749SStefano Zampini Mat coarse_sub_mat; 166825084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 166988ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 167088ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 167188ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 16728bec7fa6SStefano Zampini Mat C_B,CPHI; 16738bec7fa6SStefano Zampini IS is_dummy; 16748bec7fa6SStefano Zampini Vec mones; 167588ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 167688ebb749SStefano Zampini PetscReal real_value; 167788ebb749SStefano Zampini 167888ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 167988ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 168088ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 168188ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 168288ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 168388ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 1684c0553b1fSStefano Zampini if (unsymmetric_check) { 168588ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 168688ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 168788ebb749SStefano Zampini } 168888ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 168988ebb749SStefano Zampini 169025084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 16913301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 169225084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1693c0553b1fSStefano Zampini if (unsymmetric_check) { 169488ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 169588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 169688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 169788ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 169888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 169988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 170088ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 170188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 170288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 170388ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 170488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 170588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 170688ebb749SStefano Zampini } else { 170788ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 170888ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 170988ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 171088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 171188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 171288ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 171388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 171488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 171588ebb749SStefano Zampini } 171688ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 171788ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 171888ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 171988ebb749SStefano Zampini ierr = MatConvert(TM1,MATSEQDENSE,MAT_REUSE_MATRIX,&TM1);CHKERRQ(ierr); 17204f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1721d12edf2fSStefano Zampini Mat B0_I,B0_B,B0_BPHI,B0_IPHI; 1722d12edf2fSStefano Zampini PetscScalar *data,*data2; 17234f1b2e48SStefano Zampini PetscInt j; 1724d12edf2fSStefano Zampini 17254f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 17264f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B); 17274f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_I_local,MAT_INITIAL_MATRIX,&B0_I); 1728d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 1729d12edf2fSStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_REUSE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 1730d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 1731d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 17324f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 17334f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 1734d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 17354f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 17364f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 17374f1b2e48SStefano Zampini } 1738d12edf2fSStefano Zampini } 1739d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 1740d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 1741d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 1742d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 1743d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 1744d12edf2fSStefano Zampini ierr = MatMatMult(B0_I,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&B0_IPHI);CHKERRQ(ierr); 1745d12edf2fSStefano Zampini ierr = MatDestroy(&B0_I);CHKERRQ(ierr); 1746d12edf2fSStefano Zampini ierr = MatNorm(B0_IPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1747d12edf2fSStefano Zampini ierr = MatDestroy(&B0_IPHI);CHKERRQ(ierr); 1748d12edf2fSStefano Zampini } 1749d12edf2fSStefano Zampini #if 0 1750d12edf2fSStefano Zampini { 1751d12edf2fSStefano Zampini PetscViewer viewer; 1752d12edf2fSStefano Zampini char filename[256]; 1753d12edf2fSStefano Zampini sprintf(filename,"proj_local_coarse_mat%d.m",PetscGlobalRank); 1754d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 1755d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1756d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 1757d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1758d12edf2fSStefano Zampini } 1759d12edf2fSStefano Zampini #endif 176081d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 17618bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 17620fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 176306656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 17648bec7fa6SStefano Zampini 17658bec7fa6SStefano Zampini /* check constraints */ 17664f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 17678bec7fa6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&is_dummy);CHKERRQ(ierr); 17688bec7fa6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B); 17698bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 17708bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 17718bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 17728bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 17738bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1774bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 1775c0553b1fSStefano Zampini if (unsymmetric_check) { 1776bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 1777bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 1778bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 1779bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1780bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 178188ebb749SStefano Zampini } 17828bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 17838bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 17848bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 17858bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 1786d12edf2fSStefano Zampini } 178725084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 178888ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 178988ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 179088ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 179188ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 179288ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 179388ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 179488ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 179588ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 179688ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 179788ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 1798c0553b1fSStefano Zampini if (unsymmetric_check) { 179988ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 180088ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 180188ebb749SStefano Zampini } 180288ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 180388ebb749SStefano Zampini } 18048629588bSStefano Zampini /* get back data */ 18058629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 180688ebb749SStefano Zampini PetscFunctionReturn(0); 180788ebb749SStefano Zampini } 180888ebb749SStefano Zampini 180988ebb749SStefano Zampini #undef __FUNCT__ 1810d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 1811d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 1812aa0d41d4SStefano Zampini { 1813d65f70fdSStefano Zampini Mat *work_mat; 1814d65f70fdSStefano Zampini IS isrow_s,iscol_s; 1815d65f70fdSStefano Zampini PetscBool rsorted,csorted; 1816d65f70fdSStefano Zampini PetscInt rsize,*idxs_perm_r,csize,*idxs_perm_c; 1817aa0d41d4SStefano Zampini PetscErrorCode ierr; 1818aa0d41d4SStefano Zampini 1819aa0d41d4SStefano Zampini PetscFunctionBegin; 1820d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 1821d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 1822d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 1823d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 1824aa0d41d4SStefano Zampini 1825d65f70fdSStefano Zampini if (!rsorted) { 1826906d46d4SStefano Zampini const PetscInt *idxs; 1827906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 1828aa0d41d4SStefano Zampini 1829d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 1830d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 1831d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1832d65f70fdSStefano Zampini idxs_perm_r[i] = i; 1833aa0d41d4SStefano Zampini } 1834d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 1835d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 1836d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1837d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 1838aa0d41d4SStefano Zampini } 1839d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 1840d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 1841d65f70fdSStefano Zampini } else { 1842d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 1843d65f70fdSStefano Zampini isrow_s = isrow; 1844aa0d41d4SStefano Zampini } 1845906d46d4SStefano Zampini 1846d65f70fdSStefano Zampini if (!csorted) { 1847d65f70fdSStefano Zampini if (isrow == iscol) { 1848d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 1849d65f70fdSStefano Zampini iscol_s = isrow_s; 1850d65f70fdSStefano Zampini } else { 1851d65f70fdSStefano Zampini const PetscInt *idxs; 1852d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 1853906d46d4SStefano Zampini 1854d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 1855d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 1856d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1857d65f70fdSStefano Zampini idxs_perm_c[i] = i; 1858d65f70fdSStefano Zampini } 1859d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 1860d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 1861d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1862d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 1863d65f70fdSStefano Zampini } 1864d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 1865d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 1866d65f70fdSStefano Zampini } 1867d65f70fdSStefano Zampini } else { 1868d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 1869d65f70fdSStefano Zampini iscol_s = iscol; 1870d65f70fdSStefano Zampini } 1871d65f70fdSStefano Zampini 1872d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 1873d65f70fdSStefano Zampini 1874d65f70fdSStefano Zampini if (!rsorted || !csorted) { 1875906d46d4SStefano Zampini Mat new_mat; 1876d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 1877906d46d4SStefano Zampini 1878d65f70fdSStefano Zampini if (!rsorted) { 1879d65f70fdSStefano Zampini PetscInt *idxs_r,i; 1880d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 1881d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1882d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 1883906d46d4SStefano Zampini } 1884d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 1885d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 1886d65f70fdSStefano Zampini } else { 1887d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 1888906d46d4SStefano Zampini } 1889d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 1890d65f70fdSStefano Zampini 1891d65f70fdSStefano Zampini if (!csorted) { 1892d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 1893d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 1894d65f70fdSStefano Zampini is_perm_c = is_perm_r; 1895d65f70fdSStefano Zampini } else { 1896d65f70fdSStefano Zampini PetscInt *idxs_c,i; 1897d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 1898d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1899d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 1900d65f70fdSStefano Zampini } 1901d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 1902d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 1903d65f70fdSStefano Zampini } 1904d65f70fdSStefano Zampini } else { 1905d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 1906d65f70fdSStefano Zampini } 1907d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 1908d65f70fdSStefano Zampini 1909d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 1910d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 1911d65f70fdSStefano Zampini work_mat[0] = new_mat; 1912d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 1913d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 1914d65f70fdSStefano Zampini } 1915d65f70fdSStefano Zampini 1916d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 1917d65f70fdSStefano Zampini *B = work_mat[0]; 1918d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 1919d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 1920d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 1921d65f70fdSStefano Zampini PetscFunctionReturn(0); 1922d65f70fdSStefano Zampini } 1923d65f70fdSStefano Zampini 1924d65f70fdSStefano Zampini #undef __FUNCT__ 19255e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 19265e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 1927aa0d41d4SStefano Zampini { 1928aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 19295e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1930d65f70fdSStefano Zampini Mat new_mat; 19315e8657edSStefano Zampini IS is_local,is_global; 1932d65f70fdSStefano Zampini PetscInt local_size; 1933d65f70fdSStefano Zampini PetscBool isseqaij; 1934aa0d41d4SStefano Zampini PetscErrorCode ierr; 1935aa0d41d4SStefano Zampini 1936aa0d41d4SStefano Zampini PetscFunctionBegin; 1937aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 19385e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 19395e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 1940b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 1941aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 1942d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 1943aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 1944906d46d4SStefano Zampini 1945906d46d4SStefano Zampini /* check */ 1946906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 1947906d46d4SStefano Zampini Vec x,x_change; 1948906d46d4SStefano Zampini PetscReal error; 1949906d46d4SStefano Zampini 19505e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 1951906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 19525e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 1953e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1954e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1955d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 1956e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1957e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1958906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 1959906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 1960906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1961906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 1962906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 1963906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 1964906d46d4SStefano Zampini } 1965906d46d4SStefano Zampini 196622d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 19679b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 196822d5777bSStefano Zampini if (isseqaij) { 1969*1cf9b237SStefano Zampini Mat M; 1970*1cf9b237SStefano Zampini 1971*1cf9b237SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 1972*1cf9b237SStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 1973*1cf9b237SStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 1974aa0d41d4SStefano Zampini } else { 1975*1cf9b237SStefano Zampini Mat work_mat,M; 1976*1cf9b237SStefano Zampini 1977aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 1978*1cf9b237SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 1979*1cf9b237SStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 1980*1cf9b237SStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 1981aa0d41d4SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 1982aa0d41d4SStefano Zampini } 19833301b35fSStefano Zampini if (matis->A->symmetric_set) { 19843301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 1985e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 19863301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 1987e496cd5dSStefano Zampini #endif 19883301b35fSStefano Zampini } 198945a1bb75SStefano Zampini /* 199045a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1991d65f70fdSStefano Zampini ierr = MatView(new_mat,(PetscViewer)0);CHKERRQ(ierr); 199245a1bb75SStefano Zampini */ 1993d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 1994aa0d41d4SStefano Zampini PetscFunctionReturn(0); 1995aa0d41d4SStefano Zampini } 1996aa0d41d4SStefano Zampini 1997aa0d41d4SStefano Zampini #undef __FUNCT__ 1998a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 19998ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 2000a64d13efSStefano Zampini { 2001a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2002a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2003d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 200453892102SStefano Zampini PetscInt *idx_R_local=NULL; 20053a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 20063a50541eSStefano Zampini PetscInt vbs,bs; 20076816873aSStefano Zampini PetscBT bitmask=NULL; 2008a64d13efSStefano Zampini PetscErrorCode ierr; 2009a64d13efSStefano Zampini 2010a64d13efSStefano Zampini PetscFunctionBegin; 2011b23d619eSStefano Zampini /* 2012b23d619eSStefano Zampini No need to setup local scatters if 2013b23d619eSStefano Zampini - primal space is unchanged 2014b23d619eSStefano Zampini AND 2015b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 2016b23d619eSStefano Zampini AND 2017b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 2018b23d619eSStefano Zampini */ 2019b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 2020f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 2021f4ddd8eeSStefano Zampini } 2022f4ddd8eeSStefano Zampini /* destroy old objects */ 2023f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 2024f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 2025f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 2026a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 2027b371cd4fSStefano Zampini n_B = pcis->n_B; 2028b371cd4fSStefano Zampini n_D = pcis->n - n_B; 2029b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 20303a50541eSStefano Zampini 2031a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 20326816873aSStefano Zampini 203353892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 20346816873aSStefano Zampini if (!sub_schurs->reuse_mumps) { 2035854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 2036a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 2037a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 20380e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 2039a64d13efSStefano Zampini } 2040a64d13efSStefano Zampini 2041a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 20424641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 20436816873aSStefano Zampini idx_R_local[n_R++] = i; 2044a64d13efSStefano Zampini } 2045a64d13efSStefano Zampini } 204653892102SStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing MUMPS Schur solver */ 20476816873aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 20486816873aSStefano Zampini 204953892102SStefano Zampini ierr = ISGetIndices(reuse_mumps->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 205053892102SStefano Zampini ierr = ISGetLocalSize(reuse_mumps->is_R,&n_R);CHKERRQ(ierr); 20516816873aSStefano Zampini } 20523a50541eSStefano Zampini 20533a50541eSStefano Zampini /* Block code */ 20543a50541eSStefano Zampini vbs = 1; 20553a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 20563a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 20573a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 20583a50541eSStefano Zampini PetscInt *vary; 2059d3df7717SStefano Zampini if (!sub_schurs->reuse_mumps) { 2060785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 20613a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 2062d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 2063d3df7717SStefano Zampini /* it is ok to check this way since local_primal_ref_node are always sorted by local numbering and idx_R_local is obtained as a complement */ 20640e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 2065d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 20663a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 20673a50541eSStefano Zampini is_blocked = PETSC_FALSE; 20683a50541eSStefano Zampini break; 20693a50541eSStefano Zampini } 20703a50541eSStefano Zampini } 2071d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 2072d3df7717SStefano Zampini } else { 2073d3df7717SStefano Zampini /* Verify directly the R set */ 2074d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 2075d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 2076d3df7717SStefano Zampini for (j=1; j<bs; j++) { 2077d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 2078d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 2079d3df7717SStefano Zampini break; 2080d3df7717SStefano Zampini } 2081d3df7717SStefano Zampini } 2082d3df7717SStefano Zampini } 2083d3df7717SStefano Zampini } 20843a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 20853a50541eSStefano Zampini vbs = bs; 20863a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 20873a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 20883a50541eSStefano Zampini } 20893a50541eSStefano Zampini } 20903a50541eSStefano Zampini } 20913a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 209253892102SStefano Zampini if (sub_schurs->reuse_mumps) { 209353892102SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 209453892102SStefano Zampini 209553892102SStefano Zampini ierr = ISRestoreIndices(reuse_mumps->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 209653892102SStefano Zampini ierr = ISDestroy(&reuse_mumps->is_R);CHKERRQ(ierr); 209753892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 209853892102SStefano Zampini reuse_mumps->is_R = pcbddc->is_R_local; 209953892102SStefano Zampini } else { 21003a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 210153892102SStefano Zampini } 2102a64d13efSStefano Zampini 2103a64d13efSStefano Zampini /* print some info if requested */ 2104a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 2105a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2106a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 21070fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2108a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 2109a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 21104f1b2e48SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"r_size = %d, v_size = %d, constraints = %d, local_primal_size = %d\n",n_R,n_vertices,pcbddc->local_primal_size-n_vertices-pcbddc->benign_n,pcbddc->local_primal_size);CHKERRQ(ierr); 2111a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2112a64d13efSStefano Zampini } 2113a64d13efSStefano Zampini 2114a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 21156816873aSStefano Zampini if (!sub_schurs->reuse_mumps) { 21166816873aSStefano Zampini IS is_aux1,is_aux2; 21176816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 21186816873aSStefano Zampini 21193a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2120854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 2121854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 2122a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 21234641a718SStefano Zampini for (i=0; i<n_D; i++) { 21244641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 21254641a718SStefano Zampini } 2126a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2127a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 21284641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 21294641a718SStefano Zampini aux_array1[j++] = i; 2130a64d13efSStefano Zampini } 2131a64d13efSStefano Zampini } 2132a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2133a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2134a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 21354641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 21364641a718SStefano Zampini aux_array2[j++] = i; 2137a64d13efSStefano Zampini } 2138a64d13efSStefano Zampini } 2139a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2140a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 2141a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 2142a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2143a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 2144a64d13efSStefano Zampini 21458eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 2146785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 2147a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 21484641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 21494641a718SStefano Zampini aux_array1[j++] = i; 2150a64d13efSStefano Zampini } 2151a64d13efSStefano Zampini } 2152a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2153a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 2154a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2155a64d13efSStefano Zampini } 21564641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 21573a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2158d62866d3SStefano Zampini } else { 215953892102SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 21606816873aSStefano Zampini IS tis; 21616816873aSStefano Zampini PetscInt schur_size; 21626816873aSStefano Zampini 216353892102SStefano Zampini ierr = ISGetLocalSize(reuse_mumps->is_B,&schur_size);CHKERRQ(ierr); 21646816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 216553892102SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_mumps->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 21666816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 21676816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 21686816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 21696816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 21706816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 2171d62866d3SStefano Zampini } 2172d62866d3SStefano Zampini } 2173a64d13efSStefano Zampini PetscFunctionReturn(0); 2174a64d13efSStefano Zampini } 2175a64d13efSStefano Zampini 2176304d26faSStefano Zampini 2177304d26faSStefano Zampini #undef __FUNCT__ 2178304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 2179684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 2180304d26faSStefano Zampini { 2181304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2182304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 2183304d26faSStefano Zampini PC pc_temp; 2184304d26faSStefano Zampini Mat A_RR; 2185f4ddd8eeSStefano Zampini MatReuse reuse; 2186304d26faSStefano Zampini PetscScalar m_one = -1.0; 2187304d26faSStefano Zampini PetscReal value; 218804708bb6SStefano Zampini PetscInt n_D,n_R; 21899577ea80SStefano Zampini PetscBool use_exact,use_exact_reduced,issbaij; 2190304d26faSStefano Zampini PetscErrorCode ierr; 2191e604994aSStefano Zampini /* prefixes stuff */ 2192312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 2193e604994aSStefano Zampini size_t len; 2194304d26faSStefano Zampini 2195304d26faSStefano Zampini PetscFunctionBegin; 2196304d26faSStefano Zampini 2197e604994aSStefano Zampini /* compute prefixes */ 2198e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 2199e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 2200e604994aSStefano Zampini if (!pcbddc->current_level) { 2201e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2202e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2203e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2204e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2205e604994aSStefano Zampini } else { 2206e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 2207312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 2208e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 2209e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 2210312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 2211312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 221234d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 221334d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 2214e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2215e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2216e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 2217e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 2218e604994aSStefano Zampini } 2219e604994aSStefano Zampini 2220304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 2221684f6988SStefano Zampini if (dirichlet) { 2222d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 22233301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 22243301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 2225964fefecSStefano Zampini } 2226ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 2227964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 2228304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 2229304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 2230304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 2231304d26faSStefano Zampini /* default */ 2232304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 2233e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 22349577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 2235304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 22369577ea80SStefano Zampini if (issbaij) { 22379577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 22389577ea80SStefano Zampini } else { 2239304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 22409577ea80SStefano Zampini } 2241304d26faSStefano Zampini /* Allow user's customization */ 2242304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 2243304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 2244304d26faSStefano Zampini } 2245d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 2246d62866d3SStefano Zampini if (sub_schurs->reuse_mumps) { 2247d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2248d62866d3SStefano Zampini 2249d62866d3SStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_mumps->interior_solver);CHKERRQ(ierr); 2250d5574798SStefano Zampini } 2251304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 2252304d26faSStefano Zampini if (!n_D) { 2253304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 2254304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 2255304d26faSStefano Zampini } 2256304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 2257304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 2258304d26faSStefano Zampini /* set ksp_D into pcis data */ 2259304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 2260304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 2261304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 2262684f6988SStefano Zampini } 2263304d26faSStefano Zampini 2264304d26faSStefano Zampini /* NEUMANN PROBLEM */ 2265684f6988SStefano Zampini A_RR = 0; 2266684f6988SStefano Zampini if (neumann) { 2267d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 226804708bb6SStefano Zampini PetscInt ibs,mbs; 226904708bb6SStefano Zampini PetscBool issbaij; 227004708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 2271f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 22728ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 2273f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 2274f4ddd8eeSStefano Zampini PetscInt nn_R; 227581d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 2276f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 2277f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 2278f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 2279f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 2280f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2281f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2282f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 2283727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 2284f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2285f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2286f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 2287f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 2288f4ddd8eeSStefano Zampini } 2289f4ddd8eeSStefano Zampini } 2290f4ddd8eeSStefano Zampini /* last check */ 2291d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 2292f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2293f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2294f4ddd8eeSStefano Zampini } 2295f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 2296f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2297f4ddd8eeSStefano Zampini } 2298f4ddd8eeSStefano Zampini /* extract A_RR */ 2299af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 2300af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 230104708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 230204708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 230304708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 230404708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 230504708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 2306af732b37SStefano Zampini } else { 230704708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 23086816873aSStefano Zampini } 230904708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 231004708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 231104708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 231204708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 231304708bb6SStefano Zampini } else { 231404708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 231504708bb6SStefano Zampini } 231604708bb6SStefano Zampini } 231704708bb6SStefano Zampini if (!sub_schurs->reuse_mumps) { 2318f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 23193301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 23203301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 23216816873aSStefano Zampini } 23226816873aSStefano Zampini } else { 23236816873aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 23246816873aSStefano Zampini 23256816873aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 23266816873aSStefano Zampini ierr = PCGetOperators(reuse_mumps->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 23276816873aSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 2328af732b37SStefano Zampini } 2329f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 2330304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 2331304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 2332304d26faSStefano Zampini /* default */ 2333304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 2334e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 2335304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 23369577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 23379577ea80SStefano Zampini if (issbaij) { 23389577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 23399577ea80SStefano Zampini } else { 2340304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 23419577ea80SStefano Zampini } 2342304d26faSStefano Zampini /* Allow user's customization */ 2343304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 2344304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 2345304d26faSStefano Zampini } 2346d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 2347304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 2348304d26faSStefano Zampini if (!n_R) { 2349304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 2350304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 2351304d26faSStefano Zampini } 2352d62866d3SStefano Zampini /* Reuse MUMPS solver if it is present */ 2353d62866d3SStefano Zampini if (sub_schurs->reuse_mumps) { 2354d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2355d62866d3SStefano Zampini 2356d62866d3SStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_mumps->correction_solver);CHKERRQ(ierr); 2357d62866d3SStefano Zampini } 2358304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 2359304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 2360684f6988SStefano Zampini } 23616816873aSStefano Zampini /* free Neumann problem's matrix */ 23626816873aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2363304d26faSStefano Zampini 2364304d26faSStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 23650fccc4e9SStefano Zampini if (pcbddc->NullSpace || pcbddc->dbg_flag) { 2366684f6988SStefano Zampini if (pcbddc->dbg_flag) { 2367684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2368684f6988SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2369684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2370684f6988SStefano Zampini } 2371684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 23720fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 23730fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 23740fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 23750fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 23760fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 2377304d26faSStefano Zampini /* need to be adapted? */ 2378b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2379b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2380b8ffe317SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,use_exact_reduced);CHKERRQ(ierr); 2381304d26faSStefano Zampini /* print info */ 2382304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2383e604994aSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d infinity error for Dirichlet solve (%s) = % 1.14e \n",PetscGlobalRank,((PetscObject)(pcbddc->ksp_D))->prefix,value);CHKERRQ(ierr); 2384304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2385304d26faSStefano Zampini } 2386b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced && !pcbddc->switch_static) { 2387298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcis->is_I_local);CHKERRQ(ierr); 2388304d26faSStefano Zampini } 2389684f6988SStefano Zampini } 2390684f6988SStefano Zampini if (neumann) { /* Neumann */ 23916816873aSStefano Zampini ierr = KSPGetOperators(pcbddc->ksp_R,&A_RR,NULL);CHKERRQ(ierr); 23920fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 23930fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 23940fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 23950fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 23960fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 2397304d26faSStefano Zampini /* need to be adapted? */ 2398b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2399b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2400304d26faSStefano Zampini /* print info */ 2401304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2402e604994aSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d infinity error for Neumann solve (%s) = % 1.14e\n",PetscGlobalRank,((PetscObject)(pcbddc->ksp_R))->prefix,value);CHKERRQ(ierr); 2403304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2404304d26faSStefano Zampini } 2405b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced) { /* is it the right logic? */ 2406298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->is_R_local);CHKERRQ(ierr); 2407304d26faSStefano Zampini } 24080fccc4e9SStefano Zampini } 2409684f6988SStefano Zampini } 2410304d26faSStefano Zampini PetscFunctionReturn(0); 2411304d26faSStefano Zampini } 2412304d26faSStefano Zampini 2413304d26faSStefano Zampini #undef __FUNCT__ 2414ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 241580677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 2416674ae819SStefano Zampini { 2417674ae819SStefano Zampini PetscErrorCode ierr; 2418674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2419be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2420674ae819SStefano Zampini 2421674ae819SStefano Zampini PetscFunctionBegin; 2422be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 242380677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 242420c7b377SStefano Zampini } 242580677318SStefano Zampini if (!pcbddc->switch_static) { 242680677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 242780677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 242880677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 242920c7b377SStefano Zampini } 2430be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 243180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 243280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 243320c7b377SStefano Zampini } else { 2434be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2435be83ff47SStefano Zampini 243653892102SStefano Zampini ierr = VecScatterBegin(reuse_mumps->correction_scatter_B,inout_B,reuse_mumps->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 243753892102SStefano Zampini ierr = VecScatterEnd(reuse_mumps->correction_scatter_B,inout_B,reuse_mumps->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 243820c7b377SStefano Zampini } 2439be83ff47SStefano Zampini } else { 244080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 244180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 244280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 244380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 244480677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 244580677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 244680677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 244780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 244880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2449674ae819SStefano Zampini } 2450674ae819SStefano Zampini } 2451be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 245280677318SStefano Zampini if (applytranspose) { 245380677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 245480677318SStefano Zampini } else { 245580677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 245680677318SStefano Zampini } 245753892102SStefano Zampini #if defined(PETSC_HAVE_MUMPS) 2458be83ff47SStefano Zampini } else { 2459be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2460be83ff47SStefano Zampini 2461be83ff47SStefano Zampini if (applytranspose) { 246253892102SStefano Zampini ierr = MatMumpsSolveSchurComplementTranspose(reuse_mumps->F,reuse_mumps->rhs_B,reuse_mumps->sol_B);CHKERRQ(ierr); 2463be83ff47SStefano Zampini } else { 246453892102SStefano Zampini ierr = MatMumpsSolveSchurComplement(reuse_mumps->F,reuse_mumps->rhs_B,reuse_mumps->sol_B);CHKERRQ(ierr); 2465be83ff47SStefano Zampini } 246653892102SStefano Zampini #endif 2467be83ff47SStefano Zampini } 246880677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 246980677318SStefano Zampini if (!pcbddc->switch_static) { 2470be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 247180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 247280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2473be83ff47SStefano Zampini } else { 2474be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2475be83ff47SStefano Zampini 247653892102SStefano Zampini ierr = VecScatterBegin(reuse_mumps->correction_scatter_B,reuse_mumps->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 247753892102SStefano Zampini ierr = VecScatterEnd(reuse_mumps->correction_scatter_B,reuse_mumps->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2478be83ff47SStefano Zampini } 247980677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 248080677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 248180677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 248280677318SStefano Zampini } 248380677318SStefano Zampini } else { 248480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 248580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 248680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 248780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 248880677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 248980677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 249080677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 249180677318SStefano Zampini } 249280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 249580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2496674ae819SStefano Zampini } 2497674ae819SStefano Zampini PetscFunctionReturn(0); 2498674ae819SStefano Zampini } 2499674ae819SStefano Zampini 2500dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 2501674ae819SStefano Zampini #undef __FUNCT__ 2502674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 2503dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 2504674ae819SStefano Zampini { 2505674ae819SStefano Zampini PetscErrorCode ierr; 2506674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2507674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 2508674ae819SStefano Zampini const PetscScalar zero = 0.0; 2509674ae819SStefano Zampini 2510674ae819SStefano Zampini PetscFunctionBegin; 2511dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 2512dc359a40SStefano Zampini if (applytranspose) { 2513674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 25148eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 2515dc359a40SStefano Zampini } else { 2516674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 2517674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 251815aaf578SStefano Zampini } 2519efc2fbd9SStefano Zampini 2520efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 25214f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2522efc2fbd9SStefano Zampini PetscScalar *array; 25234f1b2e48SStefano Zampini PetscInt j; 2524efc2fbd9SStefano Zampini 2525efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 25264f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 2527efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2528efc2fbd9SStefano Zampini } 2529efc2fbd9SStefano Zampini 253012edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 253112edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 253212edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 253312edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 253412edc857SStefano Zampini 25359f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 253612edc857SStefano Zampini /* TODO remove null space when doing multilevel */ 253712edc857SStefano Zampini if (pcbddc->coarse_ksp) { 253851694757SStefano Zampini Mat coarse_mat; 2539964fefecSStefano Zampini Vec rhs,sol; 254051694757SStefano Zampini MatNullSpace nullsp; 2541964fefecSStefano Zampini 2542964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 2543964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 254451694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 254551694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 254651694757SStefano Zampini if (nullsp) { 254751694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 254851694757SStefano Zampini } 254912edc857SStefano Zampini if (applytranspose) { 2550964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 255112edc857SStefano Zampini } else { 2552964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 255312edc857SStefano Zampini } 255451694757SStefano Zampini if (nullsp) { 255551694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 255651694757SStefano Zampini } 255712edc857SStefano Zampini } 2558674ae819SStefano Zampini 2559674ae819SStefano Zampini /* Local solution on R nodes */ 256080677318SStefano Zampini if (pcis->n) { /* in/out pcbddc->vec1_B,pcbddc->vec1_D */ 256180677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 25629f00e9b4SStefano Zampini } 2563674ae819SStefano Zampini 25649f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 25659f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 256612edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2567674ae819SStefano Zampini 2568674ae819SStefano Zampini /* Sum contributions from two levels */ 2569dc359a40SStefano Zampini if (applytranspose) { 2570dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2571dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2572dc359a40SStefano Zampini } else { 2573674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 25748eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2575dc359a40SStefano Zampini } 2576efc2fbd9SStefano Zampini /* store p0 */ 25774f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2578efc2fbd9SStefano Zampini PetscScalar *array; 25794f1b2e48SStefano Zampini PetscInt j; 2580efc2fbd9SStefano Zampini 2581efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 25824f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 2583efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2584efc2fbd9SStefano Zampini } 2585674ae819SStefano Zampini PetscFunctionReturn(0); 2586674ae819SStefano Zampini } 2587674ae819SStefano Zampini 2588674ae819SStefano Zampini #undef __FUNCT__ 2589674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 259012edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 2591674ae819SStefano Zampini { 2592674ae819SStefano Zampini PetscErrorCode ierr; 2593674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 259458da7f69SStefano Zampini PetscScalar *array; 259512edc857SStefano Zampini Vec from,to; 2596674ae819SStefano Zampini 2597674ae819SStefano Zampini PetscFunctionBegin; 259812edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 259912edc857SStefano Zampini from = pcbddc->coarse_vec; 260012edc857SStefano Zampini to = pcbddc->vec1_P; 260112edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 260212edc857SStefano Zampini Vec tvec; 260358da7f69SStefano Zampini 260458da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 260558da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 260612edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 260758da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 260858da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 260958da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 261012edc857SStefano Zampini } 261112edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 261212edc857SStefano Zampini from = pcbddc->vec1_P; 261312edc857SStefano Zampini to = pcbddc->coarse_vec; 261412edc857SStefano Zampini } 261512edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 2616674ae819SStefano Zampini PetscFunctionReturn(0); 2617674ae819SStefano Zampini } 2618674ae819SStefano Zampini 2619674ae819SStefano Zampini #undef __FUNCT__ 2620674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 262112edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 2622674ae819SStefano Zampini { 2623674ae819SStefano Zampini PetscErrorCode ierr; 2624674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 262558da7f69SStefano Zampini PetscScalar *array; 262612edc857SStefano Zampini Vec from,to; 2627674ae819SStefano Zampini 2628674ae819SStefano Zampini PetscFunctionBegin; 262912edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 263012edc857SStefano Zampini from = pcbddc->coarse_vec; 263112edc857SStefano Zampini to = pcbddc->vec1_P; 263212edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 263312edc857SStefano Zampini from = pcbddc->vec1_P; 263412edc857SStefano Zampini to = pcbddc->coarse_vec; 263512edc857SStefano Zampini } 263612edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 263712edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 263812edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 263912edc857SStefano Zampini Vec tvec; 264058da7f69SStefano Zampini 264112edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 264258da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 264358da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 264458da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 264558da7f69SStefano Zampini } 264658da7f69SStefano Zampini } else { 264758da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 264858da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 264912edc857SStefano Zampini } 265012edc857SStefano Zampini } 2651674ae819SStefano Zampini PetscFunctionReturn(0); 2652674ae819SStefano Zampini } 2653674ae819SStefano Zampini 2654984c4197SStefano Zampini /* uncomment for testing purposes */ 2655984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 2656674ae819SStefano Zampini #undef __FUNCT__ 2657674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 2658674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 2659674ae819SStefano Zampini { 2660674ae819SStefano Zampini PetscErrorCode ierr; 2661674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2662674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2663674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 2664984c4197SStefano Zampini /* one and zero */ 2665984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 2666984c4197SStefano Zampini /* space to store constraints and their local indices */ 26679162d606SStefano Zampini PetscScalar *constraints_data; 26689162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 26699162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 26709162d606SStefano Zampini PetscInt *constraints_n; 2671984c4197SStefano Zampini /* iterators */ 2672b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 2673984c4197SStefano Zampini /* BLAS integers */ 2674e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 2675e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 2676c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 2677727cdba6SStefano Zampini /* reuse */ 26780e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 26790e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 2680984c4197SStefano Zampini /* change of basis */ 2681b3d85658SStefano Zampini PetscBool qr_needed; 26829162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 2683984c4197SStefano Zampini /* auxiliary stuff */ 268464efe560SStefano Zampini PetscInt *nnz,*is_indices; 26858a0068c3SStefano Zampini PetscInt ncc; 2686984c4197SStefano Zampini /* some quantities */ 268745a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 2688a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 2689984c4197SStefano Zampini 2690674ae819SStefano Zampini PetscFunctionBegin; 26918e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 26928e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 26938e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 2694088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 2695088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 26960e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 26970e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 26980e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 26990e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 27000e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 2701088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2702cf5a6209SStefano Zampini 2703cf5a6209SStefano Zampini /* print some info */ 2704cf5a6209SStefano Zampini if (pcbddc->dbg_flag) { 2705cf5a6209SStefano Zampini IS vertices; 2706cf5a6209SStefano Zampini PetscInt nv,nedges,nfaces; 2707cf5a6209SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 2708cf5a6209SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 2709cf5a6209SStefano Zampini ierr = ISDestroy(&vertices);CHKERRQ(ierr); 2710cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2711cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2712cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 2713fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 2714fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 2715cf5a6209SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2716cf5a6209SStefano Zampini } 2717cf5a6209SStefano Zampini 2718cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 27199162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 2720cf5a6209SStefano Zampini MatNullSpace nearnullsp; 2721cf5a6209SStefano Zampini const Vec *nearnullvecs; 2722cf5a6209SStefano Zampini Vec *localnearnullsp; 2723cf5a6209SStefano Zampini PetscScalar *array; 2724cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 2725cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 2726674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 2727b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 2728674ae819SStefano Zampini PetscScalar *work; 2729674ae819SStefano Zampini PetscReal *singular_vals; 2730674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2731674ae819SStefano Zampini PetscReal *rwork; 2732674ae819SStefano Zampini #endif 2733674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2734674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 2735674ae819SStefano Zampini #else 2736964fefecSStefano Zampini PetscBLASInt dummy_int=1; 2737964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 2738674ae819SStefano Zampini #endif 2739674ae819SStefano Zampini 2740674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 2741d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 2742d06fc5fdSStefano Zampini /* free unneeded index sets */ 2743d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 2744d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 2745674ae819SStefano Zampini } 2746d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 2747d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 2748d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 2749d06fc5fdSStefano Zampini } 2750d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 2751d06fc5fdSStefano Zampini n_ISForEdges = 0; 2752d06fc5fdSStefano Zampini } 2753d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 2754d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 2755d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 2756d06fc5fdSStefano Zampini } 2757d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 2758d06fc5fdSStefano Zampini n_ISForFaces = 0; 2759d06fc5fdSStefano Zampini } 276070022509SStefano Zampini 276170022509SStefano Zampini #if defined(PETSC_USE_DEBUG) 276270022509SStefano Zampini /* HACK: when solving singular problems not using vertices, a change of basis is mandatory. 276370022509SStefano Zampini Also use_change_of_basis should be consistent among processors */ 276470022509SStefano Zampini if (pcbddc->NullSpace) { 276570022509SStefano Zampini PetscBool tbool[2],gbool[2]; 276670022509SStefano Zampini 276770022509SStefano Zampini if (!ISForVertices && !pcbddc->user_ChangeOfBasisMatrix) { 2768b8ffe317SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 2769d06fc5fdSStefano Zampini if (!ISForEdges) { 2770d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = PETSC_TRUE; 2771d06fc5fdSStefano Zampini } 2772b8ffe317SStefano Zampini } 2773d06fc5fdSStefano Zampini tbool[0] = pcbddc->use_change_of_basis; 2774d06fc5fdSStefano Zampini tbool[1] = pcbddc->use_change_on_faces; 2775d06fc5fdSStefano Zampini ierr = MPI_Allreduce(tbool,gbool,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2776d06fc5fdSStefano Zampini pcbddc->use_change_of_basis = gbool[0]; 2777d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = gbool[1]; 277898a51de6SStefano Zampini } 277970022509SStefano Zampini #endif 278008122e43SStefano Zampini 2781674ae819SStefano Zampini /* check if near null space is attached to global mat */ 2782674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 2783674ae819SStefano Zampini if (nearnullsp) { 2784674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 2785f4ddd8eeSStefano Zampini /* remove any stored info */ 2786f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 2787f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2788f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 2789f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 2790f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 2791473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2792f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 2793f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 2794f4ddd8eeSStefano Zampini } 2795984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 2796984c4197SStefano Zampini nnsp_size = 0; 2797674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 2798674ae819SStefano Zampini } 2799984c4197SStefano Zampini /* get max number of constraints on a single cc */ 2800984c4197SStefano Zampini max_constraints = nnsp_size; 2801984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 2802984c4197SStefano Zampini 2803674ae819SStefano Zampini /* 2804674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 28059162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 28069162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 28079162d606SStefano Zampini There can be multiple constraints per connected component 2808674ae819SStefano Zampini */ 2809674ae819SStefano Zampini n_vertices = 0; 2810674ae819SStefano Zampini if (ISForVertices) { 2811674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 2812674ae819SStefano Zampini } 28139162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 28149162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 28159162d606SStefano Zampini 28169162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 28179162d606SStefano Zampini total_counts *= max_constraints; 2818674ae819SStefano Zampini total_counts += n_vertices; 28194641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 28209162d606SStefano Zampini 2821674ae819SStefano Zampini total_counts = 0; 2822674ae819SStefano Zampini max_size_of_constraint = 0; 2823674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 28249162d606SStefano Zampini IS used_is; 2825674ae819SStefano Zampini if (i<n_ISForEdges) { 28269162d606SStefano Zampini used_is = ISForEdges[i]; 2827674ae819SStefano Zampini } else { 28289162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 2829674ae819SStefano Zampini } 28309162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 2831674ae819SStefano Zampini total_counts += j; 2832674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 2833674ae819SStefano Zampini } 28349162d606SStefano Zampini ierr = PetscMalloc3(total_counts*max_constraints+n_vertices,&constraints_data,total_counts+n_vertices,&constraints_idxs,total_counts+n_vertices,&constraints_idxs_B);CHKERRQ(ierr); 28359162d606SStefano Zampini 2836984c4197SStefano Zampini /* get local part of global near null space vectors */ 2837785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 2838984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 2839984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 2840e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2841e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2842984c4197SStefano Zampini } 2843674ae819SStefano Zampini 2844242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 2845242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 2846a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 2847242a89d7SStefano Zampini 2848984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 2849a773dcb8SStefano Zampini if (!skip_lapack) { 2850674ae819SStefano Zampini PetscScalar temp_work; 2851911cabfeSStefano Zampini 2852674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2853984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 2854785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 2855785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 2856785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 2857674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2858785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 2859674ae819SStefano Zampini #endif 2860674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2861c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 2862c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 2863674ae819SStefano Zampini lwork = -1; 2864674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2865674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2866c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 2867674ae819SStefano Zampini #else 2868c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 2869674ae819SStefano Zampini #endif 2870674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2871984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 2872674ae819SStefano Zampini #else /* on missing GESVD */ 2873674ae819SStefano Zampini /* SVD */ 2874674ae819SStefano Zampini PetscInt max_n,min_n; 2875674ae819SStefano Zampini max_n = max_size_of_constraint; 2876984c4197SStefano Zampini min_n = max_constraints; 2877984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 2878674ae819SStefano Zampini min_n = max_size_of_constraint; 2879984c4197SStefano Zampini max_n = max_constraints; 2880674ae819SStefano Zampini } 2881785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 2882674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2883785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 2884674ae819SStefano Zampini #endif 2885674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2886674ae819SStefano Zampini lwork = -1; 2887e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 2888e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 2889b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 2890674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2891674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 28929162d606SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,&constraints_data[0],&Blas_LDA,singular_vals,&dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,&lierr)); 2893674ae819SStefano Zampini #else 28949162d606SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,&constraints_data[0],&Blas_LDA,singular_vals,&dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,rwork,&lierr)); 2895674ae819SStefano Zampini #endif 2896674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2897984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 2898984c4197SStefano Zampini #endif /* on missing GESVD */ 2899674ae819SStefano Zampini /* Allocate optimal workspace */ 2900674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 2901854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 2902674ae819SStefano Zampini } 2903674ae819SStefano Zampini /* Now we can loop on constraining sets */ 2904674ae819SStefano Zampini total_counts = 0; 29059162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 29069162d606SStefano Zampini constraints_data_ptr[0] = 0; 2907674ae819SStefano Zampini /* vertices */ 29089162d606SStefano Zampini if (n_vertices) { 2909674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 29109162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 2911674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 29129162d606SStefano Zampini constraints_n[total_counts] = 1; 29139162d606SStefano Zampini constraints_data[total_counts] = 1.0; 29149162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 29159162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 2916674ae819SStefano Zampini total_counts++; 2917674ae819SStefano Zampini } 2918674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2919674ae819SStefano Zampini n_vertices = total_counts; 2920674ae819SStefano Zampini } 2921984c4197SStefano Zampini 2922674ae819SStefano Zampini /* edges and faces */ 29239162d606SStefano Zampini total_counts_cc = total_counts; 2924911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 29259162d606SStefano Zampini IS used_is; 29269162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 29279162d606SStefano Zampini 2928911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 29299162d606SStefano Zampini used_is = ISForEdges[ncc]; 2930984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 2931674ae819SStefano Zampini } else { 29329162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 2933984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 2934674ae819SStefano Zampini } 2935674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 29369162d606SStefano Zampini 29379162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 29389162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2939984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 2940984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 2941674ae819SStefano Zampini if (nnsp_has_cnst) { 29425b08dc53SStefano Zampini PetscScalar quad_value; 29439162d606SStefano Zampini 29449162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 29459162d606SStefano Zampini idxs_copied = PETSC_TRUE; 29469162d606SStefano Zampini 2947a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 2948674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 2949a773dcb8SStefano Zampini } else { 2950a773dcb8SStefano Zampini quad_value = 1.0; 2951a773dcb8SStefano Zampini } 2952674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 29539162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 2954674ae819SStefano Zampini } 29559162d606SStefano Zampini temp_constraints++; 2956674ae819SStefano Zampini total_counts++; 2957674ae819SStefano Zampini } 2958674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 2959984c4197SStefano Zampini PetscReal real_value; 29609162d606SStefano Zampini PetscScalar *ptr_to_data; 29619162d606SStefano Zampini 2962984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 29639162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 2964674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 29659162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 2966674ae819SStefano Zampini } 2967984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 2968984c4197SStefano Zampini /* check if array is null on the connected component */ 2969e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 29709162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 29715b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 2972674ae819SStefano Zampini temp_constraints++; 2973674ae819SStefano Zampini total_counts++; 29749162d606SStefano Zampini if (!idxs_copied) { 29759162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 29769162d606SStefano Zampini idxs_copied = PETSC_TRUE; 2977674ae819SStefano Zampini } 2978674ae819SStefano Zampini } 29799162d606SStefano Zampini } 29809162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 298145a1bb75SStefano Zampini valid_constraints = temp_constraints; 2982eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 2983a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 29849162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 29859162d606SStefano Zampini 29869162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 2987a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 29889162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 2989a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 29909162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 2991a773dcb8SStefano Zampini } else { /* perform SVD */ 2992984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 29939162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 2994674ae819SStefano Zampini 2995674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2996984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 2997984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 2998984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 2999984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 3000984c4197SStefano Zampini from that computed using LAPACKgesvd 3001984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 3002984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 3003984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 3004674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 3005e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3006984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3007674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 3008674ae819SStefano Zampini for (k=0;k<j+1;k++) { 30099162d606SStefano Zampini PetscStackCallBLAS("BLASdot",correlation_mat[j*temp_constraints+k] = BLASdot_(&Blas_N,ptr_to_data+k*size_of_constraint,&Blas_one,ptr_to_data+j*size_of_constraint,&Blas_one)); 3010674ae819SStefano Zampini } 3011674ae819SStefano Zampini } 3012e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 3013e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3014e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 3015674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3016c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 3017674ae819SStefano Zampini #else 3018c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 3019674ae819SStefano Zampini #endif 3020674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3021984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 3022984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 3023674ae819SStefano Zampini j = 0; 3024984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 3025674ae819SStefano Zampini total_counts = total_counts-j; 302645a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 3027e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 3028c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3029c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3030c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 3031c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3032c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 3033c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3034674ae819SStefano Zampini if (j<temp_constraints) { 3035984c4197SStefano Zampini PetscInt ii; 3036984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 3037674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 30389162d606SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&Blas_M,&Blas_N,&Blas_K,&one,ptr_to_data,&Blas_LDA,correlation_mat,&Blas_LDB,&zero,temp_basis,&Blas_LDC)); 3039674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3040984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 3041674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 30429162d606SStefano Zampini ptr_to_data[k*size_of_constraint+ii] = singular_vals[temp_constraints-1-k]*temp_basis[(temp_constraints-1-k)*size_of_constraint+ii]; 3043674ae819SStefano Zampini } 3044674ae819SStefano Zampini } 3045674ae819SStefano Zampini } 3046674ae819SStefano Zampini #else /* on missing GESVD */ 3047e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3048e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3049b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3050674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3051674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 30529162d606SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,ptr_to_data,&Blas_LDA,singular_vals,&dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,&lierr)); 3053674ae819SStefano Zampini #else 30549162d606SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,ptr_to_data,&Blas_LDA,singular_vals,&dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,rwork,&lierr)); 3055674ae819SStefano Zampini #endif 3056984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 3057674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3058984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 3059e310c8b4SStefano Zampini k = temp_constraints; 3060e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 3061674ae819SStefano Zampini j = 0; 3062e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 306345a1bb75SStefano Zampini valid_constraints = k-j; 3064911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 3065984c4197SStefano Zampini #endif /* on missing GESVD */ 3066674ae819SStefano Zampini } 3067a773dcb8SStefano Zampini } 30689162d606SStefano Zampini /* update pointers information */ 30699162d606SStefano Zampini if (valid_constraints) { 30709162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 30719162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 30729162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 30739162d606SStefano Zampini /* set change_of_basis flag */ 307445a1bb75SStefano Zampini if (boolforchange) { 3075b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 30769162d606SStefano Zampini } 3077b3d85658SStefano Zampini total_counts_cc++; 307845a1bb75SStefano Zampini } 307945a1bb75SStefano Zampini } 3080984c4197SStefano Zampini /* free workspace */ 30818f1c130eSStefano Zampini if (!skip_lapack) { 3082984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 3083984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3084984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 3085984c4197SStefano Zampini #endif 3086984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 3087984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3088984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 3089984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 3090984c4197SStefano Zampini #endif 3091984c4197SStefano Zampini } 3092984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3093984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 3094984c4197SStefano Zampini } 3095984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 3096cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 3097cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3098cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3099cf5a6209SStefano Zampini } 3100cf5a6209SStefano Zampini if (n_ISForFaces) { 3101cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3102cf5a6209SStefano Zampini } 3103cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3104cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3105cf5a6209SStefano Zampini } 3106cf5a6209SStefano Zampini if (n_ISForEdges) { 3107cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3108cf5a6209SStefano Zampini } 3109cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 311008122e43SStefano Zampini } else { 311108122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3112984c4197SStefano Zampini 311308122e43SStefano Zampini total_counts = 0; 311408122e43SStefano Zampini n_vertices = 0; 3115d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 3116d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 311708122e43SStefano Zampini } 311808122e43SStefano Zampini max_constraints = 0; 31199162d606SStefano Zampini total_counts_cc = 0; 312008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 312108122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 31229162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 312308122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 312408122e43SStefano Zampini } 31259162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 31269162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 31279162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 31289162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 312974d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 31309162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 31319162d606SStefano Zampini total_counts_cc = 0; 31329162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 31339162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 31349162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 313508122e43SStefano Zampini } 313608122e43SStefano Zampini } 31379162d606SStefano Zampini #if 0 31389162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 31399162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 31409162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 31419162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 31429162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 31439162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 31449162d606SStefano Zampini } 31459162d606SStefano Zampini printf("\n"); 31469162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 31479162d606SStefano Zampini } 31481b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 31498bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 31501b968477SStefano Zampini } 31511b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 31528bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] sub %d, edge %d, n %d\n",PetscGlobalRank,i,(PetscBool)PetscBTLookup(sub_schurs->is_edge,i),pcbddc->adaptive_constraints_n[i+n_vertices]); 31531b968477SStefano Zampini } 315408122e43SStefano Zampini #endif 315508122e43SStefano Zampini 31568bec7fa6SStefano Zampini max_size_of_constraint = 0; 31579162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) max_size_of_constraint = PetscMax(max_size_of_constraint,constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]); 31589162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 315908122e43SStefano Zampini /* Change of basis */ 3160b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 316108122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 316208122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 316308122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 3164b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 316508122e43SStefano Zampini } 316608122e43SStefano Zampini } 316708122e43SStefano Zampini } 316808122e43SStefano Zampini } 3169984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 31704f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 317108122e43SStefano Zampini 31729162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 31739162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 31749162d606SStefano Zampini if (i != constraints_idxs_ptr[total_counts_cc]) { 31759162d606SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for constraints indices %d != %d\n",constraints_idxs_ptr[total_counts_cc],i); 317608122e43SStefano Zampini } 3177674ae819SStefano Zampini 3178674ae819SStefano Zampini /* Create constraint matrix */ 3179674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 318016f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 3181984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 3182984c4197SStefano Zampini 3183984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 3184a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 3185a717540cSStefano Zampini qr_needed = PETSC_FALSE; 318674d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 3187984c4197SStefano Zampini total_primal_vertices=0; 3188b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 31899162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 31909162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 3191984c4197SStefano Zampini if (size_of_constraint == 1) { 31929162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 3193b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 319464efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 31959162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 31969162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 3197a717540cSStefano Zampini } 3198b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 319974d5cdf7SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single || pcbddc->faster_deluxe) { 3200a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 3201a717540cSStefano Zampini qr_needed = PETSC_TRUE; 3202a717540cSStefano Zampini } 3203fa434743SStefano Zampini } else { 3204b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 3205fa434743SStefano Zampini } 3206a717540cSStefano Zampini } 3207b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 3208b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 3209674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 321070022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 3211b3d85658SStefano Zampini 32124f1b2e48SStefano Zampini ierr = PetscMalloc2(pcbddc->local_primal_size_cc+pcbddc->benign_n,&pcbddc->local_primal_ref_node,pcbddc->local_primal_size_cc+pcbddc->benign_n,&pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 32130e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 32140e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 3215984c4197SStefano Zampini 3216984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 321774d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 3218785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 3219984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 322074d5cdf7SStefano Zampini 3221984c4197SStefano Zampini j = total_primal_vertices; 322274d5cdf7SStefano Zampini total_counts = total_primal_vertices; 3223b3d85658SStefano Zampini cum = total_primal_vertices; 32249162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 32254641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 3226b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 3227b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 3228b3d85658SStefano Zampini cum++; 32299162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 323074d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 323174d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 323274d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 323374d5cdf7SStefano Zampini } 32349162d606SStefano Zampini j += constraints_n[i]; 3235674ae819SStefano Zampini } 3236674ae819SStefano Zampini } 3237674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 3238674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3239088faed8SStefano Zampini 3240674ae819SStefano Zampini /* set values in constraint matrix */ 3241984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 32420e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 3243674ae819SStefano Zampini } 3244984c4197SStefano Zampini total_counts = total_primal_vertices; 32459162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 32464641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 32479162d606SStefano Zampini PetscInt *cols; 32489162d606SStefano Zampini 32499162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 32509162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 32519162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 32529162d606SStefano Zampini PetscInt row = total_counts+k; 32539162d606SStefano Zampini PetscScalar *vals; 32549162d606SStefano Zampini 32559162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 32569162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 32579162d606SStefano Zampini } 32589162d606SStefano Zampini total_counts += constraints_n[i]; 3259674ae819SStefano Zampini } 3260674ae819SStefano Zampini } 3261674ae819SStefano Zampini /* assembling */ 3262674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3263674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3264088faed8SStefano Zampini 3265984c4197SStefano Zampini /* 326645a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3267984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 3268984c4197SStefano Zampini */ 3269674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 3270674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 3271026de310SStefano Zampini /* dual and primal dofs on a single cc */ 3272984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 3273984c4197SStefano Zampini /* working stuff for GEQRF */ 327481d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 3275984c4197SStefano Zampini PetscBLASInt lqr_work; 3276984c4197SStefano Zampini /* working stuff for UNGQR */ 3277984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 3278984c4197SStefano Zampini PetscBLASInt lgqr_work; 3279984c4197SStefano Zampini /* working stuff for TRTRS */ 3280984c4197SStefano Zampini PetscScalar *trs_rhs; 32813f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 3282984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 3283984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 3284984c4197SStefano Zampini PetscScalar *start_vals; 3285984c4197SStefano Zampini /* working stuff for values insertion */ 32864641a718SStefano Zampini PetscBT is_primal; 328764efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 3288906d46d4SStefano Zampini /* matrix sizes */ 3289906d46d4SStefano Zampini PetscInt global_size,local_size; 3290906d46d4SStefano Zampini /* temporary change of basis */ 3291906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 3292cf5a6209SStefano Zampini /* extra space for debugging */ 3293cf5a6209SStefano Zampini PetscScalar *dbg_work; 3294984c4197SStefano Zampini 3295906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 3296906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 329716f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 3298bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 3299906d46d4SStefano Zampini /* nonzeros for local mat */ 3300bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 3301bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 33029162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 3303a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 33049162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 3305a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 33069162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 3307a717540cSStefano Zampini } else { 33089162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 33099162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 3310a717540cSStefano Zampini } 3311a717540cSStefano Zampini } 3312a717540cSStefano Zampini } 3313906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 3314bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3315a717540cSStefano Zampini /* Set initial identity in the matrix */ 3316bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 3317906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 3318a717540cSStefano Zampini } 3319a717540cSStefano Zampini 3320a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3321a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3322a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 3323a717540cSStefano Zampini } 3324a717540cSStefano Zampini 3325a717540cSStefano Zampini 3326a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 3327a717540cSStefano Zampini /* 3328a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 3329a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 3330a717540cSStefano Zampini 3331a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 3332a717540cSStefano Zampini 3333a6b551f4SStefano Zampini - Using the following block transformation if there is only a primal dof on the cc (and -pc_bddc_use_qr_single is not specified) 3334a6b551f4SStefano Zampini 3335a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 3336a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 3337a717540cSStefano Zampini | ... | 3338a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 3339a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 3340a717540cSStefano Zampini 3341a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 3342a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 3343a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 3344a6b551f4SStefano Zampini 3345a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 3346a717540cSStefano Zampini */ 3347a717540cSStefano Zampini if (qr_needed) { 3348984c4197SStefano Zampini /* space to store Q */ 3349854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 3350984c4197SStefano Zampini /* first we issue queries for optimal work */ 33513f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 33523f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 33533f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3354984c4197SStefano Zampini lqr_work = -1; 33553f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 3356984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 3357984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 3358785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 3359984c4197SStefano Zampini lgqr_work = -1; 33603f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 33613f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 33623f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 33633f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 33643f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 33653f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 3366984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 3367984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 3368785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 3369984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 3370785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 3371984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 3372785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 3373a717540cSStefano Zampini /* allocating workspace for check */ 3374a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3375cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 3376a717540cSStefano Zampini } 3377a717540cSStefano Zampini } 3378984c4197SStefano Zampini /* array to store whether a node is primal or not */ 33794641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 3380473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 33810e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 338239e2fb2aSStefano Zampini if (i != total_primal_vertices) { 338339e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",total_primal_vertices,i); 33844641a718SStefano Zampini } 338539e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 338639e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 338739e2fb2aSStefano Zampini } 338839e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 3389984c4197SStefano Zampini 3390a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 33919162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 33929162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 33934641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 3394984c4197SStefano Zampini /* get constraint info */ 33959162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 3396984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 3397984c4197SStefano Zampini 3398984c4197SStefano Zampini if (pcbddc->dbg_flag) { 33999162d606SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Constraints %d: %d need a change of basis (size %d)\n",total_counts,primal_dofs,size_of_constraint);CHKERRQ(ierr); 3400674ae819SStefano Zampini } 3401984c4197SStefano Zampini 3402fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 3403a717540cSStefano Zampini 3404a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 3405a717540cSStefano Zampini if (pcbddc->dbg_flag) { 34069162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3407a717540cSStefano Zampini } 3408984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 34099162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3410984c4197SStefano Zampini 3411984c4197SStefano Zampini /* compute QR decomposition of constraints */ 34123f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 34133f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 34143f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3415674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 34163f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 3417984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 3418674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3419984c4197SStefano Zampini 3420984c4197SStefano Zampini /* explictly compute R^-T */ 3421984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 3422984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 34233f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 34243f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 34253f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 34263f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 3427984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 34283f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 3429984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 3430984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3431984c4197SStefano Zampini 3432a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 34333f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 34343f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 34353f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 34363f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3437984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 34383f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 3439984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 3440984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3441984c4197SStefano Zampini 3442984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 3443984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 3444984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 34453f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 34463f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 34473f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 34483f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 34493f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 34503f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3451984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 34529162d606SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&Blas_M,&Blas_N,&Blas_K,&one,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&zero,constraints_data+constraints_data_ptr[total_counts],&Blas_LDC)); 3453984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 34549162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3455984c4197SStefano Zampini 3456984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 34579162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 3458984c4197SStefano Zampini /* insert cols for primal dofs */ 3459984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 3460984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 34619162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3462906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3463984c4197SStefano Zampini } 3464984c4197SStefano Zampini /* insert cols for dual dofs */ 3465984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 34669162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 3467984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 34689162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3469906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3470984c4197SStefano Zampini j++; 3471674ae819SStefano Zampini } 3472674ae819SStefano Zampini } 3473984c4197SStefano Zampini 3474984c4197SStefano Zampini /* check change of basis */ 3475984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3476984c4197SStefano Zampini PetscInt ii,jj; 3477984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 3478c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 3479c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3480c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 3481c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3482c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 3483c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 3484984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3485cf5a6209SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&Blas_M,&Blas_N,&Blas_K,&one,dbg_work,&Blas_LDA,qr_basis,&Blas_LDB,&zero,&dbg_work[size_of_constraint*primal_dofs],&Blas_LDC)); 3486984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3487984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3488984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3489cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 3490cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) valid_qr = PETSC_FALSE; 3491674ae819SStefano Zampini } 3492674ae819SStefano Zampini } 3493984c4197SStefano Zampini if (!valid_qr) { 349422d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 3495984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3496984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3497cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 3498cf5a6209SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\tQr basis function %d is not orthogonal to constraint %d (%1.14e)!\n",jj,ii,PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii])); 3499674ae819SStefano Zampini } 3500cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 3501cf5a6209SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\tQr basis function %d is not unitary w.r.t constraint %d (%1.14e)!\n",jj,ii,PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii])); 3502984c4197SStefano Zampini } 3503984c4197SStefano Zampini } 3504984c4197SStefano Zampini } 3505674ae819SStefano Zampini } else { 350622d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 3507674ae819SStefano Zampini } 3508674ae819SStefano Zampini } 3509a717540cSStefano Zampini } else { /* simple transformation block */ 3510a717540cSStefano Zampini PetscInt row,col; 3511a6b551f4SStefano Zampini PetscScalar val,norm; 3512a6b551f4SStefano Zampini 3513a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 35149162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,constraints_data+constraints_data_ptr[total_counts],&Blas_one,constraints_data+constraints_data_ptr[total_counts],&Blas_one)); 3515a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 35169162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 35179162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3518bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 35199162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 3520906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 35219162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 3522a717540cSStefano Zampini } else { 3523a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 35249162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3525a717540cSStefano Zampini if (row != col) { 35269162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 3527a717540cSStefano Zampini } else { 35289162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 3529a717540cSStefano Zampini } 3530906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 3531a717540cSStefano Zampini } 3532a717540cSStefano Zampini } 3533a717540cSStefano Zampini } 353498a51de6SStefano Zampini if (pcbddc->dbg_flag) { 353522d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 3536a717540cSStefano Zampini } 3537674ae819SStefano Zampini } 3538984c4197SStefano Zampini } else { 3539984c4197SStefano Zampini if (pcbddc->dbg_flag) { 35409162d606SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Constraint %d does not need a change of basis (size %d)\n",total_counts,size_of_constraint);CHKERRQ(ierr); 3541674ae819SStefano Zampini } 3542674ae819SStefano Zampini } 3543674ae819SStefano Zampini } 3544a717540cSStefano Zampini 3545a717540cSStefano Zampini /* free workspace */ 3546a717540cSStefano Zampini if (qr_needed) { 3547984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3548cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 3549984c4197SStefano Zampini } 3550984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 3551984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 3552984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 3553984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 3554984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 3555674ae819SStefano Zampini } 3556a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 3557906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3558906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3559906d46d4SStefano Zampini 3560906d46d4SStefano Zampini /* assembling of global change of variable */ 3561bbb9e6c6SStefano Zampini { 3562bbb9e6c6SStefano Zampini Mat tmat; 356316f15bc4SStefano Zampini PetscInt bs; 356416f15bc4SStefano Zampini 3565906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 3566906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 3567bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 3568bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 3569bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3570bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 357116f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 357216f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 3573906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 3574bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 3575bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3576bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3577bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 3578bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 3579e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3580e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3581bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 3582bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 3583906d46d4SStefano Zampini } 3584906d46d4SStefano Zampini /* check */ 3585906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 3586906d46d4SStefano Zampini PetscReal error; 3587906d46d4SStefano Zampini Vec x,x_change; 3588906d46d4SStefano Zampini 3589906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 3590906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 3591906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 3592906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 3593e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3594e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3595bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 3596e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3597e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3598906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 3599906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 3600906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 3601906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3602bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 3603906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 3604906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 3605906d46d4SStefano Zampini } 3606b96c3477SStefano Zampini 3607b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 3608b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3609b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 3610b96c3477SStefano Zampini if (sub_schurs->S_Ej_all) { 3611ac632422SStefano Zampini Mat S_new,tmat; 3612b087196eSStefano Zampini ISLocalToGlobalMapping NtoSall; 3613b087196eSStefano Zampini IS is_all_N,is_V,is_V_Sall; 3614b087196eSStefano Zampini const PetscScalar *array; 3615b087196eSStefano Zampini const PetscInt *idxs_V,*idxs_all; 3616b087196eSStefano Zampini PetscInt i,n_V; 3617bbb9e6c6SStefano Zampini 3618bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 36196816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 3620b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 3621b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 3622b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 3623b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 3624bbb9e6c6SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 3625b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 3626ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 3627b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 3628ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 3629b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 3630b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 3631b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 3632b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 3633b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 3634b087196eSStefano Zampini for (i=0;i<n_V;i++) { 3635b087196eSStefano Zampini PetscScalar val; 3636b087196eSStefano Zampini PetscInt idx; 3637b087196eSStefano Zampini 3638b087196eSStefano Zampini idx = idxs_V[i]; 3639b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 3640b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 3641b087196eSStefano Zampini } 3642b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3643b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3644ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 3645ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 3646ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 3647ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 3648b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 3649ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 3650b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 3651ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 3652ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 3653ac632422SStefano Zampini } 3654b087196eSStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 3655b087196eSStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 3656b087196eSStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 3657b96c3477SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3658b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 3659b96c3477SStefano Zampini } 3660b96c3477SStefano Zampini } 3661906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 3662906d46d4SStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix) { 3663b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3664b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 3665b9b85e73SStefano Zampini } 3666906d46d4SStefano Zampini 3667906d46d4SStefano Zampini /* set up change of basis context */ 3668906d46d4SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 3669906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 3670906d46d4SStefano Zampini 3671906d46d4SStefano Zampini if (!pcbddc->new_global_mat) { 3672906d46d4SStefano Zampini PetscInt global_size,local_size; 3673906d46d4SStefano Zampini 3674906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 3675906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 3676906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->new_global_mat);CHKERRQ(ierr); 3677906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->new_global_mat,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 3678906d46d4SStefano Zampini ierr = MatSetType(pcbddc->new_global_mat,MATSHELL);CHKERRQ(ierr); 3679906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT,(void (*)(void))PCBDDCMatMult_Private);CHKERRQ(ierr); 3680906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCMatMultTranspose_Private);CHKERRQ(ierr); 3681906d46d4SStefano Zampini ierr = PetscNew(&change_ctx);CHKERRQ(ierr); 3682906d46d4SStefano Zampini ierr = MatShellSetContext(pcbddc->new_global_mat,change_ctx);CHKERRQ(ierr); 3683906d46d4SStefano Zampini } else { 3684906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 3685906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 3686906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 3687906d46d4SStefano Zampini } 3688906d46d4SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix) { 3689906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3690906d46d4SStefano Zampini change_ctx->global_change = pcbddc->ChangeOfBasisMatrix; 3691906d46d4SStefano Zampini } else { 3692906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3693906d46d4SStefano Zampini change_ctx->global_change = pcbddc->user_ChangeOfBasisMatrix; 3694906d46d4SStefano Zampini } 3695906d46d4SStefano Zampini ierr = VecDuplicateVecs(pcis->vec1_global,2,&change_ctx->work);CHKERRQ(ierr); 3696906d46d4SStefano Zampini ierr = MatSetUp(pcbddc->new_global_mat);CHKERRQ(ierr); 3697906d46d4SStefano Zampini ierr = MatAssemblyBegin(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3698906d46d4SStefano Zampini ierr = MatAssemblyEnd(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3699b9b85e73SStefano Zampini } 3700a717540cSStefano Zampini 37014f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 37024f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 37034f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 37044f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 3705019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 3706019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 3707019a44ceSStefano Zampini pcbddc->local_primal_size++; 3708019a44ceSStefano Zampini } 3709019a44ceSStefano Zampini 3710019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 3711727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 3712727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 3713aff50787SStefano Zampini ierr = PetscMemcmp(pcbddc->local_primal_ref_node,olocal_primal_ref_node,olocal_primal_size_cc*sizeof(PetscScalar),&pcbddc->new_primal_space_local);CHKERRQ(ierr); 3714c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 37150e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 3716aff50787SStefano Zampini ierr = PetscMemcmp(pcbddc->local_primal_ref_mult,olocal_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscScalar),&pcbddc->new_primal_space_local);CHKERRQ(ierr); 3717727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 3718727cdba6SStefano Zampini } 37190e6343abSStefano Zampini } 37200e6343abSStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 3721727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 3722727cdba6SStefano Zampini ierr = MPI_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 3723727cdba6SStefano Zampini 3724a717540cSStefano Zampini /* flush dbg viewer */ 3725b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 3726b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3727b8ffe317SStefano Zampini } 3728a717540cSStefano Zampini 3729e310c8b4SStefano Zampini /* free workspace */ 3730a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 37314641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 373208122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 37339162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 37349162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 373508122e43SStefano Zampini } else { 37369162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 37379162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 37389162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 373908122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 374008122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 37419162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 37429162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 374308122e43SStefano Zampini } 3744674ae819SStefano Zampini PetscFunctionReturn(0); 3745674ae819SStefano Zampini } 3746674ae819SStefano Zampini 3747674ae819SStefano Zampini #undef __FUNCT__ 3748674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 3749674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 3750674ae819SStefano Zampini { 3751674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3752674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 3753674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 37547fb0e2dbSStefano Zampini PetscInt ierr,i,vertex_size,N; 3755674ae819SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 3756674ae819SStefano Zampini 3757674ae819SStefano Zampini PetscFunctionBegin; 37588e61c736SStefano Zampini /* Reset previously computed graph */ 37598e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 3760674ae819SStefano Zampini /* Init local Graph struct */ 37617fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 37623bbff08aSStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,pcis->mapping,N);CHKERRQ(ierr); 3763674ae819SStefano Zampini 3764575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 37655099eff2SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 37665099eff2SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid size of local CSR graph! Found %d, expected %d\n",pcbddc->mat_graph->nvtxs_csr,pcbddc->mat_graph->nvtxs); 3767575ad6abSStefano Zampini } 37689577ea80SStefano Zampini 3769674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 37704d379d7bSStefano Zampini if (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) { 37714d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 37724d379d7bSStefano Zampini PetscInt nvtxs; 3773e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 3774674ae819SStefano Zampini 37754d379d7bSStefano Zampini if (pcbddc->use_local_adj) { 37762fffb893SStefano Zampini 37772fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 37782fffb893SStefano Zampini if (flg_row) { 37794d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 3780b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 37812fffb893SStefano Zampini } 37822fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 37839b28b941SStefano Zampini } else if (pcbddc->current_level && pcis->n_B) { /* just compute subdomain's connected components for coarser levels when the local boundary is not empty */ 37844d379d7bSStefano Zampini IS is_dummy; 37854d379d7bSStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 37864d379d7bSStefano Zampini PetscInt j,sum; 37874d379d7bSStefano Zampini PetscInt *cxadj,*cadjncy; 37884d379d7bSStefano Zampini const PetscInt *idxs; 37894d379d7bSStefano Zampini PCBDDCGraph graph; 37904d379d7bSStefano Zampini PetscBT is_on_boundary; 37914d379d7bSStefano Zampini 37924d379d7bSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcis->n,0,1,&is_dummy);CHKERRQ(ierr); 37934d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 37944d379d7bSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 37954d379d7bSStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 37967fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,pcis->n);CHKERRQ(ierr); 37974d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 3798e496cd5dSStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 3799e496cd5dSStefano Zampini if (flg_row) { 38004d379d7bSStefano Zampini graph->xadj = xadj; 38014d379d7bSStefano Zampini graph->adjncy = adjncy; 3802e496cd5dSStefano Zampini } 38034d379d7bSStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 38044d379d7bSStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 3805e496cd5dSStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 38064d379d7bSStefano Zampini 38074d379d7bSStefano Zampini if (pcbddc->dbg_flag) { 38089b28b941SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] Found %d subdomains (local size %d)\n",PetscGlobalRank,graph->ncc,pcis->n);CHKERRQ(ierr); 38094d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 38104d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] %d cc size %d\n",PetscGlobalRank,i,graph->cptr[i+1]-graph->cptr[i]);CHKERRQ(ierr); 38114d379d7bSStefano Zampini } 38124d379d7bSStefano Zampini } 38134d379d7bSStefano Zampini 3814e496cd5dSStefano Zampini ierr = PetscBTCreate(pcis->n,&is_on_boundary);CHKERRQ(ierr); 38154d379d7bSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 38164d379d7bSStefano Zampini for (i=0;i<pcis->n_B;i++) { 38174d379d7bSStefano Zampini ierr = PetscBTSet(is_on_boundary,idxs[i]);CHKERRQ(ierr); 38184d379d7bSStefano Zampini } 38194d379d7bSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 38204d379d7bSStefano Zampini 3821e496cd5dSStefano Zampini ierr = PetscCalloc1(pcis->n+1,&cxadj);CHKERRQ(ierr); 38224d379d7bSStefano Zampini sum = 0; 38234d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 38244d379d7bSStefano Zampini PetscInt sizecc = 0; 38254d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 38264d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 38274d379d7bSStefano Zampini sizecc++; 38284d379d7bSStefano Zampini } 38294d379d7bSStefano Zampini } 38304d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 38314d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 38324d379d7bSStefano Zampini cxadj[graph->queue[j]] = sizecc; 38334d379d7bSStefano Zampini } 38344d379d7bSStefano Zampini } 38354d379d7bSStefano Zampini sum += sizecc*sizecc; 38364d379d7bSStefano Zampini } 38374d379d7bSStefano Zampini ierr = PetscMalloc1(sum,&cadjncy);CHKERRQ(ierr); 38384d379d7bSStefano Zampini sum = 0; 3839e496cd5dSStefano Zampini for (i=0;i<pcis->n;i++) { 38404d379d7bSStefano Zampini PetscInt temp = cxadj[i]; 38414d379d7bSStefano Zampini cxadj[i] = sum; 38424d379d7bSStefano Zampini sum += temp; 38434d379d7bSStefano Zampini } 3844e496cd5dSStefano Zampini cxadj[pcis->n] = sum; 38454d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 38464d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 38474d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 38484d379d7bSStefano Zampini PetscInt k,sizecc = 0; 38494d379d7bSStefano Zampini for (k=graph->cptr[i];k<graph->cptr[i+1];k++) { 38504d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[k])) { 38514d379d7bSStefano Zampini cadjncy[cxadj[graph->queue[j]]+sizecc]=graph->queue[k]; 38524d379d7bSStefano Zampini sizecc++; 38534d379d7bSStefano Zampini } 38544d379d7bSStefano Zampini } 38554d379d7bSStefano Zampini } 38564d379d7bSStefano Zampini } 38574d379d7bSStefano Zampini } 38589b28b941SStefano Zampini if (sum) { 3859e496cd5dSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,pcis->n,cxadj,cadjncy,PETSC_OWN_POINTER);CHKERRQ(ierr); 38604d379d7bSStefano Zampini } else { 38614d379d7bSStefano Zampini ierr = PetscFree(cxadj);CHKERRQ(ierr); 38624d379d7bSStefano Zampini ierr = PetscFree(cadjncy);CHKERRQ(ierr); 38634d379d7bSStefano Zampini } 38644d379d7bSStefano Zampini graph->xadj = 0; 38654d379d7bSStefano Zampini graph->adjncy = 0; 38664d379d7bSStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 38674d379d7bSStefano Zampini ierr = PetscBTDestroy(&is_on_boundary);CHKERRQ(ierr); 38684d379d7bSStefano Zampini } 3869674ae819SStefano Zampini } 38709b28b941SStefano Zampini if (pcbddc->dbg_flag) { 38719b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3872674ae819SStefano Zampini } 3873674ae819SStefano Zampini 387463602bcaSStefano Zampini /* Set default dofs' splitting if no information has been provided by the user with PCBDDCSetDofsSplitting or PCBDDCSetDofsSplittingLocal */ 3875674ae819SStefano Zampini vertex_size = 1; 387663602bcaSStefano Zampini if (pcbddc->user_provided_isfordofs) { 387763602bcaSStefano Zampini if (pcbddc->n_ISForDofs) { /* need to convert from global to local and remove references to global dofs splitting */ 387895ecbf38SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 387963602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 3880e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 388163602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 3882674ae819SStefano Zampini } 388363602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 388463602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 388563602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 3886674ae819SStefano Zampini } 388763602bcaSStefano Zampini /* mat block size as vertex size (used for elasticity with rigid body modes as nearnullspace) */ 3888674ae819SStefano Zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 388963602bcaSStefano Zampini } else { 389063602bcaSStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering */ 389163602bcaSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->n_ISForDofsLocal);CHKERRQ(ierr); 3892854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 389363602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 389463602bcaSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),pcis->n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 389563602bcaSStefano Zampini } 389663602bcaSStefano Zampini } 3897674ae819SStefano Zampini } 3898674ae819SStefano Zampini 3899674ae819SStefano Zampini /* Setup of Graph */ 3900785d1243SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { /* need to convert from global to local */ 3901e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 3902785d1243SStefano Zampini } 3903785d1243SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { /* need to convert from global to local */ 3904e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3905785d1243SStefano Zampini } 3906302440fdSBarry Smith ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices);CHKERRQ(ierr); 3907674ae819SStefano Zampini 39084f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 39094f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 39104f1b2e48SStefano Zampini PetscInt *local_subs; 39114f1b2e48SStefano Zampini 39124f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 39134f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 39144f1b2e48SStefano Zampini const PetscInt *idxs; 39154f1b2e48SStefano Zampini PetscInt nl,j; 39164f1b2e48SStefano Zampini 39174f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 39184f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 39194f1b2e48SStefano Zampini for (j=0;j<nl;j++) { 39204f1b2e48SStefano Zampini local_subs[idxs[j]] = i; 39214f1b2e48SStefano Zampini } 39224f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 39234f1b2e48SStefano Zampini } 39244f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 39254f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 39264f1b2e48SStefano Zampini } 39274f1b2e48SStefano Zampini 3928674ae819SStefano Zampini /* Graph's connected components analysis */ 3929674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 3930674ae819SStefano Zampini 3931674ae819SStefano Zampini /* print some info to stdout */ 3932674ae819SStefano Zampini if (pcbddc->dbg_flag) { 3933302440fdSBarry Smith ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,viewer);CHKERRQ(ierr); 3934674ae819SStefano Zampini } 3935fb180af4SStefano Zampini 3936fb180af4SStefano Zampini /* mark topography has done */ 3937fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 3938674ae819SStefano Zampini PetscFunctionReturn(0); 3939674ae819SStefano Zampini } 3940674ae819SStefano Zampini 3941dc456d91SStefano Zampini /* given an index sets possibly with holes, renumbers the indexes removing the holes */ 3942674ae819SStefano Zampini #undef __FUNCT__ 3943674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 3944dc456d91SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(IS subset, IS subset_mult, PetscInt *N_n, IS *subset_n) 3945674ae819SStefano Zampini { 3946dc456d91SStefano Zampini PetscSF sf; 3947dc456d91SStefano Zampini PetscLayout map; 3948dc456d91SStefano Zampini const PetscInt *idxs; 3949dc456d91SStefano Zampini PetscInt *leaf_data,*root_data,*gidxs; 3950dc456d91SStefano Zampini PetscInt N,n,i,lbounds[2],gbounds[2],Nl; 3951dc456d91SStefano Zampini PetscInt n_n,nlocals,start,first_index; 3952dc456d91SStefano Zampini PetscMPIInt commsize; 3953674ae819SStefano Zampini PetscBool first_found; 3954674ae819SStefano Zampini PetscErrorCode ierr; 3955674ae819SStefano Zampini 3956674ae819SStefano Zampini PetscFunctionBegin; 3957dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&n);CHKERRQ(ierr); 3958dc456d91SStefano Zampini if (subset_mult) { 3959dc456d91SStefano Zampini PetscCheckSameComm(subset,1,subset_mult,2); 3960dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&i);CHKERRQ(ierr); 3961dc456d91SStefano Zampini if (i != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local subset and multiplicity sizes don't match! %d != %d",n,i); 3962674ae819SStefano Zampini } 3963dc456d91SStefano Zampini /* create workspace layout for computing global indices of subset */ 3964dc456d91SStefano Zampini ierr = ISGetIndices(subset,&idxs);CHKERRQ(ierr); 3965dc456d91SStefano Zampini lbounds[0] = lbounds[1] = 0; 3966dc456d91SStefano Zampini for (i=0;i<n;i++) { 3967dc456d91SStefano Zampini if (idxs[i] < lbounds[0]) lbounds[0] = idxs[i]; 3968dc456d91SStefano Zampini else if (idxs[i] > lbounds[1]) lbounds[1] = idxs[i]; 3969674ae819SStefano Zampini } 3970dc456d91SStefano Zampini lbounds[0] = -lbounds[0]; 3971dc456d91SStefano Zampini ierr = MPI_Allreduce(lbounds,gbounds,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 3972dc456d91SStefano Zampini gbounds[0] = -gbounds[0]; 3973dc456d91SStefano Zampini N = gbounds[1] - gbounds[0] + 1; 3974dc456d91SStefano Zampini ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)subset),&map);CHKERRQ(ierr); 3975dc456d91SStefano Zampini ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 3976dc456d91SStefano Zampini ierr = PetscLayoutSetSize(map,N);CHKERRQ(ierr); 3977dc456d91SStefano Zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 3978dc456d91SStefano Zampini ierr = PetscLayoutGetLocalSize(map,&Nl);CHKERRQ(ierr); 3979dc456d91SStefano Zampini 3980dc456d91SStefano Zampini /* create sf : leaf_data == multiplicity of indexes, root data == global index in layout */ 3981dc456d91SStefano Zampini ierr = PetscMalloc2(n,&leaf_data,Nl,&root_data);CHKERRQ(ierr); 3982dc456d91SStefano Zampini if (subset_mult) { 3983dc456d91SStefano Zampini const PetscInt* idxs_mult; 3984dc456d91SStefano Zampini 3985dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3986dc456d91SStefano Zampini ierr = PetscMemcpy(leaf_data,idxs_mult,n*sizeof(PetscInt));CHKERRQ(ierr); 3987dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3988674ae819SStefano Zampini } else { 3989dc456d91SStefano Zampini for (i=0;i<n;i++) leaf_data[i] = 1; 3990674ae819SStefano Zampini } 3991dc456d91SStefano Zampini /* local size of new subset */ 3992dc456d91SStefano Zampini n_n = 0; 3993dc456d91SStefano Zampini for (i=0;i<n;i++) n_n += leaf_data[i]; 3994dc456d91SStefano Zampini 3995dc456d91SStefano Zampini /* global indexes in layout */ 3996dc456d91SStefano Zampini ierr = PetscMalloc1(n_n,&gidxs);CHKERRQ(ierr); /* allocating possibly extra space in gidxs which will be used later */ 3997dc456d91SStefano Zampini for (i=0;i<n;i++) gidxs[i] = idxs[i] - gbounds[0]; 3998dc456d91SStefano Zampini ierr = ISRestoreIndices(subset,&idxs);CHKERRQ(ierr); 3999dc456d91SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)subset),&sf);CHKERRQ(ierr); 4000dc456d91SStefano Zampini ierr = PetscSFSetGraphLayout(sf,map,n,NULL,PETSC_COPY_VALUES,gidxs);CHKERRQ(ierr); 4001dc456d91SStefano Zampini ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 4002dc456d91SStefano Zampini 4003dc456d91SStefano Zampini /* reduce from leaves to roots */ 4004dc456d91SStefano Zampini ierr = PetscMemzero(root_data,Nl*sizeof(PetscInt));CHKERRQ(ierr); 400564a8e5bcSStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 400664a8e5bcSStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 4007dc456d91SStefano Zampini 4008dc456d91SStefano Zampini /* count indexes in local part of layout */ 4009674ae819SStefano Zampini nlocals = 0; 4010674ae819SStefano Zampini first_index = -1; 4011674ae819SStefano Zampini first_found = PETSC_FALSE; 4012dc456d91SStefano Zampini for (i=0;i<Nl;i++) { 4013dc456d91SStefano Zampini if (!first_found && root_data[i]) { 4014674ae819SStefano Zampini first_found = PETSC_TRUE; 4015674ae819SStefano Zampini first_index = i; 4016674ae819SStefano Zampini } 4017dc456d91SStefano Zampini nlocals += root_data[i]; 4018674ae819SStefano Zampini } 4019dc456d91SStefano Zampini 4020dc456d91SStefano Zampini /* cumulative of number of indexes and size of subset without holes */ 40215fa240b1SStefano Zampini #if defined(PETSC_HAVE_MPI_EXSCAN) 4022dc456d91SStefano Zampini start = 0; 402364a8e5bcSStefano Zampini ierr = MPI_Exscan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 40245fa240b1SStefano Zampini #else 402564a8e5bcSStefano Zampini ierr = MPI_Scan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 40265fa240b1SStefano Zampini start = start-nlocals; 40275fa240b1SStefano Zampini #endif 40285fa240b1SStefano Zampini 4029dc456d91SStefano Zampini if (N_n) { /* compute total size of new subset if requested */ 4030dc456d91SStefano Zampini *N_n = start + nlocals; 4031dc456d91SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)subset),&commsize);CHKERRQ(ierr); 4032dc456d91SStefano Zampini ierr = MPI_Bcast(N_n,1,MPIU_INT,commsize-1,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4033674ae819SStefano Zampini } 40345fa240b1SStefano Zampini 40355fa240b1SStefano Zampini /* adapt root data with cumulative */ 4036674ae819SStefano Zampini if (first_found) { 4037dc456d91SStefano Zampini PetscInt old_index; 4038dc456d91SStefano Zampini 4039dc456d91SStefano Zampini root_data[first_index] += start; 4040674ae819SStefano Zampini old_index = first_index; 4041dc456d91SStefano Zampini for (i=first_index+1;i<Nl;i++) { 4042dc456d91SStefano Zampini if (root_data[i]) { 4043dc456d91SStefano Zampini root_data[i] += root_data[old_index]; 4044674ae819SStefano Zampini old_index = i; 4045674ae819SStefano Zampini } 4046674ae819SStefano Zampini } 4047674ae819SStefano Zampini } 4048dc456d91SStefano Zampini 4049dc456d91SStefano Zampini /* from roots to leaves */ 4050dc456d91SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4051dc456d91SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4052dc456d91SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 4053dc456d91SStefano Zampini 4054dc456d91SStefano Zampini /* create new IS with global indexes without holes */ 4055dc456d91SStefano Zampini if (subset_mult) { 4056dc456d91SStefano Zampini const PetscInt* idxs_mult; 4057dc456d91SStefano Zampini PetscInt cum; 4058dc456d91SStefano Zampini 4059dc456d91SStefano Zampini cum = 0; 4060dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4061dc456d91SStefano Zampini for (i=0;i<n;i++) { 4062dc456d91SStefano Zampini PetscInt j; 4063dc456d91SStefano Zampini for (j=0;j<idxs_mult[i];j++) gidxs[cum++] = leaf_data[i] - idxs_mult[i] + j; 4064674ae819SStefano Zampini } 4065dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4066674ae819SStefano Zampini } else { 4067dc456d91SStefano Zampini for (i=0;i<n;i++) { 4068dc456d91SStefano Zampini gidxs[i] = leaf_data[i]-1; 4069674ae819SStefano Zampini } 4070674ae819SStefano Zampini } 4071dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)subset),n_n,gidxs,PETSC_OWN_POINTER,subset_n);CHKERRQ(ierr); 4072dc456d91SStefano Zampini ierr = PetscFree2(leaf_data,root_data);CHKERRQ(ierr); 4073674ae819SStefano Zampini PetscFunctionReturn(0); 4074674ae819SStefano Zampini } 40759a7d3425SStefano Zampini 40769a7d3425SStefano Zampini #undef __FUNCT__ 40779a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 40789a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 40799a7d3425SStefano Zampini { 40809a7d3425SStefano Zampini PetscInt i,j; 40819a7d3425SStefano Zampini PetscScalar *alphas; 40829a7d3425SStefano Zampini PetscErrorCode ierr; 40839a7d3425SStefano Zampini 40849a7d3425SStefano Zampini PetscFunctionBegin; 40859a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 4086785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 40879a7d3425SStefano Zampini for (i=0;i<n;i++) { 40889a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 40899a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 40909a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 40919a7d3425SStefano Zampini } 40929a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 40939a7d3425SStefano Zampini PetscFunctionReturn(0); 40949a7d3425SStefano Zampini } 40959a7d3425SStefano Zampini 4096e7931f94SStefano Zampini #undef __FUNCT__ 409770cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 4098b0c7d250SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt n_subdomains, PetscInt redprocs, IS* is_sends) 4099e7931f94SStefano Zampini { 410052e5ac9dSStefano Zampini IS ranks_send_to; 4101e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 4102e7931f94SStefano Zampini PetscMPIInt size,rank,color; 410352e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 410452e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 41053837a79fSStefano Zampini PetscInt i,local_size,threshold=0; 41062b510759SStefano Zampini PetscBool use_vwgt=PETSC_FALSE,use_square=PETSC_FALSE; 4107e7931f94SStefano Zampini PetscSubcomm subcomm; 410852e5ac9dSStefano Zampini PetscErrorCode ierr; 4109a57a6d2fSStefano Zampini 4110e7931f94SStefano Zampini PetscFunctionBegin; 41112b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_square",&use_square,NULL);CHKERRQ(ierr); 41122b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 41132b510759SStefano Zampini ierr = PetscOptionsGetInt(NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 4114e7931f94SStefano Zampini 4115e7931f94SStefano Zampini /* Get info on mapping */ 41163bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 41173bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4118e7931f94SStefano Zampini 4119e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 4120785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 4121e7931f94SStefano Zampini xadj[0] = 0; 4122e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 4123785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 4124785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 4125e7931f94SStefano Zampini 41262b510759SStefano Zampini if (threshold) { 4127d023bfaeSStefano Zampini PetscInt xadj_count = 0; 41282b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 4129d023bfaeSStefano Zampini if (n_shared[i] > threshold) { 4130d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 4131d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 4132d023bfaeSStefano Zampini xadj_count++; 4133e7931f94SStefano Zampini } 4134e7931f94SStefano Zampini } 4135d023bfaeSStefano Zampini xadj[1] = xadj_count; 4136c8587f34SStefano Zampini } else { 4137e7931f94SStefano Zampini if (xadj[1]) { 4138e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy,&neighs[1],xadj[1]*sizeof(*adjncy));CHKERRQ(ierr); 4139e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy_wgt,&n_shared[1],xadj[1]*sizeof(*adjncy_wgt));CHKERRQ(ierr); 4140c8587f34SStefano Zampini } 4141e7931f94SStefano Zampini } 41423bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4143e7931f94SStefano Zampini if (use_square) { 4144e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 4145e7931f94SStefano Zampini adjncy_wgt[i] = adjncy_wgt[i]*adjncy_wgt[i]; 4146e7931f94SStefano Zampini } 4147e7931f94SStefano Zampini } 4148e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4149e7931f94SStefano Zampini 41503837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 4151e7931f94SStefano Zampini 4152e7931f94SStefano Zampini /* 4153e7931f94SStefano Zampini Restrict work on active processes only. 4154e7931f94SStefano Zampini */ 4155e7931f94SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&subcomm);CHKERRQ(ierr); 4156e7931f94SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 4157e7931f94SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 41582b510759SStefano Zampini ierr = PetscMPIIntCast(!local_size,&color);CHKERRQ(ierr); 4159d3531aaaSJed Brown ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4160e7931f94SStefano Zampini if (color) { 4161e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 4162e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 4163e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 4164c8587f34SStefano Zampini } else { 416552e5ac9dSStefano Zampini Mat subdomain_adj; 416652e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 416752e5ac9dSStefano Zampini MatPartitioning partitioner; 416852e5ac9dSStefano Zampini PetscInt prank,rstart=0,rend=0; 416952e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 4170b0c7d250SStefano Zampini PetscBool aggregate; 4171b0c7d250SStefano Zampini 4172306c2d5bSBarry Smith ierr = MPI_Comm_size(PetscSubcommChild(subcomm),&size);CHKERRQ(ierr); 4173785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 4174e7931f94SStefano Zampini prank = rank; 4175306c2d5bSBarry Smith ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,PetscSubcommChild(subcomm));CHKERRQ(ierr); 41768002ef2cSStefano Zampini /* 4177e7931f94SStefano Zampini for (i=0;i<size;i++) { 4178e7931f94SStefano Zampini PetscPrintf(subcomm->comm,"oldranks[%d] = %d\n",i,oldranks[i]); 4179c8587f34SStefano Zampini } 41808002ef2cSStefano Zampini */ 4181e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 4182e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 4183c8587f34SStefano Zampini } 4184e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4185b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 4186b0c7d250SStefano Zampini if (aggregate) { 4187b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 4188b0c7d250SStefano Zampini PetscMPIInt nrank; 4189b0c7d250SStefano Zampini PetscScalar *vals; 4190b0c7d250SStefano Zampini 4191b0c7d250SStefano Zampini ierr = MPI_Comm_rank(PetscSubcommChild(subcomm),&nrank);CHKERRQ(ierr); 4192b0c7d250SStefano Zampini lrows = 0; 4193b0c7d250SStefano Zampini if (nrank<redprocs) { 4194b0c7d250SStefano Zampini lrows = size/redprocs; 4195b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 4196b0c7d250SStefano Zampini } 41975fa240b1SStefano Zampini ierr = MatCreateAIJ(PetscSubcommChild(subcomm),lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 4198b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 4199b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 4200b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 4201b0c7d250SStefano Zampini row = nrank; 4202b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 4203b0c7d250SStefano Zampini cols = adjncy; 4204b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 4205b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 4206b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 4207b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4208b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 420952e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 421052e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 421152e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 4212b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 4213b0c7d250SStefano Zampini } else { 4214306c2d5bSBarry Smith ierr = MatCreateMPIAdj(PetscSubcommChild(subcomm),1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 4215b0c7d250SStefano Zampini } 421622b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 4217e7931f94SStefano Zampini 4218e7931f94SStefano Zampini /* Partition */ 4219306c2d5bSBarry Smith ierr = MatPartitioningCreate(PetscSubcommChild(subcomm),&partitioner);CHKERRQ(ierr); 4220e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 4221e7931f94SStefano Zampini if (use_vwgt) { 42223837a79fSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 4223e7931f94SStefano Zampini v_wgt[0] = local_size; 4224e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 4225c8587f34SStefano Zampini } 422628143c3dSStefano Zampini n_subdomains = PetscMin((PetscInt)size,n_subdomains); 422728143c3dSStefano Zampini ierr = MatPartitioningSetNParts(partitioner,n_subdomains);CHKERRQ(ierr); 4228e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 4229e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 423022b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 4231e7931f94SStefano Zampini 423252e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 423352e5ac9dSStefano Zampini ierr = PCBDDCSubsetNumbering(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 423452e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 423552e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4236b0c7d250SStefano Zampini if (!redprocs) { 4237b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 423828143c3dSStefano Zampini } else { 4239b0c7d250SStefano Zampini PetscInt idxs[1]; 4240b0c7d250SStefano Zampini PetscMPIInt tag; 4241b0c7d250SStefano Zampini MPI_Request *reqs; 4242b0c7d250SStefano Zampini 4243b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 4244b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 4245b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 4246b0c7d250SStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,PetscSubcommChild(subcomm),&reqs[i-rstart]);CHKERRQ(ierr); 424728143c3dSStefano Zampini } 4248b0c7d250SStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,PetscSubcommChild(subcomm),MPI_STATUS_IGNORE);CHKERRQ(ierr); 4249b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4250b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 4251b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 4252e7931f94SStefano Zampini } 425352e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4254e7931f94SStefano Zampini /* clean up */ 4255e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 425652e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 4257e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 4258e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 4259e7931f94SStefano Zampini } 4260e7931f94SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 4261e7931f94SStefano Zampini 4262e7931f94SStefano Zampini /* assemble parallel IS for sends */ 4263e7931f94SStefano Zampini i = 1; 4264e7931f94SStefano Zampini if (color) i=0; 4265e7931f94SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,&ranks_send_to);CHKERRQ(ierr); 4266e7931f94SStefano Zampini /* get back IS */ 4267e7931f94SStefano Zampini *is_sends = ranks_send_to; 4268e7931f94SStefano Zampini PetscFunctionReturn(0); 4269e7931f94SStefano Zampini } 4270e7931f94SStefano Zampini 4271e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 4272e7931f94SStefano Zampini 4273e7931f94SStefano Zampini #undef __FUNCT__ 4274e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 427553a05cb3SStefano Zampini PetscErrorCode MatISSubassemble(Mat mat, IS is_sends, PetscInt n_subdomains, PetscBool restrict_comm, PetscBool restrict_full, MatReuse reuse, Mat *mat_n, PetscInt nis, IS isarray[]) 4276e7931f94SStefano Zampini { 427770cf5478SStefano Zampini Mat local_mat; 4278e7931f94SStefano Zampini IS is_sends_internal; 42799d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 428028143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 42819d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 4282e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 4283e7931f94SStefano Zampini PetscInt* l2gmap_indices; 4284e7931f94SStefano Zampini const PetscInt* is_indices; 4285e7931f94SStefano Zampini MatType new_local_type; 4286e7931f94SStefano Zampini /* buffers */ 4287e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 428828143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 42899d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 4290e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 4291e7931f94SStefano Zampini /* MPI */ 429228143c3dSStefano Zampini MPI_Comm comm,comm_n; 429328143c3dSStefano Zampini PetscSubcomm subcomm; 4294e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 429528143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 429628143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 429728143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 429828143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 429928143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 4300e7931f94SStefano Zampini PetscErrorCode ierr; 4301e7931f94SStefano Zampini 4302e7931f94SStefano Zampini PetscFunctionBegin; 430328143c3dSStefano Zampini /* TODO: add missing checks */ 430428143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 430528143c3dSStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 430628143c3dSStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,5); 430728143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,7); 4308e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 430928143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 4310e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 4311e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 4312e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 4313e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 4314e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 431528143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX && *mat_n) { 431670cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 431770cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 431828143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 431970cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 432070cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 432170cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 432270cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 432370cf5478SStefano Zampini } 4324e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 4325e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 4326e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 4327e7931f94SStefano Zampini if (!is_sends) { 432828143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 4329b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,n_subdomains,0,&is_sends_internal);CHKERRQ(ierr); 4330c8587f34SStefano Zampini } else { 4331e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 4332e7931f94SStefano Zampini is_sends_internal = is_sends; 4333c8587f34SStefano Zampini } 4334e7931f94SStefano Zampini 4335e7931f94SStefano Zampini /* get comm */ 4336a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 4337e7931f94SStefano Zampini 4338e7931f94SStefano Zampini /* compute number of sends */ 4339e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 4340e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 4341e7931f94SStefano Zampini 4342e7931f94SStefano Zampini /* compute number of receives */ 4343e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 4344785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 4345e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 4346e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4347e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 4348e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 4349e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 4350e7931f94SStefano Zampini 435128143c3dSStefano Zampini /* restrict comm if requested */ 435228143c3dSStefano Zampini subcomm = 0; 435328143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 435428143c3dSStefano Zampini if (restrict_comm) { 4355779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 4356779c1cceSStefano Zampini 435728143c3dSStefano Zampini color = 0; 435853a05cb3SStefano Zampini if (restrict_full) { 435953a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 436053a05cb3SStefano Zampini } else { 436153a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 436253a05cb3SStefano Zampini } 436328143c3dSStefano Zampini ierr = MPI_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 436428143c3dSStefano Zampini subcommsize = commsize - subcommsize; 436528143c3dSStefano Zampini /* check if reuse has been requested */ 436628143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 436728143c3dSStefano Zampini if (*mat_n) { 436828143c3dSStefano Zampini PetscMPIInt subcommsize2; 436928143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 437028143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 437128143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 437228143c3dSStefano Zampini } else { 437328143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 437428143c3dSStefano Zampini } 437528143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 4376779c1cceSStefano Zampini PetscMPIInt rank; 4377779c1cceSStefano Zampini 4378779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 437928143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 438028143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 438128143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4382306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 438328143c3dSStefano Zampini } 438428143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 438528143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 438628143c3dSStefano Zampini } else { 438728143c3dSStefano Zampini comm_n = comm; 438828143c3dSStefano Zampini } 438928143c3dSStefano Zampini 4390e7931f94SStefano Zampini /* prepare send/receive buffers */ 4391785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 4392e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 4393785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 4394e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 439528143c3dSStefano Zampini if (nis) { 4396854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 439728143c3dSStefano Zampini } 4398e7931f94SStefano Zampini 439928143c3dSStefano Zampini /* Get data from local matrices */ 4400e7931f94SStefano Zampini if (!isdense) { 4401a26c9d0eSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 4402e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 4403e7931f94SStefano Zampini /* 4404e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 4405e7931f94SStefano Zampini send_buffer_idxs should contain: 4406e7931f94SStefano Zampini - MatType_PRIVATE type 4407e7931f94SStefano Zampini - PetscInt size_of_l2gmap 4408e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 4409e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 4410e7931f94SStefano Zampini */ 4411e7931f94SStefano Zampini } else { 4412e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 44133bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 4414854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 4415e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 4416e7931f94SStefano Zampini send_buffer_idxs[1] = i; 44173bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4418e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 44193bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4420e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 4421e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4422e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 4423e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 4424c8587f34SStefano Zampini } 4425c8587f34SStefano Zampini } 4426e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 442728143c3dSStefano Zampini /* additional is (if any) */ 442828143c3dSStefano Zampini if (nis) { 442928143c3dSStefano Zampini PetscMPIInt psum; 443028143c3dSStefano Zampini PetscInt j; 443128143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 443228143c3dSStefano Zampini PetscInt plen; 443328143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 443428143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 443528143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 443628143c3dSStefano Zampini } 4437854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 443828143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 443928143c3dSStefano Zampini PetscInt plen; 444028143c3dSStefano Zampini const PetscInt *is_array_idxs; 444128143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 444228143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 444328143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 444428143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 444528143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 444628143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 444728143c3dSStefano Zampini } 444828143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 444928143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 445028143c3dSStefano Zampini } 445128143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 445228143c3dSStefano Zampini } 445328143c3dSStefano Zampini 4454e7931f94SStefano Zampini buf_size_idxs = 0; 4455e7931f94SStefano Zampini buf_size_vals = 0; 445628143c3dSStefano Zampini buf_size_idxs_is = 0; 4457e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4458e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 4459e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 446028143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 4461e7931f94SStefano Zampini } 4462785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 4463785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 446495ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 4465e7931f94SStefano Zampini 4466e7931f94SStefano Zampini /* get new tags for clean communications */ 4467e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 4468e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 446928143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 4470e7931f94SStefano Zampini 4471e7931f94SStefano Zampini /* allocate for requests */ 4472785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 4473785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 447495ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 4475785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 4476785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 447795ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 4478e7931f94SStefano Zampini 4479e7931f94SStefano Zampini /* communications */ 4480e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4481e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 448228143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 4483e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4484e7931f94SStefano Zampini source_dest = onodes[i]; 4485e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 4486e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 4487e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4488e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 448928143c3dSStefano Zampini if (nis) { 449028143c3dSStefano Zampini ierr = MPI_Irecv(ptr_idxs_is,olengths_idxs_is[i],MPIU_INT,source_dest,tag_idxs_is,comm,&recv_req_idxs_is[i]);CHKERRQ(ierr); 449128143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 449228143c3dSStefano Zampini } 4493e7931f94SStefano Zampini } 4494e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4495e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 4496e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 4497e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 449828143c3dSStefano Zampini if (nis) { 449928143c3dSStefano Zampini ierr = MPI_Isend(send_buffer_idxs_is,ilengths_idxs_is[source_dest],MPIU_INT,source_dest,tag_idxs_is,comm,&send_req_idxs_is[i]);CHKERRQ(ierr); 450028143c3dSStefano Zampini } 4501e7931f94SStefano Zampini } 4502e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4503e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 4504e7931f94SStefano Zampini 4505e7931f94SStefano Zampini /* assemble new l2g map */ 4506e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4507e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 45089d30be91SStefano Zampini new_local_rows = 0; 4509e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 45109d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4511e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4512e7931f94SStefano Zampini } 45139d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 4514e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 45159d30be91SStefano Zampini new_local_rows = 0; 4516e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 45179d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 45189d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4519e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4520e7931f94SStefano Zampini } 45219d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 45229d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 4523e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 4524e7931f94SStefano Zampini 4525e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 4526e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 4527e7931f94SStefano Zampini /* it also assumes that if the block size is set, than it is the same among all local matrices (see checks at the beginning of the function) */ 4528e7931f94SStefano Zampini if (n_recvs) { 452928143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 4530e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4531e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4532e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 4533e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 4534e7931f94SStefano Zampini break; 4535e7931f94SStefano Zampini } 4536e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4537e7931f94SStefano Zampini } 4538e7931f94SStefano Zampini switch (new_local_type_private) { 453928143c3dSStefano Zampini case MATDENSE_PRIVATE: 454028143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 4541e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4542e7931f94SStefano Zampini bs = 1; 454328143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 454428143c3dSStefano Zampini new_local_type = MATSEQDENSE; 454528143c3dSStefano Zampini bs = 1; 454628143c3dSStefano Zampini } 4547e7931f94SStefano Zampini break; 4548e7931f94SStefano Zampini case MATAIJ_PRIVATE: 4549e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4550e7931f94SStefano Zampini bs = 1; 4551e7931f94SStefano Zampini break; 4552e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 4553e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 4554e7931f94SStefano Zampini break; 4555e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 4556e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 4557e7931f94SStefano Zampini break; 4558e7931f94SStefano Zampini default: 45599d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 4560e7931f94SStefano Zampini break; 4561e7931f94SStefano Zampini } 456228143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 456328143c3dSStefano Zampini new_local_type = MATSEQDENSE; 456428143c3dSStefano Zampini bs = 1; 4565e7931f94SStefano Zampini } 4566e7931f94SStefano Zampini 456770cf5478SStefano Zampini /* create MATIS object if needed */ 456870cf5478SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 4569e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 4570e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 457170cf5478SStefano Zampini } else { 457270cf5478SStefano Zampini /* it also destroys the local matrices */ 457370cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 457470cf5478SStefano Zampini } 457570cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 4576e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 45779d30be91SStefano Zampini 45789d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 45799d30be91SStefano Zampini 45809d30be91SStefano Zampini /* Global to local map of received indices */ 45819d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 45829d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 45839d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 45849d30be91SStefano Zampini 45859d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 45869d30be91SStefano Zampini buf_size_idxs = 0; 45879d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 45889d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 45899d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 45909d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 45919d30be91SStefano Zampini } 45929d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 45939d30be91SStefano Zampini 45949d30be91SStefano Zampini /* set preallocation */ 45959d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 45969d30be91SStefano Zampini if (!newisdense) { 45979d30be91SStefano Zampini PetscInt *new_local_nnz=0; 45989d30be91SStefano Zampini 45999d30be91SStefano Zampini ptr_vals = recv_buffer_vals; 46009d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 46019d30be91SStefano Zampini if (n_recvs) { 46029d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 46039d30be91SStefano Zampini } 46049d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 46059d30be91SStefano Zampini PetscInt j; 46069d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 46079d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 46089d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 46099d30be91SStefano Zampini } 46109d30be91SStefano Zampini } else { 46119d30be91SStefano Zampini /* TODO */ 46129d30be91SStefano Zampini } 46139d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 46149d30be91SStefano Zampini } 46159d30be91SStefano Zampini if (new_local_nnz) { 46169d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 46179d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 46189d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 46199d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 46209d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 46219d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 46229d30be91SStefano Zampini } else { 46239d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 46249d30be91SStefano Zampini } 46259d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 46269d30be91SStefano Zampini } else { 46279d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 46289d30be91SStefano Zampini } 4629e7931f94SStefano Zampini 4630e7931f94SStefano Zampini /* set values */ 4631e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 46329d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 4633e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4634e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 4635e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 46369d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 4637e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 4638e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 4639e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 464028143c3dSStefano Zampini } else { 464128143c3dSStefano Zampini /* TODO */ 4642e7931f94SStefano Zampini } 4643e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4644e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 4645e7931f94SStefano Zampini } 4646e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4647e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 464870cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 464970cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 46509d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 46519d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 4652e7931f94SStefano Zampini 4653dfd14d43SStefano Zampini #if 0 465428143c3dSStefano Zampini if (!restrict_comm) { /* check */ 4655e7931f94SStefano Zampini Vec lvec,rvec; 4656e7931f94SStefano Zampini PetscReal infty_error; 4657e7931f94SStefano Zampini 46582a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 4659e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 4660e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 4661e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 466270cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 4663e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 4664e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 4665e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 4666e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 4667e7931f94SStefano Zampini } 466828143c3dSStefano Zampini #endif 4669e7931f94SStefano Zampini 467028143c3dSStefano Zampini /* assemble new additional is (if any) */ 467128143c3dSStefano Zampini if (nis) { 467228143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 467328143c3dSStefano Zampini 467428143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4675854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 467628143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 467728143c3dSStefano Zampini psum = 0; 467828143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 467928143c3dSStefano Zampini for (j=0;j<nis;j++) { 468028143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 468128143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 468228143c3dSStefano Zampini psum += plen; 468328143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 468428143c3dSStefano Zampini } 468528143c3dSStefano Zampini } 4686854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 4687854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 468828143c3dSStefano Zampini for (i=1;i<nis;i++) { 468928143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 469028143c3dSStefano Zampini } 469128143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 469228143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 469328143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 469428143c3dSStefano Zampini for (j=0;j<nis;j++) { 469528143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 469628143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 469728143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 469828143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 469928143c3dSStefano Zampini } 470028143c3dSStefano Zampini } 470128143c3dSStefano Zampini for (i=0;i<nis;i++) { 470228143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 470328143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 470428143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 470528143c3dSStefano Zampini } 470628143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 470728143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 470828143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 470928143c3dSStefano Zampini } 4710e7931f94SStefano Zampini /* free workspace */ 471128143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 4712e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4713e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 4714e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4715e7931f94SStefano Zampini if (isdense) { 4716e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 4717e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 4718e7931f94SStefano Zampini } else { 4719e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 4720e7931f94SStefano Zampini } 472128143c3dSStefano Zampini if (nis) { 472228143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 472328143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 472428143c3dSStefano Zampini } 4725e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 4726e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 472728143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 4728e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 4729e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 473028143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 4731e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 4732e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 4733e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 4734e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 4735e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 473628143c3dSStefano Zampini if (nis) { 473728143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 473828143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 473928143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 474028143c3dSStefano Zampini } 474128143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 474228143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 474328143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 474428143c3dSStefano Zampini for (i=0;i<nis;i++) { 474528143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 474628143c3dSStefano Zampini } 474753a05cb3SStefano Zampini *mat_n = NULL; 474828143c3dSStefano Zampini } 4749e7931f94SStefano Zampini PetscFunctionReturn(0); 4750e7931f94SStefano Zampini } 4751a57a6d2fSStefano Zampini 475212edc857SStefano Zampini /* temporary hack into ksp private data structure */ 4753af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 475412edc857SStefano Zampini 4755c8587f34SStefano Zampini #undef __FUNCT__ 4756c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 4757c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 4758c8587f34SStefano Zampini { 4759c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4760c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 476120a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 47629881197aSStefano Zampini MatNullSpace CoarseNullSpace=NULL; 476320a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 47646e683305SStefano Zampini IS coarse_is,*isarray; 47656e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 47666e683305SStefano Zampini PetscInt nis,nisdofs,nisneu; 4767f9eb5b7dSStefano Zampini PC pc_temp; 4768c8587f34SStefano Zampini PCType coarse_pc_type; 4769c8587f34SStefano Zampini KSPType coarse_ksp_type; 4770f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 47714f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 47726e683305SStefano Zampini Mat t_coarse_mat_is; 47736e683305SStefano Zampini PetscInt void_procs,ncoarse_ml,ncoarse_ds,ncoarse; 47746e683305SStefano Zampini PetscMPIInt all_procs; 477574e2c79eSStefano Zampini PetscBool csin_ml,csin_ds,csin,csin_type_simple,redist; 477668457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 477722bc73bbSStefano Zampini PetscScalar *array; 47789881197aSStefano Zampini PetscErrorCode ierr; 4779fdc09c96SStefano Zampini 4780c8587f34SStefano Zampini PetscFunctionBegin; 4781c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 478268457ee5SStefano Zampini if (pcbddc->new_primal_space || pcbddc->coarse_size == -1) { /* a new primal space is present or it is the first initialization, so recompute global numbering */ 4783fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 47845a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 4785fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 4786f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 4787f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 4788f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 4789fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 479051bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 479151bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 4792dc4bcba2SStefano Zampini PC pc; 4793dc4bcba2SStefano Zampini PetscBool isbddc; 4794dc4bcba2SStefano Zampini 4795dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 4796dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 4797dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 4798dc4bcba2SStefano Zampini if (isbddc) { 4799dc4bcba2SStefano Zampini ierr = PCDestroy(&pc);CHKERRQ(ierr); 4800dc4bcba2SStefano Zampini } 4801727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 4802fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 4803fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 4804fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 4805f4ddd8eeSStefano Zampini } 4806fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 4807fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 4808f4ddd8eeSStefano Zampini } 480970cf5478SStefano Zampini /* reset any subassembling information */ 481070cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 48116e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 48126e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 4813fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 4814f4ddd8eeSStefano Zampini } 4815c8587f34SStefano Zampini 48166e683305SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 48172b510759SStefano Zampini im_active = !!(pcis->n); 48182b510759SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 48196e683305SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&all_procs);CHKERRQ(ierr); 48206e683305SStefano Zampini void_procs = all_procs-active_procs; 48216e683305SStefano Zampini csin_type_simple = PETSC_TRUE; 482274e2c79eSStefano Zampini redist = PETSC_FALSE; 482322bc73bbSStefano Zampini if (pcbddc->current_level && void_procs) { 48246e683305SStefano Zampini csin_ml = PETSC_TRUE; 48256e683305SStefano Zampini ncoarse_ml = void_procs; 4826779c1cceSStefano Zampini /* it has no sense to redistribute on a set of processors larger than the number of active processes */ 4827779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < active_procs) { 48286e683305SStefano Zampini csin_ds = PETSC_TRUE; 482918a45a71SStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 483018a45a71SStefano Zampini redist = PETSC_TRUE; 483118a45a71SStefano Zampini } else { 48326e683305SStefano Zampini csin_ds = PETSC_TRUE; 4833779c1cceSStefano Zampini ncoarse_ds = active_procs; 4834779c1cceSStefano Zampini redist = PETSC_TRUE; 483518a45a71SStefano Zampini } 48366e683305SStefano Zampini } else { 48376e683305SStefano Zampini csin_ml = PETSC_FALSE; 48386e683305SStefano Zampini ncoarse_ml = all_procs; 48396e683305SStefano Zampini if (void_procs) { 48406e683305SStefano Zampini csin_ds = PETSC_TRUE; 48416e683305SStefano Zampini ncoarse_ds = void_procs; 48426e683305SStefano Zampini csin_type_simple = PETSC_FALSE; 48436e683305SStefano Zampini } else { 4844779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < all_procs) { 484574e2c79eSStefano Zampini csin_ds = PETSC_TRUE; 484674e2c79eSStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 484774e2c79eSStefano Zampini redist = PETSC_TRUE; 484874e2c79eSStefano Zampini } else { 48496e683305SStefano Zampini csin_ds = PETSC_FALSE; 48506e683305SStefano Zampini ncoarse_ds = all_procs; 48516e683305SStefano Zampini } 48526e683305SStefano Zampini } 485374e2c79eSStefano Zampini } 48546e683305SStefano Zampini 48556e683305SStefano Zampini /* 48566e683305SStefano Zampini test if we can go multilevel: three conditions must be satisfied: 48576e683305SStefano Zampini - we have not exceeded the number of levels requested 48586e683305SStefano Zampini - we can actually subassemble the active processes 48596e683305SStefano Zampini - we can find a suitable number of MPI processes where we can place the subassembled problem 48606e683305SStefano Zampini */ 48616e683305SStefano Zampini multilevel_allowed = PETSC_FALSE; 48626e683305SStefano Zampini multilevel_requested = PETSC_FALSE; 48636e683305SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 48646e683305SStefano Zampini multilevel_requested = PETSC_TRUE; 48656e683305SStefano Zampini if (active_procs/pcbddc->coarsening_ratio < 2 || ncoarse_ml/pcbddc->coarsening_ratio < 2) { 4866f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_FALSE; 48672b510759SStefano Zampini } else { 4868f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_TRUE; 4869c8587f34SStefano Zampini } 4870c8587f34SStefano Zampini } 48716e683305SStefano Zampini /* determine number of process partecipating to coarse solver */ 48726e683305SStefano Zampini if (multilevel_allowed) { 48736e683305SStefano Zampini ncoarse = ncoarse_ml; 48746e683305SStefano Zampini csin = csin_ml; 487558da7f69SStefano Zampini redist = PETSC_FALSE; 48766e683305SStefano Zampini } else { 48776e683305SStefano Zampini ncoarse = ncoarse_ds; 48786e683305SStefano Zampini csin = csin_ds; 48796e683305SStefano Zampini } 4880e7931f94SStefano Zampini 4881abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 4882abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 4883abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 4884abbbba34SStefano Zampini 4885abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 488622bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 488722bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 488822bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 488922bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 4890b1ecc7b1SStefano Zampini #if 0 4891b9b85e73SStefano Zampini { 4892b9b85e73SStefano Zampini PetscViewer viewer; 4893b9b85e73SStefano Zampini char filename[256]; 4894b1ecc7b1SStefano Zampini sprintf(filename,"local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4895b9b85e73SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4896b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4897b9b85e73SStefano Zampini ierr = MatView(coarse_submat_dense,viewer);CHKERRQ(ierr); 4898b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4899b9b85e73SStefano Zampini } 4900b9b85e73SStefano Zampini #endif 4901e176bc59SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)pc),1,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_islg,NULL,&t_coarse_mat_is);CHKERRQ(ierr); 49026e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 49036e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 49046e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4905abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 4906abbbba34SStefano Zampini 49076e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 49086e683305SStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal) ) { /* protects from unneded computations */ 49096e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 49106e683305SStefano Zampini const PetscInt *idxs; 49116e683305SStefano Zampini ISLocalToGlobalMapping tmap; 49126e683305SStefano Zampini 49136e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 49140be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 49156e683305SStefano Zampini /* allocate space for temporary storage */ 4916854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 4917854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 49186e683305SStefano Zampini /* allocate for IS array */ 49196e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 49206e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 49216e683305SStefano Zampini nis = nisdofs + nisneu; 4922854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 49236e683305SStefano Zampini /* dofs splitting */ 49246e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 49256e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 49266e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 49276e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 49286e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 49296e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 49306e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 49316e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->ISForDofsLocal[i]),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 49326e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 49336e683305SStefano Zampini } 49346e683305SStefano Zampini /* neumann boundaries */ 49356e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 49366e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 49376e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 49386e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 49396e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 49406e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 49416e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 49426e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->NeumannBoundariesLocal),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 49436e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 49446e683305SStefano Zampini } 49456e683305SStefano Zampini /* free memory */ 49466e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 49476e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 49486e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 49496e683305SStefano Zampini } else { 49506e683305SStefano Zampini nis = 0; 49516e683305SStefano Zampini nisdofs = 0; 49526e683305SStefano Zampini nisneu = 0; 49536e683305SStefano Zampini isarray = NULL; 49546e683305SStefano Zampini } 49556e683305SStefano Zampini /* destroy no longer needed map */ 49566e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 49576e683305SStefano Zampini 49586e683305SStefano Zampini /* restrict on coarse candidates (if needed) */ 49596e683305SStefano Zampini coarse_mat_is = NULL; 49606e683305SStefano Zampini if (csin) { 49616e683305SStefano Zampini if (!pcbddc->coarse_subassembling_init ) { /* creates subassembling init pattern if not present */ 496274e2c79eSStefano Zampini if (redist) { 496374e2c79eSStefano Zampini PetscMPIInt rank; 4964779c1cceSStefano Zampini PetscInt spc,n_spc_p1,dest[1],destsize; 496574e2c79eSStefano Zampini 496674e2c79eSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 496758da7f69SStefano Zampini spc = active_procs/ncoarse; 496858da7f69SStefano Zampini n_spc_p1 = active_procs%ncoarse; 4969779c1cceSStefano Zampini if (im_active) { 4970779c1cceSStefano Zampini destsize = 1; 497174e2c79eSStefano Zampini if (rank > n_spc_p1*(spc+1)-1) { 497274e2c79eSStefano Zampini dest[0] = n_spc_p1+(rank-(n_spc_p1*(spc+1)))/spc; 497374e2c79eSStefano Zampini } else { 497474e2c79eSStefano Zampini dest[0] = rank/(spc+1); 497574e2c79eSStefano Zampini } 497674e2c79eSStefano Zampini } else { 4977779c1cceSStefano Zampini destsize = 0; 49786e683305SStefano Zampini } 4979779c1cceSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),destsize,dest,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 4980779c1cceSStefano Zampini } else if (csin_type_simple) { 49816e683305SStefano Zampini PetscMPIInt rank; 49826e683305SStefano Zampini PetscInt issize,isidx; 4983779c1cceSStefano Zampini 49846e683305SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 49856e683305SStefano Zampini if (im_active) { 49866e683305SStefano Zampini issize = 1; 49876e683305SStefano Zampini isidx = (PetscInt)rank; 49886e683305SStefano Zampini } else { 49896e683305SStefano Zampini issize = 0; 49906e683305SStefano Zampini isidx = -1; 49916e683305SStefano Zampini } 49926e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),issize,&isidx,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 4993779c1cceSStefano Zampini } else { /* get a suitable subassembling pattern from MATIS code */ 4994b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 49956e683305SStefano Zampini } 4996779c1cceSStefano Zampini 4997779c1cceSStefano Zampini /* we need to shift on coarse candidates either if we are not redistributing or we are redistributing and we have enough void processes */ 4998779c1cceSStefano Zampini if (!redist || ncoarse <= void_procs) { 4999779c1cceSStefano Zampini PetscInt ncoarse_cand,tissize,*nisindices; 5000779c1cceSStefano Zampini PetscInt *coarse_candidates; 5001779c1cceSStefano Zampini const PetscInt* tisindices; 5002779c1cceSStefano Zampini 5003779c1cceSStefano Zampini /* get coarse candidates' ranks in pc communicator */ 5004779c1cceSStefano Zampini ierr = PetscMalloc1(all_procs,&coarse_candidates);CHKERRQ(ierr); 5005779c1cceSStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,coarse_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5006779c1cceSStefano Zampini for (i=0,ncoarse_cand=0;i<all_procs;i++) { 5007779c1cceSStefano Zampini if (!coarse_candidates[i]) { 5008779c1cceSStefano Zampini coarse_candidates[ncoarse_cand++]=i; 5009779c1cceSStefano Zampini } 5010779c1cceSStefano Zampini } 5011779c1cceSStefano Zampini if (ncoarse_cand < ncoarse) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen! %d < %d",ncoarse_cand,ncoarse); 5012779c1cceSStefano Zampini 5013779c1cceSStefano Zampini 50146e683305SStefano Zampini if (pcbddc->dbg_flag) { 50156e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 50166e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init (before shift)\n");CHKERRQ(ierr); 50176e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 50186e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse candidates\n");CHKERRQ(ierr); 5019779c1cceSStefano Zampini for (i=0;i<ncoarse_cand;i++) { 50206e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"%d ",coarse_candidates[i]);CHKERRQ(ierr); 50216e683305SStefano Zampini } 50226e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"\n");CHKERRQ(ierr); 50236e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 50246e683305SStefano Zampini } 50256e683305SStefano Zampini /* shift the pattern on coarse candidates */ 50266e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->coarse_subassembling_init,&tissize);CHKERRQ(ierr); 50276e683305SStefano Zampini ierr = ISGetIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 5028854ce69bSBarry Smith ierr = PetscMalloc1(tissize,&nisindices);CHKERRQ(ierr); 50296e683305SStefano Zampini for (i=0;i<tissize;i++) nisindices[i] = coarse_candidates[tisindices[i]]; 50306e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 50316e683305SStefano Zampini ierr = ISGeneralSetIndices(pcbddc->coarse_subassembling_init,tissize,nisindices,PETSC_OWN_POINTER);CHKERRQ(ierr); 50326e683305SStefano Zampini ierr = PetscFree(coarse_candidates);CHKERRQ(ierr); 50336e683305SStefano Zampini } 50346e683305SStefano Zampini if (pcbddc->dbg_flag) { 50356e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 50366e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init\n");CHKERRQ(ierr); 50376e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 50386e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 50396e683305SStefano Zampini } 5040779c1cceSStefano Zampini } 50416e683305SStefano Zampini /* get temporary coarse mat in IS format restricted on coarse procs (plus additional index sets of isarray) */ 504253a05cb3SStefano Zampini if (multilevel_allowed) { /* we need to keep tracking of void processes for future placements */ 504353a05cb3SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling_init,0,PETSC_TRUE,PETSC_FALSE,MAT_INITIAL_MATRIX,&coarse_mat_is,nis,isarray);CHKERRQ(ierr); 504453a05cb3SStefano Zampini } else { /* this is the last level, so use just receiving processes in subcomm */ 504553a05cb3SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling_init,0,PETSC_TRUE,PETSC_TRUE,MAT_INITIAL_MATRIX,&coarse_mat_is,nis,isarray);CHKERRQ(ierr); 504653a05cb3SStefano Zampini } 50476e683305SStefano Zampini } else { 50486e683305SStefano Zampini if (pcbddc->dbg_flag) { 50496e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 50506e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init not needed\n");CHKERRQ(ierr); 50516e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 50526e683305SStefano Zampini } 50536e683305SStefano Zampini ierr = PetscObjectReference((PetscObject)t_coarse_mat_is);CHKERRQ(ierr); 50546e683305SStefano Zampini coarse_mat_is = t_coarse_mat_is; 50556e683305SStefano Zampini } 50566e683305SStefano Zampini 50576e683305SStefano Zampini /* create local to global scatters for coarse problem */ 505868457ee5SStefano Zampini if (compute_vecs) { 50596e683305SStefano Zampini PetscInt lrows; 50606e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 50616e683305SStefano Zampini if (coarse_mat_is) { 50626e683305SStefano Zampini ierr = MatGetLocalSize(coarse_mat_is,&lrows,NULL);CHKERRQ(ierr); 50636e683305SStefano Zampini } else { 50646e683305SStefano Zampini lrows = 0; 50656e683305SStefano Zampini } 50666e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 50676e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 50686e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 50696e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 50706e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 50716e683305SStefano Zampini } 50726e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 50736e683305SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 5074c8587f34SStefano Zampini 5075f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 5076f9eb5b7dSStefano Zampini if (multilevel_allowed) { 5077f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 5078f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 5079f9eb5b7dSStefano Zampini } else { 5080f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 5081f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 5082c8587f34SStefano Zampini } 5083c8587f34SStefano Zampini 50846e683305SStefano Zampini /* print some info if requested */ 50856e683305SStefano Zampini if (pcbddc->dbg_flag) { 50866e683305SStefano Zampini if (!multilevel_allowed) { 50876e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 50886e683305SStefano Zampini if (multilevel_requested) { 50896e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Not enough active processes on level %d (active processes %d, coarsening ratio %d)\n",pcbddc->current_level,active_procs,pcbddc->coarsening_ratio);CHKERRQ(ierr); 50906e683305SStefano Zampini } else if (pcbddc->max_levels) { 50916e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 50926e683305SStefano Zampini } 50936e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 50946e683305SStefano Zampini } 50956e683305SStefano Zampini } 50966e683305SStefano Zampini 5097f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 50986e683305SStefano Zampini if (coarse_mat_is) { 50996e683305SStefano Zampini MatReuse coarse_mat_reuse; 51006a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 51016e683305SStefano Zampini if (pcbddc->dbg_flag) { 51026e683305SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat_is)); 51036e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 51046e683305SStefano Zampini } 5105f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 5106312be037SStefano Zampini char prefix[256],str_level[16]; 5107e604994aSStefano Zampini size_t len; 51086e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat_is),&pcbddc->coarse_ksp);CHKERRQ(ierr); 5109422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 5110c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 5111f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 51125f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat_is,coarse_mat_is);CHKERRQ(ierr); 5113c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 51146e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 5115c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 5116c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5117e604994aSStefano Zampini /* prefix */ 5118e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 5119e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 5120e604994aSStefano Zampini if (!pcbddc->current_level) { 5121e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 5122e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 5123c8587f34SStefano Zampini } else { 5124e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 5125312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 5126312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 512734d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 5128312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 5129e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 5130e604994aSStefano Zampini } 5131e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 51323e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 51333e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 51343e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 51353e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 5136f9eb5b7dSStefano Zampini /* allow user customization */ 5137f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 51383e3c6dadSStefano Zampini } 51393e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 514051bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 51413e3c6dadSStefano Zampini if (nisdofs) { 51423e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 51433e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 51443e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 51453e3c6dadSStefano Zampini } 51463e3c6dadSStefano Zampini } 51473e3c6dadSStefano Zampini if (nisneu) { 51483e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 51493e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 5150312be037SStefano Zampini } 5151f9eb5b7dSStefano Zampini 5152f9eb5b7dSStefano Zampini /* get some info after set from options */ 5153f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 5154f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 51554f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 51566e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 5157f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5158f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 5159f9eb5b7dSStefano Zampini } 516039f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 51614f3a063dSStefano Zampini if (isredundant) { 51624f3a063dSStefano Zampini KSP inner_ksp; 51634f3a063dSStefano Zampini PC inner_pc; 51644f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 51654f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 51664f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 51674f3a063dSStefano Zampini } 5168f9eb5b7dSStefano Zampini 5169f9eb5b7dSStefano Zampini /* assemble coarse matrix */ 5170fa7f1dd8SStefano Zampini if (coarse_reuse) { 517181d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 5172fa7f1dd8SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 51736e683305SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 5174fa7f1dd8SStefano Zampini } else { 51756e683305SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 5176fa7f1dd8SStefano Zampini } 5177c8587f34SStefano Zampini if (isbddc || isnn) { 517822bc73bbSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 517970cf5478SStefano Zampini if (!pcbddc->coarse_subassembling) { /* subassembling info is not present */ 5180b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(coarse_mat_is,active_procs/pcbddc->coarsening_ratio,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 518122b6e8a2SStefano Zampini if (pcbddc->dbg_flag) { 51826e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 51836e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Subassembling pattern\n");CHKERRQ(ierr); 51846e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,dbg_viewer);CHKERRQ(ierr); 51856e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 518622b6e8a2SStefano Zampini } 518770cf5478SStefano Zampini } 518853a05cb3SStefano Zampini ierr = MatISSubassemble(coarse_mat_is,pcbddc->coarse_subassembling,0,PETSC_FALSE,PETSC_FALSE,coarse_mat_reuse,&coarse_mat,0,NULL);CHKERRQ(ierr); 518970cf5478SStefano Zampini } else { 519022bc73bbSStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 519122bc73bbSStefano Zampini coarse_mat = coarse_mat_is; 519222bc73bbSStefano Zampini } 519322bc73bbSStefano Zampini } else { 51942e1e5fa4SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 5195c8587f34SStefano Zampini } 5196c8587f34SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 5197c8587f34SStefano Zampini 51983301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 51995a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 52003301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 52013301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 52023301b35fSStefano Zampini } 52033301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 52043301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 52053301b35fSStefano Zampini } 52063301b35fSStefano Zampini if (pc->pmat->spd_set) { 52073301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 52083301b35fSStefano Zampini } 52096e683305SStefano Zampini /* set operators */ 52105f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 52116e683305SStefano Zampini if (pcbddc->dbg_flag) { 52126e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 52136e683305SStefano Zampini } 52146e683305SStefano Zampini } else { /* processes non partecipating to coarse solver (if any) */ 52156e683305SStefano Zampini coarse_mat = 0; 52166e683305SStefano Zampini } 52176e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 5218b1ecc7b1SStefano Zampini #if 0 5219b9b85e73SStefano Zampini { 5220b9b85e73SStefano Zampini PetscViewer viewer; 5221b9b85e73SStefano Zampini char filename[256]; 5222b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 5223b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 5224b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 5225b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 5226b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5227b9b85e73SStefano Zampini } 5228b9b85e73SStefano Zampini #endif 5229c8587f34SStefano Zampini 5230c8587f34SStefano Zampini /* Compute coarse null space (special handling by BDDC only) */ 5231298c0119SStefano Zampini #if 0 5232c8587f34SStefano Zampini if (pcbddc->NullSpace) { 5233c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,coarse_mat,&CoarseNullSpace);CHKERRQ(ierr); 523498a51de6SStefano Zampini } 5235298c0119SStefano Zampini #endif 5236b0f5fe93SStefano Zampini /* hack */ 523798a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 523898a51de6SStefano Zampini Vec crhs,csol; 523904708bb6SStefano Zampini 5240f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 5241f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 5242f347579bSStefano Zampini if (!csol) { 52432a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 5244f9eb5b7dSStefano Zampini } 5245f347579bSStefano Zampini if (!crhs) { 52462a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 5247f347579bSStefano Zampini } 5248b0f5fe93SStefano Zampini } 5249b0f5fe93SStefano Zampini 5250b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 5251b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 5252b0f5fe93SStefano Zampini 5253b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 52544f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 52554f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 52564f1b2e48SStefano Zampini } 5257b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 5258b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 5259b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5260b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5261b0f5fe93SStefano Zampini if (coarse_mat) { 5262b0f5fe93SStefano Zampini Vec nullv; 5263b0f5fe93SStefano Zampini PetscScalar *array,*array2; 5264b0f5fe93SStefano Zampini PetscInt nl; 5265b0f5fe93SStefano Zampini 5266b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 5267b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 5268b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 5269b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 5270b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 5271b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 5272b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 5273b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 5274b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 5275b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 5276b0f5fe93SStefano Zampini } 5277b0f5fe93SStefano Zampini } 5278b0f5fe93SStefano Zampini 5279b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 5280b0f5fe93SStefano Zampini PetscBool ispreonly; 5281b0f5fe93SStefano Zampini 5282b0f5fe93SStefano Zampini if (CoarseNullSpace) { 5283b0f5fe93SStefano Zampini PetscBool isnull; 5284b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 5285b0f5fe93SStefano Zampini if (isnull) { 5286b0f5fe93SStefano Zampini if (isbddc) { 5287b0f5fe93SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 5288b0f5fe93SStefano Zampini } else { 5289b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 5290b0f5fe93SStefano Zampini } 5291b0f5fe93SStefano Zampini } else { 5292b0f5fe93SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 5293b0f5fe93SStefano Zampini } 5294b0f5fe93SStefano Zampini } 5295b0f5fe93SStefano Zampini /* setup coarse ksp */ 5296b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 5297cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 5298cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 52996e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 5300c8587f34SStefano Zampini KSP check_ksp; 53012b510759SStefano Zampini KSPType check_ksp_type; 5302c8587f34SStefano Zampini PC check_pc; 53036e683305SStefano Zampini Vec check_vec,coarse_vec; 53046a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 53052b510759SStefano Zampini PetscInt its; 53066e683305SStefano Zampini PetscBool compute_eigs; 53076e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 53086e683305SStefano Zampini PetscInt neigs; 53098e185a42SStefano Zampini const char *prefix; 5310c8587f34SStefano Zampini 53112b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 53126e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 5313422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 531423ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 5315f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 53162b510759SStefano Zampini if (ispreonly) { 53172b510759SStefano Zampini check_ksp_type = KSPPREONLY; 53186e683305SStefano Zampini compute_eigs = PETSC_FALSE; 53192b510759SStefano Zampini } else { 5320cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 53216e683305SStefano Zampini compute_eigs = PETSC_TRUE; 5322c8587f34SStefano Zampini } 5323c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 53246e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 53256e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 53266e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 5327a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 5328a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 5329a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 5330a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 5331c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 5332c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 5333c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 5334c8587f34SStefano Zampini /* create random vec */ 53356e683305SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&coarse_vec);CHKERRQ(ierr); 53366e683305SStefano Zampini ierr = VecDuplicate(coarse_vec,&check_vec);CHKERRQ(ierr); 5337c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 5338c8587f34SStefano Zampini if (CoarseNullSpace) { 5339c8587f34SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 5340c8587f34SStefano Zampini } 53416e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 5342c8587f34SStefano Zampini /* solve coarse problem */ 53436e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 5344c8587f34SStefano Zampini if (CoarseNullSpace) { 53456e683305SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,coarse_vec);CHKERRQ(ierr); 5346c8587f34SStefano Zampini } 5347cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 53486e683305SStefano Zampini if (compute_eigs) { 5349854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 5350854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 53516e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 53526e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 53536e683305SStefano Zampini lambda_min = eigs_r[0]; 53546e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 53556e683305SStefano Zampini if (lambda_max>lambda_min) { 5356cbcc2c2aSStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 5357cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 5358cbcc2c2aSStefano Zampini } 5359c8587f34SStefano Zampini } 5360c8587f34SStefano Zampini } 5361cbcc2c2aSStefano Zampini 5362c8587f34SStefano Zampini /* check coarse problem residual error */ 53636e683305SStefano Zampini if (pcbddc->dbg_flag) { 53646e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 53656e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 53666e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 5367c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 53686e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 53696e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 5370c8587f34SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 5371779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 53726e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 53736e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 53746e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 53756e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 5376b0f5fe93SStefano Zampini if (CoarseNullSpace) { 5377b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 5378b0f5fe93SStefano Zampini } 53796e683305SStefano Zampini if (compute_eigs) { 53806e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 5381deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 5382c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 53836e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 53846e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem eigenvalues (estimated with %d iterations of %s): %1.6e %1.6e (%1.6e %1.6e)\n",its,check_ksp_type,lambda_min,lambda_max,lambda_min_s,lambda_max_s);CHKERRQ(ierr); 53856e683305SStefano Zampini for (i=0;i<neigs;i++) { 53866e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 5387c8587f34SStefano Zampini } 53886e683305SStefano Zampini } 53896e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 53906e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 53916e683305SStefano Zampini } 5392c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 53936e683305SStefano Zampini if (compute_eigs) { 53946e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 53956e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 5396c8587f34SStefano Zampini } 53976e683305SStefano Zampini } 53986e683305SStefano Zampini } 5399cbcc2c2aSStefano Zampini /* print additional info */ 5400cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 54016e683305SStefano Zampini /* waits until all processes reaches this point */ 54026e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 5403cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 5404cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5405cbcc2c2aSStefano Zampini } 5406cbcc2c2aSStefano Zampini 54072b510759SStefano Zampini /* free memory */ 5408c8587f34SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 5409fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 5410c8587f34SStefano Zampini PetscFunctionReturn(0); 5411c8587f34SStefano Zampini } 5412674ae819SStefano Zampini 5413f34684f1SStefano Zampini #undef __FUNCT__ 5414f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 5415f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 5416f34684f1SStefano Zampini { 5417f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5418f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 5419f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5420dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 5421dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 542273be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 5423dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 5424f34684f1SStefano Zampini PetscErrorCode ierr; 5425f34684f1SStefano Zampini 5426f34684f1SStefano Zampini PetscFunctionBegin; 5427f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 54280e6343abSStefano Zampini if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) { 54290e6343abSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 5430727cdba6SStefano Zampini } 5431dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 54323bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 5433dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5434dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 5435dc456d91SStefano Zampini ierr = PCBDDCSubsetNumbering(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 5436dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 5437dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 5438dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 54390e6343abSStefano Zampini if (local_size != pcbddc->local_primal_size) { 54400e6343abSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid number of local primal indices computed %d != %d",local_size,pcbddc->local_primal_size); 54410e6343abSStefano Zampini } 5442dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 5443dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5444dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 5445dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5446dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5447f34684f1SStefano Zampini 5448f34684f1SStefano Zampini /* check numbering */ 5449f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 5450019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 5451dc456d91SStefano Zampini PetscInt i; 5452b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 5453f34684f1SStefano Zampini 5454f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5455f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5456f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 54570fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 5458019a44ceSStefano Zampini /* counter */ 5459019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5460019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 5461019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5462019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5463019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5464019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5465019a44ceSStefano Zampini 5466f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 5467f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 5468727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5469f34684f1SStefano Zampini } 5470f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5471f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5472f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5473e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5474e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5475e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5476e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5477f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5478019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5479f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5480019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 548175c01103SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]); 548275c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 5483b9b85e73SStefano Zampini set_error = PETSC_TRUE; 5484019a44ceSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d: local index %d owned by a %d processes instead of %d!\n",PetscGlobalRank,i,owned,neigh);CHKERRQ(ierr); 5485f34684f1SStefano Zampini } 5486f34684f1SStefano Zampini } 5487019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5488b9b85e73SStefano Zampini ierr = MPI_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5489f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5490f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5491f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 5492f34684f1SStefano Zampini } 5493f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5494f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5495e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5496e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5497f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 5498f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 5499b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 5500ca8b9ea9SStefano Zampini PetscInt *gidxs; 5501ca8b9ea9SStefano Zampini 5502ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 55033bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 5504f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 5505f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5506f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5507f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 55084bc2dc4bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_primal_indices[%d]=%d (%d,%d)\n",i,local_primal_indices[i],pcbddc->primal_indices_local_idxs[i],gidxs[i]);CHKERRQ(ierr); 5509f34684f1SStefano Zampini } 5510f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5511ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 5512f34684f1SStefano Zampini } 5513f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5514302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 5515f34684f1SStefano Zampini } 55168bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 5517f34684f1SStefano Zampini /* get back data */ 5518f34684f1SStefano Zampini *coarse_size_n = coarse_size; 5519f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 5520674ae819SStefano Zampini PetscFunctionReturn(0); 5521674ae819SStefano Zampini } 5522674ae819SStefano Zampini 5523e456f2a8SStefano Zampini #undef __FUNCT__ 5524e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 5525a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 5526e456f2a8SStefano Zampini { 5527e456f2a8SStefano Zampini IS localis_t; 5528a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 5529e456f2a8SStefano Zampini PetscScalar *vals; 5530e456f2a8SStefano Zampini PetscErrorCode ierr; 5531e456f2a8SStefano Zampini 5532e456f2a8SStefano Zampini PetscFunctionBegin; 5533a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 5534e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 5535854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 5536e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 5537e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5538a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 5539a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 55401035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 5541a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 55421035eff8SStefano Zampini } 5543a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 5544e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5545e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 5546a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 5547a7dc3881SStefano Zampini /* now compute set in local ordering */ 5548a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5549a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5550a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5551a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 5552a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5553ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5554e456f2a8SStefano Zampini lsize++; 5555e456f2a8SStefano Zampini } 5556e456f2a8SStefano Zampini } 5557854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 5558a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5559ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5560e456f2a8SStefano Zampini idxs[lsize++] = i; 5561e456f2a8SStefano Zampini } 5562e456f2a8SStefano Zampini } 5563a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5564a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 5565e456f2a8SStefano Zampini *localis = localis_t; 5566e456f2a8SStefano Zampini PetscFunctionReturn(0); 5567e456f2a8SStefano Zampini } 5568906d46d4SStefano Zampini 5569906d46d4SStefano Zampini /* the next two functions will be called in KSPMatMult if a change of basis has been requested */ 5570906d46d4SStefano Zampini #undef __FUNCT__ 5571906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMult_Private" 5572906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y) 5573906d46d4SStefano Zampini { 5574906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5575906d46d4SStefano Zampini PetscErrorCode ierr; 5576906d46d4SStefano Zampini 5577906d46d4SStefano Zampini PetscFunctionBegin; 5578906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5579906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5580906d46d4SStefano Zampini ierr = MatMult(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5581906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5582906d46d4SStefano Zampini PetscFunctionReturn(0); 5583906d46d4SStefano Zampini } 5584906d46d4SStefano Zampini 5585906d46d4SStefano Zampini #undef __FUNCT__ 5586906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMultTranspose_Private" 5587906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y) 5588906d46d4SStefano Zampini { 5589906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5590906d46d4SStefano Zampini PetscErrorCode ierr; 5591906d46d4SStefano Zampini 5592906d46d4SStefano Zampini PetscFunctionBegin; 5593906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5594906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5595906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5596906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5597906d46d4SStefano Zampini PetscFunctionReturn(0); 5598906d46d4SStefano Zampini } 5599b96c3477SStefano Zampini 5600b96c3477SStefano Zampini #undef __FUNCT__ 5601b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 560208122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 5603b96c3477SStefano Zampini { 5604a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5605b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5606b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5607a64f4aa4SStefano Zampini Mat S_j; 5608b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 5609b96c3477SStefano Zampini PetscBool free_used_adj; 5610b96c3477SStefano Zampini PetscErrorCode ierr; 5611b96c3477SStefano Zampini 5612b96c3477SStefano Zampini PetscFunctionBegin; 5613b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 5614b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 561508122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 5616b96c3477SStefano Zampini used_xadj = NULL; 5617b96c3477SStefano Zampini used_adjncy = NULL; 5618b96c3477SStefano Zampini } else { 561908122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 562008122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 562108122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 562208122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 5623b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 5624b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 5625b96c3477SStefano Zampini } else { 56262fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 5627b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 5628b96c3477SStefano Zampini PetscInt nvtxs; 5629b96c3477SStefano Zampini 56302fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 56312fffb893SStefano Zampini if (flg_row) { 5632b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 5633b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 5634b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 5635b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 56362fffb893SStefano Zampini } else { 56372fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 56382fffb893SStefano Zampini used_xadj = NULL; 56392fffb893SStefano Zampini used_adjncy = NULL; 56402fffb893SStefano Zampini } 56412fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 5642b96c3477SStefano Zampini } 5643b96c3477SStefano Zampini } 5644d5574798SStefano Zampini 5645d5574798SStefano Zampini /* setup sub_schurs data */ 5646a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 5647a64f4aa4SStefano Zampini if (!sub_schurs->use_mumps) { 5648a64f4aa4SStefano Zampini /* pcbddc->ksp_D up to date only if not using MUMPS */ 5649a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 565006a4e24aSStefano Zampini ierr = PCBDDCSubSchursSetUp(sub_schurs,NULL,S_j,used_xadj,used_adjncy,pcbddc->sub_schurs_layers,pcbddc->faster_deluxe,pcbddc->adaptive_selection,PETSC_FALSE,PETSC_FALSE);CHKERRQ(ierr); 5651a64f4aa4SStefano Zampini } else { 56526816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 565304708bb6SStefano Zampini PetscBool isseqaij; 56545feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 56555feab87aSStefano Zampini PetscInt n_vertices; 56565feab87aSStefano Zampini 56575feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 56582034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 56595feab87aSStefano Zampini } 566004708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 566104708bb6SStefano Zampini if (!isseqaij) { 566204708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 566304708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 566404708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 566504708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 566604708bb6SStefano Zampini } else { 566704708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 566804708bb6SStefano Zampini } 566904708bb6SStefano Zampini } 567006a4e24aSStefano Zampini ierr = PCBDDCSubSchursSetUp(sub_schurs,pcbddc->local_mat,S_j,used_xadj,used_adjncy,pcbddc->sub_schurs_layers,pcbddc->faster_deluxe,pcbddc->adaptive_selection,reuse_solvers,pcbddc->benign_saddle_point);CHKERRQ(ierr); 5671a64f4aa4SStefano Zampini } 5672a64f4aa4SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 5673b96c3477SStefano Zampini 5674b96c3477SStefano Zampini /* free adjacency */ 5675b96c3477SStefano Zampini if (free_used_adj) { 5676b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 5677b96c3477SStefano Zampini } 5678b96c3477SStefano Zampini PetscFunctionReturn(0); 5679b96c3477SStefano Zampini } 5680b96c3477SStefano Zampini 5681b96c3477SStefano Zampini #undef __FUNCT__ 5682b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 568308122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 5684b96c3477SStefano Zampini { 5685b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5686b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5687b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5688b96c3477SStefano Zampini PCBDDCGraph graph; 5689b96c3477SStefano Zampini PetscErrorCode ierr; 5690b96c3477SStefano Zampini 5691b96c3477SStefano Zampini PetscFunctionBegin; 5692b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 569308122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 56943301b35fSStefano Zampini IS verticesIS,verticescomm; 56953301b35fSStefano Zampini PetscInt vsize,*idxs; 5696b96c3477SStefano Zampini 5697b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 56983301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 56993301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 57003301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 57013301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 57023301b35fSStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 5703b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 57047fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global);CHKERRQ(ierr); 57053301b35fSStefano Zampini ierr = PCBDDCGraphSetUp(graph,0,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 57063301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 5707b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 5708b96c3477SStefano Zampini /* 5709b96c3477SStefano Zampini if (pcbddc->dbg_flag) { 5710b96c3477SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 5711b96c3477SStefano Zampini } 5712b96c3477SStefano Zampini */ 5713b96c3477SStefano Zampini } else { 5714b96c3477SStefano Zampini graph = pcbddc->mat_graph; 5715b96c3477SStefano Zampini } 5716b96c3477SStefano Zampini 5717b96c3477SStefano Zampini /* sub_schurs init */ 5718a64f4aa4SStefano Zampini ierr = PCBDDCSubSchursInit(sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 5719a64f4aa4SStefano Zampini 5720b96c3477SStefano Zampini /* free graph struct */ 572108122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 5722b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 5723b96c3477SStefano Zampini } 5724b96c3477SStefano Zampini PetscFunctionReturn(0); 5725b96c3477SStefano Zampini } 5726fa34dd3eSStefano Zampini 5727fa34dd3eSStefano Zampini #undef __FUNCT__ 5728fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 5729fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 5730fa34dd3eSStefano Zampini { 5731fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 5732fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 5733fa34dd3eSStefano Zampini PetscErrorCode ierr; 5734fa34dd3eSStefano Zampini 5735fa34dd3eSStefano Zampini PetscFunctionBegin; 5736fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 5737fa34dd3eSStefano Zampini IS zerodiag = NULL; 57384f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 5739fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 57404f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 574175c01103SStefano Zampini PetscReal norm; 5742fa34dd3eSStefano Zampini PetscInt i; 5743fa34dd3eSStefano Zampini 5744fa34dd3eSStefano Zampini /* B0 and B0_B */ 5745fa34dd3eSStefano Zampini if (zerodiag) { 5746fa34dd3eSStefano Zampini IS dummy; 5747fa34dd3eSStefano Zampini 57484f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 57494f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 5750fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 5751fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 5752fa34dd3eSStefano Zampini } 5753fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 5754fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 5755fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 5756fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5757fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5758fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5759fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5760fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 5761fa34dd3eSStefano Zampini /* S_j */ 5762fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 5763fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 5764fa34dd3eSStefano Zampini 5765fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 5766fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 5767fa34dd3eSStefano Zampini /* continuous in primal space */ 5768fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 5769fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5770fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5771fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 57724f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 57734f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 5774fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 5775fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5776fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5777fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5778fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5779fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5780fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 5781fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 5782fa34dd3eSStefano Zampini 5783fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 5784fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 5785fa34dd3eSStefano Zampini /* local with Schur */ 5786fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 5787fa34dd3eSStefano Zampini if (zerodiag) { 5788fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 57894f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 5790fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 5791fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 5792fa34dd3eSStefano Zampini } 5793fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 5794fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5795fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5796fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5797fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 5798fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 5799fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 5800fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5801fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 5802fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5803fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5804fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5805fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5806fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5807fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 5808fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 5809fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 5810fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5811fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5812fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5813fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5814fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5815fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 5816fa34dd3eSStefano Zampini if (zerodiag) { 5817fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 5818fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 58194f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 5820fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 5821fa34dd3eSStefano Zampini } 5822fa34dd3eSStefano Zampini /* BDDC */ 5823fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 5824fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 5825fa34dd3eSStefano Zampini 5826fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 5827fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 5828fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 5829fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 58304f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 58314f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 5832fa34dd3eSStefano Zampini } 58334f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 5834fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 5835fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 5836fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 5837fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 5838fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 5839fa34dd3eSStefano Zampini } 5840fa34dd3eSStefano Zampini PetscFunctionReturn(0); 5841fa34dd3eSStefano Zampini } 5842